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