Skip to content

Commit f691992

Browse files
ECH tidying
1 parent 8a7d327 commit f691992

4 files changed

Lines changed: 88 additions & 24 deletions

File tree

src/tls.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2358,7 +2358,7 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, const byte* input, word16 length,
23582358
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
23592359
if (ech != NULL && ech->sniState == ECH_INNER_SNI){
23602360
/* SNI status is carried over from processing the outer hello so it is
2361-
* necessary to clear it before processing the inner hello */
2361+
* necessary to clear it before processing the inner hello */
23622362
ech->sniState = ECH_INNER_SNI_ATTEMPT;
23632363
if (sni != NULL){
23642364
sni->status = WOLFSSL_SNI_NO_MATCH;
@@ -13340,11 +13340,23 @@ static int TLSX_ECH_Write(WOLFSSL_ECH* ech, byte msgType, byte* writeBuf,
1334013340

1334113341
WOLFSSL_MSG("TLSX_ECH_Write");
1334213342
if (msgType == hello_retry_request) {
13343-
/* reserve space to write the confirmation to */
13344-
*offset += ECH_ACCEPT_CONFIRMATION_SZ;
13345-
/* set confBuf */
13346-
ech->confBuf = writeBuf;
13347-
return 0;
13343+
WC_ALLOC_VAR_EX(rng, WC_RNG, 1, NULL, DYNAMIC_TYPE_RNG, ret = MEMORY_E);
13344+
if (ret == 0) {
13345+
ret = wc_InitRng(rng);
13346+
}
13347+
if (ret == 0) {
13348+
/* randomize confirmation in case ech is rejected */
13349+
ret = wc_RNG_GenerateBlock(rng, writeBuf,
13350+
ECH_ACCEPT_CONFIRMATION_SZ);
13351+
wc_FreeRng(rng);
13352+
}
13353+
if (ret == 0) {
13354+
*offset += ECH_ACCEPT_CONFIRMATION_SZ;
13355+
ech->confBuf = writeBuf;
13356+
}
13357+
13358+
WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
13359+
return ret;
1334813360
}
1334913361
if (ech->state == ECH_WRITE_NONE || ech->state == ECH_PARSED_INTERNAL)
1335013362
return 0;
@@ -13567,7 +13579,7 @@ static int TLSX_ECH_CheckInnerPadding(WOLFSSL* ssl, WOLFSSL_ECH* ech)
1356713579
* returns 0 on success and otherwise failure.
1356813580
*/
1356913581
static const byte* TLSX_ECH_FindOuterExtension(const byte* outerCh,
13570-
word32 chLen, word16 extType, word16* extLen, word16* extOffset,
13582+
word32 chLen, word16 extType, word32* extLen, word32* extOffset,
1357113583
word16* extensionsStart, word16* extensionsLen)
1357213584
{
1357313585
word32 idx = *extOffset;
@@ -13647,8 +13659,8 @@ static int TLSX_ECH_CopyOuterExtensions(const byte* outerCh, word32 outerChLen,
1364713659
{
1364813660
int ret = 0;
1364913661
word16 refType;
13650-
word16 outerExtLen;
13651-
word16 outerExtOffset = 0;
13662+
word32 outerExtLen;
13663+
word32 outerExtOffset = 0;
1365213664
word16 extsStart;
1365313665
word16 extsLen;
1365413666
const byte* outerExtData;

src/tls13.c

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4054,7 +4054,6 @@ static int EchCalcAcceptance(WOLFSSL* ssl, byte* label, word16 labelSz,
40544054
#endif
40554055
return ret;
40564056
}
4057-
40584057
#endif
40594058

40604059
#ifndef NO_WOLFSSL_CLIENT
@@ -5065,12 +5064,20 @@ static int Dtls13ClientDoDowngrade(WOLFSSL* ssl)
50655064
#endif /* WOLFSSL_DTLS13 && !WOLFSSL_NO_CLIENT*/
50665065

50675066
#if defined(HAVE_ECH)
5068-
/* check if the server accepted ech or not, return status */
5067+
/* Calculate ECH acceptance and verify the server accepted ECH.
5068+
*
5069+
* ssl SSL/TLS object.
5070+
* label Ascii string describing ECH acceptance type.
5071+
* labelSz Length of label excluding NULL character.
5072+
* input The buffer to calculate confirmation off of.
5073+
* acceptOffset Where the 8 ECH confirmation bytes start.
5074+
* helloSz Size of hello message.
5075+
* returns 0 on success and otherwise failure.
5076+
*/
50695077
static int EchCheckAcceptance(WOLFSSL* ssl, byte* label, word16 labelSz,
5070-
const byte* input, int acceptOffset, int helloSz)
5078+
const byte* input, int acceptOffset, int helloSz, byte msgType)
50715079
{
50725080
int ret = 0;
5073-
int isHrr = 0;
50745081
int headerSz;
50755082
HS_Hashes* tmpHashes;
50765083
byte acceptConfirmation[ECH_ACCEPT_CONFIRMATION_SZ];
@@ -5084,13 +5091,8 @@ static int EchCheckAcceptance(WOLFSSL* ssl, byte* label, word16 labelSz,
50845091
headerSz = HANDSHAKE_HEADER_SZ;
50855092
#endif
50865093

5087-
if (labelSz == ECH_HRR_ACCEPT_CONFIRMATION_LABEL_SZ &&
5088-
XMEMCMP(label, echHrrAcceptConfirmationLabel, labelSz) == 0) {
5089-
isHrr = 1;
5090-
}
5091-
50925094
ret = EchCalcAcceptance(ssl, label, labelSz, input, acceptOffset, helloSz,
5093-
isHrr, acceptConfirmation);
5095+
msgType == hello_retry_request, acceptConfirmation);
50945096

50955097
tmpHashes = ssl->hsHashes;
50965098
ssl->hsHashes = ssl->hsHashesEch;
@@ -5105,7 +5107,7 @@ static int EchCheckAcceptance(WOLFSSL* ssl, byte* label, word16 labelSz,
51055107

51065108
/* after HRR, hsHashesEch must contain:
51075109
* message_hash(ClientHelloInner1) || HRR (actual, not zeros) */
5108-
if (isHrr) {
5110+
if (msgType == hello_retry_request) {
51095111
ret = HashRaw(ssl, input, helloSz + headerSz);
51105112
}
51115113
/* normal TLS code will calculate transcript of ServerHello */
@@ -5663,7 +5665,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
56635665
}
56645666

56655667
#if defined(HAVE_ECH)
5666-
/* check for acceptConfirmation, must be done after hashes restart */
5668+
/* check for acceptConfirmation */
56675669
if (ssl->echConfigs != NULL && !ssl->options.disableECH) {
56685670
args->echX = TLSX_Find(ssl->extensions, TLSX_ECH);
56695671
/* account for hrr extension instead of server random */
@@ -5680,7 +5682,8 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
56805682
/* check acceptance */
56815683
if (ret == 0) {
56825684
ret = EchCheckAcceptance(ssl, args->acceptLabel,
5683-
args->acceptLabelSz, input, args->acceptOffset, helloSz);
5685+
args->acceptLabelSz, input, args->acceptOffset, helloSz,
5686+
args->extMsgType);
56845687
}
56855688
if (ret != 0)
56865689
return ret;

tests/api.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14210,9 +14210,9 @@ static int test_wolfSSL_Tls13_ECH_params_b64(void)
1421014210
/* base64 ech configs from cloudflare-ech.com (these are good configs) */
1421114211
const char* b64Valid = "AEX+DQBBFAAgACBuAoQI8+liEVYQbXKBDeVgTmF2rfXuKO2knhwrN7jgTgAEAAEAAQASY2xvdWRmbGFyZS1lY2guY29tAAA=";
1421214212
/* ech configs with bad/unsupported algorithm */
14213-
const char* b64BadAlgo = "AEX+DQBBFP//ACBuAoQI8+liEVYQbXKBDeVgTmF2rfXuKO2knhwrN7jgTgAEAAEAAQASY2xvdWRmbGFyZS1lY2guY29tAAA=";
14213+
const char* b64BadAlgo = "AEX+DQBBFP7+ACBuAoQI8+liEVYQbXKBDeVgTmF2rfXuKO2knhwrN7jgTgAEAAEAAQASY2xvdWRmbGFyZS1lY2guY29tAAA=";
1421414214
/* ech configs with bad/unsupported ciphersuite */
14215-
const char* b64BadCiph = "AEX+DQBBFAAgACBuAoQI8+liEVYQbXKBDeVgTmF2rfXuKO2knhwrN7jgTgAE//8AAQASY2xvdWRmbGFyZS1lY2guY29tAAA=";
14215+
const char* b64BadCiph = "AEX+DQBBFAAgACBuAoQI8+liEVYQbXKBDeVgTmF2rfXuKO2knhwrN7jgTgAE/v4AAQASY2xvdWRmbGFyZS1lY2guY29tAAA=";
1421614216
/* ech configs with bad version first */
1421714217
const char* b64BadVers1 = "AIz+HQBCAQAgACCjR6+Qn9UYkMaWdXZzsby88vXFhPHJ2tWCDHQJLvMkEgAEAAEAAQATZWNoLXB1YmxpYy1uYW1lLmNvbQAA/g0AQgIAIAAgMM6vLrTbOfsfA6fTbJY/Iu0Lj2xeHEPGUJeUwQGAYF4ABAABAAEAE2VjaC1wdWJsaWMtbmFtZS5jb20AAA==";
1421814218
/* ech configs with bad version second */

wolfcrypt/src/hpke.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,12 +464,34 @@ static int wc_HpkeLabeledExtract(Hpke* hpke, byte* suite_id,
464464
{
465465
int ret;
466466
byte* labeled_ikm_p;
467+
word32 remaining;
467468
WC_DECLARE_VAR(labeled_ikm, byte, MAX_HPKE_LABEL_SZ, 0);
468469

469470
if (hpke == NULL) {
470471
return BAD_FUNC_ARG;
471472
}
472473

474+
/* check that sum of len's will not overflow */
475+
remaining = MAX_HPKE_LABEL_SZ;
476+
if ((word32)HPKE_VERSION_STR_LEN > remaining) {
477+
return BUFFER_E;
478+
}
479+
remaining -= (word32)HPKE_VERSION_STR_LEN;
480+
481+
if (suite_id_len > remaining) {
482+
return BUFFER_E;
483+
}
484+
remaining -= suite_id_len;
485+
486+
if (label_len > remaining) {
487+
return BUFFER_E;
488+
}
489+
remaining -= label_len;
490+
491+
if (ikm_len > remaining) {
492+
return BUFFER_E;
493+
}
494+
473495
WC_ALLOC_VAR_EX(labeled_ikm, byte, MAX_HPKE_LABEL_SZ, hpke->heap,
474496
DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
475497

@@ -511,12 +533,39 @@ static int wc_HpkeLabeledExpand(Hpke* hpke, byte* suite_id, word32 suite_id_len,
511533
{
512534
int ret;
513535
byte* labeled_info_p;
536+
word32 remaining;
514537
WC_DECLARE_VAR(labeled_info, byte, MAX_HPKE_LABEL_SZ, 0);
515538

516539
if (hpke == NULL) {
517540
return BAD_FUNC_ARG;
518541
}
519542

543+
/* check that sum of len's will not overflow */
544+
remaining = MAX_HPKE_LABEL_SZ;
545+
if (2u > remaining){
546+
return BUFFER_E;
547+
}
548+
remaining -= 2u;
549+
550+
if ((word32)HPKE_VERSION_STR_LEN > remaining) {
551+
return BUFFER_E;
552+
}
553+
remaining -= (word32)HPKE_VERSION_STR_LEN;
554+
555+
if (suite_id_len > remaining) {
556+
return BUFFER_E;
557+
}
558+
remaining -= suite_id_len;
559+
560+
if (label_len > remaining) {
561+
return BUFFER_E;
562+
}
563+
remaining -= label_len;
564+
565+
if (infoSz > remaining) {
566+
return BUFFER_E;
567+
}
568+
520569
WC_ALLOC_VAR_EX(labeled_info, byte, MAX_HPKE_LABEL_SZ, hpke->heap,
521570
DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
522571

0 commit comments

Comments
 (0)