sha.c 25 KB

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