sha_hal.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. // The HAL layer for SHA
  7. #include "hal/sha_hal.h"
  8. #include "hal/sha_types.h"
  9. #include "hal/sha_ll.h"
  10. #include "soc/soc_caps.h"
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #define SHA1_STATE_LEN_WORDS (160 / 32)
  14. #define SHA256_STATE_LEN_WORDS (256 / 32)
  15. #define SHA512_STATE_LEN_WORDS (512 / 32)
  16. #if CONFIG_IDF_TARGET_ESP32
  17. /* Return state size (in words) for a given SHA type */
  18. inline static size_t state_length(esp_sha_type type)
  19. {
  20. switch (type) {
  21. case SHA1:
  22. return SHA1_STATE_LEN_WORDS;
  23. case SHA2_256:
  24. return SHA256_STATE_LEN_WORDS;
  25. case SHA2_384:
  26. case SHA2_512:
  27. return SHA512_STATE_LEN_WORDS;
  28. default:
  29. return 0;
  30. }
  31. }
  32. #else
  33. /* Return state size (in words) for a given SHA type */
  34. inline static size_t state_length(esp_sha_type type)
  35. {
  36. switch (type) {
  37. case SHA1:
  38. return SHA1_STATE_LEN_WORDS;
  39. case SHA2_224:
  40. case SHA2_256:
  41. return SHA256_STATE_LEN_WORDS;
  42. #if SOC_SHA_SUPPORT_SHA384
  43. case SHA2_384:
  44. return SHA512_STATE_LEN_WORDS;
  45. #endif
  46. #if SOC_SHA_SUPPORT_SHA512
  47. case SHA2_512:
  48. return SHA512_STATE_LEN_WORDS;
  49. #endif
  50. #if SOC_SHA_SUPPORT_SHA512_T
  51. case SHA2_512224:
  52. case SHA2_512256:
  53. case SHA2_512T:
  54. return SHA512_STATE_LEN_WORDS;
  55. #endif
  56. default:
  57. return 0;
  58. }
  59. }
  60. #endif
  61. /* Hash a single block */
  62. void sha_hal_hash_block(esp_sha_type sha_type, const void *data_block, size_t block_word_len, bool first_block)
  63. {
  64. sha_hal_wait_idle();
  65. sha_ll_fill_text_block(data_block, block_word_len);
  66. /* Start hashing */
  67. if (first_block) {
  68. sha_ll_start_block(sha_type);
  69. } else {
  70. sha_ll_continue_block(sha_type);
  71. }
  72. }
  73. #if SOC_SHA_SUPPORT_DMA
  74. /* Hashes a number of message blocks using DMA */
  75. void sha_hal_hash_dma(esp_sha_type sha_type, size_t num_blocks, bool first_block)
  76. {
  77. sha_hal_wait_idle();
  78. sha_ll_set_block_num(num_blocks);
  79. /* Start hashing */
  80. if (first_block) {
  81. sha_ll_start_dma(sha_type);
  82. } else {
  83. sha_ll_continue_dma(sha_type);
  84. }
  85. }
  86. #endif //SOC_SHA_SUPPORT_DMA
  87. void sha_hal_wait_idle()
  88. {
  89. while (sha_ll_busy()) {
  90. }
  91. }
  92. /* Reads the current message digest from the SHA engine */
  93. void sha_hal_read_digest(esp_sha_type sha_type, void *digest_state)
  94. {
  95. uint32_t *digest_state_words = (uint32_t *)digest_state;
  96. sha_ll_load(sha_type);
  97. uint32_t word_len = state_length(sha_type);
  98. sha_hal_wait_idle();
  99. sha_ll_read_digest(sha_type, digest_state, word_len);
  100. /* Fault injection check: verify SHA engine actually ran,
  101. state is not all zeroes.
  102. */
  103. for (size_t i = 0; i < word_len; i++) {
  104. if (digest_state_words[i] != 0) {
  105. return;
  106. }
  107. }
  108. abort(); // SHA peripheral returned all zero state, probably due to fault injection
  109. }
  110. #if SOC_SHA_SUPPORT_RESUME
  111. /* Writes the message digest to the SHA engine */
  112. void sha_hal_write_digest(esp_sha_type sha_type, void *digest_state)
  113. {
  114. sha_ll_write_digest(sha_type, digest_state, state_length(sha_type));
  115. }
  116. #endif //SOC_SHA_SUPPORT_RESUME
  117. #if SOC_SHA_SUPPORT_SHA512_T
  118. /* Calculates and sets the initial digiest for SHA512_t */
  119. void sha_hal_sha512_init_hash(uint32_t t_string, uint8_t t_len)
  120. {
  121. sha_ll_t_string_set(t_string);
  122. sha_ll_t_len_set(t_len);
  123. sha_ll_start_block(SHA2_512T);
  124. sha_hal_wait_idle();
  125. }
  126. #endif //SOC_SHA_SUPPORT_SHA512_T