diff --git a/configure.ac b/configure.ac index 975bb0418..0e9870028 100644 --- a/configure.ac +++ b/configure.ac @@ -10858,7 +10858,7 @@ then # Replace all options and just use WOLFSSL_USER_SETTINGS and # WOLFSSL_USER_SETTINGS_ASM. AM_CFLAGS="-DWOLFSSL_USER_SETTINGS -DWOLFSSL_USER_SETTINGS_ASM" - AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_USER_SETTINGS -DWOLFSSL_USER_SETTINGS_ASM" + AM_CCASFLAGS="-DWOLFSSL_USER_SETTINGS -DWOLFSSL_USER_SETTINGS_ASM" # Generate assembly-safe user_settings_asm.h (just preprocessor directives # from user_settings.h). diff --git a/examples/benchmark/tls_bench.c b/examples/benchmark/tls_bench.c index 29fe81e48..ede7d8fed 100644 --- a/examples/benchmark/tls_bench.c +++ b/examples/benchmark/tls_bench.c @@ -286,6 +286,9 @@ static struct group_info groups[] = { { WOLFSSL_ECC_BRAINPOOLP512R1, "ECC_BRAINPOOLP512R1" }, { WOLFSSL_ECC_X25519, "ECC_X25519" }, { WOLFSSL_ECC_X448, "ECC_X448" }, + { WOLFSSL_ECC_BRAINPOOLP256R1TLS13, "ECC_BRAINPOOLP256R1TLS13" }, + { WOLFSSL_ECC_BRAINPOOLP384R1TLS13, "ECC_BRAINPOOLP384R1TLS13" }, + { WOLFSSL_ECC_BRAINPOOLP512R1TLS13, "ECC_BRAINPOOLP512R1TLS13" }, { WOLFSSL_FFDHE_2048, "FFDHE_2048" }, { WOLFSSL_FFDHE_3072, "FFDHE_3072" }, { WOLFSSL_FFDHE_4096, "FFDHE_4096" }, diff --git a/examples/client/client.c b/examples/client/client.c index c7b1b952f..16ea02075 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -308,7 +308,8 @@ static void ShowVersions(void) #if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES) #define MAX_GROUP_NUMBER 4 static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519, - int useX448, int usePqc, char* pqcAlg, int setGroups) + int useX448, int useBp, int usePqc, char* pqcAlg, + int setGroups) { int ret; int groups[MAX_GROUP_NUMBER] = {0}; @@ -316,6 +317,7 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519, (void)useX25519; (void)useX448; + (void)useBp; (void)usePqc; (void)pqcAlg; @@ -349,6 +351,23 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519, else err_sys("unable to use curve x448"); } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); + #endif + } + else if (useBp) { + #if defined(HAVE_ECC) && defined(HAVE_ECC_BRAINPOOL) + #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256 + do { + ret = wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_BRAINPOOLP256R1TLS13); + if (ret == WOLFSSL_SUCCESS) + groups[count++] = WOLFSSL_ECC_BRAINPOOLP256R1TLS13; + #ifdef WOLFSSL_ASYNC_CRYPT + else if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) + wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); + #endif + else + err_sys("unable to use curve brainpoolp256r1"); + } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); + #endif #endif } else { @@ -587,7 +606,7 @@ static const char* client_bench_conmsg[][5] = { static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, int dtlsUDP, int dtlsSCTP, int benchmark, int resumeSession, int useX25519, int useX448, int usePqc, char* pqcAlg, int helloRetry, int onlyKeyShare, - int version, int earlyData) + int version, int earlyData, int useBp) { /* time passed in number of connects give average */ int times = benchmark, skip = (int)((double)times * 0.1); @@ -610,6 +629,7 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, (void)onlyKeyShare; (void)version; (void)earlyData; + (void)useBp; while (loops--) { #ifndef NO_SESSION_CACHE @@ -636,7 +656,7 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, else if (version >= 4) { if (!helloRetry) SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, - usePqc, pqcAlg, 1); + useBp, usePqc, pqcAlg, 1); else wolfSSL_NoKeyShares(ssl); } @@ -717,7 +737,7 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, int dtlsUDP, int dtlsSCTP, int block, size_t throughput, int useX25519, int useX448, int usePqc, char* pqcAlg, int exitWithRet, int version, - int onlyKeyShare) + int onlyKeyShare, int useBp) { double start, conn_time = 0, tx_time = 0, rx_time = 0; SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID; @@ -738,11 +758,12 @@ static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, (void)useX448; (void)usePqc; (void)pqcAlg; + (void)useBp; (void)version; (void)onlyKeyShare; #if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES) if (version >= 4) { - SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, usePqc, + SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, useBp, usePqc, pqcAlg, 1); } #endif @@ -1150,7 +1171,7 @@ static int ClientWriteRead(WOLFSSL* ssl, const char* msg, int msgSz, /* 4. add the same message into Japanese section */ /* (will be translated later) */ /* 5. add printf() into suitable position of Usage() */ -static const char* client_usage_msg[][78] = { +static const char* client_usage_msg[][79] = { /* English */ { " NOTE: All files relative to wolfSSL home dir\n", /* 0 */ @@ -1398,10 +1419,13 @@ static const char* client_usage_msg[][78] = { "--files-are-der Specified files are in DER, not PEM format\n", /* 75 */ #ifdef WOLFSSL_SYS_CRYPTO_POLICY "--crypto-policy \n", /* 76 */ +#endif +#ifdef HAVE_ECC_BRAINPOOL + "--bpKs Use Brainpool ECC group for key share\n", /* 77 */ #endif "\n" "For simpler wolfSSL TLS client examples, visit\n" - "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 77 */ + "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 78 */ NULL, }, #ifndef NO_MULTIBYTE_PRINT @@ -1653,11 +1677,14 @@ static const char* client_usage_msg[][78] = { "--files-are-der Specified files are in DER, not PEM format\n", /* 75 */ #ifdef WOLFSSL_SYS_CRYPTO_POLICY "--crypto-policy \n", /* 76 */ +#endif +#ifdef HAVE_ECC_BRAINPOOL + "--bpKs Use Brainpool ECC group for key share\n", /* 77 */ #endif "\n" "より簡単なwolfSSL TLS クライアントの例については" "下記にアクセスしてください\n" - "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 77 */ + "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 78 */ NULL, }, #endif @@ -1892,6 +1919,9 @@ static void Usage(void) #endif #ifdef HAVE_RPK printf("%s", msg[++msgid]); /* --rpk */ +#endif +#ifdef HAVE_ECC_BRAINPOOL + printf("%s", msg[++msgid]); /* --bpKs */ #endif printf("%s", msg[++msgid]); /* --files-are-der */ printf("%s", msg[++msgid]); /* Documentation Hint */ @@ -2078,6 +2108,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #if defined(WOLFSSL_SYS_CRYPTO_POLICY) { "crypto-policy", 1, 269 }, #endif /* WOLFSSL_SYS_CRYPTO_POLICY */ +#ifdef HAVE_ECC_BRAINPOOL + { "bpKs", 0, 270 }, +#endif { 0, 0, 0 } }; #endif @@ -2187,6 +2220,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif int useX25519 = 0; int useX448 = 0; + int useBrainpool = 0; int usePqc = 0; char* pqcAlg = NULL; int exitWithRet = 0; @@ -2311,6 +2345,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) (void)earlyData; (void)useX25519; (void)useX448; + (void)useBrainpool; (void)helloRetry; (void)onlyKeyShare; (void)useSupCurve; @@ -2959,6 +2994,15 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) policy = myoptarg; #endif /* WOLFSSL_SYS_CRYPTO_POLICY */ break; +#ifdef HAVE_ECC_BRAINPOOL + case 270: + useBrainpool = 1; + #if defined(HAVE_ECC) && defined(WOLFSSL_TLS13) && \ + defined(HAVE_SUPPORTED_CURVES) + onlyKeyShare = 2; + #endif + break; +#endif default: Usage(); @@ -3680,6 +3724,37 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif /* HAVE_CURVE448 */ #ifdef HAVE_ECC + #ifdef HAVE_ECC_BRAINPOOL + if (useBrainpool) { + if (version == 4) { + if (wolfSSL_CTX_UseSupportedCurve(ctx, + WOLFSSL_ECC_BRAINPOOLP256R1TLS13) + != WOLFSSL_SUCCESS) { + err_sys("unable to support brainpoolp256r1tls13"); + } + } + else if (version == CLIENT_DOWNGRADE_VERSION) { + if (wolfSSL_CTX_UseSupportedCurve(ctx, + WOLFSSL_ECC_BRAINPOOLP256R1TLS13) + != WOLFSSL_SUCCESS) { + err_sys("unable to support brainpoolp256r1tls13"); + } + if (minVersion <= 3) { + if (wolfSSL_CTX_UseSupportedCurve(ctx, + WOLFSSL_ECC_BRAINPOOLP256R1) + != WOLFSSL_SUCCESS) { + err_sys("unable to support brainpoolp256r1"); + } + } + } + else { + if (wolfSSL_CTX_UseSupportedCurve(ctx, WOLFSSL_ECC_BRAINPOOLP256R1) + != WOLFSSL_SUCCESS) { + err_sys("unable to support brainpoolp256r1"); + } + } + } + #endif /* HAVE_ECC_BRAINPOOL */ if (useSupCurve) { #if !defined(NO_ECC_SECP) && \ (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) @@ -3728,7 +3803,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) ClientBenchmarkConnections(ctx, host, port, dtlsUDP, dtlsSCTP, benchmark, resumeSession, useX25519, useX448, usePqc, pqcAlg, helloRetry, - onlyKeyShare, version, earlyData); + onlyKeyShare, version, earlyData, + useBrainpool); wolfSSL_CTX_free(ctx); ctx = NULL; XEXIT_T(EXIT_SUCCESS); } @@ -3738,7 +3814,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) ClientBenchmarkThroughput(ctx, host, port, dtlsUDP, dtlsSCTP, block, throughput, useX25519, useX448, usePqc, pqcAlg, exitWithRet, version, - onlyKeyShare); + onlyKeyShare, useBrainpool); wolfSSL_CTX_free(ctx); ctx = NULL; if (((func_args*)args)->return_code != EXIT_SUCCESS && !exitWithRet) XEXIT_T(EXIT_SUCCESS); @@ -3872,8 +3948,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES) if (!helloRetry && (version >= 4 || version <= -4)) { - SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, usePqc, - pqcAlg, 0); + SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, + useBrainpool, usePqc, pqcAlg, 0); } else { wolfSSL_NoKeyShares(ssl); diff --git a/examples/server/server.c b/examples/server/server.c index 06e0aeb6a..c7c44409d 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -104,6 +104,9 @@ static struct group_info group_id_to_text[] = { { WOLFSSL_ECC_BRAINPOOLP256R1, "BRAINPOOLP256R1" }, { WOLFSSL_ECC_BRAINPOOLP384R1, "BRAINPOOLP384R1" }, { WOLFSSL_ECC_BRAINPOOLP512R1, "BRAINPOOLP512R1" }, + { WOLFSSL_ECC_BRAINPOOLP256R1TLS13, "BRAINPOOLP256R1TLS13" }, + { WOLFSSL_ECC_BRAINPOOLP384R1TLS13, "BRAINPOOLP384R1TLS13" }, + { WOLFSSL_ECC_BRAINPOOLP512R1TLS13, "BRAINPOOLP512R1TLS13" }, { 0, NULL } }; #endif /* CAN_FORCE_CURVE && HAVE_ECC */ diff --git a/src/internal.c b/src/internal.c index 121dd9495..4740db498 100644 --- a/src/internal.c +++ b/src/internal.c @@ -3312,6 +3312,23 @@ static WC_INLINE void AddSuiteHashSigAlgo(byte* hashSigAlgo, byte macAlgo, #endif } else +#endif +#ifdef HAVE_ECC_BRAINPOOL + if (sigAlgo == ecc_brainpool_sa_algo) { + if (macAlgo == sha512_mac) { + ADD_HASH_SIG_ALGO(hashSigAlgo, inOutIdx, NEW_SA_MAJOR, + ECDSA_BRAINPOOLP512R1TLS13_SHA512_MINOR); + } + else if (macAlgo == sha384_mac) { + ADD_HASH_SIG_ALGO(hashSigAlgo, inOutIdx, NEW_SA_MAJOR, + ECDSA_BRAINPOOLP384R1TLS13_SHA384_MINOR); + } + else if (macAlgo == sha256_mac) { + ADD_HASH_SIG_ALGO(hashSigAlgo, inOutIdx, NEW_SA_MAJOR, + ECDSA_BRAINPOOLP256R1TLS13_SHA256_MINOR); + } + } + else #endif { ADD_HASH_SIG_ALGO(hashSigAlgo, inOutIdx, macAlgo, sigAlgo); @@ -3320,11 +3337,12 @@ static WC_INLINE void AddSuiteHashSigAlgo(byte* hashSigAlgo, byte macAlgo, } void InitSuitesHashSigAlgo(byte* hashSigAlgo, int haveSig, int tls1_2, - int keySz, word16* len) + int tls1_3, int keySz, word16* len) { word16 idx = 0; (void)tls1_2; + (void)tls1_3; (void)keySz; #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) @@ -3333,14 +3351,32 @@ void InitSuitesHashSigAlgo(byte* hashSigAlgo, int haveSig, int tls1_2, #ifdef WOLFSSL_SHA512 AddSuiteHashSigAlgo(hashSigAlgo, sha512_mac, ecc_dsa_sa_algo, keySz, &idx); + #ifdef HAVE_ECC_BRAINPOOL + if (tls1_3) { + AddSuiteHashSigAlgo(hashSigAlgo, sha512_mac, ecc_brainpool_sa_algo, + keySz, &idx); + } + #endif #endif #ifdef WOLFSSL_SHA384 AddSuiteHashSigAlgo(hashSigAlgo, sha384_mac, ecc_dsa_sa_algo, keySz, &idx); + #ifdef HAVE_ECC_BRAINPOOL + if (tls1_3) { + AddSuiteHashSigAlgo(hashSigAlgo, sha384_mac, ecc_brainpool_sa_algo, + keySz, &idx); + } + #endif #endif #ifndef NO_SHA256 AddSuiteHashSigAlgo(hashSigAlgo, sha256_mac, ecc_dsa_sa_algo, keySz, &idx); + #ifdef HAVE_ECC_BRAINPOOL + if (tls1_3) { + AddSuiteHashSigAlgo(hashSigAlgo, sha256_mac, ecc_brainpool_sa_algo, + keySz, &idx); + } + #endif #endif #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \ defined(WOLFSSL_ALLOW_TLS_SHA1)) @@ -3465,9 +3501,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, word16 idx = 0; int tls = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR; int tls1_2 = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_2_MINOR; -#ifdef WOLFSSL_TLS13 int tls1_3 = IsAtLeastTLSv1_3(pv); -#endif int dtls = 0; int haveRSAsig = 1; @@ -3484,6 +3518,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, (void)tls; /* shut up compiler */ (void)tls1_2; + (void)tls1_3; (void)dtls; (void)haveDH; (void)havePSK; @@ -4511,8 +4546,8 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suiteSz = idx; if (suites->hashSigAlgoSz == 0) { - InitSuitesHashSigAlgo(suites->hashSigAlgo, SIG_ALL, tls1_2, keySz, - &suites->hashSigAlgoSz); + InitSuitesHashSigAlgo(suites->hashSigAlgo, SIG_ALL, tls1_2, tls1_3, + keySz, &suites->hashSigAlgoSz); } /* Moved to the end as we set some of the vars but never use them */ @@ -4571,6 +4606,22 @@ void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType) *hashAlgo = PSS_PSS_HASH_TO_MAC(input[1]); } else + #endif + #ifdef HAVE_ECC_BRAINPOOL + /* RFC 8734 TLS 1.3 Brainpool curves */ + if (input[1] == ECDSA_BRAINPOOLP256R1TLS13_SHA256_MINOR) { + *hsType = ecc_brainpool_sa_algo; + *hashAlgo = sha256_mac; + } + else if (input[1] == ECDSA_BRAINPOOLP384R1TLS13_SHA384_MINOR) { + *hsType = ecc_brainpool_sa_algo; + *hashAlgo = sha384_mac; + } + else if (input[1] == ECDSA_BRAINPOOLP512R1TLS13_SHA512_MINOR) { + *hsType = ecc_brainpool_sa_algo; + *hashAlgo = sha512_mac; + } + else #endif { *hsType = input[0]; @@ -28313,6 +28364,7 @@ static int ParseCipherList(Suites* suites, word16 haveSHA1 = 1; /* allowed by default if compiled in */ word16 haveRC4 = 1; /* allowed by default if compiled in */ #endif + int tls1_3 = 0; const int suiteSz = GetCipherNamesSize(); const char* next = list; @@ -28638,6 +28690,7 @@ static int ParseCipherList(Suites* suites, (cipher_names[i].cipherSuite0 == ECC_BYTE && (cipher_names[i].cipherSuite == TLS_SHA256_SHA256 || cipher_names[i].cipherSuite == TLS_SHA384_SHA384))) { + tls1_3 = 1; #ifndef NO_RSA haveSig |= SIG_RSA; #endif @@ -28741,8 +28794,8 @@ static int ParseCipherList(Suites* suites, #endif { suites->suiteSz = (word16)idx; - InitSuitesHashSigAlgo(suites->hashSigAlgo, haveSig, 1, keySz, - &suites->hashSigAlgoSz); + InitSuitesHashSigAlgo(suites->hashSigAlgo, haveSig, 1, tls1_3, + keySz, &suites->hashSigAlgoSz); } #ifdef HAVE_RENEGOTIATION_INDICATION @@ -28815,6 +28868,7 @@ int SetCipherListFromBytes(WOLFSSL_CTX* ctx, Suites* suites, const byte* list, int haveFalconSig = 0; int haveDilithiumSig = 0; int haveAnon = 0; + int tls1_3 = 0; if (suites == NULL || list == NULL) { WOLFSSL_MSG("SetCipherListFromBytes parameter error"); @@ -28874,6 +28928,7 @@ int SetCipherListFromBytes(WOLFSSL_CTX* ctx, Suites* suites, const byte* list, secondByte == TLS_SHA384_SHA384)) || (firstByte == CIPHER_BYTE && (secondByte == TLS_SM4_GCM_SM3 || secondByte == TLS_SM4_CCM_SM3))) { + tls1_3 = 1; #ifndef NO_RSA haveRSAsig = 1; #endif @@ -28925,8 +28980,8 @@ int SetCipherListFromBytes(WOLFSSL_CTX* ctx, Suites* suites, const byte* list, haveSig |= haveFalconSig ? SIG_FALCON : 0; haveSig |= haveDilithiumSig ? SIG_DILITHIUM : 0; haveSig |= haveAnon ? SIG_ANON : 0; - InitSuitesHashSigAlgo(suites->hashSigAlgo, haveSig, 1, keySz, - &suites->hashSigAlgoSz); + InitSuitesHashSigAlgo(suites->hashSigAlgo, haveSig, 1, tls1_3, + keySz, &suites->hashSigAlgoSz); #ifdef HAVE_RENEGOTIATION_INDICATION if (ctx->method->side == WOLFSSL_CLIENT_END) { if (suites->suiteSz > WOLFSSL_MAX_SUITE_SZ - 2) { @@ -29107,7 +29162,7 @@ int SetSuitesHashSigAlgo(Suites* suites, const char* list) #endif /* OPENSSL_EXTRA */ -#if !defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS) +#if !defined(NO_TLS) && (!defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS)) static int MatchSigAlgo(WOLFSSL* ssl, int sigAlgo) { #ifdef HAVE_ED25519 @@ -29174,6 +29229,41 @@ static int MatchSigAlgo(WOLFSSL* ssl, int sigAlgo) if (sigAlgo == rsa_pss_sa_algo) return 1; } +#endif +#ifdef HAVE_ECC_BRAINPOOL + if ((ssl->pkCurveOID == ECC_BRAINPOOLP256R1_OID) || + (ssl->pkCurveOID == ECC_BRAINPOOLP384R1_OID) || + (ssl->pkCurveOID == ECC_BRAINPOOLP512R1_OID)) { + if (IsAtLeastTLSv1_3(ssl->version)) { + /* Certificate has an ECC Brainpool key, only match with the + * specified ECDSA brainpool signature algorithms for TLS 1.3 */ + return sigAlgo == ecc_brainpool_sa_algo; + } + else { + /* Certificate has an ECC Brainpool key, match with ECDSA in TLS 1.2 + * case, but only when the related Brainpool curve is present in + * the supported_groups extension. */ + if (ssl->pkCurveOID == ECC_BRAINPOOLP256R1_OID && + TLSX_SupportedCurve_IsSupported(ssl, + WOLFSSL_ECC_BRAINPOOLP256R1)) { + return sigAlgo == ecc_dsa_sa_algo; + } + else if (ssl->pkCurveOID == ECC_BRAINPOOLP384R1_OID && + TLSX_SupportedCurve_IsSupported(ssl, + WOLFSSL_ECC_BRAINPOOLP384R1)) { + return sigAlgo == ecc_dsa_sa_algo; + } + else if (ssl->pkCurveOID == ECC_BRAINPOOLP512R1_OID && + TLSX_SupportedCurve_IsSupported(ssl, + WOLFSSL_ECC_BRAINPOOLP512R1)) { + return sigAlgo == ecc_dsa_sa_algo; + } + else { + /* Curve not supported in supported_groups extension. */ + return 0; + } + } + } #endif /* Signature algorithm matches certificate. */ return sigAlgo == ssl->options.sigAlgo; @@ -29339,6 +29429,15 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz, break; } #endif /* HAVE_DILITHIUM */ + #if defined(HAVE_ECC_BRAINPOOL) + if (ssl->pkCurveOID == ECC_BRAINPOOLP256R1_OID || + ssl->pkCurveOID == ECC_BRAINPOOLP384R1_OID || + ssl->pkCurveOID == ECC_BRAINPOOLP512R1_OID) { + /* Matched ECC Brainpool. Set sigAlgo to "normal" ECDSA here + * for compatibility with TLS 1.2. */ + sigAlgo = ecc_dsa_sa_algo; + } + #endif #if defined(WOLFSSL_ECDSA_MATCH_HASH) && defined(USE_ECDSA_KEYSZ_HASH_ALGO) #error "WOLFSSL_ECDSA_MATCH_HASH and USE_ECDSA_KEYSZ_HASH_ALGO cannot " @@ -29479,7 +29578,7 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz, return ret; } -#endif /* !defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS) */ +#endif /* !NO_TLS && (!defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS)) */ #if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA) diff --git a/src/sniffer.c b/src/sniffer.c index 905e6abc9..0f3e18f1b 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -3364,6 +3364,11 @@ static int ProcessKeyShare(KeyShareInfo* info, const byte* input, int len, info->curve_id = ECC_SM2P256V1; break; #endif /* WOLFSSL_SM2 */ + #ifdef HAVE_ECC_BRAINPOOL + case WOLFSSL_ECC_BRAINPOOLP256R1TLS13: + info->curve_id = ECC_BRAINPOOLP256R1; + break; + #endif /* HAVE_ECC_BRAINPOOL */ #endif #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) #ifndef NO_ECC_SECP @@ -3371,6 +3376,18 @@ static int ProcessKeyShare(KeyShareInfo* info, const byte* input, int len, info->curve_id = ECC_SECP384R1; break; #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_BRAINPOOL + case WOLFSSL_ECC_BRAINPOOLP384R1TLS13: + info->curve_id = ECC_BRAINPOOLP384R1; + break; + #endif /* HAVE_ECC_BRAINPOOL */ + #endif + #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES) + #ifdef HAVE_ECC_BRAINPOOL + case WOLFSSL_ECC_BRAINPOOLP512R1TLS13: + info->curve_id = ECC_BRAINPOOLP512R1; + break; + #endif /* HAVE_ECC_BRAINPOOL */ #endif #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) #ifndef NO_ECC_SECP diff --git a/src/ssl.c b/src/ssl.c index d3961330e..2c3516e0e 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3741,6 +3741,9 @@ static int isValidCurveGroup(word16 name) case WOLFSSL_ECC_SM2P256V1: case WOLFSSL_ECC_X25519: case WOLFSSL_ECC_X448: + case WOLFSSL_ECC_BRAINPOOLP256R1TLS13: + case WOLFSSL_ECC_BRAINPOOLP384R1TLS13: + case WOLFSSL_ECC_BRAINPOOLP512R1TLS13: case WOLFSSL_FFDHE_2048: case WOLFSSL_FFDHE_3072: @@ -12439,6 +12442,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) *sigAlgo = DSAk; break; case ecc_dsa_sa_algo: + case ecc_brainpool_sa_algo: *sigAlgo = ECDSAk; break; case rsa_pss_sa_algo: @@ -18364,6 +18368,7 @@ static int SaToNid(byte sa, int* nid) *nid = WC_NID_dsa; break; case ecc_dsa_sa_algo: + case ecc_brainpool_sa_algo: *nid = WC_NID_X9_62_id_ecPublicKey; break; case rsa_pss_sa_algo: diff --git a/src/tls.c b/src/tls.c index 8226ba478..b7ba5f2ea 100644 --- a/src/tls.c +++ b/src/tls.c @@ -4407,6 +4407,7 @@ static int TLSX_IsGroupSupported(int namedGroup) #endif /* !NO_ECC_SECP */ #ifdef HAVE_ECC_BRAINPOOL case WOLFSSL_ECC_BRAINPOOLP256R1: + case WOLFSSL_ECC_BRAINPOOLP256R1TLS13: break; #endif #ifdef WOLFSSL_SM2 @@ -4429,6 +4430,7 @@ static int TLSX_IsGroupSupported(int namedGroup) #endif /* !NO_ECC_SECP */ #ifdef HAVE_ECC_BRAINPOOL case WOLFSSL_ECC_BRAINPOOLP384R1: + case WOLFSSL_ECC_BRAINPOOLP384R1TLS13: break; #endif #endif @@ -4475,6 +4477,7 @@ static int TLSX_IsGroupSupported(int namedGroup) #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512 #ifdef HAVE_ECC_BRAINPOOL case WOLFSSL_ECC_BRAINPOOLP512R1: + case WOLFSSL_ECC_BRAINPOOLP512R1TLS13: break; #endif #endif @@ -5329,6 +5332,31 @@ int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl) } #endif /* HAVE_FFDHE && !WOLFSSL_NO_TLS12 */ +/* Check if the given curve is present in the supported groups extension. + * + * ssl SSL/TLS object. + * name The curve name to check. + * returns 1 if present, 0 otherwise. + */ +int TLSX_SupportedCurve_IsSupported(WOLFSSL* ssl, word16 name) +{ + TLSX* extension; + SupportedCurve* curve; + + extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS); + if (extension == NULL) + return 0; + + curve = (SupportedCurve*)extension->data; + while (curve != NULL) { + if (curve->name == name) + return 1; + curve = curve->next; + } + + return 0; +} + #endif /* !NO_WOLFSSL_SERVER */ #if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_SERVER_GROUPS_EXT) @@ -8154,7 +8182,13 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) curveId = ECC_SM2P256V1; keySize = 32; break; - #endif /* !NO_ECC_SECP */ + #endif /* !WOLFSSL_SM2 */ + #ifdef HAVE_ECC_BRAINPOOL + case WOLFSSL_ECC_BRAINPOOLP256R1TLS13: + curveId = ECC_BRAINPOOLP256R1; + keySize = 32; + break; + #endif /* HAVE_ECC_BRAINPOOL */ #endif #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384 #ifndef NO_ECC_SECP @@ -8163,6 +8197,20 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) keySize = 48; break; #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_BRAINPOOL + case WOLFSSL_ECC_BRAINPOOLP384R1TLS13: + curveId = ECC_BRAINPOOLP384R1; + keySize = 48; + break; + #endif /* HAVE_ECC_BRAINPOOL */ + #endif + #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512 + #ifdef HAVE_ECC_BRAINPOOL + case WOLFSSL_ECC_BRAINPOOLP512R1TLS13: + curveId = ECC_BRAINPOOLP512R1; + keySize = 64; + break; + #endif /* HAVE_ECC_BRAINPOOL */ #endif #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521 #ifndef NO_ECC_SECP @@ -9273,7 +9321,12 @@ static int TLSX_KeyShare_ProcessEcc_ex(WOLFSSL* ssl, case WOLFSSL_ECC_SM2P256V1: curveId = ECC_SM2P256V1; break; - #endif + #endif /* WOLFSSL_SM2 */ + #ifdef HAVE_ECC_BRAINPOOL + case WOLFSSL_ECC_BRAINPOOLP256R1TLS13: + curveId = ECC_BRAINPOOLP256R1; + break; + #endif /* HAVE_ECC_BRAINPOOL */ #endif #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384 #ifndef NO_ECC_SECP @@ -9281,6 +9334,18 @@ static int TLSX_KeyShare_ProcessEcc_ex(WOLFSSL* ssl, curveId = ECC_SECP384R1; break; #endif /* !NO_ECC_SECP */ + #ifdef HAVE_ECC_BRAINPOOL + case WOLFSSL_ECC_BRAINPOOLP384R1TLS13: + curveId = ECC_BRAINPOOLP384R1; + break; + #endif /* HAVE_ECC_BRAINPOOL */ + #endif + #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512 + #ifdef HAVE_ECC_BRAINPOOL + case WOLFSSL_ECC_BRAINPOOLP512R1TLS13: + curveId = ECC_BRAINPOOLP512R1; + break; + #endif /* HAVE_ECC_BRAINPOOL */ #endif #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521 #ifndef NO_ECC_SECP @@ -10631,6 +10696,9 @@ static const word16 preferredGroup[] = { #if !defined(HAVE_FIPS) && defined(WOLFSSL_SM2) WOLFSSL_ECC_SM2P256V1, #endif +#if defined(HAVE_ECC_BRAINPOOL) + WOLFSSL_ECC_BRAINPOOLP256R1TLS13, +#endif #endif #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 WOLFSSL_ECC_X25519, @@ -10641,11 +10709,18 @@ static const word16 preferredGroup[] = { #if defined(HAVE_ECC) && (!defined(NO_ECC384) || \ defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 384 WOLFSSL_ECC_SECP384R1, +#if defined(HAVE_ECC_BRAINPOOL) + WOLFSSL_ECC_BRAINPOOLP384R1TLS13, +#endif #endif #if defined(HAVE_ECC) && (!defined(NO_ECC521) || \ defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 521 WOLFSSL_ECC_SECP521R1, #endif +#if defined(HAVE_ECC) && defined(HAVE_ECC512) && \ + defined(HAVE_ECC_BRAINPOOL) && ECC_MIN_KEY_SZ <= 512 + WOLFSSL_ECC_BRAINPOOLP512R1TLS13, +#endif #if defined(HAVE_FFDHE_2048) WOLFSSL_FFDHE_2048, #endif @@ -14227,9 +14302,27 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) #endif #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512 #ifdef HAVE_ECC_BRAINPOOL - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_BRAINPOOLP512R1, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; + if (IsAtLeastTLSv1_3(ssl->version)) { + /* TLS 1.3 BrainpoolP512 curve */ + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_BRAINPOOLP512R1TLS13, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + + /* If TLS 1.2 is allowed, also add the TLS 1.2 curve */ + if (ssl->options.downgrade && + (ssl->options.minDowngrade <= TLSv1_2_MINOR || + ssl->options.minDowngrade <= DTLSv1_2_MINOR)) { + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_BRAINPOOLP512R1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + } + } + else { + /* TLS 1.2 only */ + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_BRAINPOOLP512R1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + } #endif #endif #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384 @@ -14239,9 +14332,27 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) if (ret != WOLFSSL_SUCCESS) return ret; #endif #ifdef HAVE_ECC_BRAINPOOL - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_BRAINPOOLP384R1, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; + if (IsAtLeastTLSv1_3(ssl->version)) { + /* TLS 1.3 BrainpoolP384 curve */ + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_BRAINPOOLP384R1TLS13, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + + /* If TLS 1.2 is allowed, also add the TLS 1.2 curve */ + if (ssl->options.downgrade && + (ssl->options.minDowngrade <= TLSv1_2_MINOR || + ssl->options.minDowngrade <= DTLSv1_2_MINOR)) { + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_BRAINPOOLP384R1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + } + } + else { + /* TLS 1.2 only */ + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_BRAINPOOLP384R1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + } #endif #endif #endif /* HAVE_ECC */ @@ -14267,9 +14378,27 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) if (ret != WOLFSSL_SUCCESS) return ret; #endif #ifdef HAVE_ECC_BRAINPOOL - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_BRAINPOOLP256R1, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; + if (IsAtLeastTLSv1_3(ssl->version)) { + /* TLS 1.3 BrainpoolP256 curve */ + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_BRAINPOOLP256R1TLS13, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + + /* If TLS 1.2 is allowed, also add the TLS 1.2 curve */ + if (ssl->options.downgrade && + (ssl->options.minDowngrade <= TLSv1_2_MINOR || + ssl->options.minDowngrade <= DTLSv1_2_MINOR)) { + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_BRAINPOOLP256R1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + } + } + else { + /* TLS 1.2 only */ + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_BRAINPOOLP256R1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + } #endif #ifdef WOLFSSL_SM2 ret = TLSX_UseSupportedCurve(extensions, diff --git a/src/tls13.c b/src/tls13.c index 25b2b6621..c9fe44643 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -7786,12 +7786,12 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, return SIDE_ERROR; /* Get the length of the hashSigAlgo buffer */ - InitSuitesHashSigAlgo(NULL, SIG_ALL, 1, ssl->buffers.keySz, + InitSuitesHashSigAlgo(NULL, SIG_ALL, 1, 1, ssl->buffers.keySz, &hashSigAlgoSz); sa = TLSX_SignatureAlgorithms_New(ssl, hashSigAlgoSz, ssl->heap); if (sa == NULL) return MEMORY_ERROR; - InitSuitesHashSigAlgo(sa->hashSigAlgo, SIG_ALL, 1, ssl->buffers.keySz, + InitSuitesHashSigAlgo(sa->hashSigAlgo, SIG_ALL, 1, 1, ssl->buffers.keySz, &hashSigAlgoSz); ret = TLSX_Push(&ssl->extensions, TLSX_SIGNATURE_ALGORITHMS, sa, ssl->heap); if (ret != 0) { @@ -7898,8 +7898,22 @@ static WC_INLINE void EncodeSigAlg(const WOLFSSL * ssl, byte hashAlgo, byte hsTy switch (hsType) { #ifdef HAVE_ECC case ecc_dsa_sa_algo: - output[0] = hashAlgo; - output[1] = ecc_dsa_sa_algo; + if (ssl->pkCurveOID == ECC_BRAINPOOLP256R1_OID) { + output[0] = NEW_SA_MAJOR; + output[1] = ECDSA_BRAINPOOLP256R1TLS13_SHA256_MINOR; + } + else if (ssl->pkCurveOID == ECC_BRAINPOOLP384R1_OID) { + output[0] = NEW_SA_MAJOR; + output[1] = ECDSA_BRAINPOOLP384R1TLS13_SHA384_MINOR; + } + else if (ssl->pkCurveOID == ECC_BRAINPOOLP512R1_OID) { + output[0] = NEW_SA_MAJOR; + output[1] = ECDSA_BRAINPOOLP512R1TLS13_SHA512_MINOR; + } + else { + output[0] = hashAlgo; + output[1] = ecc_dsa_sa_algo; + } break; #endif #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) @@ -8068,16 +8082,19 @@ static enum wc_MACAlgorithm GetNewSAHashAlgo(int typeIn) switch (typeIn) { case RSA_PSS_RSAE_SHA256_MINOR: case RSA_PSS_PSS_SHA256_MINOR: + case ECDSA_BRAINPOOLP256R1TLS13_SHA256_MINOR: return sha256_mac; case RSA_PSS_RSAE_SHA384_MINOR: case RSA_PSS_PSS_SHA384_MINOR: + case ECDSA_BRAINPOOLP384R1TLS13_SHA384_MINOR: return sha384_mac; case RSA_PSS_RSAE_SHA512_MINOR: case RSA_PSS_PSS_SHA512_MINOR: case ED25519_SA_MINOR: case ED448_SA_MINOR: + case ECDSA_BRAINPOOLP512R1TLS13_SHA512_MINOR: return sha512_mac; default: return no_mac; @@ -8133,6 +8150,13 @@ static WC_INLINE int DecodeTls13SigAlg(byte* input, byte* hashAlgo, *hsType = ed448_sa_algo; /* Hash performed as part of sign/verify operation. */ } + #endif + #ifdef HAVE_ECC_BRAINPOOL + else if ((input[1] == ECDSA_BRAINPOOLP256R1TLS13_SHA256_MINOR) || + (input[1] == ECDSA_BRAINPOOLP384R1TLS13_SHA384_MINOR) || + (input[1] == ECDSA_BRAINPOOLP512R1TLS13_SHA512_MINOR)) { + *hsType = ecc_dsa_sa_algo; + } #endif else ret = INVALID_PARAMETER; @@ -10564,17 +10588,12 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, #ifdef HAVE_ECC if ((ssl->options.peerSigAlgo == ecc_dsa_sa_algo) && (ssl->peerEccDsaKeyPresent)) { - #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) - if (ssl->options.peerSigAlgo != sm2_sa_algo) - #endif - { - ret = CreateECCEncodedSig(args->sigData, - args->sigDataSz, ssl->options.peerHashAlgo); - if (ret < 0) - goto exit_dcv; - args->sigDataSz = (word16)ret; - ret = 0; - } + ret = CreateECCEncodedSig(args->sigData, + args->sigDataSz, ssl->options.peerHashAlgo); + if (ret < 0) + goto exit_dcv; + args->sigDataSz = (word16)ret; + ret = 0; } #ifdef WOLFSSL_DUAL_ALG_CERTS diff --git a/tests/api.c b/tests/api.c index 69803be4c..4f257c5dc 100644 --- a/tests/api.c +++ b/tests/api.c @@ -16189,7 +16189,7 @@ static int test_wolfSSL_sigalg_info(void) word16 idx = 0; int allSigAlgs = SIG_ECDSA | SIG_RSA | SIG_SM2 | SIG_FALCON | SIG_DILITHIUM; - InitSuitesHashSigAlgo(hashSigAlgo, allSigAlgs, 1, 0xFFFFFFFF, &len); + InitSuitesHashSigAlgo(hashSigAlgo, allSigAlgs, 1, 1, 0xFFFFFFFF, &len); for (idx = 0; idx < len; idx += 2) { int hashAlgo = 0; int sigAlgo = 0; @@ -16201,7 +16201,7 @@ static int test_wolfSSL_sigalg_info(void) ExpectIntNE(sigAlgo, 0); } - InitSuitesHashSigAlgo(hashSigAlgo, allSigAlgs | SIG_ANON, 1, + InitSuitesHashSigAlgo(hashSigAlgo, allSigAlgs | SIG_ANON, 1, 1, 0xFFFFFFFF, &len); for (idx = 0; idx < len; idx += 2) { int hashAlgo = 0; @@ -29290,7 +29290,13 @@ static int test_certreq_sighash_algos(void) maxIdx = idx + (int)len; for (; idx < maxIdx && EXPECT_SUCCESS(); idx += OPAQUE16_LEN) { if (test_ctx.c_buff[idx+1] == ED25519_SA_MINOR || - test_ctx.c_buff[idx+1] == ED448_SA_MINOR) + test_ctx.c_buff[idx+1] == ED448_SA_MINOR || + test_ctx.c_buff[idx+1] == + ECDSA_BRAINPOOLP256R1TLS13_SHA256_MINOR || + test_ctx.c_buff[idx+1] == + ECDSA_BRAINPOOLP384R1TLS13_SHA384_MINOR || + test_ctx.c_buff[idx+1] == + ECDSA_BRAINPOOLP512R1TLS13_SHA512_MINOR) ExpectIntEQ(test_ctx.c_buff[idx], NEW_SA_MAJOR); else ExpectIntEQ(test_ctx.c_buff[idx+1], ecc_dsa_sa_algo); diff --git a/tests/test-ecc-cust-curves.conf b/tests/test-ecc-cust-curves.conf index 6f24783e8..42f8b3561 100644 --- a/tests/test-ecc-cust-curves.conf +++ b/tests/test-ecc-cust-curves.conf @@ -49,7 +49,7 @@ -A ./certs/ecc/client-secp256k1-cert.pem -V -# client TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 (mutal auth) +# client TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 (mutual auth) -v 3 -l ECDHE-ECDSA-AES128-GCM-SHA256 -c ./certs/ecc/client-secp256k1-cert.pem @@ -65,7 +65,7 @@ -A ./certs/ecc/client-secp256k1-cert.pem -V -# client TLSv1.2 ECDH-ECDSA-AES128-GCM-SHA256 (static - mutal auth) +# client TLSv1.2 ECDH-ECDSA-AES128-GCM-SHA256 (static - mutual auth) -v 3 -l ECDH-ECDSA-AES128-GCM-SHA256 -c ./certs/ecc/client-secp256k1-cert.pem @@ -73,7 +73,7 @@ -A ./certs/ecc/server-secp256k1-cert.pem -C -# server TLSv1.3 TLS13-AES128-GCM-SHA256 (mutal auth) +# server TLSv1.3 TLS13-AES128-GCM-SHA256 (mutual auth) -v 4 -l TLS13-AES128-GCM-SHA256 -c ./certs/ecc/server-secp256k1-cert.pem @@ -81,7 +81,7 @@ -A ./certs/ecc/client-secp256k1-cert.pem -V -# client TLSv1.3 TLS13-AES128-GCM-SHA256 (mutal auth) +# client TLSv1.3 TLS13-AES128-GCM-SHA256 (mutual auth) -v 4 -l TLS13-AES128-GCM-SHA256 -c ./certs/ecc/client-secp256k1-cert.pem @@ -140,7 +140,7 @@ -A ./certs/ecc/client-bp256r1-cert.pem -V -# client TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 (mutal auth) +# client TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 (mutual auth) -v 3 -l ECDHE-ECDSA-AES128-GCM-SHA256 -c ./certs/ecc/client-bp256r1-cert.pem @@ -156,7 +156,7 @@ -A ./certs/ecc/client-bp256r1-cert.pem -V -# client TLSv1.2 ECDH-ECDSA-AES128-GCM-SHA256 (static - mutal auth) +# client TLSv1.2 ECDH-ECDSA-AES128-GCM-SHA256 (static - mutual auth) -v 3 -l ECDH-ECDSA-AES128-GCM-SHA256 -c ./certs/ecc/client-bp256r1-cert.pem @@ -164,7 +164,7 @@ -A ./certs/ecc/server-bp256r1-cert.pem -C -# server TLSv1.3 TLS13-AES128-GCM-SHA256 (mutal auth) +# server TLSv1.3 TLS13-AES128-GCM-SHA256 (mutual auth) -v 4 -l TLS13-AES128-GCM-SHA256 -c ./certs/ecc/server-bp256r1-cert.pem @@ -172,7 +172,7 @@ -A ./certs/ecc/client-bp256r1-cert.pem -V -# client TLSv1.3 TLS13-AES128-GCM-SHA256 (mutal auth) +# client TLSv1.3 TLS13-AES128-GCM-SHA256 (mutual auth) -v 4 -l TLS13-AES128-GCM-SHA256 -c ./certs/ecc/client-bp256r1-cert.pem @@ -180,6 +180,52 @@ -A ./certs/ecc/server-bp256r1-cert.pem -C +# server TLSv1.3 TLS13-AES128-GCM-SHA256 +-v 4 +-l TLS13-AES128-GCM-SHA256 +-c ./certs/ecc/server-bp256r1-cert.pem +-k ./certs/ecc/bp256r1-key.pem +-d + +# client TLSv1.3 TLS13-AES128-GCM-SHA256 (brainpool key share) +-v 4 +-l TLS13-AES128-GCM-SHA256 +-A ./certs/ecc/server-bp256r1-cert.pem +-x +-C +--bpKs + +# server TLSv1.3 TLS13-AES128-GCM-SHA256 +-v 4 +-l "TLS13-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256" +-c ./certs/ecc/server-bp256r1-cert.pem +-k ./certs/ecc/bp256r1-key.pem +-d + +# client TLSv1.3 TLS13-AES128-GCM-SHA256 (brainpool key share; downgrade) +-v d +-l "TLS13-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256" +-A ./certs/ecc/server-bp256r1-cert.pem +-x +-C +--bpKs +-7 3 + +# server TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-c ./certs/ecc/server-bp256r1-cert.pem +-k ./certs/ecc/bp256r1-key.pem +-d + +# client TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 (brainpool key share) +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-A ./certs/ecc/server-bp256r1-cert.pem +-x +-C +--bpKs + # -- SECP256K1 without OID inside PKCS#8 -- # server TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 -v 3 diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 037811e32..00fd901e8 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1761,6 +1761,9 @@ enum Misc { RSA_PSS_PSS_SHA256_MINOR = 0x09, RSA_PSS_PSS_SHA384_MINOR = 0x0A, RSA_PSS_PSS_SHA512_MINOR = 0x0B, + ECDSA_BRAINPOOLP256R1TLS13_SHA256_MINOR = 0x1A, + ECDSA_BRAINPOOLP384R1TLS13_SHA384_MINOR = 0x1B, + ECDSA_BRAINPOOLP512R1TLS13_SHA512_MINOR = 0x1C, ED25519_SA_MAJOR = 8, /* Most significant byte for ED25519 */ ED25519_SA_MINOR = 7, /* Least significant byte for ED25519 */ @@ -1884,7 +1887,7 @@ WOLFSSL_LOCAL int NamedGroupIsPqcHybrid(int group); */ #define WOLFSSL_MAX_SIGALGO 128 #else - #define WOLFSSL_MAX_SIGALGO 38 + #define WOLFSSL_MAX_SIGALGO 44 #endif #endif @@ -2378,7 +2381,8 @@ typedef struct CipherSuite { #define InitSuitesHashSigAlgo wolfSSL_InitSuitesHashSigAlgo #endif WOLFSSL_TEST_VIS void InitSuitesHashSigAlgo(byte* hashSigAlgo, int have, - int tls1_2, int keySz, word16* len); + int tls1_2, int tls1_3, int keySz, + word16* len); WOLFSSL_LOCAL int AllocateCtxSuites(WOLFSSL_CTX* ctx); WOLFSSL_LOCAL int AllocateSuites(WOLFSSL* ssl); WOLFSSL_LOCAL void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, @@ -3399,6 +3403,7 @@ WOLFSSL_LOCAL int TLSX_ValidateSupportedCurves(const WOLFSSL* ssl, byte first, byte second, word32* ecdhCurveOID); WOLFSSL_LOCAL int TLSX_SupportedCurve_CheckPriority(WOLFSSL* ssl); WOLFSSL_LOCAL int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl); +WOLFSSL_LOCAL int TLSX_SupportedCurve_IsSupported(WOLFSSL* ssl, word16 name); #endif WOLFSSL_LOCAL int TLSX_SupportedCurve_Preferred(WOLFSSL* ssl, int checkSupported); @@ -4316,6 +4321,7 @@ enum SignatureAlgorithm { dilithium_level5_sa_algo = 16, sm2_sa_algo = 17, any_sa_algo = 18, + ecc_brainpool_sa_algo = 19, invalid_sa_algo = 255 }; diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index ba8f56ca0..7b5b76d06 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -4621,6 +4621,9 @@ enum { WOLFSSL_ECC_BRAINPOOLP512R1 = 28, WOLFSSL_ECC_X25519 = 29, WOLFSSL_ECC_X448 = 30, + WOLFSSL_ECC_BRAINPOOLP256R1TLS13 = 31, + WOLFSSL_ECC_BRAINPOOLP384R1TLS13 = 32, + WOLFSSL_ECC_BRAINPOOLP512R1TLS13 = 33, WOLFSSL_ECC_SM2P256V1 = 41, WOLFSSL_ECC_MAX = 41, WOLFSSL_ECC_MAX_AVAIL = 46,