Coverage Report

Created: 2025-07-04 06:22

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