* Return correct ctx in kmac_dupctx

* Correct error check in dh export

* Support RSA algorithm ID parameter

* Support OSSL_PKEY_PARAM_EC_ENCODING parameter

* Support algorithm ID in ECDSA

* Track DH group independant of key

* Add libcrypto as link target for provider

* DH fixes for SSL layer

* Support TLS mode for AES block ciphers and styling

* PR comments
This commit is contained in:
Maxwell McKee 2024-04-24 16:51:22 -07:00 коммит произвёл GitHub
Родитель 2ef3602ece
Коммит ef91a8827e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
14 изменённых файлов: 970 добавлений и 214 удалений

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

@ -18,10 +18,10 @@ SCOSSL_DH_KEY_CTX *scossl_dh_new_key_ctx(void);
void scossl_dh_free_key_ctx(_Inout_ SCOSSL_DH_KEY_CTX *ctx);
SCOSSL_DH_KEY_CTX *scossl_dh_dup_key_ctx(_In_ SCOSSL_DH_KEY_CTX *ctx, BOOL copyGroup);
SCOSSL_STATUS scossl_dh_import_keypair(_Inout_ SCOSSL_DH_KEY_CTX *ctx, UINT32 nBitsPriv,
SCOSSL_STATUS scossl_dh_import_keypair(_Inout_ SCOSSL_DH_KEY_CTX *ctx, int nBitsPriv,
_In_ PCSYMCRYPT_DLGROUP pDlgroup, BOOL skipGroupValidation,
_In_ const BIGNUM *privateKey, _In_ const BIGNUM *publicKey);
SCOSSL_STATUS scossl_dh_generate_keypair(_Inout_ SCOSSL_DH_KEY_CTX *ctx, UINT32 nBitsPriv,
SCOSSL_STATUS scossl_dh_generate_keypair(_Inout_ SCOSSL_DH_KEY_CTX *ctx, int nBitsPriv,
_In_ PCSYMCRYPT_DLGROUP pDlgroup);
SCOSSL_STATUS scossl_dh_init_static(void);

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

@ -38,6 +38,13 @@ void scossl_dh_free_key_ctx(SCOSSL_DH_KEY_CTX *ctx)
SCOSSL_DH_KEY_CTX *scossl_dh_dup_key_ctx(SCOSSL_DH_KEY_CTX *ctx, BOOL copyGroup)
{
PBYTE pbData = NULL;
SIZE_T cbData = 0;
PBYTE pbPrivateKey;
SIZE_T cbPrivateKey;
PBYTE pbPublicKey;
SIZE_T cbPublicKey;
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
SCOSSL_STATUS success = SCOSSL_FAILURE;
SCOSSL_DH_KEY_CTX *copyCtx = OPENSSL_malloc(sizeof(SCOSSL_DH_KEY_CTX));
PSYMCRYPT_DLGROUP pDlgroupCopy = NULL;
@ -79,9 +86,44 @@ SCOSSL_DH_KEY_CTX *scossl_dh_dup_key_ctx(SCOSSL_DH_KEY_CTX *ctx, BOOL copyGroup)
{
goto cleanup;
}
else
// SymCryptDlkeyCopy expects the private key to be allocated
// The private key is only allocated with a call to SymCryptDlkeySetValue
// or SymCryptDlkeyGenerate, so instead we need to copy the key
cbPublicKey = SymCryptDlkeySizeofPublicKey(ctx->dlkey);
cbPrivateKey = SymCryptDlkeySizeofPrivateKey(ctx->dlkey);
cbData = cbPublicKey + cbPrivateKey;
if ((pbData = OPENSSL_secure_malloc(cbData)) == NULL)
{
SymCryptDlkeyCopy(ctx->dlkey, copyCtx->dlkey);
goto cleanup;
}
pbPublicKey = pbData;
pbPrivateKey = pbData + cbPublicKey;
scError = SymCryptDlkeyGetValue(
ctx->dlkey,
pbPrivateKey, cbPrivateKey,
pbPublicKey, cbPublicKey,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0);
if (scError != SYMCRYPT_NO_ERROR)
{
goto cleanup;
}
scError = SymCryptDlkeySetValue(
pbPrivateKey, cbPrivateKey,
pbPublicKey, cbPublicKey,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
SYMCRYPT_FLAG_DLKEY_DH | SYMCRYPT_FLAG_KEY_NO_FIPS, // Don't need to re-check group
copyCtx->dlkey);
if (scError != SYMCRYPT_NO_ERROR)
{
goto cleanup;
}
}
else
@ -102,11 +144,16 @@ cleanup:
copyCtx = NULL;
}
if (cbData > 0)
{
OPENSSL_secure_clear_free(pbData, cbData);
}
return copyCtx;
}
_Use_decl_annotations_
SCOSSL_STATUS scossl_dh_import_keypair(SCOSSL_DH_KEY_CTX *ctx, UINT32 nBitsPriv,
SCOSSL_STATUS scossl_dh_import_keypair(SCOSSL_DH_KEY_CTX *ctx, int nBitsPriv,
PCSYMCRYPT_DLGROUP pDlgroup, BOOL skipGroupValidation,
const BIGNUM *privateKey, const BIGNUM *publicKey)
{
@ -133,7 +180,7 @@ SCOSSL_STATUS scossl_dh_import_keypair(SCOSSL_DH_KEY_CTX *ctx, UINT32 nBitsPriv,
goto cleanup;
}
if (nBitsPriv != 0)
if (nBitsPriv > 0)
{
scError = SymCryptDlkeySetPrivateKeyLength(ctx->dlkey, nBitsPriv, 0);
if (scError != SYMCRYPT_NO_ERROR)
@ -234,7 +281,7 @@ cleanup:
}
_Use_decl_annotations_
SCOSSL_STATUS scossl_dh_generate_keypair(SCOSSL_DH_KEY_CTX *ctx, UINT32 nBitsPriv, PCSYMCRYPT_DLGROUP pDlgroup)
SCOSSL_STATUS scossl_dh_generate_keypair(SCOSSL_DH_KEY_CTX *ctx, int nBitsPriv, PCSYMCRYPT_DLGROUP pDlgroup)
{
SCOSSL_STATUS ret = SCOSSL_FAILURE;
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
@ -247,7 +294,7 @@ SCOSSL_STATUS scossl_dh_generate_keypair(SCOSSL_DH_KEY_CTX *ctx, UINT32 nBitsPri
goto cleanup;
}
if (nBitsPriv != 0)
if (nBitsPriv > 0)
{
scError = SymCryptDlkeySetPrivateKeyLength(ctx->dlkey, nBitsPriv, 0);
if (scError != SYMCRYPT_NO_ERROR)

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

@ -56,6 +56,7 @@ set_target_properties(scossl_provider PROPERTIES OUTPUT_NAME "symcryptprovider")
target_link_libraries(scossl_provider PRIVATE scossl_common)
target_link_libraries(scossl_provider PUBLIC ${SYMCRYPT_LIBRARY})
target_link_libraries(scossl_provider PUBLIC ${OPENSSL_CRYPTO_LIBRARY})
set(OPENSSL_PROVIDERS CACHE PATH "Path to OpenSSL providers" "${CMAKE_INSTALL_LIBDIR}/ossl-modules")

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

@ -5,8 +5,10 @@
#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>
#include <openssl/proverr.h>
#include <openssl/prov_ssl.h>
#include "scossl_helpers.h"
#include "p_scossl_base.h"
#include "p_scossl_aes.h"
#ifdef __cplusplus
@ -31,6 +33,8 @@ static const OSSL_PARAM p_scossl_aes_generic_gettable_ctx_param_types[] = {
static const OSSL_PARAM p_scossl_aes_generic_settable_ctx_param_types[] = {
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL),
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS_VERSION, NULL),
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS_MAC_SIZE, NULL),
OSSL_PARAM_END};
typedef struct
@ -40,14 +44,19 @@ typedef struct
BYTE iv[SYMCRYPT_AES_BLOCK_SIZE];
BYTE pbChainingValue[SYMCRYPT_AES_BLOCK_SIZE];
INT32 encrypt;
INT32 pad;
BOOL encrypt;
BOOL pad;
// Provider is responsible for buffering
// incomplete blocks in update calls
BYTE buf[SYMCRYPT_AES_BLOCK_SIZE];
SIZE_T cbBuf;
OSSL_LIB_CTX *libctx;
UINT tlsVersion;
PBYTE tlsMac;
SIZE_T tlsMacSize;
OSSL_FUNC_cipher_cipher_fn *cipher;
} SCOSSL_AES_CTX;
@ -55,21 +64,31 @@ static SCOSSL_STATUS p_scossl_aes_generic_set_ctx_params(_Inout_ SCOSSL_AES_CTX
static void p_scossl_aes_generic_freectx(SCOSSL_AES_CTX *ctx)
{
OPENSSL_free(ctx->tlsMac);
SCOSSL_COMMON_ALIGNED_FREE(ctx, OPENSSL_clear_free, SCOSSL_AES_CTX);
}
static SCOSSL_AES_CTX *p_scossl_aes_generic_dupctx(SCOSSL_AES_CTX *ctx)
{
SCOSSL_COMMON_ALIGNED_ALLOC(copy_ctx, OPENSSL_malloc, SCOSSL_AES_CTX);
if (copy_ctx != NULL)
{
memcpy(copy_ctx, ctx, sizeof(SCOSSL_AES_CTX));
SymCryptAesKeyCopy(&ctx->key, &copy_ctx->key);
SCOSSL_COMMON_ALIGNED_ALLOC(copyCtx, OPENSSL_malloc, SCOSSL_AES_CTX);
if (copyCtx != NULL)
{
*copyCtx = *ctx;
if (ctx->tlsMac != NULL &&
(copyCtx->tlsMac = OPENSSL_memdup(ctx->tlsMac, ctx->tlsMacSize)) == NULL)
{
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
p_scossl_aes_generic_freectx(copyCtx);
return NULL;
}
SymCryptAesKeyCopy(&ctx->key, &copyCtx->key);
}
return copy_ctx;
return copyCtx;
}
static SCOSSL_STATUS p_scossl_aes_generic_init_internal(_Inout_ SCOSSL_AES_CTX *ctx, INT32 encrypt,
static SCOSSL_STATUS p_scossl_aes_generic_init_internal(_Inout_ SCOSSL_AES_CTX *ctx, BOOL encrypt,
_In_reads_bytes_opt_(keylen) const unsigned char *key, size_t keylen,
_In_reads_bytes_opt_(ivlen) const unsigned char *iv, size_t ivlen,
_In_ const OSSL_PARAM params[])
@ -112,7 +131,7 @@ static SCOSSL_STATUS p_scossl_aes_generic_encrypt_init(_Inout_ SCOSSL_AES_CTX *c
_In_reads_bytes_opt_(ivlen) const unsigned char *iv, size_t ivlen,
_In_ const OSSL_PARAM params[])
{
return p_scossl_aes_generic_init_internal(ctx, 1, key, keylen, iv, ivlen, params);
return p_scossl_aes_generic_init_internal(ctx, TRUE, key, keylen, iv, ivlen, params);
}
static SCOSSL_STATUS p_scossl_aes_generic_decrypt_init(_Inout_ SCOSSL_AES_CTX *ctx,
@ -120,7 +139,101 @@ static SCOSSL_STATUS p_scossl_aes_generic_decrypt_init(_Inout_ SCOSSL_AES_CTX *c
_In_reads_bytes_opt_(ivlen) const unsigned char *iv, size_t ivlen,
_In_ const OSSL_PARAM params[])
{
return p_scossl_aes_generic_init_internal(ctx, 0, key, keylen, iv, ivlen, params);
return p_scossl_aes_generic_init_internal(ctx, FALSE, key, keylen, iv, ivlen, params);
}
#define SYMCRYPT_OPENSSL_MASK8_SELECT( _mask, _a, _b ) (SYMCRYPT_FORCE_READ8(&_mask) & _a) | (~(SYMCRYPT_FORCE_READ8(&_mask)) & _b)
// Extracts the MAC from the end of out and saves the result to ctx->tlsMac
// The mac will later be fetched through p_scossl_aes_generic_get_ctx_params
// This function is adapted from ssl3_cbc_copy_mac in ssl/record/tls_pad.c
// and runs in constant time. In case of bad padding, a random MAC is assigned instead
static SCOSSL_STATUS p_scossl_aes_copy_mac(_Inout_ SCOSSL_AES_CTX *ctx,
_In_reads_bytes_(buflen) unsigned char *record, _Inout_ SIZE_T *recordLen,
SIZE_T recordLenPadded,
SCOSSL_STATUS paddingStatus)
{
// MAC rotation is performed in place
BYTE rotatedMacBuf[64 + EVP_MAX_MD_SIZE];
PBYTE rotatedMac;
BYTE aux1, aux2, aux3, mask;
BYTE paddingStatusByte = (BYTE) (paddingStatus & 0xff);
// Random mac set in case padding removal failed
BYTE randMac[EVP_MAX_MD_SIZE];
UINT32 macEnd = *record;
UINT32 macStart = macEnd - ctx->tlsMacSize;
UINT32 inMac;
UINT32 scanStart = 0;
UINT32 rotateOffset;
UINT32 i, j;
OPENSSL_free(ctx->tlsMac);
ctx->tlsMac = NULL;
// Public info, safe to branch
// No mac to copy
if (ctx->tlsMacSize == 0)
{
return paddingStatus;
}
*recordLen -= ctx->tlsMacSize;
// Generate random bytes in case of bad padding
if (RAND_bytes_ex(ctx->libctx, randMac, ctx->tlsMacSize, 0) <= 0)
{
return SCOSSL_FAILURE;
}
if ((ctx->tlsMac = OPENSSL_malloc(ctx->tlsMacSize)) == NULL)
{
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
return SCOSSL_FAILURE;
}
rotatedMac = rotatedMacBuf + ((0 - (SIZE_T)rotatedMacBuf) & 0x3f);
// Public info, safe to branch
if (recordLenPadded > ctx->tlsMacSize + 255 + 1)
{
scanStart = recordLenPadded - (ctx->tlsMacSize + 255 + 1);
}
// Find and extract MAC
memset(rotatedMac, 0, ctx->tlsMacSize);
for (i = scanStart, j = 0; i < recordLenPadded; i++)
{
UINT32 macStarted = SYMCRYPT_MASK32_EQ(i, macStart);
UINT32 macEnded = SYMCRYPT_MASK32_LT(i, macEnd);
BYTE recordByte = record[i];
inMac = (inMac | macStarted) & macEnded;
rotateOffset |= j & macStarted;
rotatedMac[j++] |= recordByte & inMac;
j &= SYMCRYPT_MASK32_LT(j, ctx->tlsMacSize);
}
// MAC rotation
for (i = 0, j = 0; i < ctx->tlsMacSize; i++)
{
// in case cache-line is 32 bytes, load from both lines and select appropriately
aux1 = rotatedMac[rotateOffset & ~0x20];
aux2 = rotatedMac[rotateOffset | 0x20];
mask = (BYTE) SYMCRYPT_MASK32_EQ(rotateOffset & !0x20, rotateOffset);
aux3 = SYMCRYPT_OPENSSL_MASK8_SELECT(mask, aux1, aux2);
ctx->tlsMac[j++] = SYMCRYPT_OPENSSL_MASK8_SELECT(paddingStatusByte, aux3, randMac[i]);
rotateOffset++;
rotateOffset = (rotateOffset & SYMCRYPT_MASK32_LT(rotateOffset, ctx->tlsMacSize));
}
// If we failed, we still succeed, but the MAC is set to some
// random value. It's up to the caller to check the MAC.
return SCOSSL_SUCCESS;
}
static SCOSSL_STATUS p_scossl_aes_generic_update(_Inout_ SCOSSL_AES_CTX *ctx,
@ -135,6 +248,82 @@ static SCOSSL_STATUS p_scossl_aes_generic_update(_Inout_ SCOSSL_AES_CTX *ctx,
return SCOSSL_SUCCESS;
}
if (ctx->tlsVersion > 0)
{
// Each update call corresponds to a TLS record and is individually padded
if (in == NULL ||
in != out ||
outsize < inl ||
!ctx->pad)
{
ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
return SCOSSL_FAILURE;
}
if (ctx->encrypt)
{
// in == out
SymCryptPaddingPkcs7Add(
SYMCRYPT_AES_BLOCK_SIZE,
in, inl,
out, outsize, &inl);
}
if (inl % SYMCRYPT_AES_BLOCK_SIZE != 0 ||
!ctx->cipher(ctx, out, outl, outsize, in, inl))
{
ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH);
return SCOSSL_FAILURE;
}
// Need to remove padding and mac in constant time
if (!ctx->encrypt)
{
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
// Return SCOSSL_FAILURE for any code that isn't SYMCRYPT_NO_ERROR
SYMCRYPT_UINT32_MAP scErrorMap[1] = {
{SYMCRYPT_NO_ERROR, SCOSSL_SUCCESS}};
switch (ctx->tlsVersion)
{
// Need to remove explicit IV in addition to pkcs7 padding and mac
case TLS1_2_VERSION:
case DTLS1_2_VERSION:
case TLS1_1_VERSION:
case DTLS1_VERSION:
case DTLS1_BAD_VER:
out += SYMCRYPT_AES_BLOCK_SIZE;
*outl -= SYMCRYPT_AES_BLOCK_SIZE;
__attribute__ ((fallthrough));
case TLS1_VERSION:
SIZE_T outlPadded = *outl;
if (ctx->tlsMacSize > *outl)
{
ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
return SCOSSL_FAILURE;
}
scError = SymCryptPaddingPkcs7Remove(
SYMCRYPT_AES_BLOCK_SIZE,
out, *outl,
out, *outl,
outl);
return p_scossl_aes_copy_mac(ctx,
out, outl,
outlPadded,
SymCryptMapUint32(scError, SCOSSL_FAILURE, scErrorMap, 1));
break;
default:
ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
return SCOSSL_FAILURE;
}
}
// Return SCOSSL_FAILURE for any code that isn't SYMCRYPT_NO_ERROR
return SCOSSL_SUCCESS;
}
// Data from previous update in buffer. Try to fill buffer and
// encrypt/decrypt before moving to remaining data.
if (ctx->cbBuf > 0)
@ -179,13 +368,13 @@ static SCOSSL_STATUS p_scossl_aes_generic_update(_Inout_ SCOSSL_AES_CTX *ctx,
// 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 &&
if (!ctx->encrypt &&
ctx->pad &&
cbBytesInFullBlocks > 0 &&
cbBytesInFullBlocks == inl)
{
cbBytesInFullBlocks -= SYMCRYPT_AES_BLOCK_SIZE;
}
}
// in still contains whole blocks, encrypt available blocks
if (cbBytesInFullBlocks > 0)
@ -204,7 +393,7 @@ static SCOSSL_STATUS p_scossl_aes_generic_update(_Inout_ SCOSSL_AES_CTX *ctx,
// Buffer any remaining data
if (inl > 0)
{
// Ensure trailing remaining data is
// Ensure trailing remaining data is
// - less than one block for encryption or unpadded decryption
// - less than or equal to one block for padded decryption
if (inl > SYMCRYPT_AES_BLOCK_SIZE ||
@ -216,7 +405,7 @@ static SCOSSL_STATUS p_scossl_aes_generic_update(_Inout_ SCOSSL_AES_CTX *ctx,
memcpy(ctx->buf, in, inl);
ctx->cbBuf += inl;
}
// Buffer must have some data in it for padded decryption
if (!ctx->encrypt && ctx->pad && ctx->cbBuf == 0)
{
@ -230,6 +419,12 @@ static SCOSSL_STATUS p_scossl_aes_generic_update(_Inout_ SCOSSL_AES_CTX *ctx,
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)
{
if (ctx->tlsVersion > 0)
{
ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
return 0;
}
// Unpadded case
if (!ctx->pad)
{
@ -267,10 +462,8 @@ static SCOSSL_STATUS p_scossl_aes_generic_final(_Inout_ SCOSSL_AES_CTX *ctx,
SymCryptPaddingPkcs7Add(
SYMCRYPT_AES_BLOCK_SIZE,
ctx->buf,
ctx->cbBuf,
ctx->buf,
SYMCRYPT_AES_BLOCK_SIZE,
ctx->buf, ctx->cbBuf,
ctx->buf, SYMCRYPT_AES_BLOCK_SIZE,
&ctx->cbBuf);
}
@ -293,10 +486,8 @@ static SCOSSL_STATUS p_scossl_aes_generic_final(_Inout_ SCOSSL_AES_CTX *ctx,
{
scError = SymCryptPaddingPkcs7Remove(
SYMCRYPT_AES_BLOCK_SIZE,
out,
SYMCRYPT_AES_BLOCK_SIZE,
out,
SYMCRYPT_AES_BLOCK_SIZE,
out, SYMCRYPT_AES_BLOCK_SIZE,
out, SYMCRYPT_AES_BLOCK_SIZE,
outl);
}
else
@ -350,42 +541,48 @@ SCOSSL_STATUS p_scossl_aes_generic_get_params(_Inout_ OSSL_PARAM params[],
OSSL_PARAM *p = NULL;
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE);
if (p != NULL && !OSSL_PARAM_set_uint(p, mode))
if ((p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE)) != NULL &&
!OSSL_PARAM_set_uint(p, mode))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
if (p != NULL && !OSSL_PARAM_set_size_t(p, keylen))
if ((p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN)) != NULL &&
!OSSL_PARAM_set_size_t(p, keylen))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
if (p != NULL && !OSSL_PARAM_set_size_t(p, ivlen))
if ((p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN)) != NULL &&
!OSSL_PARAM_set_size_t(p, ivlen))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE);
if (p != NULL && !OSSL_PARAM_set_size_t(p, block_size))
if ((p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE)) != NULL &&
!OSSL_PARAM_set_size_t(p, block_size))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD);
if (p != NULL && !OSSL_PARAM_set_int(p, flags & SCOSSL_FLAG_AEAD ? 1 : 0))
if ((p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD)) != NULL &&
!OSSL_PARAM_set_int(p, flags & SCOSSL_FLAG_AEAD ? 1 : 0))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV);
if (p != NULL && !OSSL_PARAM_set_int(p, flags & SCOSSL_FLAG_CUSTOM_IV ? 1 : 0))
if ((p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV)) != NULL &&
!OSSL_PARAM_set_int(p, flags & SCOSSL_FLAG_CUSTOM_IV ? 1 : 0))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
return SCOSSL_SUCCESS;
}
@ -393,34 +590,43 @@ static SCOSSL_STATUS p_scossl_aes_generic_get_ctx_params(_In_ SCOSSL_AES_CTX *ct
{
OSSL_PARAM *p = NULL;
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen))
if ((p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN)) != NULL &&
!OSSL_PARAM_set_size_t(p, ctx->keylen))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
if (p != NULL && !OSSL_PARAM_set_size_t(p, SYMCRYPT_AES_BLOCK_SIZE))
if ((p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN)) != NULL &&
!OSSL_PARAM_set_size_t(p, SYMCRYPT_AES_BLOCK_SIZE))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
if (p != NULL &&
if ((p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV)) != NULL &&
!OSSL_PARAM_set_octet_ptr(p, &ctx->iv, SYMCRYPT_AES_BLOCK_SIZE) &&
!OSSL_PARAM_set_octet_string(p, &ctx->iv, SYMCRYPT_AES_BLOCK_SIZE))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV);
if (p != NULL &&
if ((p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV)) != NULL &&
!OSSL_PARAM_set_octet_ptr(p, &ctx->pbChainingValue, SYMCRYPT_AES_BLOCK_SIZE) &&
!OSSL_PARAM_set_octet_string(p, &ctx->pbChainingValue, SYMCRYPT_AES_BLOCK_SIZE))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
if ((p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS_MAC)) != NULL &&
!OSSL_PARAM_set_octet_ptr(p, ctx->tlsMac, ctx->tlsMacSize))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
return SCOSSL_SUCCESS;
}
@ -428,8 +634,7 @@ static SCOSSL_STATUS p_scossl_aes_generic_set_ctx_params(_Inout_ SCOSSL_AES_CTX
{
const OSSL_PARAM *p = NULL;
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_PADDING);
if (p != NULL)
if ((p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_PADDING)) != NULL)
{
unsigned int pad;
@ -438,7 +643,45 @@ static SCOSSL_STATUS p_scossl_aes_generic_set_ctx_params(_Inout_ SCOSSL_AES_CTX
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
}
ctx->pad = pad ? 1 : 0;
ctx->pad = pad != 0;
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_VERSION)) != NULL)
{
UINT tlsVersion;
if (!OSSL_PARAM_get_uint(p, &tlsVersion))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
}
if (tlsVersion == SSL3_VERSION)
{
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED);
return SCOSSL_FAILURE;
}
ctx->tlsVersion = tlsVersion;
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_MAC_SIZE)) != NULL)
{
SIZE_T tlsMacSize;
if (!OSSL_PARAM_get_size_t(p, &tlsMacSize))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
}
if (ctx->tlsMacSize > EVP_MAX_MD_SIZE)
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MAC);
return SCOSSL_FAILURE;
}
ctx->tlsMacSize = tlsMacSize;
}
return SCOSSL_SUCCESS;
@ -529,25 +772,29 @@ 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);
return p_scossl_aes_cfb_cipher_internal(ctx, SYMCRYPT_AES_BLOCK_SIZE, out, outl, outsize, in, inl);
}
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, out, outl, outsize, in, inl);
}
#define IMPLEMENT_SCOSSL_AES_BLOCK_CIPHER(kbits, ivlen, lcmode, UCMODE) \
SCOSSL_AES_CTX *p_scossl_aes_##kbits##_##lcmode##_newctx() \
SCOSSL_AES_CTX *p_scossl_aes_##kbits##_##lcmode##_newctx(_In_ SCOSSL_PROVCTX *provctx) \
{ \
SCOSSL_COMMON_ALIGNED_ALLOC(ctx, OPENSSL_malloc, SCOSSL_AES_CTX); \
if (ctx != NULL) \
{ \
ctx->keylen = kbits >> 3; \
ctx->pad = 1; \
ctx->pad = TRUE; \
ctx->cipher = (OSSL_FUNC_cipher_cipher_fn *)&scossl_aes_##lcmode##_cipher; \
ctx->libctx = provctx->libctx; \
ctx->tlsMac = NULL; \
ctx->tlsMacSize = 0; \
ctx->tlsVersion = 0; \
} \
\
return ctx; \

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

@ -132,7 +132,6 @@ static SCOSSL_STATUS p_scossl_dh_init(_In_ SCOSSL_DH_CTX *ctx, _In_ SCOSSL_PROV_
static SCOSSL_STATUS p_scossl_dh_set_peer(_Inout_ SCOSSL_DH_CTX *ctx, _In_ SCOSSL_PROV_DH_KEY_CTX *peerProvKey)
{
if (ctx == NULL || peerProvKey == NULL)
{
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);

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

@ -12,10 +12,13 @@ extern "C" {
typedef struct
{
// Provider needs to support importing group by parameters.
// This is only set if the group has been imported by parameters
// and needs to be freed.
// pDlGroup may be set by params, or reference a static, known
// named group. If the group is loaded from params it must be
// freed when the context is freed.
PSYMCRYPT_DLGROUP pDlGroup;
SCOSSL_DH_KEY_CTX *keyCtx;
BOOL groupSetByParams;
int nBitsPriv;
OSSL_LIB_CTX *libCtx;
} SCOSSL_PROV_DH_KEY_CTX;

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

@ -15,6 +15,9 @@ extern "C" {
#define SCOSSL_DH_KEYHEN_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)
#define SCOSSL_DH_PBITS_DEFAULT 2048
// Private key length determined by group
// Setting this to -1 matches the OpenSSL implementation for paramater fetching
#define SCOSSL_DH_PRIVATE_BITS_DEFAULT -1
#define SCOSSL_DH_FFC_TYPE_DEFAULT "default"
#define SCOSSL_DH_FFC_TYPE_GROUP "group"
@ -28,8 +31,8 @@ typedef struct
{
SCOSSL_PROVCTX *provCtx;
PCSYMCRYPT_DLGROUP pDlGroup;
SIZE_T pbits;
UINT32 nBitsPriv;
SIZE_T nBitsPub;
int nBitsPriv;
} SCOSSL_DH_KEYGEN_CTX;
#define SCOSSL_DH_PARAMETER_TYPES \
@ -74,7 +77,9 @@ static const OSSL_PARAM *p_scossl_dh_impexp_types[] = {
p_scossl_dh_pkey_types,
p_scossl_dh_all_types};
// Gettable/settable key types
static const OSSL_PARAM p_scossl_dh_keymgmt_settable_param_types[] = {
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
OSSL_PARAM_END};
static const OSSL_PARAM p_scossl_dh_keymgmt_gettable_param_types[] = {
OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
@ -105,6 +110,8 @@ static SCOSSL_PROV_DH_KEY_CTX *p_scossl_dh_keymgmt_new_ctx(_In_ SCOSSL_PROVCTX *
else
{
ctx->pDlGroup = NULL;
ctx->groupSetByParams = FALSE;
ctx->nBitsPriv = SCOSSL_DH_PRIVATE_BITS_DEFAULT;
ctx->libCtx = provCtx->libctx;
}
}
@ -118,22 +125,47 @@ static SCOSSL_PROV_DH_KEY_CTX *p_scossl_dh_keymgmt_dup_key_ctx(_In_ const SCOSSL
if (copyCtx != NULL)
{
if ((copyCtx->keyCtx = scossl_dh_dup_key_ctx(ctx->keyCtx, ctx->pDlGroup != NULL)) == NULL)
*copyCtx = *ctx;
if ((copyCtx->keyCtx = scossl_dh_dup_key_ctx(ctx->keyCtx, ctx->groupSetByParams)) == NULL)
{
OPENSSL_free(copyCtx);
return NULL;
}
// scossl_dh_dup_key_ctx performs a deep copy. If a custom group was set in ctx,
// then a new copy of that group is used by the key in copyCtx. We need to save this
// to copyCtx to ensure it properly gets freed.
if (copyCtx->keyCtx->initialized &&
ctx->pDlGroup != NULL)
// Group set by params means we need to copy the group, regardless of whether the
// key has been set
if (ctx->groupSetByParams)
{
copyCtx->pDlGroup = (PSYMCRYPT_DLGROUP) SymCryptDlkeyGetGroup(copyCtx->keyCtx->dlkey);
}
// scossl_dh_dup_key_ctx performs a deep copy. If a custom group was set in ctx,
// then a new copy of that group is used by the key in copyCtx. We need to save this
// to copyCtx to ensure it properly gets freed.
if (copyCtx->keyCtx->initialized)
{
copyCtx->pDlGroup = (PSYMCRYPT_DLGROUP) SymCryptDlkeyGetGroup(copyCtx->keyCtx->dlkey);
}
// No key was set, but we still need to copy the group from ctx
else
{
SIZE_T pcbPrimeP;
SIZE_T pcbPrimeQ;
copyCtx->libCtx = ctx->libCtx;
SymCryptDlgroupGetSizes(
ctx->pDlGroup,
&pcbPrimeP,
&pcbPrimeQ,
NULL,
NULL);
if ((copyCtx->pDlGroup = SymCryptDlgroupAllocate(pcbPrimeP, pcbPrimeQ)) == NULL)
{
OPENSSL_free(copyCtx);
return NULL;
}
SymCryptDlgroupCopy(ctx->pDlGroup, copyCtx->pDlGroup);
}
}
}
return copyCtx;
@ -146,12 +178,45 @@ static void p_scossl_dh_keymgmt_free_key_ctx(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx)
scossl_dh_free_key_ctx(ctx->keyCtx);
if (ctx->pDlGroup != NULL)
if (ctx->groupSetByParams)
{
SymCryptDlgroupFree(ctx->pDlGroup);
}
}
// Helper functions for retrieving public and private key size.
// ctx->keyCtx->dlkey may not be set, in which case the key size
// must be retrieved from ctx->pDlGroup
static int p_scossl_dh_pubkey_bits(SCOSSL_PROV_DH_KEY_CTX *ctx)
{
if (ctx->pDlGroup != NULL)
{
SIZE_T cbPrimeP;
SymCryptDlgroupGetSizes(
ctx->pDlGroup,
&cbPrimeP,
NULL,
NULL,
NULL);
return cbPrimeP * 8;
}
return -1;
}
static int p_scossl_dh_privkey_bits(SCOSSL_PROV_DH_KEY_CTX *ctx)
{
if (ctx->nBitsPriv > 0)
{
return ctx->nBitsPriv;
}
// Default max size is bits of P - 1
return p_scossl_dh_pubkey_bits(ctx) - 1;
}
// This function attempts to create a PSYMCRYPT_DLGROUP from params, and store the result in *ppDlGroup.
// If the group name is present, it will be the only thing used to fetch a known group. If the group is named
// but unknown, this will fail. If no group name is supplied, then the group parameters are used to create
@ -396,7 +461,7 @@ static SCOSSL_STATUS p_scossl_dh_keygen_set_params(_Inout_ SCOSSL_DH_KEYGEN_CTX
genCtx->pDlGroup = (PCSYMCRYPT_DLGROUP) pDlGroup;
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_PBITS)) != NULL &&
!OSSL_PARAM_get_size_t(p, &genCtx->pbits))
!OSSL_PARAM_get_size_t(p, &genCtx->nBitsPub))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
@ -411,15 +476,7 @@ static SCOSSL_STATUS p_scossl_dh_keygen_set_params(_Inout_ SCOSSL_DH_KEYGEN_CTX
return SCOSSL_FAILURE;
}
// SymCryptDlkeySetPrivateKeyLength will validate this key size.
// Here we just need to be sure we can safely cast to UINT32
if (nBitsPriv < 0)
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
return SCOSSL_FAILURE;
}
genCtx->nBitsPriv = (UINT32)nBitsPriv;
genCtx->nBitsPriv = nBitsPriv;
}
return SCOSSL_SUCCESS;
@ -447,8 +504,8 @@ static SCOSSL_DH_KEYGEN_CTX *p_scossl_dh_keygen_init(_In_ SCOSSL_PROVCTX *provCt
(genCtx = OPENSSL_malloc(sizeof(SCOSSL_DH_KEYGEN_CTX))) != NULL)
{
genCtx->pDlGroup = NULL;
genCtx->nBitsPriv = 0;
genCtx->pbits = SCOSSL_DH_PBITS_DEFAULT;
genCtx->nBitsPub = SCOSSL_DH_PBITS_DEFAULT;
genCtx->nBitsPriv = SCOSSL_DH_PRIVATE_BITS_DEFAULT;
genCtx->provCtx = provCtx;
if (!p_scossl_dh_keygen_set_params(genCtx, params))
@ -461,17 +518,38 @@ static SCOSSL_DH_KEYGEN_CTX *p_scossl_dh_keygen_init(_In_ SCOSSL_PROVCTX *provCt
return genCtx;
}
static SCOSSL_STATUS p_scossl_dh_keygen_set_template(_Inout_ SCOSSL_DH_KEYGEN_CTX *genCtx, _In_ SCOSSL_PROV_DH_KEY_CTX *tmplCtx)
{
if (genCtx == NULL ||
tmplCtx == NULL ||
tmplCtx->groupSetByParams)
{
return SCOSSL_FAILURE;
}
// DH keygen only supports named groups, which are all statically
// defined, so we can safely copy tmplCtx->pDlGroup by reference.
if (tmplCtx->pDlGroup != NULL)
{
genCtx->pDlGroup = tmplCtx->pDlGroup;
genCtx->nBitsPriv = tmplCtx->nBitsPriv;
genCtx->nBitsPub = p_scossl_dh_pubkey_bits(tmplCtx);
}
return SCOSSL_SUCCESS;
}
static SCOSSL_PROV_DH_KEY_CTX *p_scossl_dh_keygen(_In_ SCOSSL_DH_KEYGEN_CTX *genCtx, ossl_unused OSSL_CALLBACK *cb, ossl_unused void *cbarg)
{
SCOSSL_PROV_DH_KEY_CTX *ctx;
// Select named group based on pbits if named group was not explicitly set.
// Select named group based on nBitsPub if named group was not explicitly set.
// Note that the ffdhe group, not the modp group is used to match the behavior
// of the default openssl implementation.
if (genCtx->pDlGroup == NULL)
{
int dlGroupNid = 0;
switch(genCtx->pbits)
switch(genCtx->nBitsPub)
{
case 2048:
dlGroupNid = NID_ffdhe2048;
@ -503,32 +581,92 @@ static SCOSSL_PROV_DH_KEY_CTX *p_scossl_dh_keygen(_In_ SCOSSL_DH_KEYGEN_CTX *gen
return NULL;
}
ctx->pDlGroup = (PSYMCRYPT_DLGROUP) genCtx->pDlGroup;
return ctx;
}
static const OSSL_PARAM *p_scossl_dh_keymgmt_settable_params(ossl_unused void *provCtx)
{
return p_scossl_dh_keymgmt_settable_param_types;
}
static SCOSSL_STATUS p_scossl_dh_keymgmt_set_params(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx, _In_ const OSSL_PARAM params[])
{
const OSSL_PARAM *p;
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL)
{
SYMCRYPT_ERROR scError;
PCBYTE pbPublicKey;
SIZE_T cbPublicKey;
if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&pbPublicKey, &cbPublicKey))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
}
if (ctx->pDlGroup == NULL)
{
ERR_raise(ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET);
return SCOSSL_FAILURE;
}
if (ctx->keyCtx->initialized)
{
SymCryptDlkeyFree(ctx->keyCtx->dlkey);
ctx->keyCtx->initialized = FALSE;
}
if ((ctx->keyCtx->dlkey = SymCryptDlkeyAllocate(ctx->pDlGroup)) == NULL)
{
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
return SCOSSL_FAILURE;
}
scError = SymCryptDlkeySetValue(
NULL, 0,
pbPublicKey, cbPublicKey,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
SYMCRYPT_FLAG_DLKEY_DH,
ctx->keyCtx->dlkey);
if (scError != SYMCRYPT_NO_ERROR)
{
SymCryptDlkeyFree(ctx->keyCtx->dlkey);
ctx->keyCtx->dlkey = NULL;
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
return SCOSSL_FAILURE;
}
ctx->keyCtx->initialized = TRUE;
}
return SCOSSL_SUCCESS;
}
static const OSSL_PARAM *p_scossl_dh_keymgmt_gettable_params(ossl_unused void *provCtx)
{
return p_scossl_dh_keymgmt_gettable_param_types;
}
static SCOSSL_STATUS p_scossl_dh_keymgmt_get_ffc_params(_In_ SCOSSL_DH_KEY_CTX *keyCtx, _Inout_ OSSL_PARAM params[])
static SCOSSL_STATUS p_scossl_dh_keymgmt_get_ffc_params(_In_ SYMCRYPT_DLGROUP *pDlGroup, _Inout_ OSSL_PARAM params[])
{
SCOSSL_STATUS ret = SCOSSL_FAILURE;
PBYTE pbPrimeP;
PBYTE pbPrimeQ;
PBYTE pbGenG;
PBYTE pbSeed;
PBYTE pbPrimeP = NULL;
PBYTE pbPrimeQ = NULL;
PBYTE pbGenG = NULL;
PBYTE pbSeed = NULL;
PBYTE pbCur;
PBYTE pbData = NULL;
SIZE_T cbPrimeP;
SIZE_T cbPrimeQ;
SIZE_T cbGenG;
SIZE_T cbSeed;
SIZE_T cbPrimeP = 0;
SIZE_T cbPrimeQ = 0;
SIZE_T cbGenG = 0;
SIZE_T cbSeed = 0;
SIZE_T cbData = 0;
BIGNUM *bnPrimeP = NULL;
BIGNUM *bnPrimeQ = NULL;
BIGNUM *bnGenG = NULL;
PCSYMCRYPT_DLGROUP pDlGroup = SymCryptDlkeyGetGroup(keyCtx->dlkey);
OSSL_PARAM *p;
OSSL_PARAM *paramPrimeP = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_FFC_P);
OSSL_PARAM *paramPrimeQ = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_FFC_Q);
@ -589,37 +727,37 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_get_ffc_params(_In_ SCOSSL_DH_KEY_CTX *
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
goto cleanup;
}
}
if (pbPrimeP != NULL &&
(BN_bin2bn(pbPrimeP, cbPrimeP, bnPrimeP) == NULL ||
!OSSL_PARAM_set_BN(paramPrimeP, bnPrimeP)))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
if (pbPrimeP != NULL &&
(BN_bin2bn(pbPrimeP, cbPrimeP, bnPrimeP) == NULL ||
!OSSL_PARAM_set_BN(paramPrimeP, bnPrimeP)))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
if (pbPrimeQ != NULL &&
(BN_bin2bn(pbPrimeQ, cbPrimeQ, bnPrimeQ) == NULL ||
!OSSL_PARAM_set_BN(paramPrimeQ, bnPrimeQ)))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
if (pbPrimeQ != NULL &&
(BN_bin2bn(pbPrimeQ, cbPrimeQ, bnPrimeQ) == NULL ||
!OSSL_PARAM_set_BN(paramPrimeQ, bnPrimeQ)))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
if (pbGenG != NULL &&
(BN_bin2bn(pbGenG, cbGenG, bnGenG) == NULL ||
!OSSL_PARAM_set_BN(paramGenG, bnGenG)))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
if (pbGenG != NULL &&
(BN_bin2bn(pbGenG, cbGenG, bnGenG) == NULL ||
!OSSL_PARAM_set_BN(paramGenG, bnGenG)))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
if (pbSeed != NULL &&
!OSSL_PARAM_set_octet_string(paramSeed, pbSeed, cbSeed))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
if (pbSeed != NULL &&
!OSSL_PARAM_set_octet_string(paramSeed, pbSeed, cbSeed))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_FFC_GINDEX)) != NULL &&
@ -673,6 +811,19 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_get_key_params(_In_ SCOSSL_DH_KEY_CTX *
OSSL_PARAM *paramPrivKey = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PRIV_KEY);
OSSL_PARAM *paramPubKey = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY);
if (paramEncodedKey == NULL &&
paramPrivKey == NULL &&
paramPubKey == NULL)
{
return SCOSSL_SUCCESS;
}
if (!keyCtx->initialized)
{
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY);
return SCOSSL_FAILURE;
}
if (paramPrivKey != NULL)
{
cbPrivateKey = SymCryptDlkeySizeofPrivateKey(keyCtx->dlkey);
@ -766,9 +917,11 @@ cleanup:
static SCOSSL_STATUS p_scossl_dh_keymgmt_get_params(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx, _Inout_ OSSL_PARAM params[])
{
OSSL_PARAM *p;
int pubKeyBits = p_scossl_dh_pubkey_bits(ctx);
int privKeyBits = p_scossl_dh_privkey_bits(ctx);
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL &&
!OSSL_PARAM_set_int(p, SymCryptDlkeySizeofPublicKey(ctx->keyCtx->dlkey) * 8))
(pubKeyBits < 0 || !OSSL_PARAM_set_int(p, pubKeyBits)))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
@ -776,10 +929,9 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_get_params(_In_ SCOSSL_PROV_DH_KEY_CTX
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL)
{
int pubKeyBits = SymCryptDlkeySizeofPublicKey(ctx->keyCtx->dlkey) * 8;
int privKeyBits = SymCryptDlkeySizeofPrivateKey(ctx->keyCtx->dlkey) * 8;
if (!OSSL_PARAM_set_int(p, BN_security_bits(pubKeyBits, privKeyBits)))
if (pubKeyBits < 0 ||
privKeyBits < 0 ||
!OSSL_PARAM_set_int(p, BN_security_bits(pubKeyBits, privKeyBits)))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
@ -787,14 +939,14 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_get_params(_In_ SCOSSL_PROV_DH_KEY_CTX
}
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL &&
!OSSL_PARAM_set_int(p, SymCryptDlkeySizeofPublicKey(ctx->keyCtx->dlkey)))
(pubKeyBits < 0 || !OSSL_PARAM_set_int(p, pubKeyBits / 8)))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
}
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DH_PRIV_LEN)) != NULL &&
!OSSL_PARAM_set_int(p, SymCryptDlkeySizeofPrivateKey(ctx->keyCtx->dlkey) * 8))
(privKeyBits < 0 || !OSSL_PARAM_set_int(p, privKeyBits)))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
@ -816,7 +968,7 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_get_params(_In_ SCOSSL_PROV_DH_KEY_CTX
}
}
return p_scossl_dh_keymgmt_get_ffc_params(ctx->keyCtx, params) &&
return p_scossl_dh_keymgmt_get_ffc_params(ctx->pDlGroup, params) &&
p_scossl_dh_keymgmt_get_key_params(ctx->keyCtx, params);
}
@ -825,13 +977,13 @@ static BOOL p_scossl_dh_keymgmt_has(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx, int select
{
BOOL ret = TRUE;
if (ctx->keyCtx->dlkey == NULL)
if (ctx == NULL || ctx->keyCtx->dlkey == NULL)
{
return FALSE;
}
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
{
ret = ret && SymCryptDlkeyGetGroup(ctx->keyCtx->dlkey) != NULL;
ret = ret && ctx->pDlGroup != NULL;
}
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
{
@ -839,7 +991,8 @@ static BOOL p_scossl_dh_keymgmt_has(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx, int select
}
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
{
ret = ret && SymCryptDlkeyHasPrivateKey(ctx->keyCtx->dlkey);
ret = ret && ctx->keyCtx->dlkey != NULL &&
SymCryptDlkeyHasPrivateKey(ctx->keyCtx->dlkey);
}
return ret;
@ -860,13 +1013,9 @@ static BOOL p_scossl_dh_keymgmt_match(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx1, _In_ SC
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
{
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
if (!ctx1->keyCtx->initialized || !ctx2->keyCtx->initialized)
{
cbPrivateKey = SymCryptDlkeySizeofPrivateKey(ctx1->keyCtx->dlkey);
if (SymCryptDlkeySizeofPrivateKey(ctx2->keyCtx->dlkey) != cbPrivateKey)
{
goto cleanup;
}
goto cleanup;
}
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
@ -877,6 +1026,22 @@ static BOOL p_scossl_dh_keymgmt_match(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx1, _In_ SC
goto cleanup;
}
}
// Only need to check the private key if we aren't already checking
// the public key. Same behavior as default openssl implementation.
else if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 &&
SymCryptDlkeyHasPrivateKey(ctx1->keyCtx->dlkey) &&
SymCryptDlkeyHasPrivateKey(ctx2->keyCtx->dlkey))
{
cbPrivateKey = SymCryptDlkeySizeofPrivateKey(ctx1->keyCtx->dlkey);
if (SymCryptDlkeySizeofPrivateKey(ctx2->keyCtx->dlkey) != cbPrivateKey)
{
goto cleanup;
}
}
else
{
goto cleanup;
}
cbData = cbPrivateKey * 2 + cbPublicKey * 2;
if ((pbData = OPENSSL_zalloc(cbData)) == NULL)
@ -885,11 +1050,14 @@ static BOOL p_scossl_dh_keymgmt_match(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx1, _In_ SC
goto cleanup;
}
// Only the private or public keys will be compared, but not both.
// The below ensures the appropriate pointers are set for,
// SymCryptDlkeyGetValue and memcmp and the others are NULL.
pbPublicKey1 = cbPublicKey == 0 ? NULL : pbData;
pbPrivateKey1 = cbPrivateKey == 0 ? NULL : pbData;
pbPrivateKey2 = cbPrivateKey == 0 ? NULL : pbData + cbPrivateKey;
pbPublicKey1 = cbPublicKey == 0 ? NULL : pbData + cbPrivateKey * 2;
pbPublicKey2 = cbPublicKey == 0 ? NULL : pbData + cbPrivateKey * 2 + cbPublicKey;
pbPublicKey2 = cbPublicKey == 0 ? NULL : pbData + cbPublicKey + cbPrivateKey;
pbPrivateKey2 = cbPrivateKey == 0 ? NULL : pbData + cbPublicKey + cbPrivateKey;
if (SymCryptDlkeyGetValue(
ctx1->keyCtx->dlkey,
@ -908,21 +1076,19 @@ static BOOL p_scossl_dh_keymgmt_match(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx1, _In_ SC
goto cleanup;
}
if (memcmp(pbPrivateKey1, pbPrivateKey2, cbPrivateKey) != 0 ||
memcmp(pbPublicKey1, pbPublicKey2, cbPublicKey) != 0)
if (memcmp(pbPublicKey1, pbPublicKey2, cbPublicKey) != 0 ||
memcmp(pbPrivateKey1, pbPrivateKey2, cbPrivateKey) != 0)
{
goto cleanup;
}
}
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0 &&
ctx1->pDlGroup != ctx2->pDlGroup)
{
PCSYMCRYPT_DLGROUP pDlGroup1 = ctx1->keyCtx->dlkey != NULL ? SymCryptDlkeyGetGroup(ctx1->keyCtx->dlkey) : NULL;
PCSYMCRYPT_DLGROUP pDlGroup2 = ctx2->keyCtx->dlkey != NULL ? SymCryptDlkeyGetGroup(ctx2->keyCtx->dlkey) : NULL;
// Both groups must be either NULL or equal
if (pDlGroup1 != pDlGroup2 ||
!SymCryptDlgroupIsSame(pDlGroup1, pDlGroup2))
if (ctx1->pDlGroup == NULL ||
ctx2->pDlGroup == NULL ||
!SymCryptDlgroupIsSame(ctx1->pDlGroup, ctx2->pDlGroup))
{
goto cleanup;
}
@ -964,7 +1130,7 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_import(_Inout_ SCOSSL_PROV_DH_KEY_CTX *
PSYMCRYPT_DLGROUP pDlGroup = NULL;
BIGNUM *bnPrivateKey = NULL;
BIGNUM *bnPublicKey = NULL;
int nBitsPriv = 0;
int nBitsPriv = SCOSSL_DH_PRIVATE_BITS_DEFAULT;
SCOSSL_STATUS ret = SCOSSL_FAILURE;
// Group required for import
@ -973,10 +1139,11 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_import(_Inout_ SCOSSL_PROV_DH_KEY_CTX *
return SCOSSL_FAILURE;
}
if (ctx->pDlGroup != NULL)
if (ctx->groupSetByParams)
{
SymCryptDlgroupFree(ctx->pDlGroup);
ctx->pDlGroup = NULL;
ctx->groupSetByParams = FALSE;
}
if (!p_scossl_dh_params_to_group(ctx->libCtx,
@ -988,21 +1155,11 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_import(_Inout_ SCOSSL_PROV_DH_KEY_CTX *
return SCOSSL_FAILURE;
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PRIV_LEN)) != NULL)
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PRIV_LEN)) != NULL &&
!OSSL_PARAM_get_int(p, &nBitsPriv))
{
if (!OSSL_PARAM_get_int(p, &nBitsPriv))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
goto cleanup;
}
// SymCryptDlkeySetPrivateKeyLength will validate this key size.
// Here we just need to be sure we can safely cast to UINT32
if (nBitsPriv < 0)
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
goto cleanup;
}
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
goto cleanup;
}
// If keypair is selected, either the private or public key must be
@ -1048,10 +1205,9 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_import(_Inout_ SCOSSL_PROV_DH_KEY_CTX *
}
}
if (groupSetByParams)
{
ctx->pDlGroup = pDlGroup;
}
ctx->pDlGroup = pDlGroup;
ctx->groupSetByParams = groupSetByParams;
ctx->nBitsPriv = nBitsPriv;
ret = SCOSSL_SUCCESS;
@ -1097,8 +1253,8 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_export(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx
SIZE_T cbPrimeQ;
SIZE_T cbGenG;
SIZE_T cbSeed;
SIZE_T cbPrivateKey;
SIZE_T cbPublicKey;
SIZE_T cbPrivateKey;
SIZE_T cbData = 0;
BIGNUM *bnPrimeP = NULL;
BIGNUM *bnPrimeQ = NULL;
@ -1107,8 +1263,8 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_export(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx
BIGNUM *bnPubKey = NULL;
int mdNid;
int dlGroupNid;
int privateKeyBits;
const char *dlGroupName;
PCSYMCRYPT_DLGROUP pDlGroup;
PCSYMCRYPT_HASH pHashAlgorithm;
UINT32 genCounter;
@ -1116,15 +1272,12 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_export(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx
SCOSSL_STATUS ret = SCOSSL_FAILURE;
if (ctx->keyCtx == NULL ||
ctx->keyCtx->dlkey == NULL ||
(selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0 ||
((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0 && !ctx->keyCtx->initialized))
{
return SCOSSL_FAILURE;
}
pDlGroup = SymCryptDlkeyGetGroup(ctx->keyCtx->dlkey);
if ((bld = OSSL_PARAM_BLD_new()) == NULL)
{
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
@ -1132,7 +1285,7 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_export(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx
}
SymCryptDlgroupGetSizes(
pDlGroup,
ctx->pDlGroup,
&cbPrimeP,
&cbPrimeQ,
&cbGenG,
@ -1172,7 +1325,7 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_export(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx
// Always export group parameters
scError = SymCryptDlgroupGetValue(
pDlGroup,
ctx->pDlGroup,
pbPrimeP, cbPrimeP,
pbPrimeQ, cbPrimeQ,
pbGenG, cbGenG,
@ -1229,7 +1382,7 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_export(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx
}
// Group name may not be available if the group was imported by params
if ((dlGroupNid = scossl_dh_get_group_nid(pDlGroup)) != 0)
if ((dlGroupNid = scossl_dh_get_group_nid(ctx->pDlGroup)) != 0)
{
if ((dlGroupName = OBJ_nid2sn(dlGroupNid)) == NULL ||
!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME, dlGroupName, strlen(dlGroupName)))
@ -1275,7 +1428,7 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_export(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx
}
if (BN_bin2bn(pbPrivateKey, cbPrivateKey, bnPrivKey) == NULL ||
OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, bnPrivKey))
!OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, bnPrivKey))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
@ -1291,7 +1444,7 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_export(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx
}
if (BN_bin2bn(pbPublicKey, cbPublicKey, bnPubKey) == NULL ||
OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, bnPubKey))
!OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, bnPubKey))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
@ -1299,7 +1452,10 @@ static SCOSSL_STATUS p_scossl_dh_keymgmt_export(_In_ SCOSSL_PROV_DH_KEY_CTX *ctx
}
}
if (!OSSL_PARAM_BLD_push_int(bld, OSSL_PKEY_PARAM_DH_PRIV_LEN, SymCryptDlkeySizeofPrivateKey(ctx->keyCtx->dlkey) * 8) ||
privateKeyBits = p_scossl_dh_privkey_bits(ctx);
if (privateKeyBits < 0 ||
!OSSL_PARAM_BLD_push_int(bld, OSSL_PKEY_PARAM_DH_PRIV_LEN, privateKeyBits) ||
(params = OSSL_PARAM_BLD_to_param(bld)) == NULL)
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
@ -1330,7 +1486,10 @@ const OSSL_DISPATCH p_scossl_dh_keymgmt_functions[] = {
{OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))p_scossl_dh_keygen_settable_params},
{OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))p_scossl_dh_keygen_cleanup},
{OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))p_scossl_dh_keygen_init},
{OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, (void (*)(void))p_scossl_dh_keygen_set_template},
{OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))p_scossl_dh_keygen},
{OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*)(void))p_scossl_dh_keymgmt_settable_params},
{OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))p_scossl_dh_keymgmt_set_params},
{OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))p_scossl_dh_keymgmt_gettable_params},
{OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))p_scossl_dh_keymgmt_get_params},
{OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))p_scossl_dh_keymgmt_has},

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

@ -26,6 +26,7 @@ typedef struct
// ScOSSL only supports named curves
static const OSSL_PARAM p_scossl_ecc_keygen_settable_param_types[] = {
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0),
OSSL_PARAM_END};
static const OSSL_PARAM p_scossl_ecc_keymgmt_gettable_param_types[] = {
@ -35,6 +36,7 @@ static const OSSL_PARAM p_scossl_ecc_keymgmt_gettable_param_types[] = {
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, NULL),
OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL),
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0),
OSSL_PARAM_END};
static const OSSL_PARAM p_scossl_x25519_keymgmt_gettable_param_types[] = {
@ -46,6 +48,7 @@ static const OSSL_PARAM p_scossl_x25519_keymgmt_gettable_param_types[] = {
static const OSSL_PARAM p_scossl_ecc_keymgmt_settable_param_types[] = {
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0),
OSSL_PARAM_END};
// We don't need to support setting the group for X25519 import/export
@ -243,6 +246,22 @@ static SCOSSL_STATUS p_scossl_ecc_keygen_set_params(_Inout_ SCOSSL_ECC_KEYGEN_CT
genCtx->curve = pCurve;
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING)) != NULL)
{
const char* encoding;
if (!OSSL_PARAM_get_utf8_string_ptr(p, &encoding))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
}
if (OPENSSL_strcasecmp(encoding, OSSL_PKEY_EC_ENCODING_GROUP) != 0)
{
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED);
return SCOSSL_FAILURE;
}
}
return SCOSSL_SUCCESS;
}
@ -384,21 +403,21 @@ static SCOSSL_STATUS p_scossl_ecc_keymgmt_get_params(_In_ SCOSSL_ECC_KEY_CTX *ke
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL &&
!OSSL_PARAM_set_uint32(p, scossl_ecdsa_size(keyCtx->curve)))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL &&
!OSSL_PARAM_set_int(p, SymCryptEcurveBitsizeofGroupOrder(keyCtx->curve)))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL &&
!OSSL_PARAM_set_int(p, SymCryptEcurveBitsizeofGroupOrder(keyCtx->curve) / 2))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
@ -407,7 +426,7 @@ static SCOSSL_STATUS p_scossl_ecc_keymgmt_get_params(_In_ SCOSSL_ECC_KEY_CTX *ke
if (!keyCtx->initialized)
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
@ -461,11 +480,18 @@ static SCOSSL_STATUS p_scossl_ecc_keymgmt_get_params(_In_ SCOSSL_ECC_KEY_CTX *ke
if (!OSSL_PARAM_set_octet_string(p, pbPublicKeyTmp, cbPublicKey))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
}
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_ENCODING)) != NULL &&
!OSSL_PARAM_set_utf8_string(p, OSSL_PKEY_EC_ENCODING_GROUP))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
// General ECDH only
if (!keyCtx->isX25519)
{
@ -473,7 +499,7 @@ static SCOSSL_STATUS p_scossl_ecc_keymgmt_get_params(_In_ SCOSSL_ECC_KEY_CTX *ke
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS)) != NULL &&
!OSSL_PARAM_set_int(p, 0))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
@ -481,7 +507,7 @@ static SCOSSL_STATUS p_scossl_ecc_keymgmt_get_params(_In_ SCOSSL_ECC_KEY_CTX *ke
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH)) != NULL &&
!OSSL_PARAM_set_int(p, 0))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
}
@ -579,6 +605,22 @@ static SCOSSL_STATUS p_scossl_ecc_keymgmt_set_params(_Inout_ SCOSSL_ECC_KEY_CTX
keyCtx->initialized = TRUE;
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING)) != NULL)
{
const char* encoding;
if (!OSSL_PARAM_get_utf8_string_ptr(p, &encoding))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
goto cleanup;
}
if (OPENSSL_strcasecmp(encoding, OSSL_PKEY_EC_ENCODING_GROUP) != 0)
{
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED);
goto cleanup;
}
}
ret = SCOSSL_SUCCESS;
cleanup:
OPENSSL_free(encodedPoint);
@ -778,6 +820,23 @@ static SCOSSL_STATUS p_scossl_ecc_keymgmt_import(_Inout_ SCOSSL_ECC_KEY_CTX *key
goto cleanup;
}
// Only allow named curves
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING)) != NULL)
{
const char* encoding;
if (!OSSL_PARAM_get_utf8_string_ptr(p, &encoding))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return SCOSSL_FAILURE;
}
if (OPENSSL_strcasecmp(encoding, OSSL_PKEY_EC_ENCODING_GROUP) != 0)
{
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED);
return SCOSSL_FAILURE;
}
}
ecGroup = EC_GROUP_new_from_params(params, keyCtx->libctx, NULL);
pCurve = scossl_ecc_group_to_symcrypt_curve(ecGroup);
@ -925,6 +984,7 @@ static SCOSSL_STATUS p_scossl_ecc_keymgmt_export(_In_ SCOSSL_ECC_KEY_CTX *keyCtx
// Curve is assumed to be a valid named curve if it was loaded by SCOSSL
if ((curveName = scossl_ecc_get_curve_name(keyCtx->curve)) == NULL ||
!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_ENCODING, OSSL_PKEY_EC_ENCODING_GROUP, strlen(OSSL_PKEY_EC_ENCODING_GROUP)) ||
!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME, curveName, strlen(curveName)))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);

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

@ -27,7 +27,8 @@ extern "C" {
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0),
#define SCOSSL_ECC_IMPEXP_DOMAIN_PARAMS \
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), \
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0),
#define SCOSSL_ECC_IMPEXP_OTHER_PARAMS \
OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL), \

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

@ -114,7 +114,7 @@ static SCOSSL_KMAC_CTX *p_scossl_kmac_dupctx(_In_ SCOSSL_KMAC_CTX *ctx)
copyCtx->cbOutput = ctx->cbOutput;
copyCtx->xofMode = ctx->xofMode;
return ctx;
return copyCtx;
}
static SCOSSL_STATUS p_scossl_kmac_init(_Inout_ SCOSSL_KMAC_CTX *ctx,

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

@ -111,9 +111,7 @@ SCOSSL_STATUS p_scossl_rsa_pss_restrictions_from_params(OSSL_LIB_CTX *libctx, co
// Set defaults based on RFC 8017, A.2.3. This is the same behavior
// as the default provider.
pssRestrictions->mdInfo = &p_scossl_rsa_supported_mds[SCOSSL_PROV_RSA_PSS_DEFAULT_MD];
pssRestrictions->mgf1MdInfo = &p_scossl_rsa_supported_mds[SCOSSL_PROV_RSA_PSS_DEFAULT_MD];
pssRestrictions->cbSaltMin = SCOSSL_PROV_RSA_PSS_DEFAULT_SALTLEN_MIN;
p_scossl_rsa_pss_restrictions_get_defaults(pssRestrictions);
*pPssRestrictions = pssRestrictions;
}
@ -162,13 +160,24 @@ cleanup:
_Use_decl_annotations_
SCOSSL_STATUS p_scossl_rsa_pss_restrictions_to_params(const SCOSSL_RSA_PSS_RESTRICTIONS *pssRestrictions,
OSSL_PARAM_BLD *bld)
OSSL_PARAM_BLD *bld)
{
return OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_RSA_DIGEST, pssRestrictions->mdInfo->ptr, 0) &&
OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_RSA_MGF1_DIGEST, pssRestrictions->mgf1MdInfo->ptr, 0) &&
OSSL_PARAM_BLD_push_int(bld, OSSL_PKEY_PARAM_RSA_PSS_SALTLEN, pssRestrictions->cbSaltMin);
}
_Use_decl_annotations_
void p_scossl_rsa_pss_restrictions_get_defaults(SCOSSL_RSA_PSS_RESTRICTIONS* pssRestrictions)
{
if (pssRestrictions != NULL)
{
pssRestrictions->mdInfo = &p_scossl_rsa_supported_mds[SCOSSL_PROV_RSA_PSS_DEFAULT_MD];
pssRestrictions->mgf1MdInfo = &p_scossl_rsa_supported_mds[SCOSSL_PROV_RSA_PSS_DEFAULT_MD];
pssRestrictions->cbSaltMin = SCOSSL_PROV_RSA_PSS_DEFAULT_SALTLEN_MIN;
}
}
#ifdef __cplusplus
}
#endif

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

@ -34,6 +34,8 @@ SCOSSL_STATUS p_scossl_rsa_pss_restrictions_from_params(_In_ OSSL_LIB_CTX *libct
SCOSSL_STATUS p_scossl_rsa_pss_restrictions_to_params(_In_ const SCOSSL_RSA_PSS_RESTRICTIONS *pssRestrictions,
_Inout_ OSSL_PARAM_BLD *bld);
void p_scossl_rsa_pss_restrictions_get_defaults(_Inout_ SCOSSL_RSA_PSS_RESTRICTIONS *pssRestrictions);
#ifdef __cplusplus
}
#endif

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

@ -29,6 +29,7 @@ typedef struct
static const OSSL_PARAM p_scossl_ecdsa_ctx_gettable_param_types[] = {
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
OSSL_PARAM_END};
static const OSSL_PARAM p_scossl_ecdsa_ctx_settable_param_types[] = {
@ -327,22 +328,96 @@ static SCOSSL_STATUS p_scossl_ecdsa_get_ctx_params(_In_ SCOSSL_ECDSA_CTX *ctx, _
}
OSSL_PARAM *p;
X509_ALGOR *x509Alg = NULL;
SCOSSL_STATUS ret = SCOSSL_FAILURE;
if ((p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST)) != NULL &&
!OSSL_PARAM_set_utf8_string(p, ctx->md == NULL ? "" : EVP_MD_get0_name(ctx->md)))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
goto cleanup;
}
if ((p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE)) != NULL &&
!OSSL_PARAM_set_size_t(p, ctx->mdSize))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
goto cleanup;
}
return SCOSSL_SUCCESS;
if ((p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID)) != NULL)
{
int cbAid;
int algNid = NID_undef;
if (p->data_type != OSSL_PARAM_OCTET_STRING)
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
p->return_size = 0;
if (ctx->md == NULL)
{
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
goto cleanup;
}
if ((x509Alg = X509_ALGOR_new()) == NULL)
{
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
goto cleanup;
}
switch (EVP_MD_nid(ctx->md))
{
case NID_sha1:
algNid = NID_ecdsa_with_SHA1;
break;
case NID_sha256:
algNid = NID_ecdsa_with_SHA256;
break;
case NID_sha384:
algNid = NID_ecdsa_with_SHA384;
break;
case NID_sha512:
algNid = NID_ecdsa_with_SHA512;
break;
case NID_sha3_256:
algNid = NID_ecdsa_with_SHA3_256;
break;
case NID_sha3_384:
algNid = NID_ecdsa_with_SHA3_384;
break;
case NID_sha3_512:
algNid = NID_ecdsa_with_SHA3_512;
break;
}
if (algNid == NID_undef ||
!X509_ALGOR_set0(x509Alg, OBJ_nid2obj(algNid), V_ASN1_UNDEF, NULL))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
if ((cbAid = i2d_X509_ALGOR(x509Alg, (unsigned char**)&p->data)) < 0)
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
p->return_size = (SIZE_T)cbAid;
}
ret = SCOSSL_SUCCESS;
cleanup:
X509_ALGOR_free(x509Alg);
return ret;
}
static const OSSL_PARAM *p_scossl_ecdsa_gettable_ctx_md_params(_In_ SCOSSL_ECDSA_CTX *ctx)

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

@ -38,8 +38,9 @@ typedef struct
} SCOSSL_RSA_SIGN_CTX;
#define SCOSSL_RSA_SIGNATURE_GETTABLE_PARAMS \
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), \
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, NULL, 0), \
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
#define SCOSSL_RSA_PSS_SIGNATURE_GETTABLE_PARAMS \
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0), \
@ -640,6 +641,65 @@ static const OSSL_PARAM *p_scossl_rsa_gettable_ctx_params(_In_ SCOSSL_RSA_SIGN_C
return ctx->padding == RSA_PKCS1_PSS_PADDING ? p_scossl_rsa_pss_sig_ctx_gettable_param_types : p_scossl_rsa_sig_ctx_gettable_param_types;
}
static ASN1_STRING *p_scossl_rsa_pss_params_to_asn1_sequence(_In_ SCOSSL_RSA_SIGN_CTX *ctx)
{
SCOSSL_RSA_PSS_RESTRICTIONS defaultRestrictions;
RSA_PSS_PARAMS *pssParams = NULL;
ASN1_STRING *mgf1MdStr = NULL;
ASN1_STRING *pssParamSeq = NULL;
if ((pssParams = RSA_PSS_PARAMS_new()) == NULL)
{
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
goto cleanup;
}
p_scossl_rsa_pss_restrictions_get_defaults(&defaultRestrictions);
// mgf1md must equal md for symcrypt
// If this changes, the mgf1md must be checked independently
if (ctx->mdInfo->id != defaultRestrictions.mdInfo->id)
{
if ((pssParams->hashAlgorithm = X509_ALGOR_new()) == NULL ||
(pssParams->maskGenAlgorithm = X509_ALGOR_new()) == NULL)
{
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
goto cleanup;
}
X509_ALGOR_set_md(pssParams->hashAlgorithm, ctx->md);
if (ASN1_item_pack(pssParams->hashAlgorithm, ASN1_ITEM_rptr(X509_ALGOR), &mgf1MdStr) == NULL ||
!X509_ALGOR_set0(pssParams->maskGenAlgorithm, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, mgf1MdStr))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
}
if (ctx->cbSaltMin != defaultRestrictions.cbSaltMin)
{
if ((pssParams->saltLength = ASN1_INTEGER_new()) == NULL)
{
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
goto cleanup;
}
if (!ASN1_INTEGER_set(pssParams->saltLength, ctx->cbSaltMin))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
}
pssParamSeq = ASN1_item_pack(pssParams, ASN1_ITEM_rptr(RSA_PSS_PARAMS), NULL);
cleanup:
RSA_PSS_PARAMS_free(pssParams);
return pssParamSeq;
}
static SCOSSL_STATUS p_scossl_rsa_get_ctx_params(_In_ SCOSSL_RSA_SIGN_CTX *ctx, _Inout_ OSSL_PARAM params[])
{
if (params == NULL)
@ -648,12 +708,15 @@ static SCOSSL_STATUS p_scossl_rsa_get_ctx_params(_In_ SCOSSL_RSA_SIGN_CTX *ctx,
}
OSSL_PARAM *p;
ASN1_STRING *pval = NULL;
X509_ALGOR *x509Alg = NULL;
SCOSSL_STATUS ret = SCOSSL_FAILURE;
if ((p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST)) != NULL &&
!OSSL_PARAM_set_utf8_string(p, ctx->mdInfo == NULL ? "" : ctx->mdInfo->ptr))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
goto cleanup;
}
if ((p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_PAD_MODE)) != NULL)
@ -667,7 +730,7 @@ static SCOSSL_STATUS p_scossl_rsa_get_ctx_params(_In_ SCOSSL_RSA_SIGN_CTX *ctx,
if (!OSSL_PARAM_set_int(p, ctx->padding))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
goto cleanup;
}
break;
case OSSL_PARAM_UTF8_STRING:
@ -680,15 +743,99 @@ static SCOSSL_STATUS p_scossl_rsa_get_ctx_params(_In_ SCOSSL_RSA_SIGN_CTX *ctx,
if (!OSSL_PARAM_set_utf8_string(p, p_scossl_rsa_sign_padding_modes[i].ptr))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
goto cleanup;
}
break;
default:
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
goto cleanup;
}
}
if ((p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID)) != NULL) {
int cbAid;
int algNid = NID_undef;
int ptype = V_ASN1_NULL;
void *pval = NULL;
if (p->data_type != OSSL_PARAM_OCTET_STRING)
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
p->return_size = 0;
if (ctx->mdInfo == NULL)
{
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
goto cleanup;
}
if ((x509Alg = X509_ALGOR_new()) == NULL)
{
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
goto cleanup;
}
if (ctx->padding == RSA_PKCS1_PADDING)
{
switch (ctx->mdInfo->id)
{
case NID_sha1:
algNid = NID_sha1WithRSAEncryption;
break;
case NID_sha256:
algNid = NID_sha256WithRSAEncryption;
break;
case NID_sha384:
algNid = NID_sha384WithRSAEncryption;
break;
case NID_sha512:
algNid = NID_sha512WithRSAEncryption;
break;
case NID_sha3_256:
algNid = NID_RSA_SHA3_256;
break;
case NID_sha3_384:
algNid = NID_RSA_SHA3_384;
break;
case NID_sha3_512:
algNid = NID_RSA_SHA3_512;
break;
}
}
else if (ctx->padding == RSA_PKCS1_PSS_PADDING)
{
algNid = ctx->pssRestricted ? NID_rsassaPss : NID_rsaEncryption;
}
if (ctx->pssRestricted)
{
ptype = V_ASN1_SEQUENCE;
if ((pval = p_scossl_rsa_pss_params_to_asn1_sequence(ctx)) == NULL)
{
goto cleanup;
}
}
if (algNid == NID_undef ||
!X509_ALGOR_set0(x509Alg, OBJ_nid2obj(algNid), ptype, pval))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
if ((cbAid = i2d_X509_ALGOR(x509Alg, (unsigned char**)&p->data)) < 0)
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
goto cleanup;
}
p->return_size = (SIZE_T)cbAid;
}
//
// PSS paramaters
//
@ -704,7 +851,7 @@ static SCOSSL_STATUS p_scossl_rsa_get_ctx_params(_In_ SCOSSL_RSA_SIGN_CTX *ctx,
if (!OSSL_PARAM_set_int(p, ctx->cbSalt))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
goto cleanup;
}
break;
case OSSL_PARAM_UTF8_STRING:
@ -728,7 +875,7 @@ static SCOSSL_STATUS p_scossl_rsa_get_ctx_params(_In_ SCOSSL_RSA_SIGN_CTX *ctx,
len = BIO_snprintf(p->data, p->data_size, "%d",
ctx->cbSalt);
if (len <= 0)
return SCOSSL_FAILURE;
goto cleanup;
p->return_size = len;
}
@ -736,13 +883,13 @@ static SCOSSL_STATUS p_scossl_rsa_get_ctx_params(_In_ SCOSSL_RSA_SIGN_CTX *ctx,
!OSSL_PARAM_set_utf8_string(p, saltLenText))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
goto cleanup;
}
break;
default:
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
goto cleanup;
}
}
@ -750,10 +897,16 @@ static SCOSSL_STATUS p_scossl_rsa_get_ctx_params(_In_ SCOSSL_RSA_SIGN_CTX *ctx,
!OSSL_PARAM_set_utf8_string(p, ctx->mgf1MdInfo == NULL ? "" : ctx->mgf1MdInfo->ptr))
{
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return SCOSSL_FAILURE;
goto cleanup;
}
return SCOSSL_SUCCESS;
ret = SCOSSL_SUCCESS;
cleanup:
ASN1_STRING_free(pval);
X509_ALGOR_free(x509Alg);
return ret;
}
static const OSSL_PARAM *p_scossl_rsa_gettable_ctx_md_params(_In_ SCOSSL_RSA_SIGN_CTX *ctx)