diff --git a/configure.ac b/configure.ac index e066dacfb..5d02a55ba 100644 --- a/configure.ac +++ b/configure.ac @@ -193,7 +193,7 @@ then AM_CFLAGS="$AM_CFLAGS -DHAVE_AES_DECRYPT -DHAVE_AES_ECB -DWOLFSSL_ALT_NAMES -DWOLFSSL_DER_LOAD -DKEEP_OUR_CERT -DKEEP_PEER_CERT -DHAVE_CRL_IO -DHAVE_IO_TIMEOUT" # Enable DH const table speedups (eliminates `-lm` math lib dependency) - AM_CFLAGS="$AM_CFLAGS -DHAVE_FFDHE_2048 -DHAVE_FFDHE_3072 -DHAVE_FFDHE_4096 -DHAVE_FFDHE_6144 -DHAVE_FFDHE_8192" + AM_CFLAGS="$AM_CFLAGS -DHAVE_FFDHE_2048 -DHAVE_FFDHE_3072 -DFP_MAX_BITS=6144" fi AM_CONDITIONAL([BUILD_ALL], [test "x$ENABLED_ALL" = "xyes"]) @@ -1908,11 +1908,6 @@ else fi fi -if test "$ENABLED_TLS13" = "yes" && test "$ENABLED_DH" = "yes" -then - AM_CFLAGS="-DHAVE_FFDHE_2048 $AM_CFLAGS" -fi - AM_CONDITIONAL([BUILD_DH], [test "x$ENABLED_DH" = "xyes"]) @@ -2921,6 +2916,35 @@ then [AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SUPPORTED_CURVES"]) fi +# Diffie-Hellman +if test "$ENABLED_DH" = "yes" +then + if test "$ENABLED_TLS13" = "yes" || test "$ENABLED_SUPPORTED_CURVES" = "yes" + then + AM_CFLAGS="-DHAVE_FFDHE_2048 $AM_CFLAGS" + fi +fi + +# FFDHE parameters only +AC_ARG_ENABLE([ffdhe-only], + [AS_HELP_STRING([--enable-ffdhe-only],[Enable using only FFDHE in client (default: disabled)])], + [ ENABLED_FFDHE_ONLY=$enableval ], + [ ENABLED_FFDHE_ONLY=no ] + ) + +if test "x$ENABLED_FFDHE_ONLY" = "xyes" +then + if test "$ENABLED_DH" = "no" + then + AC_MSG_ERROR([FFDHE only support requires DH support]) + fi + if test "$ENABLED_SUPPORTED_CURVES" = "no" + then + AC_MSG_ERROR([FFDHE only support requires Supported Curves extension]) + fi + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_REQUIRE_FFDHE" +fi + # Session Ticket Extension AC_ARG_ENABLE([session-ticket], [AS_HELP_STRING([--enable-session-ticket],[Enable Session Ticket (default: disabled)])], @@ -4904,6 +4928,7 @@ echo " * ALPN: $ENABLED_ALPN" echo " * Maximum Fragment Length: $ENABLED_MAX_FRAGMENT" echo " * Truncated HMAC: $ENABLED_TRUNCATED_HMAC" echo " * Supported Elliptic Curves: $ENABLED_SUPPORTED_CURVES" +echo " * FFDHE only in client: $ENABLED_FFDHE_ONLY" echo " * Session Ticket: $ENABLED_SESSION_TICKET" echo " * Extended Master Secret: $ENABLED_EXTENDED_MASTER" echo " * Renegotiation Indication: $ENABLED_RENEGOTIATION_INDICATION" diff --git a/examples/client/client.c b/examples/client/client.c index 339f1722c..9279a4927 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1361,9 +1361,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) int doSTARTTLS = 0; char* starttlsProt = NULL; int useVerifyCb = 0; -#ifdef HAVE_ECC int useSupCurve = 0; -#endif #ifdef WOLFSSL_TRUST_PEER_CERT const char* trustCert = NULL; @@ -1466,9 +1464,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) (void)useX25519; (void)helloRetry; (void)onlyKeyShare; -#ifdef HAVE_ECC (void)useSupCurve; -#endif (void)loadCertKeyIntoSSLObj; StackTrap(); @@ -1617,12 +1613,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) printf("Verify should fail\n"); myVerifyFail = 1; } - #ifdef HAVE_ECC else if (XSTRNCMP(myoptarg, "useSupCurve", 11) == 0) { printf("Test use supported curve\n"); useSupCurve = 1; } - #endif else if (XSTRNCMP(myoptarg, "loadSSL", 7) == 0) { printf("Load cert/key into wolfSSL object\n"); #ifndef NO_CERTS @@ -2395,6 +2389,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif } #endif /* HAVE_ECC */ + #ifdef HAVE_FFDHE_2048 + if (useSupCurve) { + if (wolfSSL_CTX_UseSupportedCurve(ctx, WOLFSSL_FFDHE_2048) + != WOLFSSL_SUCCESS) { + err_sys("unable to support FFDHE 2048"); + } + } + #endif #endif /* HAVE_SUPPORTED_CURVES */ #ifdef WOLFSSL_TLS13 diff --git a/src/internal.c b/src/internal.c index 16b35131b..1dc6d3fa9 100644 --- a/src/internal.c +++ b/src/internal.c @@ -15886,6 +15886,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e) case DTLS_RETX_OVER_TX: return "DTLS interrupting flight transmit with retransmit"; + case DH_PARAMS_NOT_FFDHE_E: + return "Server DH parameters were not from the FFDHE set as required"; + default : return "unknown error number"; } @@ -18041,7 +18044,6 @@ exit_dpk: #endif /* HAVE_ECC */ - /* Persistable DoServerKeyExchange arguments */ typedef struct DskeArgs { byte* output; /* not allocated */ @@ -18073,6 +18075,168 @@ static void FreeDskeArgs(WOLFSSL* ssl, void* pArgs) #endif } +#ifndef NO_DH +static int GetDhPublicKey(WOLFSSL* ssl, const byte* input, word32 size, + DskeArgs* args) +{ + int ret = 0; + word16 length; +#ifdef HAVE_FFDHE + const DhParams* params = NULL; + int group; +#endif + + /* p */ + if ((args->idx - args->begin) + OPAQUE16_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_gdpk); + } + + ato16(input + args->idx, &length); + args->idx += OPAQUE16_LEN; + + if ((args->idx - args->begin) + length > size) { + ERROR_OUT(BUFFER_ERROR, exit_gdpk); + } + + if (length < ssl->options.minDhKeySz) { + WOLFSSL_MSG("Server using a DH key that is too small"); + SendAlert(ssl, alert_fatal, handshake_failure); + ERROR_OUT(DH_KEY_SIZE_E, exit_gdpk); + } + if (length > ssl->options.maxDhKeySz) { + WOLFSSL_MSG("Server using a DH key that is too big"); + SendAlert(ssl, alert_fatal, handshake_failure); + ERROR_OUT(DH_KEY_SIZE_E, exit_gdpk); + } + + ssl->buffers.serverDH_P.buffer = + (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + if (ssl->buffers.serverDH_P.buffer) { + ssl->buffers.serverDH_P.length = length; + } + else { + ERROR_OUT(MEMORY_ERROR, exit_gdpk); + } + + XMEMCPY(ssl->buffers.serverDH_P.buffer, input + args->idx, + length); + args->idx += length; + + ssl->options.dhKeySz = length; + + /* g */ + if ((args->idx - args->begin) + OPAQUE16_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_gdpk); + } + + ato16(input + args->idx, &length); + args->idx += OPAQUE16_LEN; + + if ((args->idx - args->begin) + length > size) { + ERROR_OUT(BUFFER_ERROR, exit_gdpk); + } + + ssl->buffers.serverDH_G.buffer = + (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + if (ssl->buffers.serverDH_G.buffer) { + ssl->buffers.serverDH_G.length = length; + } + else { + ERROR_OUT(MEMORY_ERROR, exit_gdpk); + } + + XMEMCPY(ssl->buffers.serverDH_G.buffer, input + args->idx, + length); + args->idx += length; + + ssl->buffers.weOwnDH = 1; + + /* pub */ + if ((args->idx - args->begin) + OPAQUE16_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_gdpk); + } + + ato16(input + args->idx, &length); + args->idx += OPAQUE16_LEN; + + if ((args->idx - args->begin) + length > size) { + ERROR_OUT(BUFFER_ERROR, exit_gdpk); + } + + ssl->buffers.serverDH_Pub.buffer = + (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + if (ssl->buffers.serverDH_Pub.buffer) { + ssl->buffers.serverDH_Pub.length = length; + } + else { + ERROR_OUT(MEMORY_ERROR, exit_gdpk); + } + + XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + args->idx, + length); + args->idx += length; + +#ifdef HAVE_FFDHE + switch (ssl->options.dhKeySz) { + #ifdef HAVE_FFDHE_2048 + case 2048/8: + params = wc_Dh_ffdhe2048_Get(); + group = WOLFSSL_FFDHE_2048; + break; + #endif + #ifdef HAVE_FFDHE_3072 + case 3072/8: + params = wc_Dh_ffdhe3072_Get(); + group = WOLFSSL_FFDHE_3072; + break; + #endif + #ifdef HAVE_FFDHE_4096 + case 4096/8: + params = wc_Dh_ffdhe4096_Get(); + group = WOLFSSL_FFDHE_4096; + break; + #endif + #ifdef HAVE_FFDHE_6144 + case 6144/8: + params = wc_Dh_ffdhe6144_Get(); + group = WOLFSSL_FFDHE_6144; + break; + #endif + #ifdef HAVE_FFDHE_8192 + case 8192/8: + params = wc_Dh_ffdhe8192_Get(); + group = WOLFSSL_FFDHE_8192; + break; + #endif + default: + break; + } + + if (params == NULL || params->g_len != ssl->buffers.serverDH_G.length || + (XMEMCMP(ssl->buffers.serverDH_G.buffer, params->g, + params->g_len) != 0) || + (XMEMCMP(ssl->buffers.serverDH_P.buffer, params->p, + params->p_len) != 0)) { + WOLFSSL_MSG("Server not using FFDHE parameters"); + #ifdef WOLFSSL_REQUIRE_FFDHE + SendAlert(ssl, alert_fatal, handshake_failure); + ERROR_OUT(DH_PARAMS_NOT_FFDHE_E, exit_gdpk); + #endif + } + else { + ssl->namedGroup = group; + #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \ + !defined(HAVE_SELFTEST) + ssl->options.dhDoKeyTest = 0; + #endif + } +#endif /* HAVE_FFDHE */ + +exit_gdpk: + return ret; +} +#endif + /* handle processing of server_key_exchange (12) */ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size) @@ -18157,97 +18321,9 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, #ifndef NO_DH case diffie_hellman_kea: { - word16 length; - - /* p */ - if ((args->idx - args->begin) + OPAQUE16_LEN > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - ato16(input + args->idx, &length); - args->idx += OPAQUE16_LEN; - - if ((args->idx - args->begin) + length > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - if (length < ssl->options.minDhKeySz) { - WOLFSSL_MSG("Server using a DH key that is too small"); - SendAlert(ssl, alert_fatal, handshake_failure); - ERROR_OUT(DH_KEY_SIZE_E, exit_dske); - } - if (length > ssl->options.maxDhKeySz) { - WOLFSSL_MSG("Server using a DH key that is too big"); - SendAlert(ssl, alert_fatal, handshake_failure); - ERROR_OUT(DH_KEY_SIZE_E, exit_dske); - } - - ssl->buffers.serverDH_P.buffer = - (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); - if (ssl->buffers.serverDH_P.buffer) { - ssl->buffers.serverDH_P.length = length; - } - else { - ERROR_OUT(MEMORY_ERROR, exit_dske); - } - - XMEMCPY(ssl->buffers.serverDH_P.buffer, input + args->idx, - length); - args->idx += length; - - ssl->options.dhKeySz = length; - - /* g */ - if ((args->idx - args->begin) + OPAQUE16_LEN > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - ato16(input + args->idx, &length); - args->idx += OPAQUE16_LEN; - - if ((args->idx - args->begin) + length > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - ssl->buffers.serverDH_G.buffer = - (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); - if (ssl->buffers.serverDH_G.buffer) { - ssl->buffers.serverDH_G.length = length; - } - else { - ERROR_OUT(MEMORY_ERROR, exit_dske); - } - - XMEMCPY(ssl->buffers.serverDH_G.buffer, input + args->idx, - length); - args->idx += length; - - ssl->buffers.weOwnDH = 1; - - /* pub */ - if ((args->idx - args->begin) + OPAQUE16_LEN > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - ato16(input + args->idx, &length); - args->idx += OPAQUE16_LEN; - - if ((args->idx - args->begin) + length > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - ssl->buffers.serverDH_Pub.buffer = - (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); - if (ssl->buffers.serverDH_Pub.buffer) { - ssl->buffers.serverDH_Pub.length = length; - } - else { - ERROR_OUT(MEMORY_ERROR, exit_dske); - } - - XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + args->idx, - length); - args->idx += length; + ret = GetDhPublicKey(ssl, input, size, args); + if (ret != 0) + goto exit_dske; break; } #endif /* !NO_DH */ @@ -18362,98 +18438,12 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, ssl->arrays->server_hint[srvHintLen] = '\0'; /* null term */ args->idx += length; - /* p */ - if ((args->idx - args->begin) + OPAQUE16_LEN > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - ato16(input + args->idx, &length); - args->idx += OPAQUE16_LEN; - - if ((args->idx - args->begin) + length > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - if (length < ssl->options.minDhKeySz) { - WOLFSSL_MSG("Server using a DH key that is too small"); - SendAlert(ssl, alert_fatal, handshake_failure); - ERROR_OUT(DH_KEY_SIZE_E, exit_dske); - } - if (length > ssl->options.maxDhKeySz) { - WOLFSSL_MSG("Server using a DH key that is too big"); - SendAlert(ssl, alert_fatal, handshake_failure); - ERROR_OUT(DH_KEY_SIZE_E, exit_dske); - } - - ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(length, - ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); - if (ssl->buffers.serverDH_P.buffer) { - ssl->buffers.serverDH_P.length = length; - } - else { - ERROR_OUT(MEMORY_ERROR, exit_dske); - } - - XMEMCPY(ssl->buffers.serverDH_P.buffer, input + args->idx, - length); - args->idx += length; - - ssl->options.dhKeySz = length; - - /* g */ - if ((args->idx - args->begin) + OPAQUE16_LEN > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - ato16(input + args->idx, &length); - args->idx += OPAQUE16_LEN; - - if ((args->idx - args->begin) + length > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(length, - ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); - if (ssl->buffers.serverDH_G.buffer) { - ssl->buffers.serverDH_G.length = length; - } - else { - ERROR_OUT(MEMORY_ERROR, exit_dske); - } - - XMEMCPY(ssl->buffers.serverDH_G.buffer, input + args->idx, - length); - args->idx += length; - - ssl->buffers.weOwnDH = 1; - - /* pub */ - if ((args->idx - args->begin) + OPAQUE16_LEN > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - ato16(input + args->idx, &length); - args->idx += OPAQUE16_LEN; - - if ((args->idx - args->begin) + length > size) { - ERROR_OUT(BUFFER_ERROR, exit_dske); - } - - ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(length, - ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); - if (ssl->buffers.serverDH_Pub.buffer) { - ssl->buffers.serverDH_Pub.length = length; - } - else { - ERROR_OUT(MEMORY_ERROR, exit_dske); - } - - XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + args->idx, - length); - args->idx += length; + ret = GetDhPublicKey(ssl, input, size, args); + if (ret != 0) + goto exit_dske; break; } - #endif /* !NO_DH || !NO_PSK */ + #endif /* !NO_DH && !NO_PSK */ #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ !defined(NO_PSK) case ecdhe_psk_kea: @@ -23934,6 +23924,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } ret = MatchSuite(ssl, &clSuites); +#if defined(HAVE_FFDHE) && defined(HAVE_SUPPORTED_CURVES) + if (ret == 0 && (ssl->specs.kea == diffie_hellman_kea || + ssl->specs.kea == dhe_psk_kea)) { + ret = TLSX_SupportedFFDHE_Set(ssl); + } +#endif + #ifdef HAVE_SECURE_RENEGOTIATION if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled && IsEncryptionOn(ssl, 0)) { diff --git a/src/ssl.c b/src/ssl.c index fc3442a61..1ad8f1b38 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2099,18 +2099,13 @@ int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name) case WOLFSSL_ECC_BRAINPOOLP384R1: case WOLFSSL_ECC_BRAINPOOLP512R1: case WOLFSSL_ECC_X25519: - break; -#ifdef WOLFSSL_TLS13 case WOLFSSL_FFDHE_2048: case WOLFSSL_FFDHE_3072: case WOLFSSL_FFDHE_4096: case WOLFSSL_FFDHE_6144: case WOLFSSL_FFDHE_8192: - if (!IsAtLeastTLSv1_3(ssl->version)) - return WOLFSSL_SUCCESS; break; -#endif default: return BAD_FUNC_ARG; @@ -2143,16 +2138,12 @@ int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name) case WOLFSSL_ECC_BRAINPOOLP384R1: case WOLFSSL_ECC_BRAINPOOLP512R1: case WOLFSSL_ECC_X25519: - break; - -#ifdef WOLFSSL_TLS13 case WOLFSSL_FFDHE_2048: case WOLFSSL_FFDHE_3072: case WOLFSSL_FFDHE_4096: case WOLFSSL_FFDHE_6144: case WOLFSSL_FFDHE_8192: break; -#endif default: return BAD_FUNC_ARG; @@ -16237,7 +16228,31 @@ const char* wolfSSL_get_cipher_name_from_suite(const byte cipherSuite0, } -#ifdef HAVE_ECC +#if defined(HAVE_ECC) || !defined(NO_DH) +#ifdef HAVE_FFDHE +static const char* wolfssl_ffdhe_name(word16 group) +{ + const char* str = NULL; + switch (group) { + case WOLFSSL_FFDHE_2048: + str = "FFDHE_2048"; + break; + case WOLFSSL_FFDHE_3072: + str = "FFDHE_3072"; + break; + case WOLFSSL_FFDHE_4096: + str = "FFDHE_4096"; + break; + case WOLFSSL_FFDHE_6144: + str = "FFDHE_6144"; + break; + case WOLFSSL_FFDHE_8192: + str = "FFDHE_8192"; + break; + } + return str; +} +#endif /* Return the name of the curve used for key exchange as a printable string. * * ssl The SSL/TLS object. @@ -16247,14 +16262,19 @@ const char* wolfSSL_get_curve_name(WOLFSSL* ssl) { if (ssl == NULL) return NULL; - if (!IsAtLeastTLSv1_3(ssl->version) && ssl->specs.kea != ecdhe_psk_kea && - ssl->specs.kea != ecc_diffie_hellman_kea) - return NULL; +#ifdef HAVE_FFDHE + if (ssl->namedGroup != 0) + return wolfssl_ffdhe_name(ssl->namedGroup); +#endif +#ifdef HAVE_ECC if (ssl->ecdhCurveOID == 0) return NULL; if (ssl->ecdhCurveOID == ECC_X25519_OID) return "X25519"; return wc_ecc_get_name(wc_ecc_get_oid(ssl->ecdhCurveOID, NULL, NULL)); +#else + return NULL; +#endif } #endif diff --git a/src/tls.c b/src/tls.c index 1431087a6..be3c5da97 100644 --- a/src/tls.c +++ b/src/tls.c @@ -3271,9 +3271,10 @@ int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type, #ifdef HAVE_SUPPORTED_CURVES -#if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && !defined(WOLFSSL_TLS13) +#if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && !defined(HAVE_FFDHE) #error Elliptic Curves Extension requires Elliptic Curve Cryptography. \ - Use --enable-ecc in the configure script or define HAVE_ECC. + Use --enable-ecc in the configure script or define HAVE_ECC. \ + Alternatively use FFDHE for DH ciperhsuites. #endif static int TLSX_SupportedCurve_New(SupportedCurve** curve, word16 name, @@ -3384,11 +3385,21 @@ static void TLSX_SupportedCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore) { int i; - for (i = 0; i < ssl->suites->suiteSz; i+= 2) - if (ssl->suites->suites[i] == ECC_BYTE || - ssl->suites->suites[i] == CHACHA_BYTE || - ssl->suites->suites[i] == TLS13_BYTE) + for (i = 0; i < ssl->suites->suiteSz; i+= 2) { + if (ssl->suites->suites[i] == TLS13_BYTE) return; + if (ssl->suites->suites[i] == ECC_BYTE || + ssl->suites->suites[i] == CHACHA_BYTE) { + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + return; + #endif + } + else { + #ifdef HAVE_FFDHE + return; + #endif + } + } /* turns semaphore on to avoid sending this extension. */ TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_GROUPS)); @@ -3398,11 +3409,21 @@ static void TLSX_PointFormat_ValidateRequest(WOLFSSL* ssl, byte* semaphore) { int i; - for (i = 0; i < ssl->suites->suiteSz; i+= 2) - if (ssl->suites->suites[i] == ECC_BYTE || - ssl->suites->suites[i] == CHACHA_BYTE || - ssl->suites->suites[i] == TLS13_BYTE) + for (i = 0; i < ssl->suites->suiteSz; i+= 2) { + if (ssl->suites->suites[i] == TLS13_BYTE) return; + if (ssl->suites->suites[i] == ECC_BYTE || + ssl->suites->suites[i] == CHACHA_BYTE) { + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + return; + #endif + } + else { + #ifdef HAVE_FFDHE + return; + #endif + } + } /* turns semaphore on to avoid sending this extension. */ TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS)); @@ -3414,10 +3435,19 @@ static void TLSX_PointFormat_ValidateRequest(WOLFSSL* ssl, byte* semaphore) static void TLSX_PointFormat_ValidateResponse(WOLFSSL* ssl, byte* semaphore) { - if (ssl->options.cipherSuite0 == ECC_BYTE || - ssl->options.cipherSuite0 == CHACHA_BYTE || - ssl->options.cipherSuite0 == TLS13_BYTE) + if (ssl->options.cipherSuite0 == TLS13_BYTE) return; + if (ssl->options.cipherSuite0 == ECC_BYTE || + ssl->options.cipherSuite0 == CHACHA_BYTE) { +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + return; +#endif + } + else { +#ifdef HAVE_FFDHE + return; +#endif + } /* turns semaphore on to avoid sending this extension. */ TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS)); @@ -3554,8 +3584,9 @@ static int TLSX_SupportedCurve_Parse(WOLFSSL* ssl, byte* input, word16 length, #endif -#if !defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \ - !defined(WOLFSSL_NO_SERVER_GROUPS_EXT) +#if !defined(NO_WOLFSSL_SERVER) + +#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_SERVER_GROUPS_EXT) /* Checks the priority of the groups on the server and set the supported groups * response if there is a group not advertised by the client that is preferred. @@ -3608,6 +3639,118 @@ int TLSX_SupportedCurve_CheckPriority(WOLFSSL* ssl) #endif +#if defined(HAVE_FFDHE) && !defined(WOLFSSL_NO_TLS12) +/* Set the highest priority common FFDHE group on the server as compared to + * client extensions. + * + * ssl SSL/TLS object. + * returns 0 on success, otherwise an error. + */ +int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl) +{ + int ret = 0; + TLSX* extension; + TLSX* priority = NULL; + TLSX* ext = NULL; + SupportedCurve* serverGroup; + SupportedCurve* clientGroup; + SupportedCurve* group; + const DhParams* params; + + extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS); + /* May be doing PSK with no key exchange. */ + if (extension == NULL) + return 0; + clientGroup = (SupportedCurve*)extension->data; + + if ((ret = TLSX_PopulateSupportedGroups(ssl, &priority)) != WOLFSSL_SUCCESS) + return ret; + ret = 0; + + ext = TLSX_Find(priority, TLSX_SUPPORTED_GROUPS); + serverGroup = (SupportedCurve*)ext->data; + + while (serverGroup != NULL) { + if ((serverGroup->name & NAMED_DH_MASK) == NAMED_DH_MASK) { + group = clientGroup; + while (group != NULL) { + if (serverGroup->name == group->name) { + switch (serverGroup->name) { + #ifdef HAVE_FFDHE_2048 + case WOLFSSL_FFDHE_2048: + params = wc_Dh_ffdhe2048_Get(); + break; + #endif + #ifdef HAVE_FFDHE_3072 + case WOLFSSL_FFDHE_3072: + params = wc_Dh_ffdhe3072_Get(); + break; + #endif + #ifdef HAVE_FFDHE_4096 + case WOLFSSL_FFDHE_4096: + params = wc_Dh_ffdhe4096_Get(); + break; + #endif + #ifdef HAVE_FFDHE_6144 + case WOLFSSL_FFDHE_6144: + params = wc_Dh_ffdhe6144_Get(); + break; + #endif + #ifdef HAVE_FFDHE_8192 + case WOLFSSL_FFDHE_8192: + params = wc_Dh_ffdhe8192_Get(); + break; + #endif + default: + return BAD_FUNC_ARG; + } + if (params->p_len >= ssl->options.minDhKeySz && + params->p_len <= ssl->options.maxDhKeySz) { + break; + } + } + + group = group->next; + } + if (group != NULL && serverGroup->name == group->name) + break; + } + serverGroup = serverGroup->next; + } + + if (serverGroup) { + + if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) { + XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + ssl->buffers.serverDH_P.buffer = NULL; + } + if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) { + XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + ssl->buffers.serverDH_G.buffer = NULL; + } + + ssl->buffers.weOwnDH = 0; + ssl->buffers.serverDH_P.buffer = (unsigned char *)params->p; + ssl->buffers.serverDH_P.length = params->p_len; + ssl->buffers.serverDH_G.buffer = (unsigned char *)params->g; + ssl->buffers.serverDH_G.length = params->g_len; + ssl->namedGroup = serverGroup->name; + #if !defined(WOLFSSL_OLD_PRIME_CHECK) && \ + !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + ssl->options.dhDoKeyTest = 0; + #endif + } + + TLSX_FreeAll(priority, ssl->heap); + + return ret; +} +#endif /* HAVE_FFDHE && !WOLFSSL_NO_TLS12 */ + +#endif /* !NO_WOLFSSL_SERVER */ + #if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_SERVER_GROUPS_EXT) /* Return the preferred group. * @@ -3662,24 +3805,24 @@ static int TLSX_PointFormat_Parse(WOLFSSL* ssl, byte* input, word16 length, #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) { - TLSX* extension = (first == ECC_BYTE || first == CHACHA_BYTE) - ? TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS) - : NULL; + TLSX* extension = NULL; SupportedCurve* curve = NULL; - word32 oid = 0; - word32 pkOid = 0; - word32 defOid = 0; - word32 defSz = 80; /* Maximum known curve size is 66. */ - word32 nextOid = 0; - word32 nextSz = 80; /* Maximum known curve size is 66. */ - word32 currOid = ssl->ecdhCurveOID; - int ephmSuite = 0; - word16 octets = 0; /* according to 'ecc_set_type ecc_sets[];' */ - int sig = 0; /* validate signature */ - int key = 0; /* validate key */ + word32 oid = 0; + word32 pkOid = 0; + word32 defOid = 0; + word32 defSz = 80; /* Maximum known curve size is 66. */ + word32 nextOid = 0; + word32 nextSz = 80; /* Maximum known curve size is 66. */ + word32 currOid = ssl->ecdhCurveOID; + int ephmSuite = 0; + word16 octets = 0; /* according to 'ecc_set_type ecc_sets[];' */ + int sig = 0; /* validate signature */ + int key = 0; /* validate key */ (void)oid; + if (first == ECC_BYTE || first == CHACHA_BYTE) + extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS); if (!extension) return 1; /* no suite restriction */ @@ -8819,41 +8962,52 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) #endif /* HAVE_FIPS */ #endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */ - #ifdef WOLFSSL_TLS13 - if (IsAtLeastTLSv1_3(ssl->version)) { /* Add FFDHE supported groups. */ #ifdef HAVE_FFDHE_8192 + if (8192/8 >= ssl->options.minDhKeySz && + 8192/8 <= ssl->options.maxDhKeySz) { ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_FFDHE_8192, ssl->heap); if (ret != WOLFSSL_SUCCESS) return ret; + } #endif #ifdef HAVE_FFDHE_6144 + if (6144/8 >= ssl->options.minDhKeySz && + 6144/8 <= ssl->options.maxDhKeySz) { ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_FFDHE_6144, ssl->heap); if (ret != WOLFSSL_SUCCESS) return ret; + } #endif #ifdef HAVE_FFDHE_4096 + if (4096/8 >= ssl->options.minDhKeySz && + 4096/8 <= ssl->options.maxDhKeySz) { ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_FFDHE_4096, ssl->heap); if (ret != WOLFSSL_SUCCESS) return ret; + } #endif #ifdef HAVE_FFDHE_3072 + if (3072/8 >= ssl->options.minDhKeySz && + 3072/8 <= ssl->options.maxDhKeySz) { ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_FFDHE_3072, ssl->heap); if (ret != WOLFSSL_SUCCESS) return ret; + } #endif #ifdef HAVE_FFDHE_2048 + if (2048/8 >= ssl->options.minDhKeySz && + 2048/8 <= ssl->options.maxDhKeySz) { ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_FFDHE_2048, ssl->heap); if (ret != WOLFSSL_SUCCESS) return ret; + } #endif - } - #endif /* WOLFSSL_TLS13 */ (void)ssl; (void)extensions; @@ -9590,6 +9744,45 @@ int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset #endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_SERVER */ +#ifdef WOLFSSL_TLS13 +int TLSX_ParseVersion(WOLFSSL* ssl, byte* input, word16 length, byte msgType, + int* found) +{ + int ret = 0; + int offset = 0; + + *found = 0; + while (offset < length) { + word16 type; + word16 size; + + ato16(input + offset, &type); + offset += HELLO_EXT_TYPE_SZ; + + ato16(input + offset, &size); + offset += OPAQUE16_LEN; + + if (offset + size > length) { + ret = BUFFER_ERROR; + break; + } + + if (type == TLSX_SUPPORTED_VERSIONS) { + *found = 1; + + WOLFSSL_MSG("Supported Versions extension received"); + + ret = SV_PARSE(ssl, input + offset, size, msgType); + break; + } + + offset += size; + } + + return ret; +} +#endif + /** Parses a buffer of TLS extensions. */ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, Suites *suites) @@ -9635,7 +9828,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, WOLFSSL_MSG("SNI extension received"); #ifdef WOLFSSL_TLS13 - if (IsAtLeastTLSv1_3(ssl->ctx->method->version) && + if (IsAtLeastTLSv1_3(ssl->version) && msgType != client_hello && msgType != server_hello && msgType != encrypted_extensions) { @@ -9653,7 +9846,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, WOLFSSL_MSG("Max Fragment Length extension received"); #ifdef WOLFSSL_TLS13 - if (IsAtLeastTLSv1_3(ssl->ctx->method->version) && + if (IsAtLeastTLSv1_3(ssl->version) && msgType != client_hello && msgType != encrypted_extensions) { return EXT_NOT_ALLOWED; @@ -9670,10 +9863,8 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, WOLFSSL_MSG("Truncated HMAC extension received"); #ifdef WOLFSSL_TLS13 - if (IsAtLeastTLSv1_3(ssl->ctx->method->version) && - !ssl->options.downgrade) { + if (IsAtLeastTLSv1_3(ssl->version)) break; - } #endif ret = THM_PARSE(ssl, input + offset, size, isRequest); break; @@ -9682,7 +9873,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, WOLFSSL_MSG("Supported Groups extension received"); #ifdef WOLFSSL_TLS13 - if (IsAtLeastTLSv1_3(ssl->ctx->method->version) && + if (IsAtLeastTLSv1_3(ssl->version) && msgType != client_hello && msgType != server_hello && msgType != encrypted_extensions) { @@ -9692,11 +9883,6 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, msgType == encrypted_extensions) { return EXT_NOT_ALLOWED; } - else if (IsAtLeastTLSv1_3(ssl->ctx->method->version) && - msgType == server_hello && - !ssl->options.downgrade) { - return EXT_NOT_ALLOWED; - } #endif ret = EC_PARSE(ssl, input + offset, size, isRequest); break; @@ -9705,10 +9891,8 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, WOLFSSL_MSG("Point Formats extension received"); #ifdef WOLFSSL_TLS13 - if (IsAtLeastTLSv1_3(ssl->ctx->method->version) && - !ssl->options.downgrade) { + if (IsAtLeastTLSv1_3(ssl->ctx->method->version)) break; - } #endif ret = PF_PARSE(ssl, input + offset, size, isRequest); break; @@ -9717,10 +9901,8 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, WOLFSSL_MSG("Certificate Status Request extension received"); #ifdef WOLFSSL_TLS13 - if (IsAtLeastTLSv1_3(ssl->ctx->method->version) && - !ssl->options.downgrade) { + if (IsAtLeastTLSv1_3(ssl->version)) break; - } #endif ret = CSR_PARSE(ssl, input + offset, size, isRequest); break; @@ -9729,7 +9911,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, WOLFSSL_MSG("Certificate Status Request v2 extension received"); #ifdef WOLFSSL_TLS13 - if (IsAtLeastTLSv1_3(ssl->ctx->method->version) && + if (IsAtLeastTLSv1_3(ssl->version) && msgType != client_hello && msgType != certificate_request && msgType != certificate) { @@ -9744,10 +9926,8 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, WOLFSSL_MSG("Extended Master Secret extension received"); #ifdef WOLFSSL_TLS13 - if (IsAtLeastTLSv1_3(ssl->ctx->method->version) && - !ssl->options.downgrade) { + if (IsAtLeastTLSv1_3(ssl->version)) break; - } #endif #ifndef NO_WOLFSSL_SERVER if (isRequest) @@ -9761,10 +9941,8 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, WOLFSSL_MSG("Secure Renegotiation extension received"); #ifdef WOLFSSL_TLS13 - if (IsAtLeastTLSv1_3(ssl->ctx->method->version) && - !ssl->options.downgrade) { + if (IsAtLeastTLSv1_3(ssl->version)) break; - } #endif ret = SCR_PARSE(ssl, input + offset, size, isRequest); break; @@ -9785,10 +9963,8 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, WOLFSSL_MSG("Quantum-Safe-Hybrid extension received"); #ifdef WOLFSSL_TLS13 - if (IsAtLeastTLSv1_3(ssl->ctx->method->version) && - !ssl->options.downgrade) { + if (IsAtLeastTLSv1_3(ssl->version)) break; - } #endif ret = QSH_PARSE(ssl, input + offset, size, isRequest); break; @@ -9797,7 +9973,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, WOLFSSL_MSG("ALPN extension received"); #ifdef WOLFSSL_TLS13 - if (IsAtLeastTLSv1_3(ssl->ctx->method->version) && + if (IsAtLeastTLSv1_3(ssl->version) && msgType != client_hello && msgType != server_hello && msgType != encrypted_extensions) { @@ -9818,7 +9994,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, break; #ifdef WOLFSSL_TLS13 - if (IsAtLeastTLSv1_3(ssl->ctx->method->version) && + if (IsAtLeastTLSv1_3(ssl->version) && msgType != client_hello && msgType != certificate_request) { return EXT_NOT_ALLOWED; @@ -9829,29 +10005,14 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, #ifdef WOLFSSL_TLS13 case TLSX_SUPPORTED_VERSIONS: - WOLFSSL_MSG("Supported Versions extension received"); + WOLFSSL_MSG("Skipping Supported Versions - already processed"); - if (!IsAtLeastTLSv1_3(ssl->ctx->method->version)) - break; - - if ( - #ifdef WOLFSSL_TLS13_DRAFT_18 - msgType != client_hello - #else - msgType != client_hello && - msgType != server_hello && - msgType != hello_retry_request - #endif - ) { - return EXT_NOT_ALLOWED; - } - ret = SV_PARSE(ssl, input + offset, size, msgType); break; case TLSX_COOKIE: WOLFSSL_MSG("Cookie extension received"); - if (!IsAtLeastTLSv1_3(ssl->ctx->method->version)) + if (!IsAtLeastTLSv1_3(ssl->version)) break; if (msgType != client_hello && @@ -9866,7 +10027,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, case TLSX_PRE_SHARED_KEY: WOLFSSL_MSG("Pre-Shared Key extension received"); - if (!IsAtLeastTLSv1_3(ssl->ctx->method->version)) + if (!IsAtLeastTLSv1_3(ssl->version)) break; if (msgType != client_hello && msgType != server_hello) @@ -9879,7 +10040,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, case TLSX_PSK_KEY_EXCHANGE_MODES: WOLFSSL_MSG("PSK Key Exchange Modes extension received"); - if (!IsAtLeastTLSv1_3(ssl->ctx->method->version)) + if (!IsAtLeastTLSv1_3(ssl->version)) break; if (msgType != client_hello) @@ -9893,7 +10054,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, case TLSX_EARLY_DATA: WOLFSSL_MSG("Early Data extension received"); - if (!IsAtLeastTLSv1_3(ssl->ctx->method->version)) + if (!IsAtLeastTLSv1_3(ssl->version)) break; if (msgType != client_hello && msgType != session_ticket && @@ -9913,7 +10074,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, case TLSX_POST_HANDSHAKE_AUTH: WOLFSSL_MSG("Post Handshake Authentication extension received"); - if (!IsAtLeastTLSv1_3(ssl->ctx->method->version)) + if (!IsAtLeastTLSv1_3(ssl->version)) break; if (msgType != client_hello) @@ -9927,7 +10088,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, case TLSX_SIGNATURE_ALGORITHMS_CERT: WOLFSSL_MSG("Signature Algorithms extension received"); - if (!IsAtLeastTLSv1_3(ssl->ctx->method->version)) + if (!IsAtLeastTLSv1_3(ssl->version)) break; if (msgType != client_hello && @@ -9946,7 +10107,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, case TLSX_KEY_SHARE: WOLFSSL_MSG("Key Share extension received"); - if (!IsAtLeastTLSv1_3(ssl->ctx->method->version)) + if (!IsAtLeastTLSv1_3(ssl->version)) break; if (msgType != client_hello && msgType != server_hello && diff --git a/src/tls13.c b/src/tls13.c index fd50831db..ddce43250 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -2788,6 +2788,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, byte sessIdSz; const byte* sessId; byte b; + int foundVersion; #endif word16 totalExtSz; #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) @@ -2910,9 +2911,24 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return BUFFER_ERROR; #ifndef WOLFSSL_TLS13_DRAFT_18 - if (ssl->options.downgrade) - ssl->version.minor = TLSv1_2_MINOR; + /* Need to negotiate version first. */ + if ((ret = TLSX_ParseVersion(ssl, (byte*)input + i, totalExtSz, + *extMsgType, &foundVersion))) { + return ret; + } + if (!foundVersion) { + if (!ssl->options.downgrade) { + WOLFSSL_MSG("Server trying to downgrade to version less than " + "TLS v1.3"); + return VERSION_ERROR; + } + + if (pv.minor < ssl->options.minDowngrade) + return VERSION_ERROR; + ssl->version.minor = pv.minor; + } #endif + /* Parse and handle extensions. */ ret = TLSX_Parse(ssl, (byte *) input + i, totalExtSz, *extMsgType, NULL); @@ -3799,6 +3815,7 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef HAVE_SESSION_TICKET int inputHashed = 0; #endif + int foundVersion; WOLFSSL_START(WC_FUNC_CLIENT_HELLO_DO); WOLFSSL_ENTER("DoTls13ClientHello"); @@ -3923,6 +3940,23 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if ((ret = TLSX_PopulateExtensions(ssl, 1)) != 0) return ret; + /* Need to negotiate version first. */ + if ((ret = TLSX_ParseVersion(ssl, (byte*)input + i, totalExtSz, + client_hello, &foundVersion))) { + return ret; + } + if (!foundVersion) { + if (!ssl->options.downgrade) { + WOLFSSL_MSG("Client trying to connect with lesser version than " + "TLS v1.3"); + return VERSION_ERROR; + } + + if (pv.minor < ssl->options.minDowngrade) + return VERSION_ERROR; + ssl->version.minor = pv.minor; + } + /* Parse extensions */ if ((ret = TLSX_Parse(ssl, (byte*)input + i, totalExtSz, client_hello, &clSuites))) { @@ -3940,29 +3974,12 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, i += totalExtSz; *inOutIdx = i; - if (TLSX_Find(ssl->extensions, TLSX_SUPPORTED_VERSIONS) == NULL) { - if (!ssl->options.downgrade) { - WOLFSSL_MSG("Client trying to connect with lesser version than " - "TLS v1.3"); - return VERSION_ERROR; - } - - if (pv.minor < ssl->options.minDowngrade) - return VERSION_ERROR; - ssl->version.minor = pv.minor; - } - ssl->options.sendVerify = SEND_CERT; ssl->options.clientState = CLIENT_HELLO_COMPLETE; ssl->options.haveSessionId = 1; if (IsAtLeastTLSv1_3(ssl->version)) { -#ifdef HAVE_SERVER_RENEGOTIATION_INFO - TLSX_Remove(&ssl->extensions, TLSX_RENEGOTIATION_INFO, ssl->heap); - ssl->secure_renegotiation = NULL; -#endif - #if !defined(WOLFSSL_TLS13_DRAFT_18) && defined(WOLFSSL_SEND_HRR_COOKIE) if (ssl->options.sendCookie && ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST_COMPLETE) { diff --git a/wolfssl/error-ssl.h b/wolfssl/error-ssl.h index 827ae0272..f1053be3d 100644 --- a/wolfssl/error-ssl.h +++ b/wolfssl/error-ssl.h @@ -164,6 +164,7 @@ enum wolfSSL_ErrorCodes { UNSUPPORTED_EXTENSION = -429, /* TLSX not requested by client */ PRF_MISSING = -430, /* PRF not compiled in */ DTLS_RETX_OVER_TX = -431, /* Retransmit DTLS flight over */ + DH_PARAMS_NOT_FFDHE_E = -432, /* DH params from server not FFDHE */ /* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */ /* begin negotiation parameter errors */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index d4fbefaba..afff15db8 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2106,6 +2106,8 @@ WOLFSSL_LOCAL int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset); #endif +WOLFSSL_LOCAL int TLSX_ParseVersion(WOLFSSL* ssl, byte* input, word16 length, + byte msgType, int* found); WOLFSSL_LOCAL int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, Suites *suites); @@ -2260,6 +2262,7 @@ WOLFSSL_LOCAL int TLSX_UsePointFormat(TLSX** extensions, byte point, WOLFSSL_LOCAL int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second); WOLFSSL_LOCAL int TLSX_SupportedCurve_CheckPriority(WOLFSSL* ssl); +WOLFSSL_LOCAL int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl); #endif WOLFSSL_LOCAL int TLSX_SupportedCurve_Preferred(WOLFSSL* ssl, int checkSupported); @@ -3697,8 +3700,10 @@ struct WOLFSSL { byte maxRequest; byte user_set_QSHSchemes; #endif -#ifdef WOLFSSL_TLS13 +#if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) word16 namedGroup; +#endif +#ifdef WOLFSSL_TLS13 word16 group[WOLFSSL_MAX_GROUP_COUNT]; byte numGroups; #endif diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 44bc2367b..f36c4a22a 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2393,7 +2393,6 @@ enum { WOLFSSL_ECC_BRAINPOOLP384R1 = 27, WOLFSSL_ECC_BRAINPOOLP512R1 = 28, WOLFSSL_ECC_X25519 = 29, -#ifdef WOLFSSL_TLS13 /* Not implemented. */ WOLFSSL_ECC_X448 = 30, @@ -2402,7 +2401,6 @@ enum { WOLFSSL_FFDHE_4096 = 258, WOLFSSL_FFDHE_6144 = 259, WOLFSSL_FFDHE_8192 = 260, -#endif }; enum { diff --git a/wolfssl/test.h b/wolfssl/test.h index a9af40315..669dc4404 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -670,7 +670,7 @@ static WC_INLINE void showPeerEx(WOLFSSL* ssl, int lng_index) WOLFSSL_CIPHER* cipher; const char** words = client_showpeer_msg[lng_index]; -#ifdef HAVE_ECC +#if defined(HAVE_ECC) || !defined(NO_DH) const char *name; #endif #ifndef NO_DH @@ -697,12 +697,12 @@ static WC_INLINE void showPeerEx(WOLFSSL* ssl, int lng_index) #else printf("%s %s\n", words[1], wolfSSL_CIPHER_get_name(cipher)); #endif -#ifdef HAVE_ECC +#if defined(HAVE_ECC) || !defined(NO_DH) if ((name = wolfSSL_get_curve_name(ssl)) != NULL) printf("%s %s\n", words[2], name); #endif #ifndef NO_DH - if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0) + else if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0) printf("%s %d bits\n", words[3], bits); #endif if (wolfSSL_session_reused(ssl)) diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index e7fa29e85..eed0a1288 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1808,6 +1808,14 @@ extern void uITRON4_free(void *p) ; #define SSL_CTRL_SET_TLSEXT_HOSTNAME #endif +#if !defined(NO_DH) && !defined(HAVE_FFDHE) + #if defined(HAVE_FFDHE_2048) || defined(HAVE_FFDHE_3072) || \ + defined(HAVE_FFDHE_4096) || defined(HAVE_FFDHE_6144) || \ + defined(HAVE_FFDHE_8192) + #define HAVE_FFDHE + #endif +#endif + /* both CURVE and ED small math should be enabled */ #ifdef CURVED25519_SMALL #define CURVE25519_SMALL