From d1fb8f14b65fae3b750cd712bee34fdaee03fadf Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Mon, 13 Apr 2026 23:33:34 +0000 Subject: [PATCH 01/11] Compare correct values in rsa match --- SymCryptProvider/src/keymgmt/p_scossl_rsa_keymgmt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SymCryptProvider/src/keymgmt/p_scossl_rsa_keymgmt.c b/SymCryptProvider/src/keymgmt/p_scossl_rsa_keymgmt.c index 46342746..07774f41 100644 --- a/SymCryptProvider/src/keymgmt/p_scossl_rsa_keymgmt.c +++ b/SymCryptProvider/src/keymgmt/p_scossl_rsa_keymgmt.c @@ -1056,7 +1056,7 @@ static BOOL p_scossl_rsa_keymgmt_match(_In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx1, _I SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, 0); if (scError != SYMCRYPT_NO_ERROR) - { + { SCOSSL_PROV_LOG_SYMCRYPT_ERROR("SymCryptRsakeyGetCrtValue failed", scError); goto cleanup; } @@ -1074,7 +1074,7 @@ static BOOL p_scossl_rsa_keymgmt_match(_In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx1, _I goto cleanup; } - if (memcmp(pbPrivateExponent1, pbPrivateExponent1, cbModulus) != 0) + if (memcmp(pbPrivateExponent1, pbPrivateExponent2, cbModulus) != 0) { goto cleanup; } From 8cc37491c2de822dedc30d38b131673d3138b8f9 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Mon, 13 Apr 2026 23:48:21 +0000 Subject: [PATCH 02/11] Use correct bit size for DH P and Q in dup --- ScosslCommon/src/scossl_dh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ScosslCommon/src/scossl_dh.c b/ScosslCommon/src/scossl_dh.c index bf2e4f5e..178e7678 100644 --- a/ScosslCommon/src/scossl_dh.c +++ b/ScosslCommon/src/scossl_dh.c @@ -73,7 +73,7 @@ SCOSSL_DH_KEY_CTX *scossl_dh_dup_key_ctx(SCOSSL_DH_KEY_CTX *ctx, BOOL copyGroup) NULL, NULL); - if ((pDlgroupCopy = SymCryptDlgroupAllocate(pcbPrimeP, pcbPrimeQ)) == NULL) + if ((pDlgroupCopy = SymCryptDlgroupAllocate(pcbPrimeP * 8, pcbPrimeQ * 8)) == NULL) { goto cleanup; } From 6a2114ca41d2843cee0097e295ef7f9f242c6fd8 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Tue, 14 Apr 2026 00:13:17 +0000 Subject: [PATCH 03/11] Properly validate x25519 key length --- .../src/keymgmt/p_scossl_ecc_keymgmt.c | 61 +++++++++++++++---- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c b/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c index 67c11b92..94f2bc3d 100644 --- a/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c +++ b/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c @@ -14,7 +14,7 @@ extern "C" { #endif -#define SCOSSL_X25519_MAX_SIZE (32) +#define SCOSSL_X25519_KEY_SIZE (32) #define SCOSSL_ECC_DEFAULT_DIGEST SN_sha256 #define SCOSSL_ECC_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_PUBLIC_KEY | OSSL_KEYMGMT_SELECT_PRIVATE_KEY | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) @@ -568,7 +568,7 @@ static SCOSSL_STATUS p_scossl_ecc_keymgmt_get_params(_In_ SCOSSL_ECC_KEY_CTX *ke { if (keyCtx->isX25519) { - if (!OSSL_PARAM_set_uint32(p, SCOSSL_X25519_MAX_SIZE)) + if (!OSSL_PARAM_set_uint32(p, SCOSSL_X25519_KEY_SIZE)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); goto cleanup; @@ -1332,10 +1332,12 @@ static SCOSSL_STATUS p_scossl_x25519_keymgmt_import(_Inout_ SCOSSL_ECC_KEY_CTX * { SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR; SCOSSL_STATUS ret = SCOSSL_FAILURE; + PSYMCRYPT_ECKEY ecKey = NULL; PBYTE pbPrivateKey = NULL; SIZE_T cbPrivateKey = 0; PBYTE pbPublicKey = NULL; SIZE_T cbPublicKey = 0; + BYTE modifiedPrivateBits = 0; const OSSL_PARAM *p; // Other parameters @@ -1352,12 +1354,6 @@ static SCOSSL_STATUS p_scossl_x25519_keymgmt_import(_Inout_ SCOSSL_ECC_KEY_CTX * // Keypair if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { - if ((keyCtx->key = SymCryptEckeyAllocate(keyCtx->curve))== NULL) - { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - goto cleanup; - } - if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY)) != NULL) { if (!OSSL_PARAM_get_octet_string(p, (void **)&pbPublicKey, 0, &cbPublicKey)) @@ -1365,6 +1361,12 @@ static SCOSSL_STATUS p_scossl_x25519_keymgmt_import(_Inout_ SCOSSL_ECC_KEY_CTX * ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); goto cleanup; } + + if (cbPublicKey != SCOSSL_X25519_KEY_SIZE) + { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + goto cleanup; + } } if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY)) != NULL) @@ -1375,33 +1377,70 @@ static SCOSSL_STATUS p_scossl_x25519_keymgmt_import(_Inout_ SCOSSL_ECC_KEY_CTX * goto cleanup; } + // Match the default OpenSSL provider by rejecting empty or short + // raw X25519 private keys before applying RFC 7748 clamping. + if (cbPrivateKey != SCOSSL_X25519_KEY_SIZE) + { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + goto cleanup; + } + // Preserve original bits for export - keyCtx->modifiedPrivateBits = pbPrivateKey[0] & 0x07; - keyCtx->modifiedPrivateBits |= pbPrivateKey[cbPrivateKey-1] & 0xc0; + modifiedPrivateBits = pbPrivateKey[0] & 0x07; + modifiedPrivateBits |= pbPrivateKey[cbPrivateKey-1] & 0xc0; pbPrivateKey[0] &= 0xf8; pbPrivateKey[cbPrivateKey-1] &= 0x7f; pbPrivateKey[cbPrivateKey-1] |= 0x40; } + if (pbPrivateKey == NULL && pbPublicKey == NULL) + { + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY); + goto cleanup; + } + + if ((ecKey = SymCryptEckeyAllocate(keyCtx->curve)) == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + goto cleanup; + } + scError = SymCryptEckeySetValue( pbPrivateKey, cbPrivateKey, pbPublicKey, cbPublicKey, SYMCRYPT_NUMBER_FORMAT_LSB_FIRST, SYMCRYPT_ECPOINT_FORMAT_X, SYMCRYPT_FLAG_ECKEY_ECDH, - keyCtx->key); + ecKey); if (scError != SYMCRYPT_NO_ERROR) { SCOSSL_PROV_LOG_SYMCRYPT_ERROR("SymCryptEckeySetValue failed", scError); goto cleanup; } + if (keyCtx->key != NULL) + { + SymCryptEckeyFree(keyCtx->key); + } + +#ifdef KEYSINUSE_ENABLED + // Reset keysinuse in case new key material is overwriting existing + p_scossl_ecc_reset_keysinuse(keyCtx); +#endif + + keyCtx->key = ecKey; + ecKey = NULL; + keyCtx->modifiedPrivateBits = modifiedPrivateBits; keyCtx->initialized = TRUE; } ret = SCOSSL_SUCCESS; cleanup: + if (ret != SCOSSL_SUCCESS && ecKey != NULL) + { + SymCryptEckeyFree(ecKey); + } OPENSSL_secure_clear_free(pbPrivateKey, cbPrivateKey); OPENSSL_free(pbPublicKey); From 8b18bf241a68c22633da1c6ad3ac5fa054d52285 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Tue, 14 Apr 2026 16:51:43 +0000 Subject: [PATCH 04/11] Update RSA encrypt/decrypt input validation to match default implementation --- .../src/asymcipher/p_scossl_rsa_cipher.c | 59 +++++++++++++++++-- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c b/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c index b5bae5fa..7a121382 100644 --- a/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c +++ b/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c @@ -8,6 +8,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -141,11 +142,12 @@ static SCOSSL_STATUS p_scossl_rsa_decrypt_init(_Inout_ SCOSSL_RSA_CIPHER_CTX *ct } static SCOSSL_STATUS p_scossl_rsa_cipher_encrypt(_In_ SCOSSL_RSA_CIPHER_CTX *ctx, - _Out_writes_bytes_(*outlen) unsigned char *out, _Out_ size_t *outlen, size_t outsize, - _In_reads_bytes_(inlen) const unsigned char *in, size_t inlen) + _Out_writes_bytes_(*outlen) unsigned char *out, _Out_ size_t *outlen, size_t outsize, + _In_reads_bytes_(inlen) const unsigned char *in, size_t inlen) { int mdnid = 0; INT32 cbResult; + UINT32 cbModulus; SCOSSL_STATUS ret; if (ctx->keyCtx == NULL) @@ -160,6 +162,19 @@ static SCOSSL_STATUS p_scossl_rsa_cipher_encrypt(_In_ SCOSSL_RSA_CIPHER_CTX *ctx return SCOSSL_FAILURE; } + cbModulus = SymCryptRsakeySizeofModulus(ctx->keyCtx->key); + if (cbModulus == 0) + { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); + return SCOSSL_FAILURE; + } + + if (outsize < cbModulus) + { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return SCOSSL_FAILURE; + } + // Default to SHA1 for OAEP. Update md in context so this is // reflected in getparam if (ctx->padding == RSA_PKCS1_OAEP_PADDING) @@ -187,11 +202,12 @@ static SCOSSL_STATUS p_scossl_rsa_cipher_encrypt(_In_ SCOSSL_RSA_CIPHER_CTX *ctx } static SCOSSL_STATUS p_scossl_rsa_cipher_decrypt(_In_ SCOSSL_RSA_CIPHER_CTX *ctx, - _Out_writes_bytes_(*outlen) unsigned char *out, _Out_ size_t *outlen, size_t outsize, - _In_reads_bytes_(inlen) const unsigned char *in, size_t inlen) + _Out_writes_bytes_(*outlen) unsigned char *out, _Out_ size_t *outlen, size_t outsize, + _In_reads_bytes_(inlen) const unsigned char *in, size_t inlen) { int mdnid = 0; INT32 cbResult; + UINT32 cbModulus; SCOSSL_STATUS ret; if (ctx->keyCtx == NULL) @@ -206,6 +222,41 @@ static SCOSSL_STATUS p_scossl_rsa_cipher_decrypt(_In_ SCOSSL_RSA_CIPHER_CTX *ctx return SCOSSL_FAILURE; } + if (ctx->padding == RSA_PKCS1_WITH_TLS_PADDING) + { + if (out == NULL) + { + *outlen = SSL_MAX_MASTER_KEY_LENGTH; + return SCOSSL_SUCCESS; + } + if (outsize < SSL_MAX_MASTER_KEY_LENGTH) + { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return SCOSSL_FAILURE; + } + } + else + { + cbModulus = SymCryptRsakeySizeofModulus(ctx->keyCtx->key); + if (out == NULL) + { + if (cbModulus == 0) + { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); + return SCOSSL_FAILURE; + } + + *outlen = cbModulus; + return SCOSSL_SUCCESS; + } + + if (outsize < cbModulus) + { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return SCOSSL_FAILURE; + } + } + // Default to SHA1 for OAEP. Update md in context so this is // reflected in getparam if (ctx->padding == RSA_PKCS1_OAEP_PADDING) From 0d032e965f95596e9328c346accffb2ee5f6b2d5 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Tue, 14 Apr 2026 16:55:38 +0000 Subject: [PATCH 05/11] Use correct bit lengths in copy group only case for DH --- SymCryptProvider/src/keymgmt/p_scossl_dh_keymgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SymCryptProvider/src/keymgmt/p_scossl_dh_keymgmt.c b/SymCryptProvider/src/keymgmt/p_scossl_dh_keymgmt.c index 99210ac2..dcb21a7a 100644 --- a/SymCryptProvider/src/keymgmt/p_scossl_dh_keymgmt.c +++ b/SymCryptProvider/src/keymgmt/p_scossl_dh_keymgmt.c @@ -155,7 +155,7 @@ static SCOSSL_PROV_DH_KEY_CTX *p_scossl_dh_keymgmt_dup_key_ctx(_In_ const SCOSSL NULL, NULL); - if ((copyCtx->pDlGroup = SymCryptDlgroupAllocate(pcbPrimeP, pcbPrimeQ)) == NULL) + if ((copyCtx->pDlGroup = SymCryptDlgroupAllocate(pcbPrimeP * 8, pcbPrimeQ * 8)) == NULL) { OPENSSL_free(copyCtx); return NULL; From d9b1807047d1d6409816ae918c9a9477247a1330 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Tue, 14 Apr 2026 20:04:57 +0000 Subject: [PATCH 06/11] Add mac initialized flag --- ScosslCommon/inc/scossl_helpers.h | 2 ++ ScosslCommon/inc/scossl_mac.h | 1 + ScosslCommon/src/scossl_helpers.c | 2 ++ ScosslCommon/src/scossl_mac.c | 49 ++++++++++++++++++++++++------- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/ScosslCommon/inc/scossl_helpers.h b/ScosslCommon/inc/scossl_helpers.h index a7122a06..7b7c6703 100644 --- a/ScosslCommon/inc/scossl_helpers.h +++ b/ScosslCommon/inc/scossl_helpers.h @@ -119,8 +119,10 @@ typedef enum { SCOSSL_ERR_F_GET_SYMCRYPT_MAC_ALGORITHM, SCOSSL_ERR_F_HKDF_DERIVE, SCOSSL_ERR_F_MAC_DUPCTX, + SCOSSL_ERR_F_MAC_FINAL, SCOSSL_ERR_F_MAC_INIT, SCOSSL_ERR_F_MAC_SET_HMAC_MD, + SCOSSL_ERR_F_MAC_UPDATE, SCOSSL_ERR_F_RSA_DECRYPT, SCOSSL_ERR_F_RSA_ENCRYPT, SCOSSL_ERR_F_RSA_EXPORT_KEY, diff --git a/ScosslCommon/inc/scossl_mac.h b/ScosslCommon/inc/scossl_mac.h index 8477ff2f..86adba12 100644 --- a/ScosslCommon/inc/scossl_mac.h +++ b/ScosslCommon/inc/scossl_mac.h @@ -32,6 +32,7 @@ typedef struct PCSCOSSL_MAC_EX pMacEx; PBYTE pbKey; SIZE_T cbKey; + BOOL initialized; // Provider specific fields PVOID libctx; diff --git a/ScosslCommon/src/scossl_helpers.c b/ScosslCommon/src/scossl_helpers.c index ce3f6ff1..8b4a06c1 100644 --- a/ScosslCommon/src/scossl_helpers.c +++ b/ScosslCommon/src/scossl_helpers.c @@ -79,8 +79,10 @@ static ERR_STRING_DATA SCOSSL_ERR_function_strings[] = { {ERR_PACK(0, SCOSSL_ERR_F_GET_SYMCRYPT_MAC_ALGORITHM, 0), "scossl_get_symcrypt_hmac_algorithm"}, {ERR_PACK(0, SCOSSL_ERR_F_HKDF_DERIVE, 0), "scossl_hkdf_derive"}, {ERR_PACK(0, SCOSSL_ERR_F_MAC_DUPCTX, 0), "scossl_mac_dupctx"}, + {ERR_PACK(0, SCOSSL_ERR_F_MAC_FINAL, 0), "scossl_mac_final"}, {ERR_PACK(0, SCOSSL_ERR_F_MAC_INIT, 0), "scossl_mac_init"}, {ERR_PACK(0, SCOSSL_ERR_F_MAC_SET_HMAC_MD, 0), "scossl_mac_set_hmac_md"}, + {ERR_PACK(0, SCOSSL_ERR_F_MAC_UPDATE, 0), "scossl_mac_update"}, {ERR_PACK(0, SCOSSL_ERR_F_RSA_DECRYPT, 0), "scossl_rsa_decrypt"}, {ERR_PACK(0, SCOSSL_ERR_F_RSA_ENCRYPT, 0), "scossl_rsa_encrypt"}, {ERR_PACK(0, SCOSSL_ERR_F_RSA_EXPORT_KEY, 0), "scossl_rsa_export_key"}, diff --git a/ScosslCommon/src/scossl_mac.c b/ScosslCommon/src/scossl_mac.c index 66b5814f..4ba3c2e5 100644 --- a/ScosslCommon/src/scossl_mac.c +++ b/ScosslCommon/src/scossl_mac.c @@ -149,6 +149,8 @@ SCOSSL_MAC_CTX *scossl_mac_dupctx(SCOSSL_MAC_CTX *ctx) } } + copyCtx->initialized = ctx->initialized; + if (ctx->mdName != NULL && (copyCtx->mdName = OPENSSL_strdup(ctx->mdName)) == NULL) { @@ -208,6 +210,8 @@ SCOSSL_STATUS scossl_mac_set_hmac_md(SCOSSL_MAC_CTX *ctx, int mdNid) ctx->expandedKey = NULL; } + ctx->initialized = FALSE; + switch (mdNid) { case NID_sha1: @@ -282,6 +286,8 @@ SCOSSL_STATUS scossl_mac_set_cmac_cipher(SCOSSL_MAC_CTX *ctx, const EVP_CIPHER * ctx->expandedKey = NULL; } + ctx->initialized = FALSE; + switch (EVP_CIPHER_nid(cipher)) { case NID_aes_128_cbc: @@ -336,21 +342,21 @@ SCOSSL_STATUS scossl_mac_init(SCOSSL_MAC_CTX *ctx, return SCOSSL_FAILURE; } - if (ctx->expandedKey == NULL) + if (pbKey != NULL) { - SCOSSL_COMMON_ALIGNED_ALLOC_EX(expandedKey, OPENSSL_malloc, SCOSSL_MAC_EXPANDED_KEY, ctx->pMac->expandedKeySize); - if (expandedKey == NULL) + if (ctx->expandedKey == NULL) { - SCOSSL_LOG_ERROR(SCOSSL_ERR_F_MAC_INIT, ERR_R_MALLOC_FAILURE, - "Failed to aligned allocate expanded key"); - return SCOSSL_FAILURE; - } + SCOSSL_COMMON_ALIGNED_ALLOC_EX(expandedKey, OPENSSL_malloc, SCOSSL_MAC_EXPANDED_KEY, ctx->pMac->expandedKeySize); + if (expandedKey == NULL) + { + SCOSSL_LOG_ERROR(SCOSSL_ERR_F_MAC_INIT, ERR_R_MALLOC_FAILURE, + "Failed to aligned allocate expanded key"); + return SCOSSL_FAILURE; + } - ctx->expandedKey = expandedKey; - } + ctx->expandedKey = expandedKey; + } - if (pbKey != NULL) - { scError = ctx->pMac->expandKeyFunc(ctx->expandedKey, pbKey, cbKey); if (scError != SYMCRYPT_NO_ERROR) @@ -359,6 +365,13 @@ SCOSSL_STATUS scossl_mac_init(SCOSSL_MAC_CTX *ctx, "SymCryptMacExpandKey failed", scError); return SCOSSL_FAILURE; } + + ctx->initialized = TRUE; + } + + if (!ctx->initialized) + { + return SCOSSL_FAILURE; } ctx->pMac->initFunc(ctx->macState, ctx->expandedKey); @@ -370,6 +383,13 @@ _Use_decl_annotations_ SCOSSL_STATUS scossl_mac_update(SCOSSL_MAC_CTX *ctx, PCBYTE pbData, SIZE_T cbData) { + if (!ctx->initialized) + { + SCOSSL_LOG_ERROR(SCOSSL_ERR_F_MAC_UPDATE, SCOSSL_ERR_R_MISSING_CTX_DATA, + "MAC key has not been initialized"); + return SCOSSL_FAILURE; + } + ctx->pMac->appendFunc(ctx->macState, pbData, cbData); return SCOSSL_SUCCESS; @@ -379,6 +399,13 @@ _Use_decl_annotations_ SCOSSL_STATUS scossl_mac_final(SCOSSL_MAC_CTX *ctx, PBYTE pbResult, SIZE_T *cbResult, SIZE_T outsize) { + if (!ctx->initialized) + { + SCOSSL_LOG_ERROR(SCOSSL_ERR_F_MAC_FINAL, SCOSSL_ERR_R_MISSING_CTX_DATA, + "MAC key has not been initialized"); + return SCOSSL_FAILURE; + } + if (pbResult != NULL) { if (outsize < ctx->pMac->resultSize) From ba805c04657a1c14cbe94093406d3dbc28b0ee5a Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Tue, 14 Apr 2026 21:45:31 +0000 Subject: [PATCH 07/11] Compare to correct mac stize in aes --- SymCryptProvider/src/ciphers/p_scossl_aes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SymCryptProvider/src/ciphers/p_scossl_aes.c b/SymCryptProvider/src/ciphers/p_scossl_aes.c index 7fbe7d85..41002e6a 100644 --- a/SymCryptProvider/src/ciphers/p_scossl_aes.c +++ b/SymCryptProvider/src/ciphers/p_scossl_aes.c @@ -774,7 +774,7 @@ static SCOSSL_STATUS p_scossl_aes_generic_set_ctx_params(_Inout_ SCOSSL_AES_CTX return SCOSSL_FAILURE; } - if (ctx->tlsMacSize > EVP_MAX_MD_SIZE) + if (tlsMacSize > EVP_MAX_MD_SIZE) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MAC); return SCOSSL_FAILURE; From 22d77ccb6fd23929633a4e09610919f81a15d89f Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Tue, 14 Apr 2026 22:17:07 +0000 Subject: [PATCH 08/11] Fix RSA size check --- SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c b/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c index 7a121382..70bc21fa 100644 --- a/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c +++ b/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c @@ -169,6 +169,12 @@ static SCOSSL_STATUS p_scossl_rsa_cipher_encrypt(_In_ SCOSSL_RSA_CIPHER_CTX *ctx return SCOSSL_FAILURE; } + if (out == NULL) + { + *outlen = cbModulus; + return SCOSSL_SUCCESS; + } + if (outsize < cbModulus) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); From cd2490f03fbdb57fda8ba4a7ee2c614b043c7192 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Tue, 21 Apr 2026 21:35:44 +0000 Subject: [PATCH 09/11] Update the version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c09a03b6..a75e7e0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.13.0) project(SymCrypt-OpenSSL - VERSION 1.9.5 + VERSION 1.9.6 DESCRIPTION "The SymCrypt engine and provider for OpenSSL (SCOSSL)" HOMEPAGE_URL "https://github.com/microsoft/SymCrypt-OpenSSL") From 1cf36dccf3e3ff5b801fe2b35ef85e1caa157ca5 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Thu, 23 Apr 2026 16:47:23 +0000 Subject: [PATCH 10/11] Check whether RSA key is valid for non-TLS case if out is non-null --- .../src/asymcipher/p_scossl_rsa_cipher.c | 12 ++++++------ SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c | 2 -- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c b/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c index 70bc21fa..444ac7ad 100644 --- a/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c +++ b/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c @@ -244,14 +244,14 @@ static SCOSSL_STATUS p_scossl_rsa_cipher_decrypt(_In_ SCOSSL_RSA_CIPHER_CTX *ctx else { cbModulus = SymCryptRsakeySizeofModulus(ctx->keyCtx->key); - if (out == NULL) + if (cbModulus == 0) { - if (cbModulus == 0) - { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); - return SCOSSL_FAILURE; - } + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); + return SCOSSL_FAILURE; + } + if (out == NULL) + { *outlen = cbModulus; return SCOSSL_SUCCESS; } diff --git a/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c b/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c index 94f2bc3d..74cb24df 100644 --- a/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c +++ b/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c @@ -1377,8 +1377,6 @@ static SCOSSL_STATUS p_scossl_x25519_keymgmt_import(_Inout_ SCOSSL_ECC_KEY_CTX * goto cleanup; } - // Match the default OpenSSL provider by rejecting empty or short - // raw X25519 private keys before applying RFC 7748 clamping. if (cbPrivateKey != SCOSSL_X25519_KEY_SIZE) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); From 46cc4a6e6af1a18d6cf10f549cb80173aa8c8aae Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Thu, 23 Apr 2026 23:20:16 +0000 Subject: [PATCH 11/11] Use secure memory for x25519 private key import scratch space --- SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c b/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c index 74cb24df..0e6bfcb6 100644 --- a/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c +++ b/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c @@ -1334,6 +1334,7 @@ static SCOSSL_STATUS p_scossl_x25519_keymgmt_import(_Inout_ SCOSSL_ECC_KEY_CTX * SCOSSL_STATUS ret = SCOSSL_FAILURE; PSYMCRYPT_ECKEY ecKey = NULL; PBYTE pbPrivateKey = NULL; + PCBYTE pcbPrivateKey = NULL; SIZE_T cbPrivateKey = 0; PBYTE pbPublicKey = NULL; SIZE_T cbPublicKey = 0; @@ -1371,7 +1372,7 @@ static SCOSSL_STATUS p_scossl_x25519_keymgmt_import(_Inout_ SCOSSL_ECC_KEY_CTX * if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY)) != NULL) { - if (!OSSL_PARAM_get_octet_string(p, (void **)&pbPrivateKey, 0, &cbPrivateKey)) + if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&pcbPrivateKey, &cbPrivateKey)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); goto cleanup; @@ -1383,6 +1384,13 @@ static SCOSSL_STATUS p_scossl_x25519_keymgmt_import(_Inout_ SCOSSL_ECC_KEY_CTX * goto cleanup; } + if ((pbPrivateKey = OPENSSL_secure_malloc(cbPrivateKey)) == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + goto cleanup; + } + memcpy(pbPrivateKey, pcbPrivateKey, cbPrivateKey); + // Preserve original bits for export modifiedPrivateBits = pbPrivateKey[0] & 0x07; modifiedPrivateBits |= pbPrivateKey[cbPrivateKey-1] & 0xc0;