Coverage Report

Created: 2026-02-14 07:18

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