move hpke-esque code out of tls

This commit is contained in:
sebastian-carpenter
2026-03-16 09:47:04 -06:00
parent 5acdcf6ad7
commit 36580b0ae8
6 changed files with 170 additions and 126 deletions
+2 -25
View File
@@ -338,23 +338,7 @@ int GetEchConfig(WOLFSSL_EchConfig* config, byte* output, word32* outputLen)
totalLen += 2;
/* hpke_pub_key */
switch (config->kemId) {
case DHKEM_P256_HKDF_SHA256:
totalLen += DHKEM_P256_ENC_LEN;
break;
case DHKEM_P384_HKDF_SHA384:
totalLen += DHKEM_P384_ENC_LEN;
break;
case DHKEM_P521_HKDF_SHA512:
totalLen += DHKEM_P521_ENC_LEN;
break;
case DHKEM_X25519_HKDF_SHA256:
totalLen += DHKEM_X25519_ENC_LEN;
break;
case DHKEM_X448_HKDF_SHA512:
totalLen += DHKEM_X448_ENC_LEN;
break;
}
totalLen += wc_HpkeKemGetEncLen(config->kemId);
/* cipherSuitesLen */
totalLen += 2;
@@ -693,16 +677,9 @@ int SetEchConfigsEx(WOLFSSL_EchConfig** outputConfigs, void* heap,
break;
}
/* check that we support this config */
for (j = 0; j < HPKE_SUPPORTED_KEM_LEN; j++) {
if (hpkeSupportedKem[j] == workingConfig->kemId)
break;
}
/* KEM or ciphersuite not supported, free this config and then try to
* parse another */
if (j >= HPKE_SUPPORTED_KEM_LEN ||
EchConfigGetSupportedCipherSuite(workingConfig) < 0) {
if (EchConfigGetSupportedCipherSuite(workingConfig) < 0) {
XFREE(workingConfig->cipherSuites, heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(workingConfig->publicName, heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(workingConfig->raw, heap, DYNAMIC_TYPE_TMP_BUFFER);
+13 -46
View File
@@ -13259,24 +13259,7 @@ static int TLSX_ECH_Use(WOLFSSL_EchConfig* echConfig, TLSX** extensions,
/* configId */
ech->configId = echConfig->configId;
/* encLen */
switch (echConfig->kemId)
{
case DHKEM_P256_HKDF_SHA256:
ech->encLen = DHKEM_P256_ENC_LEN;
break;
case DHKEM_P384_HKDF_SHA384:
ech->encLen = DHKEM_P384_ENC_LEN;
break;
case DHKEM_P521_HKDF_SHA512:
ech->encLen = DHKEM_P521_ENC_LEN;
break;
case DHKEM_X25519_HKDF_SHA256:
ech->encLen = DHKEM_X25519_ENC_LEN;
break;
case DHKEM_X448_HKDF_SHA512:
ech->encLen = DHKEM_X448_ENC_LEN;
break;
}
ech->encLen = wc_HpkeKemGetEncLen(echConfig->kemId);
/* setup hpke */
ech->hpke = (Hpke*)XMALLOC(sizeof(Hpke), heap, DYNAMIC_TYPE_TMP_BUFFER);
if (ech->hpke == NULL) {
@@ -13288,8 +13271,13 @@ static int TLSX_ECH_Use(WOLFSSL_EchConfig* echConfig, TLSX** extensions,
/* setup the ephemeralKey */
if (ret == 0)
ret = wc_HpkeGenerateKeyPair(ech->hpke, &ech->ephemeralKey, rng);
if (ret == 0)
if (ret == 0) {
ret = TLSX_Push(extensions, TLSX_ECH, ech, heap);
if (ret != 0) {
wc_HpkeFreeKey(ech->hpke, ech->hpke->kem, ech->ephemeralKey,
ech->hpke->heap);
}
}
if (ret != 0) {
XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER);
@@ -13916,7 +13904,6 @@ static int TLSX_ExtractEch(WOLFSSL_ECH* ech, WOLFSSL_EchConfig* echConfig,
byte* aad, word32 aadLen, void* heap)
{
int ret = 0;
int expectedEncLen;
int i;
word32 rawConfigLen = 0;
byte* info = NULL;
@@ -13924,28 +13911,7 @@ static int TLSX_ExtractEch(WOLFSSL_ECH* ech, WOLFSSL_EchConfig* echConfig,
if (ech == NULL || echConfig == NULL || aad == NULL)
return BAD_FUNC_ARG;
/* verify the kem and key len */
switch (echConfig->kemId)
{
case DHKEM_P256_HKDF_SHA256:
expectedEncLen = DHKEM_P256_ENC_LEN;
break;
case DHKEM_P384_HKDF_SHA384:
expectedEncLen = DHKEM_P384_ENC_LEN;
break;
case DHKEM_P521_HKDF_SHA512:
expectedEncLen = DHKEM_P521_ENC_LEN;
break;
case DHKEM_X25519_HKDF_SHA256:
expectedEncLen = DHKEM_X25519_ENC_LEN;
break;
case DHKEM_X448_HKDF_SHA512:
expectedEncLen = DHKEM_X448_ENC_LEN;
break;
default:
expectedEncLen = 0;
break;
}
if (expectedEncLen != ech->encLen)
if (wc_HpkeKemGetEncLen(echConfig->kemId) != ech->encLen)
return BAD_FUNC_ARG;
/* verify the cipher suite */
for (i = 0; i < echConfig->numCipherSuites; i++) {
@@ -14229,11 +14195,12 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
static void TLSX_ECH_Free(WOLFSSL_ECH* ech, void* heap)
{
XFREE(ech->innerClientHello, heap, DYNAMIC_TYPE_TMP_BUFFER);
if (ech->ephemeralKey != NULL)
wc_HpkeFreeKey(ech->hpke, ech->hpke->kem, ech->ephemeralKey,
ech->hpke->heap);
if (ech->hpke != NULL)
if (ech->hpke != NULL) {
if (ech->ephemeralKey != NULL)
wc_HpkeFreeKey(ech->hpke, ech->hpke->kem, ech->ephemeralKey,
ech->hpke->heap);
XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER);
}
if (ech->hpkeContext != NULL)
XFREE(ech->hpkeContext, heap, DYNAMIC_TYPE_TMP_BUFFER);
if (ech->privateName != NULL)
+8 -17
View File
@@ -3782,26 +3782,17 @@ static byte helloRetryRequestRandom[] = {
/* returns the index of the first supported cipher suite, -1 if none */
int EchConfigGetSupportedCipherSuite(WOLFSSL_EchConfig* config)
{
int i, j, supported = 0;
int i = 0;
if (!wc_HpkeKemIsSupported(config->kemId)) {
return WOLFSSL_FATAL_ERROR;
}
for (i = 0; i < config->numCipherSuites; i++) {
supported = 0;
for (j = 0; j < HPKE_SUPPORTED_KDF_LEN; j++) {
if (config->cipherSuites[i].kdfId == hpkeSupportedKdf[j])
break;
}
if (j < HPKE_SUPPORTED_KDF_LEN)
for (j = 0; j < HPKE_SUPPORTED_AEAD_LEN; j++) {
if (config->cipherSuites[i].aeadId == hpkeSupportedAead[j]) {
supported = 1;
break;
}
}
if (supported)
if (wc_HpkeKdfIsSupported(config->cipherSuites[i].kdfId) &&
wc_HpkeAeadIsSupported(config->cipherSuites[i].aeadId)) {
return i;
}
}
return WOLFSSL_FATAL_ERROR;
+29 -3
View File
@@ -14547,15 +14547,41 @@ static int test_wolfSSL_Tls13_ECH_all_algos(void)
int j;
int k;
static const word16 kems[] = {
#if defined(HAVE_ECC)
#if (defined(WOLFSSL_SHA224) || !defined(NO_SHA256))
DHKEM_P256_HKDF_SHA256,
#endif
#if defined(WOLFSSL_SHA384)
DHKEM_P384_HKDF_SHA384,
#endif
#if (defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512))
DHKEM_P521_HKDF_SHA512,
#endif
#endif /* HAVE_ECC */
#if defined(HAVE_CURVE25519) && (defined(WOLFSSL_SHA224) || !defined(NO_SHA256))
DHKEM_X25519_HKDF_SHA256,
#endif
};
static const word16 kdfs[] = {
#if defined(WOLFSSL_SHA224) || !defined(NO_SHA256)
HKDF_SHA256,
#endif
#ifdef WOLFSSL_SHA384
HKDF_SHA384,
#endif
#ifdef WOLFSSL_SHA512
HKDF_SHA512,
#endif
};
static const word16 aeads[] = {
#ifdef WOLFSSL_AES_128
HPKE_AES_128_GCM,
#endif
#ifdef WOLFSSL_AES_256
HPKE_AES_256_GCM,
#endif
};
static const word16 kdfs[] = { HKDF_SHA256, HKDF_SHA384, HKDF_SHA512 };
static const word16 aeads[] = { HPKE_AES_128_GCM, HPKE_AES_256_GCM };
/* test each KEM with default KDF and AEAD */
for (i = 0; i < (int)(sizeof(kems) / sizeof(*kems)); i++) {
echCbTestKemID = kems[i];
for (j = 0; j < (int)(sizeof(kdfs) / sizeof(*kdfs)); j++) {
+110 -24
View File
@@ -45,24 +45,6 @@
#include <wolfcrypt/src/misc.c>
#endif
const int hpkeSupportedKem[HPKE_SUPPORTED_KEM_LEN] = {
DHKEM_P256_HKDF_SHA256,
DHKEM_P384_HKDF_SHA384,
DHKEM_P521_HKDF_SHA512,
DHKEM_X25519_HKDF_SHA256,
};
const int hpkeSupportedKdf[HPKE_SUPPORTED_KDF_LEN] = {
HKDF_SHA256,
HKDF_SHA384,
HKDF_SHA512,
};
const int hpkeSupportedAead[HPKE_SUPPORTED_AEAD_LEN] = {
HPKE_AES_128_GCM,
HPKE_AES_256_GCM,
};
static const char* KEM_STR = "KEM";
static const int KEM_STR_LEN = 3;
@@ -132,9 +114,9 @@ int wc_HpkeInit(Hpke* hpke, int kem, int kdf, int aead, void* heap)
}
XMEMSET(hpke, 0, sizeof(*hpke));
hpke->kem = (word32)kem;
hpke->kdf = (word32)kdf;
hpke->aead = (word32)aead;
hpke->kem = (word16)kem;
hpke->kdf = (word16)kdf;
hpke->aead = (word16)aead;
hpke->heap = heap;
/* set kem_suite_id */
@@ -227,20 +209,26 @@ int wc_HpkeInit(Hpke* hpke, int kem, int kdf, int aead, void* heap)
if (ret == 0) {
switch (kdf) {
#if defined(WOLFSSL_SHA224) || !defined(NO_SHA256)
case HKDF_SHA256:
hpke->Nh = WC_SHA256_DIGEST_SIZE;
hpke->kdf_digest = WC_SHA256;
break;
#endif
#ifdef WOLFSSL_SHA384
case HKDF_SHA384:
hpke->Nh = WC_SHA384_DIGEST_SIZE;
hpke->kdf_digest = WC_SHA384;
break;
#endif
#ifdef WOLFSSL_SHA512
case HKDF_SHA512:
hpke->Nh = WC_SHA512_DIGEST_SIZE;
hpke->kdf_digest = WC_SHA512;
break;
#endif
default:
ret = BAD_FUNC_ARG;
@@ -250,17 +238,21 @@ int wc_HpkeInit(Hpke* hpke, int kem, int kdf, int aead, void* heap)
if (ret == 0) {
switch (aead) {
#ifdef WOLFSSL_AES_128
case HPKE_AES_128_GCM:
hpke->Nk = AES_128_KEY_SIZE;
hpke->Nn = GCM_NONCE_MID_SZ;
hpke->Nt = WC_AES_BLOCK_SIZE;
break;
#endif
#ifdef WOLFSSL_AES_256
case HPKE_AES_256_GCM:
hpke->Nk = AES_256_KEY_SIZE;
hpke->Nn = GCM_NONCE_MID_SZ;
hpke->Nt = WC_AES_BLOCK_SIZE;
break;
#endif
default:
ret = BAD_FUNC_ARG;
@@ -329,7 +321,7 @@ int wc_HpkeGenerateKeyPair(Hpke* hpke, void** keypair, WC_RNG* rng)
ret = MEMORY_E;
if (ret != 0 && *keypair != NULL) {
wc_HpkeFreeKey(hpke, (word16)hpke->kem, *keypair, hpke->heap);
wc_HpkeFreeKey(hpke, hpke->kem, *keypair, hpke->heap);
*keypair = NULL;
}
@@ -427,7 +419,7 @@ int wc_HpkeDeserializePublicKey(Hpke* hpke, void** key, const byte* in,
ret = MEMORY_E;
if (ret != 0 && *key != NULL) {
wc_HpkeFreeKey(hpke, (word16)hpke->kem, *key, hpke->heap);
wc_HpkeFreeKey(hpke, hpke->kem, *key, hpke->heap);
*key = NULL;
}
@@ -1083,7 +1075,7 @@ static int wc_HpkeDecap(Hpke* hpke, void* receiverKey, const byte* pubKey,
}
if (ephemeralKey != NULL)
wc_HpkeFreeKey(hpke, (word16)hpke->kem, ephemeralKey, hpke->heap);
wc_HpkeFreeKey(hpke, hpke->kem, ephemeralKey, hpke->heap);
if (ret == 0) {
/* copy pubKey into kemContext */
@@ -1226,4 +1218,98 @@ int wc_HpkeOpenBase(Hpke* hpke, void* receiverKey, const byte* pubKey,
return ret;
}
WOLFSSL_LOCAL word16 wc_HpkeKemGetEncLen(word16 kemId)
{
switch (kemId)
{
#if defined(HAVE_ECC)
#if defined(WOLFSSL_SHA224) || !defined(NO_SHA256)
case DHKEM_P256_HKDF_SHA256:
return DHKEM_P256_ENC_LEN;
#endif
#ifdef WOLFSSL_SHA384
case DHKEM_P384_HKDF_SHA384:
return DHKEM_P384_ENC_LEN;
#endif
#if defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)
case DHKEM_P521_HKDF_SHA512:
return DHKEM_P521_ENC_LEN;
#endif
#endif /* HAVE_ECC */
#if defined(HAVE_CURVE25519) && \
(defined(WOLFSSL_SHA224) || !defined(NO_SHA256))
case DHKEM_X25519_HKDF_SHA256:
return DHKEM_X25519_ENC_LEN;
#endif
#if defined(HAVE_CURVE448) &&\
(defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512))
case DHKEM_X448_HKDF_SHA512:
return DHKEM_X448_ENC_LEN;
#endif
default:
return 0;
}
}
WOLFSSL_LOCAL int wc_HpkeKemIsSupported(word16 kemId)
{
switch (kemId) {
#if defined(HAVE_ECC)
#if defined(WOLFSSL_SHA224) || !defined(NO_SHA256)
case DHKEM_P256_HKDF_SHA256:
#endif
#ifdef WOLFSSL_SHA384
case DHKEM_P384_HKDF_SHA384:
#endif
#if defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)
case DHKEM_P521_HKDF_SHA512:
#endif
#endif /* HAVE_ECC */
#if defined(HAVE_CURVE25519) && \
(defined(WOLFSSL_SHA224) || !defined(NO_SHA256))
case DHKEM_X25519_HKDF_SHA256:
#endif
return 1;
case DHKEM_X448_HKDF_SHA512:
default:
return 0;
}
}
WOLFSSL_LOCAL int wc_HpkeKdfIsSupported(word16 kdfId)
{
switch (kdfId) {
#if defined(WOLFSSL_SHA224) || !defined(NO_SHA256)
case HKDF_SHA256:
#endif
#ifdef WOLFSSL_SHA384
case HKDF_SHA384:
#endif
#ifdef WOLFSSL_SHA512
case HKDF_SHA512:
#endif
return 1;
default:
return 0;
}
}
WOLFSSL_LOCAL int wc_HpkeAeadIsSupported(word16 aeadId)
{
switch (aeadId) {
#ifdef WOLFSSL_AES_128
case HPKE_AES_128_GCM:
#endif
#ifdef WOLFSSL_AES_256
case HPKE_AES_256_GCM:
#endif
return 1;
default:
return 0;
}
}
#endif /* HAVE_HPKE && (HAVE_ECC || HAVE_CURVE25519) && HAVE_AESGCM */
+8 -11
View File
@@ -64,14 +64,6 @@ enum {
HPKE_AES_256_GCM = 0x0002
};
/* TODO better way of doing this */
#define HPKE_SUPPORTED_KEM_LEN 4
#define HPKE_SUPPORTED_KDF_LEN 3
#define HPKE_SUPPORTED_AEAD_LEN 2
extern const int hpkeSupportedKem[HPKE_SUPPORTED_KEM_LEN];
extern const int hpkeSupportedKdf[HPKE_SUPPORTED_KDF_LEN];
extern const int hpkeSupportedAead[HPKE_SUPPORTED_AEAD_LEN];
#define HPKE_Nh_MAX 64
#define HPKE_Nk_MAX 32
#define HPKE_Nn_MAX 12
@@ -88,9 +80,6 @@ extern const int hpkeSupportedAead[HPKE_SUPPORTED_AEAD_LEN];
typedef struct {
void* heap;
word32 kem;
word32 kdf;
word32 aead;
word32 Nh;
word32 Nk;
word32 Nn;
@@ -101,6 +90,9 @@ typedef struct {
int kdf_digest;
int kem_digest;
int curve_id;
word16 kem;
word16 kdf;
word16 aead;
byte kem_suite_id[KEM_SUITE_ID_LEN];
byte hpke_suite_id[HPKE_SUITE_ID_LEN];
} Hpke;
@@ -137,6 +129,11 @@ WOLFSSL_API int wc_HpkeOpenBase(Hpke* hpke, void* receiverKey,
const byte* pubKey, word16 pubKeySz, byte* info, word32 infoSz, byte* aad,
word32 aadSz, byte* ciphertext, word32 ctSz, byte* plaintext);
WOLFSSL_LOCAL word16 wc_HpkeKemGetEncLen(word16 kemId);
WOLFSSL_LOCAL int wc_HpkeKemIsSupported(word16 kemId);
WOLFSSL_LOCAL int wc_HpkeKdfIsSupported(word16 kdfId);
WOLFSSL_LOCAL int wc_HpkeAeadIsSupported(word16 aeadId);
#endif
#endif /* HAVE_HPKE && HAVE_ECC */