Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ML-KEM and ML-KEM hybrid #103

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
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_ecc.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ void scossl_ecc_destroy_ecc_curves();

// x25519 is a separate interface in the provider and not supported in the
// engine, so there's no need to fetch the hidden group from an EC_GROUP.
PCSYMCRYPT_ECURVE scossl_ecc_nid_to_symcrypt_curve(int groupNid);
PCSYMCRYPT_ECURVE scossl_ecc_group_to_symcrypt_curve(_In_ const EC_GROUP *group);
PCSYMCRYPT_ECURVE scossl_ecc_get_x25519_curve();
EC_GROUP *scossl_ecc_symcrypt_curve_to_ecc_group(_In_ PCSYMCRYPT_ECURVE pCurve);
Expand Down
22 changes: 15 additions & 7 deletions ScosslCommon/src/scossl_ecc.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,8 @@ void scossl_ecc_destroy_ecc_curves()
}
}

_Use_decl_annotations_
PCSYMCRYPT_ECURVE scossl_ecc_group_to_symcrypt_curve(const EC_GROUP *group)
PCSYMCRYPT_ECURVE scossl_ecc_nid_to_symcrypt_curve(int groupNid)
{
if (group == NULL)
return NULL;

int groupNid = EC_GROUP_get_curve_name(group);

// Only reroute NIST Prime curves to SymCrypt for now
switch (groupNid)
{
Expand All @@ -107,6 +101,15 @@ PCSYMCRYPT_ECURVE scossl_ecc_group_to_symcrypt_curve(const EC_GROUP *group)
return NULL;
}

_Use_decl_annotations_
PCSYMCRYPT_ECURVE scossl_ecc_group_to_symcrypt_curve(const EC_GROUP *group)
{
if (group == NULL)
return NULL;

return scossl_ecc_nid_to_symcrypt_curve(EC_GROUP_get_curve_name(group));
}

PCSYMCRYPT_ECURVE scossl_ecc_get_x25519_curve()
{
return _hidden_curve_X25519;
Expand Down Expand Up @@ -519,6 +522,11 @@ static SCOSSL_STATUS scossl_ecdsa_apply_der(_In_reads_bytes_(cbSymCryptSignature
_Use_decl_annotations_
SIZE_T scossl_ecdsa_size(PCSYMCRYPT_ECURVE curve)
{
if (curve == NULL)
{
return 0;
}

return 2*SymCryptEcurveSizeofScalarMultiplier(curve) + 8;
}

Expand Down
7 changes: 7 additions & 0 deletions SymCryptProvider/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,35 @@ set(SCOSSL_SOURCES
./src/ciphers/p_scossl_aes.c
./src/ciphers/p_scossl_aes_aead.c
./src/ciphers/p_scossl_aes_xts.c
./src/decoder/p_scossl_decode_common.c
./src/decoder/p_scossl_decode_mlkem.c
./src/digests/p_scossl_digest_common.c
./src/digests/p_scossl_digest_generic.c
./src/digests/p_scossl_shake.c
./src/digests/p_scossl_cshake.c
./src/encoder/p_scossl_encode_common.c
./src/encoder/p_scossl_encode_mlkem.c
./src/kdf/p_scossl_hkdf.c
./src/kdf/p_scossl_kbkdf.c
./src/kdf/p_scossl_srtpkdf.c
./src/kdf/p_scossl_sshkdf.c
./src/kdf/p_scossl_sskdf.c
./src/kdf/p_scossl_tls1prf.c
./src/kem/p_scossl_mlkem.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_rsa_keymgmt.c
./src/mac/p_scossl_cmac.c
./src/mac/p_scossl_hmac.c
./src/mac/p_scossl_kmac.c
./src/signature/p_scossl_ecdsa_signature.c
./src/signature/p_scossl_rsa_signature.c
./src/p_scossl_bio.c
./src/p_scossl_ecc.c
./src/p_scossl_rand.c
./src/p_scossl_rsa.c
Expand Down
5 changes: 4 additions & 1 deletion SymCryptProvider/inc/p_scossl_base.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

#pragma once

#include "scossl_helpers.h"

#include <openssl/bio.h>
#include <openssl/core_names.h>
#include <openssl/params.h>
#include "scossl_helpers.h"

#ifdef __cplusplus
extern "C" {
Expand All @@ -20,6 +22,7 @@ typedef struct
{
OSSL_LIB_CTX *libctx;
const OSSL_CORE_HANDLE *handle;
BIO_METHOD *coreBioMeth;
} SCOSSL_PROVCTX;

static const OSSL_PARAM p_scossl_param_types[] = {
Expand Down
24 changes: 21 additions & 3 deletions SymCryptProvider/inc/scossl_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,44 @@ extern "C" {
//
// Digest parameters
//

#define SCOSSL_DIGEST_PARAM_FUNCTION_NAME_STRING "function-name-string"
#define SCOSSL_DIGEST_PARAM_CUSTOMIZATION_STRING "customization-string"

//
// KDF parameters
//

#define SCOSSL_KDF_PARAM_SRTP_RATE "rate"
#define SCOSSL_KDF_PARAM_SRTP_INDEX "index"
#define SCOSSL_KDF_PARAM_SRTP_INDEX_WIDTH "index-width"

//
// SRTP labels
//

#define SCOSSL_SRTP_LABEL_ENCRYPTION "encryption"
#define SCOSSL_SRTP_LABEL_AUTHENTICATION "authentication"
#define SCOSSL_SRTP_LABEL_SALTING "salting"

//
// Extended algorithms not found in default OpenSSL implementation
//
#define SCOSSL_SN_MLKEM512 "mlkem512"
#define SCOSSL_OID_MLKEM512 "2.16.840.1.101.3.4.4.1"

#define SCOSSL_SN_MLKEM768 "mlkem768"
#define SCOSSL_OID_MLKEM768 "2.16.840.1.101.3.4.4.2"

#define SCOSSL_SN_MLKEM1024 "mlkem1024"
#define SCOSSL_OID_MLKEM1024 "2.16.840.1.101.3.4.4.3"

#define SCOSSL_SN_P256_MLKEM768 "secp256r1"SCOSSL_SN_MLKEM768
#define SCOSSL_OID_P256_MLKEM768 "2.16.840.1.101.3.4.4.4"

#define SCOSSL_SN_X25519_MLKEM768 SN_X25519 SCOSSL_SN_MLKEM768
#define SCOSSL_OID_X25519_MLKEM768 "2.16.840.1.101.3.4.4.5"

#define SCOSSL_SN_P384_MLKEM1024 SN_secp384r1 SCOSSL_SN_MLKEM1024
#define SCOSSL_OID_P384_MLKEM1024 "2.16.840.1.101.3.4.4.6"

#ifdef __cplusplus
}
#endif
123 changes: 123 additions & 0 deletions SymCryptProvider/src/decoder/p_scossl_decode_common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//

#include "p_scossl_bio.h"
#include "p_scossl_decode_common.h"

#include <openssl/asn1t.h>
#include <openssl/core_object.h>

#ifdef __cplusplus
extern "C" {
#endif

ASN1_NDEF_SEQUENCE(SUBJECT_PUBKEY_INFO) = {
ASN1_SIMPLE(SUBJECT_PUBKEY_INFO, x509Alg, X509_ALGOR),
ASN1_SIMPLE(SUBJECT_PUBKEY_INFO, subjectPublicKey, ASN1_BIT_STRING),
} ASN1_SEQUENCE_END(SUBJECT_PUBKEY_INFO)

IMPLEMENT_ASN1_FUNCTIONS(SUBJECT_PUBKEY_INFO)

const OSSL_PARAM p_scossl_der_to_key_settable_param_types[] = {
OSSL_PARAM_END};

_Use_decl_annotations_
SCOSSL_DECODE_CTX *p_scossl_decode_newctx(SCOSSL_PROVCTX *provctx, const SCOSSL_DECODE_KEYTYPE_DESC *desc)
{
SCOSSL_DECODE_CTX *ctx = OPENSSL_zalloc(sizeof(SCOSSL_DECODE_CTX));

if (ctx != NULL)
{
ctx->provctx = provctx;
ctx->desc = desc;
}

return ctx;
}

_Use_decl_annotations_
void p_scossl_decode_freectx(SCOSSL_DECODE_CTX *ctx)
{
if (ctx == NULL)
return;

OPENSSL_free(ctx);
}

SCOSSL_STATUS p_scossl_decode_set_ctx_params(ossl_unused void *ctx, ossl_unused const OSSL_PARAM params[])
{
return SCOSSL_SUCCESS;
}

const OSSL_PARAM *p_scossl_decode_settable_ctx_params(ossl_unused void *ctx)
{
return p_scossl_der_to_key_settable_param_types;
}

_Use_decl_annotations_
BOOL p_scossl_decode_does_selection(const SCOSSL_DECODE_KEYTYPE_DESC *desc, int selection)
{
if (selection == 0)
{
return TRUE;
}

// Supporting private key implies supporting public key.
// Both imply supporting key parameters
return ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 && (desc->selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) ||
((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0 && (desc->selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) ||
((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0 && (desc->selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0);
}

// This function should return SCOSSL_SUCCESS if it successfully decodes something,
// or decodes nothing at all. Another decoder may be able to decode the data into something.
// This function should only return SCOSSL_FAILURE if the data could be decoded, but further
// validation of the data failed in a way that another decoder could not handle.
_Use_decl_annotations_
SCOSSL_STATUS p_scossl_decode(SCOSSL_DECODE_CTX *ctx, OSSL_CORE_BIO *in, int selection,
OSSL_CALLBACK *dataCb, void *dataCbArg,
ossl_unused OSSL_PASSPHRASE_CALLBACK *passphraseCb, ossl_unused void *passphraseCbArg)
{
BIO *bio = NULL;
PVOID *keyCtx = NULL;
OSSL_PARAM cbParams[4];
SCOSSL_STATUS ret = SCOSSL_SUCCESS;

if (selection == 0)
{
selection = ctx->desc->selection;
}

if ((selection & ctx->desc->selection) != 0 &&
(bio = p_scossl_bio_new_from_core_bio(ctx->provctx, in)) != NULL)
{
keyCtx = ctx->desc->decodeInternal(ctx, bio);
}

if (keyCtx != NULL)
{
int objectType = OSSL_OBJECT_PKEY;

cbParams[0] = OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &objectType);
cbParams[1] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, (char *)ctx->desc->dataType, 0);
cbParams[2] = OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_REFERENCE, &keyCtx, sizeof(keyCtx));
cbParams[3] = OSSL_PARAM_construct_end();

ret = dataCb(cbParams, dataCbArg);
}

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

return ret;
}

const ASN1_ITEM *p_scossl_decode_subject_pubkey_asn1_item()
{
return ASN1_ITEM_rptr(SUBJECT_PUBKEY_INFO);
}

#ifdef __cplusplus
}
#endif
55 changes: 55 additions & 0 deletions SymCryptProvider/src/decoder/p_scossl_decode_common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//

#include "p_scossl_base.h"

#ifdef __cplusplus
extern "C" {
#endif

#define select_PrivateKeyInfo OSSL_KEYMGMT_SELECT_PRIVATE_KEY
#define select_SubjectPublicKeyInfo OSSL_KEYMGMT_SELECT_PUBLIC_KEY

typedef PVOID (*PSCOSSL_DECODE_INTERNAL_FN) (_In_ PVOID decodeCtx, _In_ BIO *bio);

typedef struct
{
const char *dataType;
int selection;

PSCOSSL_DECODE_INTERNAL_FN decodeInternal;
OSSL_FUNC_keymgmt_free_fn *freeKeyCtx;
} SCOSSL_DECODE_KEYTYPE_DESC;

typedef struct scossl_decode_ctx_st
{
SCOSSL_PROVCTX *provctx;

const SCOSSL_DECODE_KEYTYPE_DESC *desc;
} SCOSSL_DECODE_CTX;

typedef struct
{
X509_ALGOR *x509Alg;
ASN1_BIT_STRING *subjectPublicKey;
} SUBJECT_PUBKEY_INFO;

SCOSSL_DECODE_CTX *p_scossl_decode_newctx(_In_ SCOSSL_PROVCTX *provctx, _In_ const SCOSSL_DECODE_KEYTYPE_DESC *desc);
void p_scossl_decode_freectx(_Inout_ SCOSSL_DECODE_CTX *ctx);

SCOSSL_STATUS p_scossl_decode_set_ctx_params(ossl_unused void *ctx, ossl_unused const OSSL_PARAM params[]);
const OSSL_PARAM *p_scossl_decode_settable_ctx_params(ossl_unused void *ctx);

BOOL p_scossl_decode_does_selection(_In_ const SCOSSL_DECODE_KEYTYPE_DESC *desc, int selection);

SCOSSL_STATUS p_scossl_decode(_In_ SCOSSL_DECODE_CTX *ctx, _In_ OSSL_CORE_BIO *in,
int selection,
_In_ OSSL_CALLBACK *dataCb, _In_ void *dataCbArg,
ossl_unused OSSL_PASSPHRASE_CALLBACK *passphraseCb, ossl_unused void *passphraseCbArg);

const ASN1_ITEM *p_scossl_decode_subject_pubkey_asn1_item();

#ifdef __cplusplus
}
#endif
Loading