Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ScosslCommon/inc/scossl_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions ScosslCommon/src/scossl_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
Expand Down
49 changes: 37 additions & 12 deletions ScosslCommon/src/scossl_mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -118,14 +120,32 @@ 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_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;
}

copyCtx->macState = macState;
ctx->pMacEx->stateCopyFunc(ctx->macState, ctx->expandedKey, copyCtx->macState);
ctx->pMacEx->stateCopyFunc(ctx->macState, copyCtx->expandedKey, copyCtx->macState);
}
}

Expand Down Expand Up @@ -311,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)
Expand Down
40 changes: 21 additions & 19 deletions SymCryptProvider/src/ciphers/p_scossl_aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
24 changes: 21 additions & 3 deletions SymCryptProvider/src/kem/p_scossl_mlkem.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,31 @@ extern "C" {

#define SCOSSL_MLKEM_SECRET_LENGTH 32

#ifndef OSSL_KEM_PARAM_IKME
#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.
// 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 "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
#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, 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_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
{
Expand Down
10 changes: 8 additions & 2 deletions SymCryptProvider/src/keyexch/p_scossl_dh.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 4 additions & 2 deletions SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
31 changes: 29 additions & 2 deletions SymCryptProvider/src/signature/p_scossl_ecdsa_signature.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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)
{
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions SymCryptProvider/src/signature/p_scossl_rsa_signature.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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)
{
Expand Down