From 01039856037a3c7f8f1b05b5970a39394ea6c25e Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Mon, 13 Apr 2026 23:33:34 +0000 Subject: [PATCH 01/15] 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 c70fb6b3..18e616da 100644 --- a/SymCryptProvider/src/keymgmt/p_scossl_rsa_keymgmt.c +++ b/SymCryptProvider/src/keymgmt/p_scossl_rsa_keymgmt.c @@ -1045,7 +1045,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; } @@ -1063,7 +1063,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 dfbca8bdfc5015a124c286a4cd2a993d3e5fb942 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Mon, 13 Apr 2026 23:48:21 +0000 Subject: [PATCH 02/15] 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 d31c4837..df88154d 100644 --- a/ScosslCommon/src/scossl_dh.c +++ b/ScosslCommon/src/scossl_dh.c @@ -75,7 +75,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 a0655e4bc9274c3543320fce76a3040b8894f32e Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Tue, 14 Apr 2026 16:51:43 +0000 Subject: [PATCH 03/15] 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 0b1d6f7f..038e33ca 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" { @@ -132,11 +133,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) @@ -158,6 +160,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) @@ -185,11 +200,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) @@ -204,6 +220,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 973dd6aa2f27ee54b5409a9969530b1576e6bc2d Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Tue, 14 Apr 2026 16:55:38 +0000 Subject: [PATCH 04/15] 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 b0dacb33..1c0f0895 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 430e790b8350c130b45d4c0bbff72f1d96177c93 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Tue, 14 Apr 2026 20:04:57 +0000 Subject: [PATCH 05/15] 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 de6cc749a945f0b22b21890320be4f5d81b9678d Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Tue, 14 Apr 2026 21:45:31 +0000 Subject: [PATCH 06/15] 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 e56908c3..813a34a9 100644 --- a/SymCryptProvider/src/ciphers/p_scossl_aes.c +++ b/SymCryptProvider/src/ciphers/p_scossl_aes.c @@ -789,7 +789,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 858cead22b530df7443358fb9cc0a78a848f62b6 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Tue, 14 Apr 2026 22:17:07 +0000 Subject: [PATCH 07/15] 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 038e33ca..43c6a376 100644 --- a/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c +++ b/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c @@ -167,6 +167,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 3d5e3e0449cb1254f3cc6ca8be3fe8332ed7cbc4 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Tue, 28 Apr 2026 22:52:55 +0000 Subject: [PATCH 08/15] Use correct cleanup for ML-KEM decode Co-authored-by: Copilot --- SymCryptProvider/src/decoder/p_scossl_decode_mlkem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SymCryptProvider/src/decoder/p_scossl_decode_mlkem.c b/SymCryptProvider/src/decoder/p_scossl_decode_mlkem.c index 9c73020c..4149fb08 100644 --- a/SymCryptProvider/src/decoder/p_scossl_decode_mlkem.c +++ b/SymCryptProvider/src/decoder/p_scossl_decode_mlkem.c @@ -113,7 +113,7 @@ static SCOSSL_MLKEM_KEY_CTX *p_scossl_SubjectPublicKeyInfo_to_mlkem(_In_ SCOSSL_ ASN1_STRING_get0_data(subjPubKeyInfo->subjectPublicKey), ASN1_STRING_length(subjPubKeyInfo->subjectPublicKey)); cleanup: - OPENSSL_free(subjPubKeyInfo); + ASN1_item_free((ASN1_VALUE *)subjPubKeyInfo, p_scossl_decode_subject_pubkey_asn1_item()); return keyCtx; } From 88fd6806858cfee8eb831c244b8a0a6ff78a3a7b Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Thu, 23 Apr 2026 16:47:23 +0000 Subject: [PATCH 09/15] Check whether RSA key is valid for non-TLS case if out is non-null --- .../src/asymcipher/p_scossl_rsa_cipher.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c b/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c index 43c6a376..d2c94960 100644 --- a/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c +++ b/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c @@ -242,14 +242,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; } From 108de0e49d87a5f4bc72dffa387281e162a0a812 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Thu, 7 May 2026 18:48:05 +0000 Subject: [PATCH 10/15] PR comments --- ScosslCommon/src/scossl_mac.c | 2 ++ SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ScosslCommon/src/scossl_mac.c b/ScosslCommon/src/scossl_mac.c index 4ba3c2e5..28247d7c 100644 --- a/ScosslCommon/src/scossl_mac.c +++ b/ScosslCommon/src/scossl_mac.c @@ -344,6 +344,8 @@ SCOSSL_STATUS scossl_mac_init(SCOSSL_MAC_CTX *ctx, if (pbKey != NULL) { + ctx->initialized = FALSE; + if (ctx->expandedKey == NULL) { SCOSSL_COMMON_ALIGNED_ALLOC_EX(expandedKey, OPENSSL_malloc, SCOSSL_MAC_EXPANDED_KEY, ctx->pMac->expandedKeySize); diff --git a/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c b/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c index d2c94960..bad9bf40 100644 --- a/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c +++ b/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c @@ -80,7 +80,16 @@ static void p_scossl_rsa_cipher_freectx(_Inout_ SCOSSL_RSA_CIPHER_CTX *ctx) static SCOSSL_RSA_CIPHER_CTX *p_scossl_rsa_cipher_dupctx(_Inout_ SCOSSL_RSA_CIPHER_CTX *ctx) { - return OPENSSL_memdup(ctx, sizeof(SCOSSL_RSA_CIPHER_CTX)); + SCOSSL_RSA_CIPHER_CTX *copyCtx = OPENSSL_memdup(ctx, sizeof(SCOSSL_RSA_CIPHER_CTX)); + + if (copyCtx != NULL && ctx->pbLabel != NULL && + (copyCtx->pbLabel = OPENSSL_memdup(ctx->pbLabel, ctx->cbLabel)) == NULL) + { + OPENSSL_free(copyCtx); + copyCtx = NULL; + } + + return copyCtx; } static SCOSSL_STATUS p_scossl_rsa_cipher_init(_Inout_ SCOSSL_RSA_CIPHER_CTX *ctx, _In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, From 72405f2834f07553065e2f6739335b9f4bf9311c Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Thu, 7 May 2026 23:02:11 +0000 Subject: [PATCH 11/15] PR comment --- ScosslCommon/src/scossl_mac.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ScosslCommon/src/scossl_mac.c b/ScosslCommon/src/scossl_mac.c index 28247d7c..aa07fa39 100644 --- a/ScosslCommon/src/scossl_mac.c +++ b/ScosslCommon/src/scossl_mac.c @@ -373,6 +373,8 @@ SCOSSL_STATUS scossl_mac_init(SCOSSL_MAC_CTX *ctx, if (!ctx->initialized) { + SCOSSL_LOG_ERROR(SCOSSL_ERR_F_MAC_INIT, SCOSSL_ERR_R_MISSING_CTX_DATA, + "MAC key has not been initialized"); return SCOSSL_FAILURE; } From 43eb8abc6eb77916008cedb113abfebfa6ca9a29 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Fri, 8 May 2026 00:15:40 +0000 Subject: [PATCH 12/15] Use secure memory for x25519 private key import scratch space. Validate x25519 size --- .../src/keymgmt/p_scossl_ecc_keymgmt.c | 67 ++++++++++++++++--- SymCryptProvider/src/p_scossl_ecc.c | 4 +- SymCryptProvider/src/p_scossl_ecc.h | 2 + 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c b/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c index 5681b523..23a15632 100644 --- a/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c +++ b/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c @@ -13,7 +13,6 @@ extern "C" { #endif -#define SCOSSL_X25519_MAX_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) @@ -1069,10 +1068,13 @@ 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; + PCBYTE pcbPrivateKey = NULL; SIZE_T cbPrivateKey = 0; PBYTE pbPublicKey = NULL; SIZE_T cbPublicKey = 0; + BYTE modifiedPrivateBits = 0; const OSSL_PARAM *p; // Other parameters @@ -1089,12 +1091,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)) @@ -1102,43 +1098,92 @@ 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) { - 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; } + if (cbPrivateKey != SCOSSL_X25519_KEY_SIZE) + { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + 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 - 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); diff --git a/SymCryptProvider/src/p_scossl_ecc.c b/SymCryptProvider/src/p_scossl_ecc.c index 704c7803..77a7f244 100644 --- a/SymCryptProvider/src/p_scossl_ecc.c +++ b/SymCryptProvider/src/p_scossl_ecc.c @@ -11,8 +11,6 @@ extern "C" { #endif -#define SCOSSL_X25519_MAX_SIZE (32) - _Use_decl_annotations_ SCOSSL_ECC_KEY_CTX *p_scossl_ecc_new_ctx(SCOSSL_PROVCTX *provctx) { @@ -234,7 +232,7 @@ SIZE_T p_scossl_ecc_get_max_result_size(_In_ SCOSSL_ECC_KEY_CTX *keyCtx, BOOL is { if (keyCtx->isX25519) { - return SCOSSL_X25519_MAX_SIZE; + return SCOSSL_X25519_KEY_SIZE; } else if (isEcdh) { diff --git a/SymCryptProvider/src/p_scossl_ecc.h b/SymCryptProvider/src/p_scossl_ecc.h index ff02ef64..2798cb71 100644 --- a/SymCryptProvider/src/p_scossl_ecc.h +++ b/SymCryptProvider/src/p_scossl_ecc.h @@ -40,6 +40,8 @@ typedef struct { #endif } SCOSSL_ECC_KEY_CTX; +#define SCOSSL_X25519_KEY_SIZE (32) + SCOSSL_ECC_KEY_CTX *p_scossl_ecc_new_ctx(_In_ SCOSSL_PROVCTX *provctx); void p_scossl_ecc_free_ctx(_Inout_ SCOSSL_ECC_KEY_CTX *keyCtx); SCOSSL_ECC_KEY_CTX *p_scossl_ecc_dup_ctx(_In_ SCOSSL_ECC_KEY_CTX *keyCtx, int selection); From 8a7677229e4d3105572c9b9ff9b11d245309bf8b Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Fri, 8 May 2026 00:33:56 +0000 Subject: [PATCH 13/15] Fix skeymgmt compiler warning --- SymCryptProvider/src/skeymgmt/p_scossl_generic_skeymgmt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SymCryptProvider/src/skeymgmt/p_scossl_generic_skeymgmt.c b/SymCryptProvider/src/skeymgmt/p_scossl_generic_skeymgmt.c index 6f7345a8..1a35e3d0 100644 --- a/SymCryptProvider/src/skeymgmt/p_scossl_generic_skeymgmt.c +++ b/SymCryptProvider/src/skeymgmt/p_scossl_generic_skeymgmt.c @@ -115,7 +115,8 @@ SCOSSL_STATUS p_scossl_generic_skeymgmt_export(SCOSSL_SKEY *skey, int selection, return SCOSSL_FAILURE; } - params[0] = OSSL_PARAM_construct_octet_string(OSSL_SKEY_PARAM_RAW_BYTES, skey->cbKey > 0 ? skey->pbKey : "", skey->cbKey); + // The parameter data should be read only in param_cb so it's safe to cast "" to PBYTE in the case of a zero-length key. + params[0] = OSSL_PARAM_construct_octet_string(OSSL_SKEY_PARAM_RAW_BYTES, skey->cbKey > 0 ? skey->pbKey : (PBYTE)"", skey->cbKey); params[1] = OSSL_PARAM_construct_end(); return param_cb(params, cbarg); From 7a1c1bfa0ef09c42e16ad5609f74c70a52ef21c7 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Fri, 8 May 2026 00:38:49 +0000 Subject: [PATCH 14/15] cleanup --- SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c b/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c index bad9bf40..352683b7 100644 --- a/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c +++ b/SymCryptProvider/src/asymcipher/p_scossl_rsa_cipher.c @@ -142,8 +142,8 @@ 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; @@ -215,8 +215,8 @@ 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; From 87a3b980ad3e1d4a887aba84692f92bfa5aa0ba4 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Mon, 11 May 2026 20:19:52 +0000 Subject: [PATCH 15/15] Use fallthrough comment instead of attribute --- 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 813a34a9..6b1a58b8 100644 --- a/SymCryptProvider/src/ciphers/p_scossl_aes.c +++ b/SymCryptProvider/src/ciphers/p_scossl_aes.c @@ -355,7 +355,7 @@ static SCOSSL_STATUS p_scossl_aes_generic_block_update(_Inout_ SCOSSL_AES_CTX *c case DTLS1_BAD_VER: out += SYMCRYPT_AES_BLOCK_SIZE; *outl -= SYMCRYPT_AES_BLOCK_SIZE; - __attribute__ ((fallthrough)); + /* fallthrough */ case TLS1_VERSION: return p_scossl_aes_tls_remove_padding_and_copy_mac(ctx, out, outl); break;