Skip to content

Commit a462398

Browse files
committed
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".
1 parent 467d6dd commit a462398

8 files changed

Lines changed: 279 additions & 23 deletions

File tree

examples/benchmark/tls_bench.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,9 @@ static struct group_info groups[] = {
286286
{ WOLFSSL_ECC_BRAINPOOLP512R1, "ECC_BRAINPOOLP512R1" },
287287
{ WOLFSSL_ECC_X25519, "ECC_X25519" },
288288
{ WOLFSSL_ECC_X448, "ECC_X448" },
289+
{ WOLFSSL_ECC_BRAINPOOLP256R1TLS13, "ECC_BRAINPOOLP256R1TLS13" },
290+
{ WOLFSSL_ECC_BRAINPOOLP384R1TLS13, "ECC_BRAINPOOLP384R1TLS13" },
291+
{ WOLFSSL_ECC_BRAINPOOLP512R1TLS13, "ECC_BRAINPOOLP512R1TLS13" },
289292
{ WOLFSSL_FFDHE_2048, "FFDHE_2048" },
290293
{ WOLFSSL_FFDHE_3072, "FFDHE_3072" },
291294
{ WOLFSSL_FFDHE_4096, "FFDHE_4096" },

examples/client/client.c

Lines changed: 88 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -308,14 +308,16 @@ static void ShowVersions(void)
308308
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
309309
#define MAX_GROUP_NUMBER 4
310310
static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
311-
int useX448, int usePqc, char* pqcAlg, int setGroups)
311+
int useX448, int useBp, int usePqc, char* pqcAlg,
312+
int setGroups)
312313
{
313314
int ret;
314315
int groups[MAX_GROUP_NUMBER] = {0};
315316
int count = 0;
316317

317318
(void)useX25519;
318319
(void)useX448;
320+
(void)useBp;
319321
(void)usePqc;
320322
(void)pqcAlg;
321323

@@ -349,6 +351,23 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
349351
else
350352
err_sys("unable to use curve x448");
351353
} while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
354+
#endif
355+
}
356+
else if (useBp) {
357+
#if defined(HAVE_ECC) && defined(HAVE_ECC_BRAINPOOL)
358+
#if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
359+
do {
360+
ret = wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_BRAINPOOLP256R1TLS13);
361+
if (ret == WOLFSSL_SUCCESS)
362+
groups[count++] = WOLFSSL_ECC_BRAINPOOLP256R1TLS13;
363+
#ifdef WOLFSSL_ASYNC_CRYPT
364+
else if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
365+
wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
366+
#endif
367+
else
368+
err_sys("unable to use curve brainpoolp256r1");
369+
} while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
370+
#endif
352371
#endif
353372
}
354373
else {
@@ -587,7 +606,7 @@ static const char* client_bench_conmsg[][5] = {
587606
static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
588607
int dtlsUDP, int dtlsSCTP, int benchmark, int resumeSession, int useX25519,
589608
int useX448, int usePqc, char* pqcAlg, int helloRetry, int onlyKeyShare,
590-
int version, int earlyData)
609+
int version, int earlyData, int useBp)
591610
{
592611
/* time passed in number of connects give average */
593612
int times = benchmark, skip = (int)((double)times * 0.1);
@@ -610,6 +629,7 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
610629
(void)onlyKeyShare;
611630
(void)version;
612631
(void)earlyData;
632+
(void)useBp;
613633

614634
while (loops--) {
615635
#ifndef NO_SESSION_CACHE
@@ -636,7 +656,7 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
636656
else if (version >= 4) {
637657
if (!helloRetry)
638658
SetKeyShare(ssl, onlyKeyShare, useX25519, useX448,
639-
usePqc, pqcAlg, 1);
659+
useBp, usePqc, pqcAlg, 1);
640660
else
641661
wolfSSL_NoKeyShares(ssl);
642662
}
@@ -717,7 +737,7 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
717737
static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port,
718738
int dtlsUDP, int dtlsSCTP, int block, size_t throughput, int useX25519,
719739
int useX448, int usePqc, char* pqcAlg, int exitWithRet, int version,
720-
int onlyKeyShare)
740+
int onlyKeyShare, int useBp)
721741
{
722742
double start, conn_time = 0, tx_time = 0, rx_time = 0;
723743
SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
@@ -738,11 +758,12 @@ static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port,
738758
(void)useX448;
739759
(void)usePqc;
740760
(void)pqcAlg;
761+
(void)useBp;
741762
(void)version;
742763
(void)onlyKeyShare;
743764
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
744765
if (version >= 4) {
745-
SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, usePqc,
766+
SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, useBp, usePqc,
746767
pqcAlg, 1);
747768
}
748769
#endif
@@ -1150,7 +1171,7 @@ static int ClientWriteRead(WOLFSSL* ssl, const char* msg, int msgSz,
11501171
/* 4. add the same message into Japanese section */
11511172
/* (will be translated later) */
11521173
/* 5. add printf() into suitable position of Usage() */
1153-
static const char* client_usage_msg[][78] = {
1174+
static const char* client_usage_msg[][79] = {
11541175
/* English */
11551176
{
11561177
" NOTE: All files relative to wolfSSL home dir\n", /* 0 */
@@ -1398,10 +1419,13 @@ static const char* client_usage_msg[][78] = {
13981419
"--files-are-der Specified files are in DER, not PEM format\n", /* 75 */
13991420
#ifdef WOLFSSL_SYS_CRYPTO_POLICY
14001421
"--crypto-policy <path to crypto policy file>\n", /* 76 */
1422+
#endif
1423+
#ifdef HAVE_ECC_BRAINPOOL
1424+
"--bpKs Use Brainpool ECC group for key share\n", /* 77 */
14011425
#endif
14021426
"\n"
14031427
"For simpler wolfSSL TLS client examples, visit\n"
1404-
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 77 */
1428+
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 78 */
14051429
NULL,
14061430
},
14071431
#ifndef NO_MULTIBYTE_PRINT
@@ -1653,11 +1677,14 @@ static const char* client_usage_msg[][78] = {
16531677
"--files-are-der Specified files are in DER, not PEM format\n", /* 75 */
16541678
#ifdef WOLFSSL_SYS_CRYPTO_POLICY
16551679
"--crypto-policy <path to crypto policy file>\n", /* 76 */
1680+
#endif
1681+
#ifdef HAVE_ECC_BRAINPOOL
1682+
"--bpKs Use Brainpool ECC group for key share\n", /* 77 */
16561683
#endif
16571684
"\n"
16581685
"より簡単なwolfSSL TLS クライアントの例については"
16591686
"下記にアクセスしてください\n"
1660-
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 77 */
1687+
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 78 */
16611688
NULL,
16621689
},
16631690
#endif
@@ -1892,6 +1919,9 @@ static void Usage(void)
18921919
#endif
18931920
#ifdef HAVE_RPK
18941921
printf("%s", msg[++msgid]); /* --rpk */
1922+
#endif
1923+
#ifdef HAVE_ECC_BRAINPOOL
1924+
printf("%s", msg[++msgid]); /* --bpKs */
18951925
#endif
18961926
printf("%s", msg[++msgid]); /* --files-are-der */
18971927
printf("%s", msg[++msgid]); /* Documentation Hint */
@@ -2078,6 +2108,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
20782108
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
20792109
{ "crypto-policy", 1, 269 },
20802110
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
2111+
#ifdef HAVE_ECC_BRAINPOOL
2112+
{ "bpKs", 0, 270 },
2113+
#endif
20812114
{ 0, 0, 0 }
20822115
};
20832116
#endif
@@ -2187,6 +2220,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
21872220
#endif
21882221
int useX25519 = 0;
21892222
int useX448 = 0;
2223+
int useBrainpool = 0;
21902224
int usePqc = 0;
21912225
char* pqcAlg = NULL;
21922226
int exitWithRet = 0;
@@ -2311,6 +2345,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
23112345
(void)earlyData;
23122346
(void)useX25519;
23132347
(void)useX448;
2348+
(void)useBrainpool;
23142349
(void)helloRetry;
23152350
(void)onlyKeyShare;
23162351
(void)useSupCurve;
@@ -2959,6 +2994,15 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
29592994
policy = myoptarg;
29602995
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
29612996
break;
2997+
#ifdef HAVE_ECC_BRAINPOOL
2998+
case 270:
2999+
useBrainpool = 1;
3000+
#if defined(HAVE_ECC) && defined(WOLFSSL_TLS13) && \
3001+
defined(HAVE_SUPPORTED_CURVES)
3002+
onlyKeyShare = 2;
3003+
#endif
3004+
break;
3005+
#endif
29623006

29633007
default:
29643008
Usage();
@@ -3680,6 +3724,37 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
36803724
}
36813725
#endif /* HAVE_CURVE448 */
36823726
#ifdef HAVE_ECC
3727+
#ifdef HAVE_ECC_BRAINPOOL
3728+
if (useBrainpool) {
3729+
if (version == 4) {
3730+
if (wolfSSL_CTX_UseSupportedCurve(ctx,
3731+
WOLFSSL_ECC_BRAINPOOLP256R1TLS13)
3732+
!= WOLFSSL_SUCCESS) {
3733+
err_sys("unable to support brainpoolp256r1tls13");
3734+
}
3735+
}
3736+
else if (version == CLIENT_DOWNGRADE_VERSION) {
3737+
if (wolfSSL_CTX_UseSupportedCurve(ctx,
3738+
WOLFSSL_ECC_BRAINPOOLP256R1TLS13)
3739+
!= WOLFSSL_SUCCESS) {
3740+
err_sys("unable to support brainpoolp256r1tls13");
3741+
}
3742+
if (minVersion <= 3) {
3743+
if (wolfSSL_CTX_UseSupportedCurve(ctx,
3744+
WOLFSSL_ECC_BRAINPOOLP256R1)
3745+
!= WOLFSSL_SUCCESS) {
3746+
err_sys("unable to support brainpoolp256r1");
3747+
}
3748+
}
3749+
}
3750+
else {
3751+
if (wolfSSL_CTX_UseSupportedCurve(ctx, WOLFSSL_ECC_BRAINPOOLP256R1)
3752+
!= WOLFSSL_SUCCESS) {
3753+
err_sys("unable to support brainpoolp256r1");
3754+
}
3755+
}
3756+
}
3757+
#endif /* HAVE_ECC_BRAINPOOL */
36833758
if (useSupCurve) {
36843759
#if !defined(NO_ECC_SECP) && \
36853760
(defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES))
@@ -3728,7 +3803,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
37283803
ClientBenchmarkConnections(ctx, host, port, dtlsUDP, dtlsSCTP,
37293804
benchmark, resumeSession, useX25519,
37303805
useX448, usePqc, pqcAlg, helloRetry,
3731-
onlyKeyShare, version, earlyData);
3806+
onlyKeyShare, version, earlyData,
3807+
useBrainpool);
37323808
wolfSSL_CTX_free(ctx); ctx = NULL;
37333809
XEXIT_T(EXIT_SUCCESS);
37343810
}
@@ -3738,7 +3814,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
37383814
ClientBenchmarkThroughput(ctx, host, port, dtlsUDP, dtlsSCTP,
37393815
block, throughput, useX25519, useX448,
37403816
usePqc, pqcAlg, exitWithRet, version,
3741-
onlyKeyShare);
3817+
onlyKeyShare, useBrainpool);
37423818
wolfSSL_CTX_free(ctx); ctx = NULL;
37433819
if (((func_args*)args)->return_code != EXIT_SUCCESS && !exitWithRet)
37443820
XEXIT_T(EXIT_SUCCESS);
@@ -3872,8 +3948,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
38723948

38733949
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
38743950
if (!helloRetry && (version >= 4 || version <= -4)) {
3875-
SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, usePqc,
3876-
pqcAlg, 0);
3951+
SetKeyShare(ssl, onlyKeyShare, useX25519, useX448,
3952+
useBrainpool, usePqc, pqcAlg, 0);
38773953
}
38783954
else {
38793955
wolfSSL_NoKeyShares(ssl);

examples/server/server.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ static struct group_info group_id_to_text[] = {
104104
{ WOLFSSL_ECC_BRAINPOOLP256R1, "BRAINPOOLP256R1" },
105105
{ WOLFSSL_ECC_BRAINPOOLP384R1, "BRAINPOOLP384R1" },
106106
{ WOLFSSL_ECC_BRAINPOOLP512R1, "BRAINPOOLP512R1" },
107+
{ WOLFSSL_ECC_BRAINPOOLP256R1TLS13, "BRAINPOOLP256R1TLS13" },
108+
{ WOLFSSL_ECC_BRAINPOOLP384R1TLS13, "BRAINPOOLP384R1TLS13" },
109+
{ WOLFSSL_ECC_BRAINPOOLP512R1TLS13, "BRAINPOOLP512R1TLS13" },
107110
{ 0, NULL }
108111
};
109112
#endif /* CAN_FORCE_CURVE && HAVE_ECC */

src/sniffer.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3364,13 +3364,30 @@ static int ProcessKeyShare(KeyShareInfo* info, const byte* input, int len,
33643364
info->curve_id = ECC_SM2P256V1;
33653365
break;
33663366
#endif /* WOLFSSL_SM2 */
3367+
#ifdef HAVE_ECC_BRAINPOOL
3368+
case WOLFSSL_ECC_BRAINPOOLP256R1TLS13:
3369+
info->curve_id = ECC_BRAINPOOLP256R1;
3370+
break;
3371+
#endif /* HAVE_ECC_BRAINPOOL */
33673372
#endif
33683373
#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
33693374
#ifndef NO_ECC_SECP
33703375
case WOLFSSL_ECC_SECP384R1:
33713376
info->curve_id = ECC_SECP384R1;
33723377
break;
33733378
#endif /* !NO_ECC_SECP */
3379+
#ifdef HAVE_ECC_BRAINPOOL
3380+
case WOLFSSL_ECC_BRAINPOOLP384R1TLS13:
3381+
info->curve_id = ECC_BRAINPOOLP384R1;
3382+
break;
3383+
#endif /* HAVE_ECC_BRAINPOOL */
3384+
#endif
3385+
#if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
3386+
#ifdef HAVE_ECC_BRAINPOOL
3387+
case WOLFSSL_ECC_BRAINPOOLP512R1TLS13:
3388+
info->curve_id = ECC_BRAINPOOLP512R1;
3389+
break;
3390+
#endif /* HAVE_ECC_BRAINPOOL */
33743391
#endif
33753392
#if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
33763393
#ifndef NO_ECC_SECP

src/ssl.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3741,6 +3741,9 @@ static int isValidCurveGroup(word16 name)
37413741
case WOLFSSL_ECC_SM2P256V1:
37423742
case WOLFSSL_ECC_X25519:
37433743
case WOLFSSL_ECC_X448:
3744+
case WOLFSSL_ECC_BRAINPOOLP256R1TLS13:
3745+
case WOLFSSL_ECC_BRAINPOOLP384R1TLS13:
3746+
case WOLFSSL_ECC_BRAINPOOLP512R1TLS13:
37443747

37453748
case WOLFSSL_FFDHE_2048:
37463749
case WOLFSSL_FFDHE_3072:

0 commit comments

Comments
 (0)