Skip to content

Commit

Permalink
POC KEM implemetation
Browse files Browse the repository at this point in the history
cmp_asn.c: add ASN1 structure for OSSL_CMP_KEMCIPHERTEXTINFO

cmp{_asn.c, .h.in}: add function OSSL_CMP_ITAV_new_KemCiphertext

cmp{_msg.c, .h.in}: add function OSSL_CMP_MSG_get_extraCerts

cmp_server.c: extend unprotected_exception for KemCiphertextInfo without value

objects.txt, oids.txt, obj_{dah.h, mac.num, mac.h}: add id_it_KemCiphertextInfo (preliminary value for prototyping)

cmp{.h.in, _local.h, _asn.c}: add structure OSSL_CMP_KEMOTHERINFO for kdf

objects.txt, cmp_{asn.c, local.h}: add OSSL_CMP_KEMBMPARAMETER and preliminary value for id-KemBasedMac

objects.txt : add NID_hkdfWithSHA256

openssl.txt, cmperr.h: add KBM error.

cmp_{client.c, ctx.c, local.h}, cmp.h.in: extend OSSL_CMP_CTX for KEM.

cmp_mock_srv.c: add support of Key encapculation and ITAV with kemCiphertext

build.info, cmp.h.in, cmp_{kem.c, local.h}: add functions for kemBasedMac

cmp_{genm.c, local.h}: convert static function to ossl_cmp_genm_get_itav

cmp_{hdr.c, local.h}: add func ossl_cmp_hdr_has_KemCiphertextInfo

cmp_protect.c: extend protection for KemBasedMac

cmp_client.c: add kembasedMac protection to OSSL_CMP_exec_certreq

cmp_vfy.c: add msg validation for NID_id_KemBasedMac

cmp_client.c: extend unprotected_exception for NID_id_it_KemCiphertextInfo.

cmp_server.c: adapt server for kem

objects.txt, obj_{dat.h, mac.num. mac.h}, oids.txt: add oids for id_kem_rsa & id_kdf_kdf2

cmp_{asn.c, local.h}: add asn structure for OSSL_CMP_RSAKEMPARAMETERS

cmp_{kem.c, local.h}: add function ossl_cmp_kem_get_ssk_using_srvcert

kem{.crt, .key, _only.crt}: add certificate with kem.

TODO! server_withkem.cnf, test_withserverkem.cnf: added  for testing

libcrypto.num: add CMP APIs

server_kem.crt: add server cert with keyusage=keyEncipherment

test_credentials.csv: add test with kem cert

cmp_{asn.c, kem.c, local.h}: move ossl_cmp_kem_KemOtherInfo_new() from cmp_kem.c

cmp_mock_srv.c: add TODO for verifying client Kem certificate.

cmp_ctx.c: add TODO to generalize KEM default parameter

cmp_ctx.c: add helper function to set octet secret in ctx.

cmp_{ctx.c,local.h}: remove ossl_cmp_ctx_get0_transactionID()

cmp_{ctx.c, local.h}: update kem variable name

cmp_client.c: update kem variable name

cmp_kem.c: update kem variable name

cmp_protect.c: update kem variable name

cmp_server.c: update kem variable name

cmp_kem.c: fix return in case of error

cmp_kem.c: remove RSA kem code from cmp_kem.c

cmp_{kemrsa.c, local.h}: add rsa kem and kdf2  implementation

build.info: add file cmp_kemrsa.c

cmp_kem.c: updated to support KEM from oqsprovider

kem_{RSA,kyber512}.{crt,key}: add RSA and kyber512 cert and key for KEM testing

cmp_{util.c, local.h}: add function ossl_cmp_x509_algor_set0

cmp_asn.c: fix memory leak

cmp_kem.c: fix memory leak

cmp_kemrsa.c: fix memory leak

to be removed, cmp_kem.c:add debug message

kem_kyber1024.{crt, priv, pub}: add kyber1024 key and certificate for testing.
  • Loading branch information
rajeev-0 committed Jan 30, 2024
1 parent 0873e6f commit 4d6426d
Show file tree
Hide file tree
Showing 38 changed files with 2,092 additions and 58 deletions.
41 changes: 37 additions & 4 deletions apps/lib/cmp_mock_srv.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,10 +391,31 @@ static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
return OSSL_CMP_PKISI_dup(ctx->statusOut);
}

static OSSL_CMP_ITAV *process_genm_itav(mock_srv_ctx *ctx, int req_nid,
const OSSL_CMP_ITAV *req)
/* TODO: extend it to check for certificate with KEM key (PQ keys) */
static X509 *extracert_withKEM(STACK_OF(X509) *certs)
{
OSSL_CMP_ITAV *rsp;
int i;

if (certs == NULL)
return NULL;

for (i = 0; i < sk_X509_num(certs); i++) {
X509 *cert = sk_X509_value(certs, i);

if ((X509_get_key_usage(cert) & X509v3_KU_KEY_ENCIPHERMENT)) {
return cert;
}
}
return NULL;
}

static OSSL_CMP_ITAV *process_genm_itav(OSSL_CMP_SRV_CTX *srv_ctx,
int req_nid,
const OSSL_CMP_ITAV *req,
const OSSL_CMP_MSG *genm)
{
OSSL_CMP_ITAV *rsp = NULL;
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);

switch (req_nid) {
case NID_id_it_caCerts:
Expand All @@ -405,6 +426,18 @@ static OSSL_CMP_ITAV *process_genm_itav(mock_srv_ctx *ctx, int req_nid,
ctx->newWithOld,
ctx->oldWithNew);
break;
case NID_id_it_KemCiphertextInfo:
if (OSSL_CMP_ITAV_get0_value(req) == NULL) {
X509 *kemcert;

/* TODO: add certificate path validation */
kemcert = extracert_withKEM(OSSL_CMP_MSG_get_extraCerts(genm));
if (kemcert == NULL)
break;
rsp = OSSL_CMP_SRV_kem_get_ss(srv_ctx, X509_get0_pubkey(kemcert));
break;
}
/* fall through */
default:
rsp = OSSL_CMP_ITAV_dup(req);
}
Expand Down Expand Up @@ -434,7 +467,7 @@ static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx,

if ((*out = sk_OSSL_CMP_ITAV_new_reserve(NULL, 1)) == NULL)
return 0;
rsp = process_genm_itav(ctx, OBJ_obj2nid(obj), req);
rsp = process_genm_itav(srv_ctx, OBJ_obj2nid(obj), req, genm);
if (rsp != NULL && sk_OSSL_CMP_ITAV_push(*out, rsp))
return 1;
sk_OSSL_CMP_ITAV_free(*out);
Expand Down
2 changes: 1 addition & 1 deletion crypto/cmp/build.info
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ LIBS=../../libcrypto
$OPENSSLSRC=\
cmp_asn.c cmp_ctx.c cmp_err.c cmp_util.c \
cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c cmp_vfy.c \
cmp_server.c cmp_client.c cmp_genm.c
cmp_server.c cmp_client.c cmp_genm.c cmp_kem.c cmp_kemrsa.c

IF[{- !$disabled{'http'} -}]
$OPENSSLSRC=$OPENSSLSRC cmp_http.c
Expand Down
110 changes: 109 additions & 1 deletion crypto/cmp/cmp_asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,36 @@ ASN1_SEQUENCE(OSSL_CMP_CAKEYUPDANNCONTENT) = {
} ASN1_SEQUENCE_END(OSSL_CMP_CAKEYUPDANNCONTENT)
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CAKEYUPDANNCONTENT)

ASN1_SEQUENCE(OSSL_CMP_RSAKEMPARAMETERS) = {
ASN1_SIMPLE(OSSL_CMP_RSAKEMPARAMETERS, KeyDerivationFunction, X509_ALGOR),
ASN1_SIMPLE(OSSL_CMP_RSAKEMPARAMETERS, KeyLength, ASN1_INTEGER)
} ASN1_SEQUENCE_END(OSSL_CMP_RSAKEMPARAMETERS)
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_RSAKEMPARAMETERS)

ASN1_SEQUENCE(OSSL_CMP_KEMCIPHERTEXTINFO) = {
ASN1_SIMPLE(OSSL_CMP_KEMCIPHERTEXTINFO, kem, X509_ALGOR),
ASN1_SIMPLE(OSSL_CMP_KEMCIPHERTEXTINFO, ct, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(OSSL_CMP_KEMCIPHERTEXTINFO)
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_KEMCIPHERTEXTINFO)

ASN1_SEQUENCE(OSSL_CMP_KEMOTHERINFO) = {
ASN1_SEQUENCE_OF(OSSL_CMP_KEMOTHERINFO, staticString, ASN1_UTF8STRING),
ASN1_EXP_OPT(OSSL_CMP_KEMOTHERINFO, transactionID, ASN1_OCTET_STRING, 0),
ASN1_EXP_OPT(OSSL_CMP_KEMOTHERINFO, senderNonce, ASN1_OCTET_STRING, 1),
ASN1_EXP_OPT(OSSL_CMP_KEMOTHERINFO, recipNonce, ASN1_OCTET_STRING, 2),
ASN1_SIMPLE(OSSL_CMP_KEMOTHERINFO, len, ASN1_INTEGER),
ASN1_SIMPLE(OSSL_CMP_KEMOTHERINFO, mac, X509_ALGOR),
ASN1_SIMPLE(OSSL_CMP_KEMOTHERINFO, ct, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(OSSL_CMP_KEMOTHERINFO)
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_KEMOTHERINFO)

ASN1_SEQUENCE(OSSL_CMP_KEMBMPARAMETER) = {
ASN1_SIMPLE(OSSL_CMP_KEMBMPARAMETER, kdf, X509_ALGOR),
ASN1_SIMPLE(OSSL_CMP_KEMBMPARAMETER, len, ASN1_INTEGER),
ASN1_SIMPLE(OSSL_CMP_KEMBMPARAMETER, mac, X509_ALGOR)
} ASN1_SEQUENCE_END(OSSL_CMP_KEMBMPARAMETER)
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_KEMBMPARAMETER)

ASN1_SEQUENCE(OSSL_CMP_ERRORMSGCONTENT) = {
ASN1_SIMPLE(OSSL_CMP_ERRORMSGCONTENT, pKIStatusInfo, OSSL_CMP_PKISI),
ASN1_OPT(OSSL_CMP_ERRORMSGCONTENT, errorCode, ASN1_INTEGER),
Expand Down Expand Up @@ -120,6 +150,9 @@ ASN1_ADB(OSSL_CMP_ITAV) = {
ADB_ENTRY(NID_id_it_certProfile,
ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ITAV, infoValue.certProfile,
ASN1_UTF8STRING)),
ADB_ENTRY(NID_id_it_KemCiphertextInfo,
ASN1_OPT(OSSL_CMP_ITAV, infoValue.KemCiphertextInfoValue,
OSSL_CMP_KEMCIPHERTEXTINFO)),
} ASN1_ADB_END(OSSL_CMP_ITAV, 0, infoType, 0,
&infotypeandvalue_default_tt, NULL);

Expand Down Expand Up @@ -223,6 +256,81 @@ int OSSL_CMP_ITAV_get0_certProfile(const OSSL_CMP_ITAV *itav,
return 1;
}

OSSL_CMP_ITAV *ossl_cmp_itav_new_KemCiphertext(X509_ALGOR *kem,
unsigned char *in_ct,
int len)
{
OSSL_CMP_ITAV *itav = NULL;
OSSL_CMP_KEMCIPHERTEXTINFO *KemCtInfoValue;

if (kem == NULL || in_ct == NULL)
return NULL;

if ((KemCtInfoValue = OSSL_CMP_KEMCIPHERTEXTINFO_new()) == NULL
|| !ossl_cmp_x509_algor_set0(&KemCtInfoValue->kem, kem)
|| !ossl_cmp_asn1_octet_string_set1_bytes(&KemCtInfoValue->ct,
in_ct, len))
goto err;

if ((itav = OSSL_CMP_ITAV_new()) == NULL)
goto err;

itav->infoType = OBJ_nid2obj(NID_id_it_KemCiphertextInfo);
itav->infoValue.KemCiphertextInfoValue = KemCtInfoValue;

return itav;

err:
OSSL_CMP_KEMCIPHERTEXTINFO_free(KemCtInfoValue);
OSSL_CMP_ITAV_free(itav);
return NULL;
}

#define KEMCMP_STATICSTRING "CMP-KEM"
int ossl_cmp_kem_KemOtherInfo_new(OSSL_CMP_CTX *ctx,
unsigned char **out, int *len)
{
int ret = 0;
OSSL_CMP_KEMOTHERINFO *kemOtherInfo;

if (out == NULL || len == NULL)
return 0;

if ((kemOtherInfo = OSSL_CMP_KEMOTHERINFO_new()) == NULL)
return 0;

if (!ossl_cmp_sk_ASN1_UTF8STRING_push_str(kemOtherInfo->staticString,
KEMCMP_STATICSTRING, -1))
goto err;

kemOtherInfo->transactionID = ctx->transactionID;
kemOtherInfo->senderNonce = ossl_cmp_ctx_get_kem_senderNonce(ctx);
kemOtherInfo->recipNonce = ossl_cmp_ctx_get_kem_recipNonce(ctx);

if (!ASN1_INTEGER_set(kemOtherInfo->len, ctx->kem_ssklen)
|| !X509_ALGOR_set0(kemOtherInfo->mac, OBJ_nid2obj(NID_hmacWithSHA256),
V_ASN1_UNDEF, NULL))
goto err;

if (ctx->kem_ct != NULL
&& !ossl_cmp_asn1_octet_string_set1(&kemOtherInfo->ct,
ctx->kem_ct))
goto err;

*out = NULL;
if ((*len = i2d_OSSL_CMP_KEMOTHERINFO(kemOtherInfo, out)) <= 0)
goto err;

ret = 1;

err:
kemOtherInfo->transactionID = NULL;
kemOtherInfo->senderNonce = NULL;
kemOtherInfo->recipNonce = NULL;
OSSL_CMP_KEMOTHERINFO_free(kemOtherInfo);
return ret;
}

OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_caCerts(const STACK_OF(X509) *caCerts)
{
OSSL_CMP_ITAV *itav = OSSL_CMP_ITAV_new();
Expand Down Expand Up @@ -303,7 +411,7 @@ OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_rootCaKeyUpdate(const X509 *newWithNew,
itav->infoValue.rootCaKeyUpdate = upd;
return itav;

err:
err:
OSSL_CMP_ROOTCAKEYUPDATE_free(upd);
return NULL;
}
Expand Down
29 changes: 29 additions & 0 deletions crypto/cmp/cmp_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ static int unprotected_exception(const OSSL_CMP_CTX *ctx,
if (!ossl_assert(ctx != NULL && rep != NULL))
return -1;

/* unprotected response with cipher text */
if (rcvd_type == OSSL_CMP_PKIBODY_GENP
&& ctx->kem_status == KBM_SSK_USING_CLIENT_KEM_KEY
&& sk_OSSL_CMP_ITAV_num(rep->body->value.genm) == 1) {
OSSL_CMP_ITAV *req_itav = sk_OSSL_CMP_ITAV_value(rep->body->value.genm,
0);
ASN1_OBJECT *obj = OSSL_CMP_ITAV_get0_type(req_itav);

if (OBJ_obj2nid(obj) == NID_id_it_KemCiphertextInfo
&& OSSL_CMP_ITAV_get0_value(req_itav) != NULL)
return 1;
}

if (!ctx->unprotectedErrors)
return 0;

Expand Down Expand Up @@ -865,11 +878,20 @@ X509 *OSSL_CMP_exec_certreq(OSSL_CMP_CTX *ctx, int req_type,
int rid = is_p10 ? OSSL_CMP_CERTREQID_NONE : OSSL_CMP_CERTREQID;
int rep_type = is_p10 ? OSSL_CMP_PKIBODY_CP : req_type + 1;
X509 *result = NULL;
int kembasedmac;

if (ctx == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return NULL;
}
kembasedmac = ossl_cmp_kem_BasedMac_required(ctx);
if (kembasedmac == -1) {
goto err;
} else if (kembasedmac == 1
&& ctx->kem_status == KBM_SSK_USING_CLIENT_KEM_KEY) {
if (!OSSL_CMP_get_ssk(ctx))
goto err;
}

if (!initial_certreq(ctx, req_type, crm, &rep, rep_type))
goto err;
Expand Down Expand Up @@ -1045,6 +1067,13 @@ STACK_OF(OSSL_CMP_ITAV) *OSSL_CMP_exec_GENM_ses(OSSL_CMP_CTX *ctx)
/* received stack of itavs not to be freed with the genp */
genp->body->value.genp = NULL;

if (ctx->kem_status == KBM_SSK_USING_CLIENT_KEM_KEY
&& genp->header != NULL) {
ossl_cmp_ctx_set1_kem_senderNonce(ctx,
genp->header->senderNonce);
ossl_cmp_ctx_set1_kem_recipNonce(ctx,
genp->header->recipNonce);
}
err:
OSSL_CMP_MSG_free(genm);
OSSL_CMP_MSG_free(genp);
Expand Down
Loading

0 comments on commit 4d6426d

Please sign in to comment.