diff --git a/src/ssl_ech.c b/src/ssl_ech.c index a880b34d0c..a03e29e916 100644 --- a/src/ssl_ech.c +++ b/src/ssl_ech.c @@ -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); diff --git a/src/tls.c b/src/tls.c index ec949a752f..bb56c052af 100644 --- a/src/tls.c +++ b/src/tls.c @@ -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) diff --git a/src/tls13.c b/src/tls13.c index 0401b83e03..749e413705 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -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; diff --git a/tests/api.c b/tests/api.c index 10aea8d3fd..ce610df627 100644 --- a/tests/api.c +++ b/tests/api.c @@ -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++) { diff --git a/wolfcrypt/src/hpke.c b/wolfcrypt/src/hpke.c index cf13e91c8a..4039b4cf22 100644 --- a/wolfcrypt/src/hpke.c +++ b/wolfcrypt/src/hpke.c @@ -45,24 +45,6 @@ #include #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 */ diff --git a/wolfssl/wolfcrypt/hpke.h b/wolfssl/wolfcrypt/hpke.h index d6d82aaf1f..09f0e6bc11 100644 --- a/wolfssl/wolfcrypt/hpke.h +++ b/wolfssl/wolfcrypt/hpke.h @@ -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 */