source: azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/wolfssl/test.h@ 464

Last change on this file since 464 was 464, checked in by coas-nagasima, 3 years ago

WolfSSLとAzure IoT SDKを更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-chdr;charset=UTF-8
File size: 115.1 KB
Line 
1/* test.h */
2
3#ifndef wolfSSL_TEST_H
4#define wolfSSL_TEST_H
5
6#ifdef FUSION_RTOS
7 #include <fclstdio.h>
8 #include <fclstdlib.h>
9#else
10 #include <stdio.h>
11 #include <stdlib.h>
12#endif
13#include <assert.h>
14#include <ctype.h>
15#include <wolfssl/wolfcrypt/types.h>
16#include <wolfssl/wolfcrypt/error-crypt.h>
17#include <wolfssl/wolfcrypt/random.h>
18#include <wolfssl/wolfcrypt/mem_track.h>
19#if defined(SHOW_CERTS) && \
20 (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
21 #include <wolfssl/wolfcrypt/asn.h> /* for domain component NID value */
22#endif
23
24#ifdef ATOMIC_USER
25 #include <wolfssl/wolfcrypt/aes.h>
26 #include <wolfssl/wolfcrypt/arc4.h>
27 #include <wolfssl/wolfcrypt/hmac.h>
28#endif
29#ifdef HAVE_PK_CALLBACKS
30 #include <wolfssl/wolfcrypt/asn.h>
31 #ifndef NO_RSA
32 #include <wolfssl/wolfcrypt/rsa.h>
33 #endif
34 #ifdef HAVE_ECC
35 #include <wolfssl/wolfcrypt/ecc.h>
36 #endif /* HAVE_ECC */
37 #ifndef NO_DH
38 #include <wolfssl/wolfcrypt/dh.h>
39 #endif /* !NO_DH */
40 #ifdef HAVE_ED25519
41 #include <wolfssl/wolfcrypt/ed25519.h>
42 #endif /* HAVE_ED25519 */
43 #ifdef HAVE_CURVE25519
44 #include <wolfssl/wolfcrypt/curve25519.h>
45 #endif /* HAVE_ECC */
46 #ifdef HAVE_ED448
47 #include <wolfssl/wolfcrypt/ed448.h>
48 #endif /* HAVE_ED448 */
49 #ifdef HAVE_CURVE448
50 #include <wolfssl/wolfcrypt/curve448.h>
51 #endif /* HAVE_ECC */
52#endif /*HAVE_PK_CALLBACKS */
53
54#ifdef USE_WINDOWS_API
55 #include <winsock2.h>
56 #include <process.h>
57 #ifdef TEST_IPV6 /* don't require newer SDK for IPV4 */
58 #include <ws2tcpip.h>
59 #include <wspiapi.h>
60 #endif
61 #define SOCKET_T SOCKET
62 #define SNPRINTF _snprintf
63 #define XSLEEP_MS(t) Sleep(t)
64#elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
65 #include <string.h>
66 #include "rl_net.h"
67 #define SOCKET_T int
68 typedef int socklen_t ;
69 #define inet_addr wolfSSL_inet_addr
70 static unsigned long wolfSSL_inet_addr(const char *cp)
71 {
72 unsigned int a[4] ; unsigned long ret ;
73 sscanf(cp, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) ;
74 ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ;
75 return(ret) ;
76 }
77 #if defined(HAVE_KEIL_RTX)
78 #define XSLEEP_MS(t) os_dly_wait(t)
79 #elif defined(WOLFSSL_CMSIS_RTOS) || defined(WOLFSSL_CMSIS_RTOSv2)
80 #define XSLEEP_MS(t) osDelay(t)
81 #endif
82#elif defined(WOLFSSL_TIRTOS)
83 #include <string.h>
84 #include <netdb.h>
85 #include <sys/types.h>
86 #include <arpa/inet.h>
87 #include <sys/socket.h>
88 #include <ti/sysbios/knl/Task.h>
89 struct hostent {
90 char *h_name; /* official name of host */
91 char **h_aliases; /* alias list */
92 int h_addrtype; /* host address type */
93 int h_length; /* length of address */
94 char **h_addr_list; /* list of addresses from name server */
95 };
96 #define SOCKET_T int
97 #define XSLEEP_MS(t) Task_sleep(t/1000)
98#elif defined(WOLFSSL_VXWORKS)
99 #include <hostLib.h>
100 #include <sockLib.h>
101 #include <arpa/inet.h>
102 #include <string.h>
103 #include <selectLib.h>
104 #include <sys/types.h>
105 #include <netinet/in.h>
106 #include <fcntl.h>
107 #include <sys/time.h>
108 #include <netdb.h>
109 #include <pthread.h>
110 #define SOCKET_T int
111#elif defined(WOLFSSL_ZEPHYR)
112 #include <string.h>
113 #include <sys/types.h>
114 #include <net/socket.h>
115 #define SOCKET_T int
116 #define SOL_SOCKET 1
117 #define SO_REUSEADDR 201
118 #define WOLFSSL_USE_GETADDRINFO
119
120 static unsigned long inet_addr(const char *cp)
121 {
122 unsigned int a[4]; unsigned long ret;
123 int i, j;
124 for (i=0, j=0; i<4; i++) {
125 a[i] = 0;
126 while (cp[j] != '.' && cp[j] != '\0') {
127 a[i] *= 10;
128 a[i] += cp[j] - '0';
129 j++;
130 }
131 }
132 ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ;
133 return(ret) ;
134 }
135#else
136 #include <string.h>
137 #include <sys/types.h>
138#ifndef WOLFSSL_LEANPSK
139 #include <unistd.h>
140 #include <netdb.h>
141 #include <netinet/in.h>
142 #include <netinet/tcp.h>
143 #include <arpa/inet.h>
144 #include <sys/ioctl.h>
145 #include <sys/time.h>
146 #include <sys/socket.h>
147 #include <pthread.h>
148 #include <fcntl.h>
149 #ifdef TEST_IPV6
150 #include <netdb.h>
151 #endif
152#endif
153 #ifdef FREESCALE_MQX
154 typedef int socklen_t ;
155 #endif
156 #define SOCKET_T int
157 #ifndef SO_NOSIGPIPE
158 #include <signal.h> /* ignore SIGPIPE */
159 #endif
160 #define SNPRINTF snprintf
161
162 #define XSELECT_WAIT(x,y) do { \
163 struct timeval tv = {(x),(y)}; \
164 select(0, NULL, NULL, NULL, &tv); \
165 } while (0)
166 #define XSLEEP_US(u) XSELECT_WAIT(0,u)
167 #define XSLEEP_MS(m) XSELECT_WAIT(0,(m)*1000)
168#endif /* USE_WINDOWS_API */
169
170#ifndef XSLEEP_MS
171 #define XSLEEP_MS(t) sleep(t/1000)
172#endif
173
174#ifdef WOLFSSL_ASYNC_CRYPT
175 #include <wolfssl/wolfcrypt/async.h>
176#endif
177#ifdef HAVE_CAVIUM
178 #include <wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h>
179#endif
180#ifdef _MSC_VER
181 /* disable conversion warning */
182 /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
183 #pragma warning(disable:4244 4996)
184#endif
185
186#ifndef WOLFSSL_CIPHER_LIST_MAX_SIZE
187 #define WOLFSSL_CIPHER_LIST_MAX_SIZE 4096
188#endif
189/* Buffer for benchmark tests */
190#ifndef TEST_BUFFER_SIZE
191 #define TEST_BUFFER_SIZE 16384
192#endif
193
194#ifndef WOLFSSL_HAVE_MIN
195 #define WOLFSSL_HAVE_MIN
196 static WC_INLINE word32 min(word32 a, word32 b)
197 {
198 return a > b ? b : a;
199 }
200#endif /* WOLFSSL_HAVE_MIN */
201
202/* Socket Handling */
203#ifndef WOLFSSL_SOCKET_INVALID
204#ifdef USE_WINDOWS_API
205 #define WOLFSSL_SOCKET_INVALID ((SOCKET_T)INVALID_SOCKET)
206#elif defined(WOLFSSL_TIRTOS)
207 #define WOLFSSL_SOCKET_INVALID ((SOCKET_T)-1)
208#else
209 #define WOLFSSL_SOCKET_INVALID (SOCKET_T)(0)
210#endif
211#endif /* WOLFSSL_SOCKET_INVALID */
212
213#ifndef WOLFSSL_SOCKET_IS_INVALID
214#if defined(USE_WINDOWS_API) || defined(WOLFSSL_TIRTOS)
215 #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) == WOLFSSL_SOCKET_INVALID)
216#else
217 #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) < WOLFSSL_SOCKET_INVALID)
218#endif
219#endif /* WOLFSSL_SOCKET_IS_INVALID */
220
221#if defined(__MACH__) || defined(USE_WINDOWS_API)
222 #ifndef _SOCKLEN_T
223 typedef int socklen_t;
224 #endif
225#endif
226
227
228/* HPUX doesn't use socklent_t for third parameter to accept, unless
229 _XOPEN_SOURCE_EXTENDED is defined */
230#if !defined(__hpux__) && !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_IAR_ARM)\
231 && !defined(WOLFSSL_ROWLEY_ARM) && !defined(WOLFSSL_KEIL_TCP_NET)
232 typedef socklen_t* ACCEPT_THIRD_T;
233#else
234 #if defined _XOPEN_SOURCE_EXTENDED
235 typedef socklen_t* ACCEPT_THIRD_T;
236 #else
237 typedef int* ACCEPT_THIRD_T;
238 #endif
239#endif
240
241
242
243#ifdef SINGLE_THREADED
244 typedef unsigned int THREAD_RETURN;
245 typedef void* THREAD_TYPE;
246 #define WOLFSSL_THREAD
247#else
248 #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
249 typedef void* THREAD_RETURN;
250 typedef pthread_t THREAD_TYPE;
251 #define WOLFSSL_THREAD
252 #define INFINITE -1
253 #define WAIT_OBJECT_0 0L
254 #elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_KEIL_TCP_NET) || defined(FREESCALE_MQX)
255 typedef unsigned int THREAD_RETURN;
256 typedef int THREAD_TYPE;
257 #define WOLFSSL_THREAD
258 #elif defined(WOLFSSL_TIRTOS)
259 typedef void THREAD_RETURN;
260 typedef Task_Handle THREAD_TYPE;
261 #define WOLFSSL_THREAD
262 #elif defined(WOLFSSL_ZEPHYR)
263 typedef void THREAD_RETURN;
264 typedef struct k_thread THREAD_TYPE;
265 #define WOLFSSL_THREAD
266 #else
267 typedef unsigned int THREAD_RETURN;
268 typedef intptr_t THREAD_TYPE;
269 #define WOLFSSL_THREAD __stdcall
270 #endif
271#endif
272
273
274#ifdef TEST_IPV6
275 typedef struct sockaddr_in6 SOCKADDR_IN_T;
276 #define AF_INET_V AF_INET6
277#else
278 typedef struct sockaddr_in SOCKADDR_IN_T;
279 #define AF_INET_V AF_INET
280#endif
281
282
283#ifndef WOLFSSL_NO_TLS12
284#define SERVER_DEFAULT_VERSION 3
285#else
286#define SERVER_DEFAULT_VERSION 4
287#endif
288#define SERVER_DTLS_DEFAULT_VERSION (-2)
289#define SERVER_INVALID_VERSION (-99)
290#define SERVER_DOWNGRADE_VERSION (-98)
291#ifndef WOLFSSL_NO_TLS12
292#define CLIENT_DEFAULT_VERSION 3
293#else
294#define CLIENT_DEFAULT_VERSION 4
295#endif
296#define CLIENT_DTLS_DEFAULT_VERSION (-2)
297#define CLIENT_INVALID_VERSION (-99)
298#define CLIENT_DOWNGRADE_VERSION (-98)
299#define EITHER_DOWNGRADE_VERSION (-97)
300#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
301 #define DEFAULT_MIN_DHKEY_BITS 2048
302 #define DEFAULT_MAX_DHKEY_BITS 3072
303#else
304 #define DEFAULT_MIN_DHKEY_BITS 1024
305 #define DEFAULT_MAX_DHKEY_BITS 2048
306#endif
307#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
308 #define DEFAULT_MIN_RSAKEY_BITS 2048
309#else
310 #ifndef DEFAULT_MIN_RSAKEY_BITS
311 #define DEFAULT_MIN_RSAKEY_BITS 1024
312 #endif
313#endif
314#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
315 #define DEFAULT_MIN_ECCKEY_BITS 256
316#else
317 #ifndef DEFAULT_MIN_ECCKEY_BITS
318 #define DEFAULT_MIN_ECCKEY_BITS 224
319 #endif
320#endif
321
322/* all certs relative to wolfSSL home directory now */
323#if defined(WOLFSSL_NO_CURRDIR) || defined(WOLFSSL_MDK_SHELL)
324#define caCertFile "certs/ca-cert.pem"
325#define eccCertFile "certs/server-ecc.pem"
326#define eccKeyFile "certs/ecc-key.pem"
327#define eccRsaCertFile "certs/server-ecc-rsa.pem"
328#define svrCertFile "certs/server-cert.pem"
329#define svrKeyFile "certs/server-key.pem"
330#define cliCertFile "certs/client-cert.pem"
331#define cliCertDerFile "certs/client-cert.der"
332#define cliCertFileExt "certs/client-cert-ext.pem"
333#define cliCertDerFileExt "certs/client-cert-ext.der"
334#define cliKeyFile "certs/client-key.pem"
335#define ntruCertFile "certs/ntru-cert.pem"
336#define ntruKeyFile "certs/ntru-key.raw"
337#define dhParamFile "certs/dh2048.pem"
338#define cliEccKeyFile "certs/ecc-client-key.pem"
339#define cliEccCertFile "certs/client-ecc-cert.pem"
340#define caEccCertFile "certs/ca-ecc-cert.pem"
341#define crlPemDir "certs/crl"
342#define edCertFile "certs/ed25519/server-ed25519-cert.pem"
343#define edKeyFile "certs/ed25519/server-ed25519-priv.pem"
344#define cliEdCertFile "certs/ed25519/client-ed25519.pem"
345#define cliEdKeyFile "certs/ed25519/client-ed25519-priv.pem"
346#define caEdCertFile "certs/ed25519/ca-ed25519.pem"
347#define ed448CertFile "certs/ed448/server-ed448-cert.pem"
348#define ed448KeyFile "certs/ed448/server-ed448-priv.pem"
349#define cliEd448CertFile "certs/ed448/client-ed448.pem"
350#define cliEd448KeyFile "certs/ed448/client-ed448-priv.pem"
351#define caEd448CertFile "certs/ed448/ca-ed448.pem"
352#ifdef HAVE_WNR
353 /* Whitewood netRandom default config file */
354 #define wnrConfig "wnr-example.conf"
355#endif
356#else
357#define caCertFile "./certs/ca-cert.pem"
358#define eccCertFile "./certs/server-ecc.pem"
359#define eccKeyFile "./certs/ecc-key.pem"
360#define eccRsaCertFile "./certs/server-ecc-rsa.pem"
361#define svrCertFile "./certs/server-cert.pem"
362#define svrKeyFile "./certs/server-key.pem"
363#define cliCertFile "./certs/client-cert.pem"
364#define cliCertDerFile "./certs/client-cert.der"
365#define cliCertFileExt "./certs/client-cert-ext.pem"
366#define cliCertDerFileExt "./certs/client-cert-ext.der"
367#define cliKeyFile "./certs/client-key.pem"
368#define ntruCertFile "./certs/ntru-cert.pem"
369#define ntruKeyFile "./certs/ntru-key.raw"
370#define dhParamFile "./certs/dh2048.pem"
371#define cliEccKeyFile "./certs/ecc-client-key.pem"
372#define cliEccCertFile "./certs/client-ecc-cert.pem"
373#define caEccCertFile "./certs/ca-ecc-cert.pem"
374#define crlPemDir "./certs/crl"
375#define edCertFile "./certs/ed25519/server-ed25519-cert.pem"
376#define edKeyFile "./certs/ed25519/server-ed25519-priv.pem"
377#define cliEdCertFile "./certs/ed25519/client-ed25519.pem"
378#define cliEdKeyFile "./certs/ed25519/client-ed25519-priv.pem"
379#define caEdCertFile "./certs/ed25519/ca-ed25519.pem"
380#define ed448CertFile "./certs/ed448/server-ed448-cert.pem"
381#define ed448KeyFile "./certs/ed448/server-ed448-priv.pem"
382#define cliEd448CertFile "./certs/ed448/client-ed448.pem"
383#define cliEd448KeyFile "./certs/ed448/client-ed448-priv.pem"
384#define caEd448CertFile "./certs/ed448/ca-ed448.pem"
385#ifdef HAVE_WNR
386 /* Whitewood netRandom default config file */
387 #define wnrConfig "./wnr-example.conf"
388#endif
389#endif
390
391typedef struct tcp_ready {
392 word16 ready; /* predicate */
393 word16 port;
394 char* srfName; /* server ready file name */
395#if defined(_POSIX_THREADS) && !defined(__MINGW32__)
396 pthread_mutex_t mutex;
397 pthread_cond_t cond;
398#endif
399} tcp_ready;
400
401
402static WC_INLINE void InitTcpReady(tcp_ready* ready)
403{
404 ready->ready = 0;
405 ready->port = 0;
406 ready->srfName = NULL;
407#ifdef SINGLE_THREADED
408#elif defined(_POSIX_THREADS) && !defined(__MINGW32__)
409 pthread_mutex_init(&ready->mutex, 0);
410 pthread_cond_init(&ready->cond, 0);
411#endif
412}
413
414
415static WC_INLINE void FreeTcpReady(tcp_ready* ready)
416{
417#ifdef SINGLE_THREADED
418 (void)ready;
419#elif defined(_POSIX_THREADS) && !defined(__MINGW32__)
420 pthread_mutex_destroy(&ready->mutex);
421 pthread_cond_destroy(&ready->cond);
422#else
423 (void)ready;
424#endif
425}
426
427typedef WOLFSSL_METHOD* (*method_provider)(void);
428typedef void (*ctx_callback)(WOLFSSL_CTX* ctx);
429typedef void (*ssl_callback)(WOLFSSL* ssl);
430
431typedef struct callback_functions {
432 method_provider method;
433 ctx_callback ctx_ready;
434 ssl_callback ssl_ready;
435 ssl_callback on_result;
436 WOLFSSL_CTX* ctx;
437 unsigned char isSharedCtx:1;
438} callback_functions;
439
440typedef struct func_args {
441 int argc;
442 char** argv;
443 int return_code;
444 tcp_ready* signal;
445 callback_functions *callbacks;
446} func_args;
447
448
449
450
451void wait_tcp_ready(func_args*);
452
453#ifdef WOLFSSL_ZEPHYR
454typedef void THREAD_FUNC(void*, void*, void*);
455#else
456typedef THREAD_RETURN WOLFSSL_THREAD THREAD_FUNC(void*);
457#endif
458
459void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*);
460void join_thread(THREAD_TYPE);
461
462/* wolfSSL */
463#ifndef TEST_IPV6
464 static const char* const wolfSSLIP = "127.0.0.1";
465#else
466 static const char* const wolfSSLIP = "::1";
467#endif
468static const word16 wolfSSLPort = 11111;
469
470
471
472#ifndef MY_EX_USAGE
473#define MY_EX_USAGE 2
474#endif
475
476#ifndef EXIT_FAILURE
477#define EXIT_FAILURE 1
478#endif
479
480#if defined(WOLFSSL_FORCE_MALLOC_FAIL_TEST) || defined(WOLFSSL_ZEPHYR)
481 #ifndef EXIT_SUCCESS
482 #define EXIT_SUCCESS 0
483 #endif
484 #define XEXIT(rc) return rc
485 #define XEXIT_T(rc) return (THREAD_RETURN)rc
486#else
487 #define XEXIT(rc) exit((int)(rc))
488 #define XEXIT_T(rc) exit((int)(rc))
489#endif
490
491
492static WC_INLINE
493#if defined(WOLFSSL_FORCE_MALLOC_FAIL_TEST) || defined(WOLFSSL_ZEPHYR)
494THREAD_RETURN
495#else
496WC_NORETURN void
497#endif
498err_sys(const char* msg)
499{
500#if !defined(__GNUC__)
501 /* scan-build (which pretends to be gnuc) can get confused and think the
502 * msg pointer can be null even when hardcoded and then it won't exit,
503 * making null pointer checks above the err_sys() call useless.
504 * We could just always exit() but some compilers will complain about no
505 * possible return, with gcc we know the attribute to handle that with
506 * WC_NORETURN. */
507 if (msg)
508#endif
509 {
510 printf("wolfSSL error: %s\n", msg);
511
512 XEXIT_T(EXIT_FAILURE);
513 }
514}
515
516static WC_INLINE
517#if defined(WOLFSSL_FORCE_MALLOC_FAIL_TEST) || defined(WOLFSSL_ZEPHYR)
518THREAD_RETURN
519#else
520WC_NORETURN void
521#endif
522err_sys_with_errno(const char* msg)
523{
524#if !defined(__GNUC__)
525 /* scan-build (which pretends to be gnuc) can get confused and think the
526 * msg pointer can be null even when hardcoded and then it won't exit,
527 * making null pointer checks above the err_sys() call useless.
528 * We could just always exit() but some compilers will complain about no
529 * possible return, with gcc we know the attribute to handle that with
530 * WC_NORETURN. */
531 if (msg)
532#endif
533 {
534#if defined(HAVE_STRING_H) && defined(HAVE_ERRNO_H)
535 printf("wolfSSL error: %s: %s\n", msg, strerror(errno));
536#else
537 printf("wolfSSL error: %s\n", msg);
538#endif
539
540 XEXIT_T(EXIT_FAILURE);
541 }
542}
543
544
545extern int myoptind;
546extern char* myoptarg;
547
548/**
549 *
550 * @param argc Number of argv strings
551 * @param argv Array of string arguments
552 * @param optstring String containing the supported alphanumeric arguments.
553 * A ':' following a character means that it requires a
554 * value in myoptarg to be set. A ';' means that the
555 * myoptarg is optional. myoptarg is set to "" if not
556 * present.
557 * @return Option letter in argument
558 */
559static WC_INLINE int mygetopt(int argc, char** argv, const char* optstring)
560{
561 static char* next = NULL;
562
563 char c;
564 char* cp;
565
566 /* Added sanity check becuase scan-build complains argv[myoptind] access
567 * results in a null pointer dereference. */
568 if (argv == NULL) {
569 myoptarg = NULL;
570 return -1;
571 }
572
573 if (myoptind == 0)
574 next = NULL; /* we're starting new/over */
575
576 if (next == NULL || *next == '\0') {
577 if (myoptind == 0)
578 myoptind++;
579
580 if (myoptind >= argc || argv[myoptind] == NULL ||
581 argv[myoptind][0] != '-' || argv[myoptind][1] == '\0') {
582 myoptarg = NULL;
583 if (myoptind < argc)
584 myoptarg = argv[myoptind];
585
586 return -1;
587 }
588
589 if (strcmp(argv[myoptind], "--") == 0) {
590 myoptind++;
591 myoptarg = NULL;
592
593 if (myoptind < argc)
594 myoptarg = argv[myoptind];
595
596 return -1;
597 }
598
599 next = argv[myoptind];
600 next++; /* skip - */
601 myoptind++;
602 }
603
604 c = *next++;
605 /* The C++ strchr can return a different value */
606 cp = (char*)strchr(optstring, c);
607
608 if (cp == NULL || c == ':' || c == ';')
609 return '?';
610
611 cp++;
612
613 if (*cp == ':') {
614 if (*next != '\0') {
615 myoptarg = next;
616 next = NULL;
617 }
618 else if (myoptind < argc) {
619 myoptarg = argv[myoptind];
620 myoptind++;
621 }
622 else
623 return '?';
624 }
625 else if (*cp == ';') {
626 myoptarg = (char*)"";
627 if (*next != '\0') {
628 myoptarg = next;
629 next = NULL;
630 }
631 else if (myoptind < argc) {
632 /* Check if next argument is not a parameter argument */
633 if (argv[myoptind] && argv[myoptind][0] != '-') {
634 myoptarg = argv[myoptind];
635 myoptind++;
636 }
637 }
638 }
639
640 return c;
641}
642
643
644#ifdef WOLFSSL_ENCRYPTED_KEYS
645
646static WC_INLINE int PasswordCallBack(char* passwd, int sz, int rw, void* userdata)
647{
648 (void)rw;
649 (void)userdata;
650 if (userdata != NULL) {
651 strncpy(passwd, (char*)userdata, sz);
652 return (int)XSTRLEN((char*)userdata);
653 }
654 else {
655 strncpy(passwd, "yassl123", sz);
656 return 8;
657 }
658}
659
660#endif
661
662static const char* client_showpeer_msg[][8] = {
663 /* English */
664 {
665 "SSL version is",
666 "SSL cipher suite is",
667 "SSL curve name is",
668 "SSL DH size is",
669 "SSL reused session",
670 "Alternate cert chain used",
671 "peer's cert info:",
672 NULL
673 },
674#ifndef NO_MULTIBYTE_PRINT
675 /* Japanese */
676 {
677 "SSL バージョンは",
678 "SSL 暗号スイートは",
679 "SSL 曲線名は",
680 "SSL DH サイズは",
681 "SSL 再利用セッション",
682 "代替証明チェーンを使用",
683 "相手方証明書情報",
684 NULL
685 },
686#endif
687};
688
689#if defined(KEEP_PEER_CERT) || defined(KEEP_OUR_CERT) || defined(SESSION_CERTS)
690static const char* client_showx509_msg[][5] = {
691 /* English */
692 {
693 "issuer",
694 "subject",
695 "altname",
696 "serial number",
697 NULL
698 },
699#ifndef NO_MULTIBYTE_PRINT
700 /* Japanese */
701 {
702 "発行者",
703 "サブジェクト",
704 "代替名",
705 "シリアル番号",
706 NULL
707 },
708#endif
709};
710
711/* lng_index is to specify the language for displaying message. */
712/* 0:English, 1:Japanese */
713static WC_INLINE void ShowX509Ex(WOLFSSL_X509* x509, const char* hdr,
714 int lng_index)
715{
716 char* altName;
717 char* issuer;
718 char* subject;
719 byte serial[32];
720 int ret;
721 int sz = sizeof(serial);
722 const char** words = client_showx509_msg[lng_index];
723
724 if (x509 == NULL) {
725 printf("%s No Cert\n", hdr);
726 return;
727 }
728
729 issuer = wolfSSL_X509_NAME_oneline(
730 wolfSSL_X509_get_issuer_name(x509), 0, 0);
731 subject = wolfSSL_X509_NAME_oneline(
732 wolfSSL_X509_get_subject_name(x509), 0, 0);
733
734 printf("%s\n %s : %s\n %s: %s\n", hdr, words[0], issuer, words[1], subject);
735
736 while ( (altName = wolfSSL_X509_get_next_altname(x509)) != NULL)
737 printf(" %s = %s\n", words[2], altName);
738
739 ret = wolfSSL_X509_get_serial_number(x509, serial, &sz);
740 if (ret == WOLFSSL_SUCCESS) {
741 int i;
742 int strLen;
743 char serialMsg[80];
744
745 /* testsuite has multiple threads writing to stdout, get output
746 message ready to write once */
747 strLen = sprintf(serialMsg, " %s", words[3]);
748 for (i = 0; i < sz; i++)
749 sprintf(serialMsg + strLen + (i*3), ":%02x ", serial[i]);
750 printf("%s\n", serialMsg);
751 }
752
753 XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
754 XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL);
755
756#if defined(SHOW_CERTS) && defined(OPENSSL_EXTRA)
757 {
758 WOLFSSL_BIO* bio;
759 char buf[256]; /* should be size of ASN_NAME_MAX */
760 int textSz;
761
762 /* print out domain component if certificate has it */
763 textSz = wolfSSL_X509_NAME_get_text_by_NID(
764 wolfSSL_X509_get_subject_name(x509), NID_domainComponent,
765 buf, sizeof(buf));
766 if (textSz > 0) {
767 printf("Domain Component = %s\n", buf);
768 }
769
770 bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
771 if (bio != NULL) {
772 wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE);
773 wolfSSL_X509_print(bio, x509);
774 wolfSSL_BIO_free(bio);
775 }
776 }
777#endif /* SHOW_CERTS && OPENSSL_EXTRA */
778}
779/* original ShowX509 to maintain compatibility */
780static WC_INLINE void ShowX509(WOLFSSL_X509* x509, const char* hdr)
781{
782 ShowX509Ex(x509, hdr, 0);
783}
784
785#endif /* KEEP_PEER_CERT || KEEP_OUR_CERT || SESSION_CERTS */
786
787#if defined(SHOW_CERTS) && defined(SESSION_CERTS) && \
788 (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
789static WC_INLINE void ShowX509Chain(WOLFSSL_X509_CHAIN* chain, int count,
790 const char* hdr)
791{
792 int i;
793 int length;
794 unsigned char buffer[3072];
795 WOLFSSL_X509* chainX509;
796
797 for (i = 0; i < count; i++) {
798 wolfSSL_get_chain_cert_pem(chain, i, buffer, sizeof(buffer), &length);
799 buffer[length] = 0;
800 printf("\n%s: %d has length %d data = \n%s\n", hdr, i, length, buffer);
801
802 chainX509 = wolfSSL_get_chain_X509(chain, i);
803 if (chainX509)
804 ShowX509(chainX509, hdr);
805 else
806 printf("get_chain_X509 failed\n");
807 wolfSSL_FreeX509(chainX509);
808 }
809}
810#endif /* SHOW_CERTS && SESSION_CERTS */
811
812/* lng_index is to specify the language for displaying message. */
813/* 0:English, 1:Japanese */
814static WC_INLINE void showPeerEx(WOLFSSL* ssl, int lng_index)
815{
816 WOLFSSL_CIPHER* cipher;
817 const char** words = client_showpeer_msg[lng_index];
818
819#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
820 !defined(NO_DH)
821 const char *name;
822#endif
823#ifndef NO_DH
824 int bits;
825#endif
826#ifdef KEEP_PEER_CERT
827 WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
828 if (peer)
829 ShowX509Ex(peer, words[6], lng_index);
830 else
831 printf("peer has no cert!\n");
832 wolfSSL_FreeX509(peer);
833#endif
834#if defined(SHOW_CERTS) && defined(KEEP_OUR_CERT) && \
835 (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
836 ShowX509(wolfSSL_get_certificate(ssl), "our cert info:");
837 printf("Peer verify result = %lu\n", wolfSSL_get_verify_result(ssl));
838#endif /* SHOW_CERTS && KEEP_OUR_CERT */
839 printf("%s %s\n", words[0], wolfSSL_get_version(ssl));
840
841 cipher = wolfSSL_get_current_cipher(ssl);
842#ifdef HAVE_QSH
843 printf("%s %s%s\n", words[1], (wolfSSL_isQSH(ssl))? "QSH:": "",
844 wolfSSL_CIPHER_get_name(cipher));
845#else
846 printf("%s %s\n", words[1], wolfSSL_CIPHER_get_name(cipher));
847#endif
848#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
849 !defined(NO_DH)
850 if ((name = wolfSSL_get_curve_name(ssl)) != NULL)
851 printf("%s %s\n", words[2], name);
852#endif
853#ifndef NO_DH
854 else if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0)
855 printf("%s %d bits\n", words[3], bits);
856#endif
857 if (wolfSSL_session_reused(ssl))
858 printf("%s\n", words[4]);
859#ifdef WOLFSSL_ALT_CERT_CHAINS
860 if (wolfSSL_is_peer_alt_cert_chain(ssl))
861 printf("%s\n", words[5]);
862#endif
863
864#if defined(SHOW_CERTS) && defined(SESSION_CERTS) && \
865 (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
866 {
867 WOLFSSL_X509_CHAIN* chain;
868
869 chain = wolfSSL_get_peer_chain(ssl);
870 ShowX509Chain(chain, wolfSSL_get_chain_count(chain), "session cert");
871
872 #ifdef WOLFSSL_ALT_CERT_CHAINS
873 if (wolfSSL_is_peer_alt_cert_chain(ssl)) {
874 chain = wolfSSL_get_peer_alt_chain(ssl);
875 ShowX509Chain(chain, wolfSSL_get_chain_count(chain), "alt cert");
876 }
877 #endif
878 }
879#endif /* SHOW_CERTS && SESSION_CERTS */
880 (void)ssl;
881}
882/* original showPeer to maintain compatibility */
883static WC_INLINE void showPeer(WOLFSSL* ssl)
884{
885 showPeerEx(ssl, 0);
886}
887
888static WC_INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
889 word16 port, int udp, int sctp)
890{
891 int useLookup = 0;
892 (void)useLookup;
893 (void)udp;
894 (void)sctp;
895
896 if (addr == NULL)
897 err_sys("invalid argument to build_addr, addr is NULL");
898
899 XMEMSET(addr, 0, sizeof(SOCKADDR_IN_T));
900
901#ifndef TEST_IPV6
902 /* peer could be in human readable form */
903 if ( ((size_t)peer != INADDR_ANY) && isalpha((int)peer[0])) {
904 #ifndef WOLFSSL_USE_GETADDRINFO
905 #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
906 int err;
907 struct hostent* entry = gethostbyname(peer, &err);
908 #elif defined(WOLFSSL_TIRTOS)
909 struct hostent* entry = DNSGetHostByName(peer);
910 #elif defined(WOLFSSL_VXWORKS)
911 struct hostent* entry = (struct hostent*)hostGetByName((char*)peer);
912 #else
913 struct hostent* entry = gethostbyname(peer);
914 #endif
915
916 if (entry) {
917 XMEMCPY(&addr->sin_addr.s_addr, entry->h_addr_list[0],
918 entry->h_length);
919 useLookup = 1;
920 }
921 #else
922 struct zsock_addrinfo hints, *addrInfo;
923 char portStr[6];
924 XSNPRINTF(portStr, sizeof(portStr), "%d", port);
925 memset(&hints, 0, sizeof(hints));
926 hints.ai_family = AF_UNSPEC;
927 hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM;
928 hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP;
929 if (getaddrinfo((char*)peer, portStr, &hints, &addrInfo) == 0) {
930 XMEMCPY(addr, addrInfo->ai_addr, sizeof(*addr));
931 useLookup = 1;
932 }
933 #endif
934 else
935 err_sys("no entry for host");
936 }
937#endif
938
939
940#ifndef TEST_IPV6
941 #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
942 addr->sin_family = PF_INET;
943 #else
944 addr->sin_family = AF_INET_V;
945 #endif
946 addr->sin_port = XHTONS(port);
947 if ((size_t)peer == INADDR_ANY)
948 addr->sin_addr.s_addr = INADDR_ANY;
949 else {
950 if (!useLookup)
951 addr->sin_addr.s_addr = inet_addr(peer);
952 }
953#else
954 addr->sin6_family = AF_INET_V;
955 addr->sin6_port = XHTONS(port);
956 if ((size_t)peer == INADDR_ANY) {
957 addr->sin6_addr = in6addr_any;
958 }
959 else {
960 #if defined(HAVE_GETADDRINFO) || defined(WOLF_C99)
961 struct addrinfo hints;
962 struct addrinfo* answer = NULL;
963 int ret;
964 char strPort[80];
965
966 XMEMSET(&hints, 0, sizeof(hints));
967
968 hints.ai_family = AF_INET_V;
969 if (udp) {
970 hints.ai_socktype = SOCK_DGRAM;
971 hints.ai_protocol = IPPROTO_UDP;
972 }
973 #ifdef WOLFSSL_SCTP
974 else if (sctp) {
975 hints.ai_socktype = SOCK_STREAM;
976 hints.ai_protocol = IPPROTO_SCTP;
977 }
978 #endif
979 else {
980 hints.ai_socktype = SOCK_STREAM;
981 hints.ai_protocol = IPPROTO_TCP;
982 }
983
984 SNPRINTF(strPort, sizeof(strPort), "%d", port);
985 strPort[79] = '\0';
986
987 ret = getaddrinfo(peer, strPort, &hints, &answer);
988 if (ret < 0 || answer == NULL)
989 err_sys("getaddrinfo failed");
990
991 XMEMCPY(addr, answer->ai_addr, answer->ai_addrlen);
992 freeaddrinfo(answer);
993 #else
994 printf("no ipv6 getaddrinfo, loopback only tests/examples\n");
995 addr->sin6_addr = in6addr_loopback;
996 #endif
997 }
998#endif
999}
1000
1001
1002static WC_INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp)
1003{
1004 (void)sctp;
1005
1006 if (udp)
1007 *sockfd = socket(AF_INET_V, SOCK_DGRAM, IPPROTO_UDP);
1008#ifdef WOLFSSL_SCTP
1009 else if (sctp)
1010 *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_SCTP);
1011#endif
1012 else
1013 *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_TCP);
1014
1015 if(WOLFSSL_SOCKET_IS_INVALID(*sockfd)) {
1016 err_sys_with_errno("socket failed\n");
1017 }
1018
1019#ifndef USE_WINDOWS_API
1020#ifdef SO_NOSIGPIPE
1021 {
1022 int on = 1;
1023 socklen_t len = sizeof(on);
1024 int res = setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len);
1025 if (res < 0)
1026 err_sys_with_errno("setsockopt SO_NOSIGPIPE failed\n");
1027 }
1028#elif defined(WOLFSSL_MDK_ARM) || defined (WOLFSSL_TIRTOS) ||\
1029 defined(WOLFSSL_KEIL_TCP_NET) || defined(WOLFSSL_ZEPHYR)
1030 /* nothing to define */
1031#else /* no S_NOSIGPIPE */
1032 signal(SIGPIPE, SIG_IGN);
1033#endif /* S_NOSIGPIPE */
1034
1035#if defined(TCP_NODELAY)
1036 if (!udp && !sctp)
1037 {
1038 int on = 1;
1039 socklen_t len = sizeof(on);
1040 int res = setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, &on, len);
1041 if (res < 0)
1042 err_sys_with_errno("setsockopt TCP_NODELAY failed\n");
1043 }
1044#endif
1045#endif /* USE_WINDOWS_API */
1046}
1047
1048static WC_INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port,
1049 int udp, int sctp, WOLFSSL* ssl)
1050{
1051 SOCKADDR_IN_T addr;
1052 build_addr(&addr, ip, port, udp, sctp);
1053 if (udp) {
1054 wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr));
1055 }
1056 tcp_socket(sockfd, udp, sctp);
1057
1058 if (!udp) {
1059 if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
1060 err_sys_with_errno("tcp connect failed");
1061 }
1062}
1063
1064
1065static WC_INLINE void udp_connect(SOCKET_T* sockfd, void* addr, int addrSz)
1066{
1067 if (connect(*sockfd, (const struct sockaddr*)addr, addrSz) != 0)
1068 err_sys_with_errno("tcp connect failed");
1069}
1070
1071
1072enum {
1073 TEST_SELECT_FAIL,
1074 TEST_TIMEOUT,
1075 TEST_RECV_READY,
1076 TEST_SEND_READY,
1077 TEST_ERROR_READY
1078};
1079
1080
1081#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && \
1082 !defined(WOLFSSL_TIRTOS)
1083static WC_INLINE int tcp_select_ex(SOCKET_T socketfd, int to_sec, int rx)
1084{
1085 fd_set fds, errfds;
1086 fd_set* recvfds = NULL;
1087 fd_set* sendfds = NULL;
1088 SOCKET_T nfds = socketfd + 1;
1089#if !defined(__INTEGRITY)
1090 struct timeval timeout = {(to_sec > 0) ? to_sec : 0, 0};
1091#else
1092 struct timeval timeout;
1093#endif
1094 int result;
1095
1096 FD_ZERO(&fds);
1097 FD_SET(socketfd, &fds);
1098 FD_ZERO(&errfds);
1099 FD_SET(socketfd, &errfds);
1100
1101 if (rx)
1102 recvfds = &fds;
1103 else
1104 sendfds = &fds;
1105
1106#if defined(__INTEGRITY)
1107 timeout.tv_sec = (long long)(to_sec > 0) ? to_sec : 0, 0;
1108#endif
1109 result = select(nfds, recvfds, sendfds, &errfds, &timeout);
1110
1111 if (result == 0)
1112 return TEST_TIMEOUT;
1113 else if (result > 0) {
1114 if (FD_ISSET(socketfd, &fds)) {
1115 if (rx)
1116 return TEST_RECV_READY;
1117 else
1118 return TEST_SEND_READY;
1119 }
1120 else if(FD_ISSET(socketfd, &errfds))
1121 return TEST_ERROR_READY;
1122 }
1123
1124 return TEST_SELECT_FAIL;
1125}
1126
1127static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
1128{
1129 return tcp_select_ex(socketfd, to_sec, 1);
1130}
1131
1132static WC_INLINE int tcp_select_tx(SOCKET_T socketfd, int to_sec)
1133{
1134 return tcp_select_ex(socketfd, to_sec, 0);
1135}
1136
1137#elif defined(WOLFSSL_TIRTOS) || defined(WOLFSSL_KEIL_TCP_NET)
1138static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
1139{
1140 return TEST_RECV_READY;
1141}
1142static WC_INLINE int tcp_select_tx(SOCKET_T socketfd, int to_sec)
1143{
1144 return TEST_SEND_READY;
1145}
1146#endif /* !WOLFSSL_MDK_ARM */
1147
1148
1149static WC_INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr,
1150 int udp, int sctp)
1151{
1152 SOCKADDR_IN_T addr;
1153
1154 /* don't use INADDR_ANY by default, firewall may block, make user switch
1155 on */
1156 build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), *port, udp, sctp);
1157 tcp_socket(sockfd, udp, sctp);
1158
1159#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)\
1160 && !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_ZEPHYR)
1161 {
1162 int res, on = 1;
1163 socklen_t len = sizeof(on);
1164 res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
1165 if (res < 0)
1166 err_sys_with_errno("setsockopt SO_REUSEADDR failed\n");
1167 }
1168#ifdef SO_REUSEPORT
1169 {
1170 int res, on = 1;
1171 socklen_t len = sizeof(on);
1172 res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEPORT, &on, len);
1173 if (res < 0)
1174 err_sys_with_errno("setsockopt SO_REUSEPORT failed\n");
1175 }
1176#endif
1177#endif
1178
1179 if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
1180 err_sys_with_errno("tcp bind failed");
1181 if (!udp) {
1182 #ifdef WOLFSSL_KEIL_TCP_NET
1183 #define SOCK_LISTEN_MAX_QUEUE 1
1184 #else
1185 #define SOCK_LISTEN_MAX_QUEUE 5
1186 #endif
1187 if (listen(*sockfd, SOCK_LISTEN_MAX_QUEUE) != 0)
1188 err_sys_with_errno("tcp listen failed");
1189 }
1190 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS) \
1191 && !defined(WOLFSSL_ZEPHYR)
1192 if (*port == 0) {
1193 socklen_t len = sizeof(addr);
1194 if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
1195 #ifndef TEST_IPV6
1196 *port = XNTOHS(addr.sin_port);
1197 #else
1198 *port = XNTOHS(addr.sin6_port);
1199 #endif
1200 }
1201 }
1202 #endif
1203}
1204
1205
1206#if 0
1207static WC_INLINE int udp_read_connect(SOCKET_T sockfd)
1208{
1209 SOCKADDR_IN_T cliaddr;
1210 byte b[1500];
1211 int n;
1212 socklen_t len = sizeof(cliaddr);
1213
1214 n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
1215 (struct sockaddr*)&cliaddr, &len);
1216 if (n > 0) {
1217 if (connect(sockfd, (const struct sockaddr*)&cliaddr,
1218 sizeof(cliaddr)) != 0)
1219 err_sys("udp connect failed");
1220 }
1221 else
1222 err_sys("recvfrom failed");
1223
1224 return sockfd;
1225}
1226#endif
1227
1228static WC_INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
1229 int useAnyAddr, word16 port, func_args* args)
1230{
1231 SOCKADDR_IN_T addr;
1232
1233 (void)args;
1234 build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), port, 1, 0);
1235 tcp_socket(sockfd, 1, 0);
1236
1237
1238#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM) \
1239 && !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_ZEPHYR)
1240 {
1241 int res, on = 1;
1242 socklen_t len = sizeof(on);
1243 res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
1244 if (res < 0)
1245 err_sys_with_errno("setsockopt SO_REUSEADDR failed\n");
1246 }
1247#ifdef SO_REUSEPORT
1248 {
1249 int res, on = 1;
1250 socklen_t len = sizeof(on);
1251 res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEPORT, &on, len);
1252 if (res < 0)
1253 err_sys_with_errno("setsockopt SO_REUSEPORT failed\n");
1254 }
1255#endif
1256#endif
1257
1258 if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
1259 err_sys_with_errno("tcp bind failed");
1260
1261 #if (defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)) && !defined(WOLFSSL_TIRTOS)
1262 if (port == 0) {
1263 socklen_t len = sizeof(addr);
1264 if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
1265 #ifndef TEST_IPV6
1266 port = XNTOHS(addr.sin_port);
1267 #else
1268 port = XNTOHS(addr.sin6_port);
1269 #endif
1270 }
1271 }
1272 #endif
1273
1274#if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
1275 /* signal ready to accept data */
1276 {
1277 tcp_ready* ready = args->signal;
1278 pthread_mutex_lock(&ready->mutex);
1279 ready->ready = 1;
1280 ready->port = port;
1281 pthread_cond_signal(&ready->cond);
1282 pthread_mutex_unlock(&ready->mutex);
1283 }
1284#elif defined (WOLFSSL_TIRTOS)
1285 /* Need mutex? */
1286 tcp_ready* ready = args->signal;
1287 ready->ready = 1;
1288 ready->port = port;
1289#else
1290 (void)port;
1291#endif
1292
1293 *clientfd = *sockfd;
1294}
1295
1296static WC_INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
1297 func_args* args, word16 port, int useAnyAddr,
1298 int udp, int sctp, int ready_file, int do_listen)
1299{
1300 SOCKADDR_IN_T client_addr;
1301 socklen_t client_len = sizeof(client_addr);
1302 tcp_ready* ready = NULL;
1303
1304 (void) ready; /* Account for case when "ready" is not used */
1305
1306 if (udp) {
1307 udp_accept(sockfd, clientfd, useAnyAddr, port, args);
1308 return;
1309 }
1310
1311 if(do_listen) {
1312 tcp_listen(sockfd, &port, useAnyAddr, udp, sctp);
1313
1314 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
1315 /* signal ready to tcp_accept */
1316 if (args)
1317 ready = args->signal;
1318 if (ready) {
1319 pthread_mutex_lock(&ready->mutex);
1320 ready->ready = 1;
1321 ready->port = port;
1322 pthread_cond_signal(&ready->cond);
1323 pthread_mutex_unlock(&ready->mutex);
1324 }
1325 #elif defined (WOLFSSL_TIRTOS)
1326 /* Need mutex? */
1327 if (args)
1328 ready = args->signal;
1329 if (ready) {
1330 ready->ready = 1;
1331 ready->port = port;
1332 }
1333 #endif
1334
1335 if (ready_file) {
1336 #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST)
1337 XFILE srf = NULL;
1338 if (args)
1339 ready = args->signal;
1340
1341 if (ready) {
1342 srf = XFOPEN(ready->srfName, "w");
1343
1344 if (srf) {
1345 /* let's write port sever is listening on to ready file
1346 external monitor can then do ephemeral ports by passing
1347 -p 0 to server on supported platforms with -R ready_file
1348 client can then wait for existence of ready_file and see
1349 which port the server is listening on. */
1350 fprintf(srf, "%d\n", (int)port);
1351 fclose(srf);
1352 }
1353 }
1354 #endif
1355 }
1356 }
1357
1358 *clientfd = accept(*sockfd, (struct sockaddr*)&client_addr,
1359 (ACCEPT_THIRD_T)&client_len);
1360 if(WOLFSSL_SOCKET_IS_INVALID(*clientfd)) {
1361 err_sys_with_errno("tcp accept failed");
1362 }
1363}
1364
1365
1366static WC_INLINE void tcp_set_nonblocking(SOCKET_T* sockfd)
1367{
1368 #ifdef USE_WINDOWS_API
1369 unsigned long blocking = 1;
1370 int ret = ioctlsocket(*sockfd, FIONBIO, &blocking);
1371 if (ret == SOCKET_ERROR)
1372 err_sys_with_errno("ioctlsocket failed");
1373 #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) \
1374 || defined (WOLFSSL_TIRTOS)|| defined(WOLFSSL_VXWORKS) \
1375 || defined(WOLFSSL_ZEPHYR)
1376 /* non blocking not supported, for now */
1377 #else
1378 int flags = fcntl(*sockfd, F_GETFL, 0);
1379 if (flags < 0)
1380 err_sys_with_errno("fcntl get failed");
1381 flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK);
1382 if (flags < 0)
1383 err_sys_with_errno("fcntl set failed");
1384 #endif
1385}
1386
1387
1388#ifndef NO_PSK
1389
1390/* identity is OpenSSL testing default for openssl s_client, keep same */
1391static const char* kIdentityStr = "Client_identity";
1392
1393static WC_INLINE unsigned int my_psk_client_cb(WOLFSSL* ssl, const char* hint,
1394 char* identity, unsigned int id_max_len, unsigned char* key,
1395 unsigned int key_max_len)
1396{
1397 (void)ssl;
1398 (void)hint;
1399 (void)key_max_len;
1400
1401 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
1402 XSTRNCPY(identity, kIdentityStr, id_max_len);
1403
1404 if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) {
1405 /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
1406 unsigned binary */
1407 key[0] = 0x1a;
1408 key[1] = 0x2b;
1409 key[2] = 0x3c;
1410 key[3] = 0x4d;
1411
1412 return 4; /* length of key in octets or 0 for error */
1413 }
1414 else {
1415 int i;
1416 int b = 0x01;
1417
1418 for (i = 0; i < 32; i++, b += 0x22) {
1419 if (b >= 0x100)
1420 b = 0x01;
1421 key[i] = b;
1422 }
1423
1424 return 32; /* length of key in octets or 0 for error */
1425 }
1426}
1427
1428
1429static WC_INLINE unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity,
1430 unsigned char* key, unsigned int key_max_len)
1431{
1432 (void)ssl;
1433 (void)key_max_len;
1434
1435 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
1436 if (XSTRNCMP(identity, kIdentityStr, XSTRLEN(kIdentityStr)) != 0)
1437 return 0;
1438
1439 if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) {
1440 /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
1441 unsigned binary */
1442 key[0] = 0x1a;
1443 key[1] = 0x2b;
1444 key[2] = 0x3c;
1445 key[3] = 0x4d;
1446
1447 return 4; /* length of key in octets or 0 for error */
1448 }
1449 else {
1450 int i;
1451 int b = 0x01;
1452
1453 for (i = 0; i < 32; i++, b += 0x22) {
1454 if (b >= 0x100)
1455 b = 0x01;
1456 key[i] = b;
1457 }
1458
1459 return 32; /* length of key in octets or 0 for error */
1460 }
1461}
1462
1463
1464static WC_INLINE unsigned int my_psk_client_tls13_cb(WOLFSSL* ssl,
1465 const char* hint, char* identity, unsigned int id_max_len,
1466 unsigned char* key, unsigned int key_max_len, const char** ciphersuite)
1467{
1468 int i;
1469 int b = 0x01;
1470 const char* userCipher = (const char*)wolfSSL_get_psk_callback_ctx(ssl);
1471
1472 (void)ssl;
1473 (void)hint;
1474 (void)key_max_len;
1475
1476 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
1477 XSTRNCPY(identity, kIdentityStr, id_max_len);
1478
1479 for (i = 0; i < 32; i++, b += 0x22) {
1480 if (b >= 0x100)
1481 b = 0x01;
1482 key[i] = b;
1483 }
1484
1485 *ciphersuite = userCipher ? userCipher : "TLS13-AES128-GCM-SHA256";
1486
1487 return 32; /* length of key in octets or 0 for error */
1488}
1489
1490
1491static WC_INLINE unsigned int my_psk_server_tls13_cb(WOLFSSL* ssl,
1492 const char* identity, unsigned char* key, unsigned int key_max_len,
1493 const char** ciphersuite)
1494{
1495 int i;
1496 int b = 0x01;
1497 const char* userCipher = (const char*)wolfSSL_get_psk_callback_ctx(ssl);
1498
1499 (void)ssl;
1500 (void)key_max_len;
1501
1502 /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
1503 if (XSTRNCMP(identity, kIdentityStr, XSTRLEN(kIdentityStr)) != 0)
1504 return 0;
1505
1506 for (i = 0; i < 32; i++, b += 0x22) {
1507 if (b >= 0x100)
1508 b = 0x01;
1509 key[i] = b;
1510 }
1511
1512 *ciphersuite = userCipher ? userCipher : "TLS13-AES128-GCM-SHA256";
1513
1514 return 32; /* length of key in octets or 0 for error */
1515}
1516
1517#endif /* !NO_PSK */
1518
1519
1520#if defined(WOLFSSL_USER_CURRTIME)
1521 extern double current_time(int reset);
1522
1523#elif defined(USE_WINDOWS_API)
1524
1525 #define WIN32_LEAN_AND_MEAN
1526 #include <windows.h>
1527
1528 static WC_INLINE double current_time(int reset)
1529 {
1530 static int init = 0;
1531 static LARGE_INTEGER freq;
1532
1533 LARGE_INTEGER count;
1534
1535 if (!init) {
1536 QueryPerformanceFrequency(&freq);
1537 init = 1;
1538 }
1539
1540 QueryPerformanceCounter(&count);
1541
1542 (void)reset;
1543 return (double)count.QuadPart / freq.QuadPart;
1544 }
1545
1546#elif defined(WOLFSSL_TIRTOS)
1547 extern double current_time();
1548#elif defined(WOLFSSL_ZEPHYR)
1549 extern double current_time();
1550#else
1551
1552#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_CHIBIOS)
1553 #include <sys/time.h>
1554
1555 static WC_INLINE double current_time(int reset)
1556 {
1557 struct timeval tv;
1558 gettimeofday(&tv, 0);
1559 (void)reset;
1560
1561 return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
1562 }
1563#else
1564 extern double current_time(int reset);
1565#endif
1566#endif /* USE_WINDOWS_API */
1567
1568
1569#if defined(HAVE_OCSP) && defined(WOLFSSL_NONBLOCK_OCSP)
1570static WC_INLINE int OCSPIOCb(void* ioCtx, const char* url, int urlSz,
1571 unsigned char* request, int requestSz, unsigned char** response)
1572{
1573#ifdef TEST_NONBLOCK_CERTS
1574 static int ioCbCnt = 0;
1575#endif
1576
1577 (void)ioCtx;
1578 (void)url;
1579 (void)urlSz;
1580 (void)request;
1581 (void)requestSz;
1582 (void)response;
1583
1584#ifdef TEST_NONBLOCK_CERTS
1585 if (ioCbCnt) {
1586 ioCbCnt = 0;
1587 return EmbedOcspLookup(ioCtx, url, urlSz, request, requestSz, response);
1588 }
1589 else {
1590 ioCbCnt = 1;
1591 return WOLFSSL_CBIO_ERR_WANT_READ;
1592 }
1593#else
1594 return EmbedOcspLookup(ioCtx, url, urlSz, request, requestSz, response);
1595#endif
1596}
1597
1598static WC_INLINE void OCSPRespFreeCb(void* ioCtx, unsigned char* response)
1599{
1600 return EmbedOcspRespFree(ioCtx, response);
1601}
1602#endif
1603
1604#if !defined(NO_CERTS)
1605 #if !defined(NO_FILESYSTEM) || \
1606 (defined(NO_FILESYSTEM) && defined(FORCE_BUFFER_TEST))
1607
1608 /* reads file size, allocates buffer, reads into buffer, returns buffer */
1609 static WC_INLINE int load_file(const char* fname, byte** buf, size_t* bufLen)
1610 {
1611 int ret;
1612 long int fileSz;
1613 XFILE lFile;
1614
1615 if (fname == NULL || buf == NULL || bufLen == NULL)
1616 return BAD_FUNC_ARG;
1617
1618 /* set defaults */
1619 *buf = NULL;
1620 *bufLen = 0;
1621
1622 /* open file (read-only binary) */
1623 lFile = XFOPEN(fname, "rb");
1624 if (!lFile) {
1625 printf("Error loading %s\n", fname);
1626 return BAD_PATH_ERROR;
1627 }
1628
1629 fseek(lFile, 0, SEEK_END);
1630 fileSz = (int)ftell(lFile);
1631 rewind(lFile);
1632 if (fileSz > 0) {
1633 *bufLen = (size_t)fileSz;
1634 *buf = (byte*)malloc(*bufLen);
1635 if (*buf == NULL) {
1636 ret = MEMORY_E;
1637 printf("Error allocating %lu bytes\n", (unsigned long)*bufLen);
1638 }
1639 else {
1640 size_t readLen = fread(*buf, *bufLen, 1, lFile);
1641
1642 /* check response code */
1643 ret = (readLen > 0) ? 0 : -1;
1644 }
1645 }
1646 else {
1647 ret = BUFFER_E;
1648 }
1649 fclose(lFile);
1650
1651 return ret;
1652 }
1653
1654 enum {
1655 WOLFSSL_CA = 1,
1656 WOLFSSL_CERT = 2,
1657 WOLFSSL_KEY = 3,
1658 WOLFSSL_CERT_CHAIN = 4,
1659 };
1660
1661 static WC_INLINE void load_buffer(WOLFSSL_CTX* ctx, const char* fname, int type)
1662 {
1663 int format = WOLFSSL_FILETYPE_PEM;
1664 byte* buff = NULL;
1665 size_t sz = 0;
1666
1667 if (load_file(fname, &buff, &sz) != 0) {
1668 err_sys("can't open file for buffer load "
1669 "Please run from wolfSSL home directory if not");
1670 }
1671
1672 /* determine format */
1673 if (strstr(fname, ".der"))
1674 format = WOLFSSL_FILETYPE_ASN1;
1675
1676 if (type == WOLFSSL_CA) {
1677 if (wolfSSL_CTX_load_verify_buffer(ctx, buff, (long)sz, format)
1678 != WOLFSSL_SUCCESS)
1679 err_sys("can't load buffer ca file");
1680 }
1681 else if (type == WOLFSSL_CERT) {
1682 if (wolfSSL_CTX_use_certificate_buffer(ctx, buff, (long)sz,
1683 format) != WOLFSSL_SUCCESS)
1684 err_sys("can't load buffer cert file");
1685 }
1686 else if (type == WOLFSSL_KEY) {
1687 if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, (long)sz,
1688 format) != WOLFSSL_SUCCESS)
1689 err_sys("can't load buffer key file");
1690 }
1691 else if (type == WOLFSSL_CERT_CHAIN) {
1692 if (wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, buff,
1693 (long)sz, format) != WOLFSSL_SUCCESS)
1694 err_sys("can't load cert chain buffer");
1695 }
1696
1697 if (buff)
1698 free(buff);
1699 }
1700
1701 static WC_INLINE void load_ssl_buffer(WOLFSSL* ssl, const char* fname, int type)
1702 {
1703 int format = WOLFSSL_FILETYPE_PEM;
1704 byte* buff = NULL;
1705 size_t sz = 0;
1706
1707 if (load_file(fname, &buff, &sz) != 0) {
1708 err_sys("can't open file for buffer load "
1709 "Please run from wolfSSL home directory if not");
1710 }
1711
1712 /* determine format */
1713 if (strstr(fname, ".der"))
1714 format = WOLFSSL_FILETYPE_ASN1;
1715
1716 if (type == WOLFSSL_CA) {
1717 /* verify certs (CA's) use the shared ctx->cm (WOLFSSL_CERT_MANAGER) */
1718 WOLFSSL_CTX* ctx = wolfSSL_get_SSL_CTX(ssl);
1719 if (wolfSSL_CTX_load_verify_buffer(ctx, buff, (long)sz, format)
1720 != WOLFSSL_SUCCESS)
1721 err_sys("can't load buffer ca file");
1722 }
1723 else if (type == WOLFSSL_CERT) {
1724 if (wolfSSL_use_certificate_buffer(ssl, buff, (long)sz,
1725 format) != WOLFSSL_SUCCESS)
1726 err_sys("can't load buffer cert file");
1727 }
1728 else if (type == WOLFSSL_KEY) {
1729 if (wolfSSL_use_PrivateKey_buffer(ssl, buff, (long)sz,
1730 format) != WOLFSSL_SUCCESS)
1731 err_sys("can't load buffer key file");
1732 }
1733 else if (type == WOLFSSL_CERT_CHAIN) {
1734 if (wolfSSL_use_certificate_chain_buffer_format(ssl, buff,
1735 (long)sz, format) != WOLFSSL_SUCCESS)
1736 err_sys("can't load cert chain buffer");
1737 }
1738
1739 if (buff)
1740 free(buff);
1741 }
1742
1743 #ifdef TEST_PK_PRIVKEY
1744 static WC_INLINE int load_key_file(const char* fname, byte** derBuf, word32* derLen)
1745 {
1746 int ret;
1747 byte* buf = NULL;
1748 size_t bufLen;
1749
1750 ret = load_file(fname, &buf, &bufLen);
1751 if (ret != 0)
1752 return ret;
1753
1754 *derBuf = (byte*)malloc(bufLen);
1755 if (*derBuf == NULL) {
1756 free(buf);
1757 return MEMORY_E;
1758 }
1759
1760 ret = wc_KeyPemToDer(buf, (word32)bufLen, *derBuf, (word32)bufLen, NULL);
1761 if (ret < 0) {
1762 free(buf);
1763 free(*derBuf);
1764 return ret;
1765 }
1766 *derLen = ret;
1767 free(buf);
1768
1769 return 0;
1770 }
1771 #endif /* TEST_PK_PRIVKEY */
1772
1773 #endif /* !NO_FILESYSTEM || (NO_FILESYSTEM && FORCE_BUFFER_TEST) */
1774#endif /* !NO_CERTS */
1775
1776enum {
1777 VERIFY_OVERRIDE_ERROR,
1778 VERIFY_FORCE_FAIL,
1779 VERIFY_USE_PREVERFIY,
1780 VERIFY_OVERRIDE_DATE_ERR,
1781};
1782static THREAD_LS_T int myVerifyAction = VERIFY_OVERRIDE_ERROR;
1783
1784/* The verify callback is called for every certificate only when
1785 * --enable-opensslextra is defined because it sets WOLFSSL_ALWAYS_VERIFY_CB and
1786 * WOLFSSL_VERIFY_CB_ALL_CERTS.
1787 * Normal cases of the verify callback only occur on certificate failures when the
1788 * wolfSSL_set_verify(ssl, SSL_VERIFY_PEER, myVerifyCb); is called
1789*/
1790
1791static WC_INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store)
1792{
1793 char buffer[WOLFSSL_MAX_ERROR_SZ];
1794#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
1795 WOLFSSL_X509* peer;
1796#if defined(SHOW_CERTS) && !defined(NO_FILESYSTEM)
1797 WOLFSSL_BIO* bio = NULL;
1798 WOLFSSL_STACK* sk = NULL;
1799 X509* x509 = NULL;
1800 int i = 0;
1801#endif
1802#endif
1803 (void)preverify;
1804
1805 /* Verify Callback Arguments:
1806 * preverify: 1=Verify Okay, 0=Failure
1807 * store->error: Failure error code (0 indicates no failure)
1808 * store->current_cert: Current WOLFSSL_X509 object (only with OPENSSL_EXTRA)
1809 * store->error_depth: Current Index
1810 * store->domain: Subject CN as string (null term)
1811 * store->totalCerts: Number of certs presented by peer
1812 * store->certs[i]: A `WOLFSSL_BUFFER_INFO` with plain DER for each cert
1813 * store->store: WOLFSSL_X509_STORE with CA cert chain
1814 * store->store->cm: WOLFSSL_CERT_MANAGER
1815 * store->ex_data: The WOLFSSL object pointer
1816 * store->discardSessionCerts: When set to non-zero value session certs
1817 will be discarded (only with SESSION_CERTS)
1818 */
1819
1820 printf("In verification callback, error = %d, %s\n", store->error,
1821 wolfSSL_ERR_error_string(store->error, buffer));
1822#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
1823 peer = store->current_cert;
1824 if (peer) {
1825 char* issuer = wolfSSL_X509_NAME_oneline(
1826 wolfSSL_X509_get_issuer_name(peer), 0, 0);
1827 char* subject = wolfSSL_X509_NAME_oneline(
1828 wolfSSL_X509_get_subject_name(peer), 0, 0);
1829 printf("\tPeer's cert info:\n issuer : %s\n subject: %s\n", issuer,
1830 subject);
1831 XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
1832 XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL);
1833#if defined(SHOW_CERTS) && !defined(NO_FILESYSTEM)
1834 /* avoid printing duplicate certs */
1835 if (store->depth == 1) {
1836 /* retrieve x509 certs and display them on stdout */
1837 sk = wolfSSL_X509_STORE_GetCerts(store);
1838
1839 for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
1840 x509 = wolfSSL_sk_X509_value(sk, i);
1841 bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
1842 if (bio != NULL) {
1843 wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE);
1844 wolfSSL_X509_print(bio, x509);
1845 wolfSSL_BIO_free(bio);
1846 }
1847 }
1848 wolfSSL_sk_X509_free(sk);
1849 }
1850#endif
1851 }
1852 else
1853 printf("\tPeer has no cert!\n");
1854#else
1855 printf("\tPeer certs: %d\n", store->totalCerts);
1856 #ifdef SHOW_CERTS
1857 { int i;
1858 for (i=0; i<store->totalCerts; i++) {
1859 WOLFSSL_BUFFER_INFO* cert = &store->certs[i];
1860 printf("\t\tCert %d: Ptr %p, Len %u\n", i, cert->buffer, cert->length);
1861 }
1862 }
1863 #endif /* SHOW_CERTS */
1864#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
1865
1866 printf("\tSubject's domain name at %d is %s\n", store->error_depth, store->domain);
1867
1868 /* Testing forced fail case by return zero */
1869 if (myVerifyAction == VERIFY_FORCE_FAIL) {
1870 return 0; /* test failure case */
1871 }
1872
1873 if (myVerifyAction == VERIFY_OVERRIDE_DATE_ERR &&
1874 (store->error == ASN_BEFORE_DATE_E || store->error == ASN_AFTER_DATE_E)) {
1875 printf("Overriding cert date error as example for bad clock testing\n");
1876 return 1;
1877 }
1878
1879 /* If error indicate we are overriding it for testing purposes */
1880 if (store->error != 0 && myVerifyAction == VERIFY_OVERRIDE_ERROR) {
1881 printf("\tAllowing failed certificate check, testing only "
1882 "(shouldn't do this in production)\n");
1883 }
1884
1885 /* A non-zero return code indicates failure override */
1886 return (myVerifyAction == VERIFY_OVERRIDE_ERROR) ? 1 : preverify;
1887}
1888
1889
1890#ifdef HAVE_EXT_CACHE
1891
1892static WC_INLINE WOLFSSL_SESSION* mySessGetCb(WOLFSSL* ssl, unsigned char* id,
1893 int id_len, int* copy)
1894{
1895 (void)ssl;
1896 (void)id;
1897 (void)id_len;
1898 (void)copy;
1899
1900 /* using internal cache, this is for testing only */
1901 return NULL;
1902}
1903
1904static WC_INLINE int mySessNewCb(WOLFSSL* ssl, WOLFSSL_SESSION* session)
1905{
1906 (void)ssl;
1907 (void)session;
1908
1909 /* using internal cache, this is for testing only */
1910 return 0;
1911}
1912
1913static WC_INLINE void mySessRemCb(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
1914{
1915 (void)ctx;
1916 (void)session;
1917
1918 /* using internal cache, this is for testing only */
1919}
1920
1921#endif /* HAVE_EXT_CACHE */
1922
1923
1924#ifdef HAVE_CRL
1925
1926static WC_INLINE void CRL_CallBack(const char* url)
1927{
1928 printf("CRL callback url = %s\n", url);
1929}
1930
1931#endif
1932
1933#ifndef NO_DH
1934static WC_INLINE void SetDH(WOLFSSL* ssl)
1935{
1936 /* dh1024 p */
1937 static const unsigned char p[] =
1938 {
1939 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
1940 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
1941 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
1942 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
1943 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
1944 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
1945 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
1946 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
1947 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
1948 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
1949 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
1950 };
1951
1952 /* dh1024 g */
1953 static const unsigned char g[] =
1954 {
1955 0x02,
1956 };
1957
1958 wolfSSL_SetTmpDH(ssl, p, sizeof(p), g, sizeof(g));
1959}
1960
1961static WC_INLINE void SetDHCtx(WOLFSSL_CTX* ctx)
1962{
1963 /* dh1024 p */
1964 static const unsigned char p[] =
1965 {
1966 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
1967 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
1968 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
1969 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
1970 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
1971 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
1972 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
1973 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
1974 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
1975 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
1976 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
1977 };
1978
1979 /* dh1024 g */
1980 static const unsigned char g[] =
1981 {
1982 0x02,
1983 };
1984
1985 wolfSSL_CTX_SetTmpDH(ctx, p, sizeof(p), g, sizeof(g));
1986}
1987#endif /* NO_DH */
1988
1989#ifndef NO_CERTS
1990
1991static WC_INLINE void CaCb(unsigned char* der, int sz, int type)
1992{
1993 (void)der;
1994 printf("Got CA cache add callback, derSz = %d, type = %d\n", sz, type);
1995}
1996
1997#endif /* !NO_CERTS */
1998
1999
2000/* Wolf Root Directory Helper */
2001/* KEIL-RL File System does not support relative directory */
2002#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS)
2003 /* Maximum depth to search for WolfSSL root */
2004 #define MAX_WOLF_ROOT_DEPTH 5
2005
2006 static WC_INLINE int ChangeToWolfRoot(void)
2007 {
2008 #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST)
2009 int depth, res;
2010 XFILE keyFile;
2011 for(depth = 0; depth <= MAX_WOLF_ROOT_DEPTH; depth++) {
2012 keyFile = XFOPEN(ntruKeyFile, "rb");
2013 if (keyFile != NULL) {
2014 fclose(keyFile);
2015 return depth;
2016 }
2017 #ifdef USE_WINDOWS_API
2018 res = SetCurrentDirectoryA("..\\");
2019 #else
2020 res = chdir("../");
2021 #endif
2022 if (res < 0) {
2023 printf("chdir to ../ failed!\n");
2024 break;
2025 }
2026 }
2027
2028 err_sys("wolf root not found");
2029 return -1;
2030 #else
2031 return 0;
2032 #endif
2033 }
2034#endif /* !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS) */
2035
2036#ifdef HAVE_STACK_SIZE
2037
2038typedef THREAD_RETURN WOLFSSL_THREAD (*thread_func)(void* args);
2039#define STACK_CHECK_VAL 0x01
2040
2041struct stack_size_debug_context {
2042 unsigned char *myStack;
2043 size_t stackSize;
2044#ifdef HAVE_STACK_SIZE_VERBOSE
2045 size_t *stackSizeHWM_ptr;
2046 thread_func fn;
2047 void *args;
2048#endif
2049};
2050
2051#ifdef HAVE_STACK_SIZE_VERBOSE
2052
2053/* per-subtest stack high water mark tracking.
2054 *
2055 * enable with
2056 *
2057 * ./configure --enable-stacksize=verbose [...]
2058 */
2059
2060static THREAD_RETURN debug_stack_size_verbose_shim(struct stack_size_debug_context *shim_args) {
2061 StackSizeCheck_myStack = shim_args->myStack;
2062 StackSizeCheck_stackSize = shim_args->stackSize;
2063 StackSizeCheck_stackSizeHWM_ptr = shim_args->stackSizeHWM_ptr;
2064 return shim_args->fn(shim_args->args);
2065}
2066
2067static WC_INLINE int StackSizeSetOffset(const char *funcname, void *p)
2068{
2069 if (StackSizeCheck_myStack == NULL)
2070 return -BAD_FUNC_ARG;
2071
2072 StackSizeCheck_stackOffsetPointer = p;
2073
2074 printf("setting stack relative offset reference mark in %s to +%lu\n",
2075 funcname, (unsigned long)((char*)(StackSizeCheck_myStack +
2076 StackSizeCheck_stackSize) - (char *)p));
2077
2078 return 0;
2079}
2080
2081static WC_INLINE ssize_t StackSizeHWM(void)
2082{
2083 size_t i;
2084 ssize_t used;
2085
2086 if (StackSizeCheck_myStack == NULL)
2087 return -BAD_FUNC_ARG;
2088
2089 for (i = 0; i < StackSizeCheck_stackSize; i++) {
2090 if (StackSizeCheck_myStack[i] != STACK_CHECK_VAL) {
2091 break;
2092 }
2093 }
2094
2095 used = StackSizeCheck_stackSize - i;
2096 if ((ssize_t)*StackSizeCheck_stackSizeHWM_ptr < used)
2097 *StackSizeCheck_stackSizeHWM_ptr = used;
2098
2099 return used;
2100}
2101
2102static WC_INLINE ssize_t StackSizeHWM_OffsetCorrected(void)
2103{
2104 ssize_t used = StackSizeHWM();
2105 if (used < 0)
2106 return used;
2107 if (StackSizeCheck_stackOffsetPointer)
2108 used -= (ssize_t)(((char *)StackSizeCheck_myStack + StackSizeCheck_stackSize) - (char *)StackSizeCheck_stackOffsetPointer);
2109 return used;
2110}
2111
2112static
2113#ifdef __GNUC__
2114__attribute__((unused)) __attribute__((noinline))
2115#endif
2116int StackSizeHWMReset(void)
2117{
2118 volatile ssize_t i;
2119
2120 if (StackSizeCheck_myStack == NULL)
2121 return -BAD_FUNC_ARG;
2122
2123 for (i = (ssize_t)((char *)&i - (char *)StackSizeCheck_myStack) - (ssize_t)sizeof i - 1; i >= 0; --i)
2124 {
2125 StackSizeCheck_myStack[i] = STACK_CHECK_VAL;
2126 }
2127
2128 return 0;
2129}
2130
2131#define STACK_SIZE_CHECKPOINT(...) ({ \
2132 ssize_t HWM = StackSizeHWM_OffsetCorrected(); \
2133 __VA_ARGS__; \
2134 printf(" relative stack peak usage = %ld bytes\n", HWM); \
2135 StackSizeHWMReset(); \
2136 })
2137
2138#define STACK_SIZE_CHECKPOINT_WITH_MAX_CHECK(max, ...) ({ \
2139 ssize_t HWM = StackSizeHWM_OffsetCorrected(); \
2140 int _ret; \
2141 __VA_ARGS__; \
2142 printf(" relative stack peak usage = %ld bytes\n", HWM); \
2143 _ret = StackSizeHWMReset(); \
2144 if ((max >= 0) && (HWM > (ssize_t)(max))) { \
2145 printf(" relative stack usage at %s L%d exceeds designated max %ld bytes.\n", __FILE__, __LINE__, (ssize_t)(max)); \
2146 _ret = -1; \
2147 } \
2148 _ret; \
2149 })
2150
2151
2152#ifdef __GNUC__
2153#define STACK_SIZE_INIT() (void)StackSizeSetOffset(__FUNCTION__, __builtin_frame_address(0))
2154#endif
2155
2156#endif /* HAVE_STACK_SIZE_VERBOSE */
2157
2158static WC_INLINE int StackSizeCheck(func_args* args, thread_func tf)
2159{
2160 size_t i;
2161 int ret;
2162 void* status;
2163 unsigned char* myStack = NULL;
2164 size_t stackSize = 1024*1024;
2165 pthread_attr_t myAttr;
2166 pthread_t threadId;
2167#ifdef HAVE_STACK_SIZE_VERBOSE
2168 struct stack_size_debug_context shim_args;
2169#endif
2170
2171#ifdef PTHREAD_STACK_MIN
2172 if (stackSize < PTHREAD_STACK_MIN)
2173 stackSize = PTHREAD_STACK_MIN;
2174#endif
2175
2176 ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize);
2177 if (ret != 0 || myStack == NULL)
2178 err_sys_with_errno("posix_memalign failed\n");
2179
2180 XMEMSET(myStack, STACK_CHECK_VAL, stackSize);
2181
2182 ret = pthread_attr_init(&myAttr);
2183 if (ret != 0)
2184 err_sys("attr_init failed");
2185
2186 ret = pthread_attr_setstack(&myAttr, myStack, stackSize);
2187 if (ret != 0)
2188 err_sys("attr_setstackaddr failed");
2189
2190#ifdef HAVE_STACK_SIZE_VERBOSE
2191 StackSizeCheck_stackSizeHWM = 0;
2192 shim_args.myStack = myStack;
2193 shim_args.stackSize = stackSize;
2194 shim_args.stackSizeHWM_ptr = &StackSizeCheck_stackSizeHWM;
2195 shim_args.fn = tf;
2196 shim_args.args = args;
2197 ret = pthread_create(&threadId, &myAttr, (thread_func)debug_stack_size_verbose_shim, (void *)&shim_args);
2198#else
2199 ret = pthread_create(&threadId, &myAttr, tf, args);
2200#endif
2201 if (ret != 0) {
2202 perror("pthread_create failed");
2203 exit(EXIT_FAILURE);
2204 }
2205
2206 ret = pthread_join(threadId, &status);
2207 if (ret != 0)
2208 err_sys("pthread_join failed");
2209
2210 for (i = 0; i < stackSize; i++) {
2211 if (myStack[i] != STACK_CHECK_VAL) {
2212 break;
2213 }
2214 }
2215
2216 free(myStack);
2217#ifdef HAVE_STACK_SIZE_VERBOSE
2218 printf("stack used = %lu\n", StackSizeCheck_stackSizeHWM > (stackSize - i)
2219 ? (unsigned long)StackSizeCheck_stackSizeHWM
2220 : (unsigned long)(stackSize - i));
2221#else
2222 {
2223 size_t used = stackSize - i;
2224 printf("stack used = %lu\n", (unsigned long)used);
2225 }
2226#endif
2227
2228 return (int)((size_t)status);
2229}
2230
2231static WC_INLINE int StackSizeCheck_launch(func_args* args, thread_func tf, pthread_t *threadId, void **stack_context)
2232{
2233 int ret;
2234 unsigned char* myStack = NULL;
2235 size_t stackSize = 1024*1024;
2236 pthread_attr_t myAttr;
2237
2238#ifdef PTHREAD_STACK_MIN
2239 if (stackSize < PTHREAD_STACK_MIN)
2240 stackSize = PTHREAD_STACK_MIN;
2241#endif
2242
2243 struct stack_size_debug_context *shim_args = (struct stack_size_debug_context *)malloc(sizeof *shim_args);
2244 if (! shim_args) {
2245 perror("malloc");
2246 exit(EXIT_FAILURE);
2247 }
2248
2249 ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize);
2250 if (ret != 0 || myStack == NULL)
2251 err_sys_with_errno("posix_memalign failed\n");
2252
2253 XMEMSET(myStack, STACK_CHECK_VAL, stackSize);
2254
2255 ret = pthread_attr_init(&myAttr);
2256 if (ret != 0)
2257 err_sys("attr_init failed");
2258
2259 ret = pthread_attr_setstack(&myAttr, myStack, stackSize);
2260 if (ret != 0)
2261 err_sys("attr_setstackaddr failed");
2262
2263 shim_args->myStack = myStack;
2264 shim_args->stackSize = stackSize;
2265#ifdef HAVE_STACK_SIZE_VERBOSE
2266 shim_args->stackSizeHWM_ptr = &StackSizeCheck_stackSizeHWM;
2267 shim_args->fn = tf;
2268 shim_args->args = args;
2269 ret = pthread_create(threadId, &myAttr, (thread_func)debug_stack_size_verbose_shim, (void *)shim_args);
2270#else
2271 ret = pthread_create(threadId, &myAttr, tf, args);
2272#endif
2273 if (ret != 0) {
2274 fprintf(stderr,"pthread_create failed: %s",strerror(ret));
2275 exit(EXIT_FAILURE);
2276 }
2277
2278 *stack_context = (void *)shim_args;
2279
2280 return 0;
2281}
2282
2283static WC_INLINE int StackSizeCheck_reap(pthread_t threadId, void *stack_context)
2284{
2285 struct stack_size_debug_context *shim_args = (struct stack_size_debug_context *)stack_context;
2286 size_t i;
2287 void *status;
2288 int ret = pthread_join(threadId, &status);
2289 if (ret != 0)
2290 err_sys("pthread_join failed");
2291
2292 for (i = 0; i < shim_args->stackSize; i++) {
2293 if (shim_args->myStack[i] != STACK_CHECK_VAL) {
2294 break;
2295 }
2296 }
2297
2298 free(shim_args->myStack);
2299#ifdef HAVE_STACK_SIZE_VERBOSE
2300 printf("stack used = %lu\n",
2301 *shim_args->stackSizeHWM_ptr > (shim_args->stackSize - i)
2302 ? (unsigned long)*shim_args->stackSizeHWM_ptr
2303 : (unsigned long)(shim_args->stackSize - i));
2304#else
2305 {
2306 size_t used = shim_args->stackSize - i;
2307 printf("stack used = %lu\n", (unsigned long)used);
2308 }
2309#endif
2310 free(shim_args);
2311
2312 return (int)((size_t)status);
2313}
2314
2315
2316#endif /* HAVE_STACK_SIZE */
2317
2318#ifndef STACK_SIZE_CHECKPOINT
2319#define STACK_SIZE_CHECKPOINT(...) (__VA_ARGS__)
2320#endif
2321#ifndef STACK_SIZE_INIT
2322#define STACK_SIZE_INIT()
2323#endif
2324
2325#ifdef STACK_TRAP
2326
2327/* good settings
2328 --enable-debug --disable-shared C_EXTRA_FLAGS="-DUSER_TIME -DTFM_TIMING_RESISTANT -DPOSITIVE_EXP_ONLY -DSTACK_TRAP"
2329
2330*/
2331
2332#ifdef HAVE_STACK_SIZE
2333 /* client only for now, setrlimit will fail if pthread_create() called */
2334 /* STACK_SIZE does pthread_create() on client */
2335 #error "can't use STACK_TRAP with STACK_SIZE, setrlimit will fail"
2336#endif /* HAVE_STACK_SIZE */
2337
2338static WC_INLINE void StackTrap(void)
2339{
2340 struct rlimit rl;
2341 if (getrlimit(RLIMIT_STACK, &rl) != 0)
2342 err_sys_with_errno("getrlimit failed");
2343 printf("rlim_cur = %llu\n", rl.rlim_cur);
2344 rl.rlim_cur = 1024*21; /* adjust trap size here */
2345 if (setrlimit(RLIMIT_STACK, &rl) != 0)
2346 err_sys_with_errno("setrlimit failed");
2347}
2348
2349#else /* STACK_TRAP */
2350
2351static WC_INLINE void StackTrap(void)
2352{
2353}
2354
2355#endif /* STACK_TRAP */
2356
2357
2358#if defined(ATOMIC_USER) && !defined(WOLFSSL_AEAD_ONLY)
2359
2360/* Atomic Encrypt Context example */
2361typedef struct AtomicEncCtx {
2362 int keySetup; /* have we done key setup yet */
2363 Aes aes; /* for aes example */
2364} AtomicEncCtx;
2365
2366
2367/* Atomic Decrypt Context example */
2368typedef struct AtomicDecCtx {
2369 int keySetup; /* have we done key setup yet */
2370 Aes aes; /* for aes example */
2371} AtomicDecCtx;
2372
2373
2374static WC_INLINE int myMacEncryptCb(WOLFSSL* ssl, unsigned char* macOut,
2375 const unsigned char* macIn, unsigned int macInSz, int macContent,
2376 int macVerify, unsigned char* encOut, const unsigned char* encIn,
2377 unsigned int encSz, void* ctx)
2378{
2379 int ret;
2380 Hmac hmac;
2381 byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
2382 AtomicEncCtx* encCtx = (AtomicEncCtx*)ctx;
2383 const char* tlsStr = "TLS";
2384
2385 /* example supports (d)tls aes */
2386 if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
2387 printf("myMacEncryptCb not using AES\n");
2388 return -1;
2389 }
2390
2391 if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
2392 printf("myMacEncryptCb not using (D)TLS\n");
2393 return -1;
2394 }
2395
2396 /* hmac, not needed if aead mode */
2397 wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
2398
2399 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
2400 if (ret != 0)
2401 return ret;
2402 ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
2403 wolfSSL_GetMacSecret(ssl, macVerify), wolfSSL_GetHmacSize(ssl));
2404 if (ret != 0)
2405 return ret;
2406 ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
2407 if (ret != 0)
2408 return ret;
2409 ret = wc_HmacUpdate(&hmac, macIn, macInSz);
2410 if (ret != 0)
2411 return ret;
2412 ret = wc_HmacFinal(&hmac, macOut);
2413 if (ret != 0)
2414 return ret;
2415
2416
2417 /* encrypt setup on first time */
2418 if (encCtx->keySetup == 0) {
2419 int keyLen = wolfSSL_GetKeySize(ssl);
2420 const byte* key;
2421 const byte* iv;
2422
2423 if (wolfSSL_GetSide(ssl) == WOLFSSL_CLIENT_END) {
2424 key = wolfSSL_GetClientWriteKey(ssl);
2425 iv = wolfSSL_GetClientWriteIV(ssl);
2426 }
2427 else {
2428 key = wolfSSL_GetServerWriteKey(ssl);
2429 iv = wolfSSL_GetServerWriteIV(ssl);
2430 }
2431
2432 ret = wc_AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION);
2433 if (ret != 0) {
2434 printf("AesSetKey failed in myMacEncryptCb\n");
2435 return ret;
2436 }
2437 encCtx->keySetup = 1;
2438 }
2439
2440 /* encrypt */
2441 return wc_AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz);
2442}
2443
2444
2445static WC_INLINE int myDecryptVerifyCb(WOLFSSL* ssl,
2446 unsigned char* decOut, const unsigned char* decIn,
2447 unsigned int decSz, int macContent, int macVerify,
2448 unsigned int* padSz, void* ctx)
2449{
2450 AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx;
2451 int ret = 0;
2452 int macInSz = 0;
2453 int ivExtra = 0;
2454 int digestSz = wolfSSL_GetHmacSize(ssl);
2455 unsigned int pad = 0;
2456 unsigned int padByte = 0;
2457 Hmac hmac;
2458 byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
2459 byte verify[WC_MAX_DIGEST_SIZE];
2460 const char* tlsStr = "TLS";
2461
2462 /* example supports (d)tls aes */
2463 if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
2464 printf("myMacEncryptCb not using AES\n");
2465 return -1;
2466 }
2467
2468 if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
2469 printf("myMacEncryptCb not using (D)TLS\n");
2470 return -1;
2471 }
2472
2473 /*decrypt */
2474 if (decCtx->keySetup == 0) {
2475 int keyLen = wolfSSL_GetKeySize(ssl);
2476 const byte* key;
2477 const byte* iv;
2478
2479 /* decrypt is from other side (peer) */
2480 if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) {
2481 key = wolfSSL_GetClientWriteKey(ssl);
2482 iv = wolfSSL_GetClientWriteIV(ssl);
2483 }
2484 else {
2485 key = wolfSSL_GetServerWriteKey(ssl);
2486 iv = wolfSSL_GetServerWriteIV(ssl);
2487 }
2488
2489 ret = wc_AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION);
2490 if (ret != 0) {
2491 printf("AesSetKey failed in myDecryptVerifyCb\n");
2492 return ret;
2493 }
2494 decCtx->keySetup = 1;
2495 }
2496
2497 /* decrypt */
2498 ret = wc_AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz);
2499 if (ret != 0)
2500 return ret;
2501
2502 if (wolfSSL_GetCipherType(ssl) == WOLFSSL_AEAD_TYPE) {
2503 *padSz = wolfSSL_GetAeadMacSize(ssl);
2504 return 0; /* hmac, not needed if aead mode */
2505 }
2506
2507 if (wolfSSL_GetCipherType(ssl) == WOLFSSL_BLOCK_TYPE) {
2508 pad = *(decOut + decSz - 1);
2509 padByte = 1;
2510 if (wolfSSL_IsTLSv1_1(ssl))
2511 ivExtra = wolfSSL_GetCipherBlockSize(ssl);
2512 }
2513
2514 *padSz = wolfSSL_GetHmacSize(ssl) + pad + padByte;
2515 macInSz = decSz - ivExtra - digestSz - pad - padByte;
2516
2517 wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
2518
2519 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
2520 if (ret != 0)
2521 return ret;
2522 ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
2523 wolfSSL_GetMacSecret(ssl, macVerify), digestSz);
2524 if (ret != 0)
2525 return ret;
2526 ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
2527 if (ret != 0)
2528 return ret;
2529 ret = wc_HmacUpdate(&hmac, decOut + ivExtra, macInSz);
2530 if (ret != 0)
2531 return ret;
2532 ret = wc_HmacFinal(&hmac, verify);
2533 if (ret != 0)
2534 return ret;
2535
2536 if (XMEMCMP(verify, decOut + decSz - digestSz - pad - padByte,
2537 digestSz) != 0) {
2538 printf("myDecryptVerify verify failed\n");
2539 return -1;
2540 }
2541
2542 return ret;
2543}
2544
2545#if defined(HAVE_ENCRYPT_THEN_MAC)
2546
2547static WC_INLINE int myEncryptMacCb(WOLFSSL* ssl, unsigned char* macOut,
2548 int content, int macVerify, unsigned char* encOut,
2549 const unsigned char* encIn, unsigned int encSz, void* ctx)
2550{
2551 int ret;
2552 Hmac hmac;
2553 AtomicEncCtx* encCtx = (AtomicEncCtx*)ctx;
2554 byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
2555 const char* tlsStr = "TLS";
2556
2557 /* example supports (d)tls aes */
2558 if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
2559 printf("myMacEncryptCb not using AES\n");
2560 return -1;
2561 }
2562
2563 if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
2564 printf("myMacEncryptCb not using (D)TLS\n");
2565 return -1;
2566 }
2567
2568 /* encrypt setup on first time */
2569 if (encCtx->keySetup == 0) {
2570 int keyLen = wolfSSL_GetKeySize(ssl);
2571 const byte* key;
2572 const byte* iv;
2573
2574 if (wolfSSL_GetSide(ssl) == WOLFSSL_CLIENT_END) {
2575 key = wolfSSL_GetClientWriteKey(ssl);
2576 iv = wolfSSL_GetClientWriteIV(ssl);
2577 }
2578 else {
2579 key = wolfSSL_GetServerWriteKey(ssl);
2580 iv = wolfSSL_GetServerWriteIV(ssl);
2581 }
2582
2583 ret = wc_AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION);
2584 if (ret != 0) {
2585 printf("AesSetKey failed in myMacEncryptCb\n");
2586 return ret;
2587 }
2588 encCtx->keySetup = 1;
2589 }
2590
2591 /* encrypt */
2592 ret = wc_AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz);
2593 if (ret != 0)
2594 return ret;
2595
2596 /* Reconstruct record header. */
2597 wolfSSL_SetTlsHmacInner(ssl, myInner, encSz, content, macVerify);
2598
2599 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
2600 if (ret != 0)
2601 return ret;
2602 ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
2603 wolfSSL_GetMacSecret(ssl, macVerify), wolfSSL_GetHmacSize(ssl));
2604 if (ret != 0)
2605 return ret;
2606 ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
2607 if (ret != 0)
2608 return ret;
2609 ret = wc_HmacUpdate(&hmac, encOut, encSz);
2610 if (ret != 0)
2611 return ret;
2612 return wc_HmacFinal(&hmac, macOut);
2613}
2614
2615
2616static WC_INLINE int myVerifyDecryptCb(WOLFSSL* ssl,
2617 unsigned char* decOut, const unsigned char* decIn,
2618 unsigned int decSz, int content, int macVerify,
2619 unsigned int* padSz, void* ctx)
2620{
2621 AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx;
2622 int ret = 0;
2623 int digestSz = wolfSSL_GetHmacSize(ssl);
2624 Hmac hmac;
2625 byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
2626 byte verify[WC_MAX_DIGEST_SIZE];
2627 const char* tlsStr = "TLS";
2628
2629 /* example supports (d)tls aes */
2630 if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
2631 printf("myMacEncryptCb not using AES\n");
2632 return -1;
2633 }
2634
2635 if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
2636 printf("myMacEncryptCb not using (D)TLS\n");
2637 return -1;
2638 }
2639
2640 /* Reconstruct record header. */
2641 wolfSSL_SetTlsHmacInner(ssl, myInner, decSz, content, macVerify);
2642
2643 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
2644 if (ret != 0)
2645 return ret;
2646 ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
2647 wolfSSL_GetMacSecret(ssl, macVerify), digestSz);
2648 if (ret != 0)
2649 return ret;
2650 ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
2651 if (ret != 0)
2652 return ret;
2653 ret = wc_HmacUpdate(&hmac, decIn, decSz);
2654 if (ret != 0)
2655 return ret;
2656 ret = wc_HmacFinal(&hmac, verify);
2657 if (ret != 0)
2658 return ret;
2659
2660 if (XMEMCMP(verify, decOut + decSz, digestSz) != 0) {
2661 printf("myDecryptVerify verify failed\n");
2662 return -1;
2663 }
2664
2665 /* decrypt */
2666 if (decCtx->keySetup == 0) {
2667 int keyLen = wolfSSL_GetKeySize(ssl);
2668 const byte* key;
2669 const byte* iv;
2670
2671 /* decrypt is from other side (peer) */
2672 if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) {
2673 key = wolfSSL_GetClientWriteKey(ssl);
2674 iv = wolfSSL_GetClientWriteIV(ssl);
2675 }
2676 else {
2677 key = wolfSSL_GetServerWriteKey(ssl);
2678 iv = wolfSSL_GetServerWriteIV(ssl);
2679 }
2680
2681 ret = wc_AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION);
2682 if (ret != 0) {
2683 printf("AesSetKey failed in myDecryptVerifyCb\n");
2684 return ret;
2685 }
2686 decCtx->keySetup = 1;
2687 }
2688
2689 /* decrypt */
2690 ret = wc_AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz);
2691 if (ret != 0)
2692 return ret;
2693
2694 *padSz = *(decOut + decSz - 1) + 1;
2695
2696 return 0;
2697}
2698
2699#endif
2700
2701
2702static WC_INLINE void SetupAtomicUser(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
2703{
2704 AtomicEncCtx* encCtx;
2705 AtomicDecCtx* decCtx;
2706
2707 encCtx = (AtomicEncCtx*)malloc(sizeof(AtomicEncCtx));
2708 if (encCtx == NULL)
2709 err_sys_with_errno("AtomicEncCtx malloc failed");
2710 XMEMSET(encCtx, 0, sizeof(AtomicEncCtx));
2711
2712 decCtx = (AtomicDecCtx*)malloc(sizeof(AtomicDecCtx));
2713 if (decCtx == NULL) {
2714 free(encCtx);
2715 err_sys_with_errno("AtomicDecCtx malloc failed");
2716 }
2717 XMEMSET(decCtx, 0, sizeof(AtomicDecCtx));
2718
2719 wolfSSL_CTX_SetMacEncryptCb(ctx, myMacEncryptCb);
2720 wolfSSL_SetMacEncryptCtx(ssl, encCtx);
2721
2722 wolfSSL_CTX_SetDecryptVerifyCb(ctx, myDecryptVerifyCb);
2723 wolfSSL_SetDecryptVerifyCtx(ssl, decCtx);
2724
2725#if defined(HAVE_ENCRYPT_THEN_MAC)
2726 wolfSSL_CTX_SetEncryptMacCb(ctx, myEncryptMacCb);
2727 wolfSSL_SetEncryptMacCtx(ssl, encCtx);
2728
2729 wolfSSL_CTX_SetVerifyDecryptCb(ctx, myVerifyDecryptCb);
2730 wolfSSL_SetVerifyDecryptCtx(ssl, decCtx);
2731#endif
2732}
2733
2734
2735static WC_INLINE void FreeAtomicUser(WOLFSSL* ssl)
2736{
2737 AtomicEncCtx* encCtx = (AtomicEncCtx*)wolfSSL_GetMacEncryptCtx(ssl);
2738 AtomicDecCtx* decCtx = (AtomicDecCtx*)wolfSSL_GetDecryptVerifyCtx(ssl);
2739
2740 /* Encrypt-Then-MAC callbacks use same contexts. */
2741
2742 free(decCtx);
2743 free(encCtx);
2744}
2745
2746#endif /* ATOMIC_USER */
2747
2748#ifdef WOLFSSL_STATIC_MEMORY
2749static WC_INLINE int wolfSSL_PrintStats(WOLFSSL_MEM_STATS* stats)
2750{
2751 word16 i;
2752
2753 if (stats == NULL) {
2754 return 0;
2755 }
2756
2757 /* print to stderr so is on the same pipe as WOLFSSL_DEBUG */
2758 fprintf(stderr, "Total mallocs = %d\n", stats->totalAlloc);
2759 fprintf(stderr, "Total frees = %d\n", stats->totalFr);
2760 fprintf(stderr, "Current mallocs = %d\n", stats->curAlloc);
2761 fprintf(stderr, "Available IO = %d\n", stats->avaIO);
2762 fprintf(stderr, "Max con. handshakes = %d\n", stats->maxHa);
2763 fprintf(stderr, "Max con. IO = %d\n", stats->maxIO);
2764 fprintf(stderr, "State of memory blocks: size : available \n");
2765 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
2766 fprintf(stderr, " : %d\t : %d\n", stats->blockSz[i],
2767 stats->avaBlock[i]);
2768 }
2769
2770 return 1;
2771}
2772#endif /* WOLFSSL_STATIC_MEMORY */
2773
2774#ifdef HAVE_PK_CALLBACKS
2775
2776typedef struct PkCbInfo {
2777 const char* ourKey;
2778#ifdef TEST_PK_PRIVKEY
2779 union {
2780 #ifdef HAVE_ECC
2781 ecc_key ecc;
2782 #endif
2783 #ifdef HAVE_CURVE25519
2784 curve25519_key curve;
2785 #endif
2786 #ifdef HAVE_CURVE448
2787 curve448_key curve;
2788 #endif
2789 } keyGen;
2790#endif
2791} PkCbInfo;
2792
2793#if defined(DEBUG_PK_CB) || defined(TEST_PK_PRIVKEY)
2794 #define WOLFSSL_PKMSG(_f_, ...) printf(_f_, ##__VA_ARGS__)
2795#else
2796 #define WOLFSSL_PKMSG(_f_, ...)
2797#endif
2798
2799#ifdef HAVE_ECC
2800
2801static WC_INLINE int myEccKeyGen(WOLFSSL* ssl, ecc_key* key, word32 keySz,
2802 int ecc_curve, void* ctx)
2803{
2804 int ret;
2805 WC_RNG rng;
2806 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
2807 ecc_key* new_key;
2808#ifdef TEST_PK_PRIVKEY
2809 byte qx[MAX_ECC_BYTES], qy[MAX_ECC_BYTES];
2810 word32 qxLen = sizeof(qx), qyLen = sizeof(qy);
2811
2812 new_key = &cbInfo->keyGen.ecc;
2813#else
2814 new_key = key;
2815#endif
2816
2817 (void)ssl;
2818 (void)cbInfo;
2819
2820 WOLFSSL_PKMSG("PK ECC KeyGen: keySz %d, Curve ID %d\n", keySz, ecc_curve);
2821
2822 ret = wc_InitRng(&rng);
2823 if (ret != 0)
2824 return ret;
2825
2826 ret = wc_ecc_init(new_key);
2827 if (ret == 0) {
2828 /* create new key */
2829 ret = wc_ecc_make_key_ex(&rng, keySz, new_key, ecc_curve);
2830
2831 #ifdef TEST_PK_PRIVKEY
2832 if (ret == 0) {
2833 /* extract public portion from new key into `key` arg */
2834 ret = wc_ecc_export_public_raw(new_key, qx, &qxLen, qy, &qyLen);
2835 if (ret == 0) {
2836 /* load public portion only into key */
2837 ret = wc_ecc_import_unsigned(key, qx, qy, NULL, ecc_curve);
2838 }
2839 (void)qxLen;
2840 (void)qyLen;
2841 }
2842 #endif
2843 }
2844
2845 WOLFSSL_PKMSG("PK ECC KeyGen: ret %d\n", ret);
2846
2847 wc_FreeRng(&rng);
2848
2849 return ret;
2850}
2851
2852static WC_INLINE int myEccSign(WOLFSSL* ssl, const byte* in, word32 inSz,
2853 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
2854{
2855 int ret;
2856 WC_RNG rng;
2857 word32 idx = 0;
2858 ecc_key myKey;
2859 byte* keyBuf = (byte*)key;
2860 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
2861
2862 (void)ssl;
2863 (void)cbInfo;
2864
2865 WOLFSSL_PKMSG("PK ECC Sign: inSz %d, keySz %d\n", inSz, keySz);
2866
2867#ifdef TEST_PK_PRIVKEY
2868 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
2869 if (ret != 0)
2870 return ret;
2871#endif
2872
2873 ret = wc_InitRng(&rng);
2874 if (ret != 0)
2875 return ret;
2876
2877 ret = wc_ecc_init(&myKey);
2878 if (ret == 0) {
2879 ret = wc_EccPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
2880 if (ret == 0) {
2881 WOLFSSL_PKMSG("PK ECC Sign: Curve ID %d\n", myKey.dp->id);
2882 ret = wc_ecc_sign_hash(in, inSz, out, outSz, &rng, &myKey);
2883 }
2884 wc_ecc_free(&myKey);
2885 }
2886 wc_FreeRng(&rng);
2887
2888#ifdef TEST_PK_PRIVKEY
2889 free(keyBuf);
2890#endif
2891
2892 WOLFSSL_PKMSG("PK ECC Sign: ret %d outSz %d\n", ret, *outSz);
2893
2894 return ret;
2895}
2896
2897
2898static WC_INLINE int myEccVerify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
2899 const byte* hash, word32 hashSz, const byte* key, word32 keySz,
2900 int* result, void* ctx)
2901{
2902 int ret;
2903 word32 idx = 0;
2904 ecc_key myKey;
2905 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
2906
2907 (void)ssl;
2908 (void)cbInfo;
2909
2910 WOLFSSL_PKMSG("PK ECC Verify: sigSz %d, hashSz %d, keySz %d\n", sigSz, hashSz, keySz);
2911
2912 ret = wc_ecc_init(&myKey);
2913 if (ret == 0) {
2914 ret = wc_EccPublicKeyDecode(key, &idx, &myKey, keySz);
2915 if (ret == 0)
2916 ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, result, &myKey);
2917 wc_ecc_free(&myKey);
2918 }
2919
2920 WOLFSSL_PKMSG("PK ECC Verify: ret %d, result %d\n", ret, *result);
2921
2922 return ret;
2923}
2924
2925static WC_INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey,
2926 unsigned char* pubKeyDer, unsigned int* pubKeySz,
2927 unsigned char* out, unsigned int* outlen,
2928 int side, void* ctx)
2929{
2930 int ret;
2931 ecc_key* privKey = NULL;
2932 ecc_key* pubKey = NULL;
2933 ecc_key tmpKey;
2934 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
2935
2936 (void)ssl;
2937 (void)cbInfo;
2938
2939 WOLFSSL_PKMSG("PK ECC PMS: Side %s, Peer Curve %d\n",
2940 side == WOLFSSL_CLIENT_END ? "client" : "server", otherKey->dp->id);
2941
2942 ret = wc_ecc_init(&tmpKey);
2943 if (ret != 0) {
2944 return ret;
2945 }
2946
2947 /* for client: create and export public key */
2948 if (side == WOLFSSL_CLIENT_END) {
2949 WC_RNG rng;
2950
2951 privKey = &tmpKey;
2952 pubKey = otherKey;
2953
2954 ret = wc_InitRng(&rng);
2955 if (ret == 0) {
2956 ret = wc_ecc_make_key_ex(&rng, 0, privKey, otherKey->dp->id);
2957 #ifdef WOLFSSL_ASYNC_CRYPT
2958 if (ret == WC_PENDING_E) {
2959 ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_NONE);
2960 }
2961 #endif
2962 if (ret == 0)
2963 ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz);
2964 wc_FreeRng(&rng);
2965 }
2966 }
2967
2968 /* for server: import public key */
2969 else if (side == WOLFSSL_SERVER_END) {
2970 #ifdef TEST_PK_PRIVKEY
2971 privKey = &cbInfo->keyGen.ecc;
2972 #else
2973 privKey = otherKey;
2974 #endif
2975 pubKey = &tmpKey;
2976
2977 ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, pubKey,
2978 otherKey->dp->id);
2979 }
2980 else {
2981 ret = BAD_FUNC_ARG;
2982 }
2983
2984#if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_FIPS) && \
2985 !defined(HAVE_SELFTEST)
2986 if (ret == 0) {
2987 ret = wc_ecc_set_rng(privKey, wolfSSL_GetRNG(ssl));
2988 }
2989#endif
2990
2991 /* generate shared secret and return it */
2992 if (ret == 0) {
2993 ret = wc_ecc_shared_secret(privKey, pubKey, out, outlen);
2994
2995 #ifdef WOLFSSL_ASYNC_CRYPT
2996 if (ret == WC_PENDING_E) {
2997 ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
2998 }
2999 #endif
3000 }
3001
3002#ifdef TEST_PK_PRIVKEY
3003 if (side == WOLFSSL_SERVER_END) {
3004 wc_ecc_free(&cbInfo->keyGen.ecc);
3005 }
3006#endif
3007
3008 wc_ecc_free(&tmpKey);
3009
3010 WOLFSSL_PKMSG("PK ECC PMS: ret %d, PubKeySz %d, OutLen %d\n", ret, *pubKeySz, *outlen);
3011
3012 return ret;
3013}
3014
3015#ifdef HAVE_ED25519
3016static WC_INLINE int myEd25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz,
3017 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
3018{
3019 int ret;
3020 word32 idx = 0;
3021 ed25519_key myKey;
3022 byte* keyBuf = (byte*)key;
3023 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3024
3025 (void)ssl;
3026 (void)cbInfo;
3027
3028 WOLFSSL_PKMSG("PK 25519 Sign: inSz %d, keySz %d\n", inSz, keySz);
3029
3030#ifdef TEST_PK_PRIVKEY
3031 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
3032 if (ret != 0)
3033 return ret;
3034#endif
3035
3036 ret = wc_ed25519_init(&myKey);
3037 if (ret == 0) {
3038 ret = wc_Ed25519PrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
3039 if (ret == 0)
3040 ret = wc_ed25519_sign_msg(in, inSz, out, outSz, &myKey);
3041 wc_ed25519_free(&myKey);
3042 }
3043
3044#ifdef TEST_PK_PRIVKEY
3045 free(keyBuf);
3046#endif
3047
3048 WOLFSSL_PKMSG("PK 25519 Sign: ret %d, outSz %d\n", ret, *outSz);
3049
3050 return ret;
3051}
3052
3053
3054static WC_INLINE int myEd25519Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
3055 const byte* msg, word32 msgSz, const byte* key, word32 keySz,
3056 int* result, void* ctx)
3057{
3058 int ret;
3059 ed25519_key myKey;
3060 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3061
3062 (void)ssl;
3063 (void)cbInfo;
3064
3065 WOLFSSL_PKMSG("PK 25519 Verify: sigSz %d, msgSz %d, keySz %d\n", sigSz, msgSz, keySz);
3066
3067 ret = wc_ed25519_init(&myKey);
3068 if (ret == 0) {
3069 ret = wc_ed25519_import_public(key, keySz, &myKey);
3070 if (ret == 0) {
3071 ret = wc_ed25519_verify_msg(sig, sigSz, msg, msgSz, result, &myKey);
3072 }
3073 wc_ed25519_free(&myKey);
3074 }
3075
3076 WOLFSSL_PKMSG("PK 25519 Verify: ret %d, result %d\n", ret, *result);
3077
3078 return ret;
3079}
3080#endif /* HAVE_ED25519 */
3081
3082#ifdef HAVE_CURVE25519
3083static WC_INLINE int myX25519KeyGen(WOLFSSL* ssl, curve25519_key* key,
3084 unsigned int keySz, void* ctx)
3085{
3086 int ret;
3087 WC_RNG rng;
3088 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3089
3090 (void)ssl;
3091 (void)cbInfo;
3092
3093 WOLFSSL_PKMSG("PK 25519 KeyGen: keySz %d\n", keySz);
3094
3095 ret = wc_InitRng(&rng);
3096 if (ret != 0)
3097 return ret;
3098
3099 ret = wc_curve25519_make_key(&rng, keySz, key);
3100
3101 wc_FreeRng(&rng);
3102
3103 WOLFSSL_PKMSG("PK 25519 KeyGen: ret %d\n", ret);
3104
3105 return ret;
3106}
3107
3108static WC_INLINE int myX25519SharedSecret(WOLFSSL* ssl, curve25519_key* otherKey,
3109 unsigned char* pubKeyDer, unsigned int* pubKeySz,
3110 unsigned char* out, unsigned int* outlen,
3111 int side, void* ctx)
3112{
3113 int ret;
3114 curve25519_key* privKey = NULL;
3115 curve25519_key* pubKey = NULL;
3116 curve25519_key tmpKey;
3117 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3118
3119 (void)ssl;
3120 (void)cbInfo;
3121
3122 WOLFSSL_PKMSG("PK 25519 PMS: side %s\n",
3123 side == WOLFSSL_CLIENT_END ? "client" : "server");
3124
3125 ret = wc_curve25519_init(&tmpKey);
3126 if (ret != 0) {
3127 return ret;
3128 }
3129
3130 /* for client: create and export public key */
3131 if (side == WOLFSSL_CLIENT_END) {
3132 WC_RNG rng;
3133
3134 privKey = &tmpKey;
3135 pubKey = otherKey;
3136
3137 ret = wc_InitRng(&rng);
3138 if (ret == 0) {
3139 ret = wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, privKey);
3140 if (ret == 0) {
3141 ret = wc_curve25519_export_public_ex(privKey, pubKeyDer,
3142 pubKeySz, EC25519_LITTLE_ENDIAN);
3143 }
3144 wc_FreeRng(&rng);
3145 }
3146 }
3147
3148 /* for server: import public key */
3149 else if (side == WOLFSSL_SERVER_END) {
3150 privKey = otherKey;
3151 pubKey = &tmpKey;
3152
3153 ret = wc_curve25519_import_public_ex(pubKeyDer, *pubKeySz, pubKey,
3154 EC25519_LITTLE_ENDIAN);
3155 }
3156 else {
3157 ret = BAD_FUNC_ARG;
3158 }
3159
3160 /* generate shared secret and return it */
3161 if (ret == 0) {
3162 ret = wc_curve25519_shared_secret_ex(privKey, pubKey, out, outlen,
3163 EC25519_LITTLE_ENDIAN);
3164 }
3165
3166 wc_curve25519_free(&tmpKey);
3167
3168 WOLFSSL_PKMSG("PK 25519 PMS: ret %d, pubKeySz %d, outLen %d\n",
3169 ret, *pubKeySz, *outlen);
3170
3171 return ret;
3172}
3173#endif /* HAVE_CURVE25519 */
3174
3175#ifdef HAVE_ED448
3176static WC_INLINE int myEd448Sign(WOLFSSL* ssl, const byte* in, word32 inSz,
3177 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
3178{
3179 int ret;
3180 word32 idx = 0;
3181 ed448_key myKey;
3182 byte* keyBuf = (byte*)key;
3183 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3184
3185 (void)ssl;
3186 (void)cbInfo;
3187
3188 WOLFSSL_PKMSG("PK 448 Sign: inSz %d, keySz %d\n", inSz, keySz);
3189
3190#ifdef TEST_PK_PRIVKEY
3191 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
3192 if (ret != 0)
3193 return ret;
3194#endif
3195
3196 ret = wc_ed448_init(&myKey);
3197 if (ret == 0) {
3198 ret = wc_Ed448PrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
3199 if (ret == 0)
3200 ret = wc_ed448_sign_msg(in, inSz, out, outSz, &myKey, NULL, 0);
3201 wc_ed448_free(&myKey);
3202 }
3203
3204#ifdef TEST_PK_PRIVKEY
3205 free(keyBuf);
3206#endif
3207
3208 WOLFSSL_PKMSG("PK 448 Sign: ret %d, outSz %d\n", ret, *outSz);
3209
3210 return ret;
3211}
3212
3213
3214static WC_INLINE int myEd448Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
3215 const byte* msg, word32 msgSz, const byte* key, word32 keySz,
3216 int* result, void* ctx)
3217{
3218 int ret;
3219 ed448_key myKey;
3220 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3221
3222 (void)ssl;
3223 (void)cbInfo;
3224
3225 WOLFSSL_PKMSG("PK 448 Verify: sigSz %d, msgSz %d, keySz %d\n", sigSz, msgSz,
3226 keySz);
3227
3228 ret = wc_ed448_init(&myKey);
3229 if (ret == 0) {
3230 ret = wc_ed448_import_public(key, keySz, &myKey);
3231 if (ret == 0) {
3232 ret = wc_ed448_verify_msg(sig, sigSz, msg, msgSz, result, &myKey,
3233 NULL, 0);
3234 }
3235 wc_ed448_free(&myKey);
3236 }
3237
3238 WOLFSSL_PKMSG("PK 448 Verify: ret %d, result %d\n", ret, *result);
3239
3240 return ret;
3241}
3242#endif /* HAVE_ED448 */
3243
3244#ifdef HAVE_CURVE448
3245static WC_INLINE int myX448KeyGen(WOLFSSL* ssl, curve448_key* key,
3246 unsigned int keySz, void* ctx)
3247{
3248 int ret;
3249 WC_RNG rng;
3250 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3251
3252 (void)ssl;
3253 (void)cbInfo;
3254
3255 WOLFSSL_PKMSG("PK 448 KeyGen: keySz %d\n", keySz);
3256
3257 ret = wc_InitRng(&rng);
3258 if (ret != 0)
3259 return ret;
3260
3261 ret = wc_curve448_make_key(&rng, keySz, key);
3262
3263 wc_FreeRng(&rng);
3264
3265 WOLFSSL_PKMSG("PK 448 KeyGen: ret %d\n", ret);
3266
3267 return ret;
3268}
3269
3270static WC_INLINE int myX448SharedSecret(WOLFSSL* ssl, curve448_key* otherKey,
3271 unsigned char* pubKeyDer, unsigned int* pubKeySz,
3272 unsigned char* out, unsigned int* outlen,
3273 int side, void* ctx)
3274{
3275 int ret;
3276 curve448_key* privKey = NULL;
3277 curve448_key* pubKey = NULL;
3278 curve448_key tmpKey;
3279 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3280
3281 (void)ssl;
3282 (void)cbInfo;
3283
3284 WOLFSSL_PKMSG("PK 448 PMS: side %s\n",
3285 side == WOLFSSL_CLIENT_END ? "client" : "server");
3286
3287 ret = wc_curve448_init(&tmpKey);
3288 if (ret != 0) {
3289 return ret;
3290 }
3291
3292 /* for client: create and export public key */
3293 if (side == WOLFSSL_CLIENT_END) {
3294 WC_RNG rng;
3295
3296 privKey = &tmpKey;
3297 pubKey = otherKey;
3298
3299 ret = wc_InitRng(&rng);
3300 if (ret == 0) {
3301 ret = wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, privKey);
3302 if (ret == 0) {
3303 ret = wc_curve448_export_public_ex(privKey, pubKeyDer,
3304 pubKeySz, EC448_LITTLE_ENDIAN);
3305 }
3306 wc_FreeRng(&rng);
3307 }
3308 }
3309
3310 /* for server: import public key */
3311 else if (side == WOLFSSL_SERVER_END) {
3312 privKey = otherKey;
3313 pubKey = &tmpKey;
3314
3315 ret = wc_curve448_import_public_ex(pubKeyDer, *pubKeySz, pubKey,
3316 EC448_LITTLE_ENDIAN);
3317 }
3318 else {
3319 ret = BAD_FUNC_ARG;
3320 }
3321
3322 /* generate shared secret and return it */
3323 if (ret == 0) {
3324 ret = wc_curve448_shared_secret_ex(privKey, pubKey, out, outlen,
3325 EC448_LITTLE_ENDIAN);
3326 }
3327
3328 wc_curve448_free(&tmpKey);
3329
3330 WOLFSSL_PKMSG("PK 448 PMS: ret %d, pubKeySz %d, outLen %d\n",
3331 ret, *pubKeySz, *outlen);
3332
3333 return ret;
3334}
3335#endif /* HAVE_CURVE448 */
3336
3337#endif /* HAVE_ECC */
3338
3339#ifndef NO_DH
3340static WC_INLINE int myDhCallback(WOLFSSL* ssl, struct DhKey* key,
3341 const unsigned char* priv, unsigned int privSz,
3342 const unsigned char* pubKeyDer, unsigned int pubKeySz,
3343 unsigned char* out, unsigned int* outlen,
3344 void* ctx)
3345{
3346 int ret;
3347 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3348
3349 (void)ssl;
3350 (void)cbInfo;
3351
3352 /* return 0 on success */
3353 ret = wc_DhAgree(key, out, outlen, priv, privSz, pubKeyDer, pubKeySz);
3354
3355 WOLFSSL_PKMSG("PK ED Agree: ret %d, privSz %d, pubKeySz %d, outlen %d\n",
3356 ret, privSz, pubKeySz, *outlen);
3357
3358 return ret;
3359};
3360
3361#endif /* !NO_DH */
3362
3363#ifndef NO_RSA
3364
3365static WC_INLINE int myRsaSign(WOLFSSL* ssl, const byte* in, word32 inSz,
3366 byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
3367{
3368 WC_RNG rng;
3369 int ret;
3370 word32 idx = 0;
3371 RsaKey myKey;
3372 byte* keyBuf = (byte*)key;
3373 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3374
3375 (void)ssl;
3376 (void)cbInfo;
3377
3378 WOLFSSL_PKMSG("PK RSA Sign: inSz %d, keySz %d\n", inSz, keySz);
3379
3380#ifdef TEST_PK_PRIVKEY
3381 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
3382 if (ret != 0)
3383 return ret;
3384#endif
3385
3386 ret = wc_InitRng(&rng);
3387 if (ret != 0)
3388 return ret;
3389
3390 ret = wc_InitRsaKey(&myKey, NULL);
3391 if (ret == 0) {
3392 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
3393 if (ret == 0)
3394 ret = wc_RsaSSL_Sign(in, inSz, out, *outSz, &myKey, &rng);
3395 if (ret > 0) { /* save and convert to 0 success */
3396 *outSz = ret;
3397 ret = 0;
3398 }
3399 wc_FreeRsaKey(&myKey);
3400 }
3401 wc_FreeRng(&rng);
3402
3403#ifdef TEST_PK_PRIVKEY
3404 free(keyBuf);
3405#endif
3406
3407 WOLFSSL_PKMSG("PK RSA Sign: ret %d, outSz %d\n", ret, *outSz);
3408
3409 return ret;
3410}
3411
3412
3413static WC_INLINE int myRsaVerify(WOLFSSL* ssl, byte* sig, word32 sigSz,
3414 byte** out, const byte* key, word32 keySz, void* ctx)
3415{
3416 int ret;
3417 word32 idx = 0;
3418 RsaKey myKey;
3419 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3420
3421 (void)ssl;
3422 (void)cbInfo;
3423
3424 WOLFSSL_PKMSG("PK RSA Verify: sigSz %d, keySz %d\n", sigSz, keySz);
3425
3426 ret = wc_InitRsaKey(&myKey, NULL);
3427 if (ret == 0) {
3428 ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
3429 if (ret == 0)
3430 ret = wc_RsaSSL_VerifyInline(sig, sigSz, out, &myKey);
3431 wc_FreeRsaKey(&myKey);
3432 }
3433
3434 WOLFSSL_PKMSG("PK RSA Verify: ret %d\n", ret);
3435
3436 return ret;
3437}
3438
3439static WC_INLINE int myRsaSignCheck(WOLFSSL* ssl, byte* sig, word32 sigSz,
3440 byte** out, const byte* key, word32 keySz, void* ctx)
3441{
3442 int ret;
3443 word32 idx = 0;
3444 RsaKey myKey;
3445 byte* keyBuf = (byte*)key;
3446 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3447
3448 (void)ssl;
3449 (void)cbInfo;
3450
3451 WOLFSSL_PKMSG("PK RSA SignCheck: sigSz %d, keySz %d\n", sigSz, keySz);
3452
3453#ifdef TEST_PK_PRIVKEY
3454 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
3455 if (ret != 0)
3456 return ret;
3457#endif
3458
3459 ret = wc_InitRsaKey(&myKey, NULL);
3460 if (ret == 0) {
3461 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
3462 if (ret == 0)
3463 ret = wc_RsaSSL_VerifyInline(sig, sigSz, out, &myKey);
3464 wc_FreeRsaKey(&myKey);
3465 }
3466#ifdef TEST_PK_PRIVKEY
3467 free(keyBuf);
3468#endif
3469
3470 WOLFSSL_PKMSG("PK RSA SignCheck: ret %d\n", ret);
3471
3472 return ret;
3473}
3474
3475#ifdef WC_RSA_PSS
3476static WC_INLINE int myRsaPssSign(WOLFSSL* ssl, const byte* in, word32 inSz,
3477 byte* out, word32* outSz, int hash, int mgf, const byte* key,
3478 word32 keySz, void* ctx)
3479{
3480 enum wc_HashType hashType = WC_HASH_TYPE_NONE;
3481 WC_RNG rng;
3482 int ret;
3483 word32 idx = 0;
3484 RsaKey myKey;
3485 byte* keyBuf = (byte*)key;
3486 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3487
3488 (void)ssl;
3489 (void)cbInfo;
3490
3491 WOLFSSL_PKMSG("PK RSA PSS Sign: inSz %d, hash %d, mgf %d, keySz %d\n",
3492 inSz, hash, mgf, keySz);
3493
3494#ifdef TEST_PK_PRIVKEY
3495 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
3496 if (ret != 0)
3497 return ret;
3498#endif
3499
3500 switch (hash) {
3501#ifndef NO_SHA256
3502 case SHA256h:
3503 hashType = WC_HASH_TYPE_SHA256;
3504 break;
3505#endif
3506#ifdef WOLFSSL_SHA384
3507 case SHA384h:
3508 hashType = WC_HASH_TYPE_SHA384;
3509 break;
3510#endif
3511#ifdef WOLFSSL_SHA512
3512 case SHA512h:
3513 hashType = WC_HASH_TYPE_SHA512;
3514 break;
3515#endif
3516 }
3517
3518 ret = wc_InitRng(&rng);
3519 if (ret != 0)
3520 return ret;
3521
3522 ret = wc_InitRsaKey(&myKey, NULL);
3523 if (ret == 0) {
3524 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
3525 if (ret == 0) {
3526 ret = wc_RsaPSS_Sign(in, inSz, out, *outSz, hashType, mgf, &myKey,
3527 &rng);
3528 }
3529 if (ret > 0) { /* save and convert to 0 success */
3530 *outSz = ret;
3531 ret = 0;
3532 }
3533 wc_FreeRsaKey(&myKey);
3534 }
3535 wc_FreeRng(&rng);
3536
3537#ifdef TEST_PK_PRIVKEY
3538 free(keyBuf);
3539#endif
3540
3541 WOLFSSL_PKMSG("PK RSA PSS Sign: ret %d, outSz %d\n", ret, *outSz);
3542
3543 return ret;
3544}
3545
3546
3547static WC_INLINE int myRsaPssVerify(WOLFSSL* ssl, byte* sig, word32 sigSz,
3548 byte** out, int hash, int mgf, const byte* key, word32 keySz, void* ctx)
3549{
3550 int ret;
3551 word32 idx = 0;
3552 RsaKey myKey;
3553 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3554 enum wc_HashType hashType = WC_HASH_TYPE_NONE;
3555
3556 (void)ssl;
3557 (void)cbInfo;
3558
3559 WOLFSSL_PKMSG("PK RSA PSS Verify: sigSz %d, hash %d, mgf %d, keySz %d\n",
3560 sigSz, hash, mgf, keySz);
3561
3562 switch (hash) {
3563#ifndef NO_SHA256
3564 case SHA256h:
3565 hashType = WC_HASH_TYPE_SHA256;
3566 break;
3567#endif
3568#ifdef WOLFSSL_SHA384
3569 case SHA384h:
3570 hashType = WC_HASH_TYPE_SHA384;
3571 break;
3572#endif
3573#ifdef WOLFSSL_SHA512
3574 case SHA512h:
3575 hashType = WC_HASH_TYPE_SHA512;
3576 break;
3577#endif
3578 }
3579
3580 ret = wc_InitRsaKey(&myKey, NULL);
3581 if (ret == 0) {
3582 ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
3583 if (ret == 0) {
3584 ret = wc_RsaPSS_VerifyInline(sig, sigSz, out, hashType, mgf,
3585 &myKey);
3586 }
3587 wc_FreeRsaKey(&myKey);
3588 }
3589
3590 WOLFSSL_PKMSG("PK RSA PSS Verify: ret %d\n", ret);
3591
3592 return ret;
3593}
3594
3595static WC_INLINE int myRsaPssSignCheck(WOLFSSL* ssl, byte* sig, word32 sigSz,
3596 byte** out, int hash, int mgf, const byte* key, word32 keySz, void* ctx)
3597{
3598 int ret;
3599 word32 idx = 0;
3600 RsaKey myKey;
3601 byte* keyBuf = (byte*)key;
3602 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3603 enum wc_HashType hashType = WC_HASH_TYPE_NONE;
3604
3605 (void)ssl;
3606 (void)cbInfo;
3607
3608 WOLFSSL_PKMSG("PK RSA PSS SignCheck: sigSz %d, hash %d, mgf %d, keySz %d\n",
3609 sigSz, hash, mgf, keySz);
3610
3611#ifdef TEST_PK_PRIVKEY
3612 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
3613 if (ret != 0)
3614 return ret;
3615#endif
3616
3617 switch (hash) {
3618#ifndef NO_SHA256
3619 case SHA256h:
3620 hashType = WC_HASH_TYPE_SHA256;
3621 break;
3622#endif
3623#ifdef WOLFSSL_SHA384
3624 case SHA384h:
3625 hashType = WC_HASH_TYPE_SHA384;
3626 break;
3627#endif
3628#ifdef WOLFSSL_SHA512
3629 case SHA512h:
3630 hashType = WC_HASH_TYPE_SHA512;
3631 break;
3632#endif
3633 }
3634
3635 ret = wc_InitRsaKey(&myKey, NULL);
3636 if (ret == 0) {
3637 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
3638 if (ret == 0) {
3639 ret = wc_RsaPSS_VerifyInline(sig, sigSz, out, hashType, mgf,
3640 &myKey);
3641 }
3642 wc_FreeRsaKey(&myKey);
3643 }
3644
3645#ifdef TEST_PK_PRIVKEY
3646 free(keyBuf);
3647#endif
3648
3649 WOLFSSL_PKMSG("PK RSA PSS SignCheck: ret %d\n", ret);
3650
3651 return ret;
3652}
3653#endif
3654
3655
3656static WC_INLINE int myRsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz,
3657 byte* out, word32* outSz, const byte* key,
3658 word32 keySz, void* ctx)
3659{
3660 int ret;
3661 word32 idx = 0;
3662 RsaKey myKey;
3663 WC_RNG rng;
3664 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3665
3666 (void)ssl;
3667 (void)cbInfo;
3668
3669 WOLFSSL_PKMSG("PK RSA Enc: inSz %d, keySz %d\n", inSz, keySz);
3670
3671 ret = wc_InitRng(&rng);
3672 if (ret != 0)
3673 return ret;
3674
3675 ret = wc_InitRsaKey(&myKey, NULL);
3676 if (ret == 0) {
3677 ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
3678 if (ret == 0) {
3679 ret = wc_RsaPublicEncrypt(in, inSz, out, *outSz, &myKey, &rng);
3680 if (ret > 0) {
3681 *outSz = ret;
3682 ret = 0; /* reset to success */
3683 }
3684 }
3685 wc_FreeRsaKey(&myKey);
3686 }
3687 wc_FreeRng(&rng);
3688
3689 WOLFSSL_PKMSG("PK RSA Enc: ret %d, outSz %d\n", ret, *outSz);
3690
3691 return ret;
3692}
3693
3694static WC_INLINE int myRsaDec(WOLFSSL* ssl, byte* in, word32 inSz,
3695 byte** out,
3696 const byte* key, word32 keySz, void* ctx)
3697{
3698 int ret;
3699 word32 idx = 0;
3700 RsaKey myKey;
3701 byte* keyBuf = (byte*)key;
3702 PkCbInfo* cbInfo = (PkCbInfo*)ctx;
3703
3704 (void)ssl;
3705 (void)cbInfo;
3706
3707 WOLFSSL_PKMSG("PK RSA Dec: inSz %d, keySz %d\n", inSz, keySz);
3708
3709#ifdef TEST_PK_PRIVKEY
3710 ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz);
3711 if (ret != 0)
3712 return ret;
3713#endif
3714
3715 ret = wc_InitRsaKey(&myKey, NULL);
3716 if (ret == 0) {
3717 ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
3718 if (ret == 0) {
3719 #ifdef WC_RSA_BLINDING
3720 ret = wc_RsaSetRNG(&myKey, wolfSSL_GetRNG(ssl));
3721 if (ret != 0) {
3722 wc_FreeRsaKey(&myKey);
3723 return ret;
3724 }
3725 #endif
3726 ret = wc_RsaPrivateDecryptInline(in, inSz, out, &myKey);
3727 }
3728 wc_FreeRsaKey(&myKey);
3729 }
3730
3731#ifdef TEST_PK_PRIVKEY
3732 free(keyBuf);
3733#endif
3734
3735 WOLFSSL_PKMSG("PK RSA Dec: ret %d\n", ret);
3736
3737 return ret;
3738}
3739
3740#endif /* NO_RSA */
3741
3742static WC_INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx)
3743{
3744 (void)ctx;
3745
3746 #ifdef HAVE_ECC
3747 wolfSSL_CTX_SetEccKeyGenCb(ctx, myEccKeyGen);
3748 wolfSSL_CTX_SetEccSignCb(ctx, myEccSign);
3749 wolfSSL_CTX_SetEccVerifyCb(ctx, myEccVerify);
3750 wolfSSL_CTX_SetEccSharedSecretCb(ctx, myEccSharedSecret);
3751 #endif /* HAVE_ECC */
3752 #ifndef NO_DH
3753 wolfSSL_CTX_SetDhAgreeCb(ctx, myDhCallback);
3754 #endif
3755 #ifdef HAVE_ED25519
3756 wolfSSL_CTX_SetEd25519SignCb(ctx, myEd25519Sign);
3757 wolfSSL_CTX_SetEd25519VerifyCb(ctx, myEd25519Verify);
3758 #endif
3759 #ifdef HAVE_CURVE25519
3760 wolfSSL_CTX_SetX25519KeyGenCb(ctx, myX25519KeyGen);
3761 wolfSSL_CTX_SetX25519SharedSecretCb(ctx, myX25519SharedSecret);
3762 #endif
3763 #ifdef HAVE_ED448
3764 wolfSSL_CTX_SetEd448SignCb(ctx, myEd448Sign);
3765 wolfSSL_CTX_SetEd448VerifyCb(ctx, myEd448Verify);
3766 #endif
3767 #ifdef HAVE_CURVE448
3768 wolfSSL_CTX_SetX448KeyGenCb(ctx, myX448KeyGen);
3769 wolfSSL_CTX_SetX448SharedSecretCb(ctx, myX448SharedSecret);
3770 #endif
3771 #ifndef NO_RSA
3772 wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign);
3773 wolfSSL_CTX_SetRsaVerifyCb(ctx, myRsaVerify);
3774 wolfSSL_CTX_SetRsaSignCheckCb(ctx, myRsaSignCheck);
3775 #ifdef WC_RSA_PSS
3776 wolfSSL_CTX_SetRsaPssSignCb(ctx, myRsaPssSign);
3777 wolfSSL_CTX_SetRsaPssVerifyCb(ctx, myRsaPssVerify);
3778 wolfSSL_CTX_SetRsaPssSignCheckCb(ctx, myRsaPssSignCheck);
3779 #endif
3780 wolfSSL_CTX_SetRsaEncCb(ctx, myRsaEnc);
3781 wolfSSL_CTX_SetRsaDecCb(ctx, myRsaDec);
3782 #endif /* NO_RSA */
3783}
3784
3785static WC_INLINE void SetupPkCallbackContexts(WOLFSSL* ssl, void* myCtx)
3786{
3787 #ifdef HAVE_ECC
3788 wolfSSL_SetEccKeyGenCtx(ssl, myCtx);
3789 wolfSSL_SetEccSignCtx(ssl, myCtx);
3790 wolfSSL_SetEccVerifyCtx(ssl, myCtx);
3791 wolfSSL_SetEccSharedSecretCtx(ssl, myCtx);
3792 #endif /* HAVE_ECC */
3793 #ifndef NO_DH
3794 wolfSSL_SetDhAgreeCtx(ssl, myCtx);
3795 #endif
3796 #ifdef HAVE_ED25519
3797 wolfSSL_SetEd25519SignCtx(ssl, myCtx);
3798 wolfSSL_SetEd25519VerifyCtx(ssl, myCtx);
3799 #endif
3800 #ifdef HAVE_CURVE25519
3801 wolfSSL_SetX25519KeyGenCtx(ssl, myCtx);
3802 wolfSSL_SetX25519SharedSecretCtx(ssl, myCtx);
3803 #endif
3804 #ifdef HAVE_ED448
3805 wolfSSL_SetEd448SignCtx(ssl, myCtx);
3806 wolfSSL_SetEd448VerifyCtx(ssl, myCtx);
3807 #endif
3808 #ifdef HAVE_CURVE448
3809 wolfSSL_SetX448KeyGenCtx(ssl, myCtx);
3810 wolfSSL_SetX448SharedSecretCtx(ssl, myCtx);
3811 #endif
3812 #ifndef NO_RSA
3813 wolfSSL_SetRsaSignCtx(ssl, myCtx);
3814 wolfSSL_SetRsaVerifyCtx(ssl, myCtx);
3815 #ifdef WC_RSA_PSS
3816 wolfSSL_SetRsaPssSignCtx(ssl, myCtx);
3817 wolfSSL_SetRsaPssVerifyCtx(ssl, myCtx);
3818 #endif
3819 wolfSSL_SetRsaEncCtx(ssl, myCtx);
3820 wolfSSL_SetRsaDecCtx(ssl, myCtx);
3821 #endif /* NO_RSA */
3822}
3823
3824#endif /* HAVE_PK_CALLBACKS */
3825
3826static WC_INLINE int SimulateWantWriteIOSendCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
3827{
3828 static int wantWriteFlag = 1;
3829
3830 int sent;
3831 int sd = *(int*)ctx;
3832
3833 (void)ssl;
3834
3835 if (!wantWriteFlag)
3836 {
3837 wantWriteFlag = 1;
3838
3839 sent = wolfIO_Send(sd, buf, sz, 0);
3840 if (sent < 0) {
3841 int err = errno;
3842
3843 if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
3844 return WOLFSSL_CBIO_ERR_WANT_WRITE;
3845 }
3846 else if (err == SOCKET_ECONNRESET) {
3847 return WOLFSSL_CBIO_ERR_CONN_RST;
3848 }
3849 else if (err == SOCKET_EINTR) {
3850 return WOLFSSL_CBIO_ERR_ISR;
3851 }
3852 else if (err == SOCKET_EPIPE) {
3853 return WOLFSSL_CBIO_ERR_CONN_CLOSE;
3854 }
3855 else {
3856 return WOLFSSL_CBIO_ERR_GENERAL;
3857 }
3858 }
3859
3860 return sent;
3861 }
3862 else
3863 {
3864 wantWriteFlag = 0;
3865 return WOLFSSL_CBIO_ERR_WANT_WRITE;
3866 }
3867}
3868
3869#if defined(__hpux__) || defined(__MINGW32__) || defined (WOLFSSL_TIRTOS) \
3870 || defined(_MSC_VER)
3871
3872/* HP/UX doesn't have strsep, needed by test/suites.c */
3873static WC_INLINE char* strsep(char **stringp, const char *delim)
3874{
3875 char* start;
3876 char* end;
3877
3878 start = *stringp;
3879 if (start == NULL)
3880 return NULL;
3881
3882 if ((end = strpbrk(start, delim))) {
3883 *end++ = '\0';
3884 *stringp = end;
3885 } else {
3886 *stringp = NULL;
3887 }
3888
3889 return start;
3890}
3891
3892#endif /* __hpux__ and others */
3893
3894/* Create unique filename, len is length of tempfn name, assuming
3895 len does not include null terminating character,
3896 num is number of characters in tempfn name to randomize */
3897static WC_INLINE const char* mymktemp(char *tempfn, int len, int num)
3898{
3899 int x, size;
3900 static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
3901 "abcdefghijklmnopqrstuvwxyz";
3902 WC_RNG rng;
3903 byte out;
3904
3905 if (tempfn == NULL || len < 1 || num < 1 || len <= num) {
3906 printf("Bad input\n");
3907 return NULL;
3908 }
3909
3910 size = len - 1;
3911
3912 if (wc_InitRng(&rng) != 0) {
3913 printf("InitRng failed\n");
3914 return NULL;
3915 }
3916
3917 for (x = size; x > size - num; x--) {
3918 if (wc_RNG_GenerateBlock(&rng,(byte*)&out, sizeof(out)) != 0) {
3919 printf("RNG_GenerateBlock failed\n");
3920 return NULL;
3921 }
3922 tempfn[x] = alphanum[out % (sizeof(alphanum) - 1)];
3923 }
3924 tempfn[len] = '\0';
3925
3926 wc_FreeRng(&rng);
3927 (void)rng; /* for WC_NO_RNG case */
3928
3929 return tempfn;
3930}
3931
3932
3933
3934#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
3935 ((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || \
3936 defined(HAVE_AESGCM))
3937
3938#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
3939 #include <wolfssl/wolfcrypt/chacha20_poly1305.h>
3940 #define WOLFSSL_TICKET_KEY_SZ CHACHA20_POLY1305_AEAD_KEYSIZE
3941#elif defined(HAVE_AESGCM)
3942 #include <wolfssl/wolfcrypt/aes.h>
3943 #include <wolfssl/wolfcrypt/wc_encrypt.h> /* AES IV sizes in FIPS mode */
3944 #define WOLFSSL_TICKET_KEY_SZ AES_256_KEY_SIZE
3945#endif
3946
3947 typedef struct key_ctx {
3948 byte name[WOLFSSL_TICKET_NAME_SZ]; /* name for this context */
3949 byte key[WOLFSSL_TICKET_KEY_SZ]; /* cipher key */
3950 } key_ctx;
3951
3952 static THREAD_LS_T key_ctx myKey_ctx;
3953 static THREAD_LS_T WC_RNG myKey_rng;
3954
3955 static WC_INLINE int TicketInit(void)
3956 {
3957 int ret = wc_InitRng(&myKey_rng);
3958 if (ret != 0) return ret;
3959
3960 ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.key, sizeof(myKey_ctx.key));
3961 if (ret != 0) return ret;
3962
3963 ret = wc_RNG_GenerateBlock(&myKey_rng, myKey_ctx.name,sizeof(myKey_ctx.name));
3964 if (ret != 0) return ret;
3965
3966 return 0;
3967 }
3968
3969 static WC_INLINE void TicketCleanup(void)
3970 {
3971 wc_FreeRng(&myKey_rng);
3972 }
3973
3974 static WC_INLINE int myTicketEncCb(WOLFSSL* ssl,
3975 byte key_name[WOLFSSL_TICKET_NAME_SZ],
3976 byte iv[WOLFSSL_TICKET_IV_SZ],
3977 byte mac[WOLFSSL_TICKET_MAC_SZ],
3978 int enc, byte* ticket, int inLen, int* outLen,
3979 void* userCtx)
3980 {
3981 int ret;
3982 word16 sLen = XHTONS(inLen);
3983 byte aad[WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2];
3984 int aadSz = WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2;
3985 byte* tmp = aad;
3986 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
3987 /* chahca20/poly1305 */
3988 #elif defined(HAVE_AESGCM)
3989 Aes aes;
3990 #endif
3991
3992 (void)ssl;
3993 (void)userCtx;
3994
3995 /* encrypt */
3996 if (enc) {
3997 XMEMCPY(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ);
3998
3999 ret = wc_RNG_GenerateBlock(&myKey_rng, iv, WOLFSSL_TICKET_IV_SZ);
4000 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
4001
4002 /* build aad from key name, iv, and length */
4003 XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ);
4004 tmp += WOLFSSL_TICKET_NAME_SZ;
4005 XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
4006 tmp += WOLFSSL_TICKET_IV_SZ;
4007 XMEMCPY(tmp, &sLen, sizeof(sLen));
4008
4009 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
4010 ret = wc_ChaCha20Poly1305_Encrypt(myKey_ctx.key, iv,
4011 aad, aadSz,
4012 ticket, inLen,
4013 ticket,
4014 mac);
4015 #elif defined(HAVE_AESGCM)
4016 ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
4017 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
4018
4019 ret = wc_AesGcmSetKey(&aes, myKey_ctx.key, sizeof(myKey_ctx.key));
4020 if (ret == 0) {
4021 ret = wc_AesGcmEncrypt(&aes, ticket, ticket, inLen,
4022 iv, GCM_NONCE_MID_SZ, mac, AES_BLOCK_SIZE,
4023 aad, aadSz);
4024 }
4025 wc_AesFree(&aes);
4026 #endif
4027
4028 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
4029 *outLen = inLen; /* no padding in this mode */
4030 }
4031 /* decrypt */
4032 else {
4033 /* see if we know this key */
4034 if (XMEMCMP(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ) != 0){
4035 printf("client presented unknown ticket key name %s\n", key_name);
4036 return WOLFSSL_TICKET_RET_FATAL;
4037 }
4038
4039 /* build aad from key name, iv, and length */
4040 XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ);
4041 tmp += WOLFSSL_TICKET_NAME_SZ;
4042 XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
4043 tmp += WOLFSSL_TICKET_IV_SZ;
4044 XMEMCPY(tmp, &sLen, sizeof(sLen));
4045
4046 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
4047 ret = wc_ChaCha20Poly1305_Decrypt(myKey_ctx.key, iv,
4048 aad, aadSz,
4049 ticket, inLen,
4050 mac,
4051 ticket);
4052 #elif defined(HAVE_AESGCM)
4053 ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
4054 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
4055
4056 ret = wc_AesGcmSetKey(&aes, myKey_ctx.key, sizeof(myKey_ctx.key));
4057 if (ret == 0) {
4058 ret = wc_AesGcmDecrypt(&aes, ticket, ticket, inLen,
4059 iv, GCM_NONCE_MID_SZ, mac, AES_BLOCK_SIZE,
4060 aad, aadSz);
4061 }
4062 wc_AesFree(&aes);
4063 #endif
4064
4065 if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
4066 *outLen = inLen; /* no padding in this mode */
4067 }
4068
4069 return WOLFSSL_TICKET_RET_OK;
4070 }
4071
4072#endif /* HAVE_SESSION_TICKET && ((HAVE_CHACHA && HAVE_POLY1305) || HAVE_AESGCM) */
4073
4074
4075static WC_INLINE word16 GetRandomPort(void)
4076{
4077 word16 port = 0;
4078
4079 /* Generate random port for testing */
4080 WC_RNG rng;
4081 if (wc_InitRng(&rng) == 0) {
4082 if (wc_RNG_GenerateBlock(&rng, (byte*)&port, sizeof(port)) == 0) {
4083 port |= 0xC000; /* Make sure its in the 49152 - 65535 range */
4084 }
4085 wc_FreeRng(&rng);
4086 }
4087 (void)rng; /* for WC_NO_RNG case */
4088 return port;
4089}
4090
4091#endif /* wolfSSL_TEST_H */
Note: See TracBrowser for help on using the repository browser.