Coverage Report

Created: 2024-06-28 06:19

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