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