Coverage Report

Created: 2026-04-05 07:22

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