Support Brainpool ECC curve TLS 1.3 key exchange

When both TLS 1.3 and Brainpool curves are enabled, three new groups can
be used for the ECDHE key exchange according to RFC 8734:
* WOLFSSL_ECC_BRAINPOOLP256R1TLS13 (31)
* WOLFSSL_ECC_BRAINPOOLP384R1TLS13 (32)
* WOLFSSL_ECC_BRAINPOOLP512R1TLS13 (33)

Also ensure that the existing TLS 1.2 curves are sent properly.

The TLS client application is updated to support handshakes via
Brainpool curves using the new argument "--bpKs".
This commit is contained in:
Tobias Frauenschläger
2026-01-19 18:33:48 +01:00
parent 467d6dd338
commit a462398387
8 changed files with 279 additions and 23 deletions

View File

@@ -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" },

View File

@@ -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 <path to crypto policy file>\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 <path to crypto policy file>\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);

View File

@@ -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 */

View File

@@ -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

View File

@@ -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:

126
src/tls.c
View File

@@ -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
@@ -8154,7 +8157,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 +8172,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 +9296,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 +9309,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 +10671,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 +10684,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 +14277,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 +14307,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 +14353,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,

View File

@@ -180,6 +180,53 @@
-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

View File

@@ -4619,6 +4619,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,