From 63a2e01c22c5db784520da8e58188b60e1212688 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee <66395252+mamckee@users.noreply.github.com> Date: Wed, 17 Sep 2025 08:35:28 -0700 Subject: [PATCH 1/8] Additional fixes for block ciphers in TLS connections (#145) * Allow optional mac in TLS block decrypt * Fix issue found for TLSv1 connections * Bump minor version * Add comments describing etm behavior --- SymCryptProvider/src/ciphers/p_scossl_aes.c | 40 +++++++++++---------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/SymCryptProvider/src/ciphers/p_scossl_aes.c b/SymCryptProvider/src/ciphers/p_scossl_aes.c index 1bc3f15..c864a58 100644 --- a/SymCryptProvider/src/ciphers/p_scossl_aes.c +++ b/SymCryptProvider/src/ciphers/p_scossl_aes.c @@ -151,7 +151,10 @@ static SCOSSL_STATUS p_scossl_aes_generic_decrypt_init(_Inout_ SCOSSL_AES_CTX *c #define SYMCRYPT_OPENSSL_MASK8_SELECT( _mask, _a, _b ) (SYMCRYPT_FORCE_READ8(&_mask) & _a) | (~(SYMCRYPT_FORCE_READ8(&_mask)) & _b) // Verifies the TLS padding from the end of record, extracts the MAC from the end of -// the unpadded record, and saves the result to ctx->tlsMac. +// the unpadded record, and saves the result to ctx->tlsMac. +// +// If ctx->tlsMacSize is 0 (in the case of encrypt-then-mac), no MAC is extracted, +// but the padding is still verified and removed. // // 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 @@ -199,12 +202,6 @@ static SCOSSL_STATUS p_scossl_aes_tls_remove_padding_and_copy_mac( return SCOSSL_FAILURE; } - if ((ctx->tlsMac = OPENSSL_malloc(ctx->tlsMacSize)) == NULL) - { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - return SCOSSL_FAILURE; - } - // We only care about the tail of the input buffer, which we can index with UINT32 indices // The if() is safe as both cbData and u32 are public values. u32 = ctx->tlsMacSize + 255 + 1; @@ -247,15 +244,25 @@ static SCOSSL_STATUS p_scossl_aes_tls_remove_padding_and_copy_mac( paddingStatus |= (BYTE)((~SYMCRYPT_MASK32_EQ(recordByte, cbPad)) & (~macNotEnded)); } - // MAC rotation - for (i = 0; i < ctx->tlsMacSize; i++) + // Public info, safe to branch + if (ctx->tlsMacSize > 0) { - BYTE macByte = 0; - for (j = 0; j < ctx->tlsMacSize; j++) { - UINT32 match = SYMCRYPT_MASK32_EQ(j, (rotateOffset + i) % ctx->tlsMacSize); - macByte |= rotatedMac[j] & match; + if ((ctx->tlsMac = OPENSSL_malloc(ctx->tlsMacSize)) == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return SCOSSL_FAILURE; + } + + // MAC rotation + for (i = 0; i < ctx->tlsMacSize; i++) + { + BYTE macByte = 0; + for (j = 0; j < ctx->tlsMacSize; j++) { + UINT32 match = SYMCRYPT_MASK32_EQ(j, (rotateOffset + i) % ctx->tlsMacSize); + macByte |= rotatedMac[j] & match; + } + ctx->tlsMac[i] = SYMCRYPT_OPENSSL_MASK8_SELECT(paddingStatus, randMac[i], macByte); } - ctx->tlsMac[i] = SYMCRYPT_OPENSSL_MASK8_SELECT(paddingStatus, randMac[i], macByte); } *pcbData -= (1 + cbPad + ctx->tlsMacSize); @@ -292,11 +299,6 @@ static SCOSSL_STATUS p_scossl_aes_generic_block_update(_Inout_ SCOSSL_AES_CTX *c SIZE_T cbInFullBlocks = 0; *outl = 0; - if (inl == 0) - { - return SCOSSL_SUCCESS; - } - if (ctx->tlsVersion > 0) { // Each update call corresponds to a TLS record and is individually padded From 5f31c5e849984d12f65cfdd069f6551ec28a8b5d Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee <66395252+mamckee@users.noreply.github.com> Date: Mon, 20 Oct 2025 16:58:17 -0700 Subject: [PATCH 2/8] Bugfixes for 1.9 (#150) * Add OSSL_SIGNATURE_PARAM_NONCE_TYPE to ECDSA signature * Only optimize debug release builds * Only export EC public/private if available * Fix HMAC dupctx * Bump version to 1.9.4 * Add goto cleanup --- ScosslCommon/inc/scossl_helpers.h | 1 + ScosslCommon/src/scossl_helpers.c | 1 + ScosslCommon/src/scossl_mac.c | 8 +++++- .../src/keymgmt/p_scossl_ecc_keymgmt.c | 6 +++-- .../src/signature/p_scossl_ecdsa_signature.c | 27 +++++++++++++++++++ 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/ScosslCommon/inc/scossl_helpers.h b/ScosslCommon/inc/scossl_helpers.h index 06f1f85..a7122a0 100644 --- a/ScosslCommon/inc/scossl_helpers.h +++ b/ScosslCommon/inc/scossl_helpers.h @@ -118,6 +118,7 @@ typedef enum { SCOSSL_ERR_F_GET_SYMCRYPT_HASH_ALGORITHM, SCOSSL_ERR_F_GET_SYMCRYPT_MAC_ALGORITHM, SCOSSL_ERR_F_HKDF_DERIVE, + SCOSSL_ERR_F_MAC_DUPCTX, SCOSSL_ERR_F_MAC_INIT, SCOSSL_ERR_F_MAC_SET_HMAC_MD, SCOSSL_ERR_F_RSA_DECRYPT, diff --git a/ScosslCommon/src/scossl_helpers.c b/ScosslCommon/src/scossl_helpers.c index 8ada248..ce3f6ff 100644 --- a/ScosslCommon/src/scossl_helpers.c +++ b/ScosslCommon/src/scossl_helpers.c @@ -78,6 +78,7 @@ static ERR_STRING_DATA SCOSSL_ERR_function_strings[] = { {ERR_PACK(0, SCOSSL_ERR_F_GET_SYMCRYPT_HASH_ALGORITHM, 0), "scossl_get_symcrypt_hash_algorithm"}, {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_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_RSA_DECRYPT, 0), "scossl_rsa_decrypt"}, diff --git a/ScosslCommon/src/scossl_mac.c b/ScosslCommon/src/scossl_mac.c index f217f1c..b7c191a 100644 --- a/ScosslCommon/src/scossl_mac.c +++ b/ScosslCommon/src/scossl_mac.c @@ -118,6 +118,12 @@ SCOSSL_MAC_CTX *scossl_mac_dupctx(SCOSSL_MAC_CTX *ctx) if (ctx->macState != NULL) { + if (copyCtx->expandedKey == NULL) + { + SCOSSL_LOG_ERROR(SCOSSL_ERR_F_MAC_DUPCTX, ERR_R_INTERNAL_ERROR, + "Missing expandedKey in mac context when attempting to copy macState"); + goto cleanup; + } SCOSSL_COMMON_ALIGNED_ALLOC_EX(macState, OPENSSL_malloc, SCOSSL_MAC_STATE, ctx->pMac->stateSize); if (macState == NULL) { @@ -125,7 +131,7 @@ SCOSSL_MAC_CTX *scossl_mac_dupctx(SCOSSL_MAC_CTX *ctx) } copyCtx->macState = macState; - ctx->pMacEx->stateCopyFunc(ctx->macState, ctx->expandedKey, copyCtx->macState); + ctx->pMacEx->stateCopyFunc(ctx->macState, copyCtx->expandedKey, copyCtx->macState); } } diff --git a/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c b/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c index c3a2f7e..5681b52 100644 --- a/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c +++ b/SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c @@ -999,9 +999,11 @@ static SCOSSL_STATUS p_scossl_ecc_keymgmt_export(_In_ SCOSSL_ECC_KEY_CTX *keyCtx goto cleanup; } - if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) + if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0 && + keyCtx->initialized) { - if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 && + SymCryptEckeyHasPrivateKey(keyCtx->key)) { if (!p_scossl_ecc_keymgmt_get_private_key_bn(keyCtx, &bnPrivateKey, &cbPrivateKey) || !OSSL_PARAM_BLD_push_BN_pad(bld, OSSL_PKEY_PARAM_PRIV_KEY, bnPrivateKey, cbPrivateKey)) diff --git a/SymCryptProvider/src/signature/p_scossl_ecdsa_signature.c b/SymCryptProvider/src/signature/p_scossl_ecdsa_signature.c index 117a01c..e350c9a 100644 --- a/SymCryptProvider/src/signature/p_scossl_ecdsa_signature.c +++ b/SymCryptProvider/src/signature/p_scossl_ecdsa_signature.c @@ -372,6 +372,24 @@ static SCOSSL_STATUS p_scossl_ecdsa_set_ctx_params(_Inout_ SCOSSL_ECDSA_CTX *ctx return SCOSSL_FAILURE; } +#ifdef OSSL_SIGNATURE_PARAM_NONCE_TYPE + if ((p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE)) != NULL) + { + unsigned int nonce_type; + if (!OSSL_PARAM_get_uint(p, &nonce_type)) + { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return SCOSSL_FAILURE; + } + + if (nonce_type != 0) + { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED); + return SCOSSL_FAILURE; + } + } +#endif + return SCOSSL_SUCCESS; } @@ -406,6 +424,15 @@ static SCOSSL_STATUS p_scossl_ecdsa_get_ctx_params(_In_ SCOSSL_ECDSA_CTX *ctx, _ goto cleanup; } +#ifdef OSSL_SIGNATURE_PARAM_NONCE_TYPE + if ((p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE)) != NULL && + !OSSL_PARAM_set_uint(p, 0)) + { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + goto cleanup; + } +#endif + if ((p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID)) != NULL) { int cbAid; From bbcb6809578e29f9089c0fe7bc7c72fac411075a Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee <66395252+mamckee@users.noreply.github.com> Date: Fri, 16 Jan 2026 13:40:09 -0800 Subject: [PATCH 3/8] Allow MAC context duplication for partially initialized contexts (#156) * Fix context duplication for partially initialized mac contexts * Check mac state in init * Fix error messages --- ScosslCommon/src/scossl_mac.c | 47 ++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/ScosslCommon/src/scossl_mac.c b/ScosslCommon/src/scossl_mac.c index b7c191a..66b5814 100644 --- a/ScosslCommon/src/scossl_mac.c +++ b/ScosslCommon/src/scossl_mac.c @@ -109,6 +109,8 @@ SCOSSL_MAC_CTX *scossl_mac_dupctx(SCOSSL_MAC_CTX *ctx) 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_DUPCTX, ERR_R_MALLOC_FAILURE, + "Failed to aligned allocate expanded key"); goto cleanup; } @@ -118,15 +120,27 @@ SCOSSL_MAC_CTX *scossl_mac_dupctx(SCOSSL_MAC_CTX *ctx) if (ctx->macState != NULL) { + // A caller can potentially initialize a MAC context with state but no key (e.g. HMAC with digest set, but no key yet). + // SymCrypt HMAC and CMAC state copy functions allow us to pass NULL for the expanded key parameter, but the key from + // ctx will be set in copyCtx->macState, which is undesirable. Instead, allocate an empty expanded key in copyCtx. if (copyCtx->expandedKey == NULL) { - SCOSSL_LOG_ERROR(SCOSSL_ERR_F_MAC_DUPCTX, ERR_R_INTERNAL_ERROR, - "Missing expandedKey in mac context when attempting to copy macState"); - goto cleanup; + 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_DUPCTX, ERR_R_MALLOC_FAILURE, + "Failed to aligned allocate expanded key"); + goto cleanup; + } + + copyCtx->expandedKey = expandedKey; } + SCOSSL_COMMON_ALIGNED_ALLOC_EX(macState, OPENSSL_malloc, SCOSSL_MAC_STATE, ctx->pMac->stateSize); if (macState == NULL) { + SCOSSL_LOG_ERROR(SCOSSL_ERR_F_MAC_DUPCTX, ERR_R_MALLOC_FAILURE, + "Failed to aligned allocate mac state"); goto cleanup; } @@ -317,21 +331,26 @@ SCOSSL_STATUS scossl_mac_init(SCOSSL_MAC_CTX *ctx, { SYMCRYPT_ERROR scError; - if (pbKey != NULL) + if (ctx->pMac == NULL || ctx->macState == NULL) { - if (ctx->expandedKey == NULL) - { - 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_INTERNAL_ERROR, - "Failed to aligned allocated expanded key"); - return SCOSSL_FAILURE; - } + return SCOSSL_FAILURE; + } - ctx->expandedKey = expandedKey; + if (ctx->expandedKey == NULL) + { + 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; + } + + if (pbKey != NULL) + { scError = ctx->pMac->expandKeyFunc(ctx->expandedKey, pbKey, cbKey); if (scError != SYMCRYPT_NO_ERROR) From e4294db0bd2334cc119b76cab09a4f9ce5aa67e0 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Mon, 26 Jan 2026 23:38:54 +0000 Subject: [PATCH 4/8] Fix compilation --- SymCryptProvider/src/keyexch/p_scossl_dh.c | 10 ++++++++-- .../src/signature/p_scossl_ecdsa_signature.c | 4 ++-- .../src/signature/p_scossl_rsa_signature.c | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/SymCryptProvider/src/keyexch/p_scossl_dh.c b/SymCryptProvider/src/keyexch/p_scossl_dh.c index 670df5e..00ab7fe 100644 --- a/SymCryptProvider/src/keyexch/p_scossl_dh.c +++ b/SymCryptProvider/src/keyexch/p_scossl_dh.c @@ -60,6 +60,12 @@ static const OSSL_PARAM p_scossl_dh_ctx_gettable_param_types[] = { OSSL_PARAM_END}; static SCOSSL_STATUS p_scossl_dh_set_ctx_params(_Inout_ SCOSSL_DH_CTX *ctx, _In_ const OSSL_PARAM params[]); +#if OPENSSL_VERSION_MAJOR == 3 && OPENSSL_VERSION_MINOR < 4 +int EVP_MD_xof(const EVP_MD *md) +{ + return md != NULL && ((EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0); +} +#endif // OPENSSL_VERSION_MAJOR == 3 && OPENSSL_VERSION_MINOR < 4 static SCOSSL_DH_CTX *p_scossl_dh_newctx(_In_ SCOSSL_PROVCTX *provctx) { @@ -323,8 +329,8 @@ static SCOSSL_STATUS p_scossl_dh_derive(_In_ SCOSSL_DH_CTX *ctx, static SCOSSL_STATUS p_scossl_dh_set_ctx_params(_Inout_ SCOSSL_DH_CTX *ctx, _In_ const OSSL_PARAM params[]) { - const char *mdName = NULL; - const char *mdProps = NULL; + char *mdName = NULL; + char *mdProps = NULL; EVP_MD *md = NULL; SCOSSL_STATUS ret = SCOSSL_FAILURE; const OSSL_PARAM *p = NULL; diff --git a/SymCryptProvider/src/signature/p_scossl_ecdsa_signature.c b/SymCryptProvider/src/signature/p_scossl_ecdsa_signature.c index e350c9a..f455901 100644 --- a/SymCryptProvider/src/signature/p_scossl_ecdsa_signature.c +++ b/SymCryptProvider/src/signature/p_scossl_ecdsa_signature.c @@ -285,7 +285,7 @@ static SCOSSL_STATUS p_scossl_ecdsa_digest_sign_final(_In_ SCOSSL_ECDSA_CTX *ctx _Out_writes_bytes_(*siglen) unsigned char *sig, _Out_ size_t *siglen, size_t sigsize) { BYTE digest[EVP_MAX_MD_SIZE]; - SIZE_T cbDigest = 0; + unsigned int cbDigest = 0; if (ctx->mdctx == NULL) { @@ -310,7 +310,7 @@ static int p_scossl_ecdsa_digest_verify_final(_In_ SCOSSL_ECDSA_CTX *ctx, _In_reads_bytes_(siglen) unsigned char *sig, size_t siglen) { BYTE digest[EVP_MAX_MD_SIZE]; - SIZE_T cbDigest = 0; + unsigned int cbDigest = 0; if (ctx->mdctx == NULL) { diff --git a/SymCryptProvider/src/signature/p_scossl_rsa_signature.c b/SymCryptProvider/src/signature/p_scossl_rsa_signature.c index 81f86b8..43d0783 100644 --- a/SymCryptProvider/src/signature/p_scossl_rsa_signature.c +++ b/SymCryptProvider/src/signature/p_scossl_rsa_signature.c @@ -394,7 +394,7 @@ static SCOSSL_STATUS p_scossl_rsa_digest_sign_final(_In_ SCOSSL_RSA_SIGN_CTX *ct { SCOSSL_STATUS ret = SCOSSL_FAILURE; BYTE digest[EVP_MAX_MD_SIZE]; - SIZE_T cbDigest = 0; + unsigned int cbDigest = 0; if (ctx->mdctx == NULL) { @@ -415,7 +415,7 @@ static SCOSSL_STATUS p_scossl_rsa_digest_verify_final(_In_ SCOSSL_RSA_SIGN_CTX * _In_reads_bytes_(siglen) unsigned char *sig, size_t siglen) { BYTE digest[EVP_MAX_MD_SIZE]; - SIZE_T cbDigest = 0; + unsigned int cbDigest = 0; if (ctx->mdctx == NULL) { From 425fd75434a2ddf25e116fe4ce982af6e25223ac Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Wed, 4 Feb 2026 00:45:36 +0000 Subject: [PATCH 5/8] Add missing parameter on older versions --- SymCryptProvider/src/kem/p_scossl_mlkem.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SymCryptProvider/src/kem/p_scossl_mlkem.c b/SymCryptProvider/src/kem/p_scossl_mlkem.c index 5903b77..7843d07 100644 --- a/SymCryptProvider/src/kem/p_scossl_mlkem.c +++ b/SymCryptProvider/src/kem/p_scossl_mlkem.c @@ -14,6 +14,10 @@ extern "C" { #define SCOSSL_MLKEM_SECRET_LENGTH 32 +#ifndef OSSL_KEM_PARAM_IKME +#define OSSL_KEM_PARAM_IKME "ikme" +#endif + static SCOSSL_MLKEM_GROUP_INFO p_scossl_mlkem_groups[] = { {NID_undef, SCOSSL_OID_MLKEM512, SCOSSL_SN_MLKEM512, SCOSSL_LN_MLKEM512, SYMCRYPT_MLKEM_PARAMS_MLKEM512}, {NID_undef, SCOSSL_OID_MLKEM768, SCOSSL_SN_MLKEM768, SCOSSL_LN_MLKEM768, SYMCRYPT_MLKEM_PARAMS_MLKEM768}, From d4f7e6c31dea46c2fc9e18326db879eec71846ae Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Fri, 6 Feb 2026 18:32:19 +0000 Subject: [PATCH 6/8] Fix errors in OpenSSL 3.0 builds --- SymCryptProvider/src/kem/p_scossl_mlkem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SymCryptProvider/src/kem/p_scossl_mlkem.c b/SymCryptProvider/src/kem/p_scossl_mlkem.c index 7843d07..fe57f90 100644 --- a/SymCryptProvider/src/kem/p_scossl_mlkem.c +++ b/SymCryptProvider/src/kem/p_scossl_mlkem.c @@ -22,9 +22,9 @@ static SCOSSL_MLKEM_GROUP_INFO p_scossl_mlkem_groups[] = { {NID_undef, SCOSSL_OID_MLKEM512, SCOSSL_SN_MLKEM512, SCOSSL_LN_MLKEM512, SYMCRYPT_MLKEM_PARAMS_MLKEM512}, {NID_undef, SCOSSL_OID_MLKEM768, SCOSSL_SN_MLKEM768, SCOSSL_LN_MLKEM768, SYMCRYPT_MLKEM_PARAMS_MLKEM768}, {NID_undef, SCOSSL_OID_MLKEM1024, SCOSSL_SN_MLKEM1024, SCOSSL_LN_MLKEM1024, SYMCRYPT_MLKEM_PARAMS_MLKEM1024}, - {NID_undef, NULL, SCOSSL_SN_P256_MLKEM768, SCOSSL_LN_P256_MLKEM768, SYMCRYPT_MLKEM_PARAMS_MLKEM768}, - {NID_undef, NULL, SCOSSL_SN_X25519_MLKEM768, SCOSSL_LN_X25519_MLKEM768, SYMCRYPT_MLKEM_PARAMS_MLKEM768}, - {NID_undef, NULL, SCOSSL_SN_P384_MLKEM1024, SCOSSL_LN_P384_MLKEM1024, SYMCRYPT_MLKEM_PARAMS_MLKEM1024}}; + {NID_undef, "", SCOSSL_SN_P256_MLKEM768, SCOSSL_LN_P256_MLKEM768, SYMCRYPT_MLKEM_PARAMS_MLKEM768}, + {NID_undef, "", SCOSSL_SN_X25519_MLKEM768, SCOSSL_LN_X25519_MLKEM768, SYMCRYPT_MLKEM_PARAMS_MLKEM768}, + {NID_undef, "", SCOSSL_SN_P384_MLKEM1024, SCOSSL_LN_P384_MLKEM1024, SYMCRYPT_MLKEM_PARAMS_MLKEM1024}}; typedef struct { From 10a01de57808413aa79d0bb9634be80ae75651c8 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Sat, 7 Feb 2026 00:20:48 +0000 Subject: [PATCH 7/8] Use dummy OID on older versions for ml-kem composite --- SymCryptProvider/src/kem/p_scossl_mlkem.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/SymCryptProvider/src/kem/p_scossl_mlkem.c b/SymCryptProvider/src/kem/p_scossl_mlkem.c index fe57f90..e74b114 100644 --- a/SymCryptProvider/src/kem/p_scossl_mlkem.c +++ b/SymCryptProvider/src/kem/p_scossl_mlkem.c @@ -18,13 +18,25 @@ extern "C" { #define OSSL_KEM_PARAM_IKME "ikme" #endif +// Older versions of OBJ_create expect a non-NULL OID. This OID is never +// used for hybrid KEM groups, so just use a dummy OID for compatibility. +#if OPENSSL_VERSION_MAJOR == 3 && OPENSSL_VERSION_MINOR < 2 + #define SCOSSL_OID_P256_MLKEM768 "3.0.0.1" + #define SCOSSL_OID_X25519_MLKEM768 "3.0.0.2" + #define SCOSSL_OID_P384_MLKEM1024 "3.0.0.3" +#else + #define SCOSSL_OID_P256_MLKEM768 NULL + #define SCOSSL_OID_X25519_MLKEM768 NULL + #define SCOSSL_OID_P384_MLKEM1024 NULL +#endif + static SCOSSL_MLKEM_GROUP_INFO p_scossl_mlkem_groups[] = { {NID_undef, SCOSSL_OID_MLKEM512, SCOSSL_SN_MLKEM512, SCOSSL_LN_MLKEM512, SYMCRYPT_MLKEM_PARAMS_MLKEM512}, {NID_undef, SCOSSL_OID_MLKEM768, SCOSSL_SN_MLKEM768, SCOSSL_LN_MLKEM768, SYMCRYPT_MLKEM_PARAMS_MLKEM768}, {NID_undef, SCOSSL_OID_MLKEM1024, SCOSSL_SN_MLKEM1024, SCOSSL_LN_MLKEM1024, SYMCRYPT_MLKEM_PARAMS_MLKEM1024}, - {NID_undef, "", SCOSSL_SN_P256_MLKEM768, SCOSSL_LN_P256_MLKEM768, SYMCRYPT_MLKEM_PARAMS_MLKEM768}, - {NID_undef, "", SCOSSL_SN_X25519_MLKEM768, SCOSSL_LN_X25519_MLKEM768, SYMCRYPT_MLKEM_PARAMS_MLKEM768}, - {NID_undef, "", SCOSSL_SN_P384_MLKEM1024, SCOSSL_LN_P384_MLKEM1024, SYMCRYPT_MLKEM_PARAMS_MLKEM1024}}; + {NID_undef, SCOSSL_OID_P256_MLKEM768, SCOSSL_SN_P256_MLKEM768, SCOSSL_LN_P256_MLKEM768, SYMCRYPT_MLKEM_PARAMS_MLKEM768}, + {NID_undef, SCOSSL_OID_X25519_MLKEM768, SCOSSL_SN_X25519_MLKEM768, SCOSSL_LN_X25519_MLKEM768, SYMCRYPT_MLKEM_PARAMS_MLKEM768}, + {NID_undef, SCOSSL_OID_P384_MLKEM1024, SCOSSL_SN_P384_MLKEM1024, SCOSSL_LN_P384_MLKEM1024, SYMCRYPT_MLKEM_PARAMS_MLKEM1024}}; typedef struct { From 847e8c5b11468fbb5447a83bda5d6899fd7f6a07 Mon Sep 17 00:00:00 2001 From: Maxwell Moyer-McKee Date: Mon, 9 Feb 2026 18:04:20 +0000 Subject: [PATCH 8/8] Use valid dummy OID --- SymCryptProvider/src/kem/p_scossl_mlkem.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/SymCryptProvider/src/kem/p_scossl_mlkem.c b/SymCryptProvider/src/kem/p_scossl_mlkem.c index e74b114..fe577d3 100644 --- a/SymCryptProvider/src/kem/p_scossl_mlkem.c +++ b/SymCryptProvider/src/kem/p_scossl_mlkem.c @@ -20,10 +20,12 @@ extern "C" { // Older versions of OBJ_create expect a non-NULL OID. This OID is never // used for hybrid KEM groups, so just use a dummy OID for compatibility. +// These OIDs are the same as the ones used by the OQS provider, since +// OpenSSL at least expects a valid formatted OID. #if OPENSSL_VERSION_MAJOR == 3 && OPENSSL_VERSION_MINOR < 2 - #define SCOSSL_OID_P256_MLKEM768 "3.0.0.1" - #define SCOSSL_OID_X25519_MLKEM768 "3.0.0.2" - #define SCOSSL_OID_P384_MLKEM1024 "3.0.0.3" + #define SCOSSL_OID_P256_MLKEM768 "1.3.6.1.4.1.22554.5.7.1" + #define SCOSSL_OID_X25519_MLKEM768 "1.3.6.1.4.1.22554.5.7.2" + #define SCOSSL_OID_P384_MLKEM1024 "1.3.6.1.4.1.22554.5.8.1" #else #define SCOSSL_OID_P256_MLKEM768 NULL #define SCOSSL_OID_X25519_MLKEM768 NULL