Skip to content
2 changes: 2 additions & 0 deletions SymCryptProvider/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ set(SCOSSL_SOURCES
./src/kdf/p_scossl_sskdf.c
./src/kdf/p_scossl_tls1prf.c
./src/kem/p_scossl_mlkem.c
./src/kem/p_scossl_mlkem_hybrid.c
./src/keyexch/p_scossl_dh.c
./src/keyexch/p_scossl_ecdh.c
./src/keyexch/p_scossl_kdf_keyexch.c
./src/keymgmt/p_scossl_dh_keymgmt.c
./src/keymgmt/p_scossl_ecc_keymgmt.c
./src/keymgmt/p_scossl_kdf_keymgmt.c
./src/keymgmt/p_scossl_mlkem_keymgmt.c
./src/keymgmt/p_scossl_mlkem_hybrid_keymgmt.c
./src/keymgmt/p_scossl_rsa_keymgmt.c
./src/mac/p_scossl_cmac.c
./src/mac/p_scossl_hmac.c
Expand Down
15 changes: 10 additions & 5 deletions SymCryptProvider/inc/scossl_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,23 @@ extern "C" {
#define SCOSSL_LN_MLKEM1024 "ML-KEM-1024"
#define SCOSSL_OID_MLKEM1024 "2.16.840.1.101.3.4.4.3"

#define SCOSSL_SN_P256_MLKEM768 "id-alg-secp256r1-ml-kem-768"
#define SCOSSL_LN_P256_MLKEM768 "P256-ML-KEM-768"
#define SCOSSL_OID_P256_MLKEM768 "2.16.840.1.101.3.4.4.4"

#define SCOSSL_SN_X25519_MLKEM768 "id-alg-x25519-ml-kem-768"
#define SCOSSL_LN_X25519_MLKEM768 "X25519-ML-KEM-768"
#define SCOSSL_OID_X25519_MLKEM768 "2.16.840.1.101.3.4.4.5"
#define SCOSSL_OID_X25519_MLKEM768 "2.16.840.1.101.3.4.4.4"

#define SCOSSL_SN_P256_MLKEM768 "id-alg-secp256r1-ml-kem-768"
#define SCOSSL_LN_P256_MLKEM768 "P256-ML-KEM-768"
#define SCOSSL_OID_P256_MLKEM768 "2.16.840.1.101.3.4.4.5"

#define SCOSSL_SN_P384_MLKEM1024 "id-alg-secp384r1-ml-kem-1024"
#define SCOSSL_LN_P384_MLKEM1024 "P384-ML-KEM-1024"
#define SCOSSL_OID_P384_MLKEM1024 "2.16.840.1.101.3.4.4.6"
Comment thread
mamckee marked this conversation as resolved.
Outdated

// OpenSSL 3.5 parameters
#ifndef OSSL_PKEY_PARAM_ML_KEM_SEED
#define OSSL_PKEY_PARAM_ML_KEM_SEED "seed"
#endif

#ifdef __cplusplus
}
#endif
2 changes: 1 addition & 1 deletion SymCryptProvider/src/decoder/p_scossl_decode_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ SCOSSL_STATUS p_scossl_decode(SCOSSL_DECODE_CTX *ctx, OSSL_CORE_BIO *in, int sel

ret = dataCb(cbParams, dataCbArg);
}

ctx->desc->freeKeyCtx(keyCtx);
BIO_free(bio);

Expand Down
114 changes: 69 additions & 45 deletions SymCryptProvider/src/decoder/p_scossl_decode_mlkem.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,38 @@
extern "C" {
#endif

static SCOSSL_MLKEM_KEY_CTX *p_scossl_mlkem_decode_key_bytes(_In_ SCOSSL_DECODE_CTX *ctx, _In_ const ASN1_OBJECT *algorithm, int selection,
static SCOSSL_MLKEM_KEY_CTX *p_scossl_mlkem_decode_key_bytes(_In_ SCOSSL_DECODE_CTX *ctx, _In_ const ASN1_OBJECT *algorithm,
SYMCRYPT_MLKEM_PARAMS mlkemParams, SYMCRYPT_MLKEMKEY_FORMAT format,
_In_reads_bytes_(cbKey) PCBYTE pbKey, SIZE_T cbKey)
{
SCOSSL_MLKEM_KEY_CTX *keyCtx = NULL;
SCOSSL_STATUS status = SCOSSL_FAILURE;
SCOSSL_MLKEM_GROUP_INFO *groupInfo = NULL;

if (pbKey == NULL || cbKey == 0)
{
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY);
goto cleanup;
}

if ((keyCtx = p_scossl_mlkem_keymgmt_new_ctx(ctx->provctx)) == NULL)
if ((groupInfo = p_scossl_mlkem_get_group_info_by_nid(OBJ_obj2nid(algorithm))) == NULL)
{
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED);
goto cleanup;
}

if ((keyCtx->groupInfo = p_scossl_mlkem_get_group_info_by_nid(OBJ_obj2nid(algorithm))) == NULL)
if (mlkemParams != groupInfo->mlkemParams)
{
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED);
goto cleanup;
}

status = p_scossl_mlkem_keymgmt_set_encoded_key(keyCtx, selection, pbKey, cbKey);
if ((keyCtx = p_scossl_mlkem_keymgmt_new_ctx(ctx->provctx, mlkemParams)) == NULL)
{
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
goto cleanup;
}

status = p_scossl_mlkem_keymgmt_set_encoded_key(keyCtx, format, pbKey, cbKey);

cleanup:
if (status != SCOSSL_SUCCESS)
Expand All @@ -49,14 +56,15 @@ static SCOSSL_MLKEM_KEY_CTX *p_scossl_mlkem_decode_key_bytes(_In_ SCOSSL_DECODE_
return keyCtx;
}

static SCOSSL_MLKEM_KEY_CTX *p_scossl_PrivateKeyInfo_to_mlkem(_In_ SCOSSL_DECODE_CTX *ctx, _In_ BIO *bio)
static SCOSSL_MLKEM_KEY_CTX *p_scossl_PrivateKeyInfo_to_mlkem(_In_ SCOSSL_DECODE_CTX *ctx, SYMCRYPT_MLKEM_PARAMS mlkemParams, _In_ BIO *bio)
{
PKCS8_PRIV_KEY_INFO *p8Info = NULL;
const ASN1_OBJECT *algorithm;
const unsigned char *pbKey;
int cbKey;
ASN1_OCTET_STRING *p8Data = NULL;
SCOSSL_MLKEM_KEY_CTX *keyCtx = NULL;
SYMCRYPT_MLKEMKEY_FORMAT format;

if (d2i_PKCS8_PRIV_KEY_INFO_bio(bio, &p8Info) == NULL ||
!PKCS8_pkey_get0(&algorithm, &pbKey, &cbKey, NULL, p8Info) ||
Expand All @@ -66,7 +74,10 @@ static SCOSSL_MLKEM_KEY_CTX *p_scossl_PrivateKeyInfo_to_mlkem(_In_ SCOSSL_DECODE
goto cleanup;
}

keyCtx = p_scossl_mlkem_decode_key_bytes(ctx, algorithm, OSSL_KEYMGMT_SELECT_PRIVATE_KEY,
format = cbKey == 64 ? SYMCRYPT_MLKEMKEY_FORMAT_PRIVATE_SEED : SYMCRYPT_MLKEMKEY_FORMAT_DECAPSULATION_KEY;

keyCtx = p_scossl_mlkem_decode_key_bytes(ctx, algorithm,
mlkemParams, format,
ASN1_STRING_get0_data(p8Data), ASN1_STRING_length(p8Data));

cleanup:
Expand All @@ -76,7 +87,7 @@ static SCOSSL_MLKEM_KEY_CTX *p_scossl_PrivateKeyInfo_to_mlkem(_In_ SCOSSL_DECODE
return keyCtx;
}

static SCOSSL_MLKEM_KEY_CTX *p_scossl_SubjectPublicKeyInfo_to_mlkem(_In_ SCOSSL_DECODE_CTX *ctx, _In_ BIO *bio)
static SCOSSL_MLKEM_KEY_CTX *p_scossl_SubjectPublicKeyInfo_to_mlkem(_In_ SCOSSL_DECODE_CTX *ctx, SYMCRYPT_MLKEM_PARAMS mlkemParams, _In_ BIO *bio)
{
OSSL_LIB_CTX *libCtx = ctx->provctx == NULL ? NULL : ctx->provctx->libctx;
SUBJECT_PUBKEY_INFO *subjPubKeyInfo = NULL;
Expand All @@ -97,7 +108,8 @@ static SCOSSL_MLKEM_KEY_CTX *p_scossl_SubjectPublicKeyInfo_to_mlkem(_In_ SCOSSL_

X509_ALGOR_get0(&algorithm, NULL, NULL, subjPubKeyInfo->x509Alg);

keyCtx = p_scossl_mlkem_decode_key_bytes(ctx, algorithm, OSSL_KEYMGMT_SELECT_PUBLIC_KEY,
keyCtx = p_scossl_mlkem_decode_key_bytes(ctx, algorithm,
mlkemParams, SYMCRYPT_MLKEMKEY_FORMAT_ENCAPSULATION_KEY,
ASN1_STRING_get0_data(subjPubKeyInfo->subjectPublicKey), ASN1_STRING_length(subjPubKeyInfo->subjectPublicKey));

cleanup:
Expand All @@ -121,43 +133,55 @@ static SCOSSL_STATUS p_scossl_der_to_mlkem_export_object(_In_ SCOSSL_DECODE_CTX
return p_scossl_mlkem_keymgmt_export(keyCtx, ctx->desc->selection, exportCb, exportCbArg);
}

#define SCOSSL_MAKE_MLKEM_DECODER(decoderType) \
static const SCOSSL_DECODE_KEYTYPE_DESC p_scossl_mlkem_##decoderType##_desc = { \
"MLKEM", \
select_##decoderType, \
(PSCOSSL_DECODE_INTERNAL_FN)p_scossl_##decoderType##_to_mlkem, \
(OSSL_FUNC_keymgmt_free_fn *)p_scossl_mlkem_keymgmt_free_key_ctx}; \
\
static SCOSSL_DECODE_CTX * \
p_scossl_der_to_mlkem_##decoderType##_newctx(_In_ SCOSSL_PROVCTX *provctx) \
{ \
return p_scossl_decode_newctx( \
provctx, \
&p_scossl_mlkem_##decoderType##_desc); \
} \
\
static BOOL \
p_scossl_der_to_mlkem_##decoderType##_does_selection( \
ossl_unused void *provctx, \
int selection) \
{ \
return p_scossl_decode_does_selection( \
&p_scossl_mlkem_##decoderType##_desc, \
selection); \
} \
\
const OSSL_DISPATCH p_scossl_der_to_mlkem_##decoderType##_functions[] = { \
{OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))p_scossl_der_to_mlkem_##decoderType##_newctx}, \
{OSSL_FUNC_DECODER_FREECTX, (void (*)(void))p_scossl_decode_freectx}, \
{OSSL_FUNC_DECODER_SET_CTX_PARAMS, (void (*)(void))p_scossl_decode_set_ctx_params}, \
{OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_decode_settable_ctx_params}, \
{OSSL_FUNC_DECODER_DOES_SELECTION, (void (*)(void)) p_scossl_der_to_mlkem_##decoderType##_does_selection}, \
{OSSL_FUNC_DECODER_DECODE, (void (*)(void))p_scossl_decode}, \
{OSSL_FUNC_DECODER_EXPORT_OBJECT, (void (*)(void))p_scossl_der_to_mlkem_export_object}, \
#define SCOSSL_MAKE_MLKEM_DECODER(decoderType, bits) \
static SCOSSL_MLKEM_KEY_CTX \
*p_scossl_##decoderType##_to_mlkem##bits(_In_ SCOSSL_DECODE_CTX *ctx, \
_In_ BIO *bio) \
{ \
return p_scossl_##decoderType##_to_mlkem(ctx, SYMCRYPT_MLKEM_PARAMS_MLKEM##bits, bio); \
} \
\
static const SCOSSL_DECODE_KEYTYPE_DESC p_scossl_mlkem##bits##_##decoderType##_desc = { \
"MLKEM"#bits, \
select_##decoderType, \
(PSCOSSL_DECODE_INTERNAL_FN)p_scossl_##decoderType##_to_mlkem##bits, \
(OSSL_FUNC_keymgmt_free_fn *)p_scossl_mlkem_keymgmt_free_key_ctx}; \
\
static SCOSSL_DECODE_CTX * \
p_scossl_der_to_mlkem##bits##_##decoderType##_newctx(_In_ SCOSSL_PROVCTX *provctx) \
{ \
return p_scossl_decode_newctx( \
provctx, \
&p_scossl_mlkem##bits##_##decoderType##_desc); \
} \
\
static BOOL \
p_scossl_der_to_mlkem##bits##_##decoderType##_does_selection( \
ossl_unused void *provctx, \
int selection) \
{ \
return p_scossl_decode_does_selection( \
&p_scossl_mlkem##bits##_##decoderType##_desc, \
selection); \
} \
\
const OSSL_DISPATCH p_scossl_der_to_mlkem##bits##_##decoderType##_functions[] = { \
{OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))p_scossl_der_to_mlkem##bits##_##decoderType##_newctx}, \
{OSSL_FUNC_DECODER_FREECTX, (void (*)(void))p_scossl_decode_freectx}, \
{OSSL_FUNC_DECODER_SET_CTX_PARAMS, (void (*)(void))p_scossl_decode_set_ctx_params}, \
{OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_decode_settable_ctx_params}, \
{OSSL_FUNC_DECODER_DOES_SELECTION, (void (*)(void)) \
p_scossl_der_to_mlkem##bits##_##decoderType##_does_selection}, \
{OSSL_FUNC_DECODER_DECODE, (void (*)(void))p_scossl_decode}, \
{OSSL_FUNC_DECODER_EXPORT_OBJECT, (void (*)(void))p_scossl_der_to_mlkem_export_object}, \
{0, NULL}};

SCOSSL_MAKE_MLKEM_DECODER(PrivateKeyInfo);
SCOSSL_MAKE_MLKEM_DECODER(SubjectPublicKeyInfo);
SCOSSL_MAKE_MLKEM_DECODER(PrivateKeyInfo, 512);
SCOSSL_MAKE_MLKEM_DECODER(SubjectPublicKeyInfo, 512);
SCOSSL_MAKE_MLKEM_DECODER(PrivateKeyInfo, 768);
SCOSSL_MAKE_MLKEM_DECODER(SubjectPublicKeyInfo, 768);
SCOSSL_MAKE_MLKEM_DECODER(PrivateKeyInfo, 1024);
SCOSSL_MAKE_MLKEM_DECODER(SubjectPublicKeyInfo, 1024);

#ifdef __cplusplus
}
Expand Down
Loading
Loading