gnunet-android

GNUnet for Android
Log | Files | Refs | README

test.h (146462B)


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