Fixes for tpm2 (#84)
* Expose EC X and Y as parameters * Make AES-CFB compatible with OpenSSL stream cipher calling pattern * Cleanup * PR comments, address in == out case * Comment
This commit is contained in:
Родитель
ab6d48fbc9
Коммит
81bfe457ed
|
@ -22,6 +22,9 @@ static const OSSL_PARAM p_scossl_aes_generic_param_types[] = {
|
|||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL),
|
||||
OSSL_PARAM_int(OSSL_CIPHER_PARAM_AEAD, NULL),
|
||||
OSSL_PARAM_int(OSSL_CIPHER_PARAM_CUSTOM_IV, NULL),
|
||||
OSSL_PARAM_int(OSSL_CIPHER_PARAM_CTS, NULL),
|
||||
OSSL_PARAM_int(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK, NULL),
|
||||
OSSL_PARAM_int(OSSL_CIPHER_PARAM_HAS_RAND_KEY, NULL),
|
||||
OSSL_PARAM_END};
|
||||
|
||||
static const OSSL_PARAM p_scossl_aes_generic_gettable_ctx_param_types[] = {
|
||||
|
@ -236,11 +239,11 @@ static SCOSSL_STATUS p_scossl_aes_copy_mac(_Inout_ SCOSSL_AES_CTX *ctx,
|
|||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
static SCOSSL_STATUS p_scossl_aes_generic_update(_Inout_ SCOSSL_AES_CTX *ctx,
|
||||
_Out_writes_bytes_(*outl) unsigned char *out, _Out_ size_t *outl, size_t outsize,
|
||||
_In_reads_bytes_(inl) const unsigned char *in, size_t inl)
|
||||
static SCOSSL_STATUS p_scossl_aes_generic_block_update(_Inout_ SCOSSL_AES_CTX *ctx,
|
||||
_Out_writes_bytes_(*outl) unsigned char *out, _Out_ size_t *outl, size_t outsize,
|
||||
_In_reads_bytes_(inl) const unsigned char *in, size_t inl)
|
||||
{
|
||||
size_t cbBytesInFullBlocks = 0;
|
||||
SIZE_T cbInFullBlocks = 0;
|
||||
*outl = 0;
|
||||
|
||||
if (inl == 0)
|
||||
|
@ -332,7 +335,7 @@ static SCOSSL_STATUS p_scossl_aes_generic_update(_Inout_ SCOSSL_AES_CTX *ctx,
|
|||
// The buffer may already be full for padded decrypt
|
||||
if (ctx->cbBuf < SYMCRYPT_AES_BLOCK_SIZE)
|
||||
{
|
||||
size_t cbBufRemaining = SYMCRYPT_AES_BLOCK_SIZE - ctx->cbBuf;
|
||||
SIZE_T cbBufRemaining = SYMCRYPT_AES_BLOCK_SIZE - ctx->cbBuf;
|
||||
if (inl < cbBufRemaining)
|
||||
{
|
||||
cbBufRemaining = inl;
|
||||
|
@ -361,34 +364,36 @@ static SCOSSL_STATUS p_scossl_aes_generic_update(_Inout_ SCOSSL_AES_CTX *ctx,
|
|||
*outl += SYMCRYPT_AES_BLOCK_SIZE;
|
||||
outsize -= SYMCRYPT_AES_BLOCK_SIZE;
|
||||
ctx->cbBuf = 0;
|
||||
|
||||
SymCryptWipeKnownSize(ctx->buf, SYMCRYPT_AES_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the remaining number of whole blocks in inl
|
||||
cbBytesInFullBlocks = inl & ~(SYMCRYPT_AES_BLOCK_SIZE-1);
|
||||
cbInFullBlocks = inl & ~(SYMCRYPT_AES_BLOCK_SIZE-1);
|
||||
|
||||
// Decrypt with padding. Ensure the last block is buffered
|
||||
// for the call to cipher_final so padding is removed
|
||||
if (!ctx->encrypt &&
|
||||
ctx->pad &&
|
||||
cbBytesInFullBlocks > 0 &&
|
||||
cbBytesInFullBlocks == inl)
|
||||
cbInFullBlocks > 0 &&
|
||||
cbInFullBlocks == inl)
|
||||
{
|
||||
cbBytesInFullBlocks -= SYMCRYPT_AES_BLOCK_SIZE;
|
||||
cbInFullBlocks -= SYMCRYPT_AES_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
// in still contains whole blocks, encrypt available blocks
|
||||
if (cbBytesInFullBlocks > 0)
|
||||
if (cbInFullBlocks > 0)
|
||||
{
|
||||
if (!ctx->cipher(ctx, out, NULL, outsize, in, cbBytesInFullBlocks))
|
||||
if (!ctx->cipher(ctx, out, NULL, outsize, in, cbInFullBlocks))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
in += cbBytesInFullBlocks;
|
||||
inl -= cbBytesInFullBlocks;
|
||||
*outl += cbBytesInFullBlocks;
|
||||
in += cbInFullBlocks;
|
||||
inl -= cbInFullBlocks;
|
||||
*outl += cbInFullBlocks;
|
||||
}
|
||||
|
||||
// Buffer any remaining data
|
||||
|
@ -417,8 +422,46 @@ static SCOSSL_STATUS p_scossl_aes_generic_update(_Inout_ SCOSSL_AES_CTX *ctx,
|
|||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
static SCOSSL_STATUS p_scossl_aes_generic_final(_Inout_ SCOSSL_AES_CTX *ctx,
|
||||
_Out_writes_bytes_opt_(*outl) unsigned char *out, _Out_ size_t *outl, size_t outsize)
|
||||
static SCOSSL_STATUS p_scossl_aes_generic_stream_update(_Inout_ SCOSSL_AES_CTX *ctx,
|
||||
_Out_writes_bytes_(*outl) unsigned char *out, _Out_ size_t *outl, size_t outsize,
|
||||
_In_reads_bytes_(inl) const unsigned char *in, size_t inl)
|
||||
{
|
||||
if (inl == 0)
|
||||
{
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
if (outsize < inl)
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (!ctx->cipher(ctx, out, outl, outsize, in, inl))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (!ctx->encrypt &&
|
||||
ctx->tlsVersion > 0 &&
|
||||
ctx->tlsMacSize > 0)
|
||||
{
|
||||
if (ctx->tlsMacSize > *outl)
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
ctx->tlsMac = out + (*outl - ctx->tlsMacSize);
|
||||
*outl -= ctx->tlsMacSize;
|
||||
}
|
||||
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
static SCOSSL_STATUS p_scossl_aes_generic_block_final(_Inout_ SCOSSL_AES_CTX *ctx,
|
||||
_Out_writes_bytes_opt_(*outl) unsigned char *out, _Out_ size_t *outl, size_t outsize)
|
||||
{
|
||||
if (ctx->tlsVersion > 0)
|
||||
{
|
||||
|
@ -504,6 +547,13 @@ cleanup:
|
|||
return SymCryptMapUint32(scError, SCOSSL_FAILURE, scErrorMap, 1);
|
||||
}
|
||||
|
||||
static SCOSSL_STATUS p_scossl_aes_generic_stream_final(ossl_unused SCOSSL_AES_CTX *ctx,
|
||||
ossl_unused unsigned char *out, ossl_unused size_t *outl, ossl_unused size_t outsize)
|
||||
{
|
||||
*outl = 0;
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
static SCOSSL_STATUS p_scossl_aes_generic_cipher(_Inout_ SCOSSL_AES_CTX *ctx,
|
||||
_Out_writes_bytes_opt_(*outl) unsigned char *out, _Out_ size_t *outl, size_t outsize,
|
||||
_In_reads_bytes_(inl) const unsigned char *in, size_t inl)
|
||||
|
@ -584,6 +634,27 @@ SCOSSL_STATUS p_scossl_aes_generic_get_params(_Inout_ OSSL_PARAM params[],
|
|||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS)) != NULL &&
|
||||
!OSSL_PARAM_set_int(p, 0))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK)) != NULL &&
|
||||
!OSSL_PARAM_set_int(p, 0))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_HAS_RAND_KEY)) != NULL &&
|
||||
!OSSL_PARAM_set_int(p, 0))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -743,7 +814,8 @@ static SCOSSL_STATUS scossl_aes_ecb_cipher(_Inout_ SCOSSL_AES_CTX *ctx,
|
|||
}
|
||||
|
||||
static SCOSSL_STATUS p_scossl_aes_cfb_cipher_internal(_Inout_ SCOSSL_AES_CTX *ctx, SIZE_T cbShift,
|
||||
_Out_writes_bytes_(*outl) unsigned char *out, _Out_ size_t *outl, size_t outsize,
|
||||
_Inout_updates_(SYMCRYPT_AES_BLOCKSIZE) PBYTE pbChainingValue,
|
||||
_Out_writes_bytes_(*outl) unsigned char *out, _Out_opt_ size_t *outl, size_t outsize,
|
||||
_In_reads_bytes_(inl) const unsigned char *in, size_t inl)
|
||||
{
|
||||
if (outsize < inl)
|
||||
|
@ -759,31 +831,142 @@ static SCOSSL_STATUS p_scossl_aes_cfb_cipher_internal(_Inout_ SCOSSL_AES_CTX *ct
|
|||
|
||||
if (ctx->encrypt)
|
||||
{
|
||||
SymCryptCfbEncrypt(SymCryptAesBlockCipher, cbShift, &ctx->key, ctx->pbChainingValue, in, out, inl);
|
||||
SymCryptCfbEncrypt(SymCryptAesBlockCipher, cbShift, &ctx->key, pbChainingValue, in, out, inl);
|
||||
}
|
||||
else
|
||||
{
|
||||
SymCryptCfbDecrypt(SymCryptAesBlockCipher, cbShift, &ctx->key, ctx->pbChainingValue, in, out, inl);
|
||||
SymCryptCfbDecrypt(SymCryptAesBlockCipher, cbShift, &ctx->key, pbChainingValue, in, out, inl);
|
||||
}
|
||||
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
// AES-CFB requires some special buffering logic due to implementation
|
||||
// differences between OpenSSL and SymCrypt. SymCrypt will only encrypt
|
||||
// in multiples of the shift size, but OpenSSL expects the entirety of
|
||||
// inl to be encrypted in each update call. e.g. if inl is 36, SymCrypt
|
||||
// will only encrypt 32 bytes, but OpenSSL expects 36 bytes to be encrypted.
|
||||
// To handle this, any remaining data is buffered, and the previous chaining
|
||||
// value is saved for the next call. If any data is in the buffer from a
|
||||
// previous call, the remaining space in the buffer is filled and
|
||||
// encrypted/decrypted with the previous chaining value before continuing.
|
||||
static SCOSSL_STATUS scossl_aes_cfb_cipher(_Inout_ SCOSSL_AES_CTX *ctx,
|
||||
_Out_writes_bytes_opt_(*outl) unsigned char *out, _Out_ size_t *outl, size_t outsize,
|
||||
_In_reads_bytes_(inl) const unsigned char *in, size_t inl)
|
||||
{
|
||||
return p_scossl_aes_cfb_cipher_internal(ctx, SYMCRYPT_AES_BLOCK_SIZE, out, outl, outsize, in, inl);
|
||||
BYTE pbPartialBufOut[SYMCRYPT_AES_BLOCK_SIZE];
|
||||
BYTE pbChainingValueLast[SYMCRYPT_AES_BLOCK_SIZE];
|
||||
SIZE_T cbBufRemaining;
|
||||
SIZE_T cbInFullBlocks;
|
||||
SIZE_T cbInRemaining;
|
||||
|
||||
if (outl != NULL)
|
||||
{
|
||||
*outl = inl;
|
||||
}
|
||||
|
||||
if (ctx->cbBuf > 0)
|
||||
{
|
||||
// Last update call was a partial block. Fill buffer and perform cipher
|
||||
// with previous chaining value before continuing.
|
||||
cbBufRemaining = SYMCRYPT_MIN(SYMCRYPT_AES_BLOCK_SIZE - ctx->cbBuf, inl);
|
||||
|
||||
// Save the chaining value for the next call in case ctx->cbBuf + inl < cbBufRemaining
|
||||
memcpy(pbChainingValueLast, ctx->pbChainingValue, SYMCRYPT_AES_BLOCK_SIZE);
|
||||
memcpy(ctx->buf + ctx->cbBuf, in, cbBufRemaining);
|
||||
|
||||
if (p_scossl_aes_cfb_cipher_internal(
|
||||
ctx,
|
||||
SYMCRYPT_AES_BLOCK_SIZE,
|
||||
ctx->pbChainingValue,
|
||||
pbPartialBufOut, NULL, SYMCRYPT_AES_BLOCK_SIZE,
|
||||
ctx->buf, SYMCRYPT_AES_BLOCK_SIZE) != SCOSSL_SUCCESS)
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
memcpy(out, pbPartialBufOut + ctx->cbBuf, cbBufRemaining);
|
||||
|
||||
// Advance pointers and counters
|
||||
out += cbBufRemaining;
|
||||
outsize -= cbBufRemaining;
|
||||
|
||||
in += cbBufRemaining;
|
||||
inl -= cbBufRemaining;
|
||||
|
||||
ctx->cbBuf += cbBufRemaining;
|
||||
if (ctx->cbBuf == SYMCRYPT_AES_BLOCK_SIZE)
|
||||
{
|
||||
ctx->cbBuf = 0;
|
||||
SymCryptWipeKnownSize(ctx->buf, SYMCRYPT_AES_BLOCK_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(ctx->pbChainingValue, pbChainingValueLast, SYMCRYPT_AES_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
cbInFullBlocks = inl & ~(SYMCRYPT_AES_BLOCK_SIZE-1);
|
||||
cbInRemaining = inl - cbInFullBlocks;
|
||||
|
||||
if (cbInFullBlocks > 0)
|
||||
{
|
||||
if (ctx->cbBuf != 0)
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (p_scossl_aes_cfb_cipher_internal(
|
||||
ctx,
|
||||
SYMCRYPT_AES_BLOCK_SIZE,
|
||||
ctx->pbChainingValue,
|
||||
out, NULL, outsize,
|
||||
in, cbInFullBlocks) != SCOSSL_SUCCESS)
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (cbInRemaining > 0)
|
||||
{
|
||||
// Encrypt any extra bytes and save the chaining value for the next call
|
||||
memcpy(pbChainingValueLast, ctx->pbChainingValue, SYMCRYPT_AES_BLOCK_SIZE);
|
||||
|
||||
memcpy(ctx->buf, in + cbInFullBlocks, cbInRemaining);
|
||||
ctx->cbBuf = cbInRemaining;
|
||||
|
||||
out += cbInFullBlocks;
|
||||
outsize -= cbInFullBlocks;
|
||||
|
||||
if (p_scossl_aes_cfb_cipher_internal(
|
||||
ctx,
|
||||
SYMCRYPT_AES_BLOCK_SIZE,
|
||||
ctx->pbChainingValue,
|
||||
pbPartialBufOut, NULL, SYMCRYPT_AES_BLOCK_SIZE,
|
||||
ctx->buf, SYMCRYPT_AES_BLOCK_SIZE) != SCOSSL_SUCCESS)
|
||||
{
|
||||
return SCOSSL_FAILURE;
|
||||
}
|
||||
|
||||
memcpy(out, pbPartialBufOut, ctx->cbBuf);
|
||||
|
||||
// Since this was a partial block, the next update call will fill the buffer
|
||||
// and encrypt/decrypt with the same chaining value
|
||||
memcpy(ctx->pbChainingValue, pbChainingValueLast, SYMCRYPT_AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
static SCOSSL_STATUS scossl_aes_cfb8_cipher(_Inout_ SCOSSL_AES_CTX *ctx,
|
||||
_Out_writes_bytes_opt_(*outl) unsigned char *out, _Out_ size_t *outl, size_t outsize,
|
||||
_In_reads_bytes_(inl) const unsigned char *in, size_t inl)
|
||||
{
|
||||
return p_scossl_aes_cfb_cipher_internal(ctx, 1, out, outl, outsize, in, inl);
|
||||
return p_scossl_aes_cfb_cipher_internal(ctx, 1, ctx->pbChainingValue, out, outl, outsize, in, inl);
|
||||
}
|
||||
|
||||
#define IMPLEMENT_SCOSSL_AES_BLOCK_CIPHER(kbits, ivlen, lcmode, UCMODE) \
|
||||
#define IMPLEMENT_SCOSSL_AES_GENERIC_CIPHER(kbits, ivlen, lcmode, UCMODE, type) \
|
||||
SCOSSL_AES_CTX *p_scossl_aes_##kbits##_##lcmode##_newctx(_In_ SCOSSL_PROVCTX *provctx) \
|
||||
{ \
|
||||
SCOSSL_COMMON_ALIGNED_ALLOC(ctx, OPENSSL_malloc, SCOSSL_AES_CTX); \
|
||||
|
@ -812,8 +995,8 @@ static SCOSSL_STATUS scossl_aes_cfb8_cipher(_Inout_ SCOSSL_AES_CTX *ctx,
|
|||
{OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))p_scossl_aes_generic_freectx}, \
|
||||
{OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))p_scossl_aes_generic_encrypt_init}, \
|
||||
{OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))p_scossl_aes_generic_decrypt_init}, \
|
||||
{OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))p_scossl_aes_generic_update}, \
|
||||
{OSSL_FUNC_CIPHER_FINAL, (void (*)(void))p_scossl_aes_generic_final}, \
|
||||
{OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))p_scossl_aes_generic_##type##_update}, \
|
||||
{OSSL_FUNC_CIPHER_FINAL, (void (*)(void))p_scossl_aes_generic_##type##_final}, \
|
||||
{OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))p_scossl_aes_generic_cipher}, \
|
||||
{OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))p_scossl_aes_##kbits##_##lcmode##_get_params}, \
|
||||
{OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))p_scossl_aes_generic_get_ctx_params}, \
|
||||
|
@ -823,21 +1006,21 @@ static SCOSSL_STATUS scossl_aes_cfb8_cipher(_Inout_ SCOSSL_AES_CTX *ctx,
|
|||
{OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_aes_generic_settable_ctx_params}, \
|
||||
{0, NULL}};
|
||||
|
||||
IMPLEMENT_SCOSSL_AES_BLOCK_CIPHER(128, SYMCRYPT_AES_BLOCK_SIZE, cbc, CBC)
|
||||
IMPLEMENT_SCOSSL_AES_BLOCK_CIPHER(192, SYMCRYPT_AES_BLOCK_SIZE, cbc, CBC)
|
||||
IMPLEMENT_SCOSSL_AES_BLOCK_CIPHER(256, SYMCRYPT_AES_BLOCK_SIZE, cbc, CBC)
|
||||
IMPLEMENT_SCOSSL_AES_GENERIC_CIPHER(128, SYMCRYPT_AES_BLOCK_SIZE, cbc, CBC, block)
|
||||
IMPLEMENT_SCOSSL_AES_GENERIC_CIPHER(192, SYMCRYPT_AES_BLOCK_SIZE, cbc, CBC, block)
|
||||
IMPLEMENT_SCOSSL_AES_GENERIC_CIPHER(256, SYMCRYPT_AES_BLOCK_SIZE, cbc, CBC, block)
|
||||
|
||||
IMPLEMENT_SCOSSL_AES_BLOCK_CIPHER(128, 0, ecb, ECB)
|
||||
IMPLEMENT_SCOSSL_AES_BLOCK_CIPHER(192, 0, ecb, ECB)
|
||||
IMPLEMENT_SCOSSL_AES_BLOCK_CIPHER(256, 0, ecb, ECB)
|
||||
IMPLEMENT_SCOSSL_AES_GENERIC_CIPHER(128, 0, ecb, ECB, block)
|
||||
IMPLEMENT_SCOSSL_AES_GENERIC_CIPHER(192, 0, ecb, ECB, block)
|
||||
IMPLEMENT_SCOSSL_AES_GENERIC_CIPHER(256, 0, ecb, ECB, block)
|
||||
|
||||
IMPLEMENT_SCOSSL_AES_BLOCK_CIPHER(128, SYMCRYPT_AES_BLOCK_SIZE, cfb, CFB)
|
||||
IMPLEMENT_SCOSSL_AES_BLOCK_CIPHER(192, SYMCRYPT_AES_BLOCK_SIZE, cfb, CFB)
|
||||
IMPLEMENT_SCOSSL_AES_BLOCK_CIPHER(256, SYMCRYPT_AES_BLOCK_SIZE, cfb, CFB)
|
||||
IMPLEMENT_SCOSSL_AES_GENERIC_CIPHER(128, SYMCRYPT_AES_BLOCK_SIZE, cfb, CFB, stream)
|
||||
IMPLEMENT_SCOSSL_AES_GENERIC_CIPHER(192, SYMCRYPT_AES_BLOCK_SIZE, cfb, CFB, stream)
|
||||
IMPLEMENT_SCOSSL_AES_GENERIC_CIPHER(256, SYMCRYPT_AES_BLOCK_SIZE, cfb, CFB, stream)
|
||||
|
||||
IMPLEMENT_SCOSSL_AES_BLOCK_CIPHER(128, SYMCRYPT_AES_BLOCK_SIZE, cfb8, CFB)
|
||||
IMPLEMENT_SCOSSL_AES_BLOCK_CIPHER(192, SYMCRYPT_AES_BLOCK_SIZE, cfb8, CFB)
|
||||
IMPLEMENT_SCOSSL_AES_BLOCK_CIPHER(256, SYMCRYPT_AES_BLOCK_SIZE, cfb8, CFB)
|
||||
IMPLEMENT_SCOSSL_AES_GENERIC_CIPHER(128, SYMCRYPT_AES_BLOCK_SIZE, cfb8, CFB, stream)
|
||||
IMPLEMENT_SCOSSL_AES_GENERIC_CIPHER(192, SYMCRYPT_AES_BLOCK_SIZE, cfb8, CFB, stream)
|
||||
IMPLEMENT_SCOSSL_AES_GENERIC_CIPHER(256, SYMCRYPT_AES_BLOCK_SIZE, cfb8, CFB, stream)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ static const OSSL_PARAM p_scossl_ecc_keymgmt_gettable_param_types[] = {
|
|||
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, NULL, 0),
|
||||
OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0),
|
||||
OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_PUB_X, NULL, 0),
|
||||
OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_PUB_Y, NULL, 0),
|
||||
OSSL_PARAM_END};
|
||||
|
||||
static const OSSL_PARAM p_scossl_ecc_keymgmt_settable_param_types[] = {
|
||||
|
@ -461,6 +463,85 @@ cleanup:
|
|||
return keyCtx;
|
||||
}
|
||||
|
||||
static SCOSSL_STATUS p_scossl_ecc_keymgmt_get_pubkey_point(_In_ SCOSSL_ECC_KEY_CTX *keyCtx, _Inout_ OSSL_PARAM params[])
|
||||
{
|
||||
PBYTE pbPublicKey = NULL;
|
||||
SIZE_T cbPublicKey;
|
||||
BIGNUM *bnPubX = NULL;
|
||||
BIGNUM *bnPubY = NULL;
|
||||
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
|
||||
SCOSSL_STATUS ret = SCOSSL_FAILURE;
|
||||
|
||||
OSSL_PARAM *paramPubX = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_X);
|
||||
OSSL_PARAM *paramPubY = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_Y);
|
||||
|
||||
if (paramPubX == NULL &&
|
||||
paramPubY == NULL)
|
||||
{
|
||||
return SCOSSL_SUCCESS;
|
||||
}
|
||||
|
||||
cbPublicKey = SymCryptEckeySizeofPublicKey(keyCtx->key, SYMCRYPT_ECPOINT_FORMAT_XY);
|
||||
|
||||
if ((pbPublicKey = OPENSSL_malloc(cbPublicKey)) == NULL)
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
scError = SymCryptEckeyGetValue(
|
||||
keyCtx->key,
|
||||
NULL, 0,
|
||||
pbPublicKey, cbPublicKey,
|
||||
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
|
||||
SYMCRYPT_ECPOINT_FORMAT_XY,
|
||||
0 );
|
||||
if (scError != SYMCRYPT_NO_ERROR)
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (paramPubX != NULL)
|
||||
{
|
||||
if ((bnPubX = BN_bin2bn(pbPublicKey, cbPublicKey/2, NULL)) == NULL)
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!OSSL_PARAM_set_BN(paramPubX, bnPubX))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (paramPubY != NULL)
|
||||
{
|
||||
if ((bnPubY = BN_bin2bn(pbPublicKey + (cbPublicKey/2), cbPublicKey/2, NULL)) == NULL)
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!OSSL_PARAM_set_BN(paramPubY, bnPubY))
|
||||
{
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
ret = SCOSSL_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
OPENSSL_free(pbPublicKey);
|
||||
BN_free(bnPubX);
|
||||
BN_free(bnPubY);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static SCOSSL_STATUS p_scossl_ecc_keymgmt_get_params(_In_ SCOSSL_ECC_KEY_CTX *keyCtx, _Inout_ OSSL_PARAM params[])
|
||||
{
|
||||
PBYTE pbEncodedKey = NULL;
|
||||
|
@ -571,6 +652,11 @@ static SCOSSL_STATUS p_scossl_ecc_keymgmt_get_params(_In_ SCOSSL_ECC_KEY_CTX *ke
|
|||
// General ECDH only
|
||||
if (!keyCtx->isX25519)
|
||||
{
|
||||
if (!p_scossl_ecc_keymgmt_get_pubkey_point(keyCtx, params))
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL &&
|
||||
!OSSL_PARAM_set_utf8_string(p, SCOSSL_ECC_DEFAULT_DIGEST))
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче