summaryrefslogtreecommitdiffstats
path: root/providers/implementations
diff options
context:
space:
mode:
authorStephen Farrell <stephen.farrell@cs.tcd.ie>2022-11-22 02:42:04 +0000
committerMatt Caswell <matt@openssl.org>2022-11-25 16:26:55 +0000
commitad062480f7490197b174edad8625ce40d74f6e68 (patch)
treef4ac43084558412509820b4d167b4c2906f5cfb2 /providers/implementations
parent0dbd3a81e46dd7ea9f7832307fdd0b2ac207a5bf (diff)
Implements Hybrid Public Key Encryption (HPKE) as per RFC9180.
This supports all the modes, suites and export mechanisms defined in RFC9180 and should be relatively easily extensible if/as new suites are added. The APIs are based on the pseudo-code from the RFC, e.g. OSS_HPKE_encap() roughly maps to SetupBaseS(). External APIs are defined in include/openssl/hpke.h and documented in doc/man3/OSSL_HPKE_CTX_new.pod. Tests (test/hpke_test.c) include verifying a number of the test vectors from the RFC as well as round-tripping for all the modes and suites. We have demonstrated interoperability with other HPKE implementations via a fork [1] that implements TLS Encrypted ClientHello (ECH) which uses HPKE. @slontis provided huge help in getting this done and this makes extensive use of the KEM handling code from his PR#19068. [1] https://github.com/sftcd/openssl/tree/ECH-draft-13c Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Shane Lontis <shane.lontis@oracle.com> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/17172)
Diffstat (limited to 'providers/implementations')
-rw-r--r--providers/implementations/kem/ec_kem.c125
-rw-r--r--providers/implementations/kem/eckem.h1
-rw-r--r--providers/implementations/kem/ecx_kem.c114
-rw-r--r--providers/implementations/kem/kem_util.c8
4 files changed, 105 insertions, 143 deletions
diff --git a/providers/implementations/kem/ec_kem.c b/providers/implementations/kem/ec_kem.c
index 57dcea4196..cdec509f06 100644
--- a/providers/implementations/kem/ec_kem.c
+++ b/providers/implementations/kem/ec_kem.c
@@ -30,25 +30,12 @@
#include "prov/securitycheck.h"
#include "prov/providercommon.h"
-#include "crypto/hpke.h"
+#include <openssl/hpke.h>
+#include "internal/hpke_util.h"
#include "crypto/ec.h"
#include "prov/ecx.h"
#include "eckem.h"
-/*
- * Used to store constants from Section 7.1 "Table 2 KEM IDs"
- * and the bitmask for curves described in Section 7.1.3 DeriveKeyPair
- */
-typedef struct {
- const char *curve;
- const char *kdfdigestname;
- uint16_t kemid;
- size_t secretlen; /* Nsecret = Nh */
- size_t encodedpublen;
- size_t encodedprivlen;
- uint8_t bitmask;
-} DHKEM_ALG;
-
typedef struct {
EC_KEY *recipient_key;
EC_KEY *sender_authkey;
@@ -59,7 +46,7 @@ typedef struct {
unsigned char *ikm;
size_t ikmlen;
const char *kdfname;
- const DHKEM_ALG *alg;
+ const OSSL_HPKE_KEM_INFO *info;
} PROV_EC_CTX;
static OSSL_FUNC_kem_newctx_fn eckem_newctx;
@@ -73,26 +60,8 @@ static OSSL_FUNC_kem_freectx_fn eckem_freectx;
static OSSL_FUNC_kem_set_ctx_params_fn eckem_set_ctx_params;
static OSSL_FUNC_kem_settable_ctx_params_fn eckem_settable_ctx_params;
-/* See Section 7.1 "Table 2 KEM IDs" */
-static const DHKEM_ALG dhkem_alg[] = {
- { "P-256", "SHA256", 0x0010, 32, 65, 32, 0xFF },
- { "P-384", "SHA384", 0x0011, 48, 97, 48, 0xFF },
- { "P-521", "SHA512", 0x0012, 64, 133, 66, 0x01 },
- { NULL }
-};
-
-/* Return an object containing KEM constants associated with a EC curve name */
-static const DHKEM_ALG *dhkem_ec_find_alg(const char *curve)
-{
- int i;
-
- for (i = 0; dhkem_alg[i].curve != NULL; ++i) {
- if (OPENSSL_strcasecmp(curve, dhkem_alg[i].curve) == 0)
- return &dhkem_alg[i];
- }
- ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE);
- return NULL;
-}
+/* ASCII: "KEM", in hex for EBCDIC compatibility */
+static const char LABEL_KEM[] = "\x4b\x45\x4d";
static int eckey_check(const EC_KEY *ec, int requires_privatekey)
{
@@ -151,8 +120,8 @@ static int recipient_key_set(PROV_EC_CTX *ctx, EC_KEY *ec)
if (curve == NULL)
return -2;
- ctx->alg = dhkem_ec_find_alg(curve);
- if (ctx->alg == NULL)
+ ctx->info = ossl_HPKE_KEM_INFO_find_curve(curve);
+ if (ctx->info == NULL)
return -2;
if (!EC_KEY_up_ref(ec))
return 0;
@@ -372,7 +341,7 @@ static int dhkem_extract_and_expand(EVP_KDF_CTX *kctx,
const unsigned char *kemctx,
size_t kemctxlen)
{
- uint8_t suiteid[5];
+ uint8_t suiteid[2];
uint8_t prk[EVP_MAX_MD_SIZE];
size_t prklen = okmlen;
int ret;
@@ -380,13 +349,14 @@ static int dhkem_extract_and_expand(EVP_KDF_CTX *kctx,
if (prklen > sizeof(prk))
return 0;
- ossl_dhkem_getsuiteid(suiteid, kemid);
+ suiteid[0] = (kemid >> 8) & 0xff;
+ suiteid[1] = kemid & 0xff;
ret = ossl_hpke_labeled_extract(kctx, prk, prklen,
- NULL, 0, suiteid, sizeof(suiteid),
+ NULL, 0, LABEL_KEM, suiteid, sizeof(suiteid),
OSSL_DHKEM_LABEL_EAE_PRK, dhkm, dhkmlen)
&& ossl_hpke_labeled_expand(kctx, okm, okmlen, prk, prklen,
- suiteid, sizeof(suiteid),
+ LABEL_KEM, suiteid, sizeof(suiteid),
OSSL_DHKEM_LABEL_SHARED_SECRET,
kemctx, kemctxlen);
OPENSSL_cleanse(prk, prklen);
@@ -413,52 +383,53 @@ int ossl_ec_dhkem_derive_private(EC_KEY *ec, BIGNUM *priv,
{
int ret = 0;
EVP_KDF_CTX *kdfctx = NULL;
- uint8_t suiteid[5];
+ uint8_t suiteid[2];
unsigned char prk[OSSL_HPKE_MAX_SECRET];
unsigned char privbuf[OSSL_HPKE_MAX_PRIVATE];
const BIGNUM *order;
unsigned char counter = 0;
- const DHKEM_ALG *alg;
const char *curve = ec_curvename_get0(ec);
+ const OSSL_HPKE_KEM_INFO *info;
if (curve == NULL)
return -2;
- alg = dhkem_ec_find_alg(curve);
- if (alg == NULL)
+ info = ossl_HPKE_KEM_INFO_find_curve(curve);
+ if (info == NULL)
return -2;
- kdfctx = ossl_kdf_ctx_create("HKDF", alg->kdfdigestname,
+ kdfctx = ossl_kdf_ctx_create("HKDF", info->mdname,
ossl_ec_key_get_libctx(ec),
ossl_ec_key_get0_propq(ec));
if (kdfctx == NULL)
return 0;
/* ikmlen should have a length of at least Nsk */
- if (ikmlen < alg->encodedprivlen) {
+ if (ikmlen < info->Nsecret) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_INPUT_LENGTH,
"ikm length is :%zu, should be at least %zu",
- ikmlen, alg->encodedprivlen);
+ ikmlen, info->Nsecret);
goto err;
}
- ossl_dhkem_getsuiteid(suiteid, alg->kemid);
+ suiteid[0] = info->kem_id / 256;
+ suiteid[1] = info->kem_id % 256;
- if (!ossl_hpke_labeled_extract(kdfctx, prk, alg->secretlen,
- NULL, 0, suiteid, sizeof(suiteid),
+ if (!ossl_hpke_labeled_extract(kdfctx, prk, info->Nsecret,
+ NULL, 0, LABEL_KEM, suiteid, sizeof(suiteid),
OSSL_DHKEM_LABEL_DKP_PRK, ikm, ikmlen))
goto err;
order = EC_GROUP_get0_order(EC_KEY_get0_group(ec));
do {
- if (!ossl_hpke_labeled_expand(kdfctx, privbuf, alg->encodedprivlen,
- prk, alg->secretlen,
- suiteid, sizeof(suiteid),
+ if (!ossl_hpke_labeled_expand(kdfctx, privbuf, info->Nsk,
+ prk, info->Nsecret,
+ LABEL_KEM, suiteid, sizeof(suiteid),
OSSL_DHKEM_LABEL_CANDIDATE,
&counter, 1))
goto err;
- privbuf[0] &= alg->bitmask;
- if (BN_bin2bn(privbuf, alg->encodedprivlen, priv) == NULL)
+ privbuf[0] &= info->bitmask;
+ if (BN_bin2bn(privbuf, info->Nsk, priv) == NULL)
goto err;
if (counter == 0xFF) {
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY);
@@ -499,7 +470,7 @@ static EC_KEY *derivekey(PROV_EC_CTX *ctx,
/* Generate a random seed if there is no input ikm */
if (seed == NULL || seedlen == 0) {
- seedlen = ctx->alg->encodedprivlen;
+ seedlen = ctx->info->Nsk;
if (seedlen > sizeof(tmpbuf))
goto err;
if (RAND_priv_bytes_ex(ctx->libctx, tmpbuf, seedlen, 0) <= 0)
@@ -599,8 +570,9 @@ static int derive_secret(PROV_EC_CTX *ctx, unsigned char *secret,
unsigned char kemctx[OSSL_HPKE_MAX_PUBLIC * 3];
size_t sender_authpublen;
size_t kemctxlen = 0, dhkmlen = 0;
- size_t encodedpublen = ctx->alg->encodedpublen;
- size_t encodedprivlen = ctx->alg->encodedprivlen;
+ const OSSL_HPKE_KEM_INFO *info = ctx->info;
+ size_t encodedpublen = info->Npk;
+ size_t encodedprivlen = info->Nsk;
int auth = ctx->sender_authkey != NULL;
if (!generate_ecdhkm(privkey1, peerkey1, dhkm, sizeof(dhkm), encodedprivlen))
@@ -630,17 +602,16 @@ static int derive_secret(PROV_EC_CTX *ctx, unsigned char *secret,
goto err;
/* kemctx is the concat of both sides encoded public key */
- memcpy(kemctx, sender_pub, ctx->alg->encodedpublen);
- memcpy(kemctx + ctx->alg->encodedpublen, recipient_pub,
- ctx->alg->encodedpublen);
+ memcpy(kemctx, sender_pub, info->Npk);
+ memcpy(kemctx + info->Npk, recipient_pub, info->Npk);
if (auth)
memcpy(kemctx + 2 * encodedpublen, sender_authpub, encodedpublen);
- kdfctx = ossl_kdf_ctx_create(ctx->kdfname, ctx->alg->kdfdigestname,
+ kdfctx = ossl_kdf_ctx_create(ctx->kdfname, info->mdname,
ctx->libctx, ctx->propq);
if (kdfctx == NULL)
goto err;
- if (!dhkem_extract_and_expand(kdfctx, secret, ctx->alg->secretlen,
- ctx->alg->kemid, dhkm, dhkmlen,
+ if (!dhkem_extract_and_expand(kdfctx, secret, info->Nsecret,
+ info->kem_id, dhkm, dhkmlen,
kemctx, kemctxlen))
goto err;
ret = 1;
@@ -677,22 +648,23 @@ static int dhkem_encap(PROV_EC_CTX *ctx,
unsigned char sender_pub[OSSL_HPKE_MAX_PUBLIC];
unsigned char recipient_pub[OSSL_HPKE_MAX_PUBLIC];
size_t sender_publen, recipient_publen;
+ const OSSL_HPKE_KEM_INFO *info = ctx->info;
if (enc == NULL) {
if (enclen == NULL && secretlen == NULL)
return 0;
if (enclen != NULL)
- *enclen = ctx->alg->encodedpublen;
+ *enclen = info->Nenc;
if (secretlen != NULL)
- *secretlen = ctx->alg->secretlen;
+ *secretlen = info->Nsecret;
return 1;
}
- if (*secretlen < ctx->alg->secretlen) {
+ if (*secretlen < info->Nsecret) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_LENGTH, "*secretlen too small");
return 0;
}
- if (*enclen < ctx->alg->encodedpublen) {
+ if (*enclen < info->Nenc) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_LENGTH, "*enclen too small");
return 0;
}
@@ -707,7 +679,7 @@ static int dhkem_encap(PROV_EC_CTX *ctx,
&recipient_publen, sizeof(recipient_pub)))
goto err;
- if (sender_publen != ctx->alg->encodedpublen
+ if (sender_publen != info->Npk
|| recipient_publen != sender_publen) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY, "Invalid public key");
goto err;
@@ -722,7 +694,7 @@ static int dhkem_encap(PROV_EC_CTX *ctx,
/* Return the senders ephemeral public key in encoded form */
memcpy(enc, sender_pub, sender_publen);
*enclen = sender_publen;
- *secretlen = ctx->alg->secretlen;
+ *secretlen = info->Nsecret;
ret = 1;
err:
EC_KEY_free(sender_ephemkey);
@@ -751,16 +723,17 @@ static int dhkem_decap(PROV_EC_CTX *ctx,
{
int ret = 0;
EC_KEY *sender_ephempubkey = NULL;
+ const OSSL_HPKE_KEM_INFO *info = ctx->info;
unsigned char recipient_pub[OSSL_HPKE_MAX_PUBLIC];
size_t recipient_publen;
- size_t encodedpublen = ctx->alg->encodedpublen;
+ size_t encodedpublen = info->Npk;
if (secret == NULL) {
- *secretlen = ctx->alg->secretlen;
+ *secretlen = info->Nsecret;
return 1;
}
- if (*secretlen < ctx->alg->secretlen) {
+ if (*secretlen < info->Nsecret) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_LENGTH, "*secretlen too small");
return 0;
}
@@ -785,7 +758,7 @@ static int dhkem_decap(PROV_EC_CTX *ctx,
ctx->recipient_key, ctx->sender_authkey,
enc, recipient_pub))
goto err;
- *secretlen = ctx->alg->secretlen;
+ *secretlen = info->Nsecret;
ret = 1;
err:
EC_KEY_free(sender_ephempubkey);
diff --git a/providers/implementations/kem/eckem.h b/providers/implementations/kem/eckem.h
index 44fdde852b..2e46a0f2ff 100644
--- a/providers/implementations/kem/eckem.h
+++ b/providers/implementations/kem/eckem.h
@@ -11,4 +11,3 @@
#define KEM_MODE_DHKEM 1
int ossl_eckem_modename2id(const char *name);
-void ossl_dhkem_getsuiteid(unsigned char suiteid[5], uint16_t kemid);
diff --git a/providers/implementations/kem/ecx_kem.c b/providers/implementations/kem/ecx_kem.c
index 979035fa1c..b868afdfbc 100644
--- a/providers/implementations/kem/ecx_kem.c
+++ b/providers/implementations/kem/ecx_kem.c
@@ -32,7 +32,8 @@
#include "prov/providercommon.h"
#include "prov/ecx.h"
#include "crypto/ecx.h"
-#include "crypto/hpke.h"
+#include <openssl/hpke.h>
+#include "internal/hpke_util.h"
#include "eckem.h"
#define MAX_ECX_KEYLEN X448_KEYLEN
@@ -41,6 +42,9 @@
#define KEMID_X25519_HKDF_SHA256 0x20
#define KEMID_X448_HKDF_SHA512 0x21
+/* ASCII: "KEM", in hex for EBCDIC compatibility */
+static const char LABEL_KEM[] = "\x4b\x45\x4d";
+
typedef struct {
ECX_KEY *recipient_key;
ECX_KEY *sender_authkey;
@@ -48,13 +52,10 @@ typedef struct {
char *propq;
unsigned int mode;
unsigned int op;
- uint16_t kemid;
unsigned char *ikm;
size_t ikmlen;
const char *kdfname;
- const char *kdfdigestname;
- size_t sharedsecretlen;
- size_t keylen;
+ const OSSL_HPKE_KEM_INFO *info;
} PROV_ECX_CTX;
static OSSL_FUNC_kem_newctx_fn ecxkem_newctx;
@@ -72,21 +73,15 @@ static OSSL_FUNC_kem_auth_decapsulate_init_fn ecxkem_auth_decapsulate_init;
* There is only one set of values for X25519 and X448.
* Additional values could be set via set_params if required.
*/
-static void get_kem_values(ECX_KEY *ecx, uint16_t *kemid,
- const char **kdfdigestname, size_t *secretlen,
- size_t *keylen)
+static const OSSL_HPKE_KEM_INFO *get_kem_info(ECX_KEY *ecx)
{
- if (ecx->type == ECX_KEY_TYPE_X25519) {
- *kemid = KEMID_X25519_HKDF_SHA256;
- *kdfdigestname = "SHA256";
- *secretlen = SHA256_DIGEST_LENGTH;
- } else {
- *kemid = KEMID_X448_HKDF_SHA512;
- *kdfdigestname = "SHA512";
- *secretlen = SHA512_DIGEST_LENGTH;
- }
- /* ECX keys have the same length for public and private keys */
- *keylen = ecx->keylen;
+ const char *name = NULL;
+
+ if (ecx->type == ECX_KEY_TYPE_X25519)
+ name = SN_X25519;
+ else
+ name = SN_X448;
+ return ossl_HPKE_KEM_INFO_find_curve(name);
}
/*
@@ -98,8 +93,9 @@ static int recipient_key_set(PROV_ECX_CTX *ctx, ECX_KEY *ecx)
ossl_ecx_key_free(ctx->recipient_key);
ctx->recipient_key = NULL;
if (ecx != NULL) {
- get_kem_values(ecx, &ctx->kemid, &ctx->kdfdigestname,
- &ctx->sharedsecretlen, &ctx->keylen);
+ ctx->info = get_kem_info(ecx);
+ if (ctx->info == NULL)
+ return -2;
ctx->kdfname = "HKDF";
if (!ossl_ecx_key_up_ref(ecx))
return 0;
@@ -302,7 +298,7 @@ static int dhkem_extract_and_expand(EVP_KDF_CTX *kctx,
const unsigned char *kemctx,
size_t kemctxlen)
{
- uint8_t suiteid[5];
+ uint8_t suiteid[2];
uint8_t prk[EVP_MAX_MD_SIZE];
size_t prklen = okmlen; /* Nh */
int ret;
@@ -310,13 +306,14 @@ static int dhkem_extract_and_expand(EVP_KDF_CTX *kctx,
if (prklen > sizeof(prk))
return 0;
- ossl_dhkem_getsuiteid(suiteid, kemid);
+ suiteid[0] = (kemid >> 8) &0xff;
+ suiteid[1] = kemid & 0xff;
ret = ossl_hpke_labeled_extract(kctx, prk, prklen,
- NULL, 0, suiteid, sizeof(suiteid),
+ NULL, 0, LABEL_KEM, suiteid, sizeof(suiteid),
OSSL_DHKEM_LABEL_EAE_PRK, dhkm, dhkmlen)
&& ossl_hpke_labeled_expand(kctx, okm, okmlen, prk, prklen,
- suiteid, sizeof(suiteid),
+ LABEL_KEM, suiteid, sizeof(suiteid),
OSSL_DHKEM_LABEL_SHARED_SECRET,
kemctx, kemctxlen);
OPENSSL_cleanse(prk, prklen);
@@ -344,35 +341,32 @@ int ossl_ecx_dhkem_derive_private(ECX_KEY *ecx, unsigned char *privout,
int ret = 0;
EVP_KDF_CTX *kdfctx = NULL;
unsigned char prk[EVP_MAX_MD_SIZE];
- uint16_t kemid;
- const char *kdfdigestname;
- uint8_t suiteid[5];
- size_t prklen, keylen;
-
- get_kem_values(ecx, &kemid, &kdfdigestname, &prklen, &keylen);
+ uint8_t suiteid[2];
+ const OSSL_HPKE_KEM_INFO *info = get_kem_info(ecx);
/* ikmlen should have a length of at least Nsk */
- if (ikmlen < keylen) {
+ if (ikmlen < info->Nsk) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_INPUT_LENGTH,
"ikm length is :%zu, should be at least %zu",
- ikmlen, keylen);
+ ikmlen, info->Nsk);
goto err;
}
- kdfctx = ossl_kdf_ctx_create("HKDF", kdfdigestname, ecx->libctx, ecx->propq);
+ kdfctx = ossl_kdf_ctx_create("HKDF", info->mdname, ecx->libctx, ecx->propq);
if (kdfctx == NULL)
return 0;
- ossl_dhkem_getsuiteid(suiteid, kemid);
+ suiteid[0] = info->kem_id / 256;
+ suiteid[1] = info->kem_id % 256;
- if (!ossl_hpke_labeled_extract(kdfctx, prk, prklen,
- NULL, 0, suiteid, sizeof(suiteid),
+ if (!ossl_hpke_labeled_extract(kdfctx, prk, info->Nsecret,
+ NULL, 0, LABEL_KEM, suiteid, sizeof(suiteid),
OSSL_DHKEM_LABEL_DKP_PRK, ikm, ikmlen))
goto err;
- if (!ossl_hpke_labeled_expand(kdfctx, privout, keylen, prk, prklen,
- suiteid, sizeof(suiteid), OSSL_DHKEM_LABEL_SK,
- NULL, 0))
+ if (!ossl_hpke_labeled_expand(kdfctx, privout, info->Nsk, prk, info->Nsecret,
+ LABEL_KEM, suiteid, sizeof(suiteid),
+ OSSL_DHKEM_LABEL_SK, NULL, 0))
goto err;
ret = 1;
err:
@@ -398,6 +392,7 @@ static ECX_KEY *derivekey(PROV_ECX_CTX *ctx,
unsigned char *seed = (unsigned char *)ikm;
size_t seedlen = ikmlen;
unsigned char tmpbuf[OSSL_HPKE_MAX_PRIVATE];
+ const OSSL_HPKE_KEM_INFO *info = ctx->info;
key = ossl_ecx_key_new(ctx->libctx, ctx->recipient_key->type, 0, ctx->propq);
if (key == NULL)
@@ -408,12 +403,12 @@ static ECX_KEY *derivekey(PROV_ECX_CTX *ctx,
/* Generate a random seed if there is no input ikm */
if (seed == NULL || seedlen == 0) {
- if (ctx->keylen > sizeof(tmpbuf))
+ if (info->Nsk > sizeof(tmpbuf))
goto err;
- if (RAND_priv_bytes_ex(ctx->libctx, tmpbuf, ctx->keylen, 0) <= 0)
+ if (RAND_priv_bytes_ex(ctx->libctx, tmpbuf, info->Nsk, 0) <= 0)
goto err;
seed = tmpbuf;
- seedlen = ctx->keylen;
+ seedlen = info->Nsk;
}
if (!ossl_ecx_dhkem_derive_private(key, privkey, seed, seedlen))
goto err;
@@ -485,8 +480,9 @@ static int derive_secret(PROV_ECX_CTX *ctx, unsigned char *secret,
unsigned char dhkm[MAX_ECX_KEYLEN * 2];
unsigned char kemctx[MAX_ECX_KEYLEN * 3];
size_t kemctxlen = 0, dhkmlen = 0;
- size_t encodedkeylen = ctx->keylen;
+ const OSSL_HPKE_KEM_INFO *info = ctx->info;
int auth = ctx->sender_authkey != NULL;
+ size_t encodedkeylen = info->Npk;
if (!generate_ecxdhkm(privkey1, peerkey1, dhkm, sizeof(dhkm), encodedkeylen))
goto err;
@@ -513,12 +509,12 @@ static int derive_secret(PROV_ECX_CTX *ctx, unsigned char *secret,
memcpy(kemctx + encodedkeylen, recipient_pub, encodedkeylen);
if (auth)
memcpy(kemctx + 2 * encodedkeylen, sender_authpub, encodedkeylen);
- kdfctx = ossl_kdf_ctx_create(ctx->kdfname, ctx->kdfdigestname,
+ kdfctx = ossl_kdf_ctx_create(ctx->kdfname, info->mdname,
ctx->libctx, ctx->propq);
if (kdfctx == NULL)
goto err;
- if (!dhkem_extract_and_expand(kdfctx, secret, ctx->sharedsecretlen,
- ctx->kemid, dhkm, dhkmlen,
+ if (!dhkem_extract_and_expand(kdfctx, secret, info->Nsecret,
+ info->kem_id, dhkm, dhkmlen,
kemctx, kemctxlen))
goto err;
ret = 1;
@@ -553,22 +549,23 @@ static int dhkem_encap(PROV_ECX_CTX *ctx,
int ret = 0;
ECX_KEY *sender_ephemkey = NULL;
unsigned char *sender_ephempub, *recipient_pub;
+ const OSSL_HPKE_KEM_INFO *info = ctx->info;
if (enc == NULL) {
if (enclen == NULL && secretlen == NULL)
return 0;
if (enclen != NULL)
- *enclen = ctx->keylen;
+ *enclen = info->Nenc;
if (secretlen != NULL)
- *secretlen = ctx->sharedsecretlen;
+ *secretlen = info->Nsecret;
return 1;
}
- if (*secretlen < ctx->sharedsecretlen) {
+ if (*secretlen < info->Nsecret) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_LENGTH, "*secretlen too small");
return 0;
}
- if (*enclen < ctx->keylen) {
+ if (*enclen < info->Nenc) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_LENGTH, "*enclen too small");
return 0;
}
@@ -588,9 +585,9 @@ static int dhkem_encap(PROV_ECX_CTX *ctx,
goto err;
/* Return the public part of the ephemeral key */
- memcpy(enc, sender_ephempub, ctx->keylen);
- *enclen = ctx->keylen;
- *secretlen = ctx->sharedsecretlen;
+ memcpy(enc, sender_ephempub, info->Nenc);
+ *enclen = info->Nenc;
+ *secretlen = info->Nsecret;
ret = 1;
err:
ossl_ecx_key_free(sender_ephemkey);
@@ -620,17 +617,18 @@ static int dhkem_decap(PROV_ECX_CTX *ctx,
int ret = 0;
ECX_KEY *recipient_privkey = ctx->recipient_key;
ECX_KEY *sender_ephempubkey = NULL;
+ const OSSL_HPKE_KEM_INFO *info = ctx->info;
unsigned char *recipient_pub;
if (secret == NULL) {
- *secretlen = ctx->sharedsecretlen;
+ *secretlen = info->Nsecret;
return 1;
}
- if (*secretlen < ctx->sharedsecretlen) {
+ if (*secretlen < info->Nsecret) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_LENGTH, "*secretlen too small");
return 0;
}
- if (enclen != ctx->keylen) {
+ if (enclen != info->Nenc) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY, "Invalid enc public key");
return 0;
}
@@ -650,7 +648,7 @@ static int dhkem_decap(PROV_ECX_CTX *ctx,
enc, recipient_pub))
goto err;
- *secretlen = ctx->sharedsecretlen;
+ *secretlen = info->Nsecret;
ret = 1;
err:
ossl_ecx_key_free(sender_ephempubkey);
diff --git a/providers/implementations/kem/kem_util.c b/providers/implementations/kem/kem_util.c
index 8ce2854ee4..1fd52e1c2d 100644
--- a/providers/implementations/kem/kem_util.c
+++ b/providers/implementations/kem/kem_util.c
@@ -35,11 +35,3 @@ int ossl_eckem_modename2id(const char *name)
}
return KEM_MODE_UNDEFINED;
}
-
-/* suiteid = concat("KEM", I2OSP(kem_id, 2)) */
-void ossl_dhkem_getsuiteid(unsigned char suiteid[5], uint16_t kemid)
-{
- memcpy(suiteid, "KEM", 3);
- suiteid[3] = kemid >> 8;
- suiteid[4] = kemid & 0xFF;
-}