* 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:
Maxwell McKee 2024-08-15 16:01:33 -04:00 коммит произвёл GitHub
Родитель ab6d48fbc9
Коммит 81bfe457ed
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
2 изменённых файлов: 305 добавлений и 36 удалений

Просмотреть файл

@ -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))
{