esp32_sha.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. /* esp32_sha.c
  2. *
  3. * Copyright (C) 2006-2022 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. /*****************************************************************************/
  26. /* this entire file content is excluded when NO_SHA, NO_SHA256
  27. * or when using WC_SHA384 or WC_SHA512
  28. */
  29. #if !defined(NO_SHA) || !defined(NO_SHA256) || defined(WC_SHA384) || \
  30. defined(WC_SHA512)
  31. #include "wolfssl/wolfcrypt/logging.h"
  32. /* this entire file content is excluded if not using HW hash acceleration */
  33. #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
  34. !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
  35. /* TODO this may be chip type dependent: add support for others */
  36. #include <hal/clk_gate_ll.h> /* ESP32-WROOM */
  37. #include <wolfssl/wolfcrypt/sha.h>
  38. #include <wolfssl/wolfcrypt/sha256.h>
  39. #include <wolfssl/wolfcrypt/sha512.h>
  40. #include "wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h"
  41. #include "wolfssl/wolfcrypt/error-crypt.h"
  42. #ifdef NO_INLINE
  43. #include <wolfssl/wolfcrypt/misc.h>
  44. #else
  45. #define WOLFSSL_MISC_INCLUDED
  46. #include <wolfcrypt/src/misc.c>
  47. #endif
  48. static const char* TAG = "wolf_hw_sha";
  49. #ifdef NO_SHA
  50. #define WC_SHA_DIGEST_SIZE 20
  51. #endif
  52. /* mutex */
  53. #if defined(SINGLE_THREADED)
  54. static int InUse = 0;
  55. #else
  56. static wolfSSL_Mutex sha_mutex;
  57. static int espsha_CryptHwMutexInit = 0;
  58. #if defined(DEBUG_WOLFSSL)
  59. static int this_block_num = 0;
  60. #endif
  61. #endif
  62. /*
  63. * determine the digest size, depending on SHA type.
  64. *
  65. * See FIPS PUB 180-4, Instruction Section 1.
  66. *
  67. *
  68. enum SHA_TYPE {
  69. SHA1 = 0,
  70. SHA2_256,
  71. SHA2_384,
  72. SHA2_512,
  73. SHA_INVALID = -1,
  74. };
  75. */
  76. static word32 wc_esp_sha_digest_size(enum SHA_TYPE type)
  77. {
  78. ESP_LOGV(TAG, " esp_sha_digest_size");
  79. switch(type){
  80. #ifndef NO_SHA
  81. case SHA1: /* typically 20 bytes */
  82. return WC_SHA_DIGEST_SIZE;
  83. #endif
  84. #ifndef NO_SHA256
  85. case SHA2_256: /* typically 32 bytes */
  86. return WC_SHA256_DIGEST_SIZE;
  87. #endif
  88. #ifdef WOLFSSL_SHA384
  89. case SHA2_384:
  90. return WC_SHA384_DIGEST_SIZE;
  91. #endif
  92. #ifdef WOLFSSL_SHA512
  93. case SHA2_512: /* typically 64 bytes */
  94. return WC_SHA512_DIGEST_SIZE;
  95. #endif
  96. default:
  97. ESP_LOGE(TAG, "Bad sha type");
  98. return WC_SHA_DIGEST_SIZE;
  99. }
  100. /* we never get here, as all the above switches should have a return */
  101. }
  102. /*
  103. * wait until all engines becomes idle
  104. */
  105. static void wc_esp_wait_until_idle()
  106. {
  107. while((DPORT_REG_READ(SHA_1_BUSY_REG) != 0) ||
  108. (DPORT_REG_READ(SHA_256_BUSY_REG) != 0) ||
  109. (DPORT_REG_READ(SHA_384_BUSY_REG) != 0) ||
  110. (DPORT_REG_READ(SHA_512_BUSY_REG) != 0)) {
  111. /* do nothing while waiting. */
  112. }
  113. }
  114. /*
  115. * hack alert. there really should have been something implemented
  116. * in periph_ctrl.c to detect ref_counts[periph] depth.
  117. *
  118. * since there is not at this time, we have this brute-force method.
  119. *
  120. * when trying to unwrap an arbitrary depth of peripheral-enable(s),
  121. * we'll check the register upon *enable* to see if we actually did.
  122. *
  123. * Note that enable / disable only occurs when ref_counts[periph] == 0
  124. *
  125. * TODO: check if this works with other ESP32 platforms ESP32-C3, ESP32-S3, etc
  126. */
  127. int esp_unroll_sha_module_enable(WC_ESP32SHA* ctx)
  128. {
  129. /* if we end up here, there was a prior unexpected fail and
  130. * we need to unroll enables */
  131. int ret = 0; /* assume success unless proven otherwise */
  132. uint32_t this_sha_mask; /* this is the bit-mask for our SHA CLK_EN_REG */
  133. int actual_unroll_count = 0;
  134. int max_unroll_count = 1000; /* never get stuck in a hardware wait loop */
  135. this_sha_mask = periph_ll_get_clk_en_mask(PERIPH_SHA_MODULE);
  136. /* unwind prior calls to THIS ctx. decrement ref_counts[periph] */
  137. /* only when ref_counts[periph] == 0 does something actually happen */
  138. /* once the value we read is a 0 in the DPORT_PERI_CLK_EN_REG bit
  139. * then we have fully unrolled the enables via ref_counts[periph]==0 */
  140. while ((this_sha_mask & *(uint32_t*)DPORT_PERI_CLK_EN_REG) != 0) {
  141. periph_module_disable(PERIPH_SHA_MODULE);
  142. actual_unroll_count++;
  143. ESP_LOGI(TAG, "unroll not yet successful. try #%d",
  144. actual_unroll_count);
  145. /* we'll only try this some unreasonable number of times
  146. * before giving up */
  147. if (actual_unroll_count > max_unroll_count) {
  148. ret = -1; /* failed to unroll */
  149. break;
  150. }
  151. }
  152. if (ret == 0) {
  153. if (ctx->lockDepth != actual_unroll_count) {
  154. /* this could be a warning of wonkiness in RTOS environment.
  155. * we were successful, but not expected depth count*/
  156. ESP_LOGV(TAG, "warning lockDepth mismatch.");
  157. }
  158. ctx->lockDepth = 0;
  159. ctx->mode = ESP32_SHA_INIT;
  160. }
  161. else {
  162. ESP_LOGE(TAG, "Failed to unroll after %d attempts.",
  163. actual_unroll_count);
  164. ctx->mode = ESP32_SHA_SW;
  165. }
  166. return ret;
  167. }
  168. /*
  169. * lock hw engine.
  170. * this should be called before using engine.
  171. */
  172. int esp_sha_try_hw_lock(WC_ESP32SHA* ctx)
  173. {
  174. int ret = 0;
  175. ESP_LOGV(TAG, "enter esp_sha_hw_lock");
  176. if (ctx == NULL) {
  177. ESP_LOGE(TAG, " esp_sha_try_hw_lock called with NULL ctx");
  178. return -1;
  179. }
  180. /* Init mutex
  181. *
  182. * Note that even single thread mode may calculate hashes
  183. * concurrently, so we still need to keep track of the
  184. * engine being busy or not.
  185. **/
  186. #if defined(SINGLE_THREADED)
  187. if(ctx->mode == ESP32_SHA_INIT) {
  188. if(!InUse) {
  189. ctx->mode = ESP32_SHA_HW;
  190. InUse = 1;
  191. }
  192. else {
  193. ctx->mode = ESP32_SHA_SW;
  194. }
  195. }
  196. else {
  197. /* this should not happens */
  198. ESP_LOGE(TAG, "unexpected error in esp_sha_try_hw_lock.");
  199. return -1;
  200. }
  201. #else /* not defined(SINGLE_THREADED) */
  202. /*
  203. * there's only one SHA engine for all the hash types
  204. * so when any hash is in use, no others can use it.
  205. * fall back to SW.
  206. **/
  207. /*
  208. * here is some sample code to test the unrolling of sha enables:
  209. *
  210. periph_module_enable(PERIPH_SHA_MODULE);
  211. ctx->lockDepth++;
  212. periph_module_enable(PERIPH_SHA_MODULE);
  213. ctx->lockDepth++;
  214. ctx->mode = ESP32_FAIL_NEED_INIT;
  215. */
  216. if (espsha_CryptHwMutexInit == 0) {
  217. ESP_LOGV(TAG, "set esp_CryptHwMutexInit");
  218. ret = esp_CryptHwMutexInit(&sha_mutex);
  219. if (ret == 0) {
  220. espsha_CryptHwMutexInit = 1;
  221. }
  222. else {
  223. ESP_LOGE(TAG, " mutex initialization failed. revert to software");
  224. ctx->mode = ESP32_SHA_SW;
  225. /* espsha_CryptHwMutexInit is still zero */
  226. return 0; /* success, just not using HW */
  227. }
  228. }
  229. /* check if this sha has been operated as sw or hw, or not yet init */
  230. if (ctx->mode == ESP32_SHA_INIT) {
  231. /* try to lock the hw engine */
  232. ESP_LOGV(TAG, "ESP32_SHA_INIT\n");
  233. /* we don't wait:
  234. * either the engine is free, or we fall back to SW
  235. */
  236. if (esp_CryptHwMutexLock(&sha_mutex, (TickType_t)0) == 0) {
  237. /* check to see if we had a prior fail and need to unroll enables */
  238. ret = esp_unroll_sha_module_enable(ctx);
  239. ESP_LOGV(TAG, "Hardware Mode, lock depth = %d", ctx->lockDepth);
  240. }
  241. else {
  242. ESP_LOGV(TAG, ">>>> Hardware in use; Mode REVERT to ESP32_SHA_SW");
  243. ctx->mode = ESP32_SHA_SW;
  244. return 0; /* success, but revert to SW */
  245. }
  246. }
  247. else {
  248. /* this should not happen: called during mode != ESP32_SHA_INIT */
  249. ESP_LOGE(TAG, "unexpected error in esp_sha_try_hw_lock.");
  250. return -1;
  251. }
  252. #endif /* not defined(SINGLE_THREADED) */
  253. if (ret == 0) {
  254. ctx->lockDepth++; /* depth for THIS ctx (there could be others!) */
  255. periph_module_enable(PERIPH_SHA_MODULE);
  256. ctx->mode = ESP32_SHA_HW;
  257. }
  258. else {
  259. ESP_LOGI(TAG, ">>>> Other problem; Mode REVERT to ESP32_SHA_SW");
  260. ctx->mode = ESP32_SHA_SW;
  261. }
  262. ESP_LOGV(TAG, "leave esp_sha_hw_lock");
  263. return ret;
  264. } /* esp_sha_try_hw_lock */
  265. /*
  266. * release hw engine. when we don't have it locked, SHA module is DISABLED
  267. */
  268. int esp_sha_hw_unlock(WC_ESP32SHA* ctx)
  269. {
  270. ESP_LOGV(TAG, "enter esp_sha_hw_unlock");
  271. /* Disable AES hardware */
  272. periph_module_disable(PERIPH_SHA_MODULE);
  273. #if defined(SINGLE_THREADED)
  274. InUse = 0;
  275. #else
  276. /* unlock hw engine for next use */
  277. esp_CryptHwMutexUnLock(&sha_mutex);
  278. #endif
  279. /* we'll keep track of our lock depth.
  280. * in case of unexpected results, all the periph_module_disable() calls
  281. * and periph_module_disable() need to be unwound.
  282. *
  283. * see ref_counts[periph] in file: periph_ctrl.c */
  284. if (ctx->lockDepth > 0) {
  285. ctx->lockDepth--;
  286. }
  287. else {
  288. ctx->lockDepth = 0;
  289. }
  290. ESP_LOGV(TAG, "leave esp_sha_hw_unlock");
  291. return 0;
  292. } /* esp_sha_hw_unlock */
  293. /*
  294. * start sha process by using hw engine.
  295. * assumes register already loaded.
  296. */
  297. static int esp_sha_start_process(WC_ESP32SHA* sha)
  298. {
  299. int ret = 0;
  300. if (sha == NULL) {
  301. return -1;
  302. }
  303. ESP_LOGV(TAG, " enter esp_sha_start_process");
  304. if(sha->isfirstblock){
  305. /* start registers for first message block
  306. * we don't make any relational memory position assumptions.
  307. */
  308. switch (sha->sha_type) {
  309. case SHA1:
  310. DPORT_REG_WRITE(SHA_1_START_REG, 1);
  311. break;
  312. case SHA2_256:
  313. DPORT_REG_WRITE(SHA_256_START_REG, 1);
  314. break;
  315. #if defined(WOLFSSL_SHA384)
  316. case SHA2_384:
  317. DPORT_REG_WRITE(SHA_384_START_REG, 1);
  318. break;
  319. #endif
  320. #if defined(WOLFSSL_SHA512)
  321. case SHA2_512:
  322. DPORT_REG_WRITE(SHA_512_START_REG, 1);
  323. break;
  324. #endif
  325. default:
  326. sha->mode = ESP32_SHA_FAIL_NEED_UNROLL;
  327. ret = -1;
  328. break;
  329. }
  330. sha->isfirstblock = 0;
  331. ESP_LOGV(TAG, " set sha->isfirstblock = 0");
  332. #if defined(DEBUG_WOLFSSL)
  333. this_block_num = 1; /* one-based counter, just for debug info */
  334. #endif
  335. }
  336. else {
  337. /* continue */
  338. /* continue registers for next message block.
  339. * we don't make any relational memory position assumptions
  340. * for future chip architecture changes.
  341. */
  342. switch (sha->sha_type) {
  343. case SHA1:
  344. DPORT_REG_WRITE(SHA_1_CONTINUE_REG, 1);
  345. break;
  346. case SHA2_256:
  347. DPORT_REG_WRITE(SHA_256_CONTINUE_REG, 1);
  348. break;
  349. #if defined(WOLFSSL_SHA384)
  350. case SHA2_384:
  351. DPORT_REG_WRITE(SHA_384_CONTINUE_REG, 1);
  352. break;
  353. #endif
  354. #if defined(WOLFSSL_SHA512)
  355. case SHA2_512:
  356. DPORT_REG_WRITE(SHA_512_CONTINUE_REG, 1);
  357. break;
  358. #endif
  359. default:
  360. /* error for unsupported other values */
  361. sha->mode = ESP32_SHA_FAIL_NEED_UNROLL;
  362. ret = -1;
  363. break;
  364. }
  365. #if defined(DEBUG_WOLFSSL)
  366. this_block_num++; /* one-based counter */
  367. ESP_LOGV(TAG, " continue block #%d", this_block_num);
  368. #endif
  369. }
  370. ESP_LOGV(TAG, " leave esp_sha_start_process");
  371. return ret;
  372. }
  373. /*
  374. * process message block
  375. */
  376. static void wc_esp_process_block(WC_ESP32SHA* ctx, /* see ctx->sha_type */
  377. const word32* data,
  378. word32 len)
  379. {
  380. int i;
  381. int word32_to_save = (len) / (sizeof(word32));
  382. ESP_LOGV(TAG, " enter esp_process_block");
  383. if (word32_to_save > 0x31) {
  384. word32_to_save = 0x31;
  385. ESP_LOGE(TAG, " ERROR esp_process_block len exceeds 0x31 words");
  386. }
  387. /* check if there are any busy engine */
  388. wc_esp_wait_until_idle();
  389. /* load [len] words of message data into hw */
  390. for (i = 0; i < word32_to_save; i++) {
  391. /* by using DPORT_REG_WRITE, we avoid the need
  392. * to call __builtin_bswap32 to address endiness
  393. *
  394. * a useful watch array cast to watch at runtime:
  395. * ((uint32_t[32]) (*(volatile uint32_t *)(SHA_TEXT_BASE)))
  396. *
  397. * Write value to DPORT register (does not require protecting)
  398. */
  399. DPORT_REG_WRITE(SHA_TEXT_BASE + (i*sizeof(word32)), *(data + i));
  400. /* memw confirmed auto inserted by compiler here */
  401. }
  402. /* notify hw to start process
  403. * see ctx->sha_type
  404. * reg data does not change until we are ready to read */
  405. esp_sha_start_process(ctx);
  406. ESP_LOGV(TAG, " leave esp_process_block");
  407. }
  408. /*
  409. * retrieve sha digest from memory
  410. */
  411. int wc_esp_digest_state(WC_ESP32SHA* ctx, byte* hash)
  412. {
  413. ESP_LOGV(TAG, "enter esp_digest_state");
  414. if (ctx == NULL) {
  415. return -1;
  416. }
  417. /* sanity check */
  418. if (ctx->sha_type == SHA_INVALID) {
  419. ctx->mode = ESP32_SHA_FAIL_NEED_UNROLL;
  420. ESP_LOGE(TAG, "unexpected error. sha_type is invalid.");
  421. return -1;
  422. }
  423. if (ctx == NULL) {
  424. return -1;
  425. }
  426. /* wait until idle */
  427. wc_esp_wait_until_idle();
  428. /* each sha_type register is at a different location */
  429. switch (ctx->sha_type) {
  430. case SHA1:
  431. DPORT_REG_WRITE(SHA_1_LOAD_REG, 1);
  432. break;
  433. case SHA2_256:
  434. DPORT_REG_WRITE(SHA_256_LOAD_REG, 1);
  435. break;
  436. #if defined(WOLFSSL_SHA384)
  437. case SHA2_384:
  438. SHA_LOAD_REG = SHA_384_LOAD_REG;
  439. SHA_BUSY_REG = SHA_384_BUSY_REG;
  440. break;
  441. #endif
  442. #if defined(WOLFSSL_SHA512)
  443. case SHA2_512:
  444. DPORT_REG_WRITE(SHA_512_LOAD_REG, 1);
  445. break;
  446. #endif
  447. default:
  448. ctx->mode = ESP32_SHA_FAIL_NEED_UNROLL;
  449. return -1;
  450. break;
  451. }
  452. if(ctx->isfirstblock == 1){
  453. /* no hardware use yet. Nothing to do yet */
  454. return 0;
  455. }
  456. /* LOAD final digest */
  457. wc_esp_wait_until_idle();
  458. /* MEMW instructions before volatile memory references to guarantee
  459. * sequential consistency. At least one MEMW should be executed in
  460. * between every load or store to a volatile variable
  461. */
  462. asm volatile("memw");
  463. /* put result in hash variable.
  464. *
  465. * ALERT - hardware specific. See esp_hw_support\port\esp32\dport_access.c
  466. *
  467. * note we read 4-byte word32's here via DPORT_SEQUENCE_REG_READ
  468. *
  469. * example:
  470. * DPORT_SEQUENCE_REG_READ(address + i * 4);
  471. */
  472. esp_dport_access_read_buffer(
  473. (word32*)(hash), /* the result will be found in hash upon exit */
  474. SHA_TEXT_BASE, /* there's a fixed reg addy for all SHA */
  475. wc_esp_sha_digest_size(ctx->sha_type) / sizeof(word32) /* # 4-byte */
  476. );
  477. #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
  478. if (ctx->sha_type == SHA2_384 || ctx->sha_type == SHA2_512) {
  479. word32 i;
  480. word32* pwrd1 = (word32*)(hash);
  481. /* swap value */
  482. for (i = 0; i < WC_SHA512_DIGEST_SIZE / 4; i += 2) {
  483. pwrd1[i] ^= pwrd1[i + 1];
  484. pwrd1[i + 1] ^= pwrd1[i];
  485. pwrd1[i] ^= pwrd1[i + 1];
  486. }
  487. }
  488. #endif
  489. ESP_LOGV(TAG, "leave esp_digest_state");
  490. return 0;
  491. }
  492. #ifndef NO_SHA
  493. /*
  494. * sha1 process
  495. */
  496. int esp_sha_process(struct wc_Sha* sha, const byte* data)
  497. {
  498. int ret = 0;
  499. ESP_LOGV(TAG, "enter esp_sha_process");
  500. wc_esp_process_block(&sha->ctx, (const word32*)data, WC_SHA_BLOCK_SIZE);
  501. ESP_LOGV(TAG, "leave esp_sha_process");
  502. return ret;
  503. }
  504. /*
  505. * retrieve sha1 digest
  506. */
  507. int esp_sha_digest_process(struct wc_Sha* sha, byte blockprocess)
  508. {
  509. int ret = 0;
  510. ESP_LOGV(TAG, "enter esp_sha_digest_process");
  511. if (blockprocess) {
  512. wc_esp_process_block(&sha->ctx, sha->buffer, WC_SHA_BLOCK_SIZE);
  513. }
  514. wc_esp_digest_state(&sha->ctx, (byte*)sha->digest);
  515. ESP_LOGV(TAG, "leave esp_sha_digest_process");
  516. return ret;
  517. }
  518. #endif /* NO_SHA */
  519. #ifndef NO_SHA256
  520. /*
  521. * sha256 process
  522. *
  523. * repeatedly call this for [N] blocks of [WC_SHA256_BLOCK_SIZE] bytes of data
  524. */
  525. int esp_sha256_process(struct wc_Sha256* sha, const byte* data)
  526. {
  527. int ret = 0;
  528. ESP_LOGV(TAG, " enter esp_sha256_process");
  529. if ((&sha->ctx)->sha_type == SHA2_256) {
  530. #if defined(DEBUG_WOLFSSL_VERBOSE)
  531. ESP_LOGV(TAG, " confirmed sha type call match");
  532. #endif
  533. }
  534. else {
  535. ret = -1;
  536. ESP_LOGE(TAG, " ERROR sha type call mismatch");
  537. }
  538. wc_esp_process_block(&sha->ctx, (const word32*)data, WC_SHA256_BLOCK_SIZE);
  539. ESP_LOGV(TAG, " leave esp_sha256_process");
  540. return ret;
  541. }
  542. /*
  543. * retrieve sha256 digest
  544. *
  545. * note that wc_Sha256Final() in sha256.c expects to need to reverse byte
  546. * order, even though we could have returned them in the right order.
  547. */
  548. int esp_sha256_digest_process(struct wc_Sha256* sha, byte blockprocess)
  549. {
  550. int ret = 0;
  551. ESP_LOGV(TAG, "enter esp_sha256_digest_process");
  552. if(blockprocess) {
  553. wc_esp_process_block(&sha->ctx, sha->buffer, WC_SHA256_BLOCK_SIZE);
  554. }
  555. wc_esp_digest_state(&sha->ctx, (byte*)sha->digest);
  556. ESP_LOGV(TAG, "leave esp_sha256_digest_process");
  557. return ret;
  558. }
  559. #endif /* NO_SHA256 */
  560. #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
  561. /*
  562. * sha512 process. this is used for sha384 too.
  563. */
  564. void esp_sha512_block(struct wc_Sha512* sha, const word32* data, byte isfinal)
  565. {
  566. ESP_LOGV(TAG, "enter esp_sha512_block");
  567. /* start register offset */
  568. if(sha->ctx.mode == ESP32_SHA_SW){
  569. ByteReverseWords64(sha->buffer, sha->buffer,
  570. WC_SHA512_BLOCK_SIZE);
  571. if(isfinal) {
  572. sha->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2] =
  573. sha->hiLen;
  574. sha->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 1] =
  575. sha->loLen;
  576. }
  577. }
  578. else {
  579. ByteReverseWords((word32*)sha->buffer, (word32*)sha->buffer,
  580. WC_SHA512_BLOCK_SIZE);
  581. if(isfinal){
  582. sha->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2] =
  583. rotlFixed64(sha->hiLen, 32U);
  584. sha->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 1] =
  585. rotlFixed64(sha->loLen, 32U);
  586. }
  587. wc_esp_process_block(&sha->ctx, data, WC_SHA512_BLOCK_SIZE);
  588. }
  589. ESP_LOGV(TAG, "leave esp_sha512_block");
  590. }
  591. /*
  592. * sha512 process. this is used for sha384 too.
  593. */
  594. int esp_sha512_process(struct wc_Sha512* sha)
  595. {
  596. word32 *data = (word32*)sha->buffer;
  597. ESP_LOGV(TAG, "enter esp_sha512_process");
  598. esp_sha512_block(sha, data, 0);
  599. ESP_LOGV(TAG, "leave esp_sha512_process");
  600. return 0;
  601. }
  602. /*
  603. * retrieve sha512 digest. this is used for sha384 too.
  604. */
  605. int esp_sha512_digest_process(struct wc_Sha512* sha, byte blockproc)
  606. {
  607. ESP_LOGV(TAG, "enter esp_sha512_digest_process");
  608. if(blockproc) {
  609. word32* data = (word32*)sha->buffer;
  610. esp_sha512_block(sha, data, 1);
  611. }
  612. if(sha->ctx.mode != ESP32_SHA_SW)
  613. wc_esp_digest_state(&sha->ctx, (byte*)sha->digest);
  614. ESP_LOGV(TAG, "leave esp_sha512_digest_process");
  615. return 0;
  616. }
  617. #endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */
  618. #endif /* WOLFSSL_ESP32WROOM32_CRYPT */
  619. #endif /* !defined(NO_SHA) ||... */