From 0b47811c46087612a6c237b8a4cb341e9f870c1c Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Mon, 9 Apr 2018 13:53:05 +1000 Subject: [PATCH] Changes for interop and performance Changes made to test.h to allow interop of PSK with OpenSSL. Changes to allow server to pre-generate key share and perform other operations at later time. Fix ChaCha20 code header to have bigger state to support assembly code for AVX1. Fix Curve25519 code to use define instead. Change Curve25519 to memset all object data on init. Change Poly1305 to put both sizes into one buffer to avoid a second call to wc_Poly1305Update(). Added WOLFSSL_START and WOLFSSL_END API and calls to show time of protocol message function enter and leave to analyse performance differences. Moved Curve25519 code in KeyShare extension out of general ECC code. --- examples/client/client.c | 132 +++++++---- examples/server/server.c | 128 +++++++++- examples/server/server.h | 5 +- scripts/tls13.test | 6 +- src/internal.c | 159 +++++++++++-- src/tls.c | 452 +++++++++++++++++++++++------------- src/tls13.c | 77 +++++- tests/api.c | 4 +- wolfcrypt/src/chacha.c | 7 - wolfcrypt/src/curve25519.c | 48 ++-- wolfcrypt/src/logging.c | 117 ++++++++++ wolfcrypt/src/poly1305.c | 10 +- wolfssl/internal.h | 15 +- wolfssl/test.h | 58 +++-- wolfssl/wolfcrypt/chacha.h | 11 + wolfssl/wolfcrypt/logging.h | 47 ++++ 16 files changed, 959 insertions(+), 317 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index 377cb162c..d5bc0d544 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -193,10 +193,10 @@ static void ShowVersions(void) Benchmark = number of connections. */ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, int dtlsUDP, int dtlsSCTP, int benchmark, int resumeSession, int useX25519, - int helloRetry) + int helloRetry, int onlyKeyShare, int version) { /* time passed in number of connects give average */ - int times = benchmark; + int times = benchmark, skip = times * 0.1; int loops = resumeSession ? 2 : 1; int i = 0, err, ret; #ifndef NO_SESSION_CACHE @@ -204,12 +204,14 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, #endif #ifdef WOLFSSL_TLS13 byte* reply[80]; - static const char msg[] = "hello wolfssl!"; + static const char msg[] = "GET /index.html HTTP/1.0\r\n\r\n"; #endif (void)resumeSession; (void)useX25519; (void)helloRetry; + (void)onlyKeyShare; + (void)version; while (loops--) { #ifndef NO_SESSION_CACHE @@ -219,14 +221,56 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, for (i = 0; i < times; i++) { SOCKET_T sockfd; - WOLFSSL* ssl = wolfSSL_new(ctx); + WOLFSSL* ssl; + + if (i == skip) + start = current_time(1); + + ssl = wolfSSL_new(ctx); if (ssl == NULL) err_sys("unable to get SSL object"); - #ifdef WOLFSSL_TLS13 - if (helloRetry) - wolfSSL_NoKeyShares(ssl); - #endif + #ifdef WOLFSSL_TLS13 + if (version >= 4) { + if (!helloRetry) { + WOLFSSL_START(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND); + if (onlyKeyShare == 0 || onlyKeyShare == 2) { + #ifdef HAVE_CURVE25519 + if (useX25519) { + if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519) + != WOLFSSL_SUCCESS) { + err_sys("unable to use curve x25519"); + } + } + else + #endif + #ifdef HAVE_ECC + #if defined(HAVE_ECC256) || defined(HAVE_ALL_CURVES) + if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_SECP256R1) + != WOLFSSL_SUCCESS) { + err_sys("unable to use curve secp256r1"); + } + else + #endif + #endif + { + } + } + if (onlyKeyShare == 0 || onlyKeyShare == 1) { + #ifdef HAVE_FFDHE_2048 + if (wolfSSL_UseKeyShare(ssl, WOLFSSL_FFDHE_2048) + != WOLFSSL_SUCCESS) { + err_sys("unable to use DH 2048-bit parameters"); + } + #endif + } + WOLFSSL_END(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND); + } + else { + wolfSSL_NoKeyShares(ssl); + } + } + #endif tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, ssl); @@ -234,21 +278,7 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, if (benchResume) wolfSSL_set_session(ssl, benchSession); #endif - #ifdef WOLFSSL_TLS13 - #ifdef HAVE_CURVE25519 - #ifndef NO_SESSION_CACHE - if (benchResume) { - } - else - #endif - if (useX25519) { - if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519) - != WOLFSSL_SUCCESS) { - err_sys("unable to use curve x25519"); - } - } - #endif - #endif + if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) { err_sys("error in setting fd"); } @@ -271,7 +301,7 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, } #ifdef WOLFSSL_TLS13 - if (resumeSession) { + if (version >= 4 && resumeSession && !benchResume) { if (wolfSSL_write(ssl, msg, sizeof(msg)-1) <= 0) err_sys("SSL_write failed"); @@ -280,6 +310,7 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, } #endif + wolfSSL_shutdown(ssl); #ifndef NO_SESSION_CACHE if (i == (times-1) && resumeSession) { @@ -290,7 +321,7 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, CloseSocket(sockfd); } avg = current_time(0) - start; - avg /= times; + avg /= (times - skip); avg *= 1000; /* milliseconds */ #ifndef NO_SESSION_CACHE if (benchResume) @@ -298,6 +329,8 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, else #endif printf("wolfSSL_connect avg took: %8.3f milliseconds\n", avg); + + WOLFSSL_TIME(times); } return EXIT_SUCCESS; @@ -305,7 +338,7 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, /* Measures throughput in kbps. Throughput = number of bytes */ static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, - int dtlsUDP, int dtlsSCTP, int throughput, int useX25519) + int dtlsUDP, int dtlsSCTP, int block, int throughput, int useX25519) { double start, conn_time = 0, tx_time = 0, rx_time = 0; SOCKET_T sockfd; @@ -355,8 +388,8 @@ static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, conn_time = current_time(0) - start; /* Allocate TX/RX buffers */ - tx_buffer = (char*)XMALLOC(TEST_BUFFER_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - rx_buffer = (char*)XMALLOC(TEST_BUFFER_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); + tx_buffer = (char*)XMALLOC(block, NULL, DYNAMIC_TYPE_TMP_BUFFER); + rx_buffer = (char*)XMALLOC(block, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (tx_buffer && rx_buffer) { WC_RNG rng; @@ -370,7 +403,7 @@ static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, int xfer_bytes; /* Generate random data to send */ - ret = wc_RNG_GenerateBlock(&rng, (byte*)tx_buffer, TEST_BUFFER_SIZE); + ret = wc_RNG_GenerateBlock(&rng, (byte*)tx_buffer, block); wc_FreeRng(&rng); if(ret != 0) { err_sys("wc_RNG_GenerateBlock failed"); @@ -382,7 +415,7 @@ static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, int len, rx_pos, select_ret; /* Determine packet size */ - len = min(TEST_BUFFER_SIZE, throughput - xfer_bytes); + len = min(block, throughput - xfer_bytes); /* Perform TX */ start = current_time(1); @@ -814,6 +847,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) int useAnon = 0; int sendGET = 0; int benchmark = 0; + int block = TEST_BUFFER_SIZE; int throughput = 0; int doDTLS = 0; int dtlsUDP = 0; @@ -873,8 +907,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) byte disableExtMasterSecret = 0; #endif int helloRetry = 0; -#ifdef WOLFSSL_TLS13 int onlyKeyShare = 0; +#ifdef WOLFSSL_TLS13 int noPskDheKe = 0; #ifdef WOLFSSL_POST_HANDSHAKE_AUTH int postHandAuth = 0; @@ -943,6 +977,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) (void)updateKeysIVs; (void)useX25519; (void)helloRetry; + (void)onlyKeyShare; (void)useBadCert; StackTrap(); @@ -1110,7 +1145,13 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) case 'B' : throughput = atoi(myoptarg); - if (throughput <= 0) { + for (; *myoptarg != '\0'; myoptarg++) { + if (*myoptarg == ',') { + block = atoi(myoptarg + 1); + break; + } + } + if (throughput <= 0 || block <= 0) { Usage(); exit(MY_EX_USAGE); } @@ -1763,11 +1804,20 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif /* HAVE_CURVE25519 && HAVE_SUPPORTED_CURVES */ +#ifdef WOLFSSL_TLS13 + if (noPskDheKe) + wolfSSL_CTX_no_dhe_psk(ctx); +#endif +#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) + if (postHandAuth) + wolfSSL_CTX_allow_post_handshake_auth(ctx); +#endif + if (benchmark) { ((func_args*)args)->return_code = ClientBenchmarkConnections(ctx, host, port, dtlsUDP, dtlsSCTP, benchmark, resumeSession, useX25519, - helloRetry); + helloRetry, onlyKeyShare, version); wolfSSL_CTX_free(ctx); exit(EXIT_SUCCESS); } @@ -1775,7 +1825,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if(throughput) { ((func_args*)args)->return_code = ClientBenchmarkThroughput(ctx, host, port, dtlsUDP, dtlsSCTP, - throughput, useX25519); + block, throughput, useX25519); wolfSSL_CTX_free(ctx); exit(EXIT_SUCCESS); } @@ -1795,15 +1845,6 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif - #ifdef WOLFSSL_TLS13 - if (noPskDheKe) - wolfSSL_CTX_no_dhe_psk(ctx); - #endif - #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) - if (postHandAuth) - wolfSSL_CTX_allow_post_handshake_auth(ctx); - #endif - #if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL) fprintf(stderr, "Before creating SSL\n"); if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1) @@ -2270,6 +2311,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif #ifdef WOLFSSL_TLS13 + if (!helloRetry) { #ifdef HAVE_CURVE25519 if (useX25519) { if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519) != WOLFSSL_SUCCESS) { @@ -2294,6 +2336,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) err_sys("unable to use DH 2048-bit parameters"); } #endif + } + else { + wolfSSL_NoKeyShares(ssl); + } #endif #ifndef WOLFSSL_CALLBACKS diff --git a/examples/server/server.c b/examples/server/server.c index ddd7e589f..bc4591b64 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -186,14 +186,15 @@ static int NonBlockingSSL_Accept(SSL* ssl) } /* Echo number of bytes specified by -e arg */ -int ServerEchoData(SSL* ssl, int clientfd, int echoData, int throughput) +int ServerEchoData(SSL* ssl, int clientfd, int echoData, int block, + int throughput) { int ret = 0, err; double start = 0, rx_time = 0, tx_time = 0; int xfer_bytes = 0, select_ret, len, rx_pos; char* buffer; - buffer = (char*)malloc(TEST_BUFFER_SIZE); + buffer = (char*)malloc(block); if (!buffer) { err_sys_ex(runWithErrors, "Server buffer malloc failed"); } @@ -204,7 +205,7 @@ int ServerEchoData(SSL* ssl, int clientfd, int echoData, int throughput) select_ret = tcp_select(clientfd, 1); /* Timeout=1 second */ if (select_ret == TEST_RECV_READY) { - len = min(TEST_BUFFER_SIZE, throughput - xfer_bytes); + len = min(block, throughput - xfer_bytes); rx_pos = 0; if (throughput) { @@ -414,15 +415,27 @@ static void Usage(void) printf("-C The number of connections to accept, default: 1\n"); printf("-H Internal tests [defCipherList, badCert]\n"); #ifdef WOLFSSL_TLS13 - printf("-K Key Exchange for PSK not using (EC)DHE\n"); printf("-U Update keys and IVs before sending\n"); + printf("-K Key Exchange for PSK not using (EC)DHE\n"); +#ifndef NO_DH + printf("-y Pre-generate Key Share using FFDHE_2048 only\n"); +#endif +#ifdef HAVE_ECC + printf("-Y Pre-generate Key Share using P-256 only \n"); +#endif +#ifdef HAVE_CURVE25519 + printf("-t Pre-generate Key share using Curve25519 only\n"); +#endif +#ifdef HAVE_SESSION_TICKET + printf("-T Do not generate session ticket\n"); +#endif #ifdef WOLFSSL_POST_HANDSHAKE_AUTH printf("-Q Request certificate from client post-handshake\n"); #endif #ifdef WOLFSSL_SEND_HRR_COOKIE printf("-J Server sends Cookie Extension containing state\n"); #endif -#endif +#endif /* WOLFSSL_TLS13 */ #ifdef WOLFSSL_EARLY_DATA printf("-0 Early data read from client (0-RTT handshake)\n"); #endif @@ -471,7 +484,11 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) int resume = 0; int resumeCount = 0; int loops = 1; +#ifdef WOLFSSL_FUNC_TIME + int cnt = 0; +#endif int echoData = 0; + int block = TEST_BUFFER_SIZE; int throughput = 0; int minDhKeyBits = DEFAULT_MIN_DHKEY_BITS; short minRsaKeyBits = DEFAULT_MIN_RSAKEY_BITS; @@ -544,6 +561,11 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) WOLFSSL_MEM_STATS mem_stats; #endif #endif +#ifdef WOLFSSL_TLS13 + int onlyKeyShare = 0; + int noTicket = 0; +#endif + int useX25519 = 0; ((func_args*)args)->return_code = -1; /* error state */ @@ -570,6 +592,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) (void)updateKeysIVs; (void)mcastID; (void)useBadCert; + (void)useX25519; #ifdef CYASSL_TIRTOS fdOpenSession(Task_self()); @@ -578,10 +601,10 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #ifdef WOLFSSL_VXWORKS useAnyAddr = 1; #else - /* Not Used: h, m, t, y, z, F, M, T, V, W, X, Y */ + /* Not Used: h, m, z, F, M, T, V, W, X */ while ((ch = mygetopt(argc, argv, "?" - "abc:defgijk:l:nop:q:rsuv:wx" - "A:B:C:D:E:GH:IJKL:NO:PQR:S:UYZ:" + "abc:defgijk:l:nop:q:rstuv:wxy" + "A:B:C:D:E:GH:IJKL:NO:PQR:S:TUYZ:" "03:")) != -1) { switch (ch) { case '?' : @@ -781,7 +804,13 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) case 'B': throughput = atoi(myoptarg); - if (throughput <= 0) { + for (; *myoptarg != '\0'; myoptarg++) { + if (*myoptarg == ',') { + block = atoi(myoptarg + 1); + break; + } + } + if (throughput <= 0 || block <= 0) { Usage(); exit(MY_EX_USAGE); } @@ -803,12 +832,39 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) useWebServerMsg = 1; break; + case 'y' : + #if defined(WOLFSSL_TLS13) && !defined(NO_DH) + onlyKeyShare = 1; + #endif + break; + + case 'Y' : + #if defined(WOLFSSL_TLS13) && defined(HAVE_ECC) + onlyKeyShare = 2; + #endif + break; + + case 't' : + #ifdef HAVE_CURVE25519 + useX25519 = 1; + #if defined(WOLFSSL_TLS13) && defined(HAVE_ECC) + onlyKeyShare = 2; + #endif + #endif + break; + case 'K' : #ifdef WOLFSSL_TLS13 noPskDheKe = 1; #endif break; + case 'T' : + #if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) + noTicket = 1; + #endif + break; + case 'U' : #ifdef WOLFSSL_TLS13 updateKeysIVs = 1; @@ -1154,6 +1210,8 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #ifdef WOLFSSL_TLS13 if (noPskDheKe) wolfSSL_CTX_no_dhe_psk(ctx); + if (noTicket) + wolfSSL_CTX_no_ticket_TLSv13(ctx); #endif while (1) { @@ -1275,6 +1333,43 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) SetupPkCallbackContexts(ssl, &pkCbInfo); #endif + #ifdef WOLFSSL_TLS13 + if (version >= 4) { + WOLFSSL_START(WC_FUNC_CLIENT_KEY_EXCHANGE_DO); + if (onlyKeyShare == 2) { + if (useX25519 == 1) { + #ifdef HAVE_CURVE25519 + if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519) + != WOLFSSL_SUCCESS) { + err_sys("unable to use curve x25519"); + } + #endif + } + else + { + #ifdef HAVE_ECC + #if defined(HAVE_ECC256) || defined(HAVE_ALL_CURVES) + if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_SECP256R1) + != WOLFSSL_SUCCESS) { + err_sys("unable to use curve secp256r1"); + } + #endif + #endif + } + } + else if (onlyKeyShare == 1) { + #ifdef HAVE_FFDHE_2048 + if (wolfSSL_UseKeyShare(ssl, WOLFSSL_FFDHE_2048) + != WOLFSSL_SUCCESS) { + err_sys("unable to use DH 2048-bit parameters"); + } + #endif + } + WOLFSSL_END(WC_FUNC_CLIENT_KEY_EXCHANGE_DO); + } + #endif + + /* do accept */ readySignal = ((func_args*)args)->signal; if (readySignal) { @@ -1470,11 +1565,15 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #endif if (echoData == 0 && throughput == 0) { + ServerRead(ssl, input, sizeof(input)-1); + err = SSL_get_error(ssl, 0); + } + + if (err != WOLFSSL_ERROR_ZERO_RETURN && echoData == 0 && + throughput == 0) { const char* write_msg; int write_msg_sz; - ServerRead(ssl, input, sizeof(input)-1); - #ifdef WOLFSSL_TLS13 if (updateKeysIVs) wolfSSL_update_keys(ssl); @@ -1503,7 +1602,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #endif } else { - ServerEchoData(ssl, clientfd, echoData, throughput); + ServerEchoData(ssl, clientfd, echoData, block, throughput); } #if defined(WOLFSSL_MDK_SHELL) && defined(HAVE_MDK_RTX) @@ -1542,11 +1641,16 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) } resumeCount = 0; +#ifdef WOLFSSL_FUNC_TIME + cnt++; +#endif if (loops > 0 && --loops == 0) { break; /* out of while loop, done with normal and resume option */ } } /* while(1) */ + WOLFSSL_TIME(cnt); + #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) wolfSSL_CTX_DisableOCSPStapling(ctx); diff --git a/examples/server/server.h b/examples/server/server.h index 51053fe9b..7e6ab6648 100644 --- a/examples/server/server.h +++ b/examples/server/server.h @@ -26,9 +26,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args); -/* Echo bytes using buffer of TEST_BUFFER_SIZE until [echoData] bytes are complete. */ +/* Echo bytes using buffer of blockSize until [echoData] bytes are complete. */ /* If [bechmarkThroughput] set the statistcs will be output at the end */ -int ServerEchoData(WOLFSSL* ssl, int clientfd, int echoData, int benchmarkThroughput); +int ServerEchoData(WOLFSSL* ssl, int clientfd, int echoData, int blockSize, + int benchmarkThroughput); #endif /* WOLFSSL_SERVER_H */ diff --git a/scripts/tls13.test b/scripts/tls13.test index 719515ac0..4136c85e4 100755 --- a/scripts/tls13.test +++ b/scripts/tls13.test @@ -437,8 +437,8 @@ if [ $RESULT -ne 0 ]; then fi echo "" -# TLS 1.3 server / TLS 1.3 client don't use (EC)DHE with PSK. -echo -e "\n\nTLS v1.3 KeyUpdate" +# TLS 1.3 server / TLS 1.3 client - don't use (EC)DHE with PSK. +echo -e "\n\nTLS v1.3 PSK without (EC)DHE" port=0 ./examples/server/server -v 4 -r -R $ready_file -p $port & server_pid=$! @@ -447,7 +447,7 @@ create_port RESULT=$? remove_ready_file if [ $RESULT -ne 0 ]; then - echo -e "\n\nIssue with TLS v1.3 KeyUpdate" + echo -e "\n\nIssue with TLS v1.3 PSK without (EC)DHE" do_cleanup exit 1 fi diff --git a/src/internal.c b/src/internal.c index e46c31af0..c96189994 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9387,7 +9387,17 @@ exit_ppc: static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 size) { - return ProcessPeerCerts(ssl, input, inOutIdx, size); + int ret; + + WOLFSSL_START(WC_FUNC_CERTIFICATE_DO); + WOLFSSL_ENTER("DoCertificateVerify"); + + ret = ProcessPeerCerts(ssl, input, inOutIdx, size); + + WOLFSSL_LEAVE("DoCertificateVerify", ret); + WOLFSSL_END(WC_FUNC_CERTIFICATE_DO); + + return ret; } /* handle processing of certificate_status (22) */ @@ -9398,6 +9408,9 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, byte status_type; word32 status_length; + WOLFSSL_START(WC_FUNC_CERTIFICATE_STATUS_DO); + WOLFSSL_ENTER("DoCertificateStatus"); + if (size < ENUM_LEN + OPAQUE24_LEN) return BUFFER_ERROR; @@ -9595,6 +9608,9 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, if (ret != 0) SendAlert(ssl, alert_fatal, bad_certificate_status_response); + WOLFSSL_LEAVE("DoCertificateStatus", ret); + WOLFSSL_END(WC_FUNC_CERTIFICATE_STATUS_DO); + return ret; } @@ -9638,6 +9654,9 @@ int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size, { word32 finishedSz = (ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ); + WOLFSSL_START(WC_FUNC_FINISHED_DO); + WOLFSSL_ENTER("DoFinished"); + if (finishedSz != size) return BUFFER_ERROR; @@ -9705,6 +9724,9 @@ int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size, } } + WOLFSSL_LEAVE("DoFinished", 0); + WOLFSSL_END(WC_FUNC_FINISHED_DO); + return 0; } @@ -13431,6 +13453,9 @@ int SendFinished(WOLFSSL* ssl) int headerSz = HANDSHAKE_HEADER_SZ; int outputSz; + WOLFSSL_START(WC_FUNC_FINISHED_SEND); + WOLFSSL_ENTER("SendFinished"); + /* setup encrypt keys */ if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0) return ret; @@ -13525,7 +13550,12 @@ int SendFinished(WOLFSSL* ssl) ssl->buffers.outputBuffer.length += sendSz; - return SendBuffered(ssl); + ret = SendBuffered(ssl); + + WOLFSSL_LEAVE("SendFinished", ret); + WOLFSSL_END(WC_FUNC_FINISHED_SEND); + + return ret; } @@ -13537,6 +13567,9 @@ int SendCertificate(WOLFSSL* ssl) word32 certSz, certChainSz, headerSz, listSz, payloadSz; word32 length, maxFragment; + WOLFSSL_START(WC_FUNC_CERTIFICATE_SEND); + WOLFSSL_ENTER("SendCertificate"); + if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher) return 0; /* not needed */ @@ -13784,6 +13817,10 @@ int SendCertificate(WOLFSSL* ssl) ssl->options.serverState = SERVER_CERT_COMPLETE; } } + + WOLFSSL_LEAVE("SendCertificate", ret); + WOLFSSL_END(WC_FUNC_CERTIFICATE_SEND); + return ret; } @@ -13802,6 +13839,9 @@ int SendCertificateRequest(WOLFSSL* ssl) int typeTotal = 1; /* only 1 for now */ int reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ; /* add auth later */ + WOLFSSL_START(WC_FUNC_CERTIFICATE_REQUEST_SEND); + WOLFSSL_ENTER("SendCertificateRequest"); + if (IsAtLeastTLSv1_2(ssl)) reqSz += LENGTH_SZ + ssl->suites->hashSigAlgoSz; @@ -13904,9 +13944,14 @@ int SendCertificateRequest(WOLFSSL* ssl) #endif ssl->buffers.outputBuffer.length += sendSz; if (ssl->options.groupMessages) - return 0; + ret = 0; else - return SendBuffered(ssl); + ret = SendBuffered(ssl); + + WOLFSSL_LEAVE("SendCertificateRequest", ret); + WOLFSSL_END(WC_FUNC_CERTIFICATE_REQUEST_SEND); + + return ret; } #ifndef NO_WOLFSSL_SERVER @@ -14021,6 +14066,7 @@ int SendCertificateStatus(WOLFSSL* ssl) int ret = 0; byte status_type = 0; + WOLFSSL_START(WC_FUNC_CERTIFICATE_STATUS_SEND); WOLFSSL_ENTER("SendCertificateStatus"); (void) ssl; @@ -14355,6 +14401,9 @@ int SendCertificateStatus(WOLFSSL* ssl) break; } + WOLFSSL_LEAVE("SendCertificateStatus", ret); + WOLFSSL_END(WC_FUNC_CERTIFICATE_STATUS_SEND); + return ret; } @@ -17025,12 +17074,14 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, int ret; word16 extSz = 0; - #ifdef WOLFSSL_TLS13 if (IsAtLeastTLSv1_3(ssl->version)) return SendTls13ClientHello(ssl); #endif + WOLFSSL_START(WC_FUNC_CLIENT_HELLO_SEND); + WOLFSSL_ENTER("SendClientHello"); + if (ssl->suites == NULL) { WOLFSSL_MSG("Bad suites pointer in SendClientHello"); return SUITES_ERROR; @@ -17241,7 +17292,12 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, ssl->buffers.outputBuffer.length += sendSz; - return SendBuffered(ssl); + ret = SendBuffered(ssl); + + WOLFSSL_LEAVE("SendClientHello", ret); + WOLFSSL_END(WC_FUNC_CLIENT_HELLO_SEND); + + return ret; } @@ -17443,6 +17499,9 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 begin = i; int ret; + WOLFSSL_START(WC_FUNC_SERVER_HELLO_DO); + WOLFSSL_ENTER("DoServerHello"); + #ifdef WOLFSSL_CALLBACKS if (ssl->hsInfoOn) AddPacketName(ssl, "ServerHello"); if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo); @@ -17652,7 +17711,12 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, } #endif /* HAVE_SECRET_CALLBACK */ - return CompleteServerHello(ssl); + ret = CompleteServerHello(ssl); + + WOLFSSL_LEAVE("DoServerHello", ret); + WOLFSSL_END(WC_FUNC_SERVER_HELLO_DO); + + return ret; } int CompleteServerHello(WOLFSSL* ssl) @@ -17733,6 +17797,9 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word16 len; word32 begin = *inOutIdx; + WOLFSSL_START(WC_FUNC_CERTIFICATE_REQUEST_DO); + WOLFSSL_ENTER("DoCertificateRequest"); + #ifdef WOLFSSL_CALLBACKS if (ssl->hsInfoOn) AddPacketName(ssl, "CertificateRequest"); @@ -17822,6 +17889,9 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, if (IsEncryptionOn(ssl, 0)) *inOutIdx += ssl->keys.padSz; + WOLFSSL_LEAVE("DoCertificateRequest", 0); + WOLFSSL_END(WC_FUNC_CERTIFICATE_REQUEST_DO); + return 0; } #endif /* !NO_CERTS */ @@ -17948,6 +18018,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, (void)input; (void)size; + WOLFSSL_START(WC_FUNC_SERVER_KEY_EXCHANGE_DO); WOLFSSL_ENTER("DoServerKeyExchange"); #ifdef WOLFSSL_ASYNC_CRYPT @@ -18857,6 +18928,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, exit_dske: WOLFSSL_LEAVE("DoServerKeyExchange", ret); + WOLFSSL_END(WC_FUNC_SERVER_KEY_EXCHANGE_DO); #ifdef WOLFSSL_ASYNC_CRYPT /* Handle async operation */ @@ -19296,6 +19368,7 @@ int SendClientKeyExchange(WOLFSSL* ssl) SckeArgs args[1]; #endif + WOLFSSL_START(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND); WOLFSSL_ENTER("SendClientKeyExchange"); #ifdef OPENSSL_EXTRA @@ -20270,6 +20343,7 @@ int SendClientKeyExchange(WOLFSSL* ssl) exit_scke: WOLFSSL_LEAVE("SendClientKeyExchange", ret); + WOLFSSL_END(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND); #ifdef WOLFSSL_ASYNC_CRYPT /* Handle async operation */ @@ -20517,6 +20591,7 @@ int SendCertificateVerify(WOLFSSL* ssl) ScvArgs args[1]; #endif + WOLFSSL_START(WC_FUNC_CERTIFICATE_VERIFY_SEND); WOLFSSL_ENTER("SendCertificateVerify"); #ifdef WOLFSSL_ASYNC_CRYPT @@ -20909,6 +20984,7 @@ int SendCertificateVerify(WOLFSSL* ssl) exit_scv: WOLFSSL_LEAVE("SendCertificateVerify", ret); + WOLFSSL_END(WC_FUNC_CERTIFICATE_VERIFY_SEND); #ifdef WOLFSSL_ASYNC_CRYPT /* Handle async operation */ @@ -21032,6 +21108,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, byte echoId = 0; /* ticket echo id flag */ byte cacheOff = 0; /* session cache off flag */ + WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND); + WOLFSSL_ENTER("SendServerHello"); + length = VERSION_SZ + RAN_LEN + ID_LEN + ENUM_LEN + SUITE_LEN @@ -21209,9 +21288,14 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->options.serverState = SERVER_HELLO_COMPLETE; if (ssl->options.groupMessages) - return 0; + ret = 0; else - return SendBuffered(ssl); + ret = SendBuffered(ssl); + + WOLFSSL_LEAVE("SendServerHello", ret); + WOLFSSL_END(WC_FUNC_SERVER_HELLO_SEND); + + return ret; } @@ -21372,6 +21456,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, SskeArgs args[1]; #endif + WOLFSSL_START(WC_FUNC_SERVER_KEY_EXCHANGE_SEND); WOLFSSL_ENTER("SendServerKeyExchange"); #ifdef WOLFSSL_ASYNC_CRYPT @@ -22755,6 +22840,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, exit_sske: WOLFSSL_LEAVE("SendServerKeyExchange", ret); + WOLFSSL_END(WC_FUNC_SERVER_KEY_EXCHANGE_SEND); #ifdef WOLFSSL_ASYNC_CRYPT /* Handle async operation */ @@ -23192,6 +23278,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, Suites clSuites; word32 i = *inOutIdx; word32 begin = i; + int ret = 0; #ifdef WOLFSSL_DTLS Hmac cookieHmac; byte peerCookie[MAX_COOKIE_LEN]; @@ -23202,6 +23289,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, XMEMSET(&cookieHmac, 0, sizeof(Hmac)); #endif /* WOLFSSL_DTLS */ + WOLFSSL_START(WC_FUNC_CLIENT_HELLO_DO); + WOLFSSL_ENTER("DoClientHello"); #ifdef WOLFSSL_CALLBACKS if (ssl->hsInfoOn) AddPacketName(ssl, "ClientHello"); @@ -23216,7 +23305,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->chVersion = pv; /* store */ #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { - int ret; #if defined(NO_SHA) && defined(NO_SHA256) #error "DTLS needs either SHA or SHA-256" #endif /* NO_SHA && NO_SHA256 */ @@ -23363,7 +23451,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN); #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { - int ret = wc_HmacUpdate(&cookieHmac, input + i, RAN_LEN); + ret = wc_HmacUpdate(&cookieHmac, input + i, RAN_LEN); if (ret != 0) return ret; } #endif /* WOLFSSL_DTLS */ @@ -23396,7 +23484,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, XMEMCPY(ssl->arrays->sessionID, input + i, b); #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { - int ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1); + ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1); if (ret != 0) return ret; } #endif /* WOLFSSL_DTLS */ @@ -23452,8 +23540,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef HAVE_SERVER_RENEGOTIATION_INFO /* check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV suite */ if (FindSuite(&clSuites, 0, TLS_EMPTY_RENEGOTIATION_INFO_SCSV) >= 0) { - int ret = 0; - ret = TLSX_AddEmptyRenegotiationInfo(&ssl->extensions, ssl->heap); if (ret != WOLFSSL_SUCCESS) return ret; @@ -23462,7 +23548,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { - int ret = wc_HmacUpdate(&cookieHmac, + ret = wc_HmacUpdate(&cookieHmac, input + i - OPAQUE16_LEN, clSuites.suiteSz + OPAQUE16_LEN); if (ret != 0) return ret; @@ -23485,7 +23571,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { byte newCookie[MAX_COOKIE_LEN]; - int ret; ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1); if (ret != 0) return ret; @@ -23559,7 +23644,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, QSH_Init(ssl); #endif if (TLSX_SupportExtensions(ssl)) { - int ret = 0; #else if (IsAtLeastTLSv1_2(ssl)) { #endif @@ -23658,7 +23742,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* ProcessOld uses same resume code */ if (ssl->options.resuming) { - int ret = -1; WOLFSSL_SESSION* session = GetSession(ssl, ssl->arrays->masterSecret, 1); #ifdef HAVE_SESSION_TICKET @@ -23719,10 +23802,18 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE; + WOLFSSL_LEAVE("DoClientHello", ret); + WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO); + return ret; } } - return MatchSuite(ssl, &clSuites); + ret = MatchSuite(ssl, &clSuites); + + WOLFSSL_LEAVE("DoClientHello", ret); + WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO); + + return ret; } @@ -23760,6 +23851,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, DcvArgs args[1]; #endif + WOLFSSL_START(WC_FUNC_CERTIFICATE_VERIFY_DO); WOLFSSL_ENTER("DoCertificateVerify"); #ifdef WOLFSSL_ASYNC_CRYPT @@ -24032,6 +24124,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, exit_dcv: WOLFSSL_LEAVE("DoCertificateVerify", ret); + WOLFSSL_END(WC_FUNC_CERTIFICATE_VERIFY_DO); #ifdef WOLFSSL_ASYNC_CRYPT /* Handle async operation */ @@ -24067,6 +24160,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, int sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; int ret; + WOLFSSL_START(WC_FUNC_SERVER_HELLO_DONE_SEND); + WOLFSSL_ENTER("SendServerHelloDone"); + #ifdef WOLFSSL_DTLS if (ssl->options.dtls) sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; @@ -24107,7 +24203,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->buffers.outputBuffer.length += sendSz; - return SendBuffered(ssl); + ret = SendBuffered(ssl); + + WOLFSSL_LEAVE("SendServerHelloDone", ret); + WOLFSSL_END(WC_FUNC_SERVER_HELLO_DONE_SEND); + + return ret; } @@ -24257,6 +24358,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, int outLen; word16 inLen; + WOLFSSL_START(WC_FUNC_TICKET_DO); + WOLFSSL_ENTER("DoClientTicket"); + if (len > SESSION_TICKET_LEN || len < (word32)(sizeof(InternalTicket) + WOLFSSL_TICKET_FIXED_SZ)) { return BAD_TICKET_MSG_SZ; @@ -24310,6 +24414,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } } + WOLFSSL_LEAVE("DoClientTicket", ret); + WOLFSSL_END(WC_FUNC_TICKET_DO); + return ret; } @@ -24323,6 +24430,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 length = SESSION_HINT_SZ + LENGTH_SZ; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; + WOLFSSL_START(WC_FUNC_TICKET_SEND); + WOLFSSL_ENTER("SendTicket"); + if (ssl->options.createTicket) { ret = CreateTicket(ssl); if (ret != 0) return ret; @@ -24372,7 +24482,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (ret != 0) return ret; ssl->buffers.outputBuffer.length += sendSz; - return SendBuffered(ssl); + ret = SendBuffered(ssl); + + WOLFSSL_LEAVE("SendTicket", ret); + WOLFSSL_END(WC_FUNC_TICKET_SEND); + + return ret; } #endif /* HAVE_SESSION_TICKET */ @@ -24466,6 +24581,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, (void)size; (void)input; + WOLFSSL_START(WC_FUNC_CLIENT_KEY_EXCHANGE_DO); WOLFSSL_ENTER("DoClientKeyExchange"); #ifdef WOLFSSL_ASYNC_CRYPT @@ -25502,6 +25618,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, exit_dcke: WOLFSSL_LEAVE("DoClientKeyExchange", ret); + WOLFSSL_END(WC_FUNC_CLIENT_KEY_EXCHANGE_DO); #ifdef WOLFSSL_ASYNC_CRYPT /* Handle async operation */ diff --git a/src/tls.c b/src/tls.c index b250b7a07..ed36fe93b 100755 --- a/src/tls.c +++ b/src/tls.c @@ -5132,7 +5132,6 @@ static int TLSX_SetSignatureAlgorithmsCert(TLSX** extensions, const void* data, /******************************************************************************/ #ifdef WOLFSSL_TLS13 -#ifndef NO_DH /* Create a key share entry using named Diffie-Hellman parameters group. * Generates a key pair. * @@ -5143,6 +5142,7 @@ static int TLSX_SetSignatureAlgorithmsCert(TLSX** extensions, const void* data, static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse) { int ret; +#ifndef NO_DH byte* keyData; void* key = NULL; word32 keySz; @@ -5230,8 +5230,8 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse) XMEMSET(keyData, 0, params->p_len - dataSz); } - kse->ke = keyData; - kse->keLen = params->p_len; + kse->pubKey = keyData; + kse->pubKeyLen = params->p_len; kse->key = key; kse->keyLen = keySz; @@ -5251,12 +5251,90 @@ end: if (key != NULL) XFREE(key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); } +#else + (void)ssl; + (void)kse; + + ret = NOT_COMPILED_IN; +#endif return ret; } + +/* Create a key share entry using X25519 parameters group. + * Generates a key pair. + * + * ssl The SSL/TLS object. + * kse The key share entry object. + * returns 0 on success, otherwise failure. + */ +static int TLSX_KeyShare_GenX25519Key(WOLFSSL *ssl, KeyShareEntry* kse) +{ + int ret; +#ifdef HAVE_CURVE25519 + byte* keyData = NULL; + word32 dataSize = CURVE25519_KEYSIZE; + curve25519_key* key; + + /* Allocate an ECC key to hold private key. */ + key = (curve25519_key*)XMALLOC(sizeof(curve25519_key), + ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); + if (key == NULL) { + WOLFSSL_MSG("EccTempKey Memory error"); + return MEMORY_E; + } + + /* Make an ECC key. */ + ret = wc_curve25519_init(key); + if (ret != 0) + goto end; + ret = wc_curve25519_make_key(ssl->rng, CURVE25519_KEYSIZE, key); + if (ret != 0) + goto end; + + /* Allocate space for the public key. */ + keyData = (byte*)XMALLOC(CURVE25519_KEYSIZE, ssl->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + if (keyData == NULL) { + WOLFSSL_MSG("Key data Memory error"); + ret = MEMORY_E; + goto end; + } + + /* Export public key. */ + if (wc_curve25519_export_public_ex(key, keyData, &dataSize, + EC25519_LITTLE_ENDIAN) != 0) { + ret = ECC_EXPORT_ERROR; + goto end; + } + + kse->pubKey = keyData; + kse->pubKeyLen = CURVE25519_KEYSIZE; + kse->key = key; + +#ifdef WOLFSSL_DEBUG_TLS + WOLFSSL_MSG("Public Curve25519 Key"); + WOLFSSL_BUFFER(keyData, dataSize); #endif -#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) +end: + if (ret != 0) { + /* Data owned by key share entry otherwise. */ + if (keyData != NULL) + XFREE(keyData, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + wc_curve25519_free(key); + XFREE(key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); + } +#else + (void)ssl; + (void)kse; + + ret = NOT_COMPILED_IN; +#endif /* HAVE_CURVE25519 */ + + return ret; +} + /* Create a key share entry using named elliptic curve parameters group. * Generates a key pair. * @@ -5267,19 +5345,17 @@ end: static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) { int ret; +#ifdef HAVE_ECC byte* keyData = NULL; word32 dataSize; byte* keyPtr = NULL; word32 keySize; -#ifdef HAVE_ECC ecc_key* eccKey; word16 curveId; -#endif /* TODO: [TLS13] The key sizes should come from wolfcrypt. */ /* Translate named group to a curve id. */ switch (kse->group) { -#ifdef HAVE_ECC #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) #ifndef NO_ECC_SECP case WOLFSSL_ECC_SECP256R1: @@ -5307,58 +5383,6 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) break; #endif /* !NO_ECC_SECP */ #endif -#endif - #ifdef HAVE_CURVE25519 - case WOLFSSL_ECC_X25519: - { - curve25519_key* curve_key; - /* Allocate an ECC key to hold private key. */ - keyPtr = (byte*)XMALLOC(sizeof(curve25519_key), - ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); - if (keyPtr == NULL) { - WOLFSSL_MSG("EccTempKey Memory error"); - return MEMORY_E; - } - curve_key = (curve25519_key*)keyPtr; - - dataSize = keySize = 32; - - /* Make an ECC key. */ - ret = wc_curve25519_init(curve_key); - if (ret != 0) - goto end; - ret = wc_curve25519_make_key(ssl->rng, keySize, curve_key); - if (ret != 0) - goto end; - - /* Allocate space for the public key. */ - keyData = (byte*)XMALLOC(dataSize, ssl->heap, - DYNAMIC_TYPE_PUBLIC_KEY); - if (keyData == NULL) { - WOLFSSL_MSG("Key data Memory error"); - ret = MEMORY_E; - goto end; - } - - /* Export public key. */ - if (wc_curve25519_export_public_ex(curve_key, keyData, &dataSize, - EC25519_LITTLE_ENDIAN) != 0) { - ret = ECC_EXPORT_ERROR; - goto end; - } - - kse->ke = keyData; - kse->keLen = dataSize; - kse->key = keyPtr; - -#ifdef WOLFSSL_DEBUG_TLS - WOLFSSL_MSG("Public Curve25519 Key"); - WOLFSSL_BUFFER(keyData, dataSize); -#endif - - goto end; - } - #endif #ifdef HAVE_X448 case WOLFSSL_ECC_X448: curveId = ECC_X448; @@ -5369,10 +5393,9 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) return BAD_FUNC_ARG; } -#ifdef HAVE_ECC /* Allocate an ECC key to hold private key. */ keyPtr = (byte*)XMALLOC(sizeof(ecc_key), ssl->heap, - DYNAMIC_TYPE_PRIVATE_KEY); + DYNAMIC_TYPE_PRIVATE_KEY); if (keyPtr == NULL) { WOLFSSL_MSG("EccTempKey Memory error"); return MEMORY_E; @@ -5407,15 +5430,14 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) goto end; } - kse->ke = keyData; - kse->keLen = dataSize; + kse->pubKey = keyData; + kse->pubKeyLen = dataSize; kse->key = keyPtr; #ifdef WOLFSSL_DEBUG_TLS WOLFSSL_MSG("Public ECC Key"); WOLFSSL_BUFFER(keyData, dataSize); #endif -#endif /* HAVE_ECC */ end: if (ret != 0) { @@ -5425,9 +5447,15 @@ end: if (keyData != NULL) XFREE(keyData, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); } +#else + (void)ssl; + (void)kse; + + ret = NOT_COMPILED_IN; +#endif /* HAVE_ECC */ + return ret; } -#endif /* HAVE_ECC */ /* Generate a secret/key using the key share entry. * @@ -5436,16 +5464,12 @@ end: */ static int TLSX_KeyShare_GenKey(WOLFSSL *ssl, KeyShareEntry *kse) { -#ifndef NO_DH /* Named FFHE groups have a bit set to identify them. */ if ((kse->group & NAMED_DH_MASK) == NAMED_DH_MASK) return TLSX_KeyShare_GenDhKey(ssl, kse); -#endif -#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + if (kse->group == WOLFSSL_ECC_X25519) + return TLSX_KeyShare_GenX25519Key(ssl, kse); return TLSX_KeyShare_GenEccKey(ssl, kse); -#else - return NOT_COMPILED_IN; -#endif } /* Free the key share dynamic data. @@ -5459,11 +5483,10 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap) while ((current = list) != NULL) { list = current->next; -#ifdef HAVE_ECC if ((current->group & NAMED_DH_MASK) == 0) { if (current->group == WOLFSSL_ECC_X25519) { #ifdef HAVE_CURVE25519 - + wc_curve25519_free((curve25519_key*)current->key); #endif } else { @@ -5472,8 +5495,8 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap) #endif } } -#endif XFREE(current->key, heap, DYNAMIC_TYPE_PRIVATE_KEY); + XFREE(current->pubKey, heap, DYNAMIC_TYPE_PUBLIC_KEY); XFREE(current->ke, heap, DYNAMIC_TYPE_PUBLIC_KEY); XFREE(current, heap, DYNAMIC_TYPE_TLSX); } @@ -5506,7 +5529,7 @@ static word16 TLSX_KeyShare_GetSize(KeyShareEntry* list, byte msgType) if (!isRequest && current->key == NULL) continue; - len += (int)(KE_GROUP_LEN + OPAQUE16_LEN + current->keLen); + len += (int)(KE_GROUP_LEN + OPAQUE16_LEN + current->pubKeyLen); } return (word16)len; @@ -5545,10 +5568,10 @@ static word16 TLSX_KeyShare_Write(KeyShareEntry* list, byte* output, c16toa(current->group, &output[i]); i += KE_GROUP_LEN; - c16toa(current->keLen, &output[i]); + c16toa(current->pubKeyLen, &output[i]); i += OPAQUE16_LEN; - XMEMCPY(&output[i], current->ke, current->keLen); - i += current->keLen; + XMEMCPY(&output[i], current->pubKey, current->pubKeyLen); + i += current->pubKeyLen; } /* Write the length of the list if required. */ if (isRequest) @@ -5665,6 +5688,71 @@ static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) #endif } +/* Process the X25519 key share extension on the client side. + * + * ssl The SSL/TLS object. + * keyShareEntry The key share entry object to use to calculate shared secret. + * returns 0 on success and other values indicate failure. + */ +static int TLSX_KeyShare_ProcessX25519(WOLFSSL* ssl, + KeyShareEntry* keyShareEntry) +{ + int ret; + +#ifdef HAVE_CURVE25519 + curve25519_key* key = (curve25519_key*)keyShareEntry->key; + curve25519_key* peerEccKey; + + if (ssl->peerEccKey != NULL) { + wc_ecc_free(ssl->peerEccKey); + ssl->peerEccKey = NULL; + } + + peerEccKey = (curve25519_key*)XMALLOC(sizeof(curve25519_key), ssl->heap, + DYNAMIC_TYPE_TLSX); + if (peerEccKey == NULL) { + WOLFSSL_MSG("PeerEccKey Memory error"); + return MEMORY_ERROR; + } + ret = wc_curve25519_init(peerEccKey); + if (ret != 0) { + XFREE(peerEccKey, ssl->heap, DYNAMIC_TYPE_TLSX); + return ret; + } +#ifdef WOLFSSL_DEBUG_TLS + WOLFSSL_MSG("Peer Curve25519 Key"); + WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen); +#endif + + /* Point is validated by import function. */ + if (wc_curve25519_import_public_ex(keyShareEntry->ke, keyShareEntry->keLen, + peerEccKey, + EC25519_LITTLE_ENDIAN) != 0) { + ret = ECC_PEERKEY_ERROR; + } + + if (ret == 0) { + ssl->arrays->preMasterSz = ENCRYPT_LEN; + ssl->ecdhCurveOID = ECC_X25519_OID; + + /* TODO: Switch to support async */ + ret = wc_curve25519_shared_secret_ex(key, peerEccKey, + ssl->arrays->preMasterSecret, + &ssl->arrays->preMasterSz, + EC25519_LITTLE_ENDIAN); + } + wc_curve25519_free(peerEccKey); + XFREE(peerEccKey, ssl->heap, DYNAMIC_TYPE_TLSX); +#else + (void)ssl; + (void)keyShareEntry; + + ret = PEER_KEY_ERROR; +#endif /* HAVE_CURVE25519 */ + + return ret; +} + /* Process the ECC key share extension on the client side. * * ssl The SSL/TLS object. @@ -5715,47 +5803,6 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) break; #endif /* !NO_ECC_SECP */ #endif - #ifdef HAVE_CURVE25519 - case WOLFSSL_ECC_X25519: - { - curve25519_key* key = (curve25519_key*)keyShareEntry->key; - curve25519_key* peerEccKey; - - if (ssl->peerEccKey != NULL) - wc_ecc_free(ssl->peerEccKey); - - peerEccKey = (curve25519_key*)XMALLOC(sizeof(curve25519_key), - ssl->heap, DYNAMIC_TYPE_TLSX); - if (peerEccKey == NULL) { - WOLFSSL_MSG("PeerEccKey Memory error"); - return MEMORY_ERROR; - } - ret = wc_curve25519_init(peerEccKey); - if (ret == 0) { -#ifdef WOLFSSL_DEBUG_TLS - WOLFSSL_MSG("Peer Curve25519 Key"); - WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen); -#endif - /* Point is validated by import function. */ - if (wc_curve25519_import_public_ex(keyShareEntry->ke, - keyShareEntry->keLen, peerEccKey, - EC25519_LITTLE_ENDIAN) != 0) { - ret = ECC_PEERKEY_ERROR; - } - else { - ssl->arrays->preMasterSz = ENCRYPT_LEN; - ret = wc_curve25519_shared_secret_ex(key, peerEccKey, - ssl->arrays->preMasterSecret, - &ssl->arrays->preMasterSz, - EC25519_LITTLE_ENDIAN); - wc_curve25519_free(peerEccKey); - ssl->ecdhCurveOID = ECC_X25519_OID; - } - } - XFREE(peerEccKey, ssl->heap, DYNAMIC_TYPE_TLSX); - return ret; - } - #endif #ifdef HAVE_X448 case WOLFSSL_ECC_X448: curveId = ECC_X448; @@ -5829,6 +5876,8 @@ static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) /* Use Key Share Data from server. */ if (keyShareEntry->group & NAMED_DH_MASK) ret = TLSX_KeyShare_ProcessDh(ssl, keyShareEntry); + else if (keyShareEntry->group == WOLFSSL_ECC_X25519) + ret = TLSX_KeyShare_ProcessX25519(ssl, keyShareEntry); else ret = TLSX_KeyShare_ProcessEcc(ssl, keyShareEntry); @@ -5888,8 +5937,8 @@ static int TLSX_KeyShareEntry_Parse(WOLFSSL* ssl, byte* input, word16 length, /* Searches the groups sent for the specified named group. * - * ssl The SSL/TLS object. - * name The group name to match. + * ssl SSL/TLS object. + * name Group name to match. * returns 1 when the extension has the group name and 0 otherwise. */ static int TLSX_KeyShare_Find(WOLFSSL* ssl, word16 group) @@ -5903,9 +5952,8 @@ static int TLSX_KeyShare_Find(WOLFSSL* ssl, word16 group) list = (KeyShareEntry*)extension->data; while (list != NULL) { - if (list->group == group) { + if (list->group == group) return 1; - } list = list->next; } @@ -5957,8 +6005,18 @@ static int TLSX_KeyShare_Parse(WOLFSSL* ssl, byte* input, word16 length, KeyShareEntry *keyShareEntry; if (msgType == client_hello) { - int offset = 0; + int offset = 0; word16 len; + TLSX* extension; + + /* Add a KeyShare extension if it doesn't exist. */ + extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); + if (extension == NULL) { + /* Push new KeyShare extension. */ + ret = TLSX_Push(&ssl->extensions, TLSX_KEY_SHARE, NULL, ssl->heap); + if (ret != 0) + return ret; + } if (length < OPAQUE16_LEN) return BUFFER_ERROR; @@ -5971,7 +6029,7 @@ static int TLSX_KeyShare_Parse(WOLFSSL* ssl, byte* input, word16 length, while (offset < length) { ret = TLSX_KeyShareEntry_Parse(ssl, &input[offset], length, - &keyShareEntry); + &keyShareEntry); if (ret < 0) return ret; @@ -6105,9 +6163,6 @@ int TLSX_KeyShare_Use(WOLFSSL* ssl, word16 group, word16 len, byte* data, } if (data != NULL) { - /* Keep the public key data and free when finished. */ - if (keyShareEntry->ke != NULL) - XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); keyShareEntry->ke = data; keyShareEntry->keLen = len; } @@ -6259,7 +6314,7 @@ static int TLSX_KeyShare_SetSupported(WOLFSSL* ssl) return ret; } -/* Establish the secret based on the key shares received from the client. +/* Ensure there is a key pair that can be used for key exchange. * * ssl The SSL/TLS object. * returns 0 on success and other values indicate failure. @@ -6271,8 +6326,6 @@ int TLSX_KeyShare_Establish(WOLFSSL *ssl) KeyShareEntry* clientKSE = NULL; KeyShareEntry* serverKSE; KeyShareEntry* list = NULL; - byte* ke; - word16 keLen; /* Find the KeyShare extension if it exists. */ extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); @@ -6285,6 +6338,9 @@ int TLSX_KeyShare_Establish(WOLFSSL *ssl) /* TODO: [TLS13] Server's preference and sending back SupportedGroups */ /* Use client's preference. */ for (clientKSE = list; clientKSE != NULL; clientKSE = clientKSE->next) { + if (clientKSE->ke == NULL) + continue; + /* Check consistency now - extensions in any order. */ if (!TLSX_SupportedGroups_Find(ssl, clientKSE->group)) return BAD_KEY_SHARE_DATA; @@ -6309,40 +6365,62 @@ int TLSX_KeyShare_Establish(WOLFSSL *ssl) list = NULL; /* Generate a new key pair. */ ret = TLSX_KeyShare_New(&list, clientKSE->group, ssl->heap, &serverKSE); - if (ret != 0) - return ret; - ret = TLSX_KeyShare_GenKey(ssl, serverKSE); if (ret != 0) return ret; - /* Move private key to client entry. */ - if (clientKSE->key != NULL) - XFREE(clientKSE->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); - clientKSE->key = serverKSE->key; - serverKSE->key = NULL; - clientKSE->keyLen = serverKSE->keyLen; - - /* Calculate secret. */ - ret = TLSX_KeyShare_Process(ssl, clientKSE); - if (ret != 0) - return ret; - - /* Swap public keys for sending to client. */ - ke = serverKSE->ke; - keLen = serverKSE->keLen; + if (clientKSE->key == NULL) { + ret = TLSX_KeyShare_GenKey(ssl, serverKSE); + if (ret != 0) + return ret; + } + else { + serverKSE->key = clientKSE->key; + serverKSE->keyLen = clientKSE->keyLen; + serverKSE->pubKey = clientKSE->pubKey; + serverKSE->pubKeyLen = clientKSE->pubKeyLen; + clientKSE->key = NULL; + clientKSE->pubKey = NULL; + } serverKSE->ke = clientKSE->ke; serverKSE->keLen = clientKSE->keLen; - clientKSE->ke = ke; - clientKSE->keLen = keLen; + clientKSE->ke = NULL; + clientKSE->keLen = 0; + + TLSX_KeyShare_FreeAll((KeyShareEntry*)extension->data, ssl->heap); + extension->data = (void *)serverKSE; extension->resp = 1; - /* Dispose of temporary server extension. */ - TLSX_KeyShare_FreeAll(list, ssl->heap); - return 0; } +/* Derive the shared secret of the key exchange. + * + * ssl The SSL/TLS object. + * returns 0 on success and other values indicate failure. + */ +int TLSX_KeyShare_DeriveSecret(WOLFSSL *ssl) +{ + int ret; + TLSX* extension; + KeyShareEntry* list = NULL; + + /* Find the KeyShare extension if it exists. */ + extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); + if (extension != NULL) + list = (KeyShareEntry*)extension->data; + + if (list == NULL) + return KEY_SHARE_ERROR; + + /* Calculate secret. */ + ret = TLSX_KeyShare_Process(ssl, list); + if (ret != 0) + return ret; + + return ret; +} + #define KS_FREE_ALL TLSX_KeyShare_FreeAll #define KS_GET_SIZE TLSX_KeyShare_GetSize #define KS_WRITE TLSX_KeyShare_Write @@ -6380,6 +6458,30 @@ static void TLSX_PreSharedKey_FreeAll(PreSharedKey* list, void* heap) (void)heap; } +/* Delete the extension. + * + * ssl The SSL object with the extension. + */ +static void TLSX_PreSharedKey_Delete(WOLFSSL* ssl) +{ + TLSX* extension = ssl->extensions; + TLSX* prev = NULL; + + while (extension && extension->type != TLSX_PRE_SHARED_KEY) { + prev = extension; + extension = extension->next; + } + + if (extension != NULL) { + if (prev) + prev->next = extension->next; + else + ssl->extensions = extension->next; + TLSX_PreSharedKey_FreeAll((PreSharedKey*)extension->data, ssl->heap); + XFREE(extension, ssl->heap, XFREE(extension, heap, DYNAMIC_TYPE_TLSX)); + } +} + /* Get the size of the encoded pre shared key extension. * * list The linked list of pre-shared key extensions. @@ -6557,6 +6659,8 @@ static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, byte* input, word16 length, word16 len; word16 idx = 0; + TLSX_PreSharedKey_Delete(ssl); + /* Length of identities and of binders. */ if (length - idx < OPAQUE16_LEN + OPAQUE16_LEN) return BUFFER_E; @@ -8085,6 +8189,9 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) return ret; } + #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) + TLSX_PreSharedKey_Delete(ssl); + #endif #if defined(HAVE_SESSION_TICKET) if (ssl->options.resuming && ssl->session.ticketLen > 0) { WOLFSSL_SESSION* sess = &ssl->session; @@ -8212,6 +8319,18 @@ word16 TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType) TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH)); #endif } + #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) + if (IsAtLeastTLSv1_3(ssl->version) && ssl->options.noPskDheKe) { + #if !defined(NO_PSK) + if (ssl->options.havePSK) + TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); + #endif + #if defined(HAVE_SESSION_TICKET) + if (ssl->options.resuming) + TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); + #endif + } + #endif #endif #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) @@ -8287,6 +8406,18 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType) TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH)); #endif } + #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) + if (IsAtLeastTLSv1_3(ssl->version) && ssl->options.noPskDheKe) { + #if !defined(NO_PSK) + if (ssl->options.havePSK) + TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); + #endif + #if defined(HAVE_SESSION_TICKET) + if (ssl->options.resuming) + TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); + #endif + } + #endif #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) /* Must write Pre-shared Key extension at the end in TLS v1.3. * Must not write out Pre-shared Key extension in earlier versions of @@ -8373,7 +8504,8 @@ word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType) TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS)); #endif - TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); + if (!ssl->options.noPskDheKe) + TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); #endif @@ -8392,7 +8524,8 @@ word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType) #ifndef WOLFSSL_TLS13_DRAFT_18 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS)); #endif - TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); + if (!ssl->options.noPskDheKe) + TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE)); break; #endif @@ -8469,7 +8602,8 @@ word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType) TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS)); #endif - TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); + if (!ssl->options.noPskDheKe) + TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); #endif @@ -8488,7 +8622,9 @@ word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType) #ifndef WOLFSSL_TLS13_DRAFT_18 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS)); #endif - TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); + if (!ssl->options.noPskDheKe) + TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); + /* Cookie is written below as last extension. */ break; #endif #ifdef WOLFSSL_TLS13 diff --git a/src/tls13.c b/src/tls13.c index c36e3decc..66dc9c264 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -1591,7 +1591,7 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input, WOLFSSL_BUFFER(input, dataSz); #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22) && \ !defined(WOLFSSL_TLS13_DRAFT_23) - WOLFSSL_MSG("Addition Authentication Data"); + WOLFSSL_MSG("Additional Authentication Data"); WOLFSSL_BUFFER(aad, aadSz); #endif #endif @@ -1814,7 +1814,7 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz, WOLFSSL_BUFFER(input, dataSz); #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22) && \ !defined(WOLFSSL_TLS13_DRAFT_23) - WOLFSSL_MSG("Addition Authentication Data"); + WOLFSSL_MSG("Additional Authentication Data"); WOLFSSL_BUFFER(aad, aadSz); #endif WOLFSSL_MSG("Authentication tag"); @@ -2192,6 +2192,8 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx) byte binderKey[WC_MAX_DIGEST_SIZE]; word16 len; + WOLFSSL_ENTER("WritePSKBinders"); + ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY); if (ext == NULL) return SANITY_MSG_E; @@ -2260,6 +2262,9 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx) return ret; } #endif + + WOLFSSL_LEAVE("WritePSKBinders", ret); + return ret; } #endif @@ -2281,6 +2286,7 @@ int SendTls13ClientHello(WOLFSSL* ssl) int sendSz; int ret; + WOLFSSL_START(WC_FUNC_CLIENT_HELLO_SEND); WOLFSSL_ENTER("SendTls13ClientHello"); #ifdef HAVE_SESSION_TICKET @@ -2424,6 +2430,7 @@ int SendTls13ClientHello(WOLFSSL* ssl) ret = SendBuffered(ssl); WOLFSSL_LEAVE("SendTls13ClientHello", ret); + WOLFSSL_END(WC_FUNC_CLIENT_HELLO_SEND); return ret; } @@ -2650,6 +2657,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif byte extMsgType = server_hello; + WOLFSSL_START(WC_FUNC_SERVER_HELLO_DO); WOLFSSL_ENTER("DoTls13ServerHello"); #ifdef WOLFSSL_CALLBACKS @@ -2861,6 +2869,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif WOLFSSL_LEAVE("DoTls13ServerHello", ret); + WOLFSSL_END(WC_FUNC_SERVER_HELLO_DO); return ret; } @@ -2886,6 +2895,7 @@ static int DoTls13EncryptedExtensions(WOLFSSL* ssl, const byte* input, word32 i = begin; word16 totalExtSz; + WOLFSSL_START(WC_FUNC_ENCRYPTED_EXTENSIONS_DO); WOLFSSL_ENTER("DoTls13EncryptedExtensions"); #ifdef WOLFSSL_CALLBACKS @@ -2921,6 +2931,7 @@ static int DoTls13EncryptedExtensions(WOLFSSL* ssl, const byte* input, #endif WOLFSSL_LEAVE("DoTls13EncryptedExtensions", ret); + WOLFSSL_END(WC_FUNC_ENCRYPTED_EXTENSIONS_DO); return ret; } @@ -2950,6 +2961,7 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input, CertReqCtx* certReqCtx; #endif + WOLFSSL_START(WC_FUNC_CERTIFICATE_REQUEST_DO); WOLFSSL_ENTER("DoTls13CertificateRequest"); #ifdef WOLFSSL_CALLBACKS @@ -3069,6 +3081,7 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input, #endif WOLFSSL_LEAVE("DoTls13CertificateRequest", ret); + WOLFSSL_END(WC_FUNC_CERTIFICATE_REQUEST_DO); return ret; } @@ -3103,6 +3116,8 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz, TLSX* extEarlyData; #endif + WOLFSSL_ENTER("DoPreSharedKeys"); + ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY); if (ext == NULL) { #ifdef WOLFSSL_EARLY_DATA @@ -3300,21 +3315,28 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz, /* Only use named group used in last session. */ ssl->namedGroup = ssl->session.namedGroup; - /* Try to establish a new secret. */ + /* Pick key share and Generate a new key if not present. */ ret = TLSX_KeyShare_Establish(ssl); - if (ret == KEY_SHARE_ERROR) - return PSK_KEY_ERROR; + if (ret == KEY_SHARE_ERROR) { + ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST; + ret = 0; + } else if (ret < 0) return ret; /* Send new public key to client. */ ext->resp = 1; } - else if ((modes & (1 << PSK_KE)) == 0) - return PSK_KEY_ERROR; + else { + if ((modes & (1 << PSK_KE)) == 0) + return PSK_KEY_ERROR; + ssl->options.noPskDheKe = 1; + } *usingPSK = 1; + WOLFSSL_LEAVE("DoPreSharedKeys", ret); + return ret; } #endif @@ -3557,6 +3579,7 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, int usingPSK = 0; byte sessIdSz; + WOLFSSL_START(WC_FUNC_CLIENT_HELLO_DO); WOLFSSL_ENTER("DoTls13ClientHello"); #ifdef WOLFSSL_CALLBACKS @@ -3733,6 +3756,7 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->options.haveSessionId = 1; WOLFSSL_LEAVE("DoTls13ClientHello", ret); + WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO); return ret; } @@ -3832,6 +3856,7 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType) int sendSz; int ret; + WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND); WOLFSSL_ENTER("SendTls13ServerHello"); #ifndef WOLFSSL_TLS13_DRAFT_18 @@ -3947,6 +3972,7 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType) ret = SendBuffered(ssl); WOLFSSL_LEAVE("SendTls13ServerHello", ret); + WOLFSSL_END(WC_FUNC_SERVER_HELLO_SEND); return ret; } @@ -3967,6 +3993,7 @@ static int SendTls13EncryptedExtensions(WOLFSSL* ssl) word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; int sendSz; + WOLFSSL_START(WC_FUNC_ENCRYPTED_EXTENSIONS_SEND); WOLFSSL_ENTER("SendTls13EncryptedExtensions"); ssl->keys.encryptionOn = 1; @@ -4036,6 +4063,7 @@ static int SendTls13EncryptedExtensions(WOLFSSL* ssl) ret = SendBuffered(ssl); WOLFSSL_LEAVE("SendTls13EncryptedExtensions", ret); + WOLFSSL_END(WC_FUNC_ENCRYPTED_EXTENSIONS_SEND); return ret; } @@ -4063,6 +4091,7 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, TLSX* ext; #endif + WOLFSSL_START(WC_FUNC_CERTIFICATE_REQUEST_SEND); WOLFSSL_ENTER("SendTls13CertificateRequest"); if (ssl->options.side == WOLFSSL_SERVER_END) @@ -4165,6 +4194,7 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, ret = SendBuffered(ssl); WOLFSSL_LEAVE("SendTls13CertificateRequest", ret); + WOLFSSL_END(WC_FUNC_CERTIFICATE_REQUEST_SEND); return ret; } @@ -4582,6 +4612,7 @@ static int SendTls13Certificate(WOLFSSL* ssl) byte certReqCtxLen = 0; byte* certReqCtx = NULL; + WOLFSSL_START(WC_FUNC_CERTIFICATE_SEND); WOLFSSL_ENTER("SendTls13Certificate"); #ifdef WOLFSSL_POST_HANDSHAKE_AUTH @@ -4770,6 +4801,7 @@ static int SendTls13Certificate(WOLFSSL* ssl) #endif WOLFSSL_LEAVE("SendTls13Certificate", ret); + WOLFSSL_END(WC_FUNC_CERTIFICATE_SEND); return ret; } @@ -4830,6 +4862,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) Scv13Args args[1]; #endif + WOLFSSL_START(WC_FUNC_CERTIFICATE_VERIFY_SEND); WOLFSSL_ENTER("SendTls13CertificateVerify"); #ifdef WOLFSSL_ASYNC_CRYPT @@ -5124,6 +5157,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) exit_scv: WOLFSSL_LEAVE("SendTls13CertificateVerify", ret); + WOLFSSL_END(WC_FUNC_CERTIFICATE_VERIFY_SEND); #ifdef WOLFSSL_ASYNC_CRYPT /* Handle async operation */ @@ -5154,6 +5188,7 @@ static int DoTls13Certificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, { int ret; + WOLFSSL_START(WC_FUNC_CERTIFICATE_DO); WOLFSSL_ENTER("DoTls13Certificate"); ret = ProcessPeerCerts(ssl, input, inOutIdx, totalSz); @@ -5169,6 +5204,7 @@ static int DoTls13Certificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif WOLFSSL_LEAVE("DoTls13Certificate", ret); + WOLFSSL_END(WC_FUNC_CERTIFICATE_DO); return ret; } @@ -5225,6 +5261,7 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, Dcv13Args args[1]; #endif + WOLFSSL_START(WC_FUNC_CERTIFICATE_VERIFY_DO); WOLFSSL_ENTER("DoTls13CertificateVerify"); #ifdef WOLFSSL_ASYNC_CRYPT @@ -5464,6 +5501,7 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, exit_dcv: WOLFSSL_LEAVE("DoTls13CertificateVerify", ret); + WOLFSSL_END(WC_FUNC_CERTIFICATE_VERIFY_DO); #ifdef WOLFSSL_ASYNC_CRYPT /* Handle async operation */ @@ -5502,6 +5540,7 @@ static int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, byte* secret; byte mac[WC_MAX_DIGEST_SIZE]; + WOLFSSL_START(WC_FUNC_FINISHED_DO); WOLFSSL_ENTER("DoTls13Finished"); /* check against totalSz */ @@ -5575,6 +5614,7 @@ static int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif WOLFSSL_LEAVE("DoTls13Finished", 0); + WOLFSSL_END(WC_FUNC_FINISHED_DO); return 0; } @@ -5596,6 +5636,7 @@ static int SendTls13Finished(WOLFSSL* ssl) int outputSz; byte* secret; + WOLFSSL_START(WC_FUNC_FINISHED_SEND); WOLFSSL_ENTER("SendTls13Finished"); outputSz = WC_MAX_DIGEST_SIZE + DTLS_HANDSHAKE_HEADER_SZ + MAX_MSG_EXTRA; @@ -5716,6 +5757,7 @@ static int SendTls13Finished(WOLFSSL* ssl) #endif WOLFSSL_LEAVE("SendTls13Finished", ret); + WOLFSSL_END(WC_FUNC_FINISHED_SEND); return ret; } @@ -5736,6 +5778,7 @@ static int SendTls13KeyUpdate(WOLFSSL* ssl) int outputSz; word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; + WOLFSSL_START(WC_FUNC_KEY_UPDATE_SEND); WOLFSSL_ENTER("SendTls13KeyUpdate"); outputSz = OPAQUE8_LEN + MAX_MSG_EXTRA; @@ -5788,6 +5831,7 @@ static int SendTls13KeyUpdate(WOLFSSL* ssl) return ret; WOLFSSL_LEAVE("SendTls13KeyUpdate", ret); + WOLFSSL_END(WC_FUNC_KEY_UPDATE_SEND); return ret; } @@ -5808,6 +5852,7 @@ static int DoTls13KeyUpdate(WOLFSSL* ssl, const byte* input, word32* inOutIdx, int ret; word32 i = *inOutIdx; + WOLFSSL_START(WC_FUNC_KEY_UPDATE_DO); WOLFSSL_ENTER("DoTls13KeyUpdate"); /* check against totalSz */ @@ -5846,6 +5891,7 @@ static int DoTls13KeyUpdate(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return SendTls13KeyUpdate(ssl); WOLFSSL_LEAVE("DoTls13KeyUpdate", ret); + WOLFSSL_END(WC_FUNC_KEY_UPDATE_DO); return 0; } @@ -5867,6 +5913,7 @@ static int SendTls13EndOfEarlyData(WOLFSSL* ssl) word32 length; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; + WOLFSSL_START(WC_FUNC_END_OF_EARLY_DATA_SEND); WOLFSSL_ENTER("SendTls13EndOfEarlyData"); length = 0; @@ -5898,6 +5945,7 @@ static int SendTls13EndOfEarlyData(WOLFSSL* ssl) ret = SendBuffered(ssl); WOLFSSL_LEAVE("SendTls13EndOfEarlyData", ret); + WOLFSSL_END(WC_FUNC_END_OF_EARLY_DATA_SEND); return ret; } @@ -5920,6 +5968,7 @@ static int DoTls13EndOfEarlyData(WOLFSSL* ssl, const byte* input, (void)input; + WOLFSSL_START(WC_FUNC_END_OF_EARLY_DATA_DO); WOLFSSL_ENTER("DoTls13EndOfEarlyData"); if ((*inOutIdx - begin) != size) @@ -5931,6 +5980,7 @@ static int DoTls13EndOfEarlyData(WOLFSSL* ssl, const byte* input, ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY); WOLFSSL_LEAVE("SendTls13EndOfEarlyData", ret); + WOLFSSL_END(WC_FUNC_END_OF_EARLY_DATA_DO); return ret; } @@ -5963,6 +6013,7 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input, byte nonceLength; #endif + WOLFSSL_START(WC_FUNC_NEW_SESSION_TICKET_DO); WOLFSSL_ENTER("DoTls13NewSessionTicket"); /* Lifetime hint. */ @@ -6058,6 +6109,7 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input, #endif /* HAVE_SESSION_TICKET */ WOLFSSL_LEAVE("DoTls13NewSessionTicket", 0); + WOLFSSL_END(WC_FUNC_NEW_SESSION_TICKET_DO); return 0; } @@ -6175,6 +6227,7 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl) word32 length; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; + WOLFSSL_START(WC_FUNC_NEW_SESSION_TICKET_SEND); WOLFSSL_ENTER("SendTls13NewSessionTicket"); #ifdef WOLFSSL_TLS13_TICKET_BEFORE_FINISHED @@ -6273,6 +6326,7 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl) ret = SendBuffered(ssl); WOLFSSL_LEAVE("SendTls13NewSessionTicket", 0); + WOLFSSL_END(WC_FUNC_NEW_SESSION_TICKET_SEND); return ret; } @@ -7109,8 +7163,6 @@ int wolfSSL_UseKeyShare(WOLFSSL* ssl, word16 group) if (ssl == NULL) return BAD_FUNC_ARG; - if (ssl->options.side == WOLFSSL_SERVER_END) - return SIDE_ERROR; ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL); if (ret != 0) @@ -7466,6 +7518,13 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl) ssl->options.sentChangeCipher = 1; } #endif + + if (!ssl->options.noPskDheKe) { + ssl->error = TLSX_KeyShare_DeriveSecret(ssl); + if (ssl->error != 0) + return WOLFSSL_FATAL_ERROR; + } + ssl->options.acceptState = SERVER_HELLO_SENT; WOLFSSL_MSG("accept state SERVER_HELLO_SENT"); FALL_THROUGH; diff --git a/tests/api.c b/tests/api.c index 7363e06c7..a81231ee8 100644 --- a/tests/api.c +++ b/tests/api.c @@ -18124,7 +18124,7 @@ static int test_tls13_apis(void) #ifdef HAVE_ECC AssertIntEQ(wolfSSL_UseKeyShare(NULL, WOLFSSL_ECC_SECP256R1), BAD_FUNC_ARG); AssertIntEQ(wolfSSL_UseKeyShare(serverSsl, WOLFSSL_ECC_SECP256R1), - SIDE_ERROR); + WOLFSSL_SUCCESS); AssertIntEQ(wolfSSL_UseKeyShare(clientTls12Ssl, WOLFSSL_ECC_SECP256R1), WOLFSSL_SUCCESS); AssertIntEQ(wolfSSL_UseKeyShare(clientSsl, WOLFSSL_ECC_SECP256R1), @@ -18139,8 +18139,6 @@ static int test_tls13_apis(void) WOLFSSL_SUCCESS); #else AssertIntEQ(wolfSSL_UseKeyShare(NULL, WOLFSSL_ECC_SECP256R1), BAD_FUNC_ARG); - AssertIntEQ(wolfSSL_UseKeyShare(serverSsl, WOLFSSL_ECC_SECP256R1), - SIDE_ERROR); AssertIntEQ(wolfSSL_UseKeyShare(clientTls12Ssl, WOLFSSL_ECC_SECP256R1), NOT_COMPILED_IN); AssertIntEQ(wolfSSL_UseKeyShare(clientSsl, WOLFSSL_ECC_SECP256R1), diff --git a/wolfcrypt/src/chacha.c b/wolfcrypt/src/chacha.c index e499e96cd..3ebded8c4 100644 --- a/wolfcrypt/src/chacha.c +++ b/wolfcrypt/src/chacha.c @@ -49,12 +49,6 @@ #include #endif -#ifdef WOLFSSL_X86_64_BUILD -#if defined(USE_INTEL_SPEEDUP) && !defined(NO_CHACHA_ASM) - #define USE_INTEL_CHACHA_SPEEDUP -#endif -#endif - #ifdef USE_INTEL_CHACHA_SPEEDUP #include #include @@ -70,7 +64,6 @@ #undef NO_AVX2_SUPPORT #endif - #define HAVE_INTEL_AVX1 #ifndef NO_AVX2_SUPPORT #define HAVE_INTEL_AVX2 #endif diff --git a/wolfcrypt/src/curve25519.c b/wolfcrypt/src/curve25519.c index ebe0da78f..efec38f72 100644 --- a/wolfcrypt/src/curve25519.c +++ b/wolfcrypt/src/curve25519.c @@ -46,7 +46,7 @@ const curve25519_set_type curve25519_sets[] = { { - 32, + CURVE25519_KEYSIZE, "CURVE25519", } }; @@ -186,20 +186,15 @@ int wc_curve25519_export_public(curve25519_key* key, byte* out, word32* outLen) int wc_curve25519_export_public_ex(curve25519_key* key, byte* out, word32* outLen, int endian) { - word32 keySz; - if (key == NULL || out == NULL || outLen == NULL) return BAD_FUNC_ARG; - /* check size of outgoing key */ - keySz = wc_curve25519_size(key); - /* check and set outgoing key size */ - if (*outLen < keySz) { - *outLen = keySz; + if (*outLen < CURVE25519_KEYSIZE) { + *outLen = CURVE25519_KEYSIZE; return ECC_BAD_ARG_E; } - *outLen = keySz; + *outLen = CURVE25519_KEYSIZE; if (endian == EC25519_BIG_ENDIAN) { int i; @@ -209,7 +204,7 @@ int wc_curve25519_export_public_ex(curve25519_key* key, byte* out, out[i] = key->p.point[CURVE25519_KEYSIZE - i - 1]; } else - XMEMCPY(out, key->p.point, keySz); + XMEMCPY(out, key->p.point, CURVE25519_KEYSIZE); return 0; } @@ -231,15 +226,12 @@ int wc_curve25519_import_public(const byte* in, word32 inLen, int wc_curve25519_import_public_ex(const byte* in, word32 inLen, curve25519_key* key, int endian) { - word32 keySz; - /* sanity check */ if (key == NULL || in == NULL) return BAD_FUNC_ARG; /* check size of incoming keys */ - keySz = wc_curve25519_size(key); - if (inLen != keySz) + if (inLen != CURVE25519_KEYSIZE) return ECC_BAD_ARG_E; if (endian == EC25519_BIG_ENDIAN) { @@ -286,19 +278,16 @@ int wc_curve25519_export_private_raw(curve25519_key* key, byte* out, int wc_curve25519_export_private_raw_ex(curve25519_key* key, byte* out, word32* outLen, int endian) { - word32 keySz; - /* sanity check */ if (key == NULL || out == NULL || outLen == NULL) return BAD_FUNC_ARG; /* check size of outgoing buffer */ - keySz = wc_curve25519_size(key); - if (*outLen < keySz) { - *outLen = keySz; + if (*outLen < CURVE25519_KEYSIZE) { + *outLen = CURVE25519_KEYSIZE; return ECC_BAD_ARG_E; } - *outLen = keySz; + *outLen = CURVE25519_KEYSIZE; if (endian == EC25519_BIG_ENDIAN) { int i; @@ -308,7 +297,7 @@ int wc_curve25519_export_private_raw_ex(curve25519_key* key, byte* out, out[i] = key->k.point[CURVE25519_KEYSIZE - i - 1]; } else - XMEMCPY(out, key->k.point, keySz); + XMEMCPY(out, key->k.point, CURVE25519_KEYSIZE); return 0; } @@ -393,7 +382,7 @@ int wc_curve25519_import_private_ex(const byte* priv, word32 privSz, return BAD_FUNC_ARG; /* check size of incoming keys */ - if ((int)privSz != wc_curve25519_size(key)) + if ((int)privSz != CURVE25519_KEYSIZE) return ECC_BAD_ARG_E; if (endian == EC25519_BIG_ENDIAN) { @@ -404,7 +393,7 @@ int wc_curve25519_import_private_ex(const byte* priv, word32 privSz, key->k.point[i] = priv[CURVE25519_KEYSIZE - i - 1]; } else - XMEMCPY(key->k.point, priv, privSz); + XMEMCPY(key->k.point, priv, CURVE25519_KEYSIZE); key->dp = &curve25519_sets[0]; @@ -424,17 +413,14 @@ int wc_curve25519_init(curve25519_key* key) if (key == NULL) return BAD_FUNC_ARG; + XMEMSET(key, 0, sizeof(*key)); + /* currently the format for curve25519 */ key->dp = &curve25519_sets[0]; - XMEMSET(key->k.point, 0, key->dp->size); - XMEMSET(key->p.point, 0, key->dp->size); - #ifdef FREESCALE_LTC_ECC - XMEMSET(key->k.pointY, 0, key->dp->size); - XMEMSET(key->p.pointY, 0, key->dp->size); - #else - fe_init(); - #endif +#ifndef FREESCALE_LTC_ECC + fe_init(); +#endif return 0; } diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index 9ebf06627..d417a126c 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -56,7 +56,90 @@ static struct wc_error_queue* wc_last_node; /* pointer to last node in queue to make insertion O(1) */ #endif +#ifdef WOLFSSL_FUNC_TIME +static double wc_func_start[WC_FUNC_COUNT]; +static double wc_func_time[WC_FUNC_COUNT] = { 0, }; +static const char* wc_func_name[WC_FUNC_COUNT] = { + "SendClientHello", + "DoClientHello", + "SendServerHello", + "DoServerHello", + "SendEncryptedExtensions", + "DoEncryptedExtensions", + "SendCertificateRequest", + "DoCertificateRequest", + "SendCertificate", + "DoCertificate", + "SendCertificateVerify", + "DoCertificateVerify", + "SendFinished", + "DoFinished", + "SendKeyUpdate", + "DoKeyUpdate", + "SendEarlyData", + "DoEarlyData", + "SendNewSessionTicket", + "DoNewSessionTicket", + "SendServerHelloDone", + "DoServerHelloDone", + "SendTicket", + "DoTicket", + "SendClientKeyExchange", + "DoClientKeyExchange", + "SendCertificateStatus", + "DoCertificateStatus", + "SendServerKeyExchange", + "DoServerKeyExchange", + "SendEarlyData", + "DoEarlyData", +}; +#if defined(WOLFSSL_USER_CURRTIME) + extern double current_time(int reset); + +#elif defined(USE_WINDOWS_API) + + #define WIN32_LEAN_AND_MEAN + #include + + static INLINE double current_time(int reset) + { + static int init = 0; + static LARGE_INTEGER freq; + + LARGE_INTEGER count; + + if (!init) { + QueryPerformanceFrequency(&freq); + init = 1; + } + + QueryPerformanceCounter(&count); + + (void)reset; + return (double)count.QuadPart / freq.QuadPart; + } + +#elif defined(WOLFSSL_TIRTOS) + extern double current_time(); +#else + +#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_CHIBIOS) + #include + + static INLINE double current_time(int reset) + { + struct timeval tv; + gettimeofday(&tv, 0); + (void)reset; + + return (double)tv.tv_sec + (double)tv.tv_usec / 1000000; + } +#else + extern double current_time(int reset); +#endif +#endif /* USE_WINDOWS_API */ +#endif #ifdef DEBUG_WOLFSSL @@ -98,6 +181,40 @@ void wolfSSL_Debugging_OFF(void) #endif } +#ifdef WOLFSSL_FUNC_TIME +void WOLFSSL_START(int funcNum) +{ + double now = current_time(0) * 1000.0; +#ifdef WOLFSSL_FUNC_TIME_LOG + fprintf(stderr, "%17.3f: START - %s\n", now, wc_func_name[funcNum]); +#endif + wc_func_start[funcNum] = now; +} + +void WOLFSSL_END(int funcNum) +{ + double now = current_time(0) * 1000.0; + wc_func_time[funcNum] += now - wc_func_start[funcNum]; +#ifdef WOLFSSL_FUNC_TIME_LOG + fprintf(stderr, "%17.3f: END - %s\n", now, wc_func_name[funcNum]); +#endif +} + +void WOLFSSL_TIME(int count) +{ + int i; + double avg, total = 0; + + for (i = 0; i < WC_FUNC_COUNT; i++) { + if (wc_func_time[i] > 0) { + avg = wc_func_time[i] / count; + fprintf(stderr, "%8.3f ms: %s\n", avg, wc_func_name[i]); + total += avg; + } + } + fprintf(stderr, "%8.3f ms\n", total); +} +#endif #ifdef DEBUG_WOLFSSL diff --git a/wolfcrypt/src/poly1305.c b/wolfcrypt/src/poly1305.c index 56b9b0154..4fcc712f0 100644 --- a/wolfcrypt/src/poly1305.c +++ b/wolfcrypt/src/poly1305.c @@ -1587,7 +1587,7 @@ int wc_Poly1305_MAC(Poly1305* ctx, byte* additional, word32 addSz, int ret; byte padding[WC_POLY1305_PAD_SZ - 1]; word32 paddingLen; - byte little64[8]; + byte little64[16]; XMEMSET(padding, 0, sizeof(padding)); @@ -1627,13 +1627,7 @@ int wc_Poly1305_MAC(Poly1305* ctx, byte* additional, word32 addSz, /* size of additional data and input as little endian 64 bit types */ U32TO64(addSz, little64); - ret = wc_Poly1305Update(ctx, little64, sizeof(little64)); - if (ret) - { - return ret; - } - - U32TO64(sz, little64); + U32TO64(sz, little64 + 8); ret = wc_Poly1305Update(ctx, little64, sizeof(little64)); if (ret) { diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 9d5e9a19f..432365d17 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2213,18 +2213,21 @@ WOLFSSL_LOCAL int TLSX_Cookie_Use(WOLFSSL* ssl, byte* data, word16 len, /* The KeyShare extension information - entry in a linked list. */ typedef struct KeyShareEntry { - word16 group; /* NamedGroup */ - byte* ke; /* Key exchange data */ - word32 keLen; /* Key exchange data length */ - void* key; /* Private key */ - word32 keyLen; /* Private key length */ - struct KeyShareEntry* next; /* List pointer */ + word16 group; /* NamedGroup */ + byte* ke; /* Key exchange data */ + word32 keLen; /* Key exchange data length */ + void* key; /* Private key */ + word32 keyLen; /* Private key length */ + byte* pubKey; /* Public key */ + word32 pubKeyLen; /* Public key length */ + struct KeyShareEntry* next; /* List pointer */ } KeyShareEntry; WOLFSSL_LOCAL int TLSX_KeyShare_Use(WOLFSSL* ssl, word16 group, word16 len, byte* data, KeyShareEntry **kse); WOLFSSL_LOCAL int TLSX_KeyShare_Empty(WOLFSSL* ssl); WOLFSSL_LOCAL int TLSX_KeyShare_Establish(WOLFSSL* ssl); +WOLFSSL_LOCAL int TLSX_KeyShare_DeriveSecret(WOLFSSL* ssl); #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) diff --git a/wolfssl/test.h b/wolfssl/test.h index 3866dabd6..6aea1f491 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -1092,14 +1092,29 @@ static INLINE unsigned int my_psk_client_cb(WOLFSSL* ssl, const char* hint, /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */ strncpy(identity, kIdentityStr, id_max_len); - /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using - unsigned binary */ - key[0] = 26; - key[1] = 43; - key[2] = 60; - key[3] = 77; + if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) { + /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using + unsigned binary */ + key[0] = 0x1a; + key[1] = 0x2b; + key[2] = 0x3c; + key[3] = 0x4d; - return 4; /* length of key in octets or 0 for error */ + + return 4; /* length of key in octets or 0 for error */ + } + else { + int i; + int b = 0x01; + + for (i = 0; i < 32; i++, b += 0x22) { + if (b >= 0x100) + b = 0x01; + key[i] = b; + } + + return 32; /* length of key in octets or 0 for error */ + } } @@ -1113,14 +1128,29 @@ static INLINE unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity, if (strncmp(identity, kIdentityStr, strlen(kIdentityStr)) != 0) return 0; - /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using - unsigned binary */ - key[0] = 26; - key[1] = 43; - key[2] = 60; - key[3] = 77; + if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) { + /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using + unsigned binary */ + key[0] = 0x1a; + key[1] = 0x2b; + key[2] = 0x3c; + key[3] = 0x4d; - return 4; /* length of key in octets or 0 for error */ + + return 4; /* length of key in octets or 0 for error */ + } + else { + int i; + int b = 0x01; + + for (i = 0; i < 32; i++, b += 0x22) { + if (b >= 0x100) + b = 0x01; + key[i] = b; + } + + return 32; /* length of key in octets or 0 for error */ + } } #endif /* NO_PSK */ diff --git a/wolfssl/wolfcrypt/chacha.h b/wolfssl/wolfcrypt/chacha.h index 6f89caa68..29bdcd05f 100644 --- a/wolfssl/wolfcrypt/chacha.h +++ b/wolfssl/wolfcrypt/chacha.h @@ -43,6 +43,13 @@ #define CHACHA_CHUNK_WORDS 16 #define CHACHA_CHUNK_BYTES (CHACHA_CHUNK_WORDS * sizeof(word32)) +#ifdef WOLFSSL_X86_64_BUILD +#if defined(USE_INTEL_SPEEDUP) && !defined(NO_CHACHA_ASM) + #define USE_INTEL_CHACHA_SPEEDUP + #define HAVE_INTEL_AVX1 +#endif +#endif + enum { CHACHA_ENC_TYPE = WC_CIPHER_CHACHA, /* cipher unique type */ CHACHA_MAX_KEY_SZ = 32, @@ -50,6 +57,10 @@ enum { typedef struct ChaCha { word32 X[CHACHA_CHUNK_WORDS]; /* state of cipher */ +#ifdef HAVE_INTEL_AVX1 + /* vpshufd reads 16 bytes but we only use bottom 4. */ + byte extra[12]; +#endif } ChaCha; /** diff --git a/wolfssl/wolfcrypt/logging.h b/wolfssl/wolfcrypt/logging.h index a08818f8b..dc8e31902 100644 --- a/wolfssl/wolfcrypt/logging.h +++ b/wolfssl/wolfcrypt/logging.h @@ -45,6 +45,44 @@ enum wc_LogLevels { OTHER_LOG }; +#ifdef WOLFSSL_FUNC_TIME +enum wc_FuncNum { + WC_FUNC_CLIENT_HELLO_SEND = 0, + WC_FUNC_CLIENT_HELLO_DO, + WC_FUNC_SERVER_HELLO_SEND, + WC_FUNC_SERVER_HELLO_DO, + WC_FUNC_ENCRYPTED_EXTENSIONS_SEND, + WC_FUNC_ENCRYPTED_EXTENSIONS_DO, + WC_FUNC_CERTIFICATE_REQUEST_SEND, + WC_FUNC_CERTIFICATE_REQUEST_DO, + WC_FUNC_CERTIFICATE_SEND, + WC_FUNC_CERTIFICATE_DO, + WC_FUNC_CERTIFICATE_VERIFY_SEND, + WC_FUNC_CERTIFICATE_VERIFY_DO, + WC_FUNC_FINISHED_SEND, + WC_FUNC_FINISHED_DO, + WC_FUNC_KEY_UPDATE_SEND, + WC_FUNC_KEY_UPDATE_DO, + WC_FUNC_EARLY_DATA_SEND, + WC_FUNC_EARLY_DATA_DO, + WC_FUNC_NEW_SESSION_TICKET_SEND, + WC_FUNC_NEW_SESSION_TICKET_DO, + WC_FUNC_SERVER_HELLO_DONE_SEND, + WC_FUNC_SERVER_HELLO_DONE_DO, + WC_FUNC_TICKET_SEND, + WC_FUNC_TICKET_DO, + WC_FUNC_CLIENT_KEY_EXCHANGE_SEND, + WC_FUNC_CLIENT_KEY_EXCHANGE_DO, + WC_FUNC_CERTIFICATE_STATUS_SEND, + WC_FUNC_CERTIFICATE_STATUS_DO, + WC_FUNC_SERVER_KEY_EXCHANGE_SEND, + WC_FUNC_SERVER_KEY_EXCHANGE_DO, + WC_FUNC_END_OF_EARLY_DATA_SEND, + WC_FUNC_END_OF_EARLY_DATA_DO, + WC_FUNC_COUNT +}; +#endif + typedef void (*wolfSSL_Logging_cb)(const int logLevel, const char *const logMessage); @@ -74,6 +112,15 @@ WOLFSSL_API void wolfSSL_Debugging_OFF(void); #endif #endif /* OPENSSL_EXTRA || DEBUG_WOLFSSL_VERBOSE */ +#ifdef WOLFSSL_FUNC_TIME + WOLFSSL_API void WOLFSSL_START(int funcNum); + WOLFSSL_API void WOLFSSL_END(int funcNum); + WOLFSSL_API void WOLFSSL_TIME(int count); +#else + #define WOLFSSL_START(n) + #define WOLFSSL_END(n) + #define WOLFSSL_TIME(n) +#endif #if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_DEBUG_ERRORS_ONLY) #if defined(_WIN32)