forked from wolfSSL/wolfssl
refactor ECH code to handle hrr with special confirmation
This commit is contained in:
84
src/tls.c
84
src/tls.c
@@ -11451,8 +11451,9 @@ static int TLSX_ServerECH_Use(TLSX** extensions, void* heap,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return length after writing the ech */
|
/* return status after writing the ech and updating offset */
|
||||||
static int TLSX_ECH_Write(WOLFSSL_ECH* ech, byte* writeBuf, word16* offset)
|
static int TLSX_ECH_Write(WOLFSSL_ECH* ech, byte msgType, byte* writeBuf,
|
||||||
|
word16* offset)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int rngRet = -1;
|
int rngRet = -1;
|
||||||
@@ -11467,6 +11468,13 @@ static int TLSX_ECH_Write(WOLFSSL_ECH* ech, byte* writeBuf, word16* offset)
|
|||||||
WC_RNG rng[1];
|
WC_RNG rng[1];
|
||||||
#endif
|
#endif
|
||||||
WOLFSSL_MSG("TLSX_ECH_Write");
|
WOLFSSL_MSG("TLSX_ECH_Write");
|
||||||
|
if (msgType == hello_retry_request) {
|
||||||
|
/* reserve space to write the confirmation to */
|
||||||
|
*offset += ECH_ACCEPT_CONFIRMATION_SZ;
|
||||||
|
/* set confBuf */
|
||||||
|
ech->confBuf = writeBuf;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
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) {
|
||||||
@@ -11543,9 +11551,15 @@ static int TLSX_ECH_Write(WOLFSSL_ECH* ech, byte* writeBuf, word16* offset)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* write enc to writeBuf_p */
|
/* set to emptry string on hrr */
|
||||||
ret = wc_HpkeSerializePublicKey(ech->hpke, ech->ephemeralKey,
|
if (msgType == hello_retry_request) {
|
||||||
writeBuf_p, &ech->encLen);
|
XMEMSET(writeBuf_p, 0, ech->encLen);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* write enc to writeBuf_p */
|
||||||
|
ret = wc_HpkeSerializePublicKey(ech->hpke, ech->ephemeralKey,
|
||||||
|
writeBuf_p, &ech->encLen);
|
||||||
|
}
|
||||||
writeBuf_p += ech->encLen;
|
writeBuf_p += ech->encLen;
|
||||||
/* innerClientHelloLen */
|
/* innerClientHelloLen */
|
||||||
c16toa(ech->innerClientHelloLen, writeBuf_p);
|
c16toa(ech->innerClientHelloLen, writeBuf_p);
|
||||||
@@ -11722,89 +11736,85 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
|
|||||||
WOLFSSL_EchConfig* echConfig;
|
WOLFSSL_EchConfig* echConfig;
|
||||||
byte* aadCopy;
|
byte* aadCopy;
|
||||||
byte* readBuf_p = (byte*)readBuf;
|
byte* readBuf_p = (byte*)readBuf;
|
||||||
|
|
||||||
WOLFSSL_MSG("TLSX_ECH_Parse");
|
WOLFSSL_MSG("TLSX_ECH_Parse");
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
/* retry configs */
|
||||||
if (msgType == encrypted_extensions) {
|
if (msgType == encrypted_extensions) {
|
||||||
ret = wolfSSL_SetEchConfigs(ssl, readBuf, size);
|
ret = wolfSSL_SetEchConfigs(ssl, readBuf, size);
|
||||||
|
|
||||||
if (ret == WOLFSSL_SUCCESS)
|
if (ret == WOLFSSL_SUCCESS)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
else if (msgType == client_hello && ssl->ctx->echConfigs != NULL) {
|
/* HRR with special confirmation */
|
||||||
|
else if (msgType == hello_retry_request && ssl->options.useEch) {
|
||||||
|
/* length must be 8 */
|
||||||
|
if (size != ECH_ACCEPT_CONFIRMATION_SZ)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
/* get extension */
|
||||||
|
echX = TLSX_Find(ssl->extensions, TLSX_ECH);
|
||||||
|
if (echX == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
ech = (WOLFSSL_ECH*)echX->data;
|
||||||
|
ech->confBuf = (byte*)readBuf;
|
||||||
|
}
|
||||||
|
else if (msgType == client_hello && ssl->ctx->echConfigs != NULL) {
|
||||||
|
/* get extension */
|
||||||
echX = TLSX_Find(ssl->extensions, TLSX_ECH);
|
echX = TLSX_Find(ssl->extensions, TLSX_ECH);
|
||||||
|
|
||||||
if (echX == NULL)
|
if (echX == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
ech = (WOLFSSL_ECH*)echX->data;
|
ech = (WOLFSSL_ECH*)echX->data;
|
||||||
|
|
||||||
/* read the ech parameters before the payload */
|
/* read the ech parameters before the payload */
|
||||||
ech->type = *readBuf_p;
|
ech->type = *readBuf_p;
|
||||||
readBuf_p++;
|
readBuf_p++;
|
||||||
|
|
||||||
if (ech->type == ECH_TYPE_INNER) {
|
if (ech->type == ECH_TYPE_INNER) {
|
||||||
ech->state = ECH_PARSED_INTERNAL;
|
ech->state = ECH_PARSED_INTERNAL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* technically the payload would only be 1 byte at this length */
|
/* technically the payload would only be 1 byte at this length */
|
||||||
if (size < 11 + ech->encLen)
|
if (size < 11 + ech->encLen)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
/* read kdfId */
|
||||||
ato16(readBuf_p, &ech->cipherSuite.kdfId);
|
ato16(readBuf_p, &ech->cipherSuite.kdfId);
|
||||||
readBuf_p += 2;
|
readBuf_p += 2;
|
||||||
|
/* read aeadId */
|
||||||
ato16(readBuf_p, &ech->cipherSuite.aeadId);
|
ato16(readBuf_p, &ech->cipherSuite.aeadId);
|
||||||
readBuf_p += 2;
|
readBuf_p += 2;
|
||||||
|
/* read configId */
|
||||||
ech->configId = *readBuf_p;
|
ech->configId = *readBuf_p;
|
||||||
readBuf_p++;
|
readBuf_p++;
|
||||||
|
/* read encLen */
|
||||||
ato16(readBuf_p, &ech->encLen);
|
ato16(readBuf_p, &ech->encLen);
|
||||||
readBuf_p += 2;
|
readBuf_p += 2;
|
||||||
|
|
||||||
if (ech->encLen > HPKE_Npk_MAX)
|
if (ech->encLen > HPKE_Npk_MAX)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
/* read enc */
|
||||||
XMEMCPY(ech->enc, readBuf_p, ech->encLen);
|
XMEMCPY(ech->enc, readBuf_p, ech->encLen);
|
||||||
readBuf_p += ech->encLen;
|
readBuf_p += ech->encLen;
|
||||||
|
/* read hello inner len */
|
||||||
ato16(readBuf_p, &ech->innerClientHelloLen);
|
ato16(readBuf_p, &ech->innerClientHelloLen);
|
||||||
ech->innerClientHelloLen -= AES_BLOCK_SIZE;
|
ech->innerClientHelloLen -= AES_BLOCK_SIZE;
|
||||||
readBuf_p += 2;
|
readBuf_p += 2;
|
||||||
|
|
||||||
ech->outerClientPayload = readBuf_p;
|
ech->outerClientPayload = readBuf_p;
|
||||||
|
|
||||||
/* make a copy of the aad */
|
/* make a copy of the aad */
|
||||||
aadCopy = (byte*)XMALLOC(ech->aadLen, ssl->heap,
|
aadCopy = (byte*)XMALLOC(ech->aadLen, ssl->heap,
|
||||||
DYNAMIC_TYPE_TMP_BUFFER);
|
DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
|
||||||
if (aadCopy == NULL)
|
if (aadCopy == NULL)
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
|
|
||||||
XMEMCPY(aadCopy, ech->aad, ech->aadLen);
|
XMEMCPY(aadCopy, ech->aad, ech->aadLen);
|
||||||
|
|
||||||
/* set the ech payload of the copy to zeros */
|
/* set the ech payload of the copy to zeros */
|
||||||
XMEMSET(aadCopy + (readBuf_p - ech->aad), 0,
|
XMEMSET(aadCopy + (readBuf_p - ech->aad), 0,
|
||||||
ech->innerClientHelloLen + AES_BLOCK_SIZE);
|
ech->innerClientHelloLen + AES_BLOCK_SIZE);
|
||||||
|
|
||||||
/* allocate the inner payload buffer */
|
/* allocate the inner payload buffer */
|
||||||
ech->innerClientHello =
|
ech->innerClientHello =
|
||||||
(byte*)XMALLOC(ech->innerClientHelloLen + HANDSHAKE_HEADER_SZ,
|
(byte*)XMALLOC(ech->innerClientHelloLen + HANDSHAKE_HEADER_SZ,
|
||||||
ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
|
||||||
if (ech->innerClientHello == NULL) {
|
if (ech->innerClientHello == NULL) {
|
||||||
XFREE(aadCopy, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(aadCopy, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* first check if the config id matches */
|
/* first check if the config id matches */
|
||||||
echConfig = ssl->ctx->echConfigs;
|
echConfig = ssl->ctx->echConfigs;
|
||||||
|
|
||||||
while (echConfig != NULL) {
|
while (echConfig != NULL) {
|
||||||
/* decrypt with this config */
|
/* decrypt with this config */
|
||||||
if (echConfig->configId == ech->configId) {
|
if (echConfig->configId == ech->configId) {
|
||||||
@@ -11812,25 +11822,19 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
|
|||||||
ssl->heap);
|
ssl->heap);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
echConfig = echConfig->next;
|
echConfig = echConfig->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try to decrypt with all configs */
|
/* try to decrypt with all configs */
|
||||||
if (echConfig == NULL || ret != 0) {
|
if (echConfig == NULL || ret != 0) {
|
||||||
echConfig = ssl->ctx->echConfigs;
|
echConfig = ssl->ctx->echConfigs;
|
||||||
|
|
||||||
while (echConfig != NULL) {
|
while (echConfig != NULL) {
|
||||||
ret = TLSX_ExtractEch(ech, echConfig, aadCopy, ech->aadLen,
|
ret = TLSX_ExtractEch(ech, echConfig, aadCopy, ech->aadLen,
|
||||||
ssl->heap);
|
ssl->heap);
|
||||||
|
|
||||||
if (ret== 0)
|
if (ret== 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
echConfig = echConfig->next;
|
echConfig = echConfig->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we failed to extract, set state to retry configs */
|
/* 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);
|
||||||
@@ -11839,19 +11843,15 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
/* decrement until before the padding */
|
/* decrement until before the padding */
|
||||||
while (ech->innerClientHello[ech->innerClientHelloLen +
|
while (ech->innerClientHello[ech->innerClientHelloLen +
|
||||||
HANDSHAKE_HEADER_SZ - i - 1] != ECH_TYPE_INNER) {
|
HANDSHAKE_HEADER_SZ - i - 1] != ECH_TYPE_INNER) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* subtract the length of the padding from the length */
|
/* subtract the length of the padding from the length */
|
||||||
ech->innerClientHelloLen -= i;
|
ech->innerClientHelloLen -= i;
|
||||||
}
|
}
|
||||||
|
|
||||||
XFREE(aadCopy, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(aadCopy, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11868,6 +11868,8 @@ static void TLSX_ECH_Free(WOLFSSL_ECH* ech, void* heap)
|
|||||||
ech->hpke->heap);
|
ech->hpke->heap);
|
||||||
if (ech->hpke != NULL)
|
if (ech->hpke != NULL)
|
||||||
XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (ech->hpkeContext != NULL)
|
||||||
|
XFREE(ech->hpkeContext, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
|
||||||
XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
(void)heap;
|
(void)heap;
|
||||||
@@ -12536,7 +12538,7 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
|
|||||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
|
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
|
||||||
case TLSX_ECH:
|
case TLSX_ECH:
|
||||||
WOLFSSL_MSG("ECH extension to write");
|
WOLFSSL_MSG("ECH extension to write");
|
||||||
ret = ECH_WRITE((WOLFSSL_ECH*)extension->data,
|
ret = ECH_WRITE((WOLFSSL_ECH*)extension->data, msgType,
|
||||||
output + offset, &offset);
|
output + offset, &offset);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
135
src/tls13.c
135
src/tls13.c
@@ -170,11 +170,14 @@ static const byte dtls13ProtocolLabel[DTLS13_PROTOCOL_LABEL_SZ + 1] = "dtls13";
|
|||||||
#endif /* WOLFSSL_DTLS13 */
|
#endif /* WOLFSSL_DTLS13 */
|
||||||
|
|
||||||
#if defined(HAVE_ECH)
|
#if defined(HAVE_ECH)
|
||||||
#define ECH_ACCEPT_CONFIRMATION_SZ 8
|
|
||||||
#define ECH_ACCEPT_CONFIRMATION_LABEL_SZ 23
|
#define ECH_ACCEPT_CONFIRMATION_LABEL_SZ 23
|
||||||
|
#define ECH_HRR_ACCEPT_CONFIRMATION_LABEL_SZ 27
|
||||||
static const byte
|
static const byte
|
||||||
echAcceptConfirmationLabel[ECH_ACCEPT_CONFIRMATION_LABEL_SZ + 1] =
|
echAcceptConfirmationLabel[ECH_ACCEPT_CONFIRMATION_LABEL_SZ + 1] =
|
||||||
"ech accept confirmation";
|
"ech accept confirmation";
|
||||||
|
static const byte
|
||||||
|
echHrrAcceptConfirmationLabel[ECH_HRR_ACCEPT_CONFIRMATION_LABEL_SZ + 1] =
|
||||||
|
"hrr ech accept confirmation";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NO_CERTS
|
#ifndef NO_CERTS
|
||||||
@@ -4719,8 +4722,8 @@ static int Dtls13DoDowngrade(WOLFSSL* ssl)
|
|||||||
|
|
||||||
#if defined(HAVE_ECH)
|
#if defined(HAVE_ECH)
|
||||||
/* check if the server accepted ech or not */
|
/* check if the server accepted ech or not */
|
||||||
static int EchCheckAcceptance(WOLFSSL* ssl, const byte* input,
|
static int EchCheckAcceptance(WOLFSSL* ssl, byte* label, word16 labelSz,
|
||||||
int serverRandomOffset, int helloSz)
|
const byte* input, int acceptOffset, int helloSz)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int digestType;
|
int digestType;
|
||||||
@@ -4742,15 +4745,15 @@ static int EchCheckAcceptance(WOLFSSL* ssl, const byte* input,
|
|||||||
ssl->hsHashes = acceptHashes;
|
ssl->hsHashes = acceptHashes;
|
||||||
/* hash up to the last 8 bytes */
|
/* hash up to the last 8 bytes */
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = HashRaw(ssl, input, serverRandomOffset + RAN_LEN -
|
ret = HashRaw(ssl, input, acceptOffset);
|
||||||
ECH_ACCEPT_CONFIRMATION_SZ);
|
|
||||||
/* hash 8 zeros */
|
/* hash 8 zeros */
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = HashRaw(ssl, zeros, ECH_ACCEPT_CONFIRMATION_SZ);
|
ret = HashRaw(ssl, zeros, ECH_ACCEPT_CONFIRMATION_SZ);
|
||||||
/* hash the rest of the hello */
|
/* hash the rest of the hello */
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = HashRaw(ssl, input + serverRandomOffset + RAN_LEN,
|
ret = HashRaw(ssl, input + acceptOffset + ECH_ACCEPT_CONFIRMATION_SZ,
|
||||||
helloSz + HANDSHAKE_HEADER_SZ - (serverRandomOffset + RAN_LEN));
|
helloSz + HANDSHAKE_HEADER_SZ -
|
||||||
|
(acceptOffset + ECH_ACCEPT_CONFIRMATION_SZ));
|
||||||
}
|
}
|
||||||
/* get the modified transcript hash */
|
/* get the modified transcript hash */
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
@@ -4816,14 +4819,10 @@ static int EchCheckAcceptance(WOLFSSL* ssl, const byte* input,
|
|||||||
}
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* last 8 bytes should match our expand output */
|
/* last 8 bytes should match our expand output */
|
||||||
ret = XMEMCMP(acceptConfirmation,
|
ret = XMEMCMP(acceptConfirmation, input + acceptOffset,
|
||||||
ssl->arrays->serverRandom + RAN_LEN - ECH_ACCEPT_CONFIRMATION_SZ,
|
|
||||||
ECH_ACCEPT_CONFIRMATION_SZ);
|
ECH_ACCEPT_CONFIRMATION_SZ);
|
||||||
/* ech accepted */
|
/* ech accepted */
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* use the inner random for client random */
|
|
||||||
XMEMCPY(ssl->arrays->clientRandom, ssl->arrays->clientRandomInner,
|
|
||||||
RAN_LEN);
|
|
||||||
/* switch back to original hsHashes to free */
|
/* switch back to original hsHashes to free */
|
||||||
ssl->hsHashes = tmpHashes;
|
ssl->hsHashes = tmpHashes;
|
||||||
/* set the final hsHashes to the ech hashes */
|
/* set the final hsHashes to the ech hashes */
|
||||||
@@ -4850,10 +4849,10 @@ static int EchCheckAcceptance(WOLFSSL* ssl, const byte* input,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* replace the last 8 bytes of the server random with the ech acceptance
|
/* replace the last acceptance field for either sever hello or hrr with the ech
|
||||||
* parameter, return status */
|
* acceptance parameter, return status */
|
||||||
static int EchWriteAcceptance(WOLFSSL* ssl, byte* output,
|
static int EchWriteAcceptance(WOLFSSL* ssl, byte* label, word16 labelSz,
|
||||||
int serverRandomOffset, int helloSz)
|
byte* output, int acceptOffset, int helloSz)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int digestType;
|
int digestType;
|
||||||
@@ -4866,37 +4865,30 @@ static int EchWriteAcceptance(WOLFSSL* ssl, byte* output,
|
|||||||
XMEMSET(zeros, 0, sizeof(zeros));
|
XMEMSET(zeros, 0, sizeof(zeros));
|
||||||
XMEMSET(transcriptEchConf, 0, sizeof(transcriptEchConf));
|
XMEMSET(transcriptEchConf, 0, sizeof(transcriptEchConf));
|
||||||
XMEMSET(expandLabelPrk, 0, sizeof(expandLabelPrk));
|
XMEMSET(expandLabelPrk, 0, sizeof(expandLabelPrk));
|
||||||
|
|
||||||
/* copy ech hashes to accept */
|
/* copy ech hashes to accept */
|
||||||
ret = InitHandshakeHashesAndCopy(ssl, ssl->hsHashes, &acceptHashes);
|
ret = InitHandshakeHashesAndCopy(ssl, ssl->hsHashes, &acceptHashes);
|
||||||
|
if (ret == 0) {
|
||||||
/* swap hsHashes to acceptHashes */
|
/* swap hsHashes to acceptHashes */
|
||||||
tmpHashes = ssl->hsHashes;
|
tmpHashes = ssl->hsHashes;
|
||||||
ssl->hsHashes = acceptHashes;
|
ssl->hsHashes = acceptHashes;
|
||||||
|
/* hash up to the acceptOffset */
|
||||||
/* hash up to the last 8 bytes */
|
ret = HashRaw(ssl, output, acceptOffset);
|
||||||
if (ret == 0)
|
}
|
||||||
ret = HashRaw(ssl, output, serverRandomOffset + RAN_LEN -
|
|
||||||
ECH_ACCEPT_CONFIRMATION_SZ);
|
|
||||||
|
|
||||||
/* hash 8 zeros */
|
/* hash 8 zeros */
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = HashRaw(ssl, zeros, ECH_ACCEPT_CONFIRMATION_SZ);
|
ret = HashRaw(ssl, zeros, ECH_ACCEPT_CONFIRMATION_SZ);
|
||||||
|
|
||||||
/* hash the rest of the hello */
|
/* hash the rest of the hello */
|
||||||
if (ret == 0)
|
if (ret == 0) {
|
||||||
ret = HashRaw(ssl, output + serverRandomOffset + RAN_LEN,
|
ret = HashRaw(ssl, output + acceptOffset + ECH_ACCEPT_CONFIRMATION_SZ,
|
||||||
helloSz - (serverRandomOffset + RAN_LEN));
|
helloSz - (acceptOffset + ECH_ACCEPT_CONFIRMATION_SZ));
|
||||||
|
}
|
||||||
/* get the modified transcript hash */
|
/* get the modified transcript hash */
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = GetMsgHash(ssl, transcriptEchConf);
|
ret = GetMsgHash(ssl, transcriptEchConf);
|
||||||
|
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
/* pick the right type and size based on mac_algorithm */
|
/* pick the right type and size based on mac_algorithm */
|
||||||
if (ret == 0)
|
if (ret == 0) {
|
||||||
switch (ssl->specs.mac_algorithm) {
|
switch (ssl->specs.mac_algorithm) {
|
||||||
#ifndef NO_SHA256
|
#ifndef NO_SHA256
|
||||||
case sha256_mac:
|
case sha256_mac:
|
||||||
@@ -4926,7 +4918,7 @@ static int EchWriteAcceptance(WOLFSSL* ssl, byte* output,
|
|||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* extract clientRandom with a key of all zeros */
|
/* extract clientRandom with a key of all zeros */
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
PRIVATE_KEY_UNLOCK();
|
PRIVATE_KEY_UNLOCK();
|
||||||
@@ -4941,7 +4933,6 @@ static int EchWriteAcceptance(WOLFSSL* ssl, byte* output,
|
|||||||
#endif
|
#endif
|
||||||
PRIVATE_KEY_LOCK();
|
PRIVATE_KEY_LOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tls expand with the confirmation label */
|
/* tls expand with the confirmation label */
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
PRIVATE_KEY_UNLOCK();
|
PRIVATE_KEY_UNLOCK();
|
||||||
@@ -4954,16 +4945,9 @@ static int EchWriteAcceptance(WOLFSSL* ssl, byte* output,
|
|||||||
transcriptEchConf, digestSize, digestType, WOLFSSL_SERVER_END);
|
transcriptEchConf, digestSize, digestType, WOLFSSL_SERVER_END);
|
||||||
PRIVATE_KEY_LOCK();
|
PRIVATE_KEY_LOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0)
|
|
||||||
XMEMCPY(ssl->arrays->serverRandom, output + serverRandomOffset,
|
|
||||||
RAN_LEN);
|
|
||||||
|
|
||||||
/* free acceptHashes */
|
/* free acceptHashes */
|
||||||
FreeHandshakeHashes(ssl);
|
FreeHandshakeHashes(ssl);
|
||||||
|
|
||||||
ssl->hsHashes = tmpHashes;
|
ssl->hsHashes = tmpHashes;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -4989,7 +4973,9 @@ typedef struct Dsh13Args {
|
|||||||
byte sessIdSz;
|
byte sessIdSz;
|
||||||
byte extMsgType;
|
byte extMsgType;
|
||||||
#if defined(HAVE_ECH)
|
#if defined(HAVE_ECH)
|
||||||
int serverRandomOffset;
|
byte* acceptLabel;
|
||||||
|
word32 acceptOffset;
|
||||||
|
word16 acceptLabelSz;
|
||||||
#endif
|
#endif
|
||||||
} Dsh13Args;
|
} Dsh13Args;
|
||||||
|
|
||||||
@@ -5146,7 +5132,8 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
/* Server random - keep for debugging. */
|
/* Server random - keep for debugging. */
|
||||||
XMEMCPY(ssl->arrays->serverRandom, input + args->idx, RAN_LEN);
|
XMEMCPY(ssl->arrays->serverRandom, input + args->idx, RAN_LEN);
|
||||||
#if defined(HAVE_ECH)
|
#if defined(HAVE_ECH)
|
||||||
args->serverRandomOffset = args->idx;
|
/* last 8 bytes of server random */
|
||||||
|
args->acceptOffset = args->idx + RAN_LEN - ECH_ACCEPT_CONFIRMATION_SZ;
|
||||||
#endif
|
#endif
|
||||||
args->idx += RAN_LEN;
|
args->idx += RAN_LEN;
|
||||||
|
|
||||||
@@ -5432,11 +5419,30 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
#if defined(HAVE_ECH)
|
#if defined(HAVE_ECH)
|
||||||
|
TLSX* echX = NULL;
|
||||||
/* check for acceptConfirmation and HashInput with 8 0 bytes */
|
/* check for acceptConfirmation and HashInput with 8 0 bytes */
|
||||||
if (ssl->options.useEch == 1) {
|
if (ssl->options.useEch == 1) {
|
||||||
ret = EchCheckAcceptance(ssl, input, args->serverRandomOffset, helloSz);
|
echX = TLSX_Find(ssl->extensions, TLSX_ECH);
|
||||||
|
/* account for hrr */
|
||||||
|
if (args->extMsgType == hello_retry_request) {
|
||||||
|
args->acceptOffset = ((WOLFSSL_ECH*)echX->data)->confBuf - input;
|
||||||
|
args->acceptLabel = (byte*)echHrrAcceptConfirmationLabel;
|
||||||
|
args->acceptLabelSz = ECH_HRR_ACCEPT_CONFIRMATION_LABEL_SZ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
args->acceptLabel = (byte*)echAcceptConfirmationLabel;
|
||||||
|
args->acceptLabelSz = ECH_ACCEPT_CONFIRMATION_LABEL_SZ;
|
||||||
|
}
|
||||||
|
/* check acceptance */
|
||||||
|
ret = EchCheckAcceptance(ssl, args->acceptLabel, args->acceptLabelSz,
|
||||||
|
input, args->acceptOffset, helloSz);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
/* use the inner random for client random */
|
||||||
|
if (args->extMsgType != hello_retry_request) {
|
||||||
|
XMEMCPY(ssl->arrays->clientRandom, ssl->arrays->clientRandomInner,
|
||||||
|
RAN_LEN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -7236,7 +7242,9 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
|
|||||||
int sendSz;
|
int sendSz;
|
||||||
#if defined(HAVE_ECH)
|
#if defined(HAVE_ECH)
|
||||||
TLSX* echX = NULL;
|
TLSX* echX = NULL;
|
||||||
word32 serverRandomOffset;
|
byte* acceptLabel = (byte*)echAcceptConfirmationLabel;
|
||||||
|
word32 acceptOffset;
|
||||||
|
word16 acceptLabelSz = ECH_ACCEPT_CONFIRMATION_LABEL_SZ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND);
|
WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND);
|
||||||
@@ -7295,7 +7303,8 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_ECH)
|
#if defined(HAVE_ECH)
|
||||||
serverRandomOffset = idx;
|
/* last 8 bytes of server random */
|
||||||
|
acceptOffset = idx + RAN_LEN - ECH_ACCEPT_CONFIRMATION_SZ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Store in SSL for debugging. */
|
/* Store in SSL for debugging. */
|
||||||
@@ -7359,18 +7368,30 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
|
|||||||
#if defined(HAVE_ECH)
|
#if defined(HAVE_ECH)
|
||||||
if (ssl->ctx->echConfigs != NULL) {
|
if (ssl->ctx->echConfigs != NULL) {
|
||||||
echX = TLSX_Find(ssl->extensions, TLSX_ECH);
|
echX = TLSX_Find(ssl->extensions, TLSX_ECH);
|
||||||
|
|
||||||
if (echX == NULL)
|
if (echX == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
/* use normal offset instead of hrr offset */
|
||||||
|
if (extMsgType == hello_retry_request) {
|
||||||
|
acceptOffset = ((WOLFSSL_ECH*)echX->data)->confBuf - output;
|
||||||
|
acceptLabel = (byte*)echHrrAcceptConfirmationLabel;
|
||||||
|
acceptLabelSz = ECH_HRR_ACCEPT_CONFIRMATION_LABEL_SZ;
|
||||||
|
}
|
||||||
/* replace the last 8 bytes of server random with the accept */
|
/* replace the last 8 bytes of server random with the accept */
|
||||||
if (((WOLFSSL_ECH*)echX->data)->state == ECH_PARSED_INTERNAL) {
|
if (((WOLFSSL_ECH*)echX->data)->state == ECH_PARSED_INTERNAL) {
|
||||||
ret = EchWriteAcceptance(ssl, output + RECORD_HEADER_SZ,
|
ret = EchWriteAcceptance(ssl, acceptLabel, acceptLabelSz,
|
||||||
serverRandomOffset - RECORD_HEADER_SZ,
|
output + RECORD_HEADER_SZ,
|
||||||
|
acceptOffset - RECORD_HEADER_SZ,
|
||||||
sendSz - RECORD_HEADER_SZ);
|
sendSz - RECORD_HEADER_SZ);
|
||||||
|
if (extMsgType != hello_retry_request) {
|
||||||
/* remove ech so we don't keep sending it in write */
|
if (ret == 0) {
|
||||||
TLSX_Remove(&ssl->extensions, TLSX_ECH, ssl->heap);
|
/* update serverRandom on success */
|
||||||
|
XMEMCPY(ssl->arrays->serverRandom,
|
||||||
|
output + acceptOffset -
|
||||||
|
(RAN_LEN -ECH_ACCEPT_CONFIRMATION_SZ), RAN_LEN);
|
||||||
|
}
|
||||||
|
/* remove ech so we don't keep sending it in write */
|
||||||
|
TLSX_Remove(&ssl->extensions, TLSX_ECH, ssl->heap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -2886,6 +2886,7 @@ typedef struct RpkState {
|
|||||||
#endif /* HAVE_RPK */
|
#endif /* HAVE_RPK */
|
||||||
|
|
||||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
|
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
|
||||||
|
#define ECH_ACCEPT_CONFIRMATION_SZ 8
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ECH_TYPE_OUTER = 0,
|
ECH_TYPE_OUTER = 0,
|
||||||
@@ -2926,6 +2927,7 @@ typedef struct WOLFSSL_ECH {
|
|||||||
WOLFSSL_EchConfig* echConfig;
|
WOLFSSL_EchConfig* echConfig;
|
||||||
byte* innerClientHello;
|
byte* innerClientHello;
|
||||||
byte* outerClientPayload;
|
byte* outerClientPayload;
|
||||||
|
byte* confBuf;
|
||||||
EchCipherSuite cipherSuite;
|
EchCipherSuite cipherSuite;
|
||||||
word16 aadLen;
|
word16 aadLen;
|
||||||
word16 paddingLen;
|
word16 paddingLen;
|
||||||
|
Reference in New Issue
Block a user