1 /* port.c
2  *
3  * Copyright (C) 2006-2021 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 #if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A) || \
54     defined(WOLFSSL_ATECC608A)
55     #include <wolfssl/wolfcrypt/port/atmel/atmel.h>
56 #endif
57 #if defined(WOLFSSL_RENESAS_TSIP)
58     #include <wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h>
59 #endif
60 #if defined(WOLFSSL_RENESAS_SCE)
61     #include <wolfssl/wolfcrypt/port/Renesas/renesas-sce-crypt.h>
62 #endif
63 #if defined(WOLFSSL_STSAFEA100)
64     #include <wolfssl/wolfcrypt/port/st/stsafe.h>
65 #endif
66 
67 #if (defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)) \
68     && !defined(WOLFCRYPT_ONLY)
69     #include <wolfssl/openssl/evp.h>
70 #endif
71 
72 #if defined(USE_WOLFSSL_MEMORY) && defined(WOLFSSL_TRACK_MEMORY)
73     #include <wolfssl/wolfcrypt/memory.h>
74     #include <wolfssl/wolfcrypt/mem_track.h>
75 #endif
76 
77 #if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \
78     defined(WOLFSSL_IMX6UL_CAAM) || defined(WOLFSSL_IMX6_CAAM_BLOB)
79     #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
80 #endif
81 
82 #ifdef WOLFSSL_IMXRT_DCP
83     #include <wolfssl/wolfcrypt/port/nxp/dcp_port.h>
84 #endif
85 
86 #ifdef WOLF_CRYPTO_CB
87     #include <wolfssl/wolfcrypt/cryptocb.h>
88 #endif
89 
90 #ifdef HAVE_INTEL_QA_SYNC
91     #include <wolfssl/wolfcrypt/port/intel/quickassist_sync.h>
92 #endif
93 
94 #ifdef HAVE_CAVIUM_OCTEON_SYNC
95     #include <wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h>
96 #endif
97 
98 #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_INIT)
99 #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
100 #endif
101 
102 #ifdef WOLFSSL_SCE
103     #include "hal_data.h"
104 #endif
105 
106 #if defined(WOLFSSL_DSP) && !defined(WOLFSSL_DSP_BUILD)
107     #include "rpcmem.h"
108 #endif
109 
110 #ifdef _MSC_VER
111     /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
112     #pragma warning(disable: 4996)
113 #endif
114 
115 /* prevent multiple mutex initializations */
116 static volatile int initRefCount = 0;
117 
118 /* Used to initialize state for wolfcrypt
119    return 0 on success
120  */
wolfCrypt_Init(void)121 int wolfCrypt_Init(void)
122 {
123     int ret = 0;
124     if (initRefCount == 0) {
125         WOLFSSL_ENTER("wolfCrypt_Init");
126 
127     #ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST
128         {
129             word32 rngMallocFail;
130             time_t seed = time(NULL);
131             srand((word32)seed);
132             rngMallocFail = rand() % 2000; /* max 2000 */
133             printf("\n--- RNG MALLOC FAIL AT %d---\n", rngMallocFail);
134             wolfSSL_SetMemFailCount(rngMallocFail);
135         }
136     #endif
137 
138     #ifdef WOLF_CRYPTO_CB
139         wc_CryptoCb_Init();
140     #endif
141 
142     #ifdef WOLFSSL_ASYNC_CRYPT
143         ret = wolfAsync_HardwareStart();
144         if (ret != 0) {
145             WOLFSSL_MSG("Async hardware start failed");
146             /* don't return failure, allow operation to continue */
147         }
148     #endif
149 
150     #if defined(WOLFSSL_RENESAS_TSIP_CRYPT)
151         ret = tsip_Open( );
152         if( ret != TSIP_SUCCESS ) {
153             WOLFSSL_MSG("RENESAS TSIP Open failed");
154             /* not return 1 since WOLFSSL_SUCCESS=1*/
155             ret = -1;/* FATAL ERROR */
156             return ret;
157         }
158     #endif
159 
160     #if defined(WOLFSSL_RENESAS_SCEPROTECT)
161         ret = wc_sce_Open( );
162         if( ret != FSP_SUCCESS ) {
163             WOLFSSL_MSG("RENESAS SCE Open failed");
164             /* not return 1 since WOLFSSL_SUCCESS=1*/
165             ret = -1;/* FATAL ERROR */
166             return ret;
167         }
168     #endif
169 
170     #if defined(WOLFSSL_TRACK_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY)
171         ret = InitMemoryTracker();
172         if (ret != 0) {
173             WOLFSSL_MSG("InitMemoryTracker failed");
174             return ret;
175         }
176     #endif
177 
178     #if defined(WOLFSSL_LINUXKM_SIMD_X86)
179         ret = allocate_wolfcrypt_linuxkm_fpu_states();
180         if (ret != 0) {
181             WOLFSSL_MSG("allocate_wolfcrypt_linuxkm_fpu_states failed");
182             return ret;
183         }
184     #endif
185 
186     #if WOLFSSL_CRYPT_HW_MUTEX
187         /* If crypto hardware mutex protection is enabled, then initialize it */
188         ret = wolfSSL_CryptHwMutexInit();
189         if (ret != 0) {
190             WOLFSSL_MSG("Hw crypt mutex init failed");
191             return ret;
192         }
193     #endif
194 
195     /* if defined have fast RSA then initialize Intel IPP */
196     #ifdef HAVE_FAST_RSA
197         WOLFSSL_MSG("Attempting to use optimized IPP Library");
198         if ((ret = ippInit()) != ippStsNoErr) {
199             /* possible to get a CPU feature support status on optimized IPP
200               library but still use default library and see competitive speeds */
201             WOLFSSL_MSG("Warning when trying to set up optimization");
202             WOLFSSL_MSG(ippGetStatusString(ret));
203             WOLFSSL_MSG("Using default fast IPP library");
204             ret = 0;
205             (void)ret; /* suppress not read warning */
206         }
207     #endif
208 
209     #if defined(FREESCALE_LTC_TFM) || defined(FREESCALE_LTC_ECC)
210         ret = ksdk_port_init();
211         if (ret != 0) {
212             WOLFSSL_MSG("KSDK port init failed");
213             return ret;
214         }
215     #endif
216 
217     #if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A) || \
218         defined(WOLFSSL_ATECC608A)
219         ret = atmel_init();
220         if (ret != 0) {
221             WOLFSSL_MSG("CryptoAuthLib init failed");
222             return ret;
223         }
224     #endif
225     #if defined(WOLFSSL_CRYPTOCELL)
226         /* enable and initialize the ARM CryptoCell 3xx runtime library */
227         ret = cc310_Init();
228         if (ret != 0) {
229             WOLFSSL_MSG("CRYPTOCELL init failed");
230             return ret;
231         }
232     #endif
233     #if defined(WOLFSSL_STSAFEA100)
234         stsafe_interface_init();
235     #endif
236 
237     #if defined(WOLFSSL_PSOC6_CRYPTO)
238         ret = psoc6_crypto_port_init();
239         if (ret != 0) {
240             WOLFSSL_MSG("PSoC6 crypto engine init failed");
241             return ret;
242         }
243     #endif
244 
245     #ifdef WOLFSSL_SILABS_SE_ACCEL
246         /* init handles if it is already initialized */
247         ret = sl_se_init();
248     #endif
249 
250     #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_INIT)
251         ret = wc_se050_init(NULL);
252     #endif
253 
254     #ifdef WOLFSSL_ARMASM
255         WOLFSSL_MSG("Using ARM hardware acceleration");
256     #endif
257 
258     #ifdef WOLFSSL_AFALG
259         WOLFSSL_MSG("Using AF_ALG for crypto acceleration");
260     #endif
261 
262     #if !defined(WOLFCRYPT_ONLY) && defined(OPENSSL_EXTRA)
263         wolfSSL_EVP_init();
264     #endif
265 
266     #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
267         if ((ret = wc_LoggingInit()) != 0) {
268             WOLFSSL_MSG("Error creating logging mutex");
269             return ret;
270         }
271     #endif
272 
273 #ifdef HAVE_ECC
274     #ifdef FP_ECC
275         wc_ecc_fp_init();
276     #endif
277     #ifdef ECC_CACHE_CURVE
278         if ((ret = wc_ecc_curve_cache_init()) != 0) {
279             WOLFSSL_MSG("Error creating curve cache");
280             return ret;
281         }
282     #endif
283 #endif
284 
285 #ifdef WOLFSSL_SCE
286         ret = (int)WOLFSSL_SCE_GSCE_HANDLE.p_api->open(
287                 WOLFSSL_SCE_GSCE_HANDLE.p_ctrl, WOLFSSL_SCE_GSCE_HANDLE.p_cfg);
288         if (ret == SSP_ERR_CRYPTO_SCE_ALREADY_OPEN) {
289             WOLFSSL_MSG("SCE already open");
290             ret = 0;
291         }
292         if (ret != SSP_SUCCESS) {
293             WOLFSSL_MSG("Error opening SCE");
294             return -1; /* FATAL_ERROR */
295         }
296 #endif
297 
298 #if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \
299     defined(WOLFSSL_IMX6UL_CAAM) || defined(WOLFSSL_IMX6_CAAM_BLOB)
300         if ((ret = wc_caamInit()) != 0) {
301             return ret;
302         }
303 #endif
304 
305 #ifdef WOLFSSL_IMXRT_DCP
306         if ((ret = wc_dcp_init()) != 0) {
307             return ret;
308         }
309 #endif
310 
311 #if defined(WOLFSSL_DSP) && !defined(WOLFSSL_DSP_BUILD)
312         if ((ret = wolfSSL_InitHandle()) != 0) {
313             return ret;
314         }
315         rpcmem_init();
316 #endif
317     }
318     initRefCount++;
319 
320     return ret;
321 }
322 
323 #ifdef WOLFSSL_TRACK_MEMORY_VERBOSE
wolfCrypt_heap_peakAllocs_checkpoint(void)324 long wolfCrypt_heap_peakAllocs_checkpoint(void) {
325     long ret = ourMemStats.peakAllocsTripOdometer;
326     ourMemStats.peakAllocsTripOdometer = ourMemStats.totalAllocs -
327         ourMemStats.totalDeallocs;
328     return ret;
329 }
wolfCrypt_heap_peakBytes_checkpoint(void)330 long wolfCrypt_heap_peakBytes_checkpoint(void) {
331     long ret = ourMemStats.peakBytesTripOdometer;
332     ourMemStats.peakBytesTripOdometer = ourMemStats.currentBytes;
333     return ret;
334 }
335 #endif
336 
337 /* return success value is the same as wolfCrypt_Init */
wolfCrypt_Cleanup(void)338 int wolfCrypt_Cleanup(void)
339 {
340     int ret = 0;
341 
342     initRefCount--;
343     if (initRefCount < 0)
344         initRefCount = 0;
345 
346     if (initRefCount == 0) {
347         WOLFSSL_ENTER("wolfCrypt_Cleanup");
348 
349 #ifdef HAVE_ECC
350     #ifdef FP_ECC
351         wc_ecc_fp_free();
352     #endif
353     #ifdef ECC_CACHE_CURVE
354         wc_ecc_curve_cache_free();
355     #endif
356 #endif /* HAVE_ECC */
357 
358     #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
359         ret = wc_LoggingCleanup();
360     #endif
361 
362     #if defined(WOLFSSL_TRACK_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY)
363         ShowMemoryTracker();
364     #endif
365 
366     #ifdef WOLFSSL_ASYNC_CRYPT
367         wolfAsync_HardwareStop();
368     #endif
369 
370     #ifdef WOLFSSL_RENESAS_TSIP
371         tsip_Close();
372     #endif
373 
374     #ifdef WOLFSSL_RENESAS_SCEPROTECT
375         wc_sce_Close();
376     #endif
377 
378     #ifdef WOLFSSL_SCE
379         WOLFSSL_SCE_GSCE_HANDLE.p_api->close(WOLFSSL_SCE_GSCE_HANDLE.p_ctrl);
380     #endif
381 
382     #if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \
383         defined(WOLFSSL_IMX6_CAAM_BLOB)
384         wc_caamFree();
385     #endif
386     #if defined(WOLFSSL_CRYPTOCELL)
387         cc310_Free();
388     #endif
389     #ifdef WOLFSSL_SILABS_SE_ACCEL
390         ret = sl_se_deinit();
391     #endif
392     #if defined(WOLFSSL_RENESAS_TSIP_CRYPT)
393         tsip_Close();
394     #endif
395     #if defined(WOLFSSL_DSP) && !defined(WOLFSSL_DSP_BUILD)
396         rpcmem_deinit();
397         wolfSSL_CleanupHandle();
398     #endif
399     #if defined(WOLFSSL_LINUXKM_SIMD_X86)
400         free_wolfcrypt_linuxkm_fpu_states();
401     #endif
402     }
403 
404     return ret;
405 }
406 
407 #ifndef NO_FILESYSTEM
408 
409 /* Helpful function to load file into allocated buffer */
wc_FileLoad(const char * fname,unsigned char ** buf,size_t * bufLen,void * heap)410 int wc_FileLoad(const char* fname, unsigned char** buf, size_t* bufLen,
411     void* heap)
412 {
413     int ret;
414     size_t fileSz;
415     XFILE f;
416 
417     if (fname == NULL || buf == NULL || bufLen == NULL) {
418         return BAD_FUNC_ARG;
419     }
420 
421     /* set defaults */
422     *buf = NULL;
423     *bufLen = 0;
424 
425     /* open file (read-only binary) */
426     f = XFOPEN(fname, "rb");
427     if (!f) {
428         WOLFSSL_MSG("wc_LoadFile file load error");
429         return BAD_PATH_ERROR;
430     }
431 
432     if (XFSEEK(f, 0, XSEEK_END) != 0) {
433         WOLFSSL_MSG("wc_LoadFile file seek error");
434         XFCLOSE(f);
435         return BAD_PATH_ERROR;
436     }
437     fileSz = XFTELL(f);
438     XREWIND(f);
439     if (fileSz > 0) {
440         *bufLen = fileSz;
441         *buf = (byte*)XMALLOC(*bufLen, heap, DYNAMIC_TYPE_TMP_BUFFER);
442         if (*buf == NULL) {
443             WOLFSSL_MSG("wc_LoadFile memory error");
444             ret = MEMORY_E;
445         }
446         else {
447             size_t readLen = XFREAD(*buf, 1, *bufLen, f);
448 
449             /* check response code */
450             ret = (readLen == *bufLen) ? 0 : -1;
451         }
452     }
453     else {
454         ret = BUFFER_E;
455     }
456     XFCLOSE(f);
457 
458     (void)heap;
459 
460     return ret;
461 }
462 
463 #if !defined(NO_WOLFSSL_DIR) && \
464     !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2)
465 /* File Handling Helper */
466 /* returns 0 if file exists, WC_ISFILEEXIST_NOFILE if file doesn't exist */
wc_FileExists(const char * fname)467 int wc_FileExists(const char* fname)
468 {
469     struct ReadDirCtx ctx;
470 
471     XMEMSET(&ctx, 0, sizeof(ctx));
472 
473     if (fname == NULL)
474         return 0;
475 
476     if (XSTAT(fname, &ctx.s) != 0) {
477          WOLFSSL_MSG("stat on name failed");
478          return BAD_PATH_ERROR;
479     } else
480 #if defined(USE_WINDOWS_API)
481     if (XS_ISREG(ctx.s.st_mode)) {
482         return 0;
483     }
484 #elif defined(WOLFSSL_ZEPHYR)
485     if (XS_ISREG(ctx.s.type)) {
486         return 0;
487     }
488 #elif defined(WOLFSSL_TELIT_M2MB)
489     if (XS_ISREG(ctx.s.st_mode)) {
490         return 0;
491     }
492 #else
493     if (XS_ISREG(ctx.s.st_mode)) {
494         return 0;
495     }
496 #endif
497     return WC_ISFILEEXIST_NOFILE;
498 }
499 
500 /* File Handling Helpers */
501 /* returns 0 if file found, WC_READDIR_NOFILE if no files or negative error */
wc_ReadDirFirst(ReadDirCtx * ctx,const char * path,char ** name)502 int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name)
503 {
504     int ret = WC_READDIR_NOFILE; /* default to no files found */
505     int pathLen = 0;
506     int dnameLen = 0;
507 
508     if (name)
509         *name = NULL;
510 
511     if (ctx == NULL || path == NULL) {
512         return BAD_FUNC_ARG;
513     }
514 
515     XMEMSET(ctx, 0, sizeof(ReadDirCtx));
516     pathLen = (int)XSTRLEN(path);
517 
518 #ifdef USE_WINDOWS_API
519     if (pathLen > MAX_FILENAME_SZ - 3)
520         return BAD_PATH_ERROR;
521 
522     XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ - 3);
523     XSTRNCPY(ctx->name + pathLen, "\\*", MAX_FILENAME_SZ - pathLen);
524 
525     ctx->hFind = FindFirstFileA(ctx->name, &ctx->FindFileData);
526     if (ctx->hFind == INVALID_HANDLE_VALUE) {
527         WOLFSSL_MSG("FindFirstFile for path verify locations failed");
528         return BAD_PATH_ERROR;
529     }
530 
531     do {
532         if (!(ctx->FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
533             dnameLen = (int)XSTRLEN(ctx->FindFileData.cFileName);
534 
535             if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
536                 return BAD_PATH_ERROR;
537             }
538             XSTRNCPY(ctx->name, path, pathLen + 1);
539             ctx->name[pathLen] = '\\';
540             XSTRNCPY(ctx->name + pathLen + 1,
541                      ctx->FindFileData.cFileName,
542                      MAX_FILENAME_SZ - pathLen - 1);
543             if (name)
544                 *name = ctx->name;
545             return 0;
546         }
547     } while (FindNextFileA(ctx->hFind, &ctx->FindFileData));
548 
549 #elif defined(INTIME_RTOS)
550     if (pathLen > MAX_FILENAME_SZ - 3)
551         return BAD_PATH_ERROR;
552 
553     XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ - 3);
554     XSTRNCPY(ctx->name + pathLen, "\\*", MAX_FILENAME_SZ - pathLen);
555 
556     if (!IntimeFindFirst(ctx->name, &ctx->FindFileData)) {
557         WOLFSSL_MSG("FindFirstFile for path verify locations failed");
558         return BAD_PATH_ERROR;
559     }
560 
561     do {
562         dnameLen = (int)XSTRLEN(IntimeFilename(ctx));
563 
564         if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
565             return BAD_PATH_ERROR;
566         }
567         XSTRNCPY(ctx->name, path, pathLen + 1);
568         ctx->name[pathLen] = '\\';
569         XSTRNCPY(ctx->name + pathLen + 1,
570                  IntimeFilename(ctx),
571                  MAX_FILENAME_SZ - pathLen - 1);
572         if (0 == wc_FileExists(ctx->name)) {
573             if (name)
574                 *name = ctx->name;
575             return 0;
576         }
577     } while (IntimeFindNext(&ctx->FindFileData));
578 
579 #elif defined(WOLFSSL_ZEPHYR)
580     if (fs_opendir(&ctx->dir, path) != 0) {
581         WOLFSSL_MSG("opendir path verify locations failed");
582         return BAD_PATH_ERROR;
583     }
584     ctx->dirp = &ctx->dir;
585 
586     while ((fs_readdir(&ctx->dir, &ctx->entry)) != 0) {
587         dnameLen = (int)XSTRLEN(ctx->entry.name);
588 
589         if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {
590             ret = BAD_PATH_ERROR;
591             break;
592         }
593         XSTRNCPY(ctx->name, path, pathLen + 1);
594         ctx->name[pathLen] = '/';
595 
596         /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because
597          * of earlier check it is known that dnameLen is less than
598          * MAX_FILENAME_SZ - (pathLen + 2)  so dnameLen +1 will fit */
599         XSTRNCPY(ctx->name + pathLen + 1, ctx->entry.name, dnameLen + 1);
600         if ((ret = wc_FileExists(ctx->name)) == 0) {
601             if (name)
602                 *name = ctx->name;
603             return 0;
604         }
605     }
606 #elif defined(WOLFSSL_TELIT_M2MB)
607     ctx->dir = m2mb_fs_opendir((const CHAR*)path);
608     if (ctx->dir == NULL) {
609         WOLFSSL_MSG("opendir path verify locations failed");
610         return BAD_PATH_ERROR;
611     }
612 
613     while ((ctx->entry = m2mb_fs_readdir(ctx->dir)) != NULL) {
614         dnameLen = (int)XSTRLEN(ctx->entry->d_name);
615 
616         if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {
617             ret = BAD_PATH_ERROR;
618             break;
619         }
620         XSTRNCPY(ctx->name, path, pathLen + 1);
621         ctx->name[pathLen] = '/';
622 
623         /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because
624          * of earlier check it is known that dnameLen is less than
625          * MAX_FILENAME_SZ - (pathLen + 2)  so dnameLen +1 will fit */
626         XSTRNCPY(ctx->name + pathLen + 1, ctx->entry->d_name, dnameLen + 1);
627 
628         if ((ret = wc_FileExists(ctx->name)) == 0) {
629             if (name)
630                 *name = ctx->name;
631             return 0;
632         }
633     }
634 #else
635     ctx->dir = opendir(path);
636     if (ctx->dir == NULL) {
637         WOLFSSL_MSG("opendir path verify locations failed");
638         return BAD_PATH_ERROR;
639     }
640 
641     while ((ctx->entry = readdir(ctx->dir)) != NULL) {
642         dnameLen = (int)XSTRLEN(ctx->entry->d_name);
643 
644         if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {
645             ret = BAD_PATH_ERROR;
646             break;
647         }
648         XSTRNCPY(ctx->name, path, pathLen + 1);
649         ctx->name[pathLen] = '/';
650 
651         /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because
652          * of earlier check it is known that dnameLen is less than
653          * MAX_FILENAME_SZ - (pathLen + 2)  so dnameLen +1 will fit */
654         XSTRNCPY(ctx->name + pathLen + 1, ctx->entry->d_name, dnameLen + 1);
655         if ((ret = wc_FileExists(ctx->name)) == 0) {
656             if (name)
657                 *name = ctx->name;
658             return 0;
659         }
660     }
661 #endif
662     wc_ReadDirClose(ctx);
663 
664     return ret;
665 }
666 
667 /* returns 0 if file found, WC_READDIR_NOFILE if no more files */
wc_ReadDirNext(ReadDirCtx * ctx,const char * path,char ** name)668 int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name)
669 {
670     int ret = WC_READDIR_NOFILE; /* default to no file found */
671     int pathLen = 0;
672     int dnameLen = 0;
673 
674     if (name)
675         *name = NULL;
676 
677     if (ctx == NULL || path == NULL) {
678         return BAD_FUNC_ARG;
679     }
680 
681     XMEMSET(ctx->name, 0, MAX_FILENAME_SZ);
682     pathLen = (int)XSTRLEN(path);
683 
684 #ifdef USE_WINDOWS_API
685     while (FindNextFileA(ctx->hFind, &ctx->FindFileData)) {
686         if (!(ctx->FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
687             dnameLen = (int)XSTRLEN(ctx->FindFileData.cFileName);
688 
689             if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
690                 return BAD_PATH_ERROR;
691             }
692             XSTRNCPY(ctx->name, path, pathLen + 1);
693             ctx->name[pathLen] = '\\';
694             XSTRNCPY(ctx->name + pathLen + 1,
695                      ctx->FindFileData.cFileName,
696                      MAX_FILENAME_SZ - pathLen - 1);
697             if (name)
698                 *name = ctx->name;
699             return 0;
700         }
701     }
702 
703 #elif defined(INTIME_RTOS)
704     while (IntimeFindNext(&ctx->FindFileData)) {
705         dnameLen = (int)XSTRLEN(IntimeFilename(ctx));
706 
707         if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
708             return BAD_PATH_ERROR;
709         }
710         XSTRNCPY(ctx->name, path, pathLen + 1);
711         ctx->name[pathLen] = '\\';
712         XSTRNCPY(ctx->name + pathLen + 1,
713                  IntimeFilename(ctx),
714                  MAX_FILENAME_SZ - pathLen - 1);
715         if (0 == wc_FileExists(ctx->name)) {
716             if (name)
717                 *name = ctx->name;
718             return 0;
719         }
720     }
721 
722 #elif defined(WOLFSSL_ZEPHYR)
723     while ((fs_readdir(&ctx->dir, &ctx->entry)) != 0) {
724         dnameLen = (int)XSTRLEN(ctx->entry.name);
725 
726         if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {
727             ret = BAD_PATH_ERROR;
728             break;
729         }
730         XSTRNCPY(ctx->name, path, pathLen + 1);
731         ctx->name[pathLen] = '/';
732         /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because
733          * of earlier check it is known that dnameLen is less than
734          * MAX_FILENAME_SZ - (pathLen + 2) so that dnameLen +1 will fit */
735         XSTRNCPY(ctx->name + pathLen + 1, ctx->entry.name, dnameLen + 1);
736 
737        if ((ret = wc_FileExists(ctx->name)) == 0) {
738             if (name)
739                 *name = ctx->name;
740             return 0;
741         }
742     }
743 #elif defined(WOLFSSL_TELIT_M2MB)
744     while ((ctx->entry = m2mb_fs_readdir(ctx->dir)) != NULL) {
745         dnameLen = (int)XSTRLEN(ctx->entry->d_name);
746 
747         if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {
748             ret = BAD_PATH_ERROR;
749             break;
750         }
751         XSTRNCPY(ctx->name, path, pathLen + 1);
752         ctx->name[pathLen] = '/';
753 
754         /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because
755          * of earlier check it is known that dnameLen is less than
756          * MAX_FILENAME_SZ - (pathLen + 2)  so dnameLen +1 will fit */
757         XSTRNCPY(ctx->name + pathLen + 1, ctx->entry->d_name, dnameLen + 1);
758 
759         if ((ret = wc_FileExists(ctx->name)) == 0) {
760             if (name)
761                 *name = ctx->name;
762             return 0;
763         }
764     }
765 #else
766     while ((ctx->entry = readdir(ctx->dir)) != NULL) {
767         dnameLen = (int)XSTRLEN(ctx->entry->d_name);
768 
769         if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {
770             ret = BAD_PATH_ERROR;
771             break;
772         }
773         XSTRNCPY(ctx->name, path, pathLen + 1);
774         ctx->name[pathLen] = '/';
775         /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because
776          * of earlier check it is known that dnameLen is less than
777          * MAX_FILENAME_SZ - (pathLen + 2) so that dnameLen +1 will fit */
778         XSTRNCPY(ctx->name + pathLen + 1, ctx->entry->d_name, dnameLen + 1);
779 
780         if ((ret = wc_FileExists(ctx->name)) == 0) {
781             if (name)
782                 *name = ctx->name;
783             return 0;
784         }
785     }
786 #endif
787 
788     wc_ReadDirClose(ctx);
789 
790     return ret;
791 }
792 
wc_ReadDirClose(ReadDirCtx * ctx)793 void wc_ReadDirClose(ReadDirCtx* ctx)
794 {
795     if (ctx == NULL) {
796         return;
797     }
798 
799 #ifdef USE_WINDOWS_API
800     if (ctx->hFind != INVALID_HANDLE_VALUE) {
801         FindClose(ctx->hFind);
802         ctx->hFind = INVALID_HANDLE_VALUE;
803     }
804 
805 #elif defined(INTIME_RTOS)
806     IntimeFindClose(&ctx->FindFileData);
807 
808 #elif defined(WOLFSSL_ZEPHYR)
809     if (ctx->dirp) {
810         fs_closedir(ctx->dirp);
811         ctx->dirp = NULL;
812     }
813 #elif defined(WOLFSSL_TELIT_M2MB)
814     if (ctx->dir) {
815         m2mb_fs_closedir(ctx->dir);
816         ctx->dir = NULL;
817     }
818 #else
819     if (ctx->dir) {
820         closedir(ctx->dir);
821         ctx->dir = NULL;
822     }
823 #endif
824 }
825 
826 #endif /* !NO_WOLFSSL_DIR */
827 #endif /* !NO_FILESYSTEM */
828 
829 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_ZEPHYR)
z_fs_open(const char * filename,const char * perm)830 XFILE z_fs_open(const char* filename, const char* perm)
831 {
832     XFILE file;
833 
834     file = (XFILE)XMALLOC(sizeof(*file), NULL, DYNAMIC_TYPE_FILE);
835     if (file != NULL) {
836         if (fs_open(file, filename) != 0) {
837             XFREE(file, NULL, DYNAMIC_TYPE_FILE);
838             file = NULL;
839         }
840     }
841 
842     return file;
843 }
844 
z_fs_close(XFILE file)845 int z_fs_close(XFILE file)
846 {
847     int ret;
848 
849     if (file == NULL)
850         return -1;
851     ret = (fs_close(file) == 0) ? 0 : -1;
852 
853     XFREE(file, NULL, DYNAMIC_TYPE_FILE);
854 
855     return ret;
856 }
857 
858 #endif /* !NO_FILESYSTEM && !WOLFSSL_ZEPHYR */
859 
860 #if !defined(WOLFSSL_USER_MUTEX)
wc_InitAndAllocMutex(void)861 wolfSSL_Mutex* wc_InitAndAllocMutex(void)
862 {
863     wolfSSL_Mutex* m = (wolfSSL_Mutex*) XMALLOC(sizeof(wolfSSL_Mutex), NULL,
864             DYNAMIC_TYPE_MUTEX);
865     if (m != NULL) {
866         if (wc_InitMutex(m) != 0) {
867             WOLFSSL_MSG("Init Mutex failed");
868             XFREE(m, NULL, DYNAMIC_TYPE_MUTEX);
869             m = NULL;
870         }
871     }
872     else {
873         WOLFSSL_MSG("Memory error with Mutex allocation");
874     }
875 
876     return m;
877 }
878 #endif
879 
880 #ifdef USE_WOLF_STRTOK
881 /* String token (delim) search. If str is null use nextp. */
wc_strtok(char * str,const char * delim,char ** nextp)882 char* wc_strtok(char *str, const char *delim, char **nextp)
883 {
884     char* ret;
885     int i, j;
886 
887     /* Use next if str is NULL */
888     if (str == NULL && nextp)
889         str = *nextp;
890 
891     /* verify str input */
892     if (str == NULL || *str == '\0')
893         return NULL;
894 
895     /* match on entire delim */
896     for (i = 0; str[i]; i++) {
897         for (j = 0; delim[j]; j++) {
898             if (delim[j] == str[i])
899                 break;
900         }
901         if (!delim[j])
902             break;
903     }
904     str += i;
905     /* if end of string, not found so return NULL */
906     if (*str == '\0')
907         return NULL;
908 
909     ret = str;
910 
911     /* match on first delim */
912     for (i = 0; str[i]; i++) {
913         for (j = 0; delim[j]; j++) {
914             if (delim[j] == str[i])
915                 break;
916         }
917         if (delim[j] == str[i])
918             break;
919     }
920     str += i;
921 
922     /* null terminate found string */
923     if (*str)
924         *str++ = '\0';
925 
926     /* return pointer to next */
927     if (nextp)
928         *nextp = str;
929 
930     return ret;
931 }
932 #endif /* USE_WOLF_STRTOK */
933 
934 #ifdef USE_WOLF_STRSEP
wc_strsep(char ** stringp,const char * delim)935 char* wc_strsep(char **stringp, const char *delim)
936 {
937     char *s, *tok;
938     const char *spanp;
939 
940     /* null check */
941     if (stringp == NULL || *stringp == NULL)
942         return NULL;
943 
944     s = *stringp;
945     for (tok = s; *tok; ++tok) {
946         for (spanp = delim; *spanp; ++spanp) {
947             /* found delimiter */
948             if (*tok == *spanp) {
949                 *tok = '\0'; /* replace delim with null term */
950                 *stringp = tok + 1; /* return past delim */
951                 return s;
952             }
953         }
954     }
955 
956     *stringp = NULL;
957     return s;
958 }
959 #endif /* USE_WOLF_STRSEP */
960 
961 #if WOLFSSL_CRYPT_HW_MUTEX
962 /* Mutex for protection of cryptography hardware */
963 static wolfSSL_Mutex wcCryptHwMutex;
964 static int wcCryptHwMutexInit = 0;
965 
wolfSSL_CryptHwMutexInit(void)966 int wolfSSL_CryptHwMutexInit(void)
967 {
968     int ret = 0;
969     if (wcCryptHwMutexInit == 0) {
970         ret = wc_InitMutex(&wcCryptHwMutex);
971         if (ret == 0) {
972             wcCryptHwMutexInit = 1;
973         }
974     }
975     return ret;
976 }
wolfSSL_CryptHwMutexLock(void)977 int wolfSSL_CryptHwMutexLock(void)
978 {
979     int ret = BAD_MUTEX_E;
980     /* Make sure HW Mutex has been initialized */
981     ret = wolfSSL_CryptHwMutexInit();
982     if (ret == 0) {
983         ret = wc_LockMutex(&wcCryptHwMutex);
984     }
985     return ret;
986 }
wolfSSL_CryptHwMutexUnLock(void)987 int wolfSSL_CryptHwMutexUnLock(void)
988 {
989     int ret = BAD_MUTEX_E;
990     if (wcCryptHwMutexInit) {
991         ret = wc_UnLockMutex(&wcCryptHwMutex);
992     }
993     return ret;
994 }
995 #endif /* WOLFSSL_CRYPT_HW_MUTEX */
996 
997 
998 /* ---------------------------------------------------------------------------*/
999 /* Mutex Ports */
1000 /* ---------------------------------------------------------------------------*/
1001 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
1002     static mutex_cb*     compat_mutex_cb = NULL;
1003 
1004     /* Function that locks or unlocks a mutex based on the flag passed in.
1005      *
1006      * flag lock or unlock i.e. CRYPTO_LOCK
1007      * type the type of lock to unlock or lock
1008      * file name of the file calling
1009      * line the line number from file calling
1010      */
wc_LockMutex_ex(int flag,int type,const char * file,int line)1011     int wc_LockMutex_ex(int flag, int type, const char* file, int line)
1012     {
1013         if (compat_mutex_cb != NULL) {
1014             compat_mutex_cb(flag, type, file, line);
1015             return 0;
1016         }
1017         else {
1018             WOLFSSL_MSG("Mutex call back function not set. Call wc_SetMutexCb");
1019             return BAD_STATE_E;
1020         }
1021     }
1022 
1023 
1024     /* Set the callback function to use for locking/unlocking mutex
1025      *
1026      * cb callback function to use
1027      */
wc_SetMutexCb(mutex_cb * cb)1028     int wc_SetMutexCb(mutex_cb* cb)
1029     {
1030         compat_mutex_cb = cb;
1031         return 0;
1032     }
1033 #endif /* defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) */
1034 #ifdef SINGLE_THREADED
1035 
wc_InitMutex(wolfSSL_Mutex * m)1036     int wc_InitMutex(wolfSSL_Mutex* m)
1037     {
1038         (void)m;
1039         return 0;
1040     }
1041 
wc_FreeMutex(wolfSSL_Mutex * m)1042     int wc_FreeMutex(wolfSSL_Mutex *m)
1043     {
1044         (void)m;
1045         return 0;
1046     }
1047 
1048 
wc_LockMutex(wolfSSL_Mutex * m)1049     int wc_LockMutex(wolfSSL_Mutex *m)
1050     {
1051         (void)m;
1052         return 0;
1053     }
1054 
1055 
wc_UnLockMutex(wolfSSL_Mutex * m)1056     int wc_UnLockMutex(wolfSSL_Mutex *m)
1057     {
1058         (void)m;
1059         return 0;
1060     }
1061 
1062 #elif defined(FREERTOS) || defined(FREERTOS_TCP) || \
1063   defined(FREESCALE_FREE_RTOS)
1064 
wc_InitMutex(wolfSSL_Mutex * m)1065     int wc_InitMutex(wolfSSL_Mutex* m)
1066     {
1067         int iReturn;
1068 
1069         *m = ( wolfSSL_Mutex ) xSemaphoreCreateMutex();
1070         if( *m != NULL )
1071             iReturn = 0;
1072         else
1073             iReturn = BAD_MUTEX_E;
1074 
1075         return iReturn;
1076     }
1077 
wc_FreeMutex(wolfSSL_Mutex * m)1078     int wc_FreeMutex(wolfSSL_Mutex* m)
1079     {
1080         vSemaphoreDelete( *m );
1081         return 0;
1082     }
1083 
wc_LockMutex(wolfSSL_Mutex * m)1084     int wc_LockMutex(wolfSSL_Mutex* m)
1085     {
1086         /* Assume an infinite block, or should there be zero block? */
1087         xSemaphoreTake( *m, portMAX_DELAY );
1088         return 0;
1089     }
1090 
wc_UnLockMutex(wolfSSL_Mutex * m)1091     int wc_UnLockMutex(wolfSSL_Mutex* m)
1092     {
1093         xSemaphoreGive( *m );
1094         return 0;
1095     }
1096 
1097 #elif defined(RTTHREAD)
1098 
wc_InitMutex(wolfSSL_Mutex * m)1099     int wc_InitMutex(wolfSSL_Mutex* m)
1100     {
1101         int iReturn;
1102 
1103         *m = ( wolfSSL_Mutex ) rt_mutex_create("mutex",RT_IPC_FLAG_FIFO);
1104         if( *m != NULL )
1105             iReturn = 0;
1106         else
1107             iReturn = BAD_MUTEX_E;
1108 
1109 
1110         return iReturn;
1111     }
1112 
wc_FreeMutex(wolfSSL_Mutex * m)1113     int wc_FreeMutex(wolfSSL_Mutex* m)
1114     {
1115         rt_mutex_delete( *m );
1116         return 0;
1117     }
1118 
1119 
wc_LockMutex(wolfSSL_Mutex * m)1120     int wc_LockMutex(wolfSSL_Mutex* m)
1121     {
1122         /* Assume an infinite block, or should there be zero block? */
1123         return rt_mutex_take( *m, RT_WAITING_FOREVER );
1124     }
1125 
wc_UnLockMutex(wolfSSL_Mutex * m)1126     int wc_UnLockMutex(wolfSSL_Mutex* m)
1127     {
1128         return rt_mutex_release( *m );
1129     }
1130 
1131 #elif defined(WOLFSSL_SAFERTOS)
1132 
wc_InitMutex(wolfSSL_Mutex * m)1133     int wc_InitMutex(wolfSSL_Mutex* m)
1134     {
1135         vSemaphoreCreateBinary(m->mutexBuffer, m->mutex);
1136         if (m->mutex == NULL)
1137             return BAD_MUTEX_E;
1138 
1139         return 0;
1140     }
1141 
wc_FreeMutex(wolfSSL_Mutex * m)1142     int wc_FreeMutex(wolfSSL_Mutex* m)
1143     {
1144         (void)m;
1145         return 0;
1146     }
1147 
wc_LockMutex(wolfSSL_Mutex * m)1148     int wc_LockMutex(wolfSSL_Mutex* m)
1149     {
1150         /* Assume an infinite block */
1151         xSemaphoreTake(m->mutex, portMAX_DELAY);
1152         return 0;
1153     }
1154 
wc_UnLockMutex(wolfSSL_Mutex * m)1155     int wc_UnLockMutex(wolfSSL_Mutex* m)
1156     {
1157         xSemaphoreGive(m->mutex);
1158         return 0;
1159     }
1160 
1161 #elif defined(USE_WINDOWS_API)
1162 
wc_InitMutex(wolfSSL_Mutex * m)1163     int wc_InitMutex(wolfSSL_Mutex* m)
1164     {
1165         InitializeCriticalSection(m);
1166         return 0;
1167     }
1168 
1169 
wc_FreeMutex(wolfSSL_Mutex * m)1170     int wc_FreeMutex(wolfSSL_Mutex* m)
1171     {
1172         DeleteCriticalSection(m);
1173         return 0;
1174     }
1175 
1176 
wc_LockMutex(wolfSSL_Mutex * m)1177     int wc_LockMutex(wolfSSL_Mutex* m)
1178     {
1179         EnterCriticalSection(m);
1180         return 0;
1181     }
1182 
1183 
wc_UnLockMutex(wolfSSL_Mutex * m)1184     int wc_UnLockMutex(wolfSSL_Mutex* m)
1185     {
1186         LeaveCriticalSection(m);
1187         return 0;
1188     }
1189 
1190 #elif defined(WOLFSSL_PTHREADS)
1191 
wc_InitMutex(wolfSSL_Mutex * m)1192     int wc_InitMutex(wolfSSL_Mutex* m)
1193     {
1194         if (pthread_mutex_init(m, 0) == 0)
1195             return 0;
1196         else
1197             return BAD_MUTEX_E;
1198     }
1199 
1200 
wc_FreeMutex(wolfSSL_Mutex * m)1201     int wc_FreeMutex(wolfSSL_Mutex* m)
1202     {
1203         if (pthread_mutex_destroy(m) == 0)
1204             return 0;
1205         else
1206             return BAD_MUTEX_E;
1207     }
1208 
1209 
wc_LockMutex(wolfSSL_Mutex * m)1210     int wc_LockMutex(wolfSSL_Mutex* m)
1211     {
1212         if (pthread_mutex_lock(m) == 0)
1213             return 0;
1214         else
1215             return BAD_MUTEX_E;
1216     }
1217 
1218 
wc_UnLockMutex(wolfSSL_Mutex * m)1219     int wc_UnLockMutex(wolfSSL_Mutex* m)
1220     {
1221         if (pthread_mutex_unlock(m) == 0)
1222             return 0;
1223         else
1224             return BAD_MUTEX_E;
1225     }
1226 
1227 #elif defined(WOLFSSL_KTHREADS)
1228 
1229     /* Linux kernel mutex routines are voids, alas. */
1230 
wc_InitMutex(wolfSSL_Mutex * m)1231     int wc_InitMutex(wolfSSL_Mutex* m)
1232     {
1233         mutex_init(m);
1234         return 0;
1235     }
1236 
wc_FreeMutex(wolfSSL_Mutex * m)1237     int wc_FreeMutex(wolfSSL_Mutex* m)
1238     {
1239         mutex_destroy(m);
1240         return 0;
1241     }
1242 
wc_LockMutex(wolfSSL_Mutex * m)1243     int wc_LockMutex(wolfSSL_Mutex* m)
1244     {
1245         mutex_lock(m);
1246         return 0;
1247     }
1248 
1249 
wc_UnLockMutex(wolfSSL_Mutex * m)1250     int wc_UnLockMutex(wolfSSL_Mutex* m)
1251     {
1252         mutex_unlock(m);
1253         return 0;
1254     }
1255 
1256 #elif defined(WOLFSSL_VXWORKS)
1257 
wc_InitMutex(wolfSSL_Mutex * m)1258     int wc_InitMutex(wolfSSL_Mutex* m)
1259     {
1260         if (m) {
1261             if ((*m = semMCreate(0)) != SEM_ID_NULL)
1262                 return 0;
1263         }
1264         return BAD_MUTEX_E;
1265     }
1266 
1267 
wc_FreeMutex(wolfSSL_Mutex * m)1268     int wc_FreeMutex(wolfSSL_Mutex* m)
1269     {
1270         if (m) {
1271             if (semDelete(*m) == OK)
1272                 return 0;
1273         }
1274         return BAD_MUTEX_E;
1275     }
1276 
1277 
wc_LockMutex(wolfSSL_Mutex * m)1278     int wc_LockMutex(wolfSSL_Mutex* m)
1279     {
1280         if (m) {
1281             if (semTake(*m, WAIT_FOREVER) == OK)
1282                 return 0;
1283         }
1284         return BAD_MUTEX_E;
1285     }
1286 
1287 
wc_UnLockMutex(wolfSSL_Mutex * m)1288     int wc_UnLockMutex(wolfSSL_Mutex* m)
1289     {
1290         if (m) {
1291             if (semGive(*m) == OK)
1292                 return 0;
1293         }
1294         return BAD_MUTEX_E;
1295     }
1296 
1297 #elif defined(THREADX)
1298 
wc_InitMutex(wolfSSL_Mutex * m)1299     int wc_InitMutex(wolfSSL_Mutex* m)
1300     {
1301         if (tx_mutex_create(m, "wolfSSL Mutex", TX_NO_INHERIT) == 0)
1302             return 0;
1303         else
1304             return BAD_MUTEX_E;
1305     }
1306 
1307 
wc_FreeMutex(wolfSSL_Mutex * m)1308     int wc_FreeMutex(wolfSSL_Mutex* m)
1309     {
1310         if (tx_mutex_delete(m) == 0)
1311             return 0;
1312         else
1313             return BAD_MUTEX_E;
1314     }
1315 
1316 
wc_LockMutex(wolfSSL_Mutex * m)1317     int wc_LockMutex(wolfSSL_Mutex* m)
1318     {
1319         if (tx_mutex_get(m, TX_WAIT_FOREVER) == 0)
1320             return 0;
1321         else
1322             return BAD_MUTEX_E;
1323     }
1324 
wc_UnLockMutex(wolfSSL_Mutex * m)1325     int wc_UnLockMutex(wolfSSL_Mutex* m)
1326     {
1327         if (tx_mutex_put(m) == 0)
1328             return 0;
1329         else
1330             return BAD_MUTEX_E;
1331     }
1332 
1333 #elif defined(WOLFSSL_DEOS)
1334 
wc_InitMutex(wolfSSL_Mutex * m)1335     int wc_InitMutex(wolfSSL_Mutex* m)
1336     {
1337         mutexStatus mutStat;
1338         /*
1339         The empty string "" denotes an anonymous mutex, so objects do not cause name collisions.
1340         `protectWolfSSLTemp` in an XML configuration element template describing a mutex.
1341         */
1342         if (m) {
1343             mutStat = createMutex("", "protectWolfSSLTemp", m);
1344             if (mutStat == mutexSuccess)
1345                 return 0;
1346             else{
1347                 WOLFSSL_MSG("wc_InitMutex failed");
1348                 return mutStat;
1349             }
1350         }
1351         return BAD_MUTEX_E;
1352     }
1353 
wc_FreeMutex(wolfSSL_Mutex * m)1354     int wc_FreeMutex(wolfSSL_Mutex* m)
1355     {
1356         mutexStatus mutStat;
1357         if (m) {
1358             mutStat = deleteMutex(*m);
1359             if (mutStat == mutexSuccess)
1360                 return 0;
1361             else{
1362                 WOLFSSL_MSG("wc_FreeMutex failed");
1363                 return mutStat;
1364             }
1365         }
1366         return BAD_MUTEX_E;
1367     }
1368 
wc_LockMutex(wolfSSL_Mutex * m)1369     int wc_LockMutex(wolfSSL_Mutex* m)
1370     {
1371         mutexStatus mutStat;
1372         if (m) {
1373             mutStat = lockMutex(*m);
1374             if (mutStat == mutexSuccess)
1375                 return 0;
1376             else{
1377                 WOLFSSL_MSG("wc_LockMutex failed");
1378                 return mutStat;
1379             }
1380         }
1381         return BAD_MUTEX_E;
1382     }
1383 
wc_UnLockMutex(wolfSSL_Mutex * m)1384     int wc_UnLockMutex(wolfSSL_Mutex* m)
1385     {
1386         mutexStatus mutStat;
1387         if (m) {
1388             mutStat = unlockMutex(*m);
1389             if (mutStat== mutexSuccess)
1390                 return 0;
1391             else{
1392                 WOLFSSL_MSG("wc_UnLockMutex failed");
1393                 return mutStat;
1394             }
1395         }
1396         return BAD_MUTEX_E;
1397     }
1398 
1399 #elif defined(MICRIUM)
1400     #if (OS_VERSION < 50000)
1401         #define MICRIUM_ERR_TYPE OS_ERR
1402         #define MICRIUM_ERR_NONE OS_ERR_NONE
1403         #define MICRIUM_ERR_CODE(err) err
1404     #else
1405         #define MICRIUM_ERR_TYPE RTOS_ERR
1406         #define MICRIUM_ERR_NONE RTOS_ERR_NONE
1407         #define MICRIUM_ERR_CODE(err)    RTOS_ERR_CODE_GET(err)
1408     #endif
1409 
wc_InitMutex(wolfSSL_Mutex * m)1410     int wc_InitMutex(wolfSSL_Mutex* m)
1411     {
1412         MICRIUM_ERR_TYPE err;
1413 
1414         OSMutexCreate(m, "wolfSSL Mutex", &err);
1415 
1416         if (MICRIUM_ERR_CODE(err) == MICRIUM_ERR_NONE)
1417             return 0;
1418         else
1419             return BAD_MUTEX_E;
1420     }
1421 
wc_FreeMutex(wolfSSL_Mutex * m)1422     int wc_FreeMutex(wolfSSL_Mutex* m)
1423     {
1424         #if (OS_CFG_MUTEX_DEL_EN == DEF_ENABLED)
1425             MICRIUM_ERR_TYPE err;
1426 
1427             OSMutexDel(m, OS_OPT_DEL_ALWAYS, &err);
1428 
1429             if (MICRIUM_ERR_CODE(err) == MICRIUM_ERR_NONE)
1430                 return 0;
1431             else
1432                 return BAD_MUTEX_E;
1433         #else
1434             (void)m;
1435             return 0;
1436         #endif
1437     }
1438 
wc_LockMutex(wolfSSL_Mutex * m)1439     int wc_LockMutex(wolfSSL_Mutex* m)
1440     {
1441         MICRIUM_ERR_TYPE err;
1442 
1443         OSMutexPend(m, 0, OS_OPT_PEND_BLOCKING, NULL, &err);
1444 
1445         if (MICRIUM_ERR_CODE(err) == MICRIUM_ERR_NONE)
1446             return 0;
1447         else
1448             return BAD_MUTEX_E;
1449     }
1450 
wc_UnLockMutex(wolfSSL_Mutex * m)1451     int wc_UnLockMutex(wolfSSL_Mutex* m)
1452     {
1453         MICRIUM_ERR_TYPE err;
1454 
1455         OSMutexPost(m, OS_OPT_POST_NONE, &err);
1456 
1457         if (MICRIUM_ERR_CODE(err) == MICRIUM_ERR_NONE)
1458             return 0;
1459         else
1460             return BAD_MUTEX_E;
1461     }
1462 
1463 #elif defined(EBSNET)
1464 
wc_InitMutex(wolfSSL_Mutex * m)1465     int wc_InitMutex(wolfSSL_Mutex* m)
1466     {
1467         if (rtp_sig_mutex_alloc(m, "wolfSSL Mutex") == -1)
1468             return BAD_MUTEX_E;
1469         else
1470             return 0;
1471     }
1472 
wc_FreeMutex(wolfSSL_Mutex * m)1473     int wc_FreeMutex(wolfSSL_Mutex* m)
1474     {
1475         rtp_sig_mutex_free(*m);
1476         return 0;
1477     }
1478 
wc_LockMutex(wolfSSL_Mutex * m)1479     int wc_LockMutex(wolfSSL_Mutex* m)
1480     {
1481         if (rtp_sig_mutex_claim_timed(*m, RTIP_INF) == 0)
1482             return 0;
1483         else
1484             return BAD_MUTEX_E;
1485     }
1486 
wc_UnLockMutex(wolfSSL_Mutex * m)1487     int wc_UnLockMutex(wolfSSL_Mutex* m)
1488     {
1489         rtp_sig_mutex_release(*m);
1490         return 0;
1491     }
1492 
ebsnet_fseek(int a,long b,int c)1493     int ebsnet_fseek(int a, long b, int c)
1494     {
1495         int retval;
1496 
1497         retval = vf_lseek(a, b, c);
1498         if (retval > 0)
1499             retval = 0;
1500         else
1501             retval =  -1;
1502 
1503         return(retval);
1504     }
1505 
1506 #elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
1507 
wc_InitMutex(wolfSSL_Mutex * m)1508     int wc_InitMutex(wolfSSL_Mutex* m)
1509     {
1510         if (_mutex_init(m, NULL) == MQX_EOK)
1511             return 0;
1512         else
1513             return BAD_MUTEX_E;
1514     }
1515 
wc_FreeMutex(wolfSSL_Mutex * m)1516     int wc_FreeMutex(wolfSSL_Mutex* m)
1517     {
1518         if (_mutex_destroy(m) == MQX_EOK)
1519             return 0;
1520         else
1521             return BAD_MUTEX_E;
1522     }
1523 
wc_LockMutex(wolfSSL_Mutex * m)1524     int wc_LockMutex(wolfSSL_Mutex* m)
1525     {
1526         if (_mutex_lock(m) == MQX_EOK)
1527             return 0;
1528         else
1529             return BAD_MUTEX_E;
1530     }
1531 
wc_UnLockMutex(wolfSSL_Mutex * m)1532     int wc_UnLockMutex(wolfSSL_Mutex* m)
1533     {
1534         if (_mutex_unlock(m) == MQX_EOK)
1535             return 0;
1536         else
1537             return BAD_MUTEX_E;
1538     }
1539 
1540 #elif defined(WOLFSSL_TIRTOS)
1541     #include <xdc/runtime/Error.h>
1542 
wc_InitMutex(wolfSSL_Mutex * m)1543     int wc_InitMutex(wolfSSL_Mutex* m)
1544     {
1545         Semaphore_Params params;
1546         Error_Block eb;
1547 
1548         Error_init(&eb);
1549         Semaphore_Params_init(&params);
1550         params.mode = Semaphore_Mode_BINARY;
1551 
1552         *m = Semaphore_create(1, &params, &eb);
1553         if (Error_check(&eb)) {
1554             Error_raise(&eb, Error_E_generic, "Failed to Create the semaphore.",
1555                 NULL);
1556             return BAD_MUTEX_E;
1557         }
1558         else
1559             return 0;
1560     }
1561 
wc_FreeMutex(wolfSSL_Mutex * m)1562     int wc_FreeMutex(wolfSSL_Mutex* m)
1563     {
1564         Semaphore_delete(m);
1565 
1566         return 0;
1567     }
1568 
wc_LockMutex(wolfSSL_Mutex * m)1569     int wc_LockMutex(wolfSSL_Mutex* m)
1570     {
1571         Semaphore_pend(*m, BIOS_WAIT_FOREVER);
1572 
1573         return 0;
1574     }
1575 
wc_UnLockMutex(wolfSSL_Mutex * m)1576     int wc_UnLockMutex(wolfSSL_Mutex* m)
1577     {
1578         Semaphore_post(*m);
1579 
1580         return 0;
1581     }
1582 
1583 #elif defined(WOLFSSL_uITRON4)
1584 
wc_InitMutex(wolfSSL_Mutex * m)1585     int wc_InitMutex(wolfSSL_Mutex* m)
1586     {
1587         int iReturn;
1588         m->sem.sematr  = TA_TFIFO;
1589         m->sem.isemcnt = 1;
1590         m->sem.maxsem  = 1;
1591         m->sem.name    = NULL;
1592 
1593         m->id = acre_sem(&m->sem);
1594         if( m->id != E_OK )
1595             iReturn = 0;
1596         else
1597             iReturn = BAD_MUTEX_E;
1598 
1599         return iReturn;
1600     }
1601 
wc_FreeMutex(wolfSSL_Mutex * m)1602     int wc_FreeMutex(wolfSSL_Mutex* m)
1603     {
1604         del_sem( m->id );
1605         return 0;
1606     }
1607 
wc_LockMutex(wolfSSL_Mutex * m)1608     int wc_LockMutex(wolfSSL_Mutex* m)
1609     {
1610         wai_sem(m->id);
1611         return 0;
1612     }
1613 
wc_UnLockMutex(wolfSSL_Mutex * m)1614     int wc_UnLockMutex(wolfSSL_Mutex* m)
1615     {
1616         sig_sem(m->id);
1617         return 0;
1618     }
1619 
1620     /****  uITRON malloc/free ***/
1621     static ID ID_wolfssl_MPOOL = 0;
1622     static T_CMPL wolfssl_MPOOL = {TA_TFIFO, 0, NULL, "wolfSSL_MPOOL"};
1623 
uITRON4_minit(size_t poolsz)1624     int uITRON4_minit(size_t poolsz) {
1625         ER ercd;
1626         wolfssl_MPOOL.mplsz = poolsz;
1627         ercd = acre_mpl(&wolfssl_MPOOL);
1628         if (ercd > 0) {
1629             ID_wolfssl_MPOOL = ercd;
1630             return 0;
1631         } else {
1632             return -1;
1633         }
1634     }
1635 
uITRON4_malloc(size_t sz)1636     void *uITRON4_malloc(size_t sz) {
1637         ER ercd;
1638         void *p = NULL;
1639         ercd = get_mpl(ID_wolfssl_MPOOL, sz, (VP)&p);
1640         if (ercd == E_OK) {
1641             return p;
1642         } else {
1643             return 0;
1644         }
1645     }
1646 
uITRON4_realloc(void * p,size_t sz)1647     void *uITRON4_realloc(void *p, size_t sz) {
1648       ER ercd;
1649       void *newp = NULL;
1650       if(p) {
1651           ercd = get_mpl(ID_wolfssl_MPOOL, sz, (VP)&newp);
1652           if (ercd == E_OK) {
1653               XMEMCPY(newp, p, sz);
1654               ercd = rel_mpl(ID_wolfssl_MPOOL, (VP)p);
1655               if (ercd == E_OK) {
1656                   return newp;
1657               }
1658           }
1659       }
1660       return 0;
1661     }
1662 
uITRON4_free(void * p)1663     void uITRON4_free(void *p) {
1664         ER ercd;
1665         ercd = rel_mpl(ID_wolfssl_MPOOL, (VP)p);
1666         if (ercd == E_OK) {
1667             return;
1668         } else {
1669             return;
1670         }
1671     }
1672 
1673 #elif defined(WOLFSSL_uTKERNEL2)
1674 
wc_InitMutex(wolfSSL_Mutex * m)1675     int wc_InitMutex(wolfSSL_Mutex* m)
1676     {
1677         int iReturn;
1678         m->sem.sematr  = TA_TFIFO;
1679         m->sem.isemcnt = 1;
1680         m->sem.maxsem  = 1;
1681 
1682         m->id = tk_cre_sem(&m->sem);
1683         if( m->id != NULL )
1684             iReturn = 0;
1685         else
1686             iReturn = BAD_MUTEX_E;
1687 
1688         return iReturn;
1689     }
1690 
wc_FreeMutex(wolfSSL_Mutex * m)1691     int wc_FreeMutex(wolfSSL_Mutex* m)
1692     {
1693         tk_del_sem(m->id);
1694         return 0;
1695     }
1696 
wc_LockMutex(wolfSSL_Mutex * m)1697     int wc_LockMutex(wolfSSL_Mutex* m)
1698     {
1699         tk_wai_sem(m->id, 1, TMO_FEVR);
1700         return 0;
1701     }
1702 
wc_UnLockMutex(wolfSSL_Mutex * m)1703     int wc_UnLockMutex(wolfSSL_Mutex* m)
1704     {
1705         tk_sig_sem(m->id, 1);
1706         return 0;
1707     }
1708 
1709     /****  uT-Kernel malloc/free ***/
1710     static ID ID_wolfssl_MPOOL = 0;
1711     static T_CMPL wolfssl_MPOOL = {
1712         NULL,       /* Extended information */
1713         TA_TFIFO,   /* Memory pool attribute */
1714         0,          /* Size of whole memory pool (byte) */
1715         "wolfSSL"   /* Object name (max 8-char) */
1716     };
1717 
uTKernel_init_mpool(unsigned int sz)1718     int uTKernel_init_mpool(unsigned int sz) {
1719         ER ercd;
1720         wolfssl_MPOOL.mplsz = sz;
1721         ercd = tk_cre_mpl(&wolfssl_MPOOL);
1722         if (ercd > 0) {
1723             ID_wolfssl_MPOOL = ercd;
1724             return 0;
1725         } else {
1726             return (int)ercd;
1727         }
1728     }
1729 
uTKernel_malloc(unsigned int sz)1730     void *uTKernel_malloc(unsigned int sz) {
1731         ER ercd;
1732         void *p = NULL;
1733         ercd = tk_get_mpl(ID_wolfssl_MPOOL, sz, (VP)&p, TMO_FEVR);
1734         if (ercd == E_OK) {
1735             return p;
1736         } else {
1737             return 0;
1738         }
1739     }
1740 
uTKernel_realloc(void * p,unsigned int sz)1741     void *uTKernel_realloc(void *p, unsigned int sz) {
1742       ER ercd;
1743       void *newp = NULL;
1744       if (p) {
1745           ercd = tk_get_mpl(ID_wolfssl_MPOOL, sz, (VP)&newp, TMO_FEVR);
1746           if (ercd == E_OK) {
1747               XMEMCPY(newp, p, sz);
1748               ercd = tk_rel_mpl(ID_wolfssl_MPOOL, (VP)p);
1749               if (ercd == E_OK) {
1750                   return newp;
1751               }
1752           }
1753       }
1754       return 0;
1755     }
1756 
uTKernel_free(void * p)1757     void uTKernel_free(void *p) {
1758         ER ercd;
1759         ercd = tk_rel_mpl(ID_wolfssl_MPOOL, (VP)p);
1760         if (ercd == E_OK) {
1761             return;
1762         } else {
1763             return;
1764         }
1765     }
1766 
1767 #elif defined (WOLFSSL_FROSTED)
1768 
wc_InitMutex(wolfSSL_Mutex * m)1769     int wc_InitMutex(wolfSSL_Mutex* m)
1770     {
1771         *m = mutex_init();
1772         if (*m)
1773             return 0;
1774         else
1775             return -1;
1776     }
1777 
wc_FreeMutex(wolfSSL_Mutex * m)1778     int wc_FreeMutex(wolfSSL_Mutex* m)
1779     {
1780         mutex_destroy(*m);
1781         return(0);
1782     }
1783 
wc_LockMutex(wolfSSL_Mutex * m)1784     int wc_LockMutex(wolfSSL_Mutex* m)
1785     {
1786         mutex_lock(*m);
1787         return 0;
1788     }
1789 
wc_UnLockMutex(wolfSSL_Mutex * m)1790     int wc_UnLockMutex(wolfSSL_Mutex* m)
1791     {
1792         mutex_unlock(*m);
1793         return 0;
1794     }
1795 
1796 #elif defined(WOLFSSL_CMSIS_RTOS)
1797 
1798     #define CMSIS_NMUTEX 10
1799     osMutexDef(wolfSSL_mt0);  osMutexDef(wolfSSL_mt1);  osMutexDef(wolfSSL_mt2);
1800     osMutexDef(wolfSSL_mt3);  osMutexDef(wolfSSL_mt4);  osMutexDef(wolfSSL_mt5);
1801     osMutexDef(wolfSSL_mt6);  osMutexDef(wolfSSL_mt7);  osMutexDef(wolfSSL_mt8);
1802     osMutexDef(wolfSSL_mt9);
1803 
1804     static const osMutexDef_t *CMSIS_mutex[] = { osMutex(wolfSSL_mt0),
1805         osMutex(wolfSSL_mt1),    osMutex(wolfSSL_mt2),   osMutex(wolfSSL_mt3),
1806         osMutex(wolfSSL_mt4),    osMutex(wolfSSL_mt5),   osMutex(wolfSSL_mt6),
1807         osMutex(wolfSSL_mt7),    osMutex(wolfSSL_mt8),   osMutex(wolfSSL_mt9) };
1808 
1809     static osMutexId CMSIS_mutexID[CMSIS_NMUTEX] = {0};
1810 
wc_InitMutex(wolfSSL_Mutex * m)1811     int wc_InitMutex(wolfSSL_Mutex* m)
1812     {
1813         int i;
1814         for (i=0; i<CMSIS_NMUTEX; i++) {
1815             if(CMSIS_mutexID[i] == 0) {
1816                 CMSIS_mutexID[i] = osMutexCreate(CMSIS_mutex[i]);
1817                 (*m) = CMSIS_mutexID[i];
1818             return 0;
1819             }
1820         }
1821         return -1;
1822     }
1823 
wc_FreeMutex(wolfSSL_Mutex * m)1824     int wc_FreeMutex(wolfSSL_Mutex* m)
1825     {
1826         int i;
1827         osMutexDelete   (*m);
1828         for (i=0; i<CMSIS_NMUTEX; i++) {
1829             if(CMSIS_mutexID[i] == (*m)) {
1830                 CMSIS_mutexID[i] = 0;
1831                 return(0);
1832             }
1833         }
1834         return(-1);
1835     }
1836 
wc_LockMutex(wolfSSL_Mutex * m)1837     int wc_LockMutex(wolfSSL_Mutex* m)
1838     {
1839         osMutexWait(*m, osWaitForever);
1840         return(0);
1841     }
1842 
wc_UnLockMutex(wolfSSL_Mutex * m)1843     int wc_UnLockMutex(wolfSSL_Mutex* m)
1844     {
1845         osMutexRelease (*m);
1846         return 0;
1847     }
1848 
1849 #elif defined(WOLFSSL_CMSIS_RTOSv2)
wc_InitMutex(wolfSSL_Mutex * m)1850     int wc_InitMutex(wolfSSL_Mutex *m)
1851     {
1852         static const osMutexAttr_t attr = {
1853             "wolfSSL_mutex", osMutexRecursive, NULL, 0};
1854 
1855         if ((*m = osMutexNew(&attr)) != NULL)
1856             return 0;
1857         else
1858             return BAD_MUTEX_E;
1859     }
1860 
wc_FreeMutex(wolfSSL_Mutex * m)1861     int wc_FreeMutex(wolfSSL_Mutex *m)
1862     {
1863         if (osMutexDelete(*m) == osOK)
1864             return 0;
1865         else
1866             return BAD_MUTEX_E;
1867     }
1868 
1869 
wc_LockMutex(wolfSSL_Mutex * m)1870     int wc_LockMutex(wolfSSL_Mutex *m)
1871     {
1872         if (osMutexAcquire(*m, osWaitForever) == osOK)
1873             return 0;
1874         else
1875             return BAD_MUTEX_E;
1876     }
1877 
wc_UnLockMutex(wolfSSL_Mutex * m)1878     int wc_UnLockMutex(wolfSSL_Mutex *m)
1879     {
1880         if (osMutexRelease(*m) == osOK)
1881             return 0;
1882         else
1883             return BAD_MUTEX_E;
1884     }
1885 
1886 #elif defined(WOLFSSL_MDK_ARM)
1887 
wc_InitMutex(wolfSSL_Mutex * m)1888     int wc_InitMutex(wolfSSL_Mutex* m)
1889     {
1890         os_mut_init (m);
1891         return 0;
1892     }
1893 
wc_FreeMutex(wolfSSL_Mutex * m)1894     int wc_FreeMutex(wolfSSL_Mutex* m)
1895     {
1896         return(0);
1897     }
1898 
wc_LockMutex(wolfSSL_Mutex * m)1899     int wc_LockMutex(wolfSSL_Mutex* m)
1900     {
1901         os_mut_wait (m, 0xffff);
1902         return(0);
1903     }
1904 
wc_UnLockMutex(wolfSSL_Mutex * m)1905     int wc_UnLockMutex(wolfSSL_Mutex* m)
1906     {
1907         os_mut_release (m);
1908         return 0;
1909     }
1910 
1911 #elif defined(INTIME_RTOS)
1912 
wc_InitMutex(wolfSSL_Mutex * m)1913     int wc_InitMutex(wolfSSL_Mutex* m)
1914     {
1915         int ret = 0;
1916 
1917         if (m == NULL)
1918             return BAD_FUNC_ARG;
1919 
1920         *m = CreateRtSemaphore(
1921             1,                      /* initial unit count */
1922             1,                      /* maximum unit count */
1923             PRIORITY_QUEUING        /* creation flags: FIFO_QUEUING or PRIORITY_QUEUING */
1924         );
1925         if (*m == BAD_RTHANDLE) {
1926             ret = GetLastRtError();
1927             if (ret != E_OK)
1928                 ret = BAD_MUTEX_E;
1929         }
1930         return ret;
1931     }
1932 
wc_FreeMutex(wolfSSL_Mutex * m)1933     int wc_FreeMutex(wolfSSL_Mutex* m)
1934     {
1935         int ret = 0;
1936         BOOLEAN del;
1937 
1938         if (m == NULL)
1939             return BAD_FUNC_ARG;
1940 
1941         del = DeleteRtSemaphore(
1942             *m                      /* handle for RT semaphore */
1943         );
1944         if (del != TRUE)
1945             ret = BAD_MUTEX_E;
1946 
1947         return ret;
1948     }
1949 
wc_LockMutex(wolfSSL_Mutex * m)1950     int wc_LockMutex(wolfSSL_Mutex* m)
1951     {
1952         int ret = 0;
1953         DWORD lck;
1954 
1955         if (m == NULL)
1956             return BAD_FUNC_ARG;
1957 
1958         lck = WaitForRtSemaphore(
1959             *m,                     /* handle for RT semaphore */
1960             1,                      /* number of units to wait for */
1961             WAIT_FOREVER            /* number of milliseconds to wait for units */
1962         );
1963         if (lck == WAIT_FAILED) {
1964             ret = GetLastRtError();
1965             if (ret != E_OK)
1966                 ret = BAD_MUTEX_E;
1967         }
1968         return ret;
1969     }
1970 
wc_UnLockMutex(wolfSSL_Mutex * m)1971     int wc_UnLockMutex(wolfSSL_Mutex* m)
1972     {
1973         int ret = 0;
1974         BOOLEAN rel;
1975 
1976         if (m == NULL)
1977             return BAD_FUNC_ARG;
1978 
1979         rel = ReleaseRtSemaphore(
1980             *m,                     /* handle for RT semaphore */
1981             1                       /* number of units to release to semaphore */
1982         );
1983         if (rel != TRUE)
1984             ret = BAD_MUTEX_E;
1985 
1986         return ret;
1987     }
1988 
1989 #elif defined(WOLFSSL_NUCLEUS_1_2)
1990 
wc_InitMutex(wolfSSL_Mutex * m)1991     int wc_InitMutex(wolfSSL_Mutex* m)
1992     {
1993         /* Call the Nucleus function to create the semaphore */
1994         if (NU_Create_Semaphore(m, "WOLFSSL_MTX", 1,
1995                                 NU_PRIORITY) == NU_SUCCESS) {
1996             return 0;
1997         }
1998 
1999         return BAD_MUTEX_E;
2000     }
2001 
wc_FreeMutex(wolfSSL_Mutex * m)2002     int wc_FreeMutex(wolfSSL_Mutex* m)
2003     {
2004         if (NU_Delete_Semaphore(m) == NU_SUCCESS)
2005             return 0;
2006 
2007         return BAD_MUTEX_E;
2008     }
2009 
wc_LockMutex(wolfSSL_Mutex * m)2010     int wc_LockMutex(wolfSSL_Mutex* m)
2011     {
2012         /* passing suspend task option */
2013         if (NU_Obtain_Semaphore(m, NU_SUSPEND) == NU_SUCCESS)
2014             return 0;
2015 
2016         return BAD_MUTEX_E;
2017     }
2018 
wc_UnLockMutex(wolfSSL_Mutex * m)2019     int wc_UnLockMutex(wolfSSL_Mutex* m)
2020     {
2021         if (NU_Release_Semaphore(m) == NU_SUCCESS)
2022             return 0;
2023 
2024         return BAD_MUTEX_E;
2025     }
2026 
2027 #elif defined(WOLFSSL_ZEPHYR)
2028 
wc_InitMutex(wolfSSL_Mutex * m)2029     int wc_InitMutex(wolfSSL_Mutex* m)
2030     {
2031         k_mutex_init(m);
2032 
2033         return 0;
2034     }
2035 
wc_FreeMutex(wolfSSL_Mutex * m)2036     int wc_FreeMutex(wolfSSL_Mutex* m)
2037     {
2038         return 0;
2039     }
2040 
wc_LockMutex(wolfSSL_Mutex * m)2041     int wc_LockMutex(wolfSSL_Mutex* m)
2042     {
2043         int ret = 0;
2044 
2045         if (k_mutex_lock(m, K_FOREVER) != 0)
2046             ret = BAD_MUTEX_E;
2047 
2048         return ret;
2049     }
2050 
wc_UnLockMutex(wolfSSL_Mutex * m)2051     int wc_UnLockMutex(wolfSSL_Mutex* m)
2052     {
2053         k_mutex_unlock(m);
2054 
2055         return 0;
2056     }
2057 
2058 #elif defined(WOLFSSL_TELIT_M2MB)
2059 
wc_InitMutex(wolfSSL_Mutex * m)2060     int wc_InitMutex(wolfSSL_Mutex* m)
2061     {
2062         M2MB_OS_RESULT_E        osRes;
2063         M2MB_OS_MTX_ATTR_HANDLE mtxAttrHandle;
2064         UINT32                  inheritVal = 1;
2065 
2066         osRes = m2mb_os_mtx_setAttrItem(&mtxAttrHandle,
2067                                     CMDS_ARGS(
2068                                       M2MB_OS_MTX_SEL_CMD_CREATE_ATTR, NULL,
2069                                       M2MB_OS_MTX_SEL_CMD_NAME, "wolfMtx",
2070                                       M2MB_OS_MTX_SEL_CMD_INHERIT, inheritVal
2071                                     )
2072                                 );
2073         if (osRes != M2MB_OS_SUCCESS) {
2074             return BAD_MUTEX_E;
2075         }
2076 
2077         osRes = m2mb_os_mtx_init(m, &mtxAttrHandle);
2078         if (osRes != M2MB_OS_SUCCESS) {
2079             return BAD_MUTEX_E;
2080         }
2081 
2082         return 0;
2083     }
2084 
wc_FreeMutex(wolfSSL_Mutex * m)2085     int wc_FreeMutex(wolfSSL_Mutex* m)
2086     {
2087         M2MB_OS_RESULT_E osRes;
2088 
2089         if (m == NULL)
2090             return BAD_MUTEX_E;
2091 
2092         osRes = m2mb_os_mtx_deinit(*m);
2093         if (osRes != M2MB_OS_SUCCESS) {
2094             return BAD_MUTEX_E;
2095         }
2096 
2097         return 0;
2098     }
2099 
wc_LockMutex(wolfSSL_Mutex * m)2100     int wc_LockMutex(wolfSSL_Mutex* m)
2101     {
2102         M2MB_OS_RESULT_E osRes;
2103 
2104         if (m == NULL)
2105             return BAD_MUTEX_E;
2106 
2107         osRes = m2mb_os_mtx_get(*m, M2MB_OS_WAIT_FOREVER);
2108         if (osRes != M2MB_OS_SUCCESS) {
2109             return BAD_MUTEX_E;
2110         }
2111 
2112         return 0;
2113     }
2114 
wc_UnLockMutex(wolfSSL_Mutex * m)2115     int wc_UnLockMutex(wolfSSL_Mutex* m)
2116     {
2117         M2MB_OS_RESULT_E osRes;
2118 
2119         if (m == NULL)
2120             return BAD_MUTEX_E;
2121 
2122         osRes = m2mb_os_mtx_put(*m);
2123         if (osRes != M2MB_OS_SUCCESS) {
2124             return BAD_MUTEX_E;
2125         }
2126 
2127         return 0;
2128     }
2129 
2130 #elif defined(WOLFSSL_USER_MUTEX)
2131 
2132     /* Use user own mutex */
2133 
2134     /*
2135     int wc_InitMutex(wolfSSL_Mutex* m) { ... }
2136     int wc_FreeMutex(wolfSSL_Mutex *m) { ... }
2137     int wc_LockMutex(wolfSSL_Mutex *m) { ... }
2138     int wc_UnLockMutex(wolfSSL_Mutex *m) { ... }
2139     */
2140 
2141 #else
2142     #warning No mutex handling defined
2143 
2144 #endif
2145 
2146 #ifndef NO_ASN_TIME
2147 #if defined(_WIN32_WCE)
windows_time(time_t * timer)2148 time_t windows_time(time_t* timer)
2149 {
2150     SYSTEMTIME     sysTime;
2151     FILETIME       fTime;
2152     ULARGE_INTEGER intTime;
2153     time_t         localTime;
2154 
2155     if (timer == NULL)
2156         timer = &localTime;
2157 
2158     GetSystemTime(&sysTime);
2159     SystemTimeToFileTime(&sysTime, &fTime);
2160 
2161     XMEMCPY(&intTime, &fTime, sizeof(FILETIME));
2162     /* subtract EPOCH */
2163     intTime.QuadPart -= 0x19db1ded53e8000;
2164     /* to secs */
2165     intTime.QuadPart /= 10000000;
2166     *timer = (time_t)intTime.QuadPart;
2167 
2168     return *timer;
2169 }
2170 #endif /*  _WIN32_WCE */
2171 
2172 #if defined(WOLFSSL_APACHE_MYNEWT)
2173 #include "os/os_time.h"
2174 
mynewt_time(time_t * timer)2175 time_t mynewt_time(time_t* timer)
2176 {
2177     time_t now;
2178     struct os_timeval tv;
2179     os_gettimeofday(&tv, NULL);
2180     now = (time_t)tv.tv_sec;
2181     if(timer != NULL) {
2182         *timer = now;
2183     }
2184     return now;
2185 }
2186 #endif /* WOLFSSL_APACHE_MYNEWT */
2187 
2188 #if defined(WOLFSSL_GMTIME)
gmtime(const time_t * timer)2189 struct tm* gmtime(const time_t* timer)
2190 {
2191     #define YEAR0          1900
2192     #define EPOCH_YEAR     1970
2193     #define SECS_DAY       (24L * 60L * 60L)
2194     #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400)))
2195     #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
2196 
2197     static const int _ytab[2][12] =
2198     {
2199         {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
2200         {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
2201     };
2202 
2203     static struct tm st_time;
2204     struct tm* ret = &st_time;
2205     time_t secs = *timer;
2206     unsigned long dayclock, dayno;
2207     int year = EPOCH_YEAR;
2208 
2209     dayclock = (unsigned long)secs % SECS_DAY;
2210     dayno    = (unsigned long)secs / SECS_DAY;
2211 
2212     ret->tm_sec  = (int) dayclock % 60;
2213     ret->tm_min  = (int)(dayclock % 3600) / 60;
2214     ret->tm_hour = (int) dayclock / 3600;
2215     ret->tm_wday = (int) (dayno + 4) % 7;        /* day 0 a Thursday */
2216 
2217     while(dayno >= (unsigned long)YEARSIZE(year)) {
2218         dayno -= YEARSIZE(year);
2219         year++;
2220     }
2221 
2222     ret->tm_year = year - YEAR0;
2223     ret->tm_yday = (int)dayno;
2224     ret->tm_mon  = 0;
2225 
2226     while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) {
2227         dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon];
2228         ret->tm_mon++;
2229     }
2230 
2231     ret->tm_mday  = (int)++dayno;
2232 #ifndef WOLFSSL_LINUXKM
2233     ret->tm_isdst = 0;
2234 #endif
2235 
2236     return ret;
2237 }
2238 #endif /* WOLFSSL_GMTIME */
2239 
2240 
2241 #if defined(HAVE_RTP_SYS)
2242 #define YEAR0          1900
2243 
rtpsys_gmtime(const time_t * timer)2244 struct tm* rtpsys_gmtime(const time_t* timer)       /* has a gmtime() but hangs */
2245 {
2246     static struct tm st_time;
2247     struct tm* ret = &st_time;
2248 
2249     DC_RTC_CALENDAR cal;
2250     dc_rtc_time_get(&cal, TRUE);
2251 
2252     ret->tm_year  = cal.year - YEAR0;       /* gm starts at 1900 */
2253     ret->tm_mon   = cal.month - 1;          /* gm starts at 0 */
2254     ret->tm_mday  = cal.day;
2255     ret->tm_hour  = cal.hour;
2256     ret->tm_min   = cal.minute;
2257     ret->tm_sec   = cal.second;
2258 
2259     return ret;
2260 }
2261 
2262 #endif /* HAVE_RTP_SYS */
2263 
2264 
2265 #if defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
2266 
2267 /*
2268  * time() is just a stub in Microchip libraries. We need our own
2269  * implementation. Use SNTP client to get seconds since epoch.
2270  */
pic32_time(time_t * timer)2271 time_t pic32_time(time_t* timer)
2272 {
2273 #ifdef MICROCHIP_TCPIP_V5
2274     DWORD sec = 0;
2275 #else
2276     word32 sec = 0;
2277 #endif
2278     time_t localTime;
2279 
2280     if (timer == NULL)
2281         timer = &localTime;
2282 
2283 #ifdef MICROCHIP_MPLAB_HARMONY
2284     sec = TCPIP_SNTP_UTCSecondsGet();
2285 #else
2286     sec = SNTPGetUTCSeconds();
2287 #endif
2288     *timer = (time_t) sec;
2289 
2290     return *timer;
2291 }
2292 
2293 #endif /* MICROCHIP_TCPIP || MICROCHIP_TCPIP_V5 */
2294 
2295 #if defined(WOLFSSL_DEOS)
2296 
deos_time(time_t * timer)2297 time_t deos_time(time_t* timer)
2298 {
2299     const word32 systemTickTimeInHz = 1000000 / systemTickInMicroseconds();
2300     const volatile word32 *systemTickPtr = systemTickPointer();
2301 
2302     if (timer != NULL)
2303         *timer = *systemTickPtr/systemTickTimeInHz;
2304 
2305     #if defined(CURRENT_UNIX_TIMESTAMP)
2306         /* CURRENT_UNIX_TIMESTAMP is seconds since Jan 01 1970. (UTC) */
2307         return (time_t) (*systemTickPtr/systemTickTimeInHz) + CURRENT_UNIX_TIMESTAMP;
2308     #else
2309         return (time_t) *systemTickPtr/systemTickTimeInHz;
2310     #endif
2311 }
2312 #endif /* WOLFSSL_DEOS */
2313 
2314 #if defined(MICRIUM)
2315 
micrium_time(time_t * timer)2316 time_t micrium_time(time_t* timer)
2317 {
2318     CLK_TS_SEC sec;
2319 
2320     Clk_GetTS_Unix(&sec);
2321 
2322     if (timer != NULL)
2323         *timer = sec;
2324 
2325     return (time_t) sec;
2326 }
2327 
2328 #endif /* MICRIUM */
2329 
2330 #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
2331 
mqx_time(time_t * timer)2332 time_t mqx_time(time_t* timer)
2333 {
2334     time_t localTime;
2335     TIME_STRUCT time_s;
2336 
2337     if (timer == NULL)
2338         timer = &localTime;
2339 
2340     _time_get(&time_s);
2341     *timer = (time_t) time_s.SECONDS;
2342 
2343     return *timer;
2344 }
2345 
2346 #endif /* FREESCALE_MQX || FREESCALE_KSDK_MQX */
2347 
2348 
2349 #if defined(WOLFSSL_TIRTOS) && defined(USER_TIME)
2350 
XTIME(time_t * timer)2351 time_t XTIME(time_t * timer)
2352 {
2353     time_t sec = 0;
2354 
2355     sec = (time_t) Seconds_get();
2356 
2357     if (timer != NULL)
2358         *timer = sec;
2359 
2360     return sec;
2361 }
2362 
2363 #endif /* WOLFSSL_TIRTOS */
2364 
2365 #if defined(WOLFSSL_XILINX)
2366 #include "xrtcpsu.h"
2367 
xilinx_time(time_t * timer)2368 time_t xilinx_time(time_t * timer)
2369 {
2370     time_t sec = 0;
2371     XRtcPsu_Config* con;
2372     XRtcPsu         rtc;
2373 
2374     con = XRtcPsu_LookupConfig(XPAR_XRTCPSU_0_DEVICE_ID);
2375     if (con != NULL) {
2376         if (XRtcPsu_CfgInitialize(&rtc, con, con->BaseAddr) == XST_SUCCESS) {
2377             sec = (time_t)XRtcPsu_GetCurrentTime(&rtc);
2378         }
2379         else {
2380             WOLFSSL_MSG("Unable to initialize RTC");
2381         }
2382     }
2383 
2384     if (timer != NULL)
2385         *timer = sec;
2386 
2387     return sec;
2388 }
2389 
2390 #endif /* WOLFSSL_XILINX */
2391 
2392 #if defined(WOLFSSL_ZEPHYR)
2393 
z_time(time_t * timer)2394 time_t z_time(time_t * timer)
2395 {
2396     struct timespec ts;
2397 
2398     if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
2399         if (timer != NULL)
2400             *timer = ts.tv_sec;
2401 
2402     return ts.tv_sec;
2403 }
2404 
2405 #endif /* WOLFSSL_ZEPHYR */
2406 
2407 
2408 #if defined(WOLFSSL_WICED)
2409     #ifndef WOLFSSL_WICED_PSEUDO_UNIX_EPOCH_TIME
2410         #error Please define WOLFSSL_WICED_PSEUDO_UNIX_EPOCH_TIME at build time.
2411     #endif /* WOLFSSL_WICED_PSEUDO_UNIX_EPOCH_TIME */
2412 
wiced_pseudo_unix_epoch_time(time_t * timer)2413 time_t wiced_pseudo_unix_epoch_time(time_t * timer)
2414 {
2415     time_t epoch_time;
2416     /* The time() function return uptime on WICED platform. */
2417     epoch_time = time(NULL) + WOLFSSL_WICED_PSEUDO_UNIX_EPOCH_TIME;
2418 
2419     if (timer != NULL) {
2420         *timer = epoch_time;
2421     }
2422     return epoch_time;
2423 }
2424 #endif /* WOLFSSL_WICED */
2425 
2426 #ifdef WOLFSSL_TELIT_M2MB
m2mb_xtime(time_t * timer)2427     time_t m2mb_xtime(time_t * timer)
2428     {
2429         time_t myTime = 0;
2430         INT32 fd = m2mb_rtc_open("/dev/rtc0", 0);
2431         if (fd != -1) {
2432             M2MB_RTC_TIMEVAL_T timeval;
2433 
2434             m2mb_rtc_ioctl(fd, M2MB_RTC_IOCTL_GET_TIMEVAL, &timeval);
2435 
2436             myTime = timeval.sec;
2437 
2438             m2mb_rtc_close(fd);
2439         }
2440         return myTime;
2441     }
2442     #ifdef WOLFSSL_TLS13
m2mb_xtime_ms(time_t * timer)2443     time_t m2mb_xtime_ms(time_t * timer)
2444     {
2445         time_t myTime = 0;
2446         INT32 fd = m2mb_rtc_open("/dev/rtc0", 0);
2447         if (fd != -1) {
2448             M2MB_RTC_TIMEVAL_T timeval;
2449 
2450             m2mb_rtc_ioctl(fd, M2MB_RTC_IOCTL_GET_TIMEVAL, &timeval);
2451 
2452             myTime = timeval.sec + timeval.msec;
2453 
2454             m2mb_rtc_close(fd);
2455         }
2456         return myTime;
2457     }
2458     #endif /* WOLFSSL_TLS13 */
2459     #ifndef NO_CRYPT_BENCHMARK
m2mb_xtime_bench(int reset)2460     double m2mb_xtime_bench(int reset)
2461     {
2462         double myTime = 0;
2463         INT32 fd = m2mb_rtc_open("/dev/rtc0", 0);
2464         if (fd != -1) {
2465             M2MB_RTC_TIMEVAL_T timeval;
2466 
2467             m2mb_rtc_ioctl(fd, M2MB_RTC_IOCTL_GET_TIMEVAL, &timeval);
2468 
2469             myTime = (double)timeval.sec + ((double)timeval.msec / 1000);
2470 
2471             m2mb_rtc_close(fd);
2472         }
2473         return myTime;
2474     }
2475     #endif /* !NO_CRYPT_BENCHMARK */
2476 #endif /* WOLFSSL_TELIT_M2MB */
2477 
2478 
2479 #if defined(WOLFSSL_LINUXKM)
time(time_t * timer)2480 time_t time(time_t * timer)
2481 {
2482     time_t ret;
2483 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
2484     struct timespec ts;
2485     getnstimeofday(&ts);
2486     ret = ts.tv_sec;
2487 #else
2488     struct timespec64 ts;
2489 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)
2490     ts = current_kernel_time64();
2491 #else
2492     ktime_get_coarse_real_ts64(&ts);
2493 #endif
2494     ret = ts.tv_sec;
2495 #endif
2496     if (timer)
2497         *timer = ret;
2498     return ret;
2499 }
2500 #endif /* WOLFSSL_LINUXKM */
2501 
2502 #ifdef HAL_RTC_MODULE_ENABLED
2503 extern RTC_HandleTypeDef hrtc;
stm32_hal_time(time_t * t1)2504 time_t stm32_hal_time(time_t *t1)
2505 {
2506     struct tm tm_time;
2507     time_t ret;
2508     RTC_TimeTypeDef time;
2509     RTC_DateTypeDef date;
2510 
2511     /* order of GetTime followed by GetDate required here due to STM32 HW
2512      * requirement */
2513     HAL_RTC_GetTime(&hrtc, &time, FORMAT_BIN);
2514     HAL_RTC_GetDate(&hrtc, &date, FORMAT_BIN);
2515 
2516     tm_time.tm_year  = date.Year;
2517     tm_time.tm_mon   = date.Month - 1;          /* gm starts at 0 */
2518     tm_time.tm_mday  = date.Date;
2519     tm_time.tm_hour  = time.Hours;
2520     tm_time.tm_min   = time.Minutes;
2521     tm_time.tm_sec   = time.Seconds;
2522 
2523     ret = mktime(&tm_time);
2524     if (t1 != NULL)
2525         *t1 = ret;
2526     return ret;
2527 }
2528 #endif /* HAL_RTC_MODULE_ENABLED */
2529 
2530 #endif /* !NO_ASN_TIME */
2531 
2532 #if !defined(WOLFSSL_LEANPSK) && !defined(STRING_USER)
mystrnstr(const char * s1,const char * s2,unsigned int n)2533 char* mystrnstr(const char* s1, const char* s2, unsigned int n)
2534 {
2535     unsigned int s2_len = (unsigned int)XSTRLEN(s2);
2536 
2537     if (s2_len == 0)
2538         return (char*)s1;
2539 
2540     while (n >= s2_len && s1[0]) {
2541         if (s1[0] == s2[0])
2542             if (XMEMCMP(s1, s2, s2_len) == 0)
2543                 return (char*)s1;
2544         s1++;
2545         n--;
2546     }
2547 
2548     return NULL;
2549 }
2550 #endif
2551 
2552 /* custom memory wrappers */
2553 #ifdef WOLFSSL_NUCLEUS_1_2
2554 
2555     /* system memory pool */
2556     extern NU_MEMORY_POOL System_Memory;
2557 
nucleus_malloc(unsigned long size,void * heap,int type)2558     void* nucleus_malloc(unsigned long size, void* heap, int type)
2559     {
2560         STATUS status;
2561         void*  stack_ptr;
2562 
2563         status = NU_Allocate_Memory(&System_Memory, &stack_ptr, size,
2564                                     NU_NO_SUSPEND);
2565         if (status == NU_SUCCESS) {
2566             return 0;
2567         } else {
2568             return stack_ptr;
2569         }
2570     }
2571 
nucleus_realloc(void * ptr,unsigned long size,void * heap,int type)2572     void* nucleus_realloc(void* ptr, unsigned long size, void* heap, int type)
2573     {
2574         DM_HEADER* old_header;
2575         word32     old_size, copy_size;
2576         void*      new_mem;
2577 
2578         /* if ptr is NULL, behave like malloc */
2579         new_mem = nucleus_malloc(size, NULL, 0);
2580         if (new_mem == 0 || ptr == 0) {
2581             return new_mem;
2582         }
2583 
2584         /* calculate old memory block size */
2585         /* mem pointers stored in block headers (ref dm_defs.h) */
2586         old_header = (DM_HEADER*) ((byte*)ptr - DM_OVERHEAD);
2587         old_size   = (byte*)old_header->dm_next_memory - (byte*)ptr;
2588 
2589         /* copy old to new */
2590         if (old_size < size) {
2591             copy_size = old_size;
2592         } else {
2593             copy_size = size;
2594         }
2595         XMEMCPY(new_mem, ptr, copy_size);
2596 
2597         /* free old */
2598         nucleus_free(ptr, NULL, 0);
2599 
2600         return new_mem;
2601     }
2602 
nucleus_free(void * ptr,void * heap,int type)2603     void nucleus_free(void* ptr, void* heap, int type)
2604     {
2605         if (ptr != NULL)
2606             NU_Deallocate_Memory(ptr);
2607     }
2608 
2609 #endif /* WOLFSSL_NUCLEUS_1_2 */
2610 
2611 #if defined(WOLFSSL_LINUXKM) && defined(HAVE_KVMALLOC)
2612     /* adapted from kvrealloc() draft by Changli Gao, 2010-05-13 */
lkm_realloc(void * ptr,size_t newsize)2613     void *lkm_realloc(void *ptr, size_t newsize) {
2614         void *nptr;
2615         size_t oldsize;
2616 
2617         if (unlikely(newsize == 0)) {
2618             kvfree(ptr);
2619             return ZERO_SIZE_PTR;
2620         }
2621 
2622         if (unlikely(ptr == NULL))
2623             return kvmalloc_node(newsize, GFP_KERNEL, NUMA_NO_NODE);
2624 
2625         if (is_vmalloc_addr(ptr)) {
2626             /* no way to discern the size of the old allocation,
2627              * because the kernel doesn't export find_vm_area().  if
2628              * it did, we could then call get_vm_area_size() on the
2629              * returned struct vm_struct.
2630              */
2631             return NULL;
2632         } else {
2633 #ifndef __PIE__
2634             struct page *page;
2635 
2636             page = virt_to_head_page(ptr);
2637             if (PageSlab(page) || PageCompound(page)) {
2638                 if (newsize < PAGE_SIZE)
2639 #endif /* ! __PIE__ */
2640                     return krealloc(ptr, newsize, GFP_KERNEL);
2641 #ifndef __PIE__
2642                 oldsize = ksize(ptr);
2643             } else {
2644                 oldsize = page->private;
2645                 if (newsize <= oldsize)
2646                     return ptr;
2647             }
2648 #endif /* ! __PIE__ */
2649         }
2650 
2651         nptr = kvmalloc_node(newsize, GFP_KERNEL, NUMA_NO_NODE);
2652         if (nptr != NULL) {
2653             memcpy(nptr, ptr, oldsize);
2654             kvfree(ptr);
2655         }
2656 
2657         return nptr;
2658     }
2659 #endif /* WOLFSSL_LINUXKM && HAVE_KVMALLOC */
2660 
2661 #if defined(WOLFSSL_TI_CRYPT) || defined(WOLFSSL_TI_HASH)
2662     #include <wolfcrypt/src/port/ti/ti-ccm.c>  /* initialize and Mutex for TI Crypt Engine */
2663     #include <wolfcrypt/src/port/ti/ti-hash.c> /* md5, sha1, sha224, sha256 */
2664 #endif
2665 
2666 #if defined(WOLFSSL_CRYPTOCELL)
2667     #define WOLFSSL_CRYPTOCELL_C
2668     #include <wolfcrypt/src/port/arm/cryptoCell.c> /* CC310, RTC and RNG */
2669     #if !defined(NO_SHA256)
2670         #define WOLFSSL_CRYPTOCELL_HASH_C
2671         #include <wolfcrypt/src/port/arm/cryptoCellHash.c> /* sha256 */
2672     #endif
2673 #endif
2674