Coverage Report

Created: 2026-09-20 06:33

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