1 /* sha.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 
29 #if !defined(NO_SHA)
30 
31 #if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
32     /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
33     #define FIPS_NO_WRAPPERS
34 
35     #ifdef USE_WINDOWS_API
36         #pragma code_seg(".fipsA$j")
37         #pragma const_seg(".fipsB$j")
38     #endif
39 #endif
40 
41 #include <wolfssl/wolfcrypt/sha.h>
42 #include <wolfssl/wolfcrypt/error-crypt.h>
43 #include <wolfssl/wolfcrypt/hash.h>
44 
45 #ifdef WOLF_CRYPTO_CB
46     #include <wolfssl/wolfcrypt/cryptocb.h>
47 #endif
48 
49 /* fips wrapper calls, user can call direct */
50 #if defined(HAVE_FIPS) && \
51     (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
52 
wc_InitSha(wc_Sha * sha)53     int wc_InitSha(wc_Sha* sha)
54     {
55         if (sha == NULL) {
56             return BAD_FUNC_ARG;
57         }
58         return InitSha_fips(sha);
59     }
wc_InitSha_ex(wc_Sha * sha,void * heap,int devId)60     int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
61     {
62         (void)heap;
63         (void)devId;
64         if (sha == NULL) {
65             return BAD_FUNC_ARG;
66         }
67         return InitSha_fips(sha);
68     }
69 
wc_ShaUpdate(wc_Sha * sha,const byte * data,word32 len)70     int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
71     {
72         if (sha == NULL || (data == NULL && len > 0)) {
73             return BAD_FUNC_ARG;
74         }
75         return ShaUpdate_fips(sha, data, len);
76     }
77 
wc_ShaFinal(wc_Sha * sha,byte * out)78     int wc_ShaFinal(wc_Sha* sha, byte* out)
79     {
80         if (sha == NULL || out == NULL) {
81             return BAD_FUNC_ARG;
82         }
83         return ShaFinal_fips(sha,out);
84     }
wc_ShaFree(wc_Sha * sha)85     void wc_ShaFree(wc_Sha* sha)
86     {
87         (void)sha;
88         /* Not supported in FIPS */
89     }
90 
91 #else /* else build without fips, or for FIPS v2 */
92 
93 
94 #if defined(WOLFSSL_TI_HASH)
95     /* #include <wolfcrypt/src/port/ti/ti-hash.c> included by wc_port.c */
96 
97 #else
98 
99 #include <wolfssl/wolfcrypt/logging.h>
100 #ifdef NO_INLINE
101     #include <wolfssl/wolfcrypt/misc.h>
102 #else
103     #define WOLFSSL_MISC_INCLUDED
104     #include <wolfcrypt/src/misc.c>
105 #endif
106 
107 
108 /* Hardware Acceleration */
109 #if defined(WOLFSSL_PIC32MZ_HASH)
110     #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
111 
112 #elif defined(STM32_HASH)
113 
114     /* Supports CubeMX HAL or Standard Peripheral Library */
wc_InitSha_ex(wc_Sha * sha,void * heap,int devId)115     int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
116     {
117         if (sha == NULL) {
118             return BAD_FUNC_ARG;
119         }
120 
121         (void)devId;
122         (void)heap;
123 
124         wc_Stm32_Hash_Init(&sha->stmCtx);
125 
126         return 0;
127     }
128 
wc_ShaUpdate(wc_Sha * sha,const byte * data,word32 len)129     int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
130     {
131         int ret;
132 
133         if (sha == NULL || (data == NULL && len > 0)) {
134             return BAD_FUNC_ARG;
135         }
136 
137         ret = wolfSSL_CryptHwMutexLock();
138         if (ret == 0) {
139             ret = wc_Stm32_Hash_Update(&sha->stmCtx, HASH_AlgoSelection_SHA1,
140                 data, len);
141             wolfSSL_CryptHwMutexUnLock();
142         }
143         return ret;
144     }
145 
wc_ShaFinal(wc_Sha * sha,byte * hash)146     int wc_ShaFinal(wc_Sha* sha, byte* hash)
147     {
148         int ret;
149 
150         if (sha == NULL || hash == NULL) {
151             return BAD_FUNC_ARG;
152         }
153 
154         ret = wolfSSL_CryptHwMutexLock();
155         if (ret == 0) {
156             ret = wc_Stm32_Hash_Final(&sha->stmCtx, HASH_AlgoSelection_SHA1,
157                 hash, WC_SHA_DIGEST_SIZE);
158             wolfSSL_CryptHwMutexUnLock();
159         }
160 
161         (void)wc_InitSha(sha);  /* reset state */
162 
163         return ret;
164     }
165 
166 
167 #elif defined(FREESCALE_LTC_SHA)
168 
169     #include "fsl_ltc.h"
wc_InitSha_ex(wc_Sha * sha,void * heap,int devId)170     int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
171     {
172         if (sha == NULL) {
173             return BAD_FUNC_ARG;
174         }
175 
176         (void)devId;
177         (void)heap;
178 
179         LTC_HASH_Init(LTC_BASE, &sha->ctx, kLTC_Sha1, NULL, 0);
180         return 0;
181     }
182 
wc_ShaUpdate(wc_Sha * sha,const byte * data,word32 len)183     int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
184     {
185         LTC_HASH_Update(&sha->ctx, data, len);
186         return 0;
187     }
188 
wc_ShaFinal(wc_Sha * sha,byte * hash)189     int wc_ShaFinal(wc_Sha* sha, byte* hash)
190     {
191         word32 hashlen = WC_SHA_DIGEST_SIZE;
192         LTC_HASH_Finish(&sha->ctx, hash, &hashlen);
193         return wc_InitSha(sha);  /* reset state */
194     }
195 
196 
197 #elif defined(FREESCALE_MMCAU_SHA)
198 
199     #ifdef FREESCALE_MMCAU_CLASSIC_SHA
200         #include "cau_api.h"
201     #else
202         #include "fsl_mmcau.h"
203     #endif
204 
205     #define USE_SHA_SOFTWARE_IMPL /* Only for API's, actual transform is here */
206 
207     #define XTRANSFORM(S,B)       Transform((S),(B))
208     #define XTRANSFORM_LEN(S,B,L) Transform_Len((S),(B),(L))
209 
210     #ifndef WC_HASH_DATA_ALIGNMENT
211         /* these hardware API's require 4 byte (word32) alignment */
212         #define WC_HASH_DATA_ALIGNMENT 4
213     #endif
214 
InitSha(wc_Sha * sha)215     static int InitSha(wc_Sha* sha)
216     {
217         int ret = 0;
218         ret = wolfSSL_CryptHwMutexLock();
219         if (ret != 0) {
220             return ret;
221         }
222     #ifdef FREESCALE_MMCAU_CLASSIC_SHA
223         cau_sha1_initialize_output(sha->digest);
224     #else
225         MMCAU_SHA1_InitializeOutput((word32*)sha->digest);
226     #endif
227         wolfSSL_CryptHwMutexUnLock();
228 
229         sha->buffLen = 0;
230         sha->loLen   = 0;
231         sha->hiLen   = 0;
232 
233         return ret;
234     }
235 
Transform(wc_Sha * sha,const byte * data)236     static int Transform(wc_Sha* sha, const byte* data)
237     {
238         int ret = wolfSSL_CryptHwMutexLock();
239         if (ret == 0) {
240     #ifdef FREESCALE_MMCAU_CLASSIC_SHA
241             cau_sha1_hash_n((byte*)data, 1, sha->digest);
242     #else
243             MMCAU_SHA1_HashN((byte*)data, 1, (word32*)sha->digest);
244     #endif
245             wolfSSL_CryptHwMutexUnLock();
246         }
247         return ret;
248     }
249 
Transform_Len(wc_Sha * sha,const byte * data,word32 len)250     static int Transform_Len(wc_Sha* sha, const byte* data, word32 len)
251     {
252         int ret = wolfSSL_CryptHwMutexLock();
253         if (ret == 0) {
254         #if defined(WC_HASH_DATA_ALIGNMENT) && WC_HASH_DATA_ALIGNMENT > 0
255             if ((wc_ptr_t)data % WC_HASH_DATA_ALIGNMENT) {
256                 /* data pointer is NOT aligned,
257                  * so copy and perform one block at a time */
258                 byte* local = (byte*)sha->buffer;
259                 while (len >= WC_SHA_BLOCK_SIZE) {
260                     XMEMCPY(local, data, WC_SHA_BLOCK_SIZE);
261                 #ifdef FREESCALE_MMCAU_CLASSIC_SHA
262                     cau_sha1_hash_n(local, 1, sha->digest);
263                 #else
264                     MMCAU_SHA1_HashN(local, 1, sha->digest);
265                 #endif
266                     data += WC_SHA_BLOCK_SIZE;
267                     len  -= WC_SHA_BLOCK_SIZE;
268                 }
269             }
270             else
271         #endif
272             {
273     #ifdef FREESCALE_MMCAU_CLASSIC_SHA
274             cau_sha1_hash_n((byte*)data, len/WC_SHA_BLOCK_SIZE, sha->digest);
275     #else
276             MMCAU_SHA1_HashN((byte*)data, len/WC_SHA_BLOCK_SIZE,
277                 (word32*)sha->digest);
278     #endif
279             }
280             wolfSSL_CryptHwMutexUnLock();
281         }
282         return ret;
283     }
284 
285 #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \
286     !defined(WOLFSSL_QNX_CAAM)
287     /* wolfcrypt/src/port/caam/caam_sha.c */
288 
289 #elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
290      !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
291 
292     #include "wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h"
293 
294     #define USE_SHA_SOFTWARE_IMPL
295 
InitSha(wc_Sha * sha)296     static int InitSha(wc_Sha* sha)
297     {
298         int ret = 0;
299 
300         sha->digest[0] = 0x67452301L;
301         sha->digest[1] = 0xEFCDAB89L;
302         sha->digest[2] = 0x98BADCFEL;
303         sha->digest[3] = 0x10325476L;
304         sha->digest[4] = 0xC3D2E1F0L;
305 
306         sha->buffLen = 0;
307         sha->loLen   = 0;
308         sha->hiLen   = 0;
309 
310         /* always start firstblock = 1 when using hw engine */
311         sha->ctx.isfirstblock = 1;
312         sha->ctx.sha_type = SHA1;
313         if(sha->ctx.mode == ESP32_SHA_HW){
314             /* release hw engine */
315             esp_sha_hw_unlock();
316         }
317         /* always set mode as INIT
318         *  whether using HW or SW is determined at first call of update()
319         */
320         sha->ctx.mode = ESP32_SHA_INIT;
321 
322         return ret;
323     }
324 
325 #elif defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \
326     !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)
327 
328     /* implemented in wolfcrypt/src/port/Renesas/renesas_tsip_sha.c */
329 
330 #elif defined(WOLFSSL_IMXRT_DCP)
331     #include <wolfssl/wolfcrypt/port/nxp/dcp_port.h>
332     /* implemented in wolfcrypt/src/port/nxp/dcp_port.c */
333 
334 #elif defined(WOLFSSL_SILABS_SE_ACCEL)
335 
336     /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */
337 #elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
338 
339     #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
wc_InitSha_ex(wc_Sha * sha,void * heap,int devId)340     int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
341     {
342         if (sha == NULL) {
343             return BAD_FUNC_ARG;
344         }
345         (void)devId;
346 
347         return se050_hash_init(&sha->se050Ctx, heap);
348     }
349 
wc_ShaUpdate(wc_Sha * sha,const byte * data,word32 len)350     int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
351     {
352         return se050_hash_update(&sha->se050Ctx, data, len);
353 
354     }
355 
wc_ShaFinal(wc_Sha * sha,byte * hash)356     int wc_ShaFinal(wc_Sha* sha, byte* hash)
357     {
358         int ret = 0;
359         ret = se050_hash_final(&sha->se050Ctx, hash, WC_SHA_DIGEST_SIZE,
360                                kAlgorithm_SSS_SHA1);
361         (void)wc_InitSha(sha);
362         return ret;
363     }
wc_ShaFinalRaw(wc_Sha * sha,byte * hash)364     int wc_ShaFinalRaw(wc_Sha* sha, byte* hash)
365     {
366         int ret = 0;
367         ret = se050_hash_final(&sha->se050Ctx, hash, WC_SHA_DIGEST_SIZE,
368                                kAlgorithm_SSS_SHA1);
369         (void)wc_InitSha(sha);
370         return ret;
371     }
372 
373 #else
374     /* Software implementation */
375     #define USE_SHA_SOFTWARE_IMPL
376 
InitSha(wc_Sha * sha)377     static int InitSha(wc_Sha* sha)
378     {
379         int ret = 0;
380 
381         sha->digest[0] = 0x67452301L;
382         sha->digest[1] = 0xEFCDAB89L;
383         sha->digest[2] = 0x98BADCFEL;
384         sha->digest[3] = 0x10325476L;
385         sha->digest[4] = 0xC3D2E1F0L;
386 
387         sha->buffLen = 0;
388         sha->loLen   = 0;
389         sha->hiLen   = 0;
390     #ifdef WOLFSSL_HASH_FLAGS
391         sha->flags = 0;
392     #endif
393 
394         return ret;
395     }
396 #endif /* End Hardware Acceleration */
397 
398 /* Software implementation */
399 #ifdef USE_SHA_SOFTWARE_IMPL
400 
AddLength(wc_Sha * sha,word32 len)401 static WC_INLINE void AddLength(wc_Sha* sha, word32 len)
402 {
403     word32 tmp = sha->loLen;
404     if ((sha->loLen += len) < tmp)
405         sha->hiLen++;                       /* carry low to high */
406 }
407 
408 /* Check if custom wc_Sha transform is used */
409 #ifndef XTRANSFORM
410     #define XTRANSFORM(S,B)   Transform((S),(B))
411 
412     #define blk0(i) (W[i] = *((word32*)&data[i*sizeof(word32)]))
413     #define blk1(i) (W[(i)&15] = \
414         rotlFixed(W[((i)+13)&15]^W[((i)+8)&15]^W[((i)+2)&15]^W[(i)&15],1))
415 
416     #define f1(x,y,z) ((z)^((x) &((y)^(z))))
417     #define f2(x,y,z) ((x)^(y)^(z))
418     #define f3(x,y,z) (((x)&(y))|((z)&((x)|(y))))
419     #define f4(x,y,z) ((x)^(y)^(z))
420 
421     #ifdef WOLFSSL_NUCLEUS_1_2
422         /* nucleus.h also defines R1-R4 */
423         #undef R1
424         #undef R2
425         #undef R3
426         #undef R4
427     #endif
428 
429     /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
430     #define R0(v,w,x,y,z,i) (z)+= f1((w),(x),(y)) + blk0((i)) + 0x5A827999+ \
431         rotlFixed((v),5); (w) = rotlFixed((w),30);
432     #define R1(v,w,x,y,z,i) (z)+= f1((w),(x),(y)) + blk1((i)) + 0x5A827999+ \
433         rotlFixed((v),5); (w) = rotlFixed((w),30);
434     #define R2(v,w,x,y,z,i) (z)+= f2((w),(x),(y)) + blk1((i)) + 0x6ED9EBA1+ \
435         rotlFixed((v),5); (w) = rotlFixed((w),30);
436     #define R3(v,w,x,y,z,i) (z)+= f3((w),(x),(y)) + blk1((i)) + 0x8F1BBCDC+ \
437         rotlFixed((v),5); (w) = rotlFixed((w),30);
438     #define R4(v,w,x,y,z,i) (z)+= f4((w),(x),(y)) + blk1((i)) + 0xCA62C1D6+ \
439         rotlFixed((v),5); (w) = rotlFixed((w),30);
440 
Transform(wc_Sha * sha,const byte * data)441     static int Transform(wc_Sha* sha, const byte* data)
442     {
443         word32 W[WC_SHA_BLOCK_SIZE / sizeof(word32)];
444 
445         /* Copy context->state[] to working vars */
446         word32 a = sha->digest[0];
447         word32 b = sha->digest[1];
448         word32 c = sha->digest[2];
449         word32 d = sha->digest[3];
450         word32 e = sha->digest[4];
451 
452     #ifdef USE_SLOW_SHA
453         word32 t, i;
454 
455         for (i = 0; i < 16; i++) {
456             R0(a, b, c, d, e, i);
457             t = e; e = d; d = c; c = b; b = a; a = t;
458         }
459 
460         for (; i < 20; i++) {
461             R1(a, b, c, d, e, i);
462             t = e; e = d; d = c; c = b; b = a; a = t;
463         }
464 
465         for (; i < 40; i++) {
466             R2(a, b, c, d, e, i);
467             t = e; e = d; d = c; c = b; b = a; a = t;
468         }
469 
470         for (; i < 60; i++) {
471             R3(a, b, c, d, e, i);
472             t = e; e = d; d = c; c = b; b = a; a = t;
473         }
474 
475         for (; i < 80; i++) {
476             R4(a, b, c, d, e, i);
477             t = e; e = d; d = c; c = b; b = a; a = t;
478         }
479     #else
480         /* nearly 1 K bigger in code size but 25% faster */
481         /* 4 rounds of 20 operations each. Loop unrolled. */
482         R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
483         R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
484         R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
485         R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
486 
487         R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
488 
489         R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
490         R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
491         R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
492         R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
493         R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
494 
495         R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
496         R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
497         R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
498         R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
499         R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
500 
501         R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
502         R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
503         R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
504         R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
505         R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
506     #endif
507 
508         /* Add the working vars back into digest state[] */
509         sha->digest[0] += a;
510         sha->digest[1] += b;
511         sha->digest[2] += c;
512         sha->digest[3] += d;
513         sha->digest[4] += e;
514 
515         (void)data; /* Not used */
516 
517         return 0;
518     }
519 #endif /* !USE_CUSTOM_SHA_TRANSFORM */
520 
521 
wc_InitSha_ex(wc_Sha * sha,void * heap,int devId)522 int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
523 {
524     int ret = 0;
525 
526     if (sha == NULL)
527         return BAD_FUNC_ARG;
528 
529     sha->heap = heap;
530 #ifdef WOLF_CRYPTO_CB
531     sha->devId = devId;
532     sha->devCtx = NULL;
533 #endif
534 
535 #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
536     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
537     sha->ctx.mode = ESP32_SHA_INIT;
538     sha->ctx.isfirstblock = 1;
539 #endif
540     ret = InitSha(sha);
541     if (ret != 0)
542         return ret;
543 
544 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)
545     ret = wolfAsync_DevCtxInit(&sha->asyncDev, WOLFSSL_ASYNC_MARKER_SHA,
546                                                             sha->heap, devId);
547 #else
548     (void)devId;
549 #endif /* WOLFSSL_ASYNC_CRYPT */
550 
551     return ret;
552 }
553 
554 /* do block size increments/updates */
wc_ShaUpdate(wc_Sha * sha,const byte * data,word32 len)555 int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
556 {
557     int ret = 0;
558     word32 blocksLen;
559     byte* local;
560 
561     if (sha == NULL || (data == NULL && len > 0)) {
562         return BAD_FUNC_ARG;
563     }
564 
565     if (data == NULL && len == 0) {
566         /* valid, but do nothing */
567         return 0;
568     }
569 
570 #ifdef WOLF_CRYPTO_CB
571     if (sha->devId != INVALID_DEVID) {
572         ret = wc_CryptoCb_ShaHash(sha, data, len, NULL);
573         if (ret != CRYPTOCB_UNAVAILABLE)
574             return ret;
575         ret = 0; /* reset ret */
576         /* fall-through when unavailable */
577     }
578 #endif
579 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)
580     if (sha->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA) {
581     #if defined(HAVE_INTEL_QA)
582         return IntelQaSymSha(&sha->asyncDev, NULL, data, len);
583     #endif
584     }
585 #endif /* WOLFSSL_ASYNC_CRYPT */
586 
587     /* check that internal buffLen is valid */
588     if (sha->buffLen >= WC_SHA_BLOCK_SIZE)
589         return BUFFER_E;
590 
591     /* add length for final */
592     AddLength(sha, len);
593 
594     local = (byte*)sha->buffer;
595 
596     /* process any remainder from previous operation */
597     if (sha->buffLen > 0) {
598         blocksLen = min(len, WC_SHA_BLOCK_SIZE - sha->buffLen);
599         XMEMCPY(&local[sha->buffLen], data, blocksLen);
600 
601         sha->buffLen += blocksLen;
602         data         += blocksLen;
603         len          -= blocksLen;
604 
605         if (sha->buffLen == WC_SHA_BLOCK_SIZE) {
606         #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
607             ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE);
608         #endif
609 
610         #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
611             !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
612             if (sha->ctx.mode == ESP32_SHA_INIT) {
613                 esp_sha_try_hw_lock(&sha->ctx);
614             }
615             if (sha->ctx.mode == ESP32_SHA_SW) {
616                 ret = XTRANSFORM(sha, (const byte*)local);
617             } else {
618                 esp_sha_process(sha, (const byte*)local);
619             }
620         #else
621             ret = XTRANSFORM(sha, (const byte*)local);
622         #endif
623             if (ret != 0)
624                 return ret;
625 
626             sha->buffLen = 0;
627         }
628     }
629 
630     /* process blocks */
631 #ifdef XTRANSFORM_LEN
632     /* get number of blocks */
633     /* 64-1 = 0x3F (~ Inverted = 0xFFFFFFC0) */
634     /* len (masked by 0xFFFFFFC0) returns block aligned length */
635     blocksLen = len & ~(WC_SHA_BLOCK_SIZE-1);
636     if (blocksLen > 0) {
637         /* Byte reversal performed in function if required. */
638         XTRANSFORM_LEN(sha, data, blocksLen);
639         data += blocksLen;
640         len  -= blocksLen;
641     }
642 #else
643     while (len >= WC_SHA_BLOCK_SIZE) {
644         word32* local32 = sha->buffer;
645         /* optimization to avoid memcpy if data pointer is properly aligned */
646         /* Little Endian requires byte swap, so can't use data directly */
647     #if defined(WC_HASH_DATA_ALIGNMENT) && !defined(LITTLE_ENDIAN_ORDER)
648         if (((wc_ptr_t)data % WC_HASH_DATA_ALIGNMENT) == 0) {
649             local32 = (word32*)data;
650         }
651         else
652     #endif
653         {
654             XMEMCPY(local32, data, WC_SHA_BLOCK_SIZE);
655         }
656 
657         data += WC_SHA_BLOCK_SIZE;
658         len  -= WC_SHA_BLOCK_SIZE;
659 
660     #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
661         ByteReverseWords(local32, local32, WC_SHA_BLOCK_SIZE);
662     #endif
663 
664     #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
665         !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
666         if (sha->ctx.mode == ESP32_SHA_INIT){
667             esp_sha_try_hw_lock(&sha->ctx);
668         }
669         if (sha->ctx.mode == ESP32_SHA_SW){
670             ret = XTRANSFORM(sha, (const byte*)local32);
671         } else {
672             esp_sha_process(sha, (const byte*)local32);
673         }
674     #else
675         ret = XTRANSFORM(sha, (const byte*)local32);
676     #endif
677     }
678 #endif /* XTRANSFORM_LEN */
679 
680     /* save remainder */
681     if (len > 0) {
682         XMEMCPY(local, data, len);
683         sha->buffLen = len;
684     }
685 
686     return ret;
687 }
688 
wc_ShaFinalRaw(wc_Sha * sha,byte * hash)689 int wc_ShaFinalRaw(wc_Sha* sha, byte* hash)
690 {
691 #ifdef LITTLE_ENDIAN_ORDER
692     word32 digest[WC_SHA_DIGEST_SIZE / sizeof(word32)];
693 #endif
694 
695     if (sha == NULL || hash == NULL) {
696         return BAD_FUNC_ARG;
697     }
698 
699 #ifdef LITTLE_ENDIAN_ORDER
700     ByteReverseWords((word32*)digest, (word32*)sha->digest, WC_SHA_DIGEST_SIZE);
701     XMEMCPY(hash, digest, WC_SHA_DIGEST_SIZE);
702 #else
703     XMEMCPY(hash, sha->digest, WC_SHA_DIGEST_SIZE);
704 #endif
705 
706     return 0;
707 }
708 
wc_ShaFinal(wc_Sha * sha,byte * hash)709 int wc_ShaFinal(wc_Sha* sha, byte* hash)
710 {
711     int ret;
712     byte* local;
713 
714     if (sha == NULL || hash == NULL) {
715         return BAD_FUNC_ARG;
716     }
717 
718     local = (byte*)sha->buffer;
719 
720 #ifdef WOLF_CRYPTO_CB
721     if (sha->devId != INVALID_DEVID) {
722         ret = wc_CryptoCb_ShaHash(sha, NULL, 0, hash);
723         if (ret != CRYPTOCB_UNAVAILABLE)
724             return ret;
725         /* fall-through when unavailable */
726     }
727 #endif
728 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)
729     if (sha->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA) {
730     #if defined(HAVE_INTEL_QA)
731         return IntelQaSymSha(&sha->asyncDev, hash, NULL, WC_SHA_DIGEST_SIZE);
732     #endif
733     }
734 #endif /* WOLFSSL_ASYNC_CRYPT */
735 
736     local[sha->buffLen++] = 0x80;  /* add 1 */
737 
738     /* pad with zeros */
739     if (sha->buffLen > WC_SHA_PAD_SIZE) {
740         XMEMSET(&local[sha->buffLen], 0, WC_SHA_BLOCK_SIZE - sha->buffLen);
741         sha->buffLen += WC_SHA_BLOCK_SIZE - sha->buffLen;
742 
743     #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
744         ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE);
745     #endif
746 
747     #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
748         !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
749         if (sha->ctx.mode == ESP32_SHA_INIT) {
750             esp_sha_try_hw_lock(&sha->ctx);
751         }
752         if (sha->ctx.mode == ESP32_SHA_SW) {
753             ret = XTRANSFORM(sha, (const byte*)local);
754         } else {
755             ret = esp_sha_process(sha, (const byte*)local);
756         }
757     #else
758         ret = XTRANSFORM(sha, (const byte*)local);
759     #endif
760         if (ret != 0)
761             return ret;
762 
763         sha->buffLen = 0;
764     }
765     XMEMSET(&local[sha->buffLen], 0, WC_SHA_PAD_SIZE - sha->buffLen);
766 
767 #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
768     ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE);
769 #endif
770 
771     /* store lengths */
772     /* put lengths in bits */
773     sha->hiLen = (sha->loLen >> (8*sizeof(sha->loLen) - 3)) + (sha->hiLen << 3);
774     sha->loLen = sha->loLen << 3;
775 
776     /* ! length ordering dependent on digest endian type ! */
777     XMEMCPY(&local[WC_SHA_PAD_SIZE], &sha->hiLen, sizeof(word32));
778     XMEMCPY(&local[WC_SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32));
779 
780 #if defined(FREESCALE_MMCAU_SHA)
781     /* Kinetis requires only these bytes reversed */
782     ByteReverseWords(&sha->buffer[WC_SHA_PAD_SIZE/sizeof(word32)],
783                      &sha->buffer[WC_SHA_PAD_SIZE/sizeof(word32)],
784                      2 * sizeof(word32));
785 #endif
786 
787 #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
788     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
789     if (sha->ctx.mode == ESP32_SHA_INIT) {
790         esp_sha_try_hw_lock(&sha->ctx);
791     }
792     if (sha->ctx.mode == ESP32_SHA_SW) {
793         ret = XTRANSFORM(sha, (const byte*)local);
794     } else {
795         ret = esp_sha_digest_process(sha, 1);
796     }
797 #else
798     ret = XTRANSFORM(sha, (const byte*)local);
799 #endif
800 
801 #ifdef LITTLE_ENDIAN_ORDER
802     ByteReverseWords(sha->digest, sha->digest, WC_SHA_DIGEST_SIZE);
803 #endif
804 
805     XMEMCPY(hash, sha->digest, WC_SHA_DIGEST_SIZE);
806 
807     (void)InitSha(sha); /* reset state */
808 
809     return ret;
810 }
811 
812 #if defined(OPENSSL_EXTRA)
813 /* Apply SHA1 transformation to the data                  */
814 /* @param sha  a pointer to wc_Sha structure              */
815 /* @param data data to be applied SHA1 transformation     */
816 /* @return 0 on successful, otherwise non-zero on failure */
wc_ShaTransform(wc_Sha * sha,const unsigned char * data)817 int wc_ShaTransform(wc_Sha* sha, const unsigned char* data)
818 {
819     /* sanity check */
820     if (sha == NULL || data == NULL) {
821         return BAD_FUNC_ARG;
822     }
823     return (Transform(sha, data));
824 }
825 #endif
826 
827 #endif /* USE_SHA_SOFTWARE_IMPL */
828 
829 
wc_InitSha(wc_Sha * sha)830 int wc_InitSha(wc_Sha* sha)
831 {
832     return wc_InitSha_ex(sha, NULL, INVALID_DEVID);
833 }
834 
wc_ShaFree(wc_Sha * sha)835 void wc_ShaFree(wc_Sha* sha)
836 {
837     if (sha == NULL)
838         return;
839 
840 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)
841     wolfAsync_DevCtxFree(&sha->asyncDev, WOLFSSL_ASYNC_MARKER_SHA);
842 #endif /* WOLFSSL_ASYNC_CRYPT */
843 
844 #ifdef WOLFSSL_PIC32MZ_HASH
845     wc_ShaPic32Free(sha);
846 #endif
847 #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
848    se050_hash_free(&sha->se050Ctx);
849 #endif
850 #if (defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \
851     !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH))
852     if (sha->msg != NULL) {
853         XFREE(sha->msg, sha->heap, DYNAMIC_TYPE_TMP_BUFFER);
854         sha->msg = NULL;
855     }
856 #endif
857 #ifdef WOLFSSL_IMXRT_DCP
858     DCPShaFree(sha);
859 #endif
860 }
861 
862 #endif /* !WOLFSSL_TI_HASH */
863 #endif /* HAVE_FIPS */
864 
865 #if !defined(WOLFSSL_TI_HASH) && !defined(WOLFSSL_IMXRT_DCP)
866 
867 #if !defined(WOLFSSL_RENESAS_TSIP_CRYPT) || \
868     defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)
wc_ShaGetHash(wc_Sha * sha,byte * hash)869 int wc_ShaGetHash(wc_Sha* sha, byte* hash)
870 {
871     int ret;
872     wc_Sha tmpSha;
873 
874     if (sha == NULL || hash == NULL)
875         return BAD_FUNC_ARG;
876 
877 #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
878     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
879     if(sha->ctx.mode == ESP32_SHA_INIT){
880         esp_sha_try_hw_lock(&sha->ctx);
881     }
882     if(sha->ctx.mode != ESP32_SHA_SW)
883         esp_sha_digest_process(sha, 0);
884 #endif
885 
886     ret = wc_ShaCopy(sha, &tmpSha);
887     if (ret == 0) {
888        ret = wc_ShaFinal(&tmpSha, hash);
889 #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
890     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
891         sha->ctx.mode = ESP32_SHA_SW;
892 #endif
893 
894 
895     }
896     return ret;
897 }
898 
wc_ShaCopy(wc_Sha * src,wc_Sha * dst)899 int wc_ShaCopy(wc_Sha* src, wc_Sha* dst)
900 {
901     int ret = 0;
902 
903     if (src == NULL || dst == NULL)
904         return BAD_FUNC_ARG;
905 
906     XMEMCPY(dst, src, sizeof(wc_Sha));
907 
908 #ifdef WOLFSSL_SILABS_SE_ACCEL
909     dst->silabsCtx.hash_ctx.cmd_ctx = &(dst->silabsCtx.cmd_ctx);
910     dst->silabsCtx.hash_ctx.hash_type_ctx = &(dst->silabsCtx.hash_type_ctx);
911 #endif
912 
913 #ifdef WOLFSSL_ASYNC_CRYPT
914     ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
915 #endif
916 #ifdef WOLFSSL_PIC32MZ_HASH
917     ret = wc_Pic32HashCopy(&src->cache, &dst->cache);
918 #endif
919 #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
920     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
921      dst->ctx.mode = src->ctx.mode;
922      dst->ctx.isfirstblock = src->ctx.isfirstblock;
923      dst->ctx.sha_type = src->ctx.sha_type;
924 #endif
925 #ifdef WOLFSSL_HASH_FLAGS
926      dst->flags |= WC_HASH_FLAG_ISCOPY;
927 #endif
928     return ret;
929 }
930 #endif /* defined(WOLFSSL_RENESAS_TSIP_CRYPT) ... */
931 #endif /* !WOLFSSL_TI_HASH && !WOLFSSL_IMXRT_DCP */
932 
933 
934 #ifdef WOLFSSL_HASH_FLAGS
wc_ShaSetFlags(wc_Sha * sha,word32 flags)935 int wc_ShaSetFlags(wc_Sha* sha, word32 flags)
936 {
937     if (sha) {
938         sha->flags = flags;
939     }
940     return 0;
941 }
wc_ShaGetFlags(wc_Sha * sha,word32 * flags)942 int wc_ShaGetFlags(wc_Sha* sha, word32* flags)
943 {
944     if (sha && flags) {
945         *flags = sha->flags;
946     }
947     return 0;
948 }
949 #endif
950 
951 #endif /* !NO_SHA */
952