Skip to content

Commit 6b6ad38

Browse files
committed
Adds support for TLS v1.3 Encrypted Client Hello (ECH) draft-ietf-tls-esni) and HPKE (Hybrid Public Key Encryption) RFC9180.
1 parent 7120ae1 commit 6b6ad38

15 files changed

Lines changed: 4109 additions & 47 deletions

File tree

configure.ac

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,7 @@ then
742742
test "$enable_trusted_ca" = "" && enable_trusted_ca=yes
743743
test "$enable_session_ticket" = "" && enable_session_ticket=yes
744744
test "$enable_earlydata" = "" && enable_earlydata=yes
745+
test "$enable_ech" = "" && enable_ech=yes
745746

746747
if test "$ENABLED_32BIT" != "yes"
747748
then
@@ -1120,6 +1121,25 @@ AC_ARG_ENABLE([cryptonly],
11201121

11211122
AS_IF([test "x$FIPS_VERSION" = "xrand"],[ENABLED_CRYPTONLY="yes"])
11221123

1124+
# ECH
1125+
AC_ARG_ENABLE([ech],
1126+
[AS_HELP_STRING([--enable-ech],[Enable ECH (default: disabled)])],
1127+
[ ENABLED_ECH=$enableval ],
1128+
[ ENABLED_ECH=no ]
1129+
)
1130+
if test "$ENABLED_ECH" = "yes"
1131+
then
1132+
AM_CFLAGS="$AM_CFLAGS -DHAVE_ECH"
1133+
1134+
test "$enable_hpke" = "" && enable_hpke=yes
1135+
test "$enable_ecc" = "" && enable_ecc=yes
1136+
test "$enable_curve25519" = "" && enable_curve25519=yes
1137+
test "$enable_sha256" = "" && enable_sha256=yes
1138+
test "$enable_tlsx" = "" && enable_tlsx=yes
1139+
test "$enable_sni" = "" && enable_sni=yes
1140+
test "$enable_tls13" = "" && enable_tls13=yes
1141+
fi
1142+
11231143
# DTLS
11241144
# DTLS is a prereq for the options mcast, sctp, and jni. Enabling any of those
11251145
# without DTLS will also enable DTLS.
@@ -2980,6 +3000,20 @@ then
29803000
AM_CFLAGS="$AM_CFLAGS -DHAVE_HKDF"
29813001
fi
29823002

3003+
3004+
# HPKE
3005+
AC_ARG_ENABLE([hpke],
3006+
[AS_HELP_STRING([--enable-hpke],[Enable HKPE support (default: disabled)])],
3007+
[ ENABLED_HPKE=$enableval ],
3008+
[ ENABLED_HPKE=no ]
3009+
)
3010+
if test "$ENABLED_HPKE" = "yes"
3011+
then
3012+
AM_CFLAGS="$AM_CFLAGS -DHAVE_HPKE"
3013+
3014+
test "$enable_hkdf" = "" && enable_hkdf=yes
3015+
fi
3016+
29833017
# X9.63 KDF
29843018
AC_ARG_ENABLE([x963kdf],
29853019
[AS_HELP_STRING([--enable-x963kdf],[Enable X9.63 KDF support (default: disabled)])],
@@ -8450,6 +8484,7 @@ AM_CONDITIONAL([BUILD_PSA],[test "x$ENABLED_PSA" = "xyes"])
84508484
AM_CONDITIONAL([BUILD_DTLS13],[test "x$ENABLED_DTLS13" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
84518485
AM_CONDITIONAL([BUILD_QUIC],[test "x$ENABLED_QUIC" = "xyes"])
84528486
AM_CONDITIONAL([BUILD_DTLS_CID],[test "x$ENABLED_DTLS_CID" = "xyes"])
8487+
AM_CONDITIONAL([BUILD_HPKE],[test "x$ENABLED_HPKE" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
84538488
AM_CONDITIONAL([BUILD_DTLS],[test "x$ENABLED_DTLS" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
84548489
AM_CONDITIONAL([BUILD_MAXQ10XX],[test "x$ENABLED_MAXQ10XX" = "xyes"])
84558490

@@ -8740,6 +8775,7 @@ echo " * PWDBASED: $ENABLED_PWDBASED"
87408775
echo " * scrypt: $ENABLED_SCRYPT"
87418776
echo " * wolfCrypt Only: $ENABLED_CRYPTONLY"
87428777
echo " * HKDF: $ENABLED_HKDF"
8778+
echo " * HPKE: $ENABLED_HPKE"
87438779
echo " * X9.63 KDF: $ENABLED_X963KDF"
87448780
echo " * MD4: $ENABLED_MD4"
87458781
echo " * PSK: $ENABLED_PSK"

examples/configs/user_settings_all.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,9 @@ extern "C" {
234234
#define HAVE_KEYING_MATERIAL
235235
#define WOLFSSL_HAVE_PRF
236236

237+
/* Encrypted Client Hello */
238+
#define HAVE_HPKE
239+
#define HAVE_ECH
237240

238241
/* Non-Standard Algorithms (DG disabled) */
239242
//#define HAVE_CAMELLIA

src/include.am

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,10 @@ if BUILD_ASN
509509
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/asn.c
510510
endif
511511

512+
if BUILD_HPKE
513+
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/hpke.c
514+
endif
515+
512516
endif !BUILD_FIPS_RAND
513517

514518
if BUILD_CODING

src/internal.c

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2398,6 +2398,36 @@ void wolfSSL_CRYPTO_cleanup_ex_data(WOLFSSL_CRYPTO_EX_DATA* ex_data)
23982398
}
23992399
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
24002400

2401+
#if defined(HAVE_ECH)
2402+
/* free all ech configs in the list */
2403+
static void FreeEchConfigs(WOLFSSL_EchConfig* configs, void* heap)
2404+
{
2405+
WOLFSSL_EchConfig* working_config = configs;
2406+
WOLFSSL_EchConfig* next_config;
2407+
2408+
while (working_config != NULL) {
2409+
next_config = working_config->next;
2410+
2411+
XFREE(working_config->cipherSuites, heap, DYNAMIC_TYPE_TMP_BUFFER);
2412+
XFREE(working_config->publicName, heap, DYNAMIC_TYPE_TMP_BUFFER);
2413+
2414+
if (working_config->raw != NULL)
2415+
XFREE(working_config->raw, heap, DYNAMIC_TYPE_TMP_BUFFER);
2416+
2417+
if (working_config->receiverPrivkey != NULL) {
2418+
wc_HpkeFreeKey(NULL, working_config->kemId,
2419+
working_config->receiverPrivkey, heap);
2420+
}
2421+
2422+
XFREE(working_config, heap, DYNAMIC_TYPE_TMP_BUFFER);
2423+
2424+
working_config = next_config;
2425+
}
2426+
2427+
(void)heap;
2428+
}
2429+
#endif
2430+
24012431
/* In case contexts are held in array and don't want to free actual ctx. */
24022432

24032433
/* The allocations done in InitSSL_Ctx must be free'd with ctx->onHeapHint
@@ -2554,6 +2584,10 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
25542584
ctx->staticKELockInit = 0;
25552585
}
25562586
#endif
2587+
#endif
2588+
#if defined(HAVE_ECH)
2589+
FreeEchConfigs(ctx->echConfigs, ctx->heap);
2590+
ctx->echConfigs = NULL;
25572591
#endif
25582592
(void)heapAtCTXInit;
25592593
}
@@ -6479,6 +6513,71 @@ void FreeHandshakeHashes(WOLFSSL* ssl)
64796513
}
64806514
}
64816515

6516+
/* copy the hashes from source to a newly made destination return status */
6517+
int InitHandshakeHashesAndCopy(WOLFSSL* ssl, HS_Hashes* source,
6518+
HS_Hashes** destination)
6519+
{
6520+
int ret = 0;
6521+
HS_Hashes* tmpHashes;
6522+
6523+
if (source == NULL)
6524+
return BAD_FUNC_ARG;
6525+
6526+
/* save the original so we can put it back afterward */
6527+
tmpHashes = ssl->hsHashes;
6528+
ssl->hsHashes = NULL;
6529+
6530+
InitHandshakeHashes(ssl);
6531+
6532+
*destination = ssl->hsHashes;
6533+
ssl->hsHashes = tmpHashes;
6534+
6535+
/* now copy the source contents to the destination */
6536+
#ifndef NO_OLD_TLS
6537+
#ifndef NO_SHA
6538+
ret = wc_ShaCopy(&source->hashSha, &(*destination)->hashSha);
6539+
#endif
6540+
#ifndef NO_MD5
6541+
if (ret == 0)
6542+
ret = wc_Md5Copy(&source->hashMd5, &(*destination)->hashMd5);
6543+
#endif
6544+
#endif /* !NO_OLD_TLS */
6545+
#ifndef NO_SHA256
6546+
if (ret == 0)
6547+
ret = wc_Sha256Copy(&source->hashSha256,
6548+
&(*destination)->hashSha256);
6549+
#endif
6550+
#ifdef WOLFSSL_SHA384
6551+
if (ret == 0)
6552+
ret = wc_Sha384Copy(&source->hashSha384,
6553+
&(*destination)->hashSha384);
6554+
#endif
6555+
#ifdef WOLFSSL_SHA512
6556+
if (ret == 0)
6557+
ret = wc_Sha512Copy(&source->hashSha512,
6558+
&(*destination)->hashSha512);
6559+
#endif
6560+
#if (defined(HAVE_ED25519) || defined(HAVE_ED448)) && \
6561+
!defined(WOLFSSL_NO_CLIENT_AUTH)
6562+
if (ret == 0 && source->messages != NULL) {
6563+
(*destination)->messages = (byte*)XMALLOC(source->length, ssl->heap,
6564+
DYNAMIC_TYPE_HASHES);
6565+
(*destination)->length = source->length;
6566+
(*destination)->prevLen = source->prevLen;
6567+
6568+
if ((*destination)->messages == NULL) {
6569+
ret = MEMORY_E;
6570+
}
6571+
else {
6572+
XMEMCPY((*destination)->messages, source->messages,
6573+
source->length);
6574+
}
6575+
}
6576+
#endif
6577+
6578+
return ret;
6579+
}
6580+
64826581
/* called if user attempts to re-use WOLFSSL object for a new session.
64836582
* For example wolfSSL_clear() is called then wolfSSL_connect or accept */
64846583
int ReinitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
@@ -7463,6 +7562,17 @@ void SSL_ResourceFree(WOLFSSL* ssl)
74637562
ForceZero(&ssl->clientSecret, sizeof(ssl->clientSecret));
74647563
ForceZero(&ssl->serverSecret, sizeof(ssl->serverSecret));
74657564
}
7565+
7566+
#if defined(HAVE_ECH)
7567+
if (ssl->options.useEch == 1) {
7568+
FreeEchConfigs(ssl->echConfigs, ssl->heap);
7569+
ssl->echConfigs = NULL;
7570+
/* free the ech specific hashes */
7571+
ssl->hsHashes = ssl->hsHashesEch;
7572+
FreeHandshakeHashes(ssl);
7573+
ssl->options.useEch = 0;
7574+
}
7575+
#endif
74667576
#endif
74677577
#ifdef WOLFSSL_HAVE_TLS_UNIQUE
74687578
ForceZero(&ssl->clientFinished, TLS_FINISHED_SZ_MAX);

0 commit comments

Comments
 (0)