mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 10:47:28 +02:00
update ech to use multi use hpke context, still doesn' handle HRR
This commit is contained in:
270
src/tls.c
270
src/tls.c
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user