Coverage Report

Created: 2026-09-28 06:10

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