update ech to use multi use hpke context, still doesn' handle HRR

This commit is contained in:
John Bland
2023-09-24 17:39:35 -04:00
parent 34d7229d4e
commit 83d7225236
2 changed files with 114 additions and 157 deletions

270
src/tls.c
View File

@ -11360,40 +11360,29 @@ static int TLSX_ECH_Use(WOLFSSL_EchConfig* echConfig, TLSX** extensions,
int ret = 0; int ret = 0;
int suiteIndex; int suiteIndex;
WOLFSSL_ECH* ech; WOLFSSL_ECH* ech;
if (extensions == NULL) if (extensions == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
/* find a supported cipher suite */ /* find a supported cipher suite */
suiteIndex = EchConfigGetSupportedCipherSuite(echConfig); suiteIndex = EchConfigGetSupportedCipherSuite(echConfig);
if (suiteIndex < 0) if (suiteIndex < 0)
return suiteIndex; return suiteIndex;
ech = (WOLFSSL_ECH*)XMALLOC(sizeof(WOLFSSL_ECH), heap, ech = (WOLFSSL_ECH*)XMALLOC(sizeof(WOLFSSL_ECH), heap,
DYNAMIC_TYPE_TMP_BUFFER); DYNAMIC_TYPE_TMP_BUFFER);
if (ech == NULL) if (ech == NULL)
return MEMORY_E; return MEMORY_E;
ForceZero(ech, sizeof(WOLFSSL_ECH)); ForceZero(ech, sizeof(WOLFSSL_ECH));
ech->state = ECH_WRITE_REAL; ech->state = ECH_WRITE_REAL;
ech->echConfig = echConfig; ech->echConfig = echConfig;
/* 0 for outer */ /* 0 for outer */
ech->type = ECH_TYPE_OUTER; ech->type = ECH_TYPE_OUTER;
/* kemId */ /* kemId */
ech->kemId = echConfig->kemId; ech->kemId = echConfig->kemId;
/* cipherSuite kdf */ /* cipherSuite kdf */
ech->cipherSuite.kdfId = echConfig->cipherSuites[suiteIndex].kdfId; ech->cipherSuite.kdfId = echConfig->cipherSuites[suiteIndex].kdfId;
/* cipherSuite aead */ /* cipherSuite aead */
ech->cipherSuite.aeadId = echConfig->cipherSuites[suiteIndex].aeadId; ech->cipherSuite.aeadId = echConfig->cipherSuites[suiteIndex].aeadId;
/* configId */ /* configId */
ech->configId = echConfig->configId; ech->configId = echConfig->configId;
/* encLen */ /* encLen */
switch (echConfig->kemId) switch (echConfig->kemId)
{ {
@ -11413,30 +11402,23 @@ static int TLSX_ECH_Use(WOLFSSL_EchConfig* echConfig, TLSX** extensions,
ech->encLen = DHKEM_X448_ENC_LEN; ech->encLen = DHKEM_X448_ENC_LEN;
break; break;
} }
/* setup hpke */ /* setup hpke */
ech->hpke = (Hpke*)XMALLOC(sizeof(Hpke), heap, DYNAMIC_TYPE_TMP_BUFFER); ech->hpke = (Hpke*)XMALLOC(sizeof(Hpke), heap, DYNAMIC_TYPE_TMP_BUFFER);
if (ech->hpke == NULL) { if (ech->hpke == NULL) {
XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER);
return MEMORY_E; return MEMORY_E;
} }
ret = wc_HpkeInit(ech->hpke, ech->kemId, ech->cipherSuite.kdfId, ret = wc_HpkeInit(ech->hpke, ech->kemId, ech->cipherSuite.kdfId,
ech->cipherSuite.aeadId, heap); ech->cipherSuite.aeadId, heap);
/* setup the ephemeralKey */ /* setup the ephemeralKey */
if (ret == 0) if (ret == 0)
ret = wc_HpkeGenerateKeyPair(ech->hpke, &ech->ephemeralKey, rng); ret = wc_HpkeGenerateKeyPair(ech->hpke, &ech->ephemeralKey, rng);
if (ret == 0) if (ret == 0)
ret = TLSX_Push(extensions, TLSX_ECH, ech, heap); ret = TLSX_Push(extensions, TLSX_ECH, ech, heap);
if (ret != 0) { if (ret != 0) {
XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER);
} }
return ret; return ret;
} }
@ -11447,36 +11429,25 @@ static int TLSX_ServerECH_Use(TLSX** extensions, void* heap,
int ret; int ret;
WOLFSSL_ECH* ech; WOLFSSL_ECH* ech;
TLSX* echX; TLSX* echX;
if (extensions == NULL) if (extensions == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
/* if we already have ech don't override it */ /* if we already have ech don't override it */
echX = TLSX_Find(*extensions, TLSX_ECH); echX = TLSX_Find(*extensions, TLSX_ECH);
if (echX != NULL) if (echX != NULL)
return 0; return 0;
ech = (WOLFSSL_ECH*)XMALLOC(sizeof(WOLFSSL_ECH), heap, ech = (WOLFSSL_ECH*)XMALLOC(sizeof(WOLFSSL_ECH), heap,
DYNAMIC_TYPE_TMP_BUFFER); DYNAMIC_TYPE_TMP_BUFFER);
if (ech == NULL) if (ech == NULL)
return MEMORY_E; return MEMORY_E;
ForceZero(ech, sizeof(WOLFSSL_ECH)); ForceZero(ech, sizeof(WOLFSSL_ECH));
ech->state = ECH_WRITE_NONE; ech->state = ECH_WRITE_NONE;
/* 0 for outer */ /* 0 for outer */
ech->type = ECH_TYPE_OUTER; ech->type = ECH_TYPE_OUTER;
ech->echConfig = configs; ech->echConfig = configs;
/* setup the rest of the settings when we receive ech from the client */ /* setup the rest of the settings when we receive ech from the client */
ret = TLSX_Push(extensions, TLSX_ECH, ech, heap); ret = TLSX_Push(extensions, TLSX_ECH, ech, heap);
if (ret != 0) if (ret != 0)
XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER);
return ret; return ret;
} }
@ -11495,84 +11466,62 @@ static int TLSX_ECH_Write(WOLFSSL_ECH* ech, byte* writeBuf, word16* offset)
Hpke hpke[1]; Hpke hpke[1];
WC_RNG rng[1]; WC_RNG rng[1];
#endif #endif
WOLFSSL_MSG("TLSX_ECH_Write"); WOLFSSL_MSG("TLSX_ECH_Write");
if (ech->state == ECH_WRITE_NONE || ech->state == ECH_PARSED_INTERNAL) if (ech->state == ECH_WRITE_NONE || ech->state == ECH_PARSED_INTERNAL)
return 0; return 0;
if (ech->state == ECH_WRITE_RETRY_CONFIGS) { if (ech->state == ECH_WRITE_RETRY_CONFIGS) {
/* get size then write */ /* get size then write */
ret = GetEchConfigsEx(ech->echConfig, NULL, &configsLen); ret = GetEchConfigsEx(ech->echConfig, NULL, &configsLen);
if (ret != LENGTH_ONLY_E) if (ret != LENGTH_ONLY_E)
return ret; return ret;
ret = GetEchConfigsEx(ech->echConfig, writeBuf, &configsLen); ret = GetEchConfigsEx(ech->echConfig, writeBuf, &configsLen);
if (ret != WOLFSSL_SUCCESS) if (ret != WOLFSSL_SUCCESS)
return ret; return ret;
*offset += configsLen; *offset += configsLen;
return 0; return 0;
} }
#ifdef WOLFSSL_SMALL_STACK
hpke = (Hpke*)XMALLOC(sizeof(Hpke), NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (hpke == NULL)
return MEMORY_E;
rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
if (rng == NULL) {
XFREE(hpke, NULL, DYNAMIC_TYPE_RNG);
return MEMORY_E;
}
#endif
/* type */ /* type */
*writeBuf_p = ech->type; *writeBuf_p = ech->type;
writeBuf_p += sizeof(ech->type); writeBuf_p += sizeof(ech->type);
/* outer has body, inner does not */ /* outer has body, inner does not */
if (ech->type == ECH_TYPE_OUTER) { if (ech->type == ECH_TYPE_OUTER) {
/* kdfId */ /* kdfId */
c16toa(ech->cipherSuite.kdfId, writeBuf_p); c16toa(ech->cipherSuite.kdfId, writeBuf_p);
writeBuf_p += sizeof(ech->cipherSuite.kdfId); writeBuf_p += sizeof(ech->cipherSuite.kdfId);
/* aeadId */ /* aeadId */
c16toa(ech->cipherSuite.aeadId, writeBuf_p); c16toa(ech->cipherSuite.aeadId, writeBuf_p);
writeBuf_p += sizeof(ech->cipherSuite.aeadId); writeBuf_p += sizeof(ech->cipherSuite.aeadId);
/* configId */ /* configId */
*writeBuf_p = ech->configId; *writeBuf_p = ech->configId;
writeBuf_p += sizeof(ech->configId); writeBuf_p += sizeof(ech->configId);
/* encLen */ /* encLen */
c16toa(ech->encLen, writeBuf_p); c16toa(ech->encLen, writeBuf_p);
writeBuf_p += 2; writeBuf_p += 2;
if (ech->state == ECH_WRITE_GREASE) { if (ech->state == ECH_WRITE_GREASE) {
#ifdef WOLFSSL_SMALL_STACK
hpke = (Hpke*)XMALLOC(sizeof(Hpke), NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (hpke == NULL)
return MEMORY_E;
rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
if (rng == NULL) {
XFREE(hpke, NULL, DYNAMIC_TYPE_RNG);
return MEMORY_E;
}
#endif
/* hpke init */ /* hpke init */
ret = wc_HpkeInit(hpke, ech->kemId, ech->cipherSuite.kdfId, ret = wc_HpkeInit(hpke, ech->kemId, ech->cipherSuite.kdfId,
ech->cipherSuite.aeadId, NULL); ech->cipherSuite.aeadId, NULL);
if (ret == 0) if (ret == 0)
rngRet = ret = wc_InitRng(rng); rngRet = ret = wc_InitRng(rng);
/* create the ephemeralKey */ /* create the ephemeralKey */
if (ret == 0) if (ret == 0)
ret = wc_HpkeGenerateKeyPair(hpke, &ephemeralKey, rng); ret = wc_HpkeGenerateKeyPair(hpke, &ephemeralKey, rng);
/* enc */ /* enc */
if (ret == 0) { if (ret == 0) {
ret = wc_HpkeSerializePublicKey(hpke, ephemeralKey, writeBuf_p, ret = wc_HpkeSerializePublicKey(hpke, ephemeralKey, writeBuf_p,
&ech->encLen); &ech->encLen);
writeBuf_p += ech->encLen; writeBuf_p += ech->encLen;
} }
if (ret == 0) { if (ret == 0) {
/* innerClientHelloLen */ /* innerClientHelloLen */
c16toa(GREASE_ECH_SIZE + ((writeBuf_p + 2 - writeBuf) % 32), c16toa(GREASE_ECH_SIZE + ((writeBuf_p + 2 - writeBuf) % 32),
@ -11584,40 +11533,32 @@ static int TLSX_ECH_Write(WOLFSSL_ECH* ech, byte* writeBuf, word16* offset)
((writeBuf_p - writeBuf) % 32)); ((writeBuf_p - writeBuf) % 32));
writeBuf_p += GREASE_ECH_SIZE + ((writeBuf_p - writeBuf) % 32); writeBuf_p += GREASE_ECH_SIZE + ((writeBuf_p - writeBuf) % 32);
} }
if (rngRet == 0) if (rngRet == 0)
wc_FreeRng(rng); wc_FreeRng(rng);
if (ephemeralKey != NULL) if (ephemeralKey != NULL)
wc_HpkeFreeKey(hpke, hpke->kem, ephemeralKey, hpke->heap); wc_HpkeFreeKey(hpke, hpke->kem, ephemeralKey, hpke->heap);
#ifdef WOLFSSL_SMALL_STACK
XFREE(hpke, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
#endif
} }
else { else {
/* write enc to writeBuf_p */ /* write enc to writeBuf_p */
ret = wc_HpkeSerializePublicKey(ech->hpke, ech->ephemeralKey, ret = wc_HpkeSerializePublicKey(ech->hpke, ech->ephemeralKey,
writeBuf_p, &ech->encLen); writeBuf_p, &ech->encLen);
writeBuf_p += ech->encLen; writeBuf_p += ech->encLen;
/* innerClientHelloLen */ /* innerClientHelloLen */
c16toa(ech->innerClientHelloLen, writeBuf_p); c16toa(ech->innerClientHelloLen, writeBuf_p);
writeBuf_p += 2; writeBuf_p += 2;
/* set payload offset for when we finalize */ /* set payload offset for when we finalize */
ech->outerClientPayload = writeBuf_p; ech->outerClientPayload = writeBuf_p;
/* write zeros for payload */ /* write zeros for payload */
XMEMSET(writeBuf_p, 0, ech->innerClientHelloLen); XMEMSET(writeBuf_p, 0, ech->innerClientHelloLen);
writeBuf_p += ech->innerClientHelloLen; writeBuf_p += ech->innerClientHelloLen;
} }
} }
#ifdef WOLFSSL_SMALL_STACK
XFREE(hpke, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
#endif
if (ret == 0) if (ret == 0)
*offset += (writeBuf_p - writeBuf); *offset += (writeBuf_p - writeBuf);
return ret; return ret;
} }
@ -11671,10 +11612,8 @@ static int TLSX_ExtractEch(WOLFSSL_ECH* ech, WOLFSSL_EchConfig* echConfig,
word32 rawConfigLen = 0; word32 rawConfigLen = 0;
byte* info = NULL; byte* info = NULL;
word32 infoLen = 0; word32 infoLen = 0;
if (ech == NULL || echConfig == NULL || aad == NULL) if (ech == NULL || echConfig == NULL || aad == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
/* verify the kem and key len */ /* verify the kem and key len */
switch (echConfig->kemId) switch (echConfig->kemId)
{ {
@ -11697,10 +11636,8 @@ static int TLSX_ExtractEch(WOLFSSL_ECH* ech, WOLFSSL_EchConfig* echConfig,
expectedEncLen = 0; expectedEncLen = 0;
break; break;
} }
if (expectedEncLen != ech->encLen) if (expectedEncLen != ech->encLen)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
/* verify the cipher suite */ /* verify the cipher suite */
for (i = 0; i < echConfig->numCipherSuites; i++) { for (i = 0; i < echConfig->numCipherSuites; i++) {
if (echConfig->cipherSuites[i].kdfId == ech->cipherSuite.kdfId && if (echConfig->cipherSuites[i].kdfId == ech->cipherSuite.kdfId &&
@ -11708,56 +11645,68 @@ static int TLSX_ExtractEch(WOLFSSL_ECH* ech, WOLFSSL_EchConfig* echConfig,
break; break;
} }
} }
if (i >= echConfig->numCipherSuites) { if (i >= echConfig->numCipherSuites) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
/* check if hpke already exists, may if HelloRetryRequest */
ech->hpke = (Hpke*)XMALLOC(sizeof(Hpke), heap, DYNAMIC_TYPE_TMP_BUFFER); if (ech->hpke == NULL) {
ech->hpke = (Hpke*)XMALLOC(sizeof(Hpke), heap, DYNAMIC_TYPE_TMP_BUFFER);
if (ech->hpke == NULL) if (ech->hpke == NULL)
return MEMORY_E;
ret = wc_HpkeInit(ech->hpke, echConfig->kemId, ech->cipherSuite.kdfId,
ech->cipherSuite.aeadId, heap);
/* get the rawConfigLen */
if (ret == 0)
ret = GetEchConfig(echConfig, NULL, &rawConfigLen);
if (ret == LENGTH_ONLY_E)
ret = 0;
/* create info */
if (ret == 0) {
infoLen = TLS_INFO_CONST_STRING_SZ + 1 + rawConfigLen;
info = (byte*)XMALLOC(infoLen, heap, DYNAMIC_TYPE_TMP_BUFFER);
if (info == NULL)
ret = MEMORY_E; ret = MEMORY_E;
else { /* init the hpke struct */
XMEMCPY(info, (byte*)TLS_INFO_CONST_STRING, if (ret == 0) {
TLS_INFO_CONST_STRING_SZ + 1); ret = wc_HpkeInit(ech->hpke, echConfig->kemId,
ret = GetEchConfig(echConfig, info + ech->cipherSuite.kdfId, ech->cipherSuite.aeadId, heap);
TLS_INFO_CONST_STRING_SZ + 1, &rawConfigLen); }
if (ret == 0) {
/* allocate hpkeContext */
ech->hpkeContext =
(HpkeBaseContext*)XMALLOC(sizeof(HpkeBaseContext),
ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (ech->hpkeContext == NULL)
ret = MEMORY_E;
}
/* get the rawConfigLen */
if (ret == 0)
ret = GetEchConfig(echConfig, NULL, &rawConfigLen);
if (ret == LENGTH_ONLY_E)
ret = 0;
/* create info */
if (ret == 0) {
infoLen = TLS_INFO_CONST_STRING_SZ + 1 + rawConfigLen;
info = (byte*)XMALLOC(infoLen, heap, DYNAMIC_TYPE_TMP_BUFFER);
if (info == NULL)
ret = MEMORY_E;
else {
XMEMCPY(info, (byte*)TLS_INFO_CONST_STRING,
TLS_INFO_CONST_STRING_SZ + 1);
ret = GetEchConfig(echConfig, info +
TLS_INFO_CONST_STRING_SZ + 1, &rawConfigLen);
}
}
/* init the context for opening */
if (ret == 0) {
ret = wc_HpkeInitOpenContext(ech->hpke, ech->hpkeContext,
echConfig->receiverPrivkey, ech->enc, ech->encLen, info,
infoLen);
} }
} }
/* decrypt the ech payload */ /* decrypt the ech payload */
if (ret == 0) if (ret == 0) {
ret = wc_HpkeOpenBase(ech->hpke, echConfig->receiverPrivkey, ech->enc, ret = wc_HpkeContextOpenBase(ech->hpke, ech->hpkeContext, aad, aadLen,
ech->encLen, info, infoLen, aad, aadLen, ech->outerClientPayload, ech->outerClientPayload, ech->innerClientHelloLen,
ech->innerClientHelloLen,
ech->innerClientHello + HANDSHAKE_HEADER_SZ); ech->innerClientHello + HANDSHAKE_HEADER_SZ);
}
/* free the hpke and context on failure */
if (ret != 0) { if (ret != 0) {
XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER);
ech->hpke = NULL; ech->hpke = NULL;
XFREE(ech->hpkeContext, heap, DYNAMIC_TYPE_TMP_BUFFER);
ech->hpkeContext = NULL;
} }
if (info != NULL) if (info != NULL)
XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
return ret; return ret;
} }
@ -11882,7 +11831,7 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
} }
} }
/* if we failed to extract */ /* if we failed to extract, set state to retry configs */
if (ret != 0) { if (ret != 0) {
XFREE(ech->innerClientHello, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(ech->innerClientHello, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
ech->innerClientHello = NULL; ech->innerClientHello = NULL;
@ -11928,58 +11877,65 @@ static void TLSX_ECH_Free(WOLFSSL_ECH* ech, void* heap)
* status */ * status */
int TLSX_FinalizeEch(WOLFSSL_ECH* ech, byte* aad, word32 aadLen) int TLSX_FinalizeEch(WOLFSSL_ECH* ech, byte* aad, word32 aadLen)
{ {
int ret; int ret = 0;
void* receiverPubkey = NULL; void* receiverPubkey = NULL;
byte* info; byte* info = NULL;
int infoLen; int infoLen;
byte* aadCopy; byte* aadCopy = NULL;
/* setup hpke context to seal, should be done at most once per connection */
/* import the server public key */ if (ech->hpkeContext == NULL) {
ret = wc_HpkeDeserializePublicKey(ech->hpke, &receiverPubkey, /* import the server public key */
ech->echConfig->receiverPubkey, ech->encLen); ret = wc_HpkeDeserializePublicKey(ech->hpke, &receiverPubkey,
ech->echConfig->receiverPubkey, ech->encLen);
if (ret == 0) { if (ret == 0) {
/* create info */ /* allocate hpke context */
infoLen = TLS_INFO_CONST_STRING_SZ + 1 + ech->echConfig->rawLen; ech->hpkeContext =
info = (byte*)XMALLOC(infoLen, ech->hpke->heap, (HpkeBaseContext*)XMALLOC(sizeof(HpkeBaseContext),
DYNAMIC_TYPE_TMP_BUFFER); ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (info == NULL) if (ech->hpkeContext == NULL)
ret = MEMORY_E; ret = MEMORY_E;
}
if (ret == 0) {
/* create info */
infoLen = TLS_INFO_CONST_STRING_SZ + 1 + ech->echConfig->rawLen;
info = (byte*)XMALLOC(infoLen, ech->hpke->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (info == NULL)
ret = MEMORY_E;
}
if (ret == 0) { if (ret == 0) {
/* puts the null byte in for me */ /* puts the null byte in for me */
XMEMCPY(info, (byte*)TLS_INFO_CONST_STRING, TLS_INFO_CONST_STRING_SZ XMEMCPY(info, (byte*)TLS_INFO_CONST_STRING,
+ 1); TLS_INFO_CONST_STRING_SZ + 1);
XMEMCPY(info + TLS_INFO_CONST_STRING_SZ + 1, ech->echConfig->raw, XMEMCPY(info + TLS_INFO_CONST_STRING_SZ + 1,
ech->echConfig->rawLen); ech->echConfig->raw, ech->echConfig->rawLen);
/* init the context for seal with info and keys */
/* make a copy of the aad since we overwrite it */ ret = wc_HpkeInitSealContext(ech->hpke, ech->hpkeContext,
aadCopy = (byte*)XMALLOC(aadLen, ech->hpke->heap, ech->ephemeralKey, receiverPubkey, info, infoLen);
DYNAMIC_TYPE_TMP_BUFFER);
if (aadCopy == NULL) {
XFREE(info, ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER);
ret = MEMORY_E;
}
}
if (ret == 0) {
XMEMCPY(aadCopy, aad, aadLen);
/* seal the payload */
ret = wc_HpkeSealBase(ech->hpke, ech->ephemeralKey, receiverPubkey,
info, infoLen, aadCopy, aadLen, ech->innerClientHello,
ech->innerClientHelloLen - ech->hpke->Nt,
ech->outerClientPayload);
XFREE(info, ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(aadCopy, ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER);
} }
} }
if (ret == 0) {
/* make a copy of the aad since we overwrite it */
aadCopy = (byte*)XMALLOC(aadLen, ech->hpke->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (aadCopy == NULL) {
ret = MEMORY_E;
}
}
if (ret == 0) {
XMEMCPY(aadCopy, aad, aadLen);
/* seal the payload with context */
ret = wc_HpkeContextSealBase(ech->hpke, ech->hpkeContext, aadCopy,
aadLen, ech->innerClientHello,
ech->innerClientHelloLen - ech->hpke->Nt, ech->outerClientPayload);
}
if (info != NULL)
XFREE(info, ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (aadCopy != NULL)
XFREE(aadCopy, ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (receiverPubkey != NULL) if (receiverPubkey != NULL)
wc_HpkeFreeKey(ech->hpke, ech->hpke->kem, receiverPubkey, wc_HpkeFreeKey(ech->hpke, ech->hpke->kem, receiverPubkey,
ech->hpke->heap); ech->hpke->heap);
return ret; return ret;
} }

View File

@ -2920,6 +2920,7 @@ typedef struct WOLFSSL_EchConfig {
typedef struct WOLFSSL_ECH { typedef struct WOLFSSL_ECH {
Hpke* hpke; Hpke* hpke;
HpkeBaseContext* hpkeContext;
const byte* aad; const byte* aad;
void* ephemeralKey; void* ephemeralKey;
WOLFSSL_EchConfig* echConfig; WOLFSSL_EchConfig* echConfig;