]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/WolfSSL/wolfssl/test.h
Update WolfSSL library to the latest version.
[freertos] / FreeRTOS-Plus / Source / WolfSSL / wolfssl / test.h
1 /* test.h */
2
3 #ifndef wolfSSL_TEST_H
4 #define wolfSSL_TEST_H
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <assert.h>
9 #include <ctype.h>
10 #include <wolfssl/wolfcrypt/types.h>
11 #include <wolfssl/wolfcrypt/error-crypt.h>
12 #include <wolfssl/wolfcrypt/random.h>
13
14 #ifdef ATOMIC_USER
15     #include <wolfssl/wolfcrypt/aes.h>
16     #include <wolfssl/wolfcrypt/arc4.h>
17     #include <wolfssl/wolfcrypt/hmac.h>
18 #endif
19 #ifdef HAVE_PK_CALLBACKS
20     #include <wolfssl/wolfcrypt/asn.h>
21     #ifdef HAVE_ECC
22         #include <wolfssl/wolfcrypt/ecc.h>
23     #endif /* HAVE_ECC */
24 #endif /*HAVE_PK_CALLBACKS */
25
26 #ifdef USE_WINDOWS_API 
27     #include <winsock2.h>
28     #include <process.h>
29     #ifdef TEST_IPV6            /* don't require newer SDK for IPV4 */
30         #include <ws2tcpip.h>
31         #include <wspiapi.h>
32     #endif
33     #define SOCKET_T SOCKET
34     #define SNPRINTF _snprintf
35 #elif defined(WOLFSSL_MDK_ARM)
36     #include <string.h>
37 #elif defined(WOLFSSL_TIRTOS)
38     #include <string.h>
39     #include <netdb.h>
40     #include <sys/types.h>
41     #include <arpa/inet.h>
42     #include <sys/socket.h>
43     #include <ti/sysbios/knl/Task.h>
44     struct hostent {
45         char *h_name; /* official name of host */
46         char **h_aliases; /* alias list */
47         int h_addrtype; /* host address type */
48         int h_length; /* length of address */
49         char **h_addr_list; /* list of addresses from name server */
50     };
51     #define SOCKET_T int
52 #else
53     #include <string.h>
54     #include <sys/types.h>
55 #ifndef WOLFSSL_LEANPSK
56     #include <unistd.h>
57     #include <netdb.h>
58     #include <netinet/in.h>
59     #include <netinet/tcp.h>
60     #include <arpa/inet.h>
61     #include <sys/ioctl.h>
62     #include <sys/time.h>
63     #include <sys/socket.h>
64     #include <pthread.h>
65     #include <fcntl.h>
66     #ifdef TEST_IPV6
67         #include <netdb.h>
68     #endif
69 #endif
70     #define SOCKET_T int
71     #ifndef SO_NOSIGPIPE
72         #include <signal.h>  /* ignore SIGPIPE */
73     #endif
74     #define SNPRINTF snprintf
75 #endif /* USE_WINDOWS_API */
76
77 #ifdef HAVE_CAVIUM
78     #include "cavium_sysdep.h"
79     #include "cavium_common.h"
80     #include "cavium_ioctl.h"
81 #endif
82
83 #ifdef _MSC_VER
84     /* disable conversion warning */
85     /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
86     #pragma warning(disable:4244 4996)
87 #endif
88
89
90 #if defined(__MACH__) || defined(USE_WINDOWS_API)
91     #ifndef _SOCKLEN_T
92         typedef int socklen_t;
93     #endif
94 #endif
95
96
97 /* HPUX doesn't use socklent_t for third parameter to accept, unless
98    _XOPEN_SOURCE_EXTENDED is defined */
99 #if !defined(__hpux__) && !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_IAR_ARM)
100     typedef socklen_t* ACCEPT_THIRD_T;
101 #else
102     #if defined _XOPEN_SOURCE_EXTENDED
103         typedef socklen_t* ACCEPT_THIRD_T;
104     #else
105         typedef int*       ACCEPT_THIRD_T;
106     #endif
107 #endif
108
109
110 #ifdef USE_WINDOWS_API 
111     #define CloseSocket(s) closesocket(s)
112     #define StartTCP() { WSADATA wsd; WSAStartup(0x0002, &wsd); }
113 #elif defined(WOLFSSL_MDK_ARM)
114     #define CloseSocket(s) closesocket(s)
115     #define StartTCP() 
116 #else
117     #define CloseSocket(s) close(s)
118     #define StartTCP() 
119 #endif
120
121
122 #ifdef SINGLE_THREADED
123     typedef unsigned int  THREAD_RETURN;
124     typedef void*         THREAD_TYPE;
125     #define WOLFSSL_THREAD
126 #else
127     #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
128         typedef void*         THREAD_RETURN;
129         typedef pthread_t     THREAD_TYPE;
130         #define WOLFSSL_THREAD
131         #define INFINITE -1
132         #define WAIT_OBJECT_0 0L
133     #elif defined(WOLFSSL_MDK_ARM)
134         typedef unsigned int  THREAD_RETURN;
135         typedef int           THREAD_TYPE;
136         #define WOLFSSL_THREAD
137     #elif defined(WOLFSSL_TIRTOS)
138         typedef void          THREAD_RETURN;
139         typedef Task_Handle   THREAD_TYPE;
140         #define WOLFSSL_THREAD
141     #else
142         typedef unsigned int  THREAD_RETURN;
143         typedef intptr_t      THREAD_TYPE;
144         #define WOLFSSL_THREAD __stdcall
145     #endif
146 #endif
147
148
149 #ifdef TEST_IPV6
150     typedef struct sockaddr_in6 SOCKADDR_IN_T;
151     #define AF_INET_V    AF_INET6
152 #else
153     typedef struct sockaddr_in  SOCKADDR_IN_T;
154     #define AF_INET_V    AF_INET
155 #endif
156    
157
158 #define SERVER_DEFAULT_VERSION 3
159 #define SERVER_DTLS_DEFAULT_VERSION (-2)
160 #define SERVER_INVALID_VERSION (-99)
161 #define CLIENT_DEFAULT_VERSION 3
162 #define CLIENT_DTLS_DEFAULT_VERSION (-2)
163 #define CLIENT_INVALID_VERSION (-99)
164 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
165     #define DEFAULT_MIN_DHKEY_BITS 2048
166 #else
167     #define DEFAULT_MIN_DHKEY_BITS 1024
168 #endif
169
170 /* all certs relative to wolfSSL home directory now */
171 #define caCert     "./certs/ca-cert.pem"
172 #define eccCert    "./certs/server-ecc.pem"
173 #define eccKey     "./certs/ecc-key.pem"
174 #define svrCert    "./certs/server-cert.pem"
175 #define svrKey     "./certs/server-key.pem"
176 #define cliCert    "./certs/client-cert.pem"
177 #define cliKey     "./certs/client-key.pem"
178 #define ntruCert   "./certs/ntru-cert.pem"
179 #define ntruKey    "./certs/ntru-key.raw"
180 #define dhParam    "./certs/dh2048.pem"
181 #define cliEccKey  "./certs/ecc-client-key.pem"
182 #define cliEccCert "./certs/client-ecc-cert.pem"
183 #define crlPemDir  "./certs/crl"
184
185 typedef struct tcp_ready {
186     word16 ready;              /* predicate */
187     word16 port;
188 #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
189     pthread_mutex_t mutex;
190     pthread_cond_t  cond;
191 #endif
192 } tcp_ready;    
193
194
195 void InitTcpReady(tcp_ready*);
196 void FreeTcpReady(tcp_ready*);
197
198 typedef WOLFSSL_METHOD* (*method_provider)(void);
199 typedef void (*ctx_callback)(WOLFSSL_CTX* ctx);
200 typedef void (*ssl_callback)(WOLFSSL* ssl);
201
202 typedef struct callback_functions {
203     method_provider method;
204     ctx_callback ctx_ready;
205     ssl_callback ssl_ready;
206     ssl_callback on_result;
207 } callback_functions;
208
209 typedef struct func_args {
210     int    argc;
211     char** argv;
212     int    return_code;
213     tcp_ready* signal;
214     callback_functions *callbacks;
215 } func_args;
216
217 void wait_tcp_ready(func_args*);
218
219 typedef THREAD_RETURN WOLFSSL_THREAD THREAD_FUNC(void*);
220
221 void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*);
222 void join_thread(THREAD_TYPE);
223
224 /* wolfSSL */
225 #ifndef TEST_IPV6
226     static const char* const wolfSSLIP   = "127.0.0.1";
227 #else
228     static const char* const wolfSSLIP   = "::1";
229 #endif
230 static const word16      wolfSSLPort = 11111;
231
232 static INLINE void err_sys(const char* msg)
233 {
234     printf("wolfSSL error: %s\n", msg);
235     if (msg)
236         exit(EXIT_FAILURE);
237 }
238
239
240 #define MY_EX_USAGE 2
241
242 extern int   myoptind;
243 extern char* myoptarg;
244
245 static INLINE int mygetopt(int argc, char** argv, const char* optstring)
246 {
247     static char* next = NULL;
248
249     char  c;
250     char* cp;
251
252     if (myoptind == 0)
253         next = NULL;   /* we're starting new/over */
254
255     if (next == NULL || *next == '\0') {
256         if (myoptind == 0)
257             myoptind++;
258
259         if (myoptind >= argc || argv[myoptind][0] != '-' ||
260                                 argv[myoptind][1] == '\0') {
261             myoptarg = NULL;
262             if (myoptind < argc)
263                 myoptarg = argv[myoptind];
264
265             return -1;
266         }
267
268         if (strcmp(argv[myoptind], "--") == 0) {
269             myoptind++;
270             myoptarg = NULL;
271
272             if (myoptind < argc)
273                 myoptarg = argv[myoptind];
274
275             return -1;
276         }
277
278         next = argv[myoptind];
279         next++;                  /* skip - */
280         myoptind++;
281     }
282
283     c  = *next++;
284     /* The C++ strchr can return a different value */
285     cp = (char*)strchr(optstring, c);
286
287     if (cp == NULL || c == ':') 
288         return '?';
289
290     cp++;
291
292     if (*cp == ':') {
293         if (*next != '\0') {
294             myoptarg = next;
295             next     = NULL;
296         }
297         else if (myoptind < argc) {
298             myoptarg = argv[myoptind];
299             myoptind++;
300         }
301         else 
302             return '?';
303     }
304
305     return c;
306 }
307
308
309 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
310
311 static INLINE int PasswordCallBack(char* passwd, int sz, int rw, void* userdata)
312 {
313     (void)rw;
314     (void)userdata;
315     strncpy(passwd, "yassl123", sz);
316     return 8;
317 }
318
319 #endif
320
321
322 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
323
324 static INLINE void ShowX509(WOLFSSL_X509* x509, const char* hdr)
325 {
326     char* altName;
327     char* issuer  = wolfSSL_X509_NAME_oneline(
328                                        wolfSSL_X509_get_issuer_name(x509), 0, 0);
329     char* subject = wolfSSL_X509_NAME_oneline(
330                                       wolfSSL_X509_get_subject_name(x509), 0, 0);
331     byte  serial[32];
332     int   ret;
333     int   sz = sizeof(serial);
334         
335     printf("%s\n issuer : %s\n subject: %s\n", hdr, issuer, subject);
336
337     while ( (altName = wolfSSL_X509_get_next_altname(x509)) != NULL)
338         printf(" altname = %s\n", altName);
339
340     ret = wolfSSL_X509_get_serial_number(x509, serial, &sz);
341     if (ret == SSL_SUCCESS) {
342         int  i;
343         int  strLen;
344         char serialMsg[80];
345
346         /* testsuite has multiple threads writing to stdout, get output
347            message ready to write once */
348         strLen = sprintf(serialMsg, " serial number");
349         for (i = 0; i < sz; i++)
350             sprintf(serialMsg + strLen + (i*3), ":%02x ", serial[i]);
351         printf("%s\n", serialMsg);
352     }
353
354     XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
355     XFREE(issuer,  0, DYNAMIC_TYPE_OPENSSL);
356 }
357
358 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
359
360
361 static INLINE void showPeer(WOLFSSL* ssl)
362 {
363
364     WOLFSSL_CIPHER* cipher;
365 #ifdef KEEP_PEER_CERT
366     WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
367     if (peer)
368         ShowX509(peer, "peer's cert info:");
369     else
370         printf("peer has no cert!\n");
371 #endif
372     printf("SSL version is %s\n", wolfSSL_get_version(ssl));
373
374     cipher = wolfSSL_get_current_cipher(ssl);
375     printf("SSL cipher suite is %s\n", wolfSSL_CIPHER_get_name(cipher));
376
377 #if defined(SESSION_CERTS) && defined(SHOW_CERTS)
378     {
379         WOLFSSL_X509_CHAIN* chain = wolfSSL_get_peer_chain(ssl);
380         int                count = wolfSSL_get_chain_count(chain);
381         int i;
382
383         for (i = 0; i < count; i++) {
384             int length;
385             unsigned char buffer[3072];
386             WOLFSSL_X509* chainX509;
387
388             wolfSSL_get_chain_cert_pem(chain,i,buffer, sizeof(buffer), &length);
389             buffer[length] = 0;
390             printf("cert %d has length %d data = \n%s\n", i, length, buffer);
391
392             chainX509 = wolfSSL_get_chain_X509(chain, i);
393             if (chainX509)
394                 ShowX509(chainX509, "session cert info:");
395             else
396                 printf("get_chain_X509 failed\n");
397             wolfSSL_FreeX509(chainX509);
398         }
399     }
400 #endif
401   (void)ssl;
402 }
403
404
405 static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
406                               word16 port, int udp)
407 {
408     int useLookup = 0;
409     (void)useLookup;
410     (void)udp;
411
412     memset(addr, 0, sizeof(SOCKADDR_IN_T));
413
414 #ifndef TEST_IPV6
415     /* peer could be in human readable form */
416     if ( (peer != INADDR_ANY) && isalpha((int)peer[0])) {
417         #ifdef WOLFSSL_MDK_ARM
418             int err;
419             struct hostent* entry = gethostbyname(peer, &err);
420         #elif defined(WOLFSSL_TIRTOS)
421             struct hostent* entry = DNSGetHostByName(peer);
422         #else
423             struct hostent* entry = gethostbyname(peer);
424         #endif
425
426         if (entry) {
427             memcpy(&addr->sin_addr.s_addr, entry->h_addr_list[0],
428                    entry->h_length);
429             useLookup = 1;
430         }
431         else
432             err_sys("no entry for host");
433     }
434 #endif
435
436
437 #ifndef TEST_IPV6
438     #if defined(WOLFSSL_MDK_ARM)
439         addr->sin_family = PF_INET;
440     #else
441         addr->sin_family = AF_INET_V;
442     #endif
443     addr->sin_port = htons(port);
444     if (peer == INADDR_ANY)
445         addr->sin_addr.s_addr = INADDR_ANY;
446     else {
447         if (!useLookup)
448             addr->sin_addr.s_addr = inet_addr(peer);
449     }
450 #else
451     addr->sin6_family = AF_INET_V;
452     addr->sin6_port = htons(port);
453     if (peer == INADDR_ANY)
454         addr->sin6_addr = in6addr_any;
455     else {
456         #ifdef HAVE_GETADDRINFO
457             struct addrinfo  hints;
458             struct addrinfo* answer = NULL;
459             int    ret;
460             char   strPort[80];
461
462             memset(&hints, 0, sizeof(hints));
463
464             hints.ai_family   = AF_INET_V;
465             hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM;
466             hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP;
467
468             SNPRINTF(strPort, sizeof(strPort), "%d", port);
469             strPort[79] = '\0';
470
471             ret = getaddrinfo(peer, strPort, &hints, &answer);
472             if (ret < 0 || answer == NULL)
473                 err_sys("getaddrinfo failed");
474
475             memcpy(addr, answer->ai_addr, answer->ai_addrlen);
476             freeaddrinfo(answer);
477         #else
478             printf("no ipv6 getaddrinfo, loopback only tests/examples\n");
479             addr->sin6_addr = in6addr_loopback;
480         #endif
481     }
482 #endif
483 }
484
485
486 static INLINE void tcp_socket(SOCKET_T* sockfd, int udp)
487 {
488     if (udp)
489         *sockfd = socket(AF_INET_V, SOCK_DGRAM, 0);
490     else
491         *sockfd = socket(AF_INET_V, SOCK_STREAM, 0);
492
493 #ifdef USE_WINDOWS_API
494     if (*sockfd == INVALID_SOCKET)
495         err_sys("socket failed\n");
496 #elif defined(WOLFSSL_TIRTOS)
497     if (*sockfd == -1)
498         err_sys("socket failed\n");
499 #else
500     if (*sockfd < 0)
501         err_sys("socket failed\n");
502 #endif
503
504 #ifndef USE_WINDOWS_API 
505 #ifdef SO_NOSIGPIPE
506     {
507         int       on = 1;
508         socklen_t len = sizeof(on);
509         int       res = setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len);
510         if (res < 0)
511             err_sys("setsockopt SO_NOSIGPIPE failed\n");
512     }
513 #elif defined(WOLFSSL_MDK_ARM) || defined (WOLFSSL_TIRTOS)
514     /* nothing to define */
515 #else  /* no S_NOSIGPIPE */
516     signal(SIGPIPE, SIG_IGN);
517 #endif /* S_NOSIGPIPE */
518
519 #if defined(TCP_NODELAY)
520     if (!udp)
521     {
522         int       on = 1;
523         socklen_t len = sizeof(on);
524         int       res = setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, &on, len);
525         if (res < 0)
526             err_sys("setsockopt TCP_NODELAY failed\n");
527     }
528 #endif
529 #endif  /* USE_WINDOWS_API */
530 }
531
532 static INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port,
533                                int udp)
534 {
535     SOCKADDR_IN_T addr;
536     build_addr(&addr, ip, port, udp);
537     tcp_socket(sockfd, udp);
538
539     if (!udp) {
540         if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
541             err_sys("tcp connect failed");
542     }
543 }
544
545
546 static INLINE void udp_connect(SOCKET_T* sockfd, void* addr, int addrSz)
547 {
548     if (connect(*sockfd, (const struct sockaddr*)addr, addrSz) != 0)
549         err_sys("tcp connect failed");
550 }
551
552
553 enum {
554     TEST_SELECT_FAIL,
555     TEST_TIMEOUT,
556     TEST_RECV_READY,
557     TEST_ERROR_READY
558 };
559
560
561 #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_TIRTOS)
562 static INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
563 {
564     fd_set recvfds, errfds;
565     SOCKET_T nfds = socketfd + 1;
566     struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0};
567     int result;
568
569     FD_ZERO(&recvfds);
570     FD_SET(socketfd, &recvfds);
571     FD_ZERO(&errfds);
572     FD_SET(socketfd, &errfds);
573
574     result = select(nfds, &recvfds, NULL, &errfds, &timeout);
575
576     if (result == 0)
577         return TEST_TIMEOUT;
578     else if (result > 0) {
579         if (FD_ISSET(socketfd, &recvfds))
580             return TEST_RECV_READY;
581         else if(FD_ISSET(socketfd, &errfds))
582             return TEST_ERROR_READY;
583     }
584
585     return TEST_SELECT_FAIL;
586 }
587 #elif defined(WOLFSSL_TIRTOS)
588 static INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
589 {
590     return TEST_RECV_READY;
591 }
592 #endif /* !WOLFSSL_MDK_ARM */
593
594
595 static INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr,
596                               int udp)
597 {
598     SOCKADDR_IN_T addr;
599
600     /* don't use INADDR_ANY by default, firewall may block, make user switch
601        on */
602     build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), *port, udp);
603     tcp_socket(sockfd, udp);
604
605 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)
606     {
607         int       res, on  = 1;
608         socklen_t len = sizeof(on);
609         res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
610         if (res < 0)
611             err_sys("setsockopt SO_REUSEADDR failed\n");
612     }
613 #endif
614
615     if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
616         err_sys("tcp bind failed");
617     if (!udp) {
618         if (listen(*sockfd, 5) != 0)
619             err_sys("tcp listen failed");
620     }
621     #if (defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)) && !defined(WOLFSSL_TIRTOS)
622         if (*port == 0) {
623             socklen_t len = sizeof(addr);
624             if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
625                 #ifndef TEST_IPV6
626                     *port = ntohs(addr.sin_port);
627                 #else
628                     *port = ntohs(addr.sin6_port);
629                 #endif
630             }
631         }
632     #endif
633 }
634
635
636 static INLINE int udp_read_connect(SOCKET_T sockfd)
637 {
638     SOCKADDR_IN_T cliaddr;
639     byte          b[1500];
640     int           n;
641     socklen_t     len = sizeof(cliaddr);
642
643     n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
644                       (struct sockaddr*)&cliaddr, &len);
645     if (n > 0) {
646         if (connect(sockfd, (const struct sockaddr*)&cliaddr,
647                     sizeof(cliaddr)) != 0)
648             err_sys("udp connect failed");
649     }
650     else
651         err_sys("recvfrom failed");
652
653     return sockfd;
654 }
655
656 static INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
657                               int useAnyAddr, word16 port, func_args* args)
658 {
659     SOCKADDR_IN_T addr;
660
661     (void)args;
662     build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), port, 1);
663     tcp_socket(sockfd, 1);
664
665
666 #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)
667     {
668         int       res, on  = 1;
669         socklen_t len = sizeof(on);
670         res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
671         if (res < 0)
672             err_sys("setsockopt SO_REUSEADDR failed\n");
673     }
674 #endif
675
676     if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
677         err_sys("tcp bind failed");
678
679     #if (defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)) && !defined(WOLFSSL_TIRTOS)
680         if (port == 0) {
681             socklen_t len = sizeof(addr);
682             if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
683                 #ifndef TEST_IPV6
684                     port = ntohs(addr.sin_port);
685                 #else
686                     port = ntohs(addr.sin6_port);
687                 #endif
688             }
689         }
690     #endif
691
692 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
693     /* signal ready to accept data */
694     {
695     tcp_ready* ready = args->signal;
696     pthread_mutex_lock(&ready->mutex);
697     ready->ready = 1;
698     ready->port = port;
699     pthread_cond_signal(&ready->cond);
700     pthread_mutex_unlock(&ready->mutex);
701     }
702 #elif defined (WOLFSSL_TIRTOS)
703     /* Need mutex? */
704     tcp_ready* ready = args->signal;
705     ready->ready = 1;
706     ready->port = port;
707 #endif
708
709     *clientfd = udp_read_connect(*sockfd);
710 }
711
712 static INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
713                               func_args* args, word16 port, int useAnyAddr,
714                               int udp, int ready_file)
715 {
716     SOCKADDR_IN_T client;
717     socklen_t client_len = sizeof(client);
718
719     if (udp) {
720         udp_accept(sockfd, clientfd, useAnyAddr, port, args);
721         return;
722     }
723
724     tcp_listen(sockfd, &port, useAnyAddr, udp);
725
726 #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
727     /* signal ready to tcp_accept */
728     {
729     tcp_ready* ready = args->signal;
730     pthread_mutex_lock(&ready->mutex);
731     ready->ready = 1;
732     ready->port = port;
733     pthread_cond_signal(&ready->cond);
734     pthread_mutex_unlock(&ready->mutex);
735     }
736 #elif defined (WOLFSSL_TIRTOS)
737     /* Need mutex? */
738     tcp_ready* ready = args->signal;
739     ready->ready = 1;
740     ready->port = port;
741 #endif
742
743     if (ready_file) {
744 #ifndef NO_FILESYSTEM
745     #ifndef USE_WINDOWS_API
746         FILE* srf = fopen("/tmp/wolfssl_server_ready", "w");
747     #else
748         FILE* srf = fopen("wolfssl_server_ready", "w");
749     #endif
750
751         if (srf) {
752             fputs("ready", srf);
753             fclose(srf);
754         }
755 #endif
756     }
757
758     *clientfd = accept(*sockfd, (struct sockaddr*)&client,
759                       (ACCEPT_THIRD_T)&client_len);
760 #ifdef USE_WINDOWS_API
761     if (*clientfd == INVALID_SOCKET)
762         err_sys("tcp accept failed");
763 #else
764     if (*clientfd == -1)
765         err_sys("tcp accept failed");
766 #endif
767 }
768
769
770 static INLINE void tcp_set_nonblocking(SOCKET_T* sockfd)
771 {
772     #ifdef USE_WINDOWS_API 
773         unsigned long blocking = 1;
774         int ret = ioctlsocket(*sockfd, FIONBIO, &blocking);
775         if (ret == SOCKET_ERROR)
776             err_sys("ioctlsocket failed");
777     #elif defined(WOLFSSL_MDK_ARM) || defined (WOLFSSL_TIRTOS)
778          /* non blocking not suppported, for now */ 
779     #else
780         int flags = fcntl(*sockfd, F_GETFL, 0);
781         if (flags < 0)
782             err_sys("fcntl get failed");
783         flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK);
784         if (flags < 0)
785             err_sys("fcntl set failed");
786     #endif
787 }
788
789
790 #ifndef NO_PSK
791
792 static INLINE unsigned int my_psk_client_cb(WOLFSSL* ssl, const char* hint,
793         char* identity, unsigned int id_max_len, unsigned char* key,
794         unsigned int key_max_len)
795 {
796     (void)ssl;
797     (void)hint;
798     (void)key_max_len;
799
800     /* identity is OpenSSL testing default for openssl s_client, keep same */
801     strncpy(identity, "Client_identity", id_max_len);
802
803
804     /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
805        unsigned binary */
806     key[0] = 26;
807     key[1] = 43;
808     key[2] = 60;
809     key[3] = 77;
810
811     return 4;   /* length of key in octets or 0 for error */
812 }
813
814
815 static INLINE unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity,
816         unsigned char* key, unsigned int key_max_len)
817 {
818     (void)ssl;
819     (void)key_max_len;
820
821     /* identity is OpenSSL testing default for openssl s_client, keep same */
822     if (strncmp(identity, "Client_identity", 15) != 0)
823         return 0;
824
825     /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
826        unsigned binary */
827     key[0] = 26;
828     key[1] = 43;
829     key[2] = 60;
830     key[3] = 77;
831
832     return 4;   /* length of key in octets or 0 for error */
833 }
834
835 #endif /* NO_PSK */
836
837
838 #ifdef USE_WINDOWS_API 
839
840     #define WIN32_LEAN_AND_MEAN
841     #include <windows.h>
842
843     static INLINE double current_time()
844     {
845         static int init = 0;
846         static LARGE_INTEGER freq;
847     
848         LARGE_INTEGER count;
849
850         if (!init) {
851             QueryPerformanceFrequency(&freq);
852             init = 1;
853         }
854
855         QueryPerformanceCounter(&count);
856
857         return (double)count.QuadPart / freq.QuadPart;
858     }
859
860 #elif defined(WOLFSSL_TIRTOS)
861     extern double current_time();
862 #else
863
864 #if !defined(WOLFSSL_MDK_ARM)
865     #include <sys/time.h>
866
867     static INLINE double current_time(void)
868     {
869         struct timeval tv;
870         gettimeofday(&tv, 0);
871
872         return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
873     }
874         
875 #endif
876 #endif /* USE_WINDOWS_API */
877
878
879 #if defined(NO_FILESYSTEM) && !defined(NO_CERTS)
880
881     enum {
882         WOLFSSL_CA   = 1,
883         WOLFSSL_CERT = 2,
884         WOLFSSL_KEY  = 3
885     };
886
887     static INLINE void load_buffer(WOLFSSL_CTX* ctx, const char* fname, int type)
888     {
889         /* test buffer load */
890         long  sz = 0;
891         byte  buff[10000];
892         FILE* file = fopen(fname, "rb");
893
894         if (!file)
895             err_sys("can't open file for buffer load "
896                     "Please run from wolfSSL home directory if not");
897         fseek(file, 0, SEEK_END);
898         sz = ftell(file);
899         rewind(file);
900         fread(buff, sizeof(buff), 1, file);
901   
902         if (type == WOLFSSL_CA) {
903             if (wolfSSL_CTX_load_verify_buffer(ctx, buff, sz, SSL_FILETYPE_PEM)
904                                               != SSL_SUCCESS)
905                 err_sys("can't load buffer ca file");
906         }
907         else if (type == WOLFSSL_CERT) {
908             if (wolfSSL_CTX_use_certificate_buffer(ctx, buff, sz,
909                         SSL_FILETYPE_PEM) != SSL_SUCCESS)
910                 err_sys("can't load buffer cert file");
911         }
912         else if (type == WOLFSSL_KEY) {
913             if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, sz,
914                         SSL_FILETYPE_PEM) != SSL_SUCCESS)
915                 err_sys("can't load buffer key file");
916         }
917     }
918
919 #endif /* NO_FILESYSTEM */
920
921 #ifdef VERIFY_CALLBACK
922
923 static INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store)
924 {
925     (void)preverify;
926     char buffer[WOLFSSL_MAX_ERROR_SZ];
927
928 #ifdef OPENSSL_EXTRA
929     WOLFSSL_X509* peer;
930 #endif
931
932     printf("In verification callback, error = %d, %s\n", store->error,
933                                  wolfSSL_ERR_error_string(store->error, buffer));
934 #ifdef OPENSSL_EXTRA
935     peer = store->current_cert;
936     if (peer) {
937         char* issuer  = wolfSSL_X509_NAME_oneline(
938                                        wolfSSL_X509_get_issuer_name(peer), 0, 0);
939         char* subject = wolfSSL_X509_NAME_oneline(
940                                       wolfSSL_X509_get_subject_name(peer), 0, 0);
941         printf("peer's cert info:\n issuer : %s\n subject: %s\n", issuer,
942                                                                   subject);
943         XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
944         XFREE(issuer,  0, DYNAMIC_TYPE_OPENSSL);
945     }
946     else
947         printf("peer has no cert!\n");
948 #endif
949     printf("Subject's domain name is %s\n", store->domain);
950
951     printf("Allowing to continue anyway (shouldn't do this, EVER!!!)\n");
952     return 1;
953 }
954
955 #endif /* VERIFY_CALLBACK */
956
957
958 static INLINE int myDateCb(int preverify, WOLFSSL_X509_STORE_CTX* store)
959 {
960     char buffer[WOLFSSL_MAX_ERROR_SZ];
961     (void)preverify;
962
963     printf("In verification callback, error = %d, %s\n", store->error,
964                                  wolfSSL_ERR_error_string(store->error, buffer));
965     printf("Subject's domain name is %s\n", store->domain);
966
967     if (store->error == ASN_BEFORE_DATE_E || store->error == ASN_AFTER_DATE_E) {
968         printf("Overriding cert date error as example for bad clock testing\n");
969         return 1;
970     }
971     printf("Cert error is not date error, not overriding\n");
972
973     return 0;
974 }
975
976
977 #ifdef HAVE_CRL
978
979 static INLINE void CRL_CallBack(const char* url)
980 {
981     printf("CRL callback url = %s\n", url);
982 }
983
984 #endif
985
986 #ifndef NO_DH
987 static INLINE void SetDH(WOLFSSL* ssl)
988 {
989     /* dh1024 p */
990     static unsigned char p[] =
991     {
992         0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
993         0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
994         0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
995         0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
996         0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
997         0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
998         0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
999         0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
1000         0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
1001         0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
1002         0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
1003     };
1004
1005     /* dh1024 g */
1006     static unsigned char g[] =
1007     {
1008       0x02,
1009     };
1010
1011     wolfSSL_SetTmpDH(ssl, p, sizeof(p), g, sizeof(g));
1012 }
1013
1014 static INLINE void SetDHCtx(WOLFSSL_CTX* ctx)
1015 {
1016     /* dh1024 p */
1017     static unsigned char p[] =
1018     {
1019         0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
1020         0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
1021         0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
1022         0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
1023         0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
1024         0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
1025         0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
1026         0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
1027         0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
1028         0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
1029         0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
1030     };
1031
1032     /* dh1024 g */
1033     static unsigned char g[] =
1034     {
1035       0x02,
1036     };
1037
1038     wolfSSL_CTX_SetTmpDH(ctx, p, sizeof(p), g, sizeof(g));
1039 }
1040 #endif /* NO_DH */
1041
1042 #ifndef NO_CERTS
1043
1044 static INLINE void CaCb(unsigned char* der, int sz, int type)
1045 {
1046     (void)der;
1047     printf("Got CA cache add callback, derSz = %d, type = %d\n", sz, type);
1048 }
1049
1050 #endif /* !NO_CERTS */
1051
1052 #ifdef HAVE_CAVIUM
1053
1054 static INLINE int OpenNitroxDevice(int dma_mode,int dev_id)
1055 {
1056    Csp1CoreAssignment core_assign;
1057    Uint32             device;
1058
1059    if (CspInitialize(CAVIUM_DIRECT,CAVIUM_DEV_ID))
1060       return -1;
1061    if (Csp1GetDevType(&device))
1062       return -1;
1063    if (device != NPX_DEVICE) {
1064       if (ioctl(gpkpdev_hdlr[CAVIUM_DEV_ID], IOCTL_CSP1_GET_CORE_ASSIGNMENT,
1065                 (Uint32 *)&core_assign)!= 0)
1066          return -1;
1067    }
1068    CspShutdown(CAVIUM_DEV_ID);
1069
1070    return CspInitialize(dma_mode, dev_id);
1071 }
1072
1073 #endif /* HAVE_CAVIUM */
1074
1075
1076 #ifdef USE_WINDOWS_API 
1077
1078 /* do back x number of directories */
1079 static INLINE void ChangeDirBack(int x)
1080 {
1081     char path[MAX_PATH];
1082
1083     if (x == 1)
1084         strncpy(path, "..\\", MAX_PATH);
1085     else if (x == 2)
1086         strncpy(path, "..\\..\\", MAX_PATH);
1087     else if (x == 3)
1088         strncpy(path, "..\\..\\..\\", MAX_PATH);
1089     else if (x == 4)
1090         strncpy(path, "..\\..\\..\\..\\", MAX_PATH);
1091     else
1092         strncpy(path, ".\\", MAX_PATH);
1093     
1094     SetCurrentDirectoryA(path);
1095 }
1096
1097 /* does current dir contain str */
1098 static INLINE int CurrentDir(const char* str)
1099 {
1100     char  path[MAX_PATH];
1101     char* baseName;
1102
1103     GetCurrentDirectoryA(sizeof(path), path);
1104
1105     baseName = strrchr(path, '\\');
1106     if (baseName)
1107         baseName++;
1108     else
1109         baseName = path;
1110
1111     if (strstr(baseName, str))
1112         return 1;
1113
1114     return 0;
1115 }
1116
1117 #elif defined(WOLFSSL_MDK_ARM)
1118     /* KEIL-RL File System does not support relative directry */
1119 #elif defined(WOLFSSL_TIRTOS)
1120 #else
1121
1122 #ifndef MAX_PATH
1123     #define MAX_PATH 256
1124 #endif
1125
1126 /* do back x number of directories */
1127 static INLINE void ChangeDirBack(int x)
1128 {
1129     char path[MAX_PATH];
1130
1131     if (x == 1)
1132         strncpy(path, "../", MAX_PATH);
1133     else if (x == 2)
1134         strncpy(path, "../../", MAX_PATH);
1135     else if (x == 3)
1136         strncpy(path, "../../../", MAX_PATH);
1137     else if (x == 4)
1138         strncpy(path, "../../../../", MAX_PATH);
1139     else
1140         strncpy(path, "./", MAX_PATH);
1141     
1142     if (chdir(path) < 0)
1143         printf("chdir to %s failed\n", path);
1144 }
1145
1146 /* does current dir contain str */
1147 static INLINE int CurrentDir(const char* str)
1148 {
1149     char  path[MAX_PATH];
1150     char* baseName;
1151
1152     if (getcwd(path, sizeof(path)) == NULL) {
1153         printf("no current dir?\n");
1154         return 0;
1155     }
1156
1157     baseName = strrchr(path, '/');
1158     if (baseName)
1159         baseName++;
1160     else
1161         baseName = path;
1162
1163     if (strstr(baseName, str))
1164         return 1;
1165
1166     return 0;
1167 }
1168
1169 #endif /* USE_WINDOWS_API */
1170
1171
1172 #ifdef USE_WOLFSSL_MEMORY
1173
1174     typedef struct memoryStats {
1175         size_t totalAllocs;     /* number of allocations */
1176         size_t totalBytes;      /* total number of bytes allocated */
1177         size_t peakBytes;       /* concurrent max bytes */
1178         size_t currentBytes;    /* total current bytes in use */
1179     } memoryStats;
1180
1181     typedef struct memHint {
1182         size_t thisSize;      /* size of this memory */
1183         void*  thisMemory;    /* actual memory for user */
1184     } memHint;
1185
1186     typedef struct memoryTrack {
1187         union {
1188             memHint hint;
1189             byte    alignit[16];   /* make sure we have strong alignment */
1190         } u;
1191     } memoryTrack;
1192
1193     #if defined(WOLFSSL_TRACK_MEMORY)
1194         #define DO_MEM_STATS
1195         static memoryStats ourMemStats;
1196     #endif
1197
1198     static INLINE void* TrackMalloc(size_t sz)
1199     {
1200         memoryTrack* mt;
1201
1202         if (sz == 0)
1203             return NULL;
1204
1205         mt = (memoryTrack*)malloc(sizeof(memoryTrack) + sz);
1206         if (mt == NULL)
1207             return NULL;
1208
1209         mt->u.hint.thisSize   = sz;
1210         mt->u.hint.thisMemory = (byte*)mt + sizeof(memoryTrack);
1211
1212 #ifdef DO_MEM_STATS
1213         ourMemStats.totalAllocs++;
1214         ourMemStats.totalBytes   += sz;
1215         ourMemStats.currentBytes += sz;
1216         if (ourMemStats.currentBytes > ourMemStats.peakBytes)
1217             ourMemStats.peakBytes = ourMemStats.currentBytes;
1218 #endif
1219
1220         return mt->u.hint.thisMemory;
1221     }
1222
1223
1224     static INLINE void TrackFree(void* ptr)
1225     {
1226         memoryTrack* mt;
1227
1228         if (ptr == NULL)
1229             return;
1230
1231         mt = (memoryTrack*)ptr;
1232         --mt;   /* same as minus sizeof(memoryTrack), removes header */
1233
1234 #ifdef DO_MEM_STATS 
1235         ourMemStats.currentBytes -= mt->u.hint.thisSize; 
1236 #endif
1237
1238         free(mt);
1239     }
1240
1241
1242     static INLINE void* TrackRealloc(void* ptr, size_t sz)
1243     {
1244         void* ret = TrackMalloc(sz);
1245
1246         if (ptr) {
1247             /* if realloc is bigger, don't overread old ptr */
1248             memoryTrack* mt = (memoryTrack*)ptr;
1249             --mt;  /* same as minus sizeof(memoryTrack), removes header */
1250
1251             if (mt->u.hint.thisSize < sz)
1252                 sz = mt->u.hint.thisSize;
1253         }
1254
1255         if (ret && ptr)
1256             memcpy(ret, ptr, sz);
1257
1258         if (ret)
1259             TrackFree(ptr);
1260
1261         return ret;
1262     }
1263
1264     static INLINE void InitMemoryTracker(void) 
1265     {
1266         if (wolfSSL_SetAllocators(TrackMalloc, TrackFree, TrackRealloc) != 0)
1267             err_sys("wolfSSL SetAllocators failed for track memory");
1268
1269     #ifdef DO_MEM_STATS
1270         ourMemStats.totalAllocs  = 0;
1271         ourMemStats.totalBytes   = 0;
1272         ourMemStats.peakBytes    = 0;
1273         ourMemStats.currentBytes = 0;
1274     #endif
1275     }
1276
1277     static INLINE void ShowMemoryTracker(void) 
1278     {
1279     #ifdef DO_MEM_STATS 
1280         printf("total   Allocs = %9lu\n",
1281                                        (unsigned long)ourMemStats.totalAllocs);
1282         printf("total   Bytes  = %9lu\n",
1283                                        (unsigned long)ourMemStats.totalBytes);
1284         printf("peak    Bytes  = %9lu\n",
1285                                        (unsigned long)ourMemStats.peakBytes);
1286         printf("current Bytes  = %9lu\n",
1287                                        (unsigned long)ourMemStats.currentBytes);
1288     #endif
1289     }
1290
1291 #endif /* USE_WOLFSSL_MEMORY */
1292
1293
1294 #ifdef HAVE_STACK_SIZE
1295
1296 typedef THREAD_RETURN WOLFSSL_THREAD (*thread_func)(void* args);
1297
1298
1299 static INLINE void StackSizeCheck(func_args* args, thread_func tf)
1300 {
1301     int            ret, i, used;
1302     unsigned char* myStack;
1303     int            stackSize = 1024*128;
1304     pthread_attr_t myAttr;
1305     pthread_t      threadId;
1306
1307 #ifdef PTHREAD_STACK_MIN
1308     if (stackSize < PTHREAD_STACK_MIN)
1309         stackSize = PTHREAD_STACK_MIN;
1310 #endif
1311
1312     ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize);
1313     if (ret != 0) 
1314         err_sys("posix_memalign failed\n");        
1315
1316     memset(myStack, 0x01, stackSize);
1317
1318     ret = pthread_attr_init(&myAttr);
1319     if (ret != 0)
1320         err_sys("attr_init failed");
1321
1322     ret = pthread_attr_setstack(&myAttr, myStack, stackSize);
1323     if (ret != 0)
1324         err_sys("attr_setstackaddr failed");
1325
1326     ret = pthread_create(&threadId, &myAttr, tf, args);
1327     if (ret != 0) {
1328         perror("pthread_create failed");
1329         exit(EXIT_FAILURE);
1330     }
1331
1332     ret = pthread_join(threadId, NULL);
1333     if (ret != 0)
1334         err_sys("pthread_join failed");
1335
1336     for (i = 0; i < stackSize; i++) {
1337         if (myStack[i] != 0x01) {
1338             break;
1339         }
1340     }
1341
1342     used = stackSize - i;
1343     printf("stack used = %d\n", used);
1344 }
1345
1346
1347 #endif /* HAVE_STACK_SIZE */
1348
1349
1350 #ifdef STACK_TRAP
1351
1352 /* good settings
1353    --enable-debug --disable-shared C_EXTRA_FLAGS="-DUSER_TIME -DTFM_TIMING_RESISTANT -DPOSITIVE_EXP_ONLY -DSTACK_TRAP"
1354
1355 */
1356
1357 #ifdef HAVE_STACK_SIZE
1358     /* client only for now, setrlimit will fail if pthread_create() called */
1359     /* STACK_SIZE does pthread_create() on client */
1360     #error "can't use STACK_TRAP with STACK_SIZE, setrlimit will fail"
1361 #endif /* HAVE_STACK_SIZE */
1362
1363 static INLINE void StackTrap(void)
1364 {
1365     struct rlimit  rl;
1366     if (getrlimit(RLIMIT_STACK, &rl) != 0)
1367         err_sys("getrlimit failed");
1368     printf("rlim_cur = %llu\n", rl.rlim_cur);
1369     rl.rlim_cur = 1024*21;  /* adjust trap size here */
1370     if (setrlimit(RLIMIT_STACK, &rl) != 0) {
1371         perror("setrlimit");
1372         err_sys("setrlimit failed");
1373     }
1374 }
1375
1376 #else /* STACK_TRAP */
1377
1378 static INLINE void StackTrap(void)
1379 {
1380 }
1381
1382 #endif /* STACK_TRAP */
1383
1384
1385 #ifdef ATOMIC_USER
1386
1387 /* Atomic Encrypt Context example */
1388 typedef struct AtomicEncCtx {
1389     int  keySetup;           /* have we done key setup yet */
1390     Aes  aes;                /* for aes example */
1391 } AtomicEncCtx;
1392
1393
1394 /* Atomic Decrypt Context example */
1395 typedef struct AtomicDecCtx {
1396     int  keySetup;           /* have we done key setup yet */
1397     Aes  aes;                /* for aes example */
1398 } AtomicDecCtx;
1399
1400
1401 static INLINE int myMacEncryptCb(WOLFSSL* ssl, unsigned char* macOut, 
1402        const unsigned char* macIn, unsigned int macInSz, int macContent, 
1403        int macVerify, unsigned char* encOut, const unsigned char* encIn,
1404        unsigned int encSz, void* ctx)
1405 {
1406     int  ret;
1407     Hmac hmac;
1408     byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
1409     AtomicEncCtx* encCtx = (AtomicEncCtx*)ctx;
1410     const char* tlsStr = "TLS";
1411
1412     /* example supports (d)tls aes */
1413     if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
1414         printf("myMacEncryptCb not using AES\n");
1415         return -1;
1416     }
1417
1418     if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
1419         printf("myMacEncryptCb not using (D)TLS\n");
1420         return -1;
1421     }
1422
1423     /* hmac, not needed if aead mode */
1424     wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
1425
1426     ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
1427                wolfSSL_GetMacSecret(ssl, macVerify), wolfSSL_GetHmacSize(ssl));
1428     if (ret != 0)
1429         return ret;
1430     ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
1431     if (ret != 0)
1432         return ret;
1433     ret = wc_HmacUpdate(&hmac, macIn, macInSz);
1434     if (ret != 0)
1435         return ret;
1436     ret = wc_HmacFinal(&hmac, macOut);
1437     if (ret != 0)
1438         return ret;
1439
1440
1441     /* encrypt setup on first time */
1442     if (encCtx->keySetup == 0) {
1443         int   keyLen = wolfSSL_GetKeySize(ssl);
1444         const byte* key;
1445         const byte* iv;
1446
1447         if (wolfSSL_GetSide(ssl) == WOLFSSL_CLIENT_END) {
1448             key = wolfSSL_GetClientWriteKey(ssl);
1449             iv  = wolfSSL_GetClientWriteIV(ssl);
1450         }
1451         else {
1452             key = wolfSSL_GetServerWriteKey(ssl);
1453             iv  = wolfSSL_GetServerWriteIV(ssl);
1454         }
1455
1456         ret = wc_AesSetKey(&encCtx->aes, key, keyLen, iv, AES_ENCRYPTION);
1457         if (ret != 0) {
1458             printf("AesSetKey failed in myMacEncryptCb\n");
1459             return ret;
1460         }
1461         encCtx->keySetup = 1;
1462     }
1463
1464     /* encrypt */
1465     return wc_AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz);
1466 }
1467
1468
1469 static INLINE int myDecryptVerifyCb(WOLFSSL* ssl, 
1470        unsigned char* decOut, const unsigned char* decIn,
1471        unsigned int decSz, int macContent, int macVerify,
1472        unsigned int* padSz, void* ctx)
1473 {
1474     AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx;
1475     int ret      = 0;
1476     int macInSz  = 0;
1477     int ivExtra  = 0;
1478     int digestSz = wolfSSL_GetHmacSize(ssl);
1479     unsigned int pad     = 0;
1480     unsigned int padByte = 0;
1481     Hmac hmac;
1482     byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
1483     byte verify[MAX_DIGEST_SIZE];
1484     const char* tlsStr = "TLS";
1485
1486     /* example supports (d)tls aes */
1487     if (wolfSSL_GetBulkCipher(ssl) != wolfssl_aes) {
1488         printf("myMacEncryptCb not using AES\n");
1489         return -1;
1490     }
1491
1492     if (strstr(wolfSSL_get_version(ssl), tlsStr) == NULL) {
1493         printf("myMacEncryptCb not using (D)TLS\n");
1494         return -1;
1495     }
1496
1497     /*decrypt */
1498     if (decCtx->keySetup == 0) {
1499         int   keyLen = wolfSSL_GetKeySize(ssl);
1500         const byte* key;
1501         const byte* iv;
1502
1503         /* decrypt is from other side (peer) */
1504         if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) {
1505             key = wolfSSL_GetClientWriteKey(ssl);
1506             iv  = wolfSSL_GetClientWriteIV(ssl);
1507         }
1508         else {
1509             key = wolfSSL_GetServerWriteKey(ssl);
1510             iv  = wolfSSL_GetServerWriteIV(ssl);
1511         }
1512
1513         ret = wc_AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION);
1514         if (ret != 0) {
1515             printf("AesSetKey failed in myDecryptVerifyCb\n");
1516             return ret;
1517         }
1518         decCtx->keySetup = 1;
1519     }
1520
1521     /* decrypt */
1522     ret = wc_AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz);
1523
1524     if (wolfSSL_GetCipherType(ssl) == WOLFSSL_AEAD_TYPE) {
1525         *padSz = wolfSSL_GetAeadMacSize(ssl);
1526         return 0; /* hmac, not needed if aead mode */
1527     }
1528
1529     if (wolfSSL_GetCipherType(ssl) == WOLFSSL_BLOCK_TYPE) {
1530         pad     = *(decOut + decSz - 1);
1531         padByte = 1;
1532         if (wolfSSL_IsTLSv1_1(ssl))
1533             ivExtra = wolfSSL_GetCipherBlockSize(ssl);
1534     }
1535
1536     *padSz  = wolfSSL_GetHmacSize(ssl) + pad + padByte;
1537     macInSz = decSz - ivExtra - digestSz - pad - padByte;
1538
1539     wolfSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
1540
1541     ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
1542                wolfSSL_GetMacSecret(ssl, macVerify), digestSz);
1543     if (ret != 0)
1544         return ret;
1545     ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
1546     if (ret != 0)
1547         return ret;
1548     ret = wc_HmacUpdate(&hmac, decOut + ivExtra, macInSz);
1549     if (ret != 0)
1550         return ret;
1551     ret = wc_HmacFinal(&hmac, verify);
1552     if (ret != 0)
1553         return ret;
1554
1555     if (memcmp(verify, decOut + decSz - digestSz - pad - padByte,
1556                digestSz) != 0) {
1557         printf("myDecryptVerify verify failed\n");
1558         return -1;
1559     }
1560
1561     return ret;
1562 }
1563
1564
1565 static INLINE void SetupAtomicUser(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
1566 {
1567     AtomicEncCtx* encCtx;
1568     AtomicDecCtx* decCtx;
1569
1570     encCtx = (AtomicEncCtx*)malloc(sizeof(AtomicEncCtx));
1571     if (encCtx == NULL)
1572         err_sys("AtomicEncCtx malloc failed");
1573     memset(encCtx, 0, sizeof(AtomicEncCtx));
1574
1575     decCtx = (AtomicDecCtx*)malloc(sizeof(AtomicDecCtx));
1576     if (decCtx == NULL) {
1577         free(encCtx);
1578         err_sys("AtomicDecCtx malloc failed");
1579     }
1580     memset(decCtx, 0, sizeof(AtomicDecCtx));
1581
1582     wolfSSL_CTX_SetMacEncryptCb(ctx, myMacEncryptCb);
1583     wolfSSL_SetMacEncryptCtx(ssl, encCtx);
1584
1585     wolfSSL_CTX_SetDecryptVerifyCb(ctx, myDecryptVerifyCb);
1586     wolfSSL_SetDecryptVerifyCtx(ssl, decCtx);
1587 }
1588
1589
1590 static INLINE void FreeAtomicUser(WOLFSSL* ssl)
1591 {
1592     AtomicEncCtx* encCtx = (AtomicEncCtx*)wolfSSL_GetMacEncryptCtx(ssl);
1593     AtomicDecCtx* decCtx = (AtomicDecCtx*)wolfSSL_GetDecryptVerifyCtx(ssl);
1594
1595     free(decCtx);
1596     free(encCtx);
1597 }
1598
1599 #endif /* ATOMIC_USER */
1600
1601
1602 #ifdef HAVE_PK_CALLBACKS
1603
1604 #ifdef HAVE_ECC
1605
1606 static INLINE int myEccSign(WOLFSSL* ssl, const byte* in, word32 inSz,
1607         byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
1608 {
1609     RNG     rng;
1610     int     ret;
1611     word32  idx = 0;
1612     ecc_key myKey;
1613
1614     (void)ssl;
1615     (void)ctx;
1616
1617     ret = wc_InitRng(&rng);
1618     if (ret != 0)
1619         return ret;
1620
1621     wc_ecc_init(&myKey);
1622     
1623     ret = wc_EccPrivateKeyDecode(key, &idx, &myKey, keySz);    
1624     if (ret == 0)
1625         ret = wc_ecc_sign_hash(in, inSz, out, outSz, &rng, &myKey);
1626     wc_ecc_free(&myKey);
1627     wc_FreeRng(&rng);
1628
1629     return ret;
1630 }
1631
1632
1633 static INLINE int myEccVerify(WOLFSSL* ssl, const byte* sig, word32 sigSz,
1634         const byte* hash, word32 hashSz, const byte* key, word32 keySz,
1635         int* result, void* ctx)
1636 {
1637     int     ret;
1638     ecc_key myKey;
1639
1640     (void)ssl;
1641     (void)ctx;
1642
1643     wc_ecc_init(&myKey);
1644     
1645     ret = wc_ecc_import_x963(key, keySz, &myKey);
1646     if (ret == 0)
1647         ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, result, &myKey);
1648     wc_ecc_free(&myKey);
1649
1650     return ret;
1651 }
1652
1653 #endif /* HAVE_ECC */
1654
1655 #ifndef NO_RSA
1656
1657 static INLINE int myRsaSign(WOLFSSL* ssl, const byte* in, word32 inSz,
1658         byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
1659 {
1660     RNG     rng;
1661     int     ret;
1662     word32  idx = 0;
1663     RsaKey  myKey;
1664
1665     (void)ssl;
1666     (void)ctx;
1667
1668     ret = wc_InitRng(&rng);
1669     if (ret != 0)
1670         return ret;
1671
1672     wc_InitRsaKey(&myKey, NULL);
1673     
1674     ret = wc_RsaPrivateKeyDecode(key, &idx, &myKey, keySz);    
1675     if (ret == 0)
1676         ret = wc_RsaSSL_Sign(in, inSz, out, *outSz, &myKey, &rng);
1677     if (ret > 0) {  /* save and convert to 0 success */
1678         *outSz = ret;
1679         ret = 0;
1680     }
1681     wc_FreeRsaKey(&myKey);
1682     wc_FreeRng(&rng);
1683
1684     return ret;
1685 }
1686
1687
1688 static INLINE int myRsaVerify(WOLFSSL* ssl, byte* sig, word32 sigSz,
1689         byte** out,
1690         const byte* key, word32 keySz,
1691         void* ctx)
1692 {
1693     int     ret;
1694     word32  idx = 0;
1695     RsaKey  myKey;
1696
1697     (void)ssl;
1698     (void)ctx;
1699
1700     wc_InitRsaKey(&myKey, NULL);
1701
1702     ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
1703     if (ret == 0)
1704         ret = wc_RsaSSL_VerifyInline(sig, sigSz, out, &myKey);
1705     wc_FreeRsaKey(&myKey);
1706
1707     return ret;
1708 }
1709
1710
1711 static INLINE int myRsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz,
1712                            byte* out, word32* outSz, const byte* key,
1713                            word32 keySz, void* ctx)
1714 {
1715     int     ret;
1716     word32  idx = 0;
1717     RsaKey  myKey;
1718     RNG     rng;
1719
1720     (void)ssl;
1721     (void)ctx;
1722
1723     ret = wc_InitRng(&rng);
1724     if (ret != 0)
1725         return ret;
1726
1727     wc_InitRsaKey(&myKey, NULL);
1728     
1729     ret = wc_RsaPublicKeyDecode(key, &idx, &myKey, keySz);
1730     if (ret == 0) {
1731         ret = wc_RsaPublicEncrypt(in, inSz, out, *outSz, &myKey, &rng);
1732         if (ret > 0) {
1733             *outSz = ret;
1734             ret = 0;  /* reset to success */
1735         }
1736     }
1737     wc_FreeRsaKey(&myKey);
1738     wc_FreeRng(&rng);
1739
1740     return ret;
1741 }
1742
1743 static INLINE int myRsaDec(WOLFSSL* ssl, byte* in, word32 inSz,
1744                            byte** out,
1745                            const byte* key, word32 keySz, void* ctx)
1746 {
1747     int     ret;
1748     word32  idx = 0;
1749     RsaKey  myKey;
1750
1751     (void)ssl;
1752     (void)ctx;
1753
1754     wc_InitRsaKey(&myKey, NULL);
1755
1756     ret = wc_RsaPrivateKeyDecode(key, &idx, &myKey, keySz);
1757     if (ret == 0) {
1758         ret = wc_RsaPrivateDecryptInline(in, inSz, out, &myKey);
1759     }
1760     wc_FreeRsaKey(&myKey);
1761
1762     return ret;
1763 }
1764
1765 #endif /* NO_RSA */
1766
1767 static INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
1768 {
1769     (void)ctx;
1770     (void)ssl;
1771
1772     #ifdef HAVE_ECC
1773         wolfSSL_CTX_SetEccSignCb(ctx, myEccSign);
1774         wolfSSL_CTX_SetEccVerifyCb(ctx, myEccVerify);
1775     #endif /* HAVE_ECC */
1776     #ifndef NO_RSA 
1777         wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign);
1778         wolfSSL_CTX_SetRsaVerifyCb(ctx, myRsaVerify);
1779         wolfSSL_CTX_SetRsaEncCb(ctx, myRsaEnc);
1780         wolfSSL_CTX_SetRsaDecCb(ctx, myRsaDec);
1781     #endif /* NO_RSA */
1782 }
1783
1784 #endif /* HAVE_PK_CALLBACKS */
1785
1786
1787
1788
1789
1790 #if defined(__hpux__) || defined(__MINGW32__) || defined (WOLFSSL_TIRTOS) \
1791                       || defined(_MSC_VER)
1792
1793 /* HP/UX doesn't have strsep, needed by test/suites.c */
1794 static INLINE char* strsep(char **stringp, const char *delim)
1795 {
1796     char* start;
1797     char* end;
1798
1799     start = *stringp;
1800     if (start == NULL)
1801         return NULL;
1802
1803     if ((end = strpbrk(start, delim))) {
1804         *end++ = '\0';
1805         *stringp = end;
1806     } else {
1807         *stringp = NULL;
1808     }
1809
1810     return start;
1811 }
1812
1813 #endif /* __hpux__ and others */
1814
1815 /* Create unique filename, len is length of tempfn name, assuming
1816    len does not include null terminating character,
1817    num is number of characters in tempfn name to randomize */
1818 static INLINE const char* mymktemp(char *tempfn, int len, int num)
1819 {
1820     int x, size;
1821     static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1822                                    "abcdefghijklmnopqrstuvwxyz";
1823     RNG rng;
1824     byte out;
1825
1826     if (tempfn == NULL || len < 1 || num < 1 || len <= num) {
1827         printf("Bad input\n");
1828         return NULL;
1829     }
1830
1831     size = len - 1;
1832
1833     if (wc_InitRng(&rng) != 0) {
1834         printf("InitRng failed\n");
1835         return NULL;
1836     }
1837
1838     for (x = size; x > size - num; x--) {
1839         if (wc_RNG_GenerateBlock(&rng,(byte*)&out, sizeof(out)) != 0) {
1840             printf("RNG_GenerateBlock failed\n");
1841             return NULL;
1842         }
1843         tempfn[x] = alphanum[out % (sizeof(alphanum) - 1)];
1844     }
1845     tempfn[len] = '\0';
1846
1847     wc_FreeRng(&rng);
1848
1849     return tempfn;
1850 }
1851
1852
1853
1854 #if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
1855                                     defined(HAVE_POLY1305)
1856
1857     #include <wolfssl/wolfcrypt/chacha20_poly1305.h>
1858
1859     typedef struct key_ctx {
1860         byte name[WOLFSSL_TICKET_NAME_SZ];     /* name for this context */
1861         byte key[16];                          /* cipher key */
1862     } key_ctx;
1863
1864     static key_ctx myKey_ctx;
1865     static RNG rng;
1866
1867     static INLINE int TicketInit(void)
1868     {
1869         int ret = wc_InitRng(&rng);
1870         if (ret != 0) return ret;
1871
1872         ret = wc_RNG_GenerateBlock(&rng, myKey_ctx.key, sizeof(myKey_ctx.key));
1873         if (ret != 0) return ret;
1874
1875         ret = wc_RNG_GenerateBlock(&rng, myKey_ctx.name,sizeof(myKey_ctx.name));
1876         if (ret != 0) return ret;
1877
1878         return 0;
1879     }
1880
1881     static INLINE void TicketCleanup(void)
1882     {
1883         wc_FreeRng(&rng);
1884     }
1885
1886     static INLINE int myTicketEncCb(WOLFSSL* ssl,
1887                              byte key_name[WOLFSSL_TICKET_NAME_SZ],
1888                              byte iv[WOLFSSL_TICKET_IV_SZ],
1889                              byte mac[WOLFSSL_TICKET_MAC_SZ],
1890                              int enc, byte* ticket, int inLen, int* outLen,
1891                              void* userCtx)
1892     {
1893         (void)ssl;
1894         (void)userCtx;
1895
1896         int ret;
1897         word16 sLen = htons(inLen);
1898         byte aad[WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2];
1899         int  aadSz = WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2;
1900         byte* tmp = aad;
1901
1902         if (enc) {
1903             XMEMCPY(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ);
1904
1905             ret = wc_RNG_GenerateBlock(&rng, iv, WOLFSSL_TICKET_IV_SZ);
1906             if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
1907
1908             /* build aad from key name, iv, and length */
1909             XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ);
1910             tmp += WOLFSSL_TICKET_NAME_SZ;
1911             XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
1912             tmp += WOLFSSL_TICKET_IV_SZ;
1913             XMEMCPY(tmp, &sLen, 2);
1914
1915             ret = wc_ChaCha20Poly1305_Encrypt(myKey_ctx.key, iv,
1916                                               aad, aadSz,
1917                                               ticket, inLen,
1918                                               ticket,
1919                                               mac);
1920             if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
1921             *outLen = inLen;  /* no padding in this mode */
1922         } else {
1923             /* decrypt */
1924
1925             /* see if we know this key */
1926             if (XMEMCMP(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ) != 0){
1927                 printf("client presented unknown ticket key name ");
1928                 return WOLFSSL_TICKET_RET_FATAL;
1929             }
1930
1931             /* build aad from key name, iv, and length */
1932             XMEMCPY(tmp, key_name, WOLFSSL_TICKET_NAME_SZ);
1933             tmp += WOLFSSL_TICKET_NAME_SZ;
1934             XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
1935             tmp += WOLFSSL_TICKET_IV_SZ;
1936             XMEMCPY(tmp, &sLen, 2);
1937
1938             ret = wc_ChaCha20Poly1305_Decrypt(myKey_ctx.key, iv,
1939                                               aad, aadSz,
1940                                               ticket, inLen,
1941                                               mac,
1942                                               ticket);
1943             if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
1944             *outLen = inLen;  /* no padding in this mode */
1945         }
1946
1947         return WOLFSSL_TICKET_RET_OK;
1948     }
1949
1950 #endif  /* HAVE_SESSION_TICKET && CHACHA20 && POLY1305 */
1951
1952 #endif /* wolfSSL_TEST_H */