From 642795db1b907bde3df2a453734721def90177b6 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 2 Jun 2017 14:05:47 +1000 Subject: [PATCH] Implement TLS v1.3 specified downgrade protection mechanism TLS v1.2 implementations whould implement the downgrade protection mechanism too and so is included. --- examples/client/client.c | 10 +++++--- src/internal.c | 52 +++++++++++++++++++++++++++++++++++++++- src/tls13.c | 2 -- 3 files changed, 58 insertions(+), 6 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index 8d5039236..a86b5681e 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1520,12 +1520,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifdef WOLFSSL_TLS13 if (!helloRetry) { if (onlyKeyShare == 0 || onlyKeyShare == 2) { + #ifdef HAVE_CURVE25519 if (useX25519) { if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519) != SSL_SUCCESS) { err_sys("unable to use curve secp256r1"); } } + #endif if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_SECP256R1) != SSL_SUCCESS) { err_sys("unable to use curve secp256r1"); @@ -1950,12 +1952,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) (void*)"resumed session"); #endif - #ifdef WOLFSSL_TLS13 +#ifdef WOLFSSL_TLS13 + #ifdef HAVE_CURVE25519 if (useX25519) { if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519) != SSL_SUCCESS) { err_sys("unable to use curve secp256r1"); } } + #endif if (wolfSSL_UseKeyShare(sslResume, WOLFSSL_ECC_SECP256R1) != SSL_SUCCESS) { err_sys("unable to use curve secp256r1"); @@ -1964,12 +1968,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) WOLFSSL_ECC_SECP384R1) != SSL_SUCCESS) { err_sys("unable to use curve secp384r1"); } - #ifdef HAVE_FFDHE_2048 + #ifdef HAVE_FFDHE_2048 if (wolfSSL_UseKeyShare(sslResume, WOLFSSL_FFDHE_2048) != SSL_SUCCESS) { err_sys("unable to use DH 2048-bit parameters"); } - #endif #endif +#endif #ifndef WOLFSSL_CALLBACKS if (nonBlocking) { diff --git a/src/internal.c b/src/internal.c index a634f9210..6689dc207 100755 --- a/src/internal.c +++ b/src/internal.c @@ -143,6 +143,12 @@ enum cipherState { CIPHER_STATE_END, }; +/* Server random bytes for TLS v1.3 described downgrade protection mechanism. */ +static const byte tls13Downgrade[7] = { + 0x44, 0x4f, 0x47, 0x4e, 0x47, 0x52, 0x44 +}; +#define TLS13_DOWNGRADE_SZ sizeof(tls13Downgrade) + #ifndef NO_OLD_TLS static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, @@ -15741,6 +15747,33 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN); i += RAN_LEN; +#ifdef WOLFSSL_TLS13 + if (IsAtLeastTLSv1_3(ssl->ctx->method->version)) { + /* TLS v1.3 capable client not allowed to downgrade when connecting + * to TLS v1.3 capable server. + */ + if (XMEMCMP(input + i - (TLS13_DOWNGRADE_SZ + 1), + tls13Downgrade, TLS13_DOWNGRADE_SZ) == 0 && + (*(input + i - 1) == 0 || *(input + i - 1) == 1)) { + SendAlert(ssl, alert_fatal, illegal_parameter); + return VERSION_ERROR; + } + } + else +#endif + if (ssl->ctx->method->version.major == SSLv3_MAJOR && + ssl->ctx->method->version.minor == TLSv1_2_MINOR) { + /* TLS v1.2 capable client not allowed to downgrade when connecting + * to TLS v1.2 capable server. + */ + if (XMEMCMP(input + i - (TLS13_DOWNGRADE_SZ + 1), + tls13Downgrade, TLS13_DOWNGRADE_SZ) == 0 && + *(input + i - 1) == 0) { + SendAlert(ssl, alert_fatal, illegal_parameter); + return VERSION_ERROR; + } + } + /* session id */ ssl->arrays->sessionIDSz = input[i++]; @@ -19049,7 +19082,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif /* NO_WOLFSSL_CLIENT */ - #ifndef NO_WOLFSSL_SERVER int SendServerHello(WOLFSSL* ssl) @@ -19138,6 +19170,24 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (ret != 0) return ret; +#ifdef WOLFSSL_TLS13 + if (IsAtLeastTLSv1_3(ssl->ctx->method->version)) { + /* TLS v1.3 capable server downgraded. */ + XMEMCPY(output + idx + RAN_LEN - (TLS13_DOWNGRADE_SZ + 1), + tls13Downgrade, TLS13_DOWNGRADE_SZ); + output[idx + RAN_LEN - 1] = IsAtLeastTLSv1_2(ssl); + } + else +#endif + if (ssl->ctx->method->version.major == SSLv3_MAJOR && + ssl->ctx->method->version.minor == TLSv1_2_MINOR && + !IsAtLeastTLSv1_2(ssl)) { + /* TLS v1.2 capable server downgraded. */ + XMEMCPY(output + idx + RAN_LEN - (TLS13_DOWNGRADE_SZ + 1), + tls13Downgrade, TLS13_DOWNGRADE_SZ); + output[idx + RAN_LEN - 1] = 0; + } + /* store info in SSL for later */ XMEMCPY(ssl->arrays->serverRandom, output + idx, RAN_LEN); idx += RAN_LEN; diff --git a/src/tls13.c b/src/tls13.c index cb1879019..14458457c 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -2027,7 +2027,6 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* Server random - keep for debugging. */ XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN); i += RAN_LEN; - /* TODO: [TLS13] Check last 8 bytes. */ /* Set the cipher suite from the message. */ ssl->options.cipherSuite0 = input[i++]; @@ -2671,7 +2670,6 @@ int SendTls13ServerHello(WOLFSSL* ssl) output[idx++] = TLS_DRAFT_MAJOR; output[idx++] = TLS_DRAFT_MINOR; - /* TODO: [TLS13] Last 8 bytes have special meaning. */ /* Generate server random. */ ret = wc_RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN); if (ret != 0)