diff --git a/src/ssl_ech.c b/src/ssl_ech.c index 717b7092742..ee1870db0da 100644 --- a/src/ssl_ech.c +++ b/src/ssl_ech.c @@ -570,6 +570,13 @@ int SetEchConfigsEx(WOLFSSL_EchConfig** outputConfigs, void* heap, /* rawLen */ workingConfig->rawLen = length + 4; + /* Reject configs whose raw encoding would overflow the fixed-size + * labeled_ikm buffer in wc_HpkeLabeledExtract */ + if (workingConfig->rawLen > MAX_ECH_CONFIG_RAW_SZ) { + ret = BUFFER_E; + break; + } + /* raw body */ workingConfig->raw = (byte*)XMALLOC(workingConfig->rawLen, heap, DYNAMIC_TYPE_TMP_BUFFER); diff --git a/src/tls.c b/src/tls.c index 5ddb1ca40c5..132979b7304 100644 --- a/src/tls.c +++ b/src/tls.c @@ -9986,6 +9986,10 @@ static int TLSX_KeyShare_ProcessPqcHybridClient(WOLFSSL* ssl, ssl->arrays->preMasterSz = ssSzEcc + ssSzPqc; } + if (ret != 0) { + ForceZero(ssl->arrays->preMasterSecret, ENCRYPT_LEN); + } + TLSX_KeyShare_FreeAll(ecc_kse, ssl->heap); TLSX_KeyShare_FreeAll(pqc_kse, ssl->heap); diff --git a/wolfcrypt/src/hpke.c b/wolfcrypt/src/hpke.c index ed6b1a06e28..6d789baf3d1 100644 --- a/wolfcrypt/src/hpke.c +++ b/wolfcrypt/src/hpke.c @@ -473,6 +473,13 @@ static int wc_HpkeLabeledExtract(Hpke* hpke, byte* suite_id, WC_ALLOC_VAR_EX(labeled_ikm, byte, MAX_HPKE_LABEL_SZ, hpke->heap, DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E); + /* validate total size fits in the labeled_ikm buffer */ + if (HPKE_VERSION_STR_LEN + suite_id_len + label_len + ikm_len + > MAX_HPKE_LABEL_SZ) { + WC_FREE_VAR_EX(labeled_ikm, hpke->heap, DYNAMIC_TYPE_TMP_BUFFER); + return BUFFER_E; + } + /* concat the labeled_ikm */ /* version */ XMEMCPY(labeled_ikm, HPKE_VERSION_STR, HPKE_VERSION_STR_LEN); @@ -520,6 +527,14 @@ static int wc_HpkeLabeledExpand(Hpke* hpke, byte* suite_id, word32 suite_id_len, WC_ALLOC_VAR_EX(labeled_info, byte, MAX_HPKE_LABEL_SZ, hpke->heap, DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E); + /* validate total size fits in the labeled_info buffer + * total = I2OSP length prefix + version + suite_id + label + info */ + if (HPKE_I2OSP_LEN_SZ + HPKE_VERSION_STR_LEN + suite_id_len + label_len + + infoSz > MAX_HPKE_LABEL_SZ) { + WC_FREE_VAR_EX(labeled_info, hpke->heap, DYNAMIC_TYPE_TMP_BUFFER); + return BUFFER_E; + } + /* copy length */ ret = I2OSP((int)L, 2, labeled_info); labeled_info_p = labeled_info + 2; diff --git a/wolfssl/wolfcrypt/hpke.h b/wolfssl/wolfcrypt/hpke.h index 307f46b6ea9..3cc198c6f5b 100644 --- a/wolfssl/wolfcrypt/hpke.h +++ b/wolfssl/wolfcrypt/hpke.h @@ -86,6 +86,15 @@ extern const int hpkeSupportedAead[HPKE_SUPPORTED_AEAD_LEN]; #define MAX_HPKE_LABEL_SZ 512 #endif +/* I2OSP encoded length prefix size in LabeledExpand (RFC 9180 Section 4) */ +#define HPKE_I2OSP_LEN_SZ 2 + +/* Maximum raw ECH config length accepted by SetEchConfigsEx. The raw config + * is concatenated into a MAX_HPKE_LABEL_SZ buffer in wc_HpkeLabeledExtract + * along with version (7) + suite_id (HPKE_SUITE_ID_LEN) + label (~12) + + * TLS info prefix (8) overhead. */ +#define MAX_ECH_CONFIG_RAW_SZ (MAX_HPKE_LABEL_SZ - 50) + typedef struct { void* heap; word32 kem;