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)