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