Coverage Report

Created: 2025-07-23 06:53

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