Coverage Report

Created: 2026-01-06 06:52

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