Coverage Report

Created: 2026-05-18 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-openssl-api/wolfcrypt/src/wc_port.c
Line
Count
Source
1
/* port.c
2
 *
3
 * Copyright (C) 2006-2026 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#if (defined(__linux__) || defined(__ANDROID__)) && \
23
    !defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_ZEPHYR) && \
24
    !defined(_GNU_SOURCE)
25
    #define _GNU_SOURCE 1
26
#elif defined(__FreeBSD__)
27
    /* for __FreeBSD_version */
28
    #include <sys/param.h>
29
#endif
30
31
/*
32
wolfCrypt Porting Build Options:
33
34
Threading/Mutex options:
35
 * SINGLE_THREADED:     No-op mutex/threading implementations   default: off
36
 * WOLFSSL_PTHREADS:    Use pthread-based mutex/threading       default: off
37
 *                      (auto-detected on most POSIX systems)
38
 * WOLFSSL_MUTEX_INITIALIZER: Use static mutex initialization   default: off
39
 * WC_MUTEX_OPS_INLINE: Use inlined mutex operations            default: off
40
 * WOLFSSL_USER_MUTEX:  User-provided mutex implementation      default: off
41
 * WOLFSSL_COND:        Enable condition variable support       default: off
42
 * WOLFSSL_USE_RWLOCK:  Enable reader-writer lock support       default: off
43
 * WOLFSSL_THREAD_NO_JOIN: Create threads without join          default: off
44
 * WOLFSSL_ALGO_HW_MUTEX: Per-algorithm hardware mutex locks    default: off
45
 *                      Controls AES, hash, PK, and RNG mutexes.
46
 * WOLFSSL_CRYPT_HW_MUTEX: Cryptography hardware mutex          default: off
47
 *                      Master control for all HW mutex init.
48
 * NO_AES_MUTEX:        Disable AES hardware mutex              default: off
49
 * NO_HASH_MUTEX:       Disable hash hardware mutex             default: off
50
 * NO_PK_MUTEX:         Disable public-key hardware mutex       default: off
51
 * NO_RNG_MUTEX:        Disable RNG hardware mutex              default: off
52
 *
53
 * Memory options:
54
 * USE_WOLFSSL_MEMORY:  Enable custom memory allocation hooks   default: on
55
 * WOLFSSL_STATIC_MEMORY: Use static memory pools instead of    default: off
56
 *                      dynamic allocation.
57
 * WOLFSSL_TRACK_MEMORY: Enable memory allocation tracking      default: off
58
 * WOLFSSL_TRACK_MEMORY_VERBOSE: Verbose memory tracking output default: off
59
 * WOLFSSL_FORCE_MALLOC_FAIL_TEST: Force malloc failures for    default: off
60
 *                      testing error handling paths.
61
 * WOLFSSL_MEM_FAIL_COUNT: Count malloc failures for testing    default: off
62
 * WOLFSSL_CHECK_MEM_ZERO: Verify sensitive memory is zeroed    default: off
63
 *                      on free. Debug tool for key material.
64
 *
65
 * Filesystem options:
66
 * NO_FILESYSTEM:       Disable all filesystem operations       default: off
67
 * NO_WOLFSSL_DIR:      Disable directory listing/iteration     default: off
68
 *
69
 * Time options:
70
 * WOLFSSL_GMTIME:      Provide custom gmtime implementation    default: off
71
 * HAVE_TIME_T_TYPE:    Platform provides time_t                default: auto
72
 * TIME_OVERRIDES:      Application provides custom time funcs  default: off
73
 * USER_TICKS:          Application provides tick counter       default: off
74
 * USE_WOLF_TM:         Use wolfSSL struct tm definition        default: off
75
 *
76
 * String function options:
77
 * STRING_USER:         User provides all string functions      default: off
78
 * USE_WOLF_STRTOK:     Use wolfSSL strtok implementation       default: off
79
 * USE_WOLF_STRSEP:     Use wolfSSL strsep implementation       default: off
80
 * USE_WOLF_STRLCPY:    Use wolfSSL strlcpy implementation      default: off
81
 * USE_WOLF_STRLCAT:    Use wolfSSL strlcat implementation      default: off
82
 * USE_WOLF_STRCASECMP: Use wolfSSL strcasecmp implementation   default: off
83
 * USE_WOLF_STRNCASECMP:Use wolfSSL strncasecmp implementation  default: off
84
 * USE_WOLF_STRDUP:     Use wolfSSL strdup implementation       default: off
85
 *
86
 * Atomic operation options:
87
 * WOLFSSL_ATOMIC_OPS:  Enable atomic operations for thread     default: off
88
 *                      safety without full mutexes.
89
 * WOLFSSL_USER_DEFINED_ATOMICS: User-provided atomic impl     default: off
90
 * WOLFSSL_HAVE_ATOMIC_H: Has C11 atomic.h header              default: off
91
 *
92
 * General options:
93
 * WOLFCRYPT_ONLY:      Exclude TLS/SSL, wolfCrypt only build   default: off
94
 * WOLFSSL_LEANPSK:     Lean PSK build, minimal features        default: off
95
 * WOLF_C89:            C89 compatibility mode                  default: off
96
 * WOLFSSL_SMALL_STACK: Reduce stack usage by allocating from   default: off
97
 *                      heap instead. Slower but needed for
98
 *                      constrained environments.
99
 * DEBUG_WOLFSSL_VERBOSE: Enable verbose debug logging           default: off
100
 */
101
102
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
103
104
#ifdef __APPLE__
105
    #include <AvailabilityMacros.h>
106
#endif
107
108
#include <wolfssl/wolfcrypt/cpuid.h>
109
#ifdef HAVE_ENTROPY_MEMUSE
110
    #include <wolfssl/wolfcrypt/wolfentropy.h>
111
#endif
112
#ifdef HAVE_ECC
113
    #include <wolfssl/wolfcrypt/ecc.h>
114
#endif
115
#ifdef WOLFSSL_ASYNC_CRYPT
116
    #include <wolfssl/wolfcrypt/async.h>
117
#endif
118
#if defined(HAVE_HASHDRBG) && !defined(WC_NO_RNG)
119
    #include <wolfssl/wolfcrypt/random.h>
120
#endif
121
122
#ifdef FREESCALE_LTC_TFM
123
    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
124
#endif
125
126
#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)
127
    #include <wolfssl/wolfcrypt/port/maxim/max3266x.h>
128
#ifdef WOLF_CRYPTO_CB
129
    #include <wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h>
130
#endif
131
#endif
132
133
#ifdef WOLFSSL_PSOC6_CRYPTO
134
    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
135
#endif
136
137
#ifdef MAXQ10XX_MODULE_INIT
138
    #include <wolfssl/wolfcrypt/port/maxim/maxq10xx.h>
139
#endif
140
141
#if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A) || \
142
    defined(WOLFSSL_ATECC608A) || \
143
    defined(WOLFSSL_MICROCHIP_TA100)
144
    #include <wolfssl/wolfcrypt/port/atmel/atmel.h>
145
#endif
146
#if defined(WOLFSSL_RENESAS_TSIP)
147
    #include <wolfssl/wolfcrypt/port/Renesas/renesas_tsip_internal.h>
148
#endif
149
#if defined(WOLFSSL_RENESAS_FSPSM)
150
    #include <wolfssl/wolfcrypt/port/Renesas/renesas_fspsm_internal.h>
151
#endif
152
#if defined(WOLFSSL_RENESAS_RX64_HASH)
153
    #include <wolfssl/wolfcrypt/port/Renesas/renesas-rx64-hw-crypt.h>
154
#endif
155
#ifdef WOLFSSL_STSAFE
156
    #include <wolfssl/wolfcrypt/port/st/stsafe.h>
157
#endif
158
159
#if defined(WOLFSSL_TROPIC01)
160
    #include <wolfssl/wolfcrypt/port/tropicsquare/tropic01.h>
161
#endif
162
163
#if (defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)) \
164
    && !defined(WOLFCRYPT_ONLY)
165
    #include <wolfssl/openssl/evp.h>
166
#endif
167
168
#include <wolfssl/wolfcrypt/memory.h>
169
#if defined(USE_WOLFSSL_MEMORY) && defined(WOLFSSL_TRACK_MEMORY)
170
    #include <wolfssl/wolfcrypt/mem_track.h>
171
#endif
172
173
#if defined(WOLFSSL_CAAM)
174
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
175
#endif
176
#if defined(HAVE_ARIA)
177
    #include <wolfssl/wolfcrypt/port/aria/aria-cryptocb.h>
178
#endif
179
#if defined(WOLFSSL_DEVCRYPTO)
180
    #include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
181
#endif
182
#ifdef WOLFSSL_IMXRT_DCP
183
    #include <wolfssl/wolfcrypt/port/nxp/dcp_port.h>
184
#endif
185
186
#ifdef WOLFSSL_NXP_CASPER
187
    #include <wolfssl/wolfcrypt/port/nxp/casper_port.h>
188
#endif
189
#ifdef WOLFSSL_NXP_HASHCRYPT
190
    #include <wolfssl/wolfcrypt/port/nxp/hashcrypt_port.h>
191
#endif
192
193
#ifdef WOLF_CRYPTO_CB
194
    #include <wolfssl/wolfcrypt/cryptocb.h>
195
#endif
196
197
#ifdef HAVE_INTEL_QA_SYNC
198
    #include <wolfssl/wolfcrypt/port/intel/quickassist_sync.h>
199
#endif
200
201
#ifdef HAVE_CAVIUM_OCTEON_SYNC
202
    #include <wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h>
203
#endif
204
205
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_INIT)
206
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
207
#endif
208
209
#ifdef WOLFSSL_SCE
210
    #include "hal_data.h"
211
#endif
212
213
#if defined(WOLFSSL_DSP) && !defined(WOLFSSL_DSP_BUILD)
214
    #include "rpcmem.h"
215
#endif
216
217
#ifdef _MSC_VER
218
    /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
219
    #pragma warning(disable: 4996)
220
#endif
221
222
#if defined(WOLFSSL_HAVE_PSA)
223
    #include <wolfssl/wolfcrypt/port/psa/psa.h>
224
#endif
225
226
#if defined(HAVE_LIBOQS)
227
    #include <wolfssl/wolfcrypt/port/liboqs/liboqs.h>
228
#endif
229
230
#if defined(FREERTOS) && defined(WOLFSSL_ESPIDF)
231
    #include <freertos/FreeRTOS.h>
232
    #include <freertos/task.h>
233
    /* The Espressif-specific platform include: */
234
    #include <pthread.h>
235
#endif
236
237
#if defined(WOLFSSL_ZEPHYR)
238
#if defined(CONFIG_BOARD_NATIVE_POSIX) || defined(CONFIG_BOARD_NATIVE_SIM)
239
#include "native_rtc.h"
240
#define CONFIG_RTC
241
#endif
242
#endif
243
244
/* prevent multiple mutex initializations */
245
#ifdef WOLFSSL_ATOMIC_OPS
246
    wolfSSL_Atomic_Int initRefCount = WOLFSSL_ATOMIC_INITIALIZER(0);
247
#else
248
    static int initRefCount = 0;
249
#endif
250
251
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM_BARRIER_DETECT)
252
int aarch64_use_sb = 0;
253
#endif
254
255
/* Used to initialize state for wolfcrypt
256
   return 0 on success
257
 */
258
WOLFSSL_ABI
259
int wolfCrypt_Init(void)
260
16
{
261
16
    int ret = 0;
262
16
    int my_initRefCount = wolfSSL_Atomic_Int_FetchAdd(&initRefCount, 1);
263
16
    if (my_initRefCount == 0) {
264
16
        WOLFSSL_ENTER("wolfCrypt_Init");
265
266
    #if defined(__aarch64__) && defined(WOLFSSL_ARMASM_BARRIER_DETECT)
267
        aarch64_use_sb = IS_AARCH64_SB(cpuid_get_flags());
268
    #endif
269
270
    #ifdef WOLFSSL_CHECK_MEM_ZERO
271
        /* Initialize the mutex for access to the list of memory locations that
272
         * must be freed. */
273
        wc_MemZero_Init();
274
    #endif
275
    #ifdef WOLFSSL_MEM_FAIL_COUNT
276
        wc_MemFailCount_Init();
277
    #endif
278
279
    #ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST
280
        {
281
            word32 rngMallocFail;
282
            time_t seed = time(NULL);
283
            srand((word32)seed);
284
            rngMallocFail = rand() % 2000; /* max 2000 */
285
            fprintf(stderr, "\n--- RNG MALLOC FAIL AT %u ---\n", rngMallocFail);
286
            wolfSSL_SetMemFailCount(rngMallocFail);
287
        }
288
    #endif
289
290
16
    #ifdef WOLF_CRYPTO_CB
291
16
        wc_CryptoCb_Init();
292
16
    #endif
293
294
    #ifdef WOLFSSL_ASYNC_CRYPT
295
        ret = wolfAsync_HardwareStart();
296
        if (ret != 0) {
297
            WOLFSSL_MSG("Async hardware start failed");
298
            /* don't return failure, allow operation to continue */
299
        }
300
    #endif
301
302
    #if defined(WOLFSSL_RENESAS_TSIP)
303
        ret = tsip_Open( );
304
        if( ret != TSIP_SUCCESS ) {
305
            WOLFSSL_MSG("RENESAS TSIP Open failed");
306
            /* not return 1 since WOLFSSL_SUCCESS=1*/
307
            ret = -1;/* FATAL ERROR */
308
            return ret;
309
        }
310
    #endif
311
312
    #if defined(WOLFSSL_RENESAS_RX64_HASH)
313
    ret = rx64_hw_Open();
314
    if( ret != 0 ) {
315
        WOLFSSL_MSG("Renesas RX64 HW Open failed");
316
        /* not return 1 since WOLFSSL_SUCCESS=1*/
317
        ret = -1;/* FATAL ERROR */
318
        return ret;
319
    }
320
    #endif
321
322
    #if defined(WOLFSSL_RENESAS_FSPSM)
323
        ret = wc_fspsm_Open( );
324
        if( ret != FSP_SUCCESS ) {
325
            WOLFSSL_MSG("RENESAS SCE Open failed");
326
            /* not return 1 since WOLFSSL_SUCCESS=1*/
327
            ret = -1;/* FATAL ERROR */
328
            return ret;
329
        }
330
    #endif
331
332
    #if defined(WOLFSSL_TRACK_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY)
333
        ret = InitMemoryTracker();
334
        if (ret != 0) {
335
            WOLFSSL_MSG("InitMemoryTracker failed");
336
            return ret;
337
        }
338
    #endif
339
340
    #if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && defined(WOLFSSL_LINUXKM)
341
        ret = allocate_wolfcrypt_linuxkm_fpu_states();
342
        if (ret != 0) {
343
            WOLFSSL_MSG("allocate_wolfcrypt_linuxkm_fpu_states failed");
344
            return ret;
345
        }
346
    #endif
347
348
    #if WOLFSSL_CRYPT_HW_MUTEX
349
        /* If crypto hardware mutex protection is enabled, then initialize it */
350
        ret = wolfSSL_CryptHwMutexInit();
351
        if (ret != 0) {
352
            WOLFSSL_MSG("Hw crypt mutex init failed");
353
            return ret;
354
        }
355
    #endif
356
357
16
    #if defined(HAVE_HASHDRBG) && !defined(WC_NO_RNG) && \
358
16
        !defined(HAVE_SELFTEST) && \
359
16
        (!defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0))
360
16
        ret = wc_DrbgState_MutexInit();
361
16
        if (ret != 0) {
362
0
            WOLFSSL_MSG("DRBG state mutex init failed");
363
0
            return ret;
364
0
        }
365
16
    #endif
366
367
    #if defined(FREESCALE_LTC_TFM) || defined(FREESCALE_LTC_ECC)
368
        ret = ksdk_port_init();
369
        if (ret != 0) {
370
            WOLFSSL_MSG("KSDK port init failed");
371
            return ret;
372
        }
373
    #endif
374
375
    /* Crypto Callbacks only works on AES for MAX32666/5 HW */
376
    #if defined(MAX3266X_AES) && defined(WOLF_CRYPTO_CB)
377
        ret = wc_CryptoCb_RegisterDevice(WOLFSSL_MAX3266X_DEVID, wc_MxcCryptoCb,
378
                                            NULL);
379
        if(ret != 0) {
380
            return ret;
381
        }
382
    #endif
383
    #if defined(MAX3266X_RTC)
384
        ret = wc_MXC_RTC_Init();
385
        if (ret != 0) {
386
            WOLFSSL_MSG("MXC RTC Init Failed");
387
            return WC_HW_E;
388
        }
389
    #endif
390
391
    #if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A) || \
392
        defined(WOLFSSL_ATECC608A) || defined(WOLFSSL_MICROCHIP_TA100)
393
        ret = atmel_init();
394
        if (ret != 0) {
395
            WOLFSSL_MSG("CryptoAuthLib init failed");
396
            return ret;
397
        }
398
    #endif
399
    #if defined(WOLFSSL_CRYPTOCELL)
400
        /* enable and initialize the ARM CryptoCell 3xx runtime library */
401
        ret = cc310_Init();
402
        if (ret != 0) {
403
            WOLFSSL_MSG("CRYPTOCELL init failed");
404
            return ret;
405
        }
406
    #endif
407
    #ifdef WOLFSSL_STSAFE
408
        ret = stsafe_interface_init();
409
        if (ret != 0) {
410
            WOLFSSL_MSG("STSAFE init failed");
411
            return ret;
412
        }
413
    #endif
414
    #if defined(WOLFSSL_TROPIC01)
415
        ret = Tropic01_Init();
416
        if (ret != 0) {
417
            WOLFSSL_MSG("Tropic01 init failed");
418
            return ret;
419
        }
420
    #endif
421
    #if defined(WOLFSSL_PSOC6_CRYPTO)
422
        ret = psoc6_crypto_port_init();
423
        if (ret != 0) {
424
            WOLFSSL_MSG("PSoC6 crypto engine init failed");
425
            return ret;
426
        }
427
    #endif
428
429
    #ifdef MAXQ10XX_MODULE_INIT
430
        ret = maxq10xx_port_init();
431
        if (ret != 0) {
432
            WOLFSSL_MSG("MAXQ10xx port init failed");
433
            return ret;
434
        }
435
    #endif
436
437
    #ifdef WOLFSSL_SILABS_SE_ACCEL
438
        /* init handles if it is already initialized */
439
        ret = sl_se_init();
440
    #endif
441
442
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_INIT)
443
        ret = wc_se050_init(NULL);
444
        if (ret != 0) {
445
            WOLFSSL_MSG("SE050 init failed");
446
            return ret;
447
        }
448
    #endif
449
450
    #ifdef WOLFSSL_ARMASM
451
        WOLFSSL_MSG("Using ARM hardware acceleration");
452
    #endif
453
454
    #ifdef WOLFSSL_AFALG
455
        WOLFSSL_MSG("Using AF_ALG for crypto acceleration");
456
    #endif
457
458
16
    #if !defined(WOLFCRYPT_ONLY) && defined(OPENSSL_EXTRA)
459
16
        wolfSSL_EVP_init();
460
16
    #endif
461
462
16
    #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
463
16
        if ((ret = wc_LoggingInit()) != 0) {
464
0
            WOLFSSL_MSG("Error creating logging mutex");
465
0
            return ret;
466
0
        }
467
16
    #endif
468
469
    #if defined(WOLFSSL_HAVE_PSA)
470
        if ((ret = wc_psa_init()) != 0)
471
            return ret;
472
    #endif
473
474
    #if defined(USE_WINDOWS_API) && defined(WIN_REUSE_CRYPT_HANDLE)
475
        /* A failure here should not happen, but if it does the actual RNG seed
476
         * call will fail. This init is for a shared crypt provider handle for
477
         * RNG */
478
        (void)wc_WinCryptHandleInit();
479
    #endif
480
481
    #ifdef HAVE_ENTROPY_MEMUSE
482
        ret = Entropy_Init();
483
        if (ret != 0) {
484
            WOLFSSL_MSG("Error initializing entropy");
485
            return ret;
486
        }
487
    #endif
488
489
16
#ifdef HAVE_ECC
490
    #ifdef FP_ECC
491
        wc_ecc_fp_init();
492
    #endif
493
    #ifdef ECC_CACHE_CURVE
494
        if ((ret = wc_ecc_curve_cache_init()) != 0) {
495
            WOLFSSL_MSG("Error creating curve cache");
496
            return ret;
497
        }
498
    #endif
499
16
    #if defined(HAVE_OID_ENCODING) && (!defined(HAVE_FIPS) || \
500
16
            (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(6,0)))
501
16
        if ((ret = wc_ecc_oid_cache_init()) != 0) {
502
0
            WOLFSSL_MSG("Error creating ECC oid cache");
503
0
            return ret;
504
0
        }
505
16
    #endif
506
16
#endif
507
508
#ifdef WOLFSSL_SCE
509
        ret = (int)WOLFSSL_SCE_GSCE_HANDLE.p_api->open(
510
                WOLFSSL_SCE_GSCE_HANDLE.p_ctrl, WOLFSSL_SCE_GSCE_HANDLE.p_cfg);
511
        if (ret == SSP_ERR_CRYPTO_SCE_ALREADY_OPEN) {
512
            WOLFSSL_MSG("SCE already open");
513
            ret = 0;
514
        }
515
        if (ret != SSP_SUCCESS) {
516
            WOLFSSL_MSG("Error opening SCE");
517
            return -1; /* FATAL_ERROR */
518
        }
519
#endif
520
521
#if defined(WOLFSSL_DEVCRYPTO)
522
        if ((ret = wc_DevCryptoInit()) != 0) {
523
            return ret;
524
        }
525
#endif
526
527
#if defined(WOLFSSL_CAAM)
528
        if ((ret = wc_caamInit()) != 0) {
529
            return ret;
530
        }
531
#endif
532
533
#if defined(HAVE_ARIA)
534
        if ((ret = wc_AriaInit()) != 0) {
535
            return ret;
536
        }
537
#endif
538
539
#ifdef WOLFSSL_IMXRT_DCP
540
        if ((ret = wc_dcp_init()) != 0) {
541
            return ret;
542
        }
543
#endif
544
545
#ifdef WOLFSSL_NXP_CASPER
546
        if ((ret = wc_casper_init()) != 0) {
547
            return ret;
548
        }
549
#endif
550
#ifdef WOLFSSL_NXP_HASHCRYPT
551
        if ((ret = wc_hashcrypt_init()) != 0) {
552
            return ret;
553
        }
554
#endif
555
556
#if defined(WOLFSSL_DSP) && !defined(WOLFSSL_DSP_BUILD)
557
        if ((ret = wolfSSL_InitHandle()) != 0) {
558
            return ret;
559
        }
560
        rpcmem_init();
561
#endif
562
563
#if defined(HAVE_LIBOQS)
564
        if ((ret = wolfSSL_liboqsInit()) != 0) {
565
            return ret;
566
        }
567
#endif
568
569
        /* increment to 2, to signify successful initialization: */
570
16
        (void)wolfSSL_Atomic_Int_FetchAdd(&initRefCount, 1);
571
16
    }
572
0
    else {
573
0
        if (my_initRefCount < 2) {
574
0
            (void)wolfSSL_Atomic_Int_FetchSub(&initRefCount, 1);
575
0
            ret = BUSY_E;
576
0
        }
577
0
    }
578
579
16
    return ret;
580
16
}
581
582
#if defined(WOLFSSL_TRACK_MEMORY_VERBOSE) && !defined(WOLFSSL_STATIC_MEMORY)
583
long wolfCrypt_heap_peakAllocs_checkpoint(void) {
584
    long ret = ourMemStats.peakAllocsTripOdometer;
585
    ourMemStats.peakAllocsTripOdometer = ourMemStats.totalAllocs -
586
        ourMemStats.totalDeallocs;
587
    return ret;
588
}
589
long wolfCrypt_heap_peakBytes_checkpoint(void) {
590
    long ret = ourMemStats.peakBytesTripOdometer;
591
    ourMemStats.peakBytesTripOdometer = ourMemStats.currentBytes;
592
    return ret;
593
}
594
#endif
595
596
/* return success value is the same as wolfCrypt_Init */
597
WOLFSSL_ABI
598
int wolfCrypt_Cleanup(void)
599
5.32k
{
600
5.32k
    int ret = 0;
601
5.32k
    int my_initRefCount = wolfSSL_Atomic_Int_SubFetch(&initRefCount, 1);
602
603
5.32k
    if (my_initRefCount == 1) {
604
5.32k
        WOLFSSL_ENTER("wolfCrypt_Cleanup");
605
606
5.32k
#ifdef HAVE_ECC
607
    #ifdef FP_ECC
608
        wc_ecc_fp_free();
609
    #endif
610
    #ifdef ECC_CACHE_CURVE
611
        wc_ecc_curve_cache_free();
612
    #endif
613
5.32k
    #if defined(HAVE_OID_ENCODING) && (!defined(HAVE_FIPS) || \
614
5.32k
            (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(6,0)))
615
5.32k
        wc_ecc_oid_cache_free();
616
5.32k
    #endif
617
5.32k
#endif /* HAVE_ECC */
618
619
5.32k
    #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
620
5.32k
        ret = wc_LoggingCleanup();
621
5.32k
    #endif
622
623
    #if defined(WOLFSSL_TRACK_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY)
624
        ShowMemoryTracker();
625
    #endif
626
627
    #ifdef WOLFSSL_ASYNC_CRYPT
628
        wolfAsync_HardwareStop();
629
    #endif
630
631
    #ifdef WOLFSSL_RENESAS_TSIP
632
        tsip_Close();
633
    #endif
634
635
    #if defined(WOLFSSL_RENESAS_RX64_HASH)
636
        rx64_hw_Close();
637
    #endif
638
639
    #if defined(WOLFSSL_RENESAS_FSPSM)
640
        wc_fspsm_Close();
641
    #endif
642
643
    #ifdef WOLFSSL_SCE
644
        WOLFSSL_SCE_GSCE_HANDLE.p_api->close(WOLFSSL_SCE_GSCE_HANDLE.p_ctrl);
645
    #endif
646
647
    #if defined(WOLFSSL_CAAM)
648
        wc_caamFree();
649
    #endif
650
    #if defined(WOLFSSL_CRYPTOCELL)
651
        cc310_Free();
652
    #endif
653
    #ifdef WOLFSSL_SILABS_SE_ACCEL
654
        ret = sl_se_deinit();
655
    #endif
656
    #if defined(WOLFSSL_TROPIC01)
657
        Tropic01_Deinit();
658
    #endif
659
    #if defined(WOLFSSL_RENESAS_TSIP)
660
        tsip_Close();
661
    #endif
662
    #if defined(WOLFSSL_DEVCRYPTO)
663
        wc_DevCryptoCleanup();
664
    #endif
665
    #if defined(WOLFSSL_DSP) && !defined(WOLFSSL_DSP_BUILD)
666
        rpcmem_deinit();
667
        wolfSSL_CleanupHandle();
668
    #endif
669
    #if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && defined(WOLFSSL_LINUXKM)
670
        free_wolfcrypt_linuxkm_fpu_states();
671
    #endif
672
673
    #ifdef HAVE_ENTROPY_MEMUSE
674
        Entropy_Final();
675
    #endif
676
677
    #if defined(USE_WINDOWS_API) && defined(WIN_REUSE_CRYPT_HANDLE)
678
        wc_WinCryptHandleCleanup();
679
    #endif
680
681
5.32k
    #ifdef WOLF_CRYPTO_CB
682
5.32k
        wc_CryptoCb_Cleanup();
683
5.32k
    #endif
684
685
5.32k
    #if defined(HAVE_HASHDRBG) && !defined(WC_NO_RNG) && \
686
5.32k
        !defined(HAVE_SELFTEST) && \
687
5.32k
        (!defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0))
688
5.32k
        wc_DrbgState_MutexFree();
689
5.32k
    #endif
690
691
    #if defined(WOLFSSL_MEM_FAIL_COUNT) && defined(WOLFCRYPT_ONLY)
692
        wc_MemFailCount_Free();
693
    #endif
694
    #ifdef WOLFSSL_CHECK_MEM_ZERO
695
        /* Free the mutex for access to the list of memory locations that
696
         * must be freed. */
697
        wc_MemZero_Free();
698
    #endif
699
700
5.32k
        (void)wolfSSL_Atomic_Int_SubFetch(&initRefCount, 1);
701
702
#if defined(HAVE_LIBOQS)
703
        wolfSSL_liboqsClose();
704
#endif
705
5.32k
    }
706
0
    else if (my_initRefCount < 0) {
707
0
        (void)wolfSSL_Atomic_Int_AddFetch(&initRefCount, 1);
708
0
        WOLFSSL_MSG("wolfCrypt_Cleanup() called with initRefCount <= 0.");
709
0
        ret = ALREADY_E;
710
0
    }
711
712
5.32k
    return ret;
713
5.32k
}
714
715
#ifndef NO_FILESYSTEM
716
717
/* Helpful function to load file into allocated buffer */
718
int wc_FileLoad(const char* fname, unsigned char** buf, size_t* bufLen,
719
    void* heap)
720
0
{
721
0
    int ret;
722
0
    ssize_t fileSz;
723
0
    XFILE f;
724
725
0
    if (fname == NULL || buf == NULL || bufLen == NULL) {
726
0
        return BAD_FUNC_ARG;
727
0
    }
728
729
    /* set defaults */
730
0
    *buf = NULL;
731
0
    *bufLen = 0;
732
733
    /* open file (read-only binary) */
734
0
    f = XFOPEN(fname, "rb");
735
0
    if (!f) {
736
0
        WOLFSSL_MSG("wc_LoadFile file load error");
737
0
        return BAD_PATH_ERROR;
738
0
    }
739
740
0
    if (XFSEEK(f, 0, XSEEK_END) != 0) {
741
0
        WOLFSSL_MSG("wc_LoadFile file seek error");
742
0
        XFCLOSE(f);
743
0
        return BAD_PATH_ERROR;
744
0
    }
745
0
    fileSz = XFTELL(f);
746
0
    if (fileSz < 0) {
747
0
        WOLFSSL_MSG("wc_LoadFile ftell error");
748
0
        XFCLOSE(f);
749
0
        return BAD_PATH_ERROR;
750
0
    }
751
0
    if (XFSEEK(f, 0, XSEEK_SET) != 0) {
752
0
        WOLFSSL_MSG("wc_LoadFile file seek error");
753
0
        XFCLOSE(f);
754
0
        return BAD_PATH_ERROR;
755
0
    }
756
0
    if (fileSz > 0) {
757
0
        *bufLen = (size_t)fileSz;
758
0
        *buf = (byte*)XMALLOC(*bufLen, heap, DYNAMIC_TYPE_TMP_BUFFER);
759
0
        if (*buf == NULL) {
760
0
            WOLFSSL_MSG("wc_LoadFile memory error");
761
0
            ret = MEMORY_E;
762
0
        }
763
0
        else {
764
0
            size_t readLen = XFREAD(*buf, 1, *bufLen, f);
765
766
            /* check response code */
767
0
            ret = (readLen == *bufLen) ? 0 : -1;
768
0
        }
769
0
    }
770
0
    else {
771
0
        ret = BUFFER_E;
772
0
    }
773
0
    XFCLOSE(f);
774
775
0
    (void)heap;
776
777
0
    return ret;
778
0
}
779
780
#if !defined(NO_WOLFSSL_DIR) && \
781
    !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2)
782
/* File Handling Helper */
783
/* returns 0 if file exists, WC_ISFILEEXIST_NOFILE if file doesn't exist */
784
int wc_FileExists(const char* fname)
785
0
{
786
0
    struct ReadDirCtx ctx;
787
788
0
    XMEMSET(&ctx, 0, sizeof(ctx));
789
790
0
    if (fname == NULL)
791
0
        return 0;
792
793
0
    if (XSTAT(fname, &ctx.s) != 0) {
794
0
         WOLFSSL_MSG("stat on name failed");
795
0
         return BAD_PATH_ERROR;
796
0
    } else {
797
#if defined(USE_WINDOWS_API)
798
        if (XS_ISREG(ctx.s.st_mode)) {
799
            return 0;
800
        }
801
#elif defined(WOLFSSL_ZEPHYR)
802
        if (XS_ISREG(ctx.s.type)) {
803
            return 0;
804
        }
805
#elif defined(WOLFSSL_TELIT_M2MB)
806
        if (XS_ISREG(ctx.s.st_mode)) {
807
            return 0;
808
        }
809
#else
810
0
        if (XS_ISREG(ctx.s.st_mode)) {
811
0
            return 0;
812
0
        }
813
0
#endif
814
0
    }
815
0
    return WC_ISFILEEXIST_NOFILE;
816
0
}
817
818
/* File Handling Helpers */
819
/* returns 0 if file found, WC_READDIR_NOFILE if no files or negative error */
820
int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name)
821
0
{
822
0
    int ret = WC_READDIR_NOFILE; /* default to no files found */
823
0
    int pathLen = 0;
824
825
0
    if (name)
826
0
        *name = NULL;
827
828
0
    if (ctx != NULL)
829
0
        XMEMSET(ctx, 0, sizeof(ReadDirCtx));
830
831
0
    if (ctx == NULL || path == NULL) {
832
0
        return BAD_FUNC_ARG;
833
0
    }
834
835
0
    pathLen = (int)XSTRLEN(path);
836
837
#ifdef USE_WINDOWS_API
838
    if (pathLen > MAX_FILENAME_SZ - 3)
839
        return BAD_PATH_ERROR;
840
841
    XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ - 3);
842
    XSTRNCPY(ctx->name + pathLen, "\\*", (size_t)(MAX_FILENAME_SZ - pathLen));
843
844
    ctx->hFind = FindFirstFileA(ctx->name, &ctx->FindFileData);
845
    if (ctx->hFind == INVALID_HANDLE_VALUE) {
846
        WOLFSSL_MSG("FindFirstFile for path verify locations failed");
847
        return BAD_PATH_ERROR;
848
    }
849
850
    do {
851
        if (!(ctx->FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
852
            int dnameLen = (int)XSTRLEN(ctx->FindFileData.cFileName);
853
854
            if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
855
                return BAD_PATH_ERROR;
856
            }
857
            XSTRNCPY(ctx->name, path, (size_t)pathLen + 1);
858
            ctx->name[pathLen] = '\\';
859
            XSTRNCPY(ctx->name + pathLen + 1,
860
                     ctx->FindFileData.cFileName,
861
                     (size_t)(MAX_FILENAME_SZ - pathLen - 1));
862
            if (name)
863
                *name = ctx->name;
864
            return 0;
865
        }
866
    } while (FindNextFileA(ctx->hFind, &ctx->FindFileData));
867
868
#elif defined(INTIME_RTOS)
869
    if (pathLen > MAX_FILENAME_SZ - 3)
870
        return BAD_PATH_ERROR;
871
872
    XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ - 3);
873
    XSTRNCPY(ctx->name + pathLen, "\\*", MAX_FILENAME_SZ - pathLen);
874
875
    if (!IntimeFindFirst(ctx->name, &ctx->FindFileData)) {
876
        WOLFSSL_MSG("FindFirstFile for path verify locations failed");
877
        return BAD_PATH_ERROR;
878
    }
879
880
    do {
881
        int dnameLen = (int)XSTRLEN(IntimeFilename(ctx));
882
883
        if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
884
            return BAD_PATH_ERROR;
885
        }
886
        XSTRNCPY(ctx->name, path, pathLen + 1);
887
        ctx->name[pathLen] = '\\';
888
        XSTRNCPY(ctx->name + pathLen + 1,
889
                 IntimeFilename(ctx),
890
                 MAX_FILENAME_SZ - pathLen - 1);
891
        if (0 == wc_FileExists(ctx->name)) {
892
            if (name)
893
                *name = ctx->name;
894
            return 0;
895
        }
896
    } while (IntimeFindNext(&ctx->FindFileData));
897
898
#elif defined(WOLFSSL_ZEPHYR)
899
    if (fs_opendir(&ctx->dir, path) != 0) {
900
        WOLFSSL_MSG("opendir path verify locations failed");
901
        return BAD_PATH_ERROR;
902
    }
903
    ctx->dirp = &ctx->dir;
904
905
    while ((fs_readdir(&ctx->dir, &ctx->entry)) != 0) {
906
        int dnameLen = (int)XSTRLEN(ctx->entry.name);
907
908
        if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {
909
            ret = BAD_PATH_ERROR;
910
            break;
911
        }
912
        XSTRNCPY(ctx->name, path, pathLen + 1);
913
        ctx->name[pathLen] = '/';
914
915
        /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because
916
         * of earlier check it is known that dnameLen is less than
917
         * MAX_FILENAME_SZ - (pathLen + 2)  so dnameLen +1 will fit */
918
        XSTRNCPY(ctx->name + pathLen + 1, ctx->entry.name, dnameLen + 1);
919
        if ((ret = wc_FileExists(ctx->name)) == 0) {
920
            if (name)
921
                *name = ctx->name;
922
            return 0;
923
        }
924
    }
925
#elif defined(WOLFSSL_TELIT_M2MB)
926
    ctx->dir = m2mb_fs_opendir((const CHAR*)path);
927
    if (ctx->dir == NULL) {
928
        WOLFSSL_MSG("opendir path verify locations failed");
929
        return BAD_PATH_ERROR;
930
    }
931
932
    while ((ctx->entry = m2mb_fs_readdir(ctx->dir)) != NULL) {
933
        int dnameLen = (int)XSTRLEN(ctx->entry->d_name);
934
935
        if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {
936
            ret = BAD_PATH_ERROR;
937
            break;
938
        }
939
        XSTRNCPY(ctx->name, path, pathLen + 1);
940
        ctx->name[pathLen] = '/';
941
942
        /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because
943
         * of earlier check it is known that dnameLen is less than
944
         * MAX_FILENAME_SZ - (pathLen + 2)  so dnameLen +1 will fit */
945
        XSTRNCPY(ctx->name + pathLen + 1, ctx->entry->d_name, dnameLen + 1);
946
947
        if ((ret = wc_FileExists(ctx->name)) == 0) {
948
            if (name)
949
                *name = ctx->name;
950
            return 0;
951
        }
952
    }
953
#else
954
0
    ctx->dir = opendir(path);
955
0
    if (ctx->dir == NULL) {
956
0
        WOLFSSL_MSG("opendir path verify locations failed");
957
0
        return BAD_PATH_ERROR;
958
0
    }
959
960
0
    while ((ctx->entry = readdir(ctx->dir)) != NULL) {
961
0
        int dnameLen = (int)XSTRLEN(ctx->entry->d_name);
962
963
0
        if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {
964
0
            ret = BAD_PATH_ERROR;
965
0
            break;
966
0
        }
967
0
        XSTRNCPY(ctx->name, path, (size_t)pathLen + 1);
968
0
        ctx->name[pathLen] = '/';
969
970
        /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because
971
         * of earlier check it is known that dnameLen is less than
972
         * MAX_FILENAME_SZ - (pathLen + 2)  so dnameLen +1 will fit */
973
0
        XSTRNCPY(ctx->name + pathLen + 1, ctx->entry->d_name, (size_t)dnameLen + 1);
974
0
        if ((ret = wc_FileExists(ctx->name)) == 0) {
975
0
            if (name)
976
0
                *name = ctx->name;
977
0
            return 0;
978
0
        }
979
0
    }
980
0
#endif
981
0
    wc_ReadDirClose(ctx);
982
983
0
    return ret;
984
0
}
985
986
/* returns 0 if file found, WC_READDIR_NOFILE if no more files */
987
int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name)
988
0
{
989
0
    int ret = WC_READDIR_NOFILE; /* default to no file found */
990
0
    int pathLen = 0;
991
992
0
    if (name)
993
0
        *name = NULL;
994
995
0
    if (ctx == NULL || path == NULL) {
996
0
        return BAD_FUNC_ARG;
997
0
    }
998
999
0
    XMEMSET(ctx->name, 0, MAX_FILENAME_SZ);
1000
0
    pathLen = (int)XSTRLEN(path);
1001
1002
#ifdef USE_WINDOWS_API
1003
    while (FindNextFileA(ctx->hFind, &ctx->FindFileData)) {
1004
        if (!(ctx->FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
1005
            int dnameLen = (int)XSTRLEN(ctx->FindFileData.cFileName);
1006
1007
            if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
1008
                return BAD_PATH_ERROR;
1009
            }
1010
            XSTRNCPY(ctx->name, path, (size_t)pathLen + 1);
1011
            ctx->name[pathLen] = '\\';
1012
            XSTRNCPY(ctx->name + pathLen + 1,
1013
                     ctx->FindFileData.cFileName,
1014
                     (size_t)(MAX_FILENAME_SZ - pathLen - 1));
1015
            if (name)
1016
                *name = ctx->name;
1017
            return 0;
1018
        }
1019
    }
1020
1021
#elif defined(INTIME_RTOS)
1022
    while (IntimeFindNext(&ctx->FindFileData)) {
1023
        int dnameLen = (int)XSTRLEN(IntimeFilename(ctx));
1024
1025
        if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
1026
            return BAD_PATH_ERROR;
1027
        }
1028
        XSTRNCPY(ctx->name, path, pathLen + 1);
1029
        ctx->name[pathLen] = '\\';
1030
        XSTRNCPY(ctx->name + pathLen + 1,
1031
                 IntimeFilename(ctx),
1032
                 MAX_FILENAME_SZ - pathLen - 1);
1033
        if (0 == wc_FileExists(ctx->name)) {
1034
            if (name)
1035
                *name = ctx->name;
1036
            return 0;
1037
        }
1038
    }
1039
1040
#elif defined(WOLFSSL_ZEPHYR)
1041
    while ((fs_readdir(&ctx->dir, &ctx->entry)) != 0) {
1042
        int dnameLen = (int)XSTRLEN(ctx->entry.name);
1043
1044
        if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {
1045
            ret = BAD_PATH_ERROR;
1046
            break;
1047
        }
1048
        XSTRNCPY(ctx->name, path, pathLen + 1);
1049
        ctx->name[pathLen] = '/';
1050
        /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because
1051
         * of earlier check it is known that dnameLen is less than
1052
         * MAX_FILENAME_SZ - (pathLen + 2) so that dnameLen +1 will fit */
1053
        XSTRNCPY(ctx->name + pathLen + 1, ctx->entry.name, dnameLen + 1);
1054
1055
       if ((ret = wc_FileExists(ctx->name)) == 0) {
1056
            if (name)
1057
                *name = ctx->name;
1058
            return 0;
1059
        }
1060
    }
1061
#elif defined(WOLFSSL_TELIT_M2MB)
1062
    while ((ctx->entry = m2mb_fs_readdir(ctx->dir)) != NULL) {
1063
        int dnameLen = (int)XSTRLEN(ctx->entry->d_name);
1064
1065
        if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {
1066
            ret = BAD_PATH_ERROR;
1067
            break;
1068
        }
1069
        XSTRNCPY(ctx->name, path, pathLen + 1);
1070
        ctx->name[pathLen] = '/';
1071
1072
        /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because
1073
         * of earlier check it is known that dnameLen is less than
1074
         * MAX_FILENAME_SZ - (pathLen + 2)  so dnameLen +1 will fit */
1075
        XSTRNCPY(ctx->name + pathLen + 1, ctx->entry->d_name, dnameLen + 1);
1076
1077
        if ((ret = wc_FileExists(ctx->name)) == 0) {
1078
            if (name)
1079
                *name = ctx->name;
1080
            return 0;
1081
        }
1082
    }
1083
#else
1084
0
    while ((ctx->entry = readdir(ctx->dir)) != NULL) {
1085
0
        int dnameLen = (int)XSTRLEN(ctx->entry->d_name);
1086
1087
0
        if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {
1088
0
            ret = BAD_PATH_ERROR;
1089
0
            break;
1090
0
        }
1091
0
        XSTRNCPY(ctx->name, path, (size_t)pathLen + 1);
1092
0
        ctx->name[pathLen] = '/';
1093
        /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because
1094
         * of earlier check it is known that dnameLen is less than
1095
         * MAX_FILENAME_SZ - (pathLen + 2) so that dnameLen +1 will fit */
1096
0
        XSTRNCPY(ctx->name + pathLen + 1, ctx->entry->d_name, (size_t)dnameLen + 1);
1097
1098
0
        if ((ret = wc_FileExists(ctx->name)) == 0) {
1099
0
            if (name)
1100
0
                *name = ctx->name;
1101
0
            return 0;
1102
0
        }
1103
0
    }
1104
0
#endif
1105
1106
0
    wc_ReadDirClose(ctx);
1107
1108
0
    return ret;
1109
0
}
1110
1111
void wc_ReadDirClose(ReadDirCtx* ctx)
1112
0
{
1113
0
    if (ctx == NULL) {
1114
0
        return;
1115
0
    }
1116
1117
#ifdef USE_WINDOWS_API
1118
    if (ctx->hFind != INVALID_HANDLE_VALUE) {
1119
        FindClose(ctx->hFind);
1120
        ctx->hFind = INVALID_HANDLE_VALUE;
1121
    }
1122
1123
#elif defined(INTIME_RTOS)
1124
    IntimeFindClose(&ctx->FindFileData);
1125
1126
#elif defined(WOLFSSL_ZEPHYR)
1127
    if (ctx->dirp) {
1128
        fs_closedir(ctx->dirp);
1129
        ctx->dirp = NULL;
1130
    }
1131
#elif defined(WOLFSSL_TELIT_M2MB)
1132
    if (ctx->dir) {
1133
        m2mb_fs_closedir(ctx->dir);
1134
        ctx->dir = NULL;
1135
    }
1136
#else
1137
0
    if (ctx->dir) {
1138
0
        if (closedir(ctx->dir) < 0)
1139
0
            WOLFSSL_MSG("closedir() failed");
1140
0
        ctx->dir = NULL;
1141
0
    }
1142
0
#endif
1143
0
}
1144
1145
#endif /* !NO_WOLFSSL_DIR */
1146
#endif /* !NO_FILESYSTEM */
1147
1148
#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_ZEPHYR)
1149
XFILE z_fs_open(const char* filename, const char* mode)
1150
{
1151
    XFILE file;
1152
    fs_mode_t flags = 0;
1153
1154
    if (mode == NULL)
1155
        return NULL;
1156
1157
    /* Parse mode */
1158
    switch (*mode++) {
1159
        case 'r':
1160
            flags |= FS_O_READ;
1161
            break;
1162
        case 'w':
1163
            flags |= FS_O_WRITE|FS_O_CREATE;
1164
            break;
1165
        case 'a':
1166
            flags |= FS_O_APPEND|FS_O_CREATE;
1167
            break;
1168
        default:
1169
            return NULL;
1170
    }
1171
1172
    /* Ignore binary flag */
1173
    if (*mode == 'b')
1174
        mode++;
1175
    if (*mode == '+') {
1176
        flags |= FS_O_READ;
1177
        /* Don't add write flag if already appending */
1178
        if (!(flags & FS_O_APPEND))
1179
            flags |= FS_O_RDWR;
1180
    }
1181
    /* Ignore binary flag */
1182
    if (*mode == 'b')
1183
        mode++;
1184
    /* Incorrect mode string */
1185
    if (*mode != '\0')
1186
        return NULL;
1187
1188
    file = (XFILE)XMALLOC(sizeof(*file), NULL, DYNAMIC_TYPE_FILE);
1189
    if (file != NULL) {
1190
        fs_file_t_init(file);
1191
        if (fs_open(file, filename, flags) != 0) {
1192
            XFREE(file, NULL, DYNAMIC_TYPE_FILE);
1193
            file = NULL;
1194
        }
1195
    }
1196
1197
    return file;
1198
}
1199
1200
int z_fs_close(XFILE file)
1201
{
1202
    int ret;
1203
1204
    if (file == NULL)
1205
        return -1;
1206
    ret = (fs_close(file) == 0) ? 0 : -1;
1207
1208
    XFREE(file, NULL, DYNAMIC_TYPE_FILE);
1209
1210
    return ret;
1211
}
1212
1213
/* Rewind the file pointer to the beginning of the file */
1214
/* This is not a 'rewind' is not supported in Zephyr so */
1215
/* use fs_seek to move the file pointer to the beginning of the file */
1216
/* calling it z_fs_rewind to avoid future conflicts if rewind is added */
1217
int z_fs_rewind(XFILE file)
1218
{
1219
    return fs_seek(file, 0, FS_SEEK_SET);
1220
}
1221
1222
#endif /* !NO_FILESYSTEM && !WOLFSSL_ZEPHYR */
1223
1224
#if !defined(WOLFSSL_USER_MUTEX)
1225
wolfSSL_Mutex* wc_InitAndAllocMutex(void)
1226
0
{
1227
0
    wolfSSL_Mutex* m = (wolfSSL_Mutex*) XMALLOC(sizeof(wolfSSL_Mutex), NULL,
1228
0
            DYNAMIC_TYPE_MUTEX);
1229
0
    if (m != NULL) {
1230
0
        if (wc_InitMutex(m) != 0) {
1231
0
            WOLFSSL_MSG("Init Mutex failed");
1232
0
            XFREE(m, NULL, DYNAMIC_TYPE_MUTEX);
1233
0
            m = NULL;
1234
0
        }
1235
0
    }
1236
0
    else {
1237
0
        WOLFSSL_MSG("Memory error with Mutex allocation");
1238
0
    }
1239
1240
0
    return m;
1241
0
}
1242
#endif
1243
1244
#ifdef USE_WOLF_STRTOK
1245
/* String token (delim) search. If str is null use nextp. */
1246
char* wc_strtok(char *str, const char *delim, char **nextp)
1247
0
{
1248
0
    char* ret;
1249
0
    int i, j;
1250
1251
    /* Use next if str is NULL */
1252
0
    if (str == NULL && nextp)
1253
0
        str = *nextp;
1254
1255
    /* verify str input */
1256
0
    if (str == NULL || *str == '\0')
1257
0
        return NULL;
1258
1259
    /* match on entire delim */
1260
0
    for (i = 0; str[i]; i++) {
1261
0
        for (j = 0; delim[j]; j++) {
1262
0
            if (delim[j] == str[i])
1263
0
                break;
1264
0
        }
1265
0
        if (!delim[j])
1266
0
            break;
1267
0
    }
1268
0
    str += i;
1269
    /* if end of string, not found so return NULL */
1270
0
    if (*str == '\0')
1271
0
        return NULL;
1272
1273
0
    ret = str;
1274
1275
    /* match on first delim */
1276
0
    for (i = 0; str[i]; i++) {
1277
0
        for (j = 0; delim[j]; j++) {
1278
0
            if (delim[j] == str[i])
1279
0
                break;
1280
0
        }
1281
0
        if (delim[j] == str[i])
1282
0
            break;
1283
0
    }
1284
0
    str += i;
1285
1286
    /* null terminate found string */
1287
0
    if (*str)
1288
0
        *str++ = '\0';
1289
1290
    /* return pointer to next */
1291
0
    if (nextp)
1292
0
        *nextp = str;
1293
1294
0
    return ret;
1295
0
}
1296
#endif /* USE_WOLF_STRTOK */
1297
1298
#ifdef USE_WOLF_STRSEP
1299
char* wc_strsep(char **stringp, const char *delim)
1300
0
{
1301
0
    char *s, *tok;
1302
0
    const char *spanp;
1303
1304
    /* null check */
1305
0
    if (stringp == NULL || *stringp == NULL)
1306
0
        return NULL;
1307
1308
0
    s = *stringp;
1309
0
    for (tok = s; *tok; ++tok) {
1310
0
        for (spanp = delim; *spanp; ++spanp) {
1311
            /* found delimiter */
1312
0
            if (*tok == *spanp) {
1313
0
                *tok = '\0'; /* replace delim with null term */
1314
0
                *stringp = tok + 1; /* return past delim */
1315
0
                return s;
1316
0
            }
1317
0
        }
1318
0
    }
1319
1320
0
    *stringp = NULL;
1321
0
    return s;
1322
0
}
1323
#endif /* USE_WOLF_STRSEP */
1324
1325
#ifdef USE_WOLF_STRLCPY
1326
size_t wc_strlcpy(char *dst, const char *src, size_t dstSize)
1327
0
{
1328
0
    size_t i;
1329
1330
0
    if (!dstSize)
1331
0
        return 0;
1332
1333
    /* Always have to leave a space for NULL */
1334
0
    for (i = 0; i < (dstSize - 1) && *src != '\0'; i++) {
1335
0
        *dst++ = *src++;
1336
0
    }
1337
0
    *dst = '\0';
1338
1339
0
    return i; /* return length without NULL */
1340
0
}
1341
#endif /* USE_WOLF_STRLCPY */
1342
1343
#ifdef USE_WOLF_STRLCAT
1344
size_t wc_strlcat(char *dst, const char *src, size_t dstSize)
1345
0
{
1346
0
    size_t dstLen;
1347
1348
0
    if (!dstSize)
1349
0
        return 0;
1350
1351
0
    dstLen = XSTRLEN(dst);
1352
1353
0
    if (dstSize < dstLen)
1354
0
        return dstLen + XSTRLEN(src);
1355
1356
0
    return dstLen + wc_strlcpy(dst + dstLen, src, dstSize - dstLen);
1357
0
}
1358
#endif /* USE_WOLF_STRLCAT */
1359
1360
#ifdef USE_WOLF_STRCASECMP
1361
int wc_strcasecmp(const char *s1, const char *s2)
1362
{
1363
    char c1, c2;
1364
    for (;;++s1, ++s2) {
1365
        c1 = *s1;
1366
        if ((c1 >= 'a') && (c1 <= 'z'))
1367
            c1 = (char)(c1 - ('a' - 'A'));
1368
        c2 = *s2;
1369
        if ((c2 >= 'a') && (c2 <= 'z'))
1370
            c2 = (char)(c2 - ('a' - 'A'));
1371
        if ((c1 != c2) || (c1 == 0))
1372
            break;
1373
    }
1374
    return (c1 - c2);
1375
}
1376
#endif /* USE_WOLF_STRCASECMP */
1377
1378
#ifdef USE_WOLF_STRNCASECMP
1379
int wc_strncasecmp(const char *s1, const char *s2, size_t n)
1380
{
1381
    char c1, c2;
1382
    for (c1 = 0, c2 = 0; n > 0; --n, ++s1, ++s2) {
1383
        c1 = *s1;
1384
        if ((c1 >= 'a') && (c1 <= 'z'))
1385
            c1 = (char)(c1 - ('a' - 'A'));
1386
        c2 = *s2;
1387
        if ((c2 >= 'a') && (c2 <= 'z'))
1388
            c2 = (char)(c2 - ('a' - 'A'));
1389
        if ((c1 != c2) || (c1 == 0))
1390
            break;
1391
    }
1392
    return (c1 - c2);
1393
}
1394
#endif /* USE_WOLF_STRNCASECMP */
1395
1396
#ifdef USE_WOLF_STRDUP
1397
0
char* wc_strdup_ex(const char *src, int memType) {
1398
0
    char *ret = NULL;
1399
0
    word32 len = 0;
1400
1401
0
    if (src) {
1402
0
        len = (word32)XSTRLEN(src) + 1; /* Add one for null terminator */
1403
0
        ret = (char*)XMALLOC(len, NULL, memType);
1404
0
        if (ret != NULL) {
1405
0
            XMEMCPY(ret, src, len);
1406
0
        }
1407
0
    }
1408
1409
0
    return ret;
1410
0
}
1411
#endif
1412
1413
#ifdef WOLFSSL_ATOMIC_OPS
1414
1415
#if defined(WOLFSSL_USER_DEFINED_ATOMICS)
1416
1417
#elif defined(SINGLE_THREADED)
1418
1419
#elif defined(WOLFSSL_BSDKM)
1420
/* Note: using compiler built-ins like __atomic_fetch_add will technically
1421
 * build in FreeBSD kernel, but are not commonly used in FreeBSD kernel and
1422
 * might not be safe or portable.
1423
 * */
1424
void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i)
1425
{
1426
    *c = i;
1427
}
1428
1429
void wolfSSL_Atomic_Uint_Init(wolfSSL_Atomic_Uint* c, unsigned int i)
1430
{
1431
    *c = i;
1432
}
1433
1434
int wolfSSL_Atomic_Int_FetchAdd(wolfSSL_Atomic_Int* c, int i)
1435
{
1436
    return atomic_fetchadd_int(c, i);
1437
}
1438
1439
int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i)
1440
{
1441
    return atomic_fetchadd_int(c, -i);
1442
}
1443
1444
int wolfSSL_Atomic_Int_AddFetch(wolfSSL_Atomic_Int* c, int i)
1445
{
1446
    int val = atomic_fetchadd_int(c, i);
1447
    return val + i;
1448
}
1449
1450
int wolfSSL_Atomic_Int_SubFetch(wolfSSL_Atomic_Int* c, int i)
1451
{
1452
    int val = atomic_fetchadd_int(c, -i);
1453
    return val - i;
1454
}
1455
1456
unsigned int wolfSSL_Atomic_Uint_FetchAdd(wolfSSL_Atomic_Uint* c,
1457
                                          unsigned int i)
1458
{
1459
    return atomic_fetchadd_int(c, i);
1460
}
1461
1462
unsigned int wolfSSL_Atomic_Uint_FetchSub(wolfSSL_Atomic_Uint* c,
1463
                                          unsigned int i)
1464
{
1465
    return atomic_fetchadd_int(c, -i);
1466
}
1467
1468
unsigned int wolfSSL_Atomic_Uint_AddFetch(wolfSSL_Atomic_Uint* c,
1469
                                          unsigned int i)
1470
{
1471
    unsigned int val = atomic_fetchadd_int(c, i);
1472
    return val + i;
1473
}
1474
1475
unsigned int wolfSSL_Atomic_Uint_SubFetch(wolfSSL_Atomic_Uint* c,
1476
                                          unsigned int i)
1477
{
1478
    unsigned int val = atomic_fetchadd_int(c, -i);
1479
    return val - i;
1480
}
1481
1482
int wolfSSL_Atomic_Int_Exchange(wolfSSL_Atomic_Int* c, int new_i)
1483
{
1484
    return atomic_swap_int(c, new_i);
1485
}
1486
1487
int wolfSSL_Atomic_Int_CompareExchange(wolfSSL_Atomic_Int* c, int *expected_i,
1488
                                       int new_i)
1489
{
1490
    u_int exp = (u_int) *expected_i;
1491
    int ret = atomic_fcmpset_int(c, &exp, new_i);
1492
    *expected_i = (int)exp;
1493
    return ret;
1494
}
1495
1496
int wolfSSL_Atomic_Uint_CompareExchange(
1497
    wolfSSL_Atomic_Uint* c, unsigned int *expected_i, unsigned int new_i)
1498
{
1499
    u_int exp = (u_int)*expected_i;
1500
    int ret = atomic_fcmpset_int(c, &exp, new_i);
1501
    *expected_i = (unsigned int)exp;
1502
    return ret;
1503
}
1504
1505
int wolfSSL_Atomic_Ptr_CompareExchange(
1506
    void * volatile *c, void **expected_ptr, void *new_ptr)
1507
{
1508
    uintptr_t exp = (uintptr_t)*expected_ptr;
1509
    int ret = atomic_fcmpset_ptr((uintptr_t *)c, &exp, (uintptr_t)new_ptr);
1510
    *expected_ptr = (void *)exp;
1511
    return ret;
1512
}
1513
1514
#elif defined(HAVE_C___ATOMIC) && defined(WOLFSSL_HAVE_ATOMIC_H) && \
1515
        !defined(__cplusplus)
1516
1517
/* Default C Implementation */
1518
void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i)
1519
411k
{
1520
411k
    atomic_init(c, i);
1521
411k
}
1522
1523
void wolfSSL_Atomic_Uint_Init(wolfSSL_Atomic_Uint* c, unsigned int i)
1524
0
{
1525
0
    atomic_init(c, i);
1526
0
}
1527
1528
int wolfSSL_Atomic_Int_FetchAdd(wolfSSL_Atomic_Int* c, int i)
1529
11.1k
{
1530
11.1k
    return atomic_fetch_add_explicit(c, i, memory_order_relaxed);
1531
11.1k
}
1532
1533
int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i)
1534
106k
{
1535
106k
    return atomic_fetch_sub_explicit(c, i, memory_order_relaxed);
1536
106k
}
1537
1538
int wolfSSL_Atomic_Int_AddFetch(wolfSSL_Atomic_Int* c, int i)
1539
0
{
1540
0
    int ret = atomic_fetch_add_explicit(c, i, memory_order_relaxed);
1541
0
    return ret + i;
1542
0
}
1543
1544
int wolfSSL_Atomic_Int_SubFetch(wolfSSL_Atomic_Int* c, int i)
1545
10.6k
{
1546
10.6k
    int ret = atomic_fetch_sub_explicit(c, i, memory_order_relaxed);
1547
10.6k
    return ret - i;
1548
10.6k
}
1549
1550
int wolfSSL_Atomic_Int_Exchange(wolfSSL_Atomic_Int* c, int new_i)
1551
0
{
1552
0
    return atomic_exchange_explicit(c, new_i, memory_order_seq_cst);
1553
0
}
1554
1555
int wolfSSL_Atomic_Int_CompareExchange(
1556
    wolfSSL_Atomic_Int* c, int *expected_i, int new_i)
1557
0
{
1558
    /* For the success path, use full synchronization with barriers --
1559
     * "Sequentially-consistent ordering" -- so that all threads see the same
1560
     * "single total modification order of all atomic operations" -- but on
1561
     * failure we just need to be sure we acquire the value that changed out
1562
     * from under us.
1563
     */
1564
0
    return atomic_compare_exchange_strong_explicit(
1565
0
        c, expected_i, new_i, memory_order_seq_cst, memory_order_acquire);
1566
0
}
1567
1568
unsigned int wolfSSL_Atomic_Uint_FetchAdd(wolfSSL_Atomic_Uint* c,
1569
                                          unsigned int i)
1570
0
{
1571
0
    return atomic_fetch_add_explicit(c, i, memory_order_relaxed);
1572
0
}
1573
1574
unsigned int wolfSSL_Atomic_Uint_FetchSub(wolfSSL_Atomic_Uint* c,
1575
                                          unsigned int i)
1576
0
{
1577
0
    return atomic_fetch_sub_explicit(c, i, memory_order_relaxed);
1578
0
}
1579
1580
unsigned int wolfSSL_Atomic_Uint_AddFetch(wolfSSL_Atomic_Uint* c,
1581
                                          unsigned int i)
1582
0
{
1583
0
    unsigned int ret = atomic_fetch_add_explicit(c, i, memory_order_relaxed);
1584
0
    return ret + i;
1585
0
}
1586
1587
unsigned int wolfSSL_Atomic_Uint_SubFetch(wolfSSL_Atomic_Uint* c,
1588
                                          unsigned int i)
1589
0
{
1590
0
    unsigned int ret = atomic_fetch_sub_explicit(c, i, memory_order_relaxed);
1591
0
    return ret - i;
1592
0
}
1593
1594
int wolfSSL_Atomic_Uint_CompareExchange(
1595
    wolfSSL_Atomic_Uint* c, unsigned int *expected_i, unsigned int new_i)
1596
0
{
1597
    /* For the success path, use full synchronization with barriers --
1598
     * "Sequentially-consistent ordering" -- so that all threads see the same
1599
     * "single total modification order of all atomic operations" -- but on
1600
     * failure we just need to be sure we acquire the value that changed out
1601
     * from under us.
1602
     */
1603
0
    return atomic_compare_exchange_strong_explicit(
1604
0
        c, expected_i, new_i, memory_order_seq_cst, memory_order_acquire);
1605
0
}
1606
1607
int wolfSSL_Atomic_Ptr_CompareExchange(
1608
    void * volatile *c, void **expected_ptr, void *new_ptr)
1609
0
{
1610
    /* use gcc-built-in __atomic_compare_exchange_n(), not
1611
     * atomic_compare_exchange_strong_explicit(), to sidestep _Atomic type
1612
     * requirements.
1613
     */
1614
0
     if (__atomic_compare_exchange_n(
1615
0
             c, expected_ptr, new_ptr,
1616
#ifdef WOLF_C89
1617
             0 /* weak */,
1618
#else
1619
0
             (_Bool)0 /* weak */,
1620
0
#endif
1621
0
             __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE))
1622
0
         return 1;
1623
0
     else
1624
0
         return 0;
1625
0
}
1626
1627
#elif defined(__GNUC__) && defined(__ATOMIC_RELAXED)
1628
/* direct calls using gcc-style compiler built-ins */
1629
1630
void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i)
1631
{
1632
    *c = i;
1633
}
1634
1635
void wolfSSL_Atomic_Uint_Init(wolfSSL_Atomic_Uint* c, unsigned int i)
1636
{
1637
    *c = i;
1638
}
1639
1640
int wolfSSL_Atomic_Int_FetchAdd(wolfSSL_Atomic_Int* c, int i)
1641
{
1642
    return __atomic_fetch_add(c, i, __ATOMIC_RELAXED);
1643
}
1644
1645
int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i)
1646
{
1647
    return __atomic_fetch_sub(c, i, __ATOMIC_RELAXED);
1648
}
1649
1650
int wolfSSL_Atomic_Int_AddFetch(wolfSSL_Atomic_Int* c, int i)
1651
{
1652
    return __atomic_add_fetch(c, i, __ATOMIC_RELAXED);
1653
}
1654
1655
int wolfSSL_Atomic_Int_SubFetch(wolfSSL_Atomic_Int* c, int i)
1656
{
1657
    return __atomic_sub_fetch(c, i, __ATOMIC_RELAXED);
1658
}
1659
1660
int wolfSSL_Atomic_Int_Exchange(wolfSSL_Atomic_Int* c, int new_i)
1661
{
1662
    return __atomic_exchange_n(c, new_i, __ATOMIC_SEQ_CST);
1663
}
1664
1665
int wolfSSL_Atomic_Int_CompareExchange(wolfSSL_Atomic_Int* c, int *expected_i,
1666
                                       int new_i)
1667
{
1668
    /* For the success path, use full synchronization with barriers --
1669
     * "Sequentially-consistent ordering" -- so that all threads see the same
1670
     * "single total modification order of all atomic operations" -- but on
1671
     * failure we just need to be sure we acquire the value that changed out
1672
     * from under us.
1673
     */
1674
    return __atomic_compare_exchange_n(c, expected_i, new_i, 0 /* weak */,
1675
                                       __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE);
1676
}
1677
1678
unsigned int wolfSSL_Atomic_Uint_FetchAdd(wolfSSL_Atomic_Uint* c,
1679
                                          unsigned int i)
1680
{
1681
    return __atomic_fetch_add(c, i, __ATOMIC_RELAXED);
1682
}
1683
1684
unsigned int wolfSSL_Atomic_Uint_FetchSub(wolfSSL_Atomic_Uint* c,
1685
                                          unsigned int i)
1686
{
1687
    return __atomic_fetch_sub(c, i, __ATOMIC_RELAXED);
1688
}
1689
1690
unsigned int wolfSSL_Atomic_Uint_AddFetch(wolfSSL_Atomic_Uint* c,
1691
                                          unsigned int i)
1692
{
1693
    return __atomic_add_fetch(c, i, __ATOMIC_RELAXED);
1694
}
1695
1696
unsigned int wolfSSL_Atomic_Uint_SubFetch(wolfSSL_Atomic_Uint* c,
1697
                                          unsigned int i)
1698
{
1699
    return __atomic_sub_fetch(c, i, __ATOMIC_RELAXED);
1700
}
1701
1702
int wolfSSL_Atomic_Uint_CompareExchange(
1703
    wolfSSL_Atomic_Uint* c, unsigned int *expected_i, unsigned int new_i)
1704
{
1705
    /* For the success path, use full synchronization with barriers --
1706
     * "Sequentially-consistent ordering" -- so that all threads see the same
1707
     * "single total modification order of all atomic operations" -- but on
1708
     * failure we just need to be sure we acquire the value that changed out
1709
     * from under us.
1710
     */
1711
    return __atomic_compare_exchange_n(
1712
        c, expected_i, new_i, 0 /* weak */, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE);
1713
}
1714
1715
int wolfSSL_Atomic_Ptr_CompareExchange(
1716
    void * volatile *c, void **expected_ptr, void *new_ptr)
1717
{
1718
    return __atomic_compare_exchange_n(
1719
        c, expected_ptr, new_ptr, 0 /* weak */,
1720
        __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE);
1721
}
1722
1723
#elif defined(_MSC_VER) && !defined(WOLFSSL_NOT_WINDOWS_API)
1724
1725
void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i)
1726
{
1727
    *c = i;
1728
}
1729
1730
void wolfSSL_Atomic_Uint_Init(wolfSSL_Atomic_Uint* c, unsigned int i)
1731
{
1732
    *c = i;
1733
}
1734
1735
int wolfSSL_Atomic_Int_FetchAdd(wolfSSL_Atomic_Int* c, int i)
1736
{
1737
    return (int)_InterlockedExchangeAdd(c, (long)i);
1738
}
1739
1740
int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i)
1741
{
1742
    return (int)_InterlockedExchangeAdd(c, (long)-i);
1743
}
1744
1745
int wolfSSL_Atomic_Int_AddFetch(wolfSSL_Atomic_Int* c, int i)
1746
{
1747
    int ret = (int)_InterlockedExchangeAdd(c, (long)i);
1748
    return ret + i;
1749
}
1750
1751
int wolfSSL_Atomic_Int_SubFetch(wolfSSL_Atomic_Int* c, int i)
1752
{
1753
    int ret = (int)_InterlockedExchangeAdd(c, (long)-i);
1754
    return ret - i;
1755
}
1756
1757
int wolfSSL_Atomic_Int_Exchange(wolfSSL_Atomic_Int* c, int new_i)
1758
{
1759
    long actual_i = InterlockedExchange(c, (long)new_i);
1760
    return (int)actual_i;
1761
}
1762
1763
int wolfSSL_Atomic_Int_CompareExchange(wolfSSL_Atomic_Int* c, int *expected_i,
1764
                                       int new_i)
1765
{
1766
    long actual_i = InterlockedCompareExchange(c, (long)new_i,
1767
                                               (long)*expected_i);
1768
    if (actual_i == (long)*expected_i) {
1769
        return 1;
1770
    }
1771
    else {
1772
        *expected_i = (int)actual_i;
1773
        return 0;
1774
    }
1775
}
1776
1777
unsigned int wolfSSL_Atomic_Uint_FetchAdd(wolfSSL_Atomic_Uint* c,
1778
                                          unsigned int i)
1779
{
1780
    return (unsigned int)_InterlockedExchangeAdd((wolfSSL_Atomic_Int *)c,
1781
                                                 (long)i);
1782
}
1783
1784
unsigned int wolfSSL_Atomic_Uint_FetchSub(wolfSSL_Atomic_Uint* c,
1785
                                          unsigned int i)
1786
{
1787
    return (unsigned int)_InterlockedExchangeAdd((wolfSSL_Atomic_Int *)c,
1788
                                                 -(long)i);
1789
}
1790
1791
unsigned int wolfSSL_Atomic_Uint_AddFetch(wolfSSL_Atomic_Uint* c,
1792
                                          unsigned int i)
1793
{
1794
    unsigned int ret = (unsigned int)_InterlockedExchangeAdd
1795
        ((wolfSSL_Atomic_Int *)c, (long)i);
1796
    return ret + i;
1797
}
1798
1799
unsigned int wolfSSL_Atomic_Uint_SubFetch(wolfSSL_Atomic_Uint* c,
1800
                                          unsigned int i)
1801
{
1802
    unsigned int ret = (unsigned int)_InterlockedExchangeAdd
1803
        ((wolfSSL_Atomic_Int *)c, -(long)i);
1804
    return ret - i;
1805
}
1806
1807
int wolfSSL_Atomic_Uint_CompareExchange(
1808
    wolfSSL_Atomic_Uint* c, unsigned int *expected_i, unsigned int new_i)
1809
{
1810
    long actual_i = InterlockedCompareExchange(
1811
        (wolfSSL_Atomic_Int *)c, (long)new_i, (long)*expected_i);
1812
    if (actual_i == (long)*expected_i) {
1813
        return 1;
1814
    }
1815
    else {
1816
        *expected_i = (unsigned int)actual_i;
1817
        return 0;
1818
    }
1819
}
1820
1821
int wolfSSL_Atomic_Ptr_CompareExchange(
1822
    void * volatile * c, void **expected_ptr, void *new_ptr)
1823
{
1824
#ifdef _WIN64
1825
    LONG64 actual_ptr = InterlockedCompareExchange64(
1826
        (LONG64 *)c, (LONG64)new_ptr, (LONG64)*expected_ptr);
1827
    if (actual_ptr == (LONG64)*expected_ptr) {
1828
        return 1;
1829
    }
1830
    else {
1831
        *expected_ptr = (void *)actual_ptr;
1832
        return 0;
1833
    }
1834
#else /* !_WIN64 */
1835
    LONG actual_ptr = InterlockedCompareExchange(
1836
        (LONG *)c, (LONG)new_ptr, (LONG)*expected_ptr);
1837
    if (actual_ptr == (LONG)*expected_ptr) {
1838
        return 1;
1839
    }
1840
    else {
1841
        *expected_ptr = (void *)actual_ptr;
1842
        return 0;
1843
    }
1844
#endif /* !_WIN64 */
1845
}
1846
1847
#endif
1848
1849
#endif /* WOLFSSL_ATOMIC_OPS */
1850
1851
#if !defined(SINGLE_THREADED)
1852
1853
void wolfSSL_RefWithMutexInit(wolfSSL_RefWithMutex* ref, int* err)
1854
5.35k
{
1855
5.35k
    int ret = wc_InitMutex(&ref->mutex);
1856
5.35k
    if (ret != 0) {
1857
0
        WOLFSSL_MSG("Failed to create mutex for reference counting!");
1858
0
    }
1859
5.35k
    ref->count = 1;
1860
1861
5.35k
    *err = ret;
1862
5.35k
}
1863
1864
void wolfSSL_RefWithMutexFree(wolfSSL_RefWithMutex* ref)
1865
5.30k
{
1866
5.30k
    if (wc_FreeMutex(&ref->mutex) != 0) {
1867
0
        WOLFSSL_MSG("Failed to free mutex of reference counting!");
1868
0
    }
1869
5.30k
    ref->count = 0;
1870
5.30k
}
1871
1872
void wolfSSL_RefWithMutexInc(wolfSSL_RefWithMutex* ref, int* err)
1873
96.7k
{
1874
96.7k
    int ret = wc_LockMutex(&ref->mutex);
1875
96.7k
    if (ret != 0) {
1876
0
        WOLFSSL_MSG("Failed to lock mutex for reference increment!");
1877
0
    }
1878
96.7k
    else {
1879
96.7k
        ref->count++;
1880
96.7k
        wc_UnLockMutex(&ref->mutex);
1881
96.7k
    }
1882
96.7k
    *err = ret;
1883
96.7k
}
1884
1885
void wolfSSL_RefWithMutexInc2(wolfSSL_RefWithMutex* ref, int *new_count,
1886
                              int* err)
1887
0
{
1888
0
    int ret = wc_LockMutex(&ref->mutex);
1889
0
    if (ret != 0) {
1890
0
        WOLFSSL_MSG("Failed to lock mutex for reference increment!");
1891
0
        *new_count = -1;
1892
0
    }
1893
0
    else {
1894
0
        *new_count = ++ref->count;
1895
0
        wc_UnLockMutex(&ref->mutex);
1896
0
    }
1897
0
    *err = ret;
1898
0
}
1899
1900
int wolfSSL_RefWithMutexLock(wolfSSL_RefWithMutex* ref)
1901
0
{
1902
0
    return wc_LockMutex(&ref->mutex);
1903
0
}
1904
1905
int wolfSSL_RefWithMutexUnlock(wolfSSL_RefWithMutex* ref)
1906
0
{
1907
0
    return wc_UnLockMutex(&ref->mutex);
1908
0
}
1909
1910
void wolfSSL_RefWithMutexDec(wolfSSL_RefWithMutex* ref, int* isZero, int* err)
1911
102k
{
1912
102k
    int ret = wc_LockMutex(&ref->mutex);
1913
102k
    if (ret != 0) {
1914
0
        WOLFSSL_MSG("Failed to lock mutex for reference decrement!");
1915
        /* Can't say count is zero. */
1916
0
        *isZero = 0;
1917
0
    }
1918
102k
    else {
1919
102k
        if (ref->count > 0) {
1920
102k
            ref->count--;
1921
102k
        }
1922
102k
        *isZero = (ref->count == 0);
1923
102k
        wc_UnLockMutex(&ref->mutex);
1924
102k
    }
1925
102k
    *err = ret;
1926
102k
}
1927
1928
void wolfSSL_RefWithMutexDec2(wolfSSL_RefWithMutex* ref, int* new_count,
1929
                              int* err)
1930
0
{
1931
0
    int ret = wc_LockMutex(&ref->mutex);
1932
0
    if (ret != 0) {
1933
0
        WOLFSSL_MSG("Failed to lock mutex for reference decrement!");
1934
0
        *new_count = -1;
1935
0
    }
1936
0
    else {
1937
0
        if (ref->count > 0) {
1938
0
            ref->count--;
1939
0
        }
1940
0
        *new_count = ref->count;
1941
0
        wc_UnLockMutex(&ref->mutex);
1942
0
    }
1943
0
    *err = ret;
1944
0
}
1945
#endif /* ! SINGLE_THREADED */
1946
1947
#if WOLFSSL_CRYPT_HW_MUTEX
1948
/* Mutex for protection of cryptography hardware */
1949
static wolfSSL_Mutex wcCryptHwMutex
1950
    WOLFSSL_MUTEX_INITIALIZER_CLAUSE(wcCryptHwMutex);
1951
#ifndef WOLFSSL_MUTEX_INITIALIZER
1952
static int wcCryptHwMutexInit = 0;
1953
#endif
1954
1955
int wolfSSL_CryptHwMutexInit(void)
1956
{
1957
    int ret = 0;
1958
#ifndef WOLFSSL_MUTEX_INITIALIZER
1959
    if (wcCryptHwMutexInit == 0) {
1960
        ret = wc_InitMutex(&wcCryptHwMutex);
1961
        if (ret == 0) {
1962
            wcCryptHwMutexInit = 1;
1963
        }
1964
    }
1965
#endif
1966
    return ret;
1967
}
1968
int wolfSSL_CryptHwMutexLock(void)
1969
{
1970
    /* Make sure HW Mutex has been initialized */
1971
    int ret = wolfSSL_CryptHwMutexInit();
1972
    if (ret == 0) {
1973
        ret = wc_LockMutex(&wcCryptHwMutex);
1974
    }
1975
    return ret;
1976
}
1977
int wolfSSL_CryptHwMutexUnLock(void)
1978
{
1979
    if (wcCryptHwMutexInit) {
1980
        return wc_UnLockMutex(&wcCryptHwMutex);
1981
    }
1982
    else {
1983
        return BAD_MUTEX_E;
1984
    }
1985
}
1986
#endif /* WOLFSSL_CRYPT_HW_MUTEX */
1987
1988
1989
#if WOLFSSL_CRYPT_HW_MUTEX && defined(WOLFSSL_ALGO_HW_MUTEX)
1990
/* Mutex for protection of cryptography hardware */
1991
#ifndef NO_RNG_MUTEX
1992
static wolfSSL_Mutex wcCryptHwRngMutex
1993
    WOLFSSL_MUTEX_INITIALIZER_CLAUSE(wcCryptHwRngMutex);
1994
#endif /* NO_RNG_MUTEX */
1995
#ifndef NO_AES_MUTEX
1996
static wolfSSL_Mutex wcCryptHwAesMutex
1997
    WOLFSSL_MUTEX_INITIALIZER_CLAUSE(wcCryptHwAesMutex);
1998
#endif /* NO_AES_MUTEX */
1999
#ifndef NO_HASH_MUTEX
2000
static wolfSSL_Mutex wcCryptHwHashMutex
2001
    WOLFSSL_MUTEX_INITIALIZER_CLAUSE(wcCryptHwHashMutex);
2002
#endif /* NO_HASH_MUTEX */
2003
#ifndef NO_PK_MUTEX
2004
static wolfSSL_Mutex wcCryptHwPkMutex
2005
    WOLFSSL_MUTEX_INITIALIZER_CLAUSE(wcCryptHwPkMutex);
2006
#endif /* NO_PK_MUTEX */
2007
2008
#ifndef WOLFSSL_MUTEX_INITIALIZER
2009
#ifndef NO_RNG_MUTEX
2010
static int wcCryptHwRngMutexInit = 0;
2011
#endif /* NO_RNG_MUTEX */
2012
#ifndef NO_AES_MUTEX
2013
static int wcCryptHwAesMutexInit = 0;
2014
#endif /* NO_AES_MUTEX */
2015
#ifndef NO_HASH_MUTEX
2016
static int wcCryptHwHashMutexInit = 0;
2017
#endif /* NO_HASH_MUTEX */
2018
#ifndef NO_PK_MUTEX
2019
static int wcCryptHwPkMutexInit = 0;
2020
#endif /* NO_PK_MUTEX */
2021
#endif /* WOLFSSL_MUTEX_INITIALIZER */
2022
2023
2024
/* Allows ability to switch to different mutex based on enum type */
2025
/* hw_mutex_algo, expects the dereferenced Ptrs to be set to NULL */
2026
static int hwAlgoPtrSet(hw_mutex_algo hwAlgo, wolfSSL_Mutex** wcHwAlgoMutexPtr,
2027
                                int** wcHwAlgoInitPtr)
2028
{
2029
    if (*wcHwAlgoMutexPtr != NULL || *wcHwAlgoInitPtr != NULL) {
2030
        return BAD_FUNC_ARG;
2031
    }
2032
    switch (hwAlgo) {
2033
        #ifndef NO_RNG_MUTEX
2034
        case rng_mutex:
2035
            *wcHwAlgoMutexPtr = &wcCryptHwRngMutex;
2036
            *wcHwAlgoInitPtr = &wcCryptHwRngMutexInit;
2037
            break;
2038
        #endif
2039
        #ifndef NO_AES_MUTEX
2040
        case aes_mutex:
2041
            *wcHwAlgoMutexPtr = &wcCryptHwAesMutex;
2042
            *wcHwAlgoInitPtr = &wcCryptHwAesMutexInit;
2043
            break;
2044
        #endif
2045
        #ifndef NO_HASH_MUTEX
2046
        case hash_mutex:
2047
            *wcHwAlgoMutexPtr = &wcCryptHwHashMutex;
2048
            *wcHwAlgoInitPtr = &wcCryptHwHashMutexInit;
2049
            break;
2050
        #endif
2051
        #ifndef NO_PK_MUTEX
2052
        case pk_mutex:
2053
            *wcHwAlgoMutexPtr = &wcCryptHwPkMutex;
2054
            *wcHwAlgoInitPtr = &wcCryptHwPkMutexInit;
2055
            break;
2056
        #endif
2057
        default:
2058
            return BAD_FUNC_ARG;
2059
    }
2060
    return 0;
2061
}
2062
2063
static int hwAlgoMutexInit(hw_mutex_algo hwAlgo)
2064
{
2065
    int ret = 0;
2066
#ifndef WOLFSSL_MUTEX_INITIALIZER
2067
    wolfSSL_Mutex* wcHwAlgoMutexPtr = NULL;
2068
    int* wcHwAlgoInitPtr = NULL;
2069
    ret = hwAlgoPtrSet(hwAlgo, &wcHwAlgoMutexPtr, &wcHwAlgoInitPtr);
2070
    if (ret != 0) {
2071
        return ret;
2072
    }
2073
    if (*wcHwAlgoInitPtr == 0) {
2074
        ret = wc_InitMutex(wcHwAlgoMutexPtr);
2075
        if (ret == 0) {
2076
            *wcHwAlgoInitPtr = 1;
2077
        }
2078
    }
2079
#endif
2080
    return ret;
2081
}
2082
2083
static int hwAlgoMutexLock(hw_mutex_algo hwAlgo)
2084
{
2085
    /* Make sure HW Mutex has been initialized */
2086
    int ret = 0;
2087
    wolfSSL_Mutex* wcHwAlgoMutexPtr = NULL;
2088
    int* wcHwAlgoInitPtr = NULL;
2089
    ret = hwAlgoPtrSet(hwAlgo, &wcHwAlgoMutexPtr, &wcHwAlgoInitPtr);
2090
    if (ret != 0) {
2091
        return ret;
2092
    }
2093
    ret = hwAlgoMutexInit(hwAlgo);
2094
    if (ret == 0) {
2095
        ret = wc_LockMutex(wcHwAlgoMutexPtr);
2096
    }
2097
    return ret;
2098
}
2099
2100
static int hwAlgoMutexUnLock(hw_mutex_algo hwAlgo)
2101
{
2102
    wolfSSL_Mutex* wcHwAlgoMutexPtr = NULL;
2103
    int* wcHwAlgoInitPtr = NULL;
2104
    if (hwAlgoPtrSet(hwAlgo, &wcHwAlgoMutexPtr, &wcHwAlgoInitPtr) != 0) {
2105
        return BAD_FUNC_ARG;
2106
    }
2107
    if (*wcHwAlgoInitPtr) {
2108
        return wc_UnLockMutex(wcHwAlgoMutexPtr);
2109
    }
2110
    else {
2111
        return BAD_MUTEX_E;
2112
    }
2113
}
2114
2115
/* Wrap around generic hwAlgo* functions and use correct */
2116
/* global mutex to determine if it can be unlocked/locked */
2117
#ifndef NO_RNG_MUTEX
2118
int wolfSSL_HwRngMutexInit(void)
2119
{
2120
    return hwAlgoMutexInit(rng_mutex);
2121
}
2122
int wolfSSL_HwRngMutexLock(void)
2123
{
2124
    return hwAlgoMutexLock(rng_mutex);
2125
}
2126
int wolfSSL_HwRngMutexUnLock(void)
2127
{
2128
    return hwAlgoMutexUnLock(rng_mutex);
2129
}
2130
#endif /* NO_RNG_MUTEX */
2131
2132
#ifndef NO_AES_MUTEX
2133
int wolfSSL_HwAesMutexInit(void)
2134
{
2135
    return hwAlgoMutexInit(aes_mutex);
2136
}
2137
int wolfSSL_HwAesMutexLock(void)
2138
{
2139
    return hwAlgoMutexLock(aes_mutex);
2140
}
2141
int wolfSSL_HwAesMutexUnLock(void)
2142
{
2143
    return hwAlgoMutexUnLock(aes_mutex);
2144
}
2145
#endif /* NO_AES_MUTEX */
2146
2147
#ifndef NO_HASH_MUTEX
2148
int wolfSSL_HwHashMutexInit(void)
2149
{
2150
    return hwAlgoMutexInit(hash_mutex);
2151
}
2152
int wolfSSL_HwHashMutexLock(void)
2153
{
2154
    return hwAlgoMutexLock(hash_mutex);
2155
}
2156
int wolfSSL_HwHashMutexUnLock(void)
2157
{
2158
    return hwAlgoMutexUnLock(hash_mutex);
2159
}
2160
#endif /* NO_HASH_MUTEX */
2161
2162
#ifndef NO_PK_MUTEX
2163
int wolfSSL_HwPkMutexInit(void)
2164
{
2165
    return hwAlgoMutexInit(pk_mutex);
2166
}
2167
int wolfSSL_HwPkMutexLock(void)
2168
{
2169
    return hwAlgoMutexLock(pk_mutex);
2170
}
2171
int wolfSSL_HwPkMutexUnLock(void)
2172
{
2173
    return hwAlgoMutexUnLock(pk_mutex);
2174
}
2175
#endif /* NO_PK_MUTEX */
2176
2177
#endif /* WOLFSSL_CRYPT_HW_MUTEX && defined(WOLFSSL_ALGO_HW_MUTEX) */
2178
2179
/* ---------------------------------------------------------------------------*/
2180
/* Mutex Ports */
2181
/* ---------------------------------------------------------------------------*/
2182
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
2183
    static mutex_cb*     compat_mutex_cb = NULL;
2184
2185
    /* Function that locks or unlocks a mutex based on the flag passed in.
2186
     *
2187
     * flag lock or unlock i.e. CRYPTO_LOCK
2188
     * type the type of lock to unlock or lock
2189
     * file name of the file calling
2190
     * line the line number from file calling
2191
     */
2192
    int wc_LockMutex_ex(int flag, int type, const char* file, int line)
2193
0
    {
2194
0
        if (compat_mutex_cb != NULL) {
2195
0
            compat_mutex_cb(flag, type, file, line);
2196
0
            return 0;
2197
0
        }
2198
0
        else {
2199
0
            WOLFSSL_MSG("Mutex call back function not set. Call wc_SetMutexCb");
2200
0
            return BAD_STATE_E;
2201
0
        }
2202
0
    }
2203
2204
2205
    /* Set the callback function to use for locking/unlocking mutex
2206
     *
2207
     * cb callback function to use
2208
     */
2209
    int wc_SetMutexCb(mutex_cb* cb)
2210
0
    {
2211
0
        compat_mutex_cb = cb;
2212
0
        return 0;
2213
0
    }
2214
2215
    /* Gets the current callback function in use for locking/unlocking mutex
2216
     *
2217
     */
2218
    mutex_cb* wc_GetMutexCb(void)
2219
0
    {
2220
0
        return compat_mutex_cb;
2221
0
    }
2222
#endif /* defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) */
2223
2224
#if defined(WC_MUTEX_OPS_INLINE)
2225
2226
    /* defined in headers */
2227
2228
#elif defined(SINGLE_THREADED)
2229
2230
    int wc_InitMutex(wolfSSL_Mutex* m)
2231
    {
2232
        (void)m;
2233
        return 0;
2234
    }
2235
2236
    int wc_FreeMutex(wolfSSL_Mutex *m)
2237
    {
2238
        (void)m;
2239
        return 0;
2240
    }
2241
2242
2243
    int wc_LockMutex(wolfSSL_Mutex *m)
2244
    {
2245
        (void)m;
2246
        return 0;
2247
    }
2248
2249
2250
    int wc_UnLockMutex(wolfSSL_Mutex *m)
2251
    {
2252
        (void)m;
2253
        return 0;
2254
    }
2255
2256
#elif defined(__WATCOMC__)
2257
2258
    int wc_InitMutex(wolfSSL_Mutex* m)
2259
    {
2260
    #ifdef __OS2__
2261
        DosCreateMutexSem( NULL, m, 0, FALSE );
2262
    #elif defined(__NT__)
2263
        InitializeCriticalSection(m);
2264
    #elif defined(__LINUX__)
2265
        if (pthread_mutex_init(m, NULL) )
2266
            return BAD_MUTEX_E;
2267
    #endif
2268
        return 0;
2269
    }
2270
2271
    int wc_FreeMutex(wolfSSL_Mutex* m)
2272
    {
2273
    #ifdef __OS2__
2274
        DosCloseMutexSem(*m);
2275
    #elif defined(__NT__)
2276
        DeleteCriticalSection(m);
2277
    #elif defined(__LINUX__)
2278
        if (pthread_mutex_destroy(m) )
2279
            return BAD_MUTEX_E;
2280
    #endif
2281
        return 0;
2282
    }
2283
2284
    int wc_LockMutex(wolfSSL_Mutex* m)
2285
    {
2286
    #ifdef __OS2__
2287
        DosRequestMutexSem(*m, SEM_INDEFINITE_WAIT);
2288
    #elif defined(__NT__)
2289
        EnterCriticalSection(m);
2290
    #elif defined(__LINUX__)
2291
        if (pthread_mutex_lock(m) )
2292
            return BAD_MUTEX_E;
2293
    #endif
2294
        return 0;
2295
    }
2296
2297
    int wc_UnLockMutex(wolfSSL_Mutex* m)
2298
    {
2299
    #ifdef __OS2__
2300
        DosReleaseMutexSem(*m);
2301
    #elif defined(__NT__)
2302
        LeaveCriticalSection(m);
2303
    #elif defined(__LINUX__)
2304
        if (pthread_mutex_unlock(m) )
2305
            return BAD_MUTEX_E;
2306
    #endif
2307
        return 0;
2308
    }
2309
2310
    #if defined(WOLFSSL_USE_RWLOCK) && defined(__LINUX__)
2311
2312
    int wc_InitRwLock(wolfSSL_RwLock* m)
2313
    {
2314
        if (pthread_rwlock_init(m, NULL) )
2315
             return BAD_MUTEX_E;
2316
        return 0;
2317
    }
2318
2319
    int wc_FreeRwLock(wolfSSL_RwLock* m)
2320
    {
2321
        if (pthread_rwlock_destroy(m) )
2322
            return BAD_MUTEX_E;
2323
        return 0;
2324
    }
2325
2326
    int wc_LockRwLock_Wr(wolfSSL_RwLock* m)
2327
    {
2328
        if (pthread_rwlock_wrlock(m) )
2329
            return BAD_MUTEX_E;
2330
        return 0;
2331
    }
2332
2333
    int wc_LockRwLock_Rd(wolfSSL_RwLock* m)
2334
    {
2335
        if (pthread_rwlock_rdlock(m) )
2336
            return BAD_MUTEX_E;
2337
        return 0;
2338
    }
2339
2340
    int wc_UnLockRwLock(wolfSSL_RwLock* m)
2341
    {
2342
        if (pthread_rwlock_unlock(m) == 0)
2343
            return BAD_MUTEX_E;
2344
        return 0;
2345
    }
2346
2347
    #endif
2348
2349
#elif defined(FREERTOS) || defined(FREERTOS_TCP) || \
2350
  defined(FREESCALE_FREE_RTOS)
2351
2352
    int wc_InitMutex(wolfSSL_Mutex* m)
2353
    {
2354
        int iReturn;
2355
2356
        *m = ( wolfSSL_Mutex ) xSemaphoreCreateMutex();
2357
        if( *m != NULL )
2358
            iReturn = 0;
2359
        else
2360
            iReturn = BAD_MUTEX_E;
2361
2362
        return iReturn;
2363
    }
2364
2365
    int wc_FreeMutex(wolfSSL_Mutex* m)
2366
    {
2367
        vSemaphoreDelete( *m );
2368
        return 0;
2369
    }
2370
2371
    int wc_LockMutex(wolfSSL_Mutex* m)
2372
    {
2373
        /* Assume an infinite block, or should there be zero block? */
2374
        xSemaphoreTake( *m, portMAX_DELAY );
2375
        return 0;
2376
    }
2377
2378
    int wc_UnLockMutex(wolfSSL_Mutex* m)
2379
    {
2380
        xSemaphoreGive( *m );
2381
        return 0;
2382
    }
2383
2384
#elif defined(RTTHREAD)
2385
2386
    int wc_InitMutex(wolfSSL_Mutex* m)
2387
    {
2388
        int iReturn;
2389
2390
        *m = ( wolfSSL_Mutex ) rt_mutex_create("mutex",RT_IPC_FLAG_FIFO);
2391
        if( *m != NULL )
2392
            iReturn = 0;
2393
        else
2394
            iReturn = BAD_MUTEX_E;
2395
2396
2397
        return iReturn;
2398
    }
2399
2400
    int wc_FreeMutex(wolfSSL_Mutex* m)
2401
    {
2402
        rt_mutex_delete( *m );
2403
        return 0;
2404
    }
2405
2406
2407
    int wc_LockMutex(wolfSSL_Mutex* m)
2408
    {
2409
        /* Assume an infinite block, or should there be zero block? */
2410
        return rt_mutex_take( *m, RT_WAITING_FOREVER );
2411
    }
2412
2413
    int wc_UnLockMutex(wolfSSL_Mutex* m)
2414
    {
2415
        return rt_mutex_release( *m );
2416
    }
2417
2418
#elif defined(WOLFSSL_SAFERTOS)
2419
2420
    int wc_InitMutex(wolfSSL_Mutex* m)
2421
    {
2422
        vSemaphoreCreateBinary(m->mutexBuffer, m->mutex);
2423
        if (m->mutex == NULL)
2424
            return BAD_MUTEX_E;
2425
2426
        return 0;
2427
    }
2428
2429
    int wc_FreeMutex(wolfSSL_Mutex* m)
2430
    {
2431
        (void)m;
2432
        return 0;
2433
    }
2434
2435
    int wc_LockMutex(wolfSSL_Mutex* m)
2436
    {
2437
        /* Assume an infinite block */
2438
        xSemaphoreTake(m->mutex, portMAX_DELAY);
2439
        return 0;
2440
    }
2441
2442
    int wc_UnLockMutex(wolfSSL_Mutex* m)
2443
    {
2444
        xSemaphoreGive(m->mutex);
2445
        return 0;
2446
    }
2447
2448
#elif defined(USE_WINDOWS_API) && !defined(WOLFSSL_PTHREADS)
2449
2450
    int wc_InitMutex(wolfSSL_Mutex* m)
2451
    {
2452
        InitializeCriticalSection(m);
2453
        return 0;
2454
    }
2455
2456
2457
    int wc_FreeMutex(wolfSSL_Mutex* m)
2458
    {
2459
        DeleteCriticalSection(m);
2460
        return 0;
2461
    }
2462
2463
2464
    int wc_LockMutex(wolfSSL_Mutex* m)
2465
    {
2466
        EnterCriticalSection(m);
2467
        return 0;
2468
    }
2469
2470
2471
    int wc_UnLockMutex(wolfSSL_Mutex* m)
2472
    {
2473
        LeaveCriticalSection(m);
2474
        return 0;
2475
    }
2476
2477
#elif defined(MAXQ10XX_MUTEX)
2478
    static pthread_mutex_t *wcCryptHwSharedMutexPtr;
2479
    static pthread_once_t key_once_own_hw_mutex = PTHREAD_ONCE_INIT;
2480
    static pthread_key_t key_own_hw_mutex;
2481
2482
    static void destruct_key(void *buf)
2483
    {
2484
        if (buf != NULL) {
2485
            XFREE(buf, NULL, DYNAMIC_TYPE_OS_BUF);
2486
        }
2487
    }
2488
2489
    static void make_key_own_hw_mutex(void)
2490
    {
2491
        (void)pthread_key_create(&key_own_hw_mutex, destruct_key);
2492
    }
2493
2494
    int wc_InitMutex(wolfSSL_Mutex* m)
2495
    {
2496
        int created = 0;
2497
        void *addr = NULL;
2498
2499
        if (m != &wcCryptHwMutex) {
2500
            if (pthread_mutex_init(m, 0) == 0) {
2501
                return 0;
2502
            }
2503
            return BAD_MUTEX_E;
2504
        }
2505
2506
        /* try to open mutex memory */
2507
        int shm_fd = shm_open("/maxq-mutex", O_RDWR, 0666);
2508
        if (shm_fd < 0) {
2509
            /* create mutex memory */
2510
            shm_fd = shm_open("/maxq-mutex", O_RDWR | O_CREAT | O_EXCL, 0666);
2511
            created = 1;
2512
        }
2513
2514
        if (shm_fd < 0) {
2515
            WOLFSSL_MSG("wc_InitMutex: shm_open() failed");
2516
            return BAD_MUTEX_E;
2517
        }
2518
2519
        if (ftruncate(shm_fd, sizeof(pthread_mutex_t))) {
2520
            WOLFSSL_MSG("wc_InitMutex: ftruncate() failed");
2521
            return BAD_MUTEX_E;
2522
        }
2523
2524
        addr = mmap(NULL, sizeof(pthread_mutex_t), PROT_READ | PROT_WRITE,
2525
                    MAP_SHARED, shm_fd, 0);
2526
2527
        if (addr == MAP_FAILED) {
2528
            WOLFSSL_MSG("wc_InitMutex: mmap() failed");
2529
            return BAD_MUTEX_E;
2530
        }
2531
2532
        wcCryptHwSharedMutexPtr = (pthread_mutex_t *)addr;
2533
2534
        if (close(shm_fd)) {
2535
            WOLFSSL_MSG("wc_InitMutex: close() failed");
2536
            return BAD_MUTEX_E;
2537
        }
2538
2539
        if (created) {
2540
            /* initialize mutex */
2541
            pthread_mutexattr_t attr;
2542
            if (pthread_mutexattr_init(&attr)) {
2543
                WOLFSSL_MSG("wc_InitMutex: pthread_mutexattr_init() failed");
2544
                return BAD_MUTEX_E;
2545
            }
2546
2547
            if (pthread_mutexattr_setpshared(&attr,
2548
                                             PTHREAD_PROCESS_SHARED)) {
2549
                WOLFSSL_MSG(
2550
                    "wc_InitMutex: pthread_mutexattr_setpshared() failed");
2551
                return BAD_MUTEX_E;
2552
            }
2553
2554
            if (pthread_mutex_init(wcCryptHwSharedMutexPtr, &attr)) {
2555
                WOLFSSL_MSG("wc_InitMutex: pthread_mutex_init() failed");
2556
                return BAD_MUTEX_E;
2557
            }
2558
        }
2559
2560
        if (pthread_once(&key_once_own_hw_mutex, make_key_own_hw_mutex)) {
2561
            WOLFSSL_MSG("wc_InitMutex: pthread_once() failed");
2562
            return BAD_MUTEX_E;
2563
        }
2564
2565
        return 0;
2566
    }
2567
2568
    int wc_FreeMutex(wolfSSL_Mutex* m)
2569
    {
2570
        void *key_ptr = NULL;
2571
        if (m != &wcCryptHwMutex) {
2572
            if (pthread_mutex_destroy(m) == 0) {
2573
                return 0;
2574
            }
2575
            return BAD_MUTEX_E;
2576
        }
2577
2578
        if (wcCryptHwSharedMutexPtr) {
2579
            if (munmap((void *)wcCryptHwSharedMutexPtr,
2580
                       sizeof(pthread_mutex_t))) {
2581
                WOLFSSL_MSG("wc_FreeMutex: munmap() failed");
2582
                return BAD_MUTEX_E;
2583
            }
2584
2585
            wcCryptHwSharedMutexPtr = NULL;
2586
        }
2587
2588
        key_ptr = pthread_getspecific(key_own_hw_mutex);
2589
        if (key_ptr) {
2590
            *((int *)key_ptr) = 0;
2591
        }
2592
2593
        return 0;
2594
    }
2595
2596
    static int maxq_LockMutex(wolfSSL_Mutex* m, int trylock)
2597
    {
2598
        void *key_ptr = NULL;
2599
        int ret = 0;
2600
2601
        if (m != &wcCryptHwMutex) {
2602
            if (pthread_mutex_lock(m) == 0) {
2603
                return 0;
2604
            }
2605
            return BAD_MUTEX_E;
2606
        }
2607
2608
        if (wcCryptHwSharedMutexPtr == NULL) {
2609
            return BAD_MUTEX_E;
2610
        }
2611
2612
        key_ptr = pthread_getspecific(key_own_hw_mutex);
2613
        if (key_ptr == NULL) {
2614
            key_ptr = XMALLOC(sizeof(int), NULL, DYNAMIC_TYPE_OS_BUF);
2615
            if (key_ptr == NULL) {
2616
                return MEMORY_E;
2617
            }
2618
2619
            memset(key_ptr, 0, sizeof(int));
2620
2621
            if (pthread_setspecific(key_own_hw_mutex, key_ptr)) {
2622
                return THREAD_STORE_SET_E;
2623
            }
2624
        }
2625
        else {
2626
            if ((trylock == 0) && (*((int *)key_ptr) > 0)) {
2627
                *((int *)key_ptr) = *((int *)key_ptr) + 1;
2628
                return 0;
2629
            }
2630
        }
2631
2632
        if (trylock) {
2633
            ret = pthread_mutex_trylock(wcCryptHwSharedMutexPtr);
2634
        }
2635
        else {
2636
            ret = pthread_mutex_lock(wcCryptHwSharedMutexPtr);
2637
        }
2638
2639
        if (ret != 0) {
2640
            return BAD_MUTEX_E;
2641
        }
2642
2643
        *((int *)key_ptr) = 1;
2644
        return 0;
2645
    }
2646
2647
    int wc_LockMutex(wolfSSL_Mutex* m)
2648
    {
2649
        return maxq_LockMutex(m, 0);
2650
    }
2651
2652
    int maxq_CryptHwMutexTryLock()
2653
    {
2654
        /* Make sure HW Mutex has been initialized */
2655
        int ret = wolfSSL_CryptHwMutexInit();
2656
        if (ret == 0) {
2657
            ret = maxq_LockMutex(&wcCryptHwMutex, 1);
2658
        }
2659
        return ret;
2660
    }
2661
2662
    int wc_UnLockMutex(wolfSSL_Mutex* m)
2663
    {
2664
        void *key_ptr = NULL;
2665
2666
        if (m != &wcCryptHwMutex) {
2667
            if (pthread_mutex_unlock(m) == 0) {
2668
                return 0;
2669
            }
2670
            return BAD_MUTEX_E;
2671
        }
2672
2673
        if (wcCryptHwSharedMutexPtr == NULL) {
2674
            return BAD_MUTEX_E;
2675
        }
2676
2677
        key_ptr = pthread_getspecific(key_own_hw_mutex);
2678
        if (key_ptr) {
2679
            if (*((int *)key_ptr) > 0) {
2680
                *((int *)key_ptr) = *((int *)key_ptr) - 1;
2681
                if (*((int *)key_ptr) > 0) {
2682
                    return 0;
2683
                }
2684
            }
2685
        }
2686
2687
        if (pthread_mutex_unlock(wcCryptHwSharedMutexPtr) != 0) {
2688
            return BAD_MUTEX_E;
2689
        }
2690
        return 0;
2691
    }
2692
2693
#elif defined(WOLFSSL_PTHREADS)
2694
2695
    #ifdef WOLFSSL_USE_RWLOCK
2696
        int wc_InitRwLock(wolfSSL_RwLock* m)
2697
        {
2698
            if (pthread_rwlock_init(m, NULL) == 0)
2699
                return 0;
2700
            else
2701
                return BAD_MUTEX_E;
2702
        }
2703
2704
        int wc_FreeRwLock(wolfSSL_RwLock* m)
2705
        {
2706
            if (pthread_rwlock_destroy(m) == 0)
2707
                return 0;
2708
            else
2709
                return BAD_MUTEX_E;
2710
        }
2711
2712
        int wc_LockRwLock_Wr(wolfSSL_RwLock* m)
2713
        {
2714
            if (pthread_rwlock_wrlock(m) == 0)
2715
                return 0;
2716
            else
2717
                return BAD_MUTEX_E;
2718
        }
2719
2720
        int wc_LockRwLock_Rd(wolfSSL_RwLock* m)
2721
        {
2722
            if (pthread_rwlock_rdlock(m) == 0)
2723
                return 0;
2724
            else
2725
                return BAD_MUTEX_E;
2726
        }
2727
2728
        int wc_UnLockRwLock(wolfSSL_RwLock* m)
2729
        {
2730
            if (pthread_rwlock_unlock(m) == 0)
2731
                return 0;
2732
            else
2733
                return BAD_MUTEX_E;
2734
        }
2735
    #endif
2736
2737
    int wc_InitMutex(wolfSSL_Mutex* m)
2738
16.1k
    {
2739
16.1k
        if (pthread_mutex_init(m, NULL) == 0)
2740
16.1k
            return 0;
2741
0
        else
2742
0
            return BAD_MUTEX_E;
2743
16.1k
    }
2744
2745
2746
    int wc_FreeMutex(wolfSSL_Mutex* m)
2747
15.9k
    {
2748
15.9k
        if (pthread_mutex_destroy(m) == 0)
2749
15.9k
            return 0;
2750
0
        else
2751
0
            return BAD_MUTEX_E;
2752
15.9k
    }
2753
2754
2755
    int wc_LockMutex(wolfSSL_Mutex* m)
2756
381k
    {
2757
381k
        if (pthread_mutex_lock(m) == 0)
2758
380k
            return 0;
2759
663
        else
2760
663
            return BAD_MUTEX_E;
2761
381k
    }
2762
2763
2764
    int wc_UnLockMutex(wolfSSL_Mutex* m)
2765
380k
    {
2766
380k
        if (pthread_mutex_unlock(m) == 0)
2767
380k
            return 0;
2768
0
        else
2769
0
            return BAD_MUTEX_E;
2770
380k
    }
2771
#elif defined(WOLFSSL_VXWORKS)
2772
2773
    int wc_InitMutex(wolfSSL_Mutex* m)
2774
    {
2775
        if (m) {
2776
            if ((*m = semMCreate(0)) != SEM_ID_NULL)
2777
                return 0;
2778
        }
2779
        return BAD_MUTEX_E;
2780
    }
2781
2782
2783
    int wc_FreeMutex(wolfSSL_Mutex* m)
2784
    {
2785
        if (m) {
2786
            if (semDelete(*m) == OK)
2787
                return 0;
2788
        }
2789
        return BAD_MUTEX_E;
2790
    }
2791
2792
2793
    int wc_LockMutex(wolfSSL_Mutex* m)
2794
    {
2795
        if (m) {
2796
            if (semTake(*m, WAIT_FOREVER) == OK)
2797
                return 0;
2798
        }
2799
        return BAD_MUTEX_E;
2800
    }
2801
2802
2803
    int wc_UnLockMutex(wolfSSL_Mutex* m)
2804
    {
2805
        if (m) {
2806
            if (semGive(*m) == OK)
2807
                return 0;
2808
        }
2809
        return BAD_MUTEX_E;
2810
    }
2811
2812
#elif defined(THREADX)
2813
2814
    int wc_InitMutex(wolfSSL_Mutex* m)
2815
    {
2816
        if (tx_mutex_create(m, (CHAR*)"wolfSSL Mutex", TX_NO_INHERIT) == 0)
2817
            return 0;
2818
        else
2819
            return BAD_MUTEX_E;
2820
    }
2821
2822
2823
    int wc_FreeMutex(wolfSSL_Mutex* m)
2824
    {
2825
        if (tx_mutex_delete(m) == 0)
2826
            return 0;
2827
        else
2828
            return BAD_MUTEX_E;
2829
    }
2830
2831
2832
    int wc_LockMutex(wolfSSL_Mutex* m)
2833
    {
2834
        if (tx_mutex_get(m, TX_WAIT_FOREVER) == 0)
2835
            return 0;
2836
        else
2837
            return BAD_MUTEX_E;
2838
    }
2839
2840
    int wc_UnLockMutex(wolfSSL_Mutex* m)
2841
    {
2842
        if (tx_mutex_put(m) == 0)
2843
            return 0;
2844
        else
2845
            return BAD_MUTEX_E;
2846
    }
2847
2848
#elif defined(WOLFSSL_DEOS)
2849
2850
    int wc_InitMutex(wolfSSL_Mutex* m)
2851
    {
2852
        mutexStatus mutStat;
2853
        /*
2854
        The empty string "" denotes an anonymous mutex, so objects do not cause name collisions.
2855
        `protectWolfSSLTemp` in an XML configuration element template describing a mutex.
2856
        */
2857
        if (m) {
2858
            mutStat = createMutex("", "protectWolfSSLTemp", m);
2859
            if (mutStat == mutexSuccess)
2860
                return 0;
2861
            else{
2862
                WOLFSSL_MSG("wc_InitMutex failed");
2863
                return mutStat;
2864
            }
2865
        }
2866
        return BAD_MUTEX_E;
2867
    }
2868
2869
    int wc_FreeMutex(wolfSSL_Mutex* m)
2870
    {
2871
        mutexStatus mutStat;
2872
        if (m) {
2873
            mutStat = deleteMutex(*m);
2874
            if (mutStat == mutexSuccess)
2875
                return 0;
2876
            else{
2877
                WOLFSSL_MSG("wc_FreeMutex failed");
2878
                return mutStat;
2879
            }
2880
        }
2881
        return BAD_MUTEX_E;
2882
    }
2883
2884
    int wc_LockMutex(wolfSSL_Mutex* m)
2885
    {
2886
        mutexStatus mutStat;
2887
        if (m) {
2888
            mutStat = lockMutex(*m);
2889
            if (mutStat == mutexSuccess)
2890
                return 0;
2891
            else{
2892
                WOLFSSL_MSG("wc_LockMutex failed");
2893
                return mutStat;
2894
            }
2895
        }
2896
        return BAD_MUTEX_E;
2897
    }
2898
2899
    int wc_UnLockMutex(wolfSSL_Mutex* m)
2900
    {
2901
        mutexStatus mutStat;
2902
        if (m) {
2903
            mutStat = unlockMutex(*m);
2904
            if (mutStat== mutexSuccess)
2905
                return 0;
2906
            else{
2907
                WOLFSSL_MSG("wc_UnLockMutex failed");
2908
                return mutStat;
2909
            }
2910
        }
2911
        return BAD_MUTEX_E;
2912
    }
2913
2914
#elif defined(MICRIUM)
2915
    #if (OS_VERSION < 50000)
2916
        #define MICRIUM_ERR_TYPE OS_ERR
2917
        #define MICRIUM_ERR_NONE OS_ERR_NONE
2918
        #define MICRIUM_ERR_CODE(err) err
2919
    #else
2920
        #define MICRIUM_ERR_TYPE RTOS_ERR
2921
        #define MICRIUM_ERR_NONE RTOS_ERR_NONE
2922
        #define MICRIUM_ERR_CODE(err)    RTOS_ERR_CODE_GET(err)
2923
    #endif
2924
2925
    int wc_InitMutex(wolfSSL_Mutex* m)
2926
    {
2927
        MICRIUM_ERR_TYPE err;
2928
2929
        OSMutexCreate(m, "wolfSSL Mutex", &err);
2930
2931
        if (MICRIUM_ERR_CODE(err) == MICRIUM_ERR_NONE)
2932
            return 0;
2933
        else
2934
            return BAD_MUTEX_E;
2935
    }
2936
2937
    int wc_FreeMutex(wolfSSL_Mutex* m)
2938
    {
2939
        #if (OS_CFG_MUTEX_DEL_EN == DEF_ENABLED)
2940
            MICRIUM_ERR_TYPE err;
2941
2942
            OSMutexDel(m, OS_OPT_DEL_ALWAYS, &err);
2943
2944
            if (MICRIUM_ERR_CODE(err) == MICRIUM_ERR_NONE)
2945
                return 0;
2946
            else
2947
                return BAD_MUTEX_E;
2948
        #else
2949
            (void)m;
2950
            return 0;
2951
        #endif
2952
    }
2953
2954
    int wc_LockMutex(wolfSSL_Mutex* m)
2955
    {
2956
        MICRIUM_ERR_TYPE err;
2957
2958
        OSMutexPend(m, 0, OS_OPT_PEND_BLOCKING, NULL, &err);
2959
2960
        if (MICRIUM_ERR_CODE(err) == MICRIUM_ERR_NONE)
2961
            return 0;
2962
        else
2963
            return BAD_MUTEX_E;
2964
    }
2965
2966
    int wc_UnLockMutex(wolfSSL_Mutex* m)
2967
    {
2968
        MICRIUM_ERR_TYPE err;
2969
2970
        OSMutexPost(m, OS_OPT_POST_NONE, &err);
2971
2972
        if (MICRIUM_ERR_CODE(err) == MICRIUM_ERR_NONE)
2973
            return 0;
2974
        else
2975
            return BAD_MUTEX_E;
2976
    }
2977
2978
#elif defined(EBSNET)
2979
    #if (defined(RTPLATFORM) && (RTPLATFORM != 0))
2980
    int wc_InitMutex(wolfSSL_Mutex* m)
2981
    {
2982
        if (rtp_sig_mutex_alloc(m, "wolfSSL Mutex") == -1)
2983
            return BAD_MUTEX_E;
2984
        else
2985
            return 0;
2986
    }
2987
2988
    int wc_FreeMutex(wolfSSL_Mutex* m)
2989
    {
2990
        rtp_sig_mutex_free(*m);
2991
        return 0;
2992
    }
2993
2994
    int wc_LockMutex(wolfSSL_Mutex* m)
2995
    {
2996
        if (rtp_sig_mutex_claim_timed(*m, RTIP_INF) == 0)
2997
            return 0;
2998
        else
2999
            return BAD_MUTEX_E;
3000
    }
3001
3002
    int wc_UnLockMutex(wolfSSL_Mutex* m)
3003
    {
3004
        rtp_sig_mutex_release(*m);
3005
        return 0;
3006
    }
3007
3008
    int ebsnet_fseek(int a, long b, int c)
3009
    {
3010
        int retval;
3011
3012
        retval = vf_lseek(a, b, c);
3013
        if (retval > 0)
3014
            retval = 0;
3015
        else
3016
            retval =  -1;
3017
3018
        return(retval);
3019
    }
3020
    #else
3021
    static int rtip_semaphore_build(wolfSSL_Mutex *m)
3022
    {
3023
        KS_SEMAPHORE_BUILD(m)
3024
        return(RTP_TRUE);
3025
    }
3026
3027
    int wc_InitMutex(wolfSSL_Mutex* m)
3028
    {
3029
        if (rtip_semaphore_build(m) == RTP_FALSE)
3030
            return BAD_MUTEX_E;
3031
        else
3032
            return 0;
3033
    }
3034
3035
    int wc_FreeMutex(wolfSSL_Mutex* m)
3036
    {
3037
        KS_SEMAPHORE_FREE(*m);
3038
        return 0;
3039
    }
3040
3041
    int wc_LockMutex(wolfSSL_Mutex* m)
3042
    {
3043
        if (KS_SEMAPHORE_GET(*m))
3044
            return 0;
3045
        else
3046
            return BAD_MUTEX_E;
3047
    }
3048
3049
    int wc_UnLockMutex(wolfSSL_Mutex* m)
3050
    {
3051
        KS_SEMAPHORE_GIVE(*m);
3052
        return 0;
3053
    }
3054
    #endif
3055
    int ebsnet_fseek(int a, long b, int c)
3056
    {
3057
        int retval;
3058
3059
        retval = (int)vf_lseek(a, b, c);
3060
        if (retval > 0)
3061
            retval = 0;
3062
        else
3063
            retval =  -1;
3064
3065
        return(retval);
3066
    }
3067
3068
    int strcasecmp(const char *s1, const char *s2)
3069
    {
3070
        while (rtp_tolower(*s1) == rtp_tolower(*s2)) {
3071
            if (*s1 == '\0' || *s2 == '\0')
3072
                break;
3073
            s1++;
3074
            s2++;
3075
        }
3076
3077
        return rtp_tolower(*(unsigned char *) s1) -
3078
               rtp_tolower(*(unsigned char *) s2);
3079
    }
3080
3081
#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
3082
3083
    int wc_InitMutex(wolfSSL_Mutex* m)
3084
    {
3085
    #if (defined(HAVE_FIPS) && FIPS_VERSION_EQ(5,2))
3086
        if (wolfCrypt_GetMode_fips() == FIPS_MODE_INIT)
3087
            return 0;
3088
    #endif
3089
        if (_mutex_init(m, NULL) == MQX_EOK)
3090
            return 0;
3091
        else
3092
            return BAD_MUTEX_E;
3093
    }
3094
3095
    int wc_FreeMutex(wolfSSL_Mutex* m)
3096
    {
3097
        if (_mutex_destroy(m) == MQX_EOK)
3098
            return 0;
3099
        else
3100
            return BAD_MUTEX_E;
3101
    }
3102
3103
    int wc_LockMutex(wolfSSL_Mutex* m)
3104
    {
3105
    #if (defined(HAVE_FIPS) && FIPS_VERSION_EQ(5,2))
3106
        if (m->VALID != MUTEX_VALID) {
3107
            if (_mutex_init(m, NULL) != MQX_EOK)
3108
                return BAD_MUTEX_E;
3109
        }
3110
    #endif
3111
3112
        if (_mutex_lock(m) == MQX_EOK)
3113
            return 0;
3114
        else
3115
            return BAD_MUTEX_E;
3116
    }
3117
3118
    int wc_UnLockMutex(wolfSSL_Mutex* m)
3119
    {
3120
    #if (defined(HAVE_FIPS) && FIPS_VERSION_EQ(5,2))
3121
        if (m->VALID != MUTEX_VALID) {
3122
            if (_mutex_init(m, NULL) != MQX_EOK)
3123
                return BAD_MUTEX_E;
3124
        }
3125
    #endif
3126
3127
        if (_mutex_unlock(m) == MQX_EOK)
3128
            return 0;
3129
        else
3130
            return BAD_MUTEX_E;
3131
    }
3132
3133
#elif defined(WOLFSSL_TIRTOS)
3134
    #include <xdc/runtime/Error.h>
3135
3136
    int wc_InitMutex(wolfSSL_Mutex* m)
3137
    {
3138
        Semaphore_Params params;
3139
        Error_Block eb;
3140
3141
        Error_init(&eb);
3142
        Semaphore_Params_init(&params);
3143
        params.mode = Semaphore_Mode_BINARY;
3144
3145
        *m = Semaphore_create(1, &params, &eb);
3146
        if (Error_check(&eb)) {
3147
            Error_raise(&eb, Error_E_generic, "Failed to Create the semaphore.",
3148
                NULL);
3149
            return BAD_MUTEX_E;
3150
        }
3151
        else
3152
            return 0;
3153
    }
3154
3155
    int wc_FreeMutex(wolfSSL_Mutex* m)
3156
    {
3157
        Semaphore_delete(m);
3158
3159
        return 0;
3160
    }
3161
3162
    int wc_LockMutex(wolfSSL_Mutex* m)
3163
    {
3164
        Semaphore_pend(*m, BIOS_WAIT_FOREVER);
3165
3166
        return 0;
3167
    }
3168
3169
    int wc_UnLockMutex(wolfSSL_Mutex* m)
3170
    {
3171
        Semaphore_post(*m);
3172
3173
        return 0;
3174
    }
3175
3176
#elif defined(WOLFSSL_uITRON4)
3177
3178
    int wc_InitMutex(wolfSSL_Mutex* m)
3179
    {
3180
        int iReturn;
3181
        m->sem.sematr  = TA_TFIFO;
3182
        m->sem.isemcnt = 1;
3183
        m->sem.maxsem  = 1;
3184
        m->sem.name    = NULL;
3185
3186
        m->id = acre_sem(&m->sem);
3187
        if( m->id != E_OK )
3188
            iReturn = 0;
3189
        else
3190
            iReturn = BAD_MUTEX_E;
3191
3192
        return iReturn;
3193
    }
3194
3195
    int wc_FreeMutex(wolfSSL_Mutex* m)
3196
    {
3197
        del_sem( m->id );
3198
        return 0;
3199
    }
3200
3201
    int wc_LockMutex(wolfSSL_Mutex* m)
3202
    {
3203
        wai_sem(m->id);
3204
        return 0;
3205
    }
3206
3207
    int wc_UnLockMutex(wolfSSL_Mutex* m)
3208
    {
3209
        sig_sem(m->id);
3210
        return 0;
3211
    }
3212
3213
    /****  uITRON malloc/free ***/
3214
    static ID ID_wolfssl_MPOOL = 0;
3215
    static T_CMPL wolfssl_MPOOL = {TA_TFIFO, 0, NULL, "wolfSSL_MPOOL"};
3216
3217
    int uITRON4_minit(size_t poolsz) {
3218
        ER ercd;
3219
        wolfssl_MPOOL.mplsz = poolsz;
3220
        ercd = acre_mpl(&wolfssl_MPOOL);
3221
        if (ercd > 0) {
3222
            ID_wolfssl_MPOOL = ercd;
3223
            return 0;
3224
        } else {
3225
            return -1;
3226
        }
3227
    }
3228
3229
    void *uITRON4_malloc(size_t sz) {
3230
        ER ercd;
3231
        void *p = NULL;
3232
        ercd = get_mpl(ID_wolfssl_MPOOL, sz, (VP)&p);
3233
        if (ercd == E_OK) {
3234
            return p;
3235
        } else {
3236
            return 0;
3237
        }
3238
    }
3239
3240
    void *uITRON4_realloc(void *p, size_t sz) {
3241
      ER ercd;
3242
      void *newp = NULL;
3243
      if(p) {
3244
          ercd = get_mpl(ID_wolfssl_MPOOL, sz, (VP)&newp);
3245
          if ((ercd == E_OK) && (newp != NULL)) {
3246
              XMEMCPY(newp, p, sz);
3247
              ercd = rel_mpl(ID_wolfssl_MPOOL, (VP)p);
3248
              if (ercd == E_OK) {
3249
                  return newp;
3250
              }
3251
          }
3252
      }
3253
      return 0;
3254
    }
3255
3256
    void uITRON4_free(void *p) {
3257
        ER ercd;
3258
        ercd = rel_mpl(ID_wolfssl_MPOOL, (VP)p);
3259
        if (ercd == E_OK) {
3260
            return;
3261
        } else {
3262
            return;
3263
        }
3264
    }
3265
3266
#elif defined(WOLFSSL_uTKERNEL2)
3267
3268
    int wc_InitMutex(wolfSSL_Mutex* m)
3269
    {
3270
        int iReturn;
3271
        m->sem.sematr  = TA_TFIFO;
3272
        m->sem.isemcnt = 1;
3273
        m->sem.maxsem  = 1;
3274
3275
        m->id = tk_cre_sem(&m->sem);
3276
        if( m->id != NULL )
3277
            iReturn = 0;
3278
        else
3279
            iReturn = BAD_MUTEX_E;
3280
3281
        return iReturn;
3282
    }
3283
3284
    int wc_FreeMutex(wolfSSL_Mutex* m)
3285
    {
3286
        tk_del_sem(m->id);
3287
        return 0;
3288
    }
3289
3290
    int wc_LockMutex(wolfSSL_Mutex* m)
3291
    {
3292
        tk_wai_sem(m->id, 1, TMO_FEVR);
3293
        return 0;
3294
    }
3295
3296
    int wc_UnLockMutex(wolfSSL_Mutex* m)
3297
    {
3298
        tk_sig_sem(m->id, 1);
3299
        return 0;
3300
    }
3301
3302
    /****  uT-Kernel malloc/free ***/
3303
    static ID ID_wolfssl_MPOOL = 0;
3304
    static T_CMPL wolfssl_MPOOL = {
3305
        NULL,       /* Extended information */
3306
        TA_TFIFO,   /* Memory pool attribute */
3307
        0,          /* Size of whole memory pool (byte) */
3308
        "wolfSSL"   /* Object name (max 8-char) */
3309
    };
3310
3311
    int uTKernel_init_mpool(unsigned int sz) {
3312
        ER ercd;
3313
        wolfssl_MPOOL.mplsz = sz;
3314
        ercd = tk_cre_mpl(&wolfssl_MPOOL);
3315
        if (ercd > 0) {
3316
            ID_wolfssl_MPOOL = ercd;
3317
            return 0;
3318
        } else {
3319
            return (int)ercd;
3320
        }
3321
    }
3322
3323
    void *uTKernel_malloc(unsigned int sz) {
3324
        ER ercd;
3325
        void *p = NULL;
3326
        ercd = tk_get_mpl(ID_wolfssl_MPOOL, sz, (VP)&p, TMO_FEVR);
3327
        if (ercd == E_OK) {
3328
            return p;
3329
        } else {
3330
            return 0;
3331
        }
3332
    }
3333
3334
    void *uTKernel_realloc(void *p, unsigned int sz) {
3335
      ER ercd;
3336
      void *newp = NULL;
3337
      if (p) {
3338
          ercd = tk_get_mpl(ID_wolfssl_MPOOL, sz, (VP)&newp, TMO_FEVR);
3339
          if ((ercd == E_OK) && (newp != NULL)) {
3340
              XMEMCPY(newp, p, sz);
3341
              ercd = tk_rel_mpl(ID_wolfssl_MPOOL, (VP)p);
3342
              if (ercd == E_OK) {
3343
                  return newp;
3344
              }
3345
          }
3346
      }
3347
      return 0;
3348
    }
3349
3350
    void uTKernel_free(void *p) {
3351
        ER ercd;
3352
        ercd = tk_rel_mpl(ID_wolfssl_MPOOL, (VP)p);
3353
        if (ercd == E_OK) {
3354
            return;
3355
        } else {
3356
            return;
3357
        }
3358
    }
3359
3360
#elif defined (WOLFSSL_FROSTED)
3361
3362
    int wc_InitMutex(wolfSSL_Mutex* m)
3363
    {
3364
        *m = mutex_init();
3365
        if (*m)
3366
            return 0;
3367
        else
3368
            return -1;
3369
    }
3370
3371
    int wc_FreeMutex(wolfSSL_Mutex* m)
3372
    {
3373
        mutex_destroy(*m);
3374
        return(0);
3375
    }
3376
3377
    int wc_LockMutex(wolfSSL_Mutex* m)
3378
    {
3379
        mutex_lock(*m);
3380
        return 0;
3381
    }
3382
3383
    int wc_UnLockMutex(wolfSSL_Mutex* m)
3384
    {
3385
        mutex_unlock(*m);
3386
        return 0;
3387
    }
3388
3389
#elif defined(WOLFSSL_CMSIS_RTOS)
3390
3391
    #ifndef CMSIS_NMUTEX
3392
        #define CMSIS_NMUTEX 10
3393
    #endif
3394
    osMutexDef(wolfSSL_mt0);  osMutexDef(wolfSSL_mt1);  osMutexDef(wolfSSL_mt2);
3395
    osMutexDef(wolfSSL_mt3);  osMutexDef(wolfSSL_mt4);  osMutexDef(wolfSSL_mt5);
3396
    osMutexDef(wolfSSL_mt6);  osMutexDef(wolfSSL_mt7);  osMutexDef(wolfSSL_mt8);
3397
    osMutexDef(wolfSSL_mt9);
3398
3399
    static const osMutexDef_t *CMSIS_mutex[] = { osMutex(wolfSSL_mt0),
3400
        osMutex(wolfSSL_mt1),    osMutex(wolfSSL_mt2),   osMutex(wolfSSL_mt3),
3401
        osMutex(wolfSSL_mt4),    osMutex(wolfSSL_mt5),   osMutex(wolfSSL_mt6),
3402
        osMutex(wolfSSL_mt7),    osMutex(wolfSSL_mt8),   osMutex(wolfSSL_mt9) };
3403
3404
    static osMutexId CMSIS_mutexID[CMSIS_NMUTEX] = {0};
3405
3406
    int wc_InitMutex(wolfSSL_Mutex* m)
3407
    {
3408
        int i;
3409
3410
        if(!osKernelRunning()) {
3411
            return 0;
3412
        }
3413
3414
        for (i=0; i<CMSIS_NMUTEX; i++) {
3415
            if(CMSIS_mutexID[i] == 0) {
3416
                CMSIS_mutexID[i] = osMutexCreate(CMSIS_mutex[i]);
3417
                (*m) = CMSIS_mutexID[i];
3418
            return 0;
3419
            }
3420
        }
3421
        return -1;
3422
    }
3423
3424
    int wc_FreeMutex(wolfSSL_Mutex* m)
3425
    {
3426
        int i;
3427
3428
        if(!osKernelRunning()) {
3429
            return 0;
3430
        }
3431
3432
        osMutexDelete   (*m);
3433
        for (i=0; i<CMSIS_NMUTEX; i++) {
3434
            if(CMSIS_mutexID[i] == (*m)) {
3435
                CMSIS_mutexID[i] = 0;
3436
                return(0);
3437
            }
3438
        }
3439
        return(-1);
3440
    }
3441
3442
    int wc_LockMutex(wolfSSL_Mutex* m)
3443
    {
3444
        if(osKernelRunning()) {
3445
            osMutexWait(*m, osWaitForever);
3446
        }
3447
        return(0);
3448
    }
3449
3450
    int wc_UnLockMutex(wolfSSL_Mutex* m)
3451
    {
3452
        if(osKernelRunning()) {
3453
            osMutexRelease (*m);
3454
        }
3455
        return 0;
3456
    }
3457
3458
#elif defined(WOLFSSL_CMSIS_RTOSv2)
3459
    int wc_InitMutex(wolfSSL_Mutex *m)
3460
    {
3461
        static const osMutexAttr_t attr = {
3462
            "wolfSSL_mutex", osMutexRecursive, NULL, 0};
3463
3464
        if ((*m = osMutexNew(&attr)) != NULL)
3465
            return 0;
3466
        else
3467
            return BAD_MUTEX_E;
3468
    }
3469
3470
    int wc_FreeMutex(wolfSSL_Mutex *m)
3471
    {
3472
        if (osMutexDelete(*m) == osOK)
3473
            return 0;
3474
        else
3475
            return BAD_MUTEX_E;
3476
    }
3477
3478
3479
    int wc_LockMutex(wolfSSL_Mutex *m)
3480
    {
3481
        if (osMutexAcquire(*m, osWaitForever) == osOK)
3482
            return 0;
3483
        else
3484
            return BAD_MUTEX_E;
3485
    }
3486
3487
    int wc_UnLockMutex(wolfSSL_Mutex *m)
3488
    {
3489
        if (osMutexRelease(*m) == osOK)
3490
            return 0;
3491
        else
3492
            return BAD_MUTEX_E;
3493
    }
3494
3495
#elif defined(WOLFSSL_MDK_ARM)
3496
3497
    int wc_InitMutex(wolfSSL_Mutex* m)
3498
    {
3499
        os_mut_init (m);
3500
        return 0;
3501
    }
3502
3503
    int wc_FreeMutex(wolfSSL_Mutex* m)
3504
    {
3505
        return(0);
3506
    }
3507
3508
    int wc_LockMutex(wolfSSL_Mutex* m)
3509
    {
3510
        os_mut_wait (m, 0xffff);
3511
        return(0);
3512
    }
3513
3514
    int wc_UnLockMutex(wolfSSL_Mutex* m)
3515
    {
3516
        os_mut_release (m);
3517
        return 0;
3518
    }
3519
3520
#elif defined(INTIME_RTOS)
3521
3522
    int wc_InitMutex(wolfSSL_Mutex* m)
3523
    {
3524
        int ret = 0;
3525
3526
        if (m == NULL)
3527
            return BAD_FUNC_ARG;
3528
3529
        *m = CreateRtSemaphore(
3530
            1,                      /* initial unit count */
3531
            1,                      /* maximum unit count */
3532
            PRIORITY_QUEUING        /* creation flags: FIFO_QUEUING or PRIORITY_QUEUING */
3533
        );
3534
        if (*m == BAD_RTHANDLE) {
3535
            ret = GetLastRtError();
3536
            if (ret != E_OK)
3537
                ret = BAD_MUTEX_E;
3538
        }
3539
        return ret;
3540
    }
3541
3542
    int wc_FreeMutex(wolfSSL_Mutex* m)
3543
    {
3544
        int ret = 0;
3545
        BOOLEAN del;
3546
3547
        if (m == NULL)
3548
            return BAD_FUNC_ARG;
3549
3550
        del = DeleteRtSemaphore(
3551
            *m                      /* handle for RT semaphore */
3552
        );
3553
        if (del != TRUE)
3554
            ret = BAD_MUTEX_E;
3555
3556
        return ret;
3557
    }
3558
3559
    int wc_LockMutex(wolfSSL_Mutex* m)
3560
    {
3561
        int ret = 0;
3562
        DWORD lck;
3563
3564
        if (m == NULL)
3565
            return BAD_FUNC_ARG;
3566
3567
        lck = WaitForRtSemaphore(
3568
            *m,                     /* handle for RT semaphore */
3569
            1,                      /* number of units to wait for */
3570
            WAIT_FOREVER            /* number of milliseconds to wait for units */
3571
        );
3572
        if (lck == WAIT_FAILED) {
3573
            ret = GetLastRtError();
3574
            if (ret != E_OK)
3575
                ret = BAD_MUTEX_E;
3576
        }
3577
        return ret;
3578
    }
3579
3580
    int wc_UnLockMutex(wolfSSL_Mutex* m)
3581
    {
3582
        int ret = 0;
3583
        BOOLEAN rel;
3584
3585
        if (m == NULL)
3586
            return BAD_FUNC_ARG;
3587
3588
        rel = ReleaseRtSemaphore(
3589
            *m,                     /* handle for RT semaphore */
3590
            1                       /* number of units to release to semaphore */
3591
        );
3592
        if (rel != TRUE)
3593
            ret = BAD_MUTEX_E;
3594
3595
        return ret;
3596
    }
3597
3598
#elif defined(WOLFSSL_NUCLEUS_1_2)
3599
3600
    int wc_InitMutex(wolfSSL_Mutex* m)
3601
    {
3602
        /* Call the Nucleus function to create the semaphore */
3603
        if (NU_Create_Semaphore(m, "WOLFSSL_MTX", 1,
3604
                                NU_PRIORITY) == NU_SUCCESS) {
3605
            return 0;
3606
        }
3607
3608
        return BAD_MUTEX_E;
3609
    }
3610
3611
    int wc_FreeMutex(wolfSSL_Mutex* m)
3612
    {
3613
        if (NU_Delete_Semaphore(m) == NU_SUCCESS)
3614
            return 0;
3615
3616
        return BAD_MUTEX_E;
3617
    }
3618
3619
    int wc_LockMutex(wolfSSL_Mutex* m)
3620
    {
3621
        /* passing suspend task option */
3622
        if (NU_Obtain_Semaphore(m, NU_SUSPEND) == NU_SUCCESS)
3623
            return 0;
3624
3625
        return BAD_MUTEX_E;
3626
    }
3627
3628
    int wc_UnLockMutex(wolfSSL_Mutex* m)
3629
    {
3630
        if (NU_Release_Semaphore(m) == NU_SUCCESS)
3631
            return 0;
3632
3633
        return BAD_MUTEX_E;
3634
    }
3635
3636
#elif defined(WOLFSSL_ZEPHYR)
3637
3638
    int wc_InitMutex(wolfSSL_Mutex* m)
3639
    {
3640
        k_mutex_init(m);
3641
3642
        return 0;
3643
    }
3644
3645
    int wc_FreeMutex(wolfSSL_Mutex* m)
3646
    {
3647
        return 0;
3648
    }
3649
3650
    int wc_LockMutex(wolfSSL_Mutex* m)
3651
    {
3652
        int ret = 0;
3653
3654
        if (k_mutex_lock(m, K_FOREVER) != 0)
3655
            ret = BAD_MUTEX_E;
3656
3657
        return ret;
3658
    }
3659
3660
    int wc_UnLockMutex(wolfSSL_Mutex* m)
3661
    {
3662
        k_mutex_unlock(m);
3663
3664
        return 0;
3665
    }
3666
3667
#elif defined(WOLFSSL_TELIT_M2MB)
3668
3669
    int wc_InitMutex(wolfSSL_Mutex* m)
3670
    {
3671
        M2MB_OS_RESULT_E        osRes;
3672
        M2MB_OS_MTX_ATTR_HANDLE mtxAttrHandle;
3673
        UINT32                  inheritVal = 1;
3674
3675
        osRes = m2mb_os_mtx_setAttrItem(&mtxAttrHandle,
3676
                                    CMDS_ARGS(
3677
                                      M2MB_OS_MTX_SEL_CMD_CREATE_ATTR, NULL,
3678
                                      M2MB_OS_MTX_SEL_CMD_NAME, "wolfMtx",
3679
                                      M2MB_OS_MTX_SEL_CMD_INHERIT, inheritVal
3680
                                    )
3681
                                );
3682
        if (osRes != M2MB_OS_SUCCESS) {
3683
            return BAD_MUTEX_E;
3684
        }
3685
3686
        osRes = m2mb_os_mtx_init(m, &mtxAttrHandle);
3687
        if (osRes != M2MB_OS_SUCCESS) {
3688
            return BAD_MUTEX_E;
3689
        }
3690
3691
        return 0;
3692
    }
3693
3694
    int wc_FreeMutex(wolfSSL_Mutex* m)
3695
    {
3696
        M2MB_OS_RESULT_E osRes;
3697
3698
        if (m == NULL)
3699
            return BAD_MUTEX_E;
3700
3701
        osRes = m2mb_os_mtx_deinit(*m);
3702
        if (osRes != M2MB_OS_SUCCESS) {
3703
            return BAD_MUTEX_E;
3704
        }
3705
3706
        return 0;
3707
    }
3708
3709
    int wc_LockMutex(wolfSSL_Mutex* m)
3710
    {
3711
        M2MB_OS_RESULT_E osRes;
3712
3713
        if (m == NULL)
3714
            return BAD_MUTEX_E;
3715
3716
        osRes = m2mb_os_mtx_get(*m, M2MB_OS_WAIT_FOREVER);
3717
        if (osRes != M2MB_OS_SUCCESS) {
3718
            return BAD_MUTEX_E;
3719
        }
3720
3721
        return 0;
3722
    }
3723
3724
    int wc_UnLockMutex(wolfSSL_Mutex* m)
3725
    {
3726
        M2MB_OS_RESULT_E osRes;
3727
3728
        if (m == NULL)
3729
            return BAD_MUTEX_E;
3730
3731
        osRes = m2mb_os_mtx_put(*m);
3732
        if (osRes != M2MB_OS_SUCCESS) {
3733
            return BAD_MUTEX_E;
3734
        }
3735
3736
        return 0;
3737
    }
3738
3739
#elif defined(WOLFSSL_EMBOS)
3740
3741
    int wc_InitMutex(wolfSSL_Mutex* m)
3742
    {
3743
        int ret;
3744
3745
        OS_MUTEX_Create((OS_MUTEX*) m);
3746
        if (m != NULL)
3747
            ret = 0;
3748
        else
3749
            ret = BAD_MUTEX_E;
3750
3751
        return ret;
3752
    }
3753
3754
    int wc_FreeMutex(wolfSSL_Mutex* m)
3755
    {
3756
        OS_MUTEX_Delete((OS_MUTEX*) m);
3757
        return 0;
3758
    }
3759
3760
    int wc_LockMutex(wolfSSL_Mutex* m)
3761
    {
3762
        OS_MUTEX_LockBlocked((OS_MUTEX*) m);
3763
        return 0;
3764
    }
3765
3766
    int wc_UnLockMutex(wolfSSL_Mutex* m)
3767
    {
3768
        OS_MUTEX_Unlock((OS_MUTEX*) m);
3769
        return 0;
3770
    }
3771
3772
#elif defined(NETOS)
3773
3774
    int wc_InitMutex(wolfSSL_Mutex* m)
3775
    {
3776
        if (tx_mutex_create(&ready->mutex, "wolfSSL Lock", TX_INHERIT)
3777
                == TX_SUCCESS)
3778
            return 0;
3779
        else
3780
            return BAD_MUTEX_E;
3781
    }
3782
3783
    int wc_FreeMutex(wolfSSL_Mutex* m)
3784
    {
3785
        if (tx_mutex_delete(&ready->mutex) == TX_SUCCESS)
3786
            return 0;
3787
        else
3788
            return BAD_MUTEX_E;
3789
    }
3790
3791
    int wc_LockMutex(wolfSSL_Mutex* m)
3792
    {
3793
3794
    }
3795
3796
    int wc_UnLockMutex(wolfSSL_Mutex* m)
3797
    {
3798
3799
    }
3800
3801
#elif defined(WOLFSSL_USER_MUTEX)
3802
3803
    /* Use user own mutex */
3804
3805
    /*
3806
    int wc_InitMutex(wolfSSL_Mutex* m) { ... }
3807
    int wc_FreeMutex(wolfSSL_Mutex *m) { ... }
3808
    int wc_LockMutex(wolfSSL_Mutex *m) { ... }
3809
    int wc_UnLockMutex(wolfSSL_Mutex *m) { ... }
3810
    */
3811
3812
#else
3813
    #warning No mutex handling defined
3814
3815
#endif
3816
#if !defined(WOLFSSL_USE_RWLOCK) || defined(SINGLE_THREADED) || \
3817
    (defined(WC_MUTEX_OPS_INLINE) && !defined(WC_RWLOCK_OPS_INLINE))
3818
    int wc_InitRwLock(wolfSSL_RwLock* m)
3819
5.32k
    {
3820
5.32k
        return wc_InitMutex(m);
3821
5.32k
    }
3822
3823
    int wc_FreeRwLock(wolfSSL_RwLock* m)
3824
5.32k
    {
3825
5.32k
        return wc_FreeMutex(m);
3826
5.32k
    }
3827
3828
    int wc_LockRwLock_Wr(wolfSSL_RwLock* m)
3829
663
    {
3830
663
        return wc_LockMutex(m);
3831
663
    }
3832
3833
    int wc_LockRwLock_Rd(wolfSSL_RwLock* m)
3834
147
    {
3835
147
        return wc_LockMutex(m);
3836
147
    }
3837
3838
    int wc_UnLockRwLock(wolfSSL_RwLock* m)
3839
147
    {
3840
147
        return wc_UnLockMutex(m);
3841
147
    }
3842
#endif
3843
3844
#ifndef NO_ASN_TIME
3845
#if defined(_WIN32_WCE)
3846
time_t windows_time(time_t* timer)
3847
{
3848
    SYSTEMTIME     sysTime;
3849
    FILETIME       fTime;
3850
    ULARGE_INTEGER intTime;
3851
3852
3853
    GetSystemTime(&sysTime);
3854
    SystemTimeToFileTime(&sysTime, &fTime);
3855
3856
    XMEMCPY(&intTime, &fTime, sizeof(FILETIME));
3857
    /* subtract EPOCH */
3858
    intTime.QuadPart -= 0x19db1ded53e8000;
3859
    /* to secs */
3860
    intTime.QuadPart /= 10000000;
3861
3862
    if (timer != NULL)
3863
        *timer = (time_t)intTime.QuadPart;
3864
3865
    return (time_t)intTime.QuadPart;
3866
}
3867
#endif /*  _WIN32_WCE */
3868
3869
#if defined(WOLFSSL_APACHE_MYNEWT)
3870
#include "os/os_time.h"
3871
3872
time_t mynewt_time(time_t* timer)
3873
{
3874
    time_t now;
3875
    struct os_timeval tv;
3876
    os_gettimeofday(&tv, NULL);
3877
    now = (time_t)tv.tv_sec;
3878
    if(timer != NULL) {
3879
        *timer = now;
3880
    }
3881
    return now;
3882
}
3883
#endif /* WOLFSSL_APACHE_MYNEWT */
3884
3885
#if defined(WOLFSSL_GMTIME)
3886
struct tm* gmtime_r(const time_t* timer, struct tm *ret)
3887
{
3888
    #define YEAR0          1900
3889
    #define EPOCH_YEAR     1970
3890
    #define SECS_DAY       (24L * 60L * 60L)
3891
    #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400)))
3892
    #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
3893
3894
    static const int _ytab[2][12] =
3895
    {
3896
        {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
3897
        {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
3898
    };
3899
3900
    time_t secs = *timer;
3901
    unsigned long dayclock, dayno;
3902
    int year = EPOCH_YEAR;
3903
3904
    dayclock = (unsigned long)secs % SECS_DAY;
3905
    dayno    = (unsigned long)secs / SECS_DAY;
3906
3907
    ret->tm_sec  = (int) dayclock % 60;
3908
    ret->tm_min  = (int)(dayclock % 3600) / 60;
3909
    ret->tm_hour = (int) dayclock / 3600;
3910
    ret->tm_wday = (int) (dayno + 4) % 7;        /* day 0 a Thursday */
3911
3912
    while(dayno >= (unsigned long)YEARSIZE(year)) {
3913
        dayno -= YEARSIZE(year);
3914
        year++;
3915
    }
3916
3917
    ret->tm_year = year - YEAR0;
3918
    ret->tm_yday = (int)dayno;
3919
    ret->tm_mon  = 0;
3920
3921
    while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) {
3922
        dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon];
3923
        ret->tm_mon++;
3924
    }
3925
3926
    ret->tm_mday  = (int)++dayno;
3927
#ifndef WOLFSSL_LINUXKM
3928
    ret->tm_isdst = 0;
3929
#endif
3930
3931
    return ret;
3932
}
3933
3934
struct tm* gmtime(const time_t* timer) {
3935
    static struct tm st_time;
3936
    return gmtime_r(timer, &st_time);
3937
}
3938
3939
#endif /* WOLFSSL_GMTIME */
3940
3941
3942
#if defined(HAVE_RTP_SYS)
3943
#define YEAR0          1900
3944
3945
struct tm* rtpsys_gmtime(const time_t* timer)       /* has a gmtime() but hangs */
3946
{
3947
    static struct tm st_time;
3948
    struct tm* ret = &st_time;
3949
3950
    DC_RTC_CALENDAR cal;
3951
    dc_rtc_time_get(&cal, TRUE);
3952
3953
    ret->tm_year  = cal.year - YEAR0;       /* gm starts at 1900 */
3954
    ret->tm_mon   = cal.month - 1;          /* gm starts at 0 */
3955
    ret->tm_mday  = cal.day;
3956
    ret->tm_hour  = cal.hour;
3957
    ret->tm_min   = cal.minute;
3958
    ret->tm_sec   = cal.second;
3959
3960
    return ret;
3961
}
3962
3963
#endif /* HAVE_RTP_SYS */
3964
3965
3966
#if defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
3967
3968
/*
3969
 * time() is just a stub in Microchip libraries. We need our own
3970
 * implementation. Use SNTP client to get seconds since epoch.
3971
 */
3972
time_t pic32_time(time_t* timer)
3973
{
3974
#ifdef MICROCHIP_TCPIP_V5
3975
    DWORD sec = 0;
3976
#else
3977
    word32 sec = 0;
3978
#endif
3979
3980
#ifdef MICROCHIP_MPLAB_HARMONY
3981
    sec = TCPIP_SNTP_UTCSecondsGet();
3982
#else
3983
    sec = SNTPGetUTCSeconds();
3984
#endif
3985
3986
    if (timer != NULL)
3987
        *timer = (time_t)sec;
3988
3989
    return (time_t)sec;
3990
}
3991
3992
#endif /* MICROCHIP_TCPIP || MICROCHIP_TCPIP_V5 */
3993
3994
#if defined(WOLFSSL_DEOS) || defined(WOLFSSL_DEOS_RTEMS)
3995
3996
time_t deos_time(time_t* timer)
3997
{
3998
    const word32 systemTickTimeInHz = 1000000 / systemTickInMicroseconds();
3999
    const volatile word32 *systemTickPtr = systemTickPointer();
4000
4001
    if (timer != NULL)
4002
        *timer = *systemTickPtr/systemTickTimeInHz;
4003
4004
    #if defined(CURRENT_UNIX_TIMESTAMP)
4005
        /* CURRENT_UNIX_TIMESTAMP is seconds since Jan 01 1970. (UTC) */
4006
        return (time_t) (*systemTickPtr/systemTickTimeInHz) + CURRENT_UNIX_TIMESTAMP;
4007
    #else
4008
        return (time_t) *systemTickPtr/systemTickTimeInHz;
4009
    #endif
4010
}
4011
#endif /* WOLFSSL_DEOS || WOLFSSL_DEOS_RTEMS */
4012
4013
#if defined(FREESCALE_RTC)
4014
#include "fsl_rtc.h"
4015
time_t fsl_time(time_t* t)
4016
{
4017
    *t = RTC_GetSecondsTimerCount(RTC);
4018
    return *t;
4019
}
4020
#endif
4021
4022
#if defined(FREESCALE_SNVS_RTC)
4023
time_t fsl_time(time_t* t)
4024
{
4025
    struct tm tm_time;
4026
    time_t ret;
4027
4028
    snvs_hp_rtc_datetime_t rtcDate;
4029
    snvs_hp_rtc_config_t snvsRtcConfig;
4030
4031
    SNVS_HP_RTC_GetDefaultConfig(&snvsRtcConfig);
4032
    SNVS_HP_RTC_Init(SNVS, &snvsRtcConfig);
4033
4034
    SNVS_HP_RTC_GetDatetime(SNVS, &rtcDate);
4035
4036
    tm_time.tm_year  = rtcDate.year;
4037
    tm_time.tm_mon   = rtcDate.month;
4038
    tm_time.tm_mday  = rtcDate.day;
4039
    tm_time.tm_hour  = rtcDate.hour;
4040
    tm_time.tm_min   = rtcDate.minute;
4041
    tm_time.tm_sec   = rtcDate.second;
4042
4043
    ret = mktime(&tm_time);
4044
    if (t != NULL)
4045
        *t = ret;
4046
    return ret;
4047
}
4048
#endif
4049
4050
#if defined(MICRIUM)
4051
4052
time_t micrium_time(time_t* timer)
4053
{
4054
    CLK_TS_SEC sec;
4055
4056
    Clk_GetTS_Unix(&sec);
4057
4058
    if (timer != NULL)
4059
        *timer = sec;
4060
4061
    return (time_t) sec;
4062
}
4063
4064
#endif /* MICRIUM */
4065
4066
#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
4067
4068
time_t mqx_time(time_t* timer)
4069
{
4070
    TIME_STRUCT time_s;
4071
4072
    _time_get(&time_s);
4073
4074
    if (timer != NULL)
4075
        *timer = (time_t)time_s.SECONDS;
4076
4077
    return (time_t)time_s.SECONDS;
4078
}
4079
4080
#endif /* FREESCALE_MQX || FREESCALE_KSDK_MQX */
4081
4082
#if defined(MAX3266X_RTC)
4083
    #define XTIME wc_MXC_RTC_Time
4084
#endif
4085
4086
#if defined(WOLFSSL_TIRTOS) && defined(USER_TIME)
4087
4088
time_t XTIME(time_t * timer)
4089
{
4090
    time_t sec = 0;
4091
4092
    sec = (time_t) Seconds_get();
4093
4094
    if (timer != NULL)
4095
        *timer = sec;
4096
4097
    return sec;
4098
}
4099
4100
#endif /* WOLFSSL_TIRTOS */
4101
4102
#if defined(WOLFSSL_XILINX)
4103
#include "xrtcpsu.h"
4104
4105
time_t xilinx_time(time_t * timer)
4106
{
4107
    time_t sec = 0;
4108
    XRtcPsu_Config* con;
4109
    XRtcPsu         rtc;
4110
4111
    con = XRtcPsu_LookupConfig(XPAR_XRTCPSU_0_DEVICE_ID);
4112
    if (con != NULL) {
4113
        if (XRtcPsu_CfgInitialize(&rtc, con, con->BaseAddr) == XST_SUCCESS) {
4114
            sec = (time_t)XRtcPsu_GetCurrentTime(&rtc);
4115
        }
4116
        else {
4117
            WOLFSSL_MSG("Unable to initialize RTC");
4118
        }
4119
    }
4120
4121
    if (timer != NULL)
4122
        *timer = sec;
4123
4124
    return sec;
4125
}
4126
4127
#endif /* WOLFSSL_XILINX */
4128
4129
#if defined(WOLFSSL_ZEPHYR)
4130
4131
time_t z_time(time_t * timer)
4132
{
4133
    struct timespec ts;
4134
4135
    #if defined(CONFIG_RTC) && \
4136
        (defined(CONFIG_PICOLIBC) || defined(CONFIG_NEWLIB_LIBC))
4137
4138
    #if defined(CONFIG_BOARD_NATIVE_POSIX) || defined(CONFIG_BOARD_NATIVE_SIM)
4139
4140
    /* When using native sim, get time from simulator rtc */
4141
    uint32_t nsec = 0;
4142
    uint64_t sec = 0;
4143
    native_rtc_gettime(RTC_CLOCK_PSEUDOHOSTREALTIME, &nsec, &sec);
4144
4145
    if (timer != NULL)
4146
        *timer = sec;
4147
4148
    return sec;
4149
4150
    #else
4151
4152
    /* Try to obtain the actual time from an RTC */
4153
    static const struct device *rtc = DEVICE_DT_GET(DT_NODELABEL(rtc));
4154
4155
    if (device_is_ready(rtc)) {
4156
        struct rtc_time rtc_time;
4157
        struct tm *tm_time = rtc_time_to_tm(&rtc_time);
4158
4159
        int ret = rtc_get_time(rtc, &rtc_time);
4160
4161
        if (ret == 0) {
4162
            time_t epochTime = mktime(tm_time);
4163
4164
            if (timer != NULL)
4165
                *timer = epochTime;
4166
4167
            return epochTime;
4168
        }
4169
    }
4170
    #endif /* CONFIG_BOARD_NATIVE_POSIX || CONFIG_BOARD_NATIVE_SIM */
4171
    #endif
4172
4173
    /* Fallback to uptime since boot. This works for relative times, but
4174
     * not for ASN.1 date validation */
4175
    if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
4176
        if (timer != NULL)
4177
            *timer = ts.tv_sec;
4178
4179
    return ts.tv_sec;
4180
}
4181
4182
#endif /* WOLFSSL_ZEPHYR */
4183
4184
4185
#if defined(WOLFSSL_WICED)
4186
    #ifndef WOLFSSL_WICED_PSEUDO_UNIX_EPOCH_TIME
4187
        #error Please define WOLFSSL_WICED_PSEUDO_UNIX_EPOCH_TIME at build time.
4188
    #endif /* WOLFSSL_WICED_PSEUDO_UNIX_EPOCH_TIME */
4189
4190
time_t wiced_pseudo_unix_epoch_time(time_t * timer)
4191
{
4192
    time_t epoch_time;
4193
    /* The time() function return uptime on WICED platform. */
4194
    epoch_time = time(NULL) + WOLFSSL_WICED_PSEUDO_UNIX_EPOCH_TIME;
4195
4196
    if (timer != NULL) {
4197
        *timer = epoch_time;
4198
    }
4199
    return epoch_time;
4200
}
4201
#endif /* WOLFSSL_WICED */
4202
4203
#ifdef WOLFSSL_TELIT_M2MB
4204
    time_t m2mb_xtime(time_t * timer)
4205
    {
4206
        time_t myTime = 0;
4207
        INT32 fd = m2mb_rtc_open("/dev/rtc0", 0);
4208
        if (fd != -1) {
4209
            M2MB_RTC_TIMEVAL_T timeval;
4210
4211
            m2mb_rtc_ioctl(fd, M2MB_RTC_IOCTL_GET_TIMEVAL, &timeval);
4212
4213
            myTime = timeval.sec;
4214
4215
            m2mb_rtc_close(fd);
4216
        }
4217
        return myTime;
4218
    }
4219
    #ifdef WOLFSSL_TLS13
4220
    time_t m2mb_xtime_ms(time_t * timer)
4221
    {
4222
        time_t myTime = 0;
4223
        INT32 fd = m2mb_rtc_open("/dev/rtc0", 0);
4224
        if (fd != -1) {
4225
            M2MB_RTC_TIMEVAL_T timeval;
4226
4227
            m2mb_rtc_ioctl(fd, M2MB_RTC_IOCTL_GET_TIMEVAL, &timeval);
4228
4229
            myTime = timeval.sec + timeval.msec;
4230
4231
            m2mb_rtc_close(fd);
4232
        }
4233
        return myTime;
4234
    }
4235
    #endif /* WOLFSSL_TLS13 */
4236
    #ifndef NO_CRYPT_BENCHMARK
4237
    double m2mb_xtime_bench(int reset)
4238
    {
4239
        double myTime = 0;
4240
        INT32 fd = m2mb_rtc_open("/dev/rtc0", 0);
4241
        if (fd != -1) {
4242
            M2MB_RTC_TIMEVAL_T timeval;
4243
4244
            m2mb_rtc_ioctl(fd, M2MB_RTC_IOCTL_GET_TIMEVAL, &timeval);
4245
4246
            myTime = (double)timeval.sec + ((double)timeval.msec / 1000);
4247
4248
            m2mb_rtc_close(fd);
4249
        }
4250
        return myTime;
4251
    }
4252
    #endif /* !NO_CRYPT_BENCHMARK */
4253
#endif /* WOLFSSL_TELIT_M2MB */
4254
4255
4256
#if defined(WOLFSSL_LINUXKM)
4257
time_t time(time_t * timer)
4258
{
4259
    time_t ret;
4260
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
4261
    struct timespec ts;
4262
    getnstimeofday(&ts);
4263
    ret = ts.tv_sec;
4264
#else
4265
    struct timespec64 ts;
4266
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)
4267
    ts = current_kernel_time64();
4268
#else
4269
    ktime_get_coarse_real_ts64(&ts);
4270
#endif
4271
    ret = ts.tv_sec;
4272
#endif
4273
    if (timer)
4274
        *timer = ret;
4275
    return ret;
4276
}
4277
#endif /* WOLFSSL_LINUXKM */
4278
4279
#ifdef HAL_RTC_MODULE_ENABLED
4280
extern RTC_HandleTypeDef hrtc;
4281
time_t stm32_hal_time(time_t *t1)
4282
{
4283
    struct tm tm_time;
4284
    time_t ret;
4285
    RTC_TimeTypeDef time;
4286
    RTC_DateTypeDef date;
4287
4288
    XMEMSET(&tm_time, 0, sizeof(struct tm));
4289
4290
    /* order of GetTime followed by GetDate required here due to STM32 HW
4291
     * requirement */
4292
    HAL_RTC_GetTime(&hrtc, &time, FORMAT_BIN);
4293
    HAL_RTC_GetDate(&hrtc, &date, FORMAT_BIN);
4294
4295
    /* RTC year is 0-99 and "struct tm" is 1900+, so assume after year 2000 */
4296
    tm_time.tm_year  = date.Year + 100;
4297
    /* RTC month is 1-12 and "struct tm" is 0-12, so subtract 1 */
4298
    tm_time.tm_mon   = date.Month - 1;
4299
    tm_time.tm_mday  = date.Date;
4300
    tm_time.tm_hour  = time.Hours;
4301
    tm_time.tm_min   = time.Minutes;
4302
    tm_time.tm_sec   = time.Seconds;
4303
4304
    ret = mktime(&tm_time);
4305
    if (t1 != NULL)
4306
        *t1 = ret;
4307
    return ret;
4308
}
4309
#endif /* HAL_RTC_MODULE_ENABLED */
4310
4311
#endif /* !NO_ASN_TIME */
4312
4313
#if (!defined(WOLFSSL_LEANPSK) && !defined(STRING_USER)) || \
4314
    defined(USE_WOLF_STRNSTR)
4315
char* wolfSSL_strnstr(const char* s1, const char* s2, size_t n)
4316
63.2k
{
4317
63.2k
    size_t s2_len = XSTRLEN(s2);
4318
4319
63.2k
    if (s2_len == 0)
4320
0
        return (char *)(wc_ptr_t)s1;
4321
4322
11.1M
    while (n >= s2_len && s1[0]) {
4323
11.1M
        if (s1[0] == s2[0])
4324
569k
            if (XMEMCMP(s1, s2, s2_len) == 0)
4325
59.2k
                return (char *)(wc_ptr_t)s1;
4326
11.1M
        s1++;
4327
11.1M
        n--;
4328
11.1M
    }
4329
4330
4.05k
    return NULL;
4331
63.2k
}
4332
#endif
4333
4334
4335
/* custom memory wrappers */
4336
#ifdef WOLFSSL_NUCLEUS_1_2
4337
4338
    /* system memory pool */
4339
    extern NU_MEMORY_POOL System_Memory;
4340
4341
    void* nucleus_malloc(unsigned long size, void* heap, int type)
4342
    {
4343
        STATUS status;
4344
        void*  stack_ptr;
4345
4346
        status = NU_Allocate_Memory(&System_Memory, &stack_ptr, size,
4347
                                    NU_NO_SUSPEND);
4348
        if (status == NU_SUCCESS) {
4349
            return 0;
4350
        } else {
4351
            return stack_ptr;
4352
        }
4353
    }
4354
4355
    void* nucleus_realloc(void* ptr, unsigned long size, void* heap, int type)
4356
    {
4357
        DM_HEADER* old_header;
4358
        word32     old_size, copy_size;
4359
        void*      new_mem;
4360
4361
        /* if ptr is NULL, behave like malloc */
4362
        new_mem = nucleus_malloc(size, NULL, 0);
4363
        if (new_mem == 0 || ptr == 0) {
4364
            return new_mem;
4365
        }
4366
4367
        /* calculate old memory block size */
4368
        /* mem pointers stored in block headers (ref dm_defs.h) */
4369
        old_header = (DM_HEADER*) ((byte*)ptr - DM_OVERHEAD);
4370
        old_size   = (byte*)old_header->dm_next_memory - (byte*)ptr;
4371
4372
        /* copy old to new */
4373
        if (old_size < size) {
4374
            copy_size = old_size;
4375
        } else {
4376
            copy_size = size;
4377
        }
4378
        XMEMCPY(new_mem, ptr, copy_size);
4379
4380
        /* free old */
4381
        nucleus_free(ptr, NULL, 0);
4382
4383
        return new_mem;
4384
    }
4385
4386
    void nucleus_free(void* ptr, void* heap, int type)
4387
    {
4388
        if (ptr != NULL)
4389
            NU_Deallocate_Memory(ptr);
4390
    }
4391
4392
#endif /* WOLFSSL_NUCLEUS_1_2 */
4393
4394
#if defined(WOLFSSL_TI_CRYPT) || defined(WOLFSSL_TI_HASH)
4395
    #include <wolfcrypt/src/port/ti/ti-ccm.c>  /* initialize and Mutex for TI Crypt Engine */
4396
    #include <wolfcrypt/src/port/ti/ti-hash.c> /* md5, sha1, sha224, sha256 */
4397
#endif
4398
4399
#if defined(WOLFSSL_CRYPTOCELL)
4400
    #define WOLFSSL_CRYPTOCELL_C
4401
    #include <wolfcrypt/src/port/arm/cryptoCell.c> /* CC310, RTC and RNG */
4402
    #if !defined(NO_SHA256)
4403
        #define WOLFSSL_CRYPTOCELL_HASH_C
4404
        #include <wolfcrypt/src/port/arm/cryptoCellHash.c> /* sha256 */
4405
    #endif
4406
#endif
4407
4408
4409
#ifndef SINGLE_THREADED
4410
4411
/* Environment-specific multi-thread implementation check  */
4412
#if defined(__WATCOMC__)
4413
4414
    int wolfSSL_NewThread(THREAD_TYPE* thread,
4415
        THREAD_CB cb, void* arg)
4416
    {
4417
        if (thread == NULL || cb == NULL)
4418
            return BAD_FUNC_ARG;
4419
    #if defined(__OS2__)
4420
        *thread = _beginthread(cb, NULL, 0, arg);
4421
        if (*thread == INVALID_THREAD_VAL) {
4422
            return MEMORY_E;
4423
        }
4424
    #elif defined(__NT__)
4425
        /* Use _beginthreadex instead of _beginthread because of:
4426
         *   _beginthreadex is safer to use than _beginthread. If the thread
4427
         *   that's generated by _beginthread exits quickly, the handle that's
4428
         *   returned to the caller of _beginthread might be invalid or point
4429
         *   to another thread. However, the handle that's returned by
4430
         *   _beginthreadex has to be closed by the caller of _beginthreadex,
4431
         *   so it's guaranteed to be a valid handle if _beginthreadex didn't
4432
         *   return an error.*/
4433
        *thread = _beginthreadex(NULL, 0, cb, arg, 0, NULL);
4434
        if (*thread == 0) {
4435
            *thread = INVALID_THREAD_VAL;
4436
            return MEMORY_E;
4437
        }
4438
    #elif defined(__LINUX__)
4439
        if (pthread_create(thread, NULL, cb, arg))
4440
            return MEMORY_E;
4441
    #endif
4442
        return 0;
4443
    }
4444
4445
    int wolfSSL_JoinThread(THREAD_TYPE thread)
4446
    {
4447
        int ret = 0;
4448
4449
        if (thread == INVALID_THREAD_VAL)
4450
            return BAD_FUNC_ARG;
4451
    #if defined(__OS2__)
4452
        DosWaitThread(&thread, DCWW_WAIT);
4453
    #elif defined(__NT__)
4454
        /* We still want to attempt to close the thread handle even on error */
4455
        if (WaitForSingleObject((HANDLE)thread, INFINITE) == WAIT_FAILED)
4456
            ret = MEMORY_E;
4457
        if (CloseHandle((HANDLE)thread) == 0)
4458
            ret = MEMORY_E;
4459
    #elif defined(__LINUX__)
4460
        if (pthread_join(thread, NULL) != 0)
4461
            ret = MEMORY_E;
4462
    #endif
4463
        return ret;
4464
    }
4465
4466
    #if defined(WOLFSSL_THREAD_NO_JOIN)
4467
    int wolfSSL_NewThreadNoJoin(THREAD_CB_NOJOIN cb, void* arg)
4468
    {
4469
        THREAD_TYPE thread;
4470
        int ret = 0;
4471
4472
        if (cb == NULL)
4473
            return BAD_FUNC_ARG;
4474
    #if defined(__OS2__)
4475
        thread = _beginthread(cb, NULL, 0, arg);
4476
        if (thread == INVALID_THREAD_VAL)
4477
            ret = MEMORY_E;
4478
    #elif defined(__NT__)
4479
        thread = _beginthread(cb, 0, arg);
4480
        if (thread == -1L)
4481
            ret = MEMORY_E;
4482
    #elif defined(__LINUX__)
4483
        XMEMSET(&thread, 0, sizeof(thread));
4484
        ret = wolfSSL_NewThread(&thread, cb, arg);
4485
        if (ret == 0)
4486
            ret = pthread_detach(thread);
4487
    #endif
4488
        return ret;
4489
    }
4490
    #endif
4491
4492
    #ifdef WOLFSSL_COND
4493
    int wolfSSL_CondInit(COND_TYPE* cond)
4494
    {
4495
        if (cond == NULL)
4496
            return BAD_FUNC_ARG;
4497
    #if defined(__MACH__)
4498
        cond->cond = dispatch_semaphore_create(0);
4499
        if (cond->cond == NULL)
4500
            return MEMORY_E;
4501
4502
        /* dispatch_release() fails hard, with Trace/BPT trap signal, if the
4503
         * sem's internal count is less than the value passed in with
4504
         * dispatch_semaphore_create().  work around this by initializing
4505
         * with 0, then incrementing it afterwards.
4506
         */
4507
        if (dispatch_semaphore_signal(s->sem) < 0) {
4508
            dispatch_release(s->sem);
4509
            return MEMORY_E;
4510
        }
4511
    #elif defined(__OS2__)
4512
        DosCreateMutexSem( NULL, &cond->mutex, 0, FALSE );
4513
        DosCreateEventSem( NULL, &cond->cond, DCE_POSTONE, FALSE );
4514
    #elif defined(__NT__)
4515
        cond->cond = CreateEventA(NULL, FALSE, FALSE, NULL);
4516
        if (cond->cond == NULL)
4517
            return MEMORY_E;
4518
4519
        if (wc_InitMutex(&cond->mutex) != 0) {
4520
            if (CloseHandle(cond->cond) == 0)
4521
                return MEMORY_E;
4522
            return MEMORY_E;
4523
        }
4524
    #elif defined(__LINUX__)
4525
        if (pthread_mutex_init(&cond->mutex, NULL) != 0)
4526
            return MEMORY_E;
4527
4528
        if (pthread_cond_init(&cond->cond, NULL) != 0) {
4529
            /* Keep compilers happy that we are using the return code */
4530
            if (pthread_mutex_destroy(&cond->mutex) != 0)
4531
                return MEMORY_E;
4532
            return MEMORY_E;
4533
        }
4534
    #endif
4535
        return 0;
4536
    }
4537
4538
    int wolfSSL_CondFree(COND_TYPE* cond)
4539
    {
4540
        if (cond == NULL)
4541
            return BAD_FUNC_ARG;
4542
    #if defined(__MACH__)
4543
        dispatch_release(cond->cond);
4544
    #elif defined(__OS2__)
4545
        DosCloseMutexSem(cond->mutex);
4546
        DosCloseEventSem(cond->cond);
4547
    #elif defined(__NT__)
4548
        if (CloseHandle(cond->cond) == 0)
4549
            return MEMORY_E;
4550
    #elif defined(__LINUX__)
4551
        if (pthread_mutex_destroy(&cond->mutex) != 0)
4552
            return MEMORY_E;
4553
4554
        if (pthread_cond_destroy(&cond->cond) != 0)
4555
            return MEMORY_E;
4556
    #endif
4557
        return 0;
4558
    }
4559
4560
    int wolfSSL_CondStart(COND_TYPE* cond)
4561
    {
4562
        if (cond == NULL)
4563
            return BAD_FUNC_ARG;
4564
    #if defined(__MACH__)
4565
    #elif defined(__OS2__)
4566
    #elif defined(__NT__)
4567
        if (wc_LockMutex(&cond->mutex) != 0)
4568
            return BAD_MUTEX_E;
4569
    #elif defined(__LINUX__)
4570
        if (pthread_mutex_lock(&cond->mutex) != 0)
4571
            return BAD_MUTEX_E;
4572
    #endif
4573
        return 0;
4574
    }
4575
4576
    int wolfSSL_CondSignal(COND_TYPE* cond)
4577
    {
4578
        if (cond == NULL)
4579
            return BAD_FUNC_ARG;
4580
    #if defined(__MACH__)
4581
        dispatch_semaphore_signal(cond->cond);
4582
    #elif defined(__OS2__)
4583
    #elif defined(__NT__)
4584
        if (wc_UnLockMutex(&cond->mutex) != 0)
4585
            return BAD_MUTEX_E;
4586
4587
        if (SetEvent(cond->cond) == 0)
4588
            return MEMORY_E;
4589
4590
        if (wc_LockMutex(&cond->mutex) != 0)
4591
            return BAD_MUTEX_E;
4592
    #elif defined(__LINUX__)
4593
        if (pthread_cond_signal(&cond->cond) != 0)
4594
            return MEMORY_E;
4595
    #endif
4596
        return 0;
4597
    }
4598
4599
    int wolfSSL_CondWait(COND_TYPE* cond)
4600
    {
4601
        if (cond == NULL)
4602
            return BAD_FUNC_ARG;
4603
    #if defined(__MACH__)
4604
        dispatch_semaphore_wait(cond->cond, DISPATCH_TIME_FOREVER);
4605
    #elif defined(__OS2__)
4606
    #elif defined(__NT__)
4607
        if (wc_UnLockMutex(&cond->mutex) != 0)
4608
            return BAD_MUTEX_E;
4609
4610
        if (WaitForSingleObject(cond->cond, INFINITE) == WAIT_FAILED)
4611
            return MEMORY_E;
4612
4613
        if (wc_LockMutex(&cond->mutex) != 0)
4614
            return BAD_MUTEX_E;
4615
    #elif defined(__LINUX__)
4616
        if (pthread_cond_wait(&cond->cond, &cond->mutex) != 0)
4617
            return MEMORY_E;
4618
    #endif
4619
        return 0;
4620
    }
4621
4622
    int wolfSSL_CondEnd(COND_TYPE* cond)
4623
    {
4624
        if (cond == NULL)
4625
            return BAD_FUNC_ARG;
4626
    #if defined(__OS2__)
4627
    #elif defined(__NT__)
4628
        if (wc_UnLockMutex(&cond->mutex) != 0)
4629
            return BAD_MUTEX_E;
4630
    #elif defined(__LINUX__)
4631
        if (pthread_mutex_unlock(&cond->mutex) != 0)
4632
            return BAD_MUTEX_E;
4633
    #endif
4634
        return 0;
4635
    }
4636
    #endif /* WOLFSSL_COND */
4637
4638
4639
#elif defined(USE_WINDOWS_API) && !defined(WOLFSSL_PTHREADS) && \
4640
    !defined(_WIN32_WCE)
4641
    int wolfSSL_NewThread(THREAD_TYPE* thread,
4642
        THREAD_CB cb, void* arg)
4643
    {
4644
        if (thread == NULL || cb == NULL)
4645
            return BAD_FUNC_ARG;
4646
4647
        /* Use _beginthreadex instead of _beginthread because of:
4648
         *   _beginthreadex is safer to use than _beginthread. If the thread
4649
         *   that's generated by _beginthread exits quickly, the handle that's
4650
         *   returned to the caller of _beginthread might be invalid or point
4651
         *   to another thread. However, the handle that's returned by
4652
         *   _beginthreadex has to be closed by the caller of _beginthreadex,
4653
         *   so it's guaranteed to be a valid handle if _beginthreadex didn't
4654
         *   return an error.*/
4655
        *thread = _beginthreadex(NULL, 0, cb, arg, 0, NULL);
4656
        if (*thread == 0) {
4657
            *thread = INVALID_THREAD_VAL;
4658
            return MEMORY_E;
4659
        }
4660
4661
        return 0;
4662
    }
4663
4664
#ifdef WOLFSSL_THREAD_NO_JOIN
4665
    int wolfSSL_NewThreadNoJoin(THREAD_CB_NOJOIN cb, void* arg)
4666
    {
4667
        THREAD_TYPE thread;
4668
4669
        if (cb == NULL)
4670
            return BAD_FUNC_ARG;
4671
4672
        thread = _beginthread(cb, 0, arg);
4673
        if (thread == -1L) {
4674
            return MEMORY_E;
4675
        }
4676
4677
        return 0;
4678
    }
4679
#endif
4680
4681
    int wolfSSL_JoinThread(THREAD_TYPE thread)
4682
    {
4683
        int ret = 0;
4684
4685
        if (thread == INVALID_THREAD_VAL)
4686
            return BAD_FUNC_ARG;
4687
4688
        /* We still want to attempt to close the thread handle even on error */
4689
        if (WaitForSingleObject((HANDLE)thread, INFINITE) == WAIT_FAILED)
4690
            ret = MEMORY_E;
4691
4692
        if (CloseHandle((HANDLE)thread) == 0)
4693
            ret = MEMORY_E;
4694
4695
        return ret;
4696
    }
4697
4698
#ifdef WOLFSSL_COND
4699
    int wolfSSL_CondInit(COND_TYPE* cond)
4700
    {
4701
        if (cond == NULL)
4702
            return BAD_FUNC_ARG;
4703
4704
        cond->cond = CreateEventA(NULL, FALSE, FALSE, NULL);
4705
        if (cond->cond == NULL)
4706
            return MEMORY_E;
4707
4708
        if (wc_InitMutex(&cond->mutex) != 0) {
4709
            if (CloseHandle(cond->cond) == 0)
4710
                return MEMORY_E;
4711
            return MEMORY_E;
4712
        }
4713
4714
        return 0;
4715
    }
4716
4717
    int wolfSSL_CondFree(COND_TYPE* cond)
4718
    {
4719
        if (cond == NULL)
4720
            return BAD_FUNC_ARG;
4721
4722
        if (CloseHandle(cond->cond) == 0)
4723
            return MEMORY_E;
4724
4725
        return 0;
4726
    }
4727
4728
    int wolfSSL_CondStart(COND_TYPE* cond)
4729
    {
4730
        if (cond == NULL)
4731
            return BAD_FUNC_ARG;
4732
4733
        if (wc_LockMutex(&cond->mutex) != 0)
4734
            return BAD_MUTEX_E;
4735
4736
        return 0;
4737
    }
4738
4739
    int wolfSSL_CondSignal(COND_TYPE* cond)
4740
    {
4741
        if (cond == NULL)
4742
            return BAD_FUNC_ARG;
4743
4744
        if (wc_UnLockMutex(&cond->mutex) != 0)
4745
            return BAD_MUTEX_E;
4746
4747
        if (SetEvent(cond->cond) == 0)
4748
            return MEMORY_E;
4749
4750
        if (wc_LockMutex(&cond->mutex) != 0)
4751
            return BAD_MUTEX_E;
4752
4753
        return 0;
4754
    }
4755
4756
    int wolfSSL_CondWait(COND_TYPE* cond)
4757
    {
4758
        if (cond == NULL)
4759
            return BAD_FUNC_ARG;
4760
4761
        if (wc_UnLockMutex(&cond->mutex) != 0)
4762
            return BAD_MUTEX_E;
4763
4764
        if (WaitForSingleObject(cond->cond, INFINITE) == WAIT_FAILED)
4765
            return MEMORY_E;
4766
4767
        if (wc_LockMutex(&cond->mutex) != 0)
4768
            return BAD_MUTEX_E;
4769
4770
        return 0;
4771
    }
4772
4773
    int wolfSSL_CondEnd(COND_TYPE* cond)
4774
    {
4775
        if (cond == NULL)
4776
            return BAD_FUNC_ARG;
4777
4778
        if (wc_UnLockMutex(&cond->mutex) != 0)
4779
            return BAD_MUTEX_E;
4780
4781
        return 0;
4782
    }
4783
#endif /* WOLFSSL_COND */
4784
4785
#elif defined(WOLFSSL_TIRTOS)
4786
4787
    int wolfSSL_NewThread(THREAD_TYPE* thread,
4788
        THREAD_CB cb, void* arg)
4789
    {
4790
        /* Initialize the defaults and set the parameters. */
4791
        Task_Params taskParams;
4792
        Task_Params_init(&taskParams);
4793
        taskParams.arg0 = (UArg)arg;
4794
        taskParams.stackSize = 65535;
4795
        *thread = Task_create((Task_FuncPtr)cb, &taskParams, NULL);
4796
        if (*thread == NULL) {
4797
            return MEMORY_E;
4798
        }
4799
        Task_yield();
4800
        return 0;
4801
    }
4802
4803
    int wolfSSL_JoinThread(THREAD_TYPE thread)
4804
    {
4805
        while(1) {
4806
            if (Task_getMode(thread) == Task_Mode_TERMINATED) {
4807
                Task_sleep(5);
4808
                break;
4809
            }
4810
            Task_yield();
4811
        }
4812
        return 0;
4813
    }
4814
4815
#elif defined(NETOS)
4816
4817
    int wolfSSL_NewThread(THREAD_TYPE* thread,
4818
        THREAD_CB cb, void* arg)
4819
    {
4820
        /* For backwards compatibility allow using this declaration as well. */
4821
        #ifdef TESTSUITE_THREAD_STACK_SZ
4822
            #define WOLFSSL_NETOS_STACK_SZ TESTSUITE_THREAD_STACK_SZ
4823
        #endif
4824
        /* This can be adjusted by defining in user_settings.h, will default to
4825
         * 65k in the event it is undefined */
4826
        #ifndef WOLFSSL_NETOS_STACK_SZ
4827
            #define WOLFSSL_NETOS_STACK_SZ 65535
4828
        #endif
4829
        int result;
4830
4831
        if (thread == NULL || cb == NULL)
4832
            return BAD_FUNC_ARG;
4833
4834
        XMEMSET(thread, 0, sizeof(*thread));
4835
4836
        thread->threadStack = (void *)XMALLOC(WOLFSSL_NETOS_STACK_SZ, NULL,
4837
                DYNAMIC_TYPE_OS_BUF);
4838
        if (thread->threadStack == NULL)
4839
            return MEMORY_E;
4840
4841
4842
        /* first create the idle thread:
4843
         * ARGS:
4844
         * Param1: pointer to thread
4845
         * Param2: name
4846
         * Param3 and 4: entry function and input
4847
         * Param5: pointer to thread stack
4848
         * Param6: stack size
4849
         * Param7 and 8: priority level and preempt threshold
4850
         * Param9 and 10: time slice and auto-start indicator */
4851
        result = tx_thread_create(&thread->tid,
4852
                           "wolfSSL thread",
4853
                           (entry_functionType)cb, (ULONG)arg,
4854
                           thread->threadStack,
4855
                           WOLFSSL_NETOS_STACK_SZ,
4856
                           2, 2,
4857
                           1, TX_AUTO_START);
4858
        if (result != TX_SUCCESS) {
4859
            XFREE(thread->threadStack, NULL, DYNAMIC_TYPE_OS_BUF);
4860
            thread->threadStack = NULL;
4861
            return MEMORY_E;
4862
        }
4863
4864
        return 0;
4865
    }
4866
4867
    int wolfSSL_JoinThread(THREAD_TYPE thread)
4868
    {
4869
        /* TODO: maybe have to use tx_thread_delete? */
4870
        XFREE(thread.threadStack, NULL, DYNAMIC_TYPE_OS_BUF);
4871
        thread.threadStack = NULL;
4872
        return 0;
4873
    }
4874
4875
#elif defined(WOLFSSL_ZEPHYR)
4876
4877
    void* wolfsslThreadHeapHint = NULL;
4878
4879
    int wolfSSL_NewThread(THREAD_TYPE* thread,
4880
        THREAD_CB cb, void* arg)
4881
    {
4882
        #ifndef WOLFSSL_ZEPHYR_STACK_SZ
4883
            #define WOLFSSL_ZEPHYR_STACK_SZ (48*1024)
4884
        #endif
4885
4886
        if (thread == NULL || cb == NULL)
4887
            return BAD_FUNC_ARG;
4888
4889
        XMEMSET(thread, 0, sizeof(*thread));
4890
4891
        thread->tid = (struct k_thread*)XMALLOC(
4892
                Z_KERNEL_STACK_SIZE_ADJUST(sizeof(struct k_thread)),
4893
                wolfsslThreadHeapHint, DYNAMIC_TYPE_TMP_BUFFER);
4894
        if (thread->tid == NULL) {
4895
            WOLFSSL_MSG("error: XMALLOC thread->tid failed");
4896
            return MEMORY_E;
4897
        }
4898
4899
        /* TODO: Use the following once k_thread_stack_alloc makes it into a
4900
         * release.
4901
         * thread->threadStack = k_thread_stack_alloc(WOLFSSL_ZEPHYR_STACK_SZ,
4902
         *                                            0);
4903
         */
4904
        thread->threadStack = (void*)XMALLOC(
4905
                Z_KERNEL_STACK_SIZE_ADJUST(WOLFSSL_ZEPHYR_STACK_SZ),
4906
                wolfsslThreadHeapHint, DYNAMIC_TYPE_TMP_BUFFER);
4907
        if (thread->threadStack == NULL) {
4908
            XFREE(thread->tid, wolfsslThreadHeapHint,
4909
                    DYNAMIC_TYPE_TMP_BUFFER);
4910
            thread->tid = NULL;
4911
4912
            WOLFSSL_MSG("error: XMALLOC thread->threadStack failed");
4913
            return MEMORY_E;
4914
        }
4915
4916
        /* k_thread_create does not return any error codes */
4917
        /* Casting to k_thread_entry_t should be fine since we just ignore the
4918
         * extra arguments being passed in */
4919
        k_thread_create(thread->tid, thread->threadStack,
4920
                WOLFSSL_ZEPHYR_STACK_SZ, (k_thread_entry_t)cb, arg, NULL, NULL,
4921
                5, 0, K_NO_WAIT);
4922
4923
        return 0;
4924
    }
4925
4926
    int wolfSSL_JoinThread(THREAD_TYPE thread)
4927
    {
4928
        int ret = 0;
4929
        int err;
4930
4931
        err = k_thread_join(thread.tid, K_FOREVER);
4932
        if (err != 0)
4933
            ret = MEMORY_E;
4934
4935
        XFREE(thread.tid, wolfsslThreadHeapHint,
4936
                DYNAMIC_TYPE_TMP_BUFFER);
4937
        thread.tid = NULL;
4938
4939
        /* TODO: Use the following once k_thread_stack_free makes it into a
4940
         * release.
4941
         * err = k_thread_stack_free(thread.threadStack);
4942
         * if (err != 0)
4943
         *     ret = MEMORY_E;
4944
         */
4945
        XFREE(thread.threadStack, wolfsslThreadHeapHint,
4946
                DYNAMIC_TYPE_TMP_BUFFER);
4947
        thread.threadStack = NULL;
4948
4949
        /* No thread resources to free. Everything is stored in thread.tid */
4950
4951
        return ret;
4952
    }
4953
4954
#ifdef WOLFSSL_COND
4955
    /* Use the pthreads translation layer for signaling */
4956
4957
#endif /* WOLFSSL_COND */
4958
4959
#elif defined(WOLFSSL_PTHREADS) || \
4960
     (defined(FREERTOS) && defined(WOLFSSL_ESPIDF))
4961
4962
    int wolfSSL_NewThread(THREAD_TYPE* thread,
4963
        THREAD_CB cb, void* arg)
4964
0
    {
4965
0
        if (thread == NULL || cb == NULL)
4966
0
            return BAD_FUNC_ARG;
4967
4968
0
        if (pthread_create(thread, NULL, cb, arg) != 0)
4969
0
            return MEMORY_E;
4970
4971
0
        return 0;
4972
0
    }
4973
4974
    #ifdef WOLFSSL_THREAD_NO_JOIN
4975
        int wolfSSL_NewThreadNoJoin(THREAD_CB_NOJOIN cb, void* arg)
4976
0
        {
4977
0
            THREAD_TYPE thread;
4978
0
            int ret;
4979
0
            XMEMSET(&thread, 0, sizeof(thread));
4980
0
            ret = wolfSSL_NewThread(&thread, cb, arg);
4981
0
            if (ret == 0)
4982
0
                ret = pthread_detach(thread);
4983
0
            return ret;
4984
0
        }
4985
    #endif
4986
4987
    int wolfSSL_JoinThread(THREAD_TYPE thread)
4988
0
    {
4989
0
        if (thread == INVALID_THREAD_VAL)
4990
0
            return BAD_FUNC_ARG;
4991
4992
0
        if (pthread_join(thread, NULL) != 0)
4993
0
            return MEMORY_E;
4994
4995
0
        return 0;
4996
0
    }
4997
4998
#ifdef WOLFSSL_COND
4999
    #if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 \
5000
        && !defined(__ppc__)
5001
    /* Apple style dispatch semaphore */
5002
    int wolfSSL_CondInit(COND_TYPE* cond)
5003
    {
5004
        if (cond == NULL)
5005
            return BAD_FUNC_ARG;
5006
5007
        /* dispatch_release() fails hard, with Trace/BPT trap signal, if the
5008
         * sem's internal count is less than the value passed in with
5009
         * dispatch_semaphore_create().  work around this by initing
5010
         * with 0, then incrementing it afterwards.
5011
         */
5012
        cond->cond = dispatch_semaphore_create(0);
5013
        if (cond->cond == NULL)
5014
            return MEMORY_E;
5015
5016
        if (wc_InitMutex(&cond->mutex) != 0) {
5017
            dispatch_release(cond->cond);
5018
            return MEMORY_E;
5019
        }
5020
5021
        return 0;
5022
    }
5023
5024
    int wolfSSL_CondFree(COND_TYPE* cond)
5025
    {
5026
        if (cond == NULL)
5027
            return BAD_FUNC_ARG;
5028
5029
        dispatch_release(cond->cond);
5030
        cond->cond = NULL;
5031
5032
        if (wc_FreeMutex(&cond->mutex) != 0) {
5033
            return MEMORY_E;
5034
        }
5035
5036
        return 0;
5037
    }
5038
5039
    int wolfSSL_CondStart(COND_TYPE* cond)
5040
    {
5041
        if (cond == NULL)
5042
            return BAD_FUNC_ARG;
5043
5044
        if (wc_LockMutex(&cond->mutex) != 0)
5045
            return BAD_MUTEX_E;
5046
5047
        return 0;
5048
    }
5049
5050
    int wolfSSL_CondSignal(COND_TYPE* cond)
5051
    {
5052
        if (cond == NULL)
5053
            return BAD_FUNC_ARG;
5054
5055
        if (wc_UnLockMutex(&cond->mutex) != 0)
5056
            return BAD_MUTEX_E;
5057
5058
        dispatch_semaphore_signal(cond->cond);
5059
5060
        if (wc_LockMutex(&cond->mutex) != 0)
5061
            return BAD_MUTEX_E;
5062
5063
        return 0;
5064
    }
5065
5066
    int wolfSSL_CondWait(COND_TYPE* cond)
5067
    {
5068
        if (cond == NULL)
5069
            return BAD_FUNC_ARG;
5070
5071
        if (wc_UnLockMutex(&cond->mutex) != 0)
5072
            return BAD_MUTEX_E;
5073
5074
        dispatch_semaphore_wait(cond->cond, DISPATCH_TIME_FOREVER);
5075
5076
        if (wc_LockMutex(&cond->mutex) != 0)
5077
            return BAD_MUTEX_E;
5078
5079
        return 0;
5080
    }
5081
5082
    int wolfSSL_CondEnd(COND_TYPE* cond)
5083
    {
5084
        if (cond == NULL)
5085
            return BAD_FUNC_ARG;
5086
5087
        if (wc_UnLockMutex(&cond->mutex) != 0)
5088
            return BAD_MUTEX_E;
5089
5090
        return 0;
5091
    }
5092
5093
    #else /* Generic POSIX conditional */
5094
5095
    int wolfSSL_CondInit(COND_TYPE* cond)
5096
0
    {
5097
0
        if (cond == NULL)
5098
0
            return BAD_FUNC_ARG;
5099
5100
0
        if (pthread_mutex_init(&cond->mutex, NULL) != 0)
5101
0
            return MEMORY_E;
5102
5103
0
        if (pthread_cond_init(&cond->cond, NULL) != 0) {
5104
            /* Keep compilers happy that we are using the return code */
5105
0
            if (pthread_mutex_destroy(&cond->mutex) != 0)
5106
0
                return MEMORY_E;
5107
0
            return MEMORY_E;
5108
0
        }
5109
5110
0
        return 0;
5111
0
    }
5112
5113
    int wolfSSL_CondFree(COND_TYPE* cond)
5114
0
    {
5115
0
        int ret = 0;
5116
5117
0
        if (cond == NULL)
5118
0
            return BAD_FUNC_ARG;
5119
5120
0
        if (pthread_mutex_destroy(&cond->mutex) != 0)
5121
0
            ret = MEMORY_E;
5122
5123
0
        if (pthread_cond_destroy(&cond->cond) != 0)
5124
0
            ret = MEMORY_E;
5125
5126
0
        return ret;
5127
0
    }
5128
5129
    int wolfSSL_CondStart(COND_TYPE* cond)
5130
0
    {
5131
0
        if (cond == NULL)
5132
0
            return BAD_FUNC_ARG;
5133
5134
0
        if (pthread_mutex_lock(&cond->mutex) != 0)
5135
0
            return BAD_MUTEX_E;
5136
5137
0
        return 0;
5138
0
    }
5139
5140
    int wolfSSL_CondSignal(COND_TYPE* cond)
5141
0
    {
5142
0
        if (cond == NULL)
5143
0
            return BAD_FUNC_ARG;
5144
5145
0
        if (pthread_cond_signal(&cond->cond) != 0)
5146
0
            return MEMORY_E;
5147
5148
0
        return 0;
5149
0
    }
5150
5151
    int wolfSSL_CondWait(COND_TYPE* cond)
5152
0
    {
5153
0
        if (cond == NULL)
5154
0
            return BAD_FUNC_ARG;
5155
5156
0
        if (pthread_cond_wait(&cond->cond, &cond->mutex) != 0)
5157
0
            return MEMORY_E;
5158
5159
0
        return 0;
5160
0
    }
5161
5162
    int wolfSSL_CondEnd(COND_TYPE* cond)
5163
0
    {
5164
0
        if (cond == NULL)
5165
0
            return BAD_FUNC_ARG;
5166
5167
0
        if (pthread_mutex_unlock(&cond->mutex) != 0)
5168
0
            return BAD_MUTEX_E;
5169
5170
0
        return 0;
5171
0
    }
5172
5173
    #endif /* __MACH__ */
5174
#endif /* WOLFSSL_COND */
5175
5176
#endif /* Environment check */
5177
5178
#endif /* not SINGLE_THREADED */
5179
5180
#if (defined(__unix__) || defined(__APPLE__)) && \
5181
    !defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_ZEPHYR)
5182
5183
#include <fcntl.h>
5184
#include <errno.h>
5185
#include <sys/socket.h>
5186
5187
#ifndef O_CLOEXEC
5188
    #define O_CLOEXEC 0
5189
#endif
5190
#ifndef SOCK_CLOEXEC
5191
    #define SOCK_CLOEXEC 0
5192
#endif
5193
5194
void wc_set_cloexec(int fd)
5195
0
{
5196
0
#ifdef FD_CLOEXEC
5197
0
    int fdFlags;
5198
0
    if (fd < 0)
5199
0
        return;
5200
0
    fdFlags = fcntl(fd, F_GETFD);
5201
0
    if (fdFlags >= 0)
5202
0
        (void)fcntl(fd, F_SETFD, fdFlags | FD_CLOEXEC);
5203
#else
5204
    (void)fd;
5205
#endif
5206
0
}
5207
5208
int wc_open_cloexec(const char* path, int flags)
5209
0
{
5210
0
    int fd = open(path, flags | O_CLOEXEC);
5211
0
#ifdef FD_CLOEXEC
5212
0
    if (fd < 0 && errno == EINVAL) {
5213
0
        fd = open(path, flags);
5214
0
        wc_set_cloexec(fd);
5215
0
    }
5216
0
#endif
5217
0
    return fd;
5218
0
}
5219
5220
int wc_socket_cloexec(int domain, int type, int protocol)
5221
0
{
5222
0
    int fd = socket(domain, type | SOCK_CLOEXEC, protocol);
5223
0
#ifdef FD_CLOEXEC
5224
0
    if (fd < 0 && errno == EINVAL) {
5225
0
        fd = socket(domain, type, protocol);
5226
0
        wc_set_cloexec(fd);
5227
0
    }
5228
0
#endif
5229
0
    return fd;
5230
0
}
5231
5232
int wc_accept_cloexec(int sockfd, void* addr, void* addrlen)
5233
0
{
5234
0
    int fd;
5235
0
#if (defined(__USE_GNU) && (defined(__linux__) || defined(__ANDROID__))) || \
5236
0
    (defined(__FreeBSD__) && defined(__BSD_VISIBLE) && __BSD_VISIBLE && \
5237
0
     (__FreeBSD_version >= 1000000))
5238
0
    fd = accept4(sockfd, (struct sockaddr*)addr, (socklen_t*)addrlen,
5239
0
                 SOCK_CLOEXEC);
5240
0
    if (fd >= 0)
5241
0
        return fd;
5242
0
    if (errno != ENOSYS && errno != EINVAL)
5243
0
        return fd;
5244
0
#endif
5245
0
    fd = accept(sockfd, (struct sockaddr*)addr, (socklen_t*)addrlen);
5246
0
    wc_set_cloexec(fd);
5247
0
    return fd;
5248
0
}
5249
5250
#endif /* (__unix__ || __APPLE__) && !WOLFSSL_LINUXKM && !WOLFSSL_ZEPHYR */
5251
5252
#if defined(WOLFSSL_LINUXKM) && defined(CONFIG_ARM64) && \
5253
    defined(WC_SYM_RELOC_TABLES)
5254
#ifndef CONFIG_ARCH_TEGRA
5255
5256
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
5257
noinstr void my__alt_cb_patch_nops(struct alt_instr *alt, __le32 *origptr,
5258
                                   __le32 *updptr, int nr_inst)
5259
{
5260
    return WC_PIE_INDIRECT_SYM(alt_cb_patch_nops)
5261
        (alt, origptr, updptr, nr_inst);
5262
}
5263
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) */
5264
5265
void my__queued_spin_lock_slowpath(struct qspinlock *lock, u32 val)
5266
{
5267
    return WC_PIE_INDIRECT_SYM(queued_spin_lock_slowpath)
5268
        (lock, val);
5269
}
5270
#endif
5271
#endif