Bugfixes for TLS connections (#78)
* 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:
Родитель
2ef3602ece
Коммит
ef91a8827e
|
@ -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, ©_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, ©Ctx->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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче