test_hmac.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*
  2. * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <string.h>
  7. #include "esp_private/esp_crypto_lock_internal.h"
  8. #include "esp_log.h"
  9. #include "memory_checks.h"
  10. #include "unity_fixture.h"
  11. #include "rom/efuse.h"
  12. #include "rom/hmac.h"
  13. #include "rom/ets_sys.h"
  14. #include "soc/hwcrypto_reg.h"
  15. #include "soc/system_reg.h"
  16. #include "hmac_params.h"
  17. typedef enum {
  18. HMAC_KEY0 = 0,
  19. HMAC_KEY1,
  20. HMAC_KEY2,
  21. HMAC_KEY3,
  22. HMAC_KEY4,
  23. HMAC_KEY5,
  24. HMAC_KEY_MAX
  25. } hmac_key_id_t;
  26. static ets_efuse_block_t convert_key_type(hmac_key_id_t key_id) {
  27. return ETS_EFUSE_BLOCK_KEY0 + (ets_efuse_block_t) key_id;
  28. }
  29. static esp_err_t hmac_jtag_disable(void)
  30. {
  31. REG_WRITE(HMAC_SET_INVALIDATE_JTAG_REG, 1);
  32. return ESP_OK;
  33. }
  34. #if !CONFIG_IDF_TARGET_ESP32S2
  35. #include "hal/hmac_hal.h"
  36. #include "hal/hmac_ll.h"
  37. #include "hal/ds_ll.h"
  38. #include "esp_private/periph_ctrl.h"
  39. #define SHA256_BLOCK_SZ 64
  40. #define SHA256_PAD_SZ 8
  41. static esp_err_t hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token)
  42. {
  43. int ets_status;
  44. esp_err_t err = ESP_OK;
  45. ets_status = ets_jtag_enable_temporarily(token, convert_key_type(key_id));
  46. if (ets_status != ETS_OK) {
  47. err = ESP_FAIL;
  48. }
  49. ets_hmac_disable();
  50. return err;
  51. }
  52. static void write_and_padd(uint8_t *block, const uint8_t *data, uint16_t data_len)
  53. {
  54. memcpy(block, data, data_len);
  55. block[data_len] = 0x80;
  56. bzero(block + data_len + 1, SHA256_BLOCK_SZ - data_len - 1);
  57. }
  58. static esp_err_t hmac_calculate(hmac_key_id_t key_id, const void *message, size_t message_len, uint8_t *hmac)
  59. {
  60. const uint8_t *message_bytes = (const uint8_t *)message;
  61. HMAC_RCC_ATOMIC() {
  62. hmac_ll_enable_bus_clock(true);
  63. hmac_ll_reset_register();
  64. }
  65. periph_module_enable(PERIPH_SHA_MODULE);
  66. DS_RCC_ATOMIC() {
  67. ds_ll_enable_bus_clock(true);
  68. ds_ll_reset_register();
  69. }
  70. hmac_hal_start();
  71. uint32_t conf_error = hmac_hal_configure(HMAC_OUTPUT_USER, key_id);
  72. if (conf_error) {
  73. return ESP_FAIL;
  74. }
  75. if (message_len + 1 + SHA256_PAD_SZ <= SHA256_BLOCK_SZ) {
  76. uint8_t block[SHA256_BLOCK_SZ];
  77. uint64_t bit_len = __builtin_bswap64(message_len * 8 + 512);
  78. write_and_padd(block, message_bytes, message_len);
  79. memcpy(block + SHA256_BLOCK_SZ - sizeof(bit_len),
  80. &bit_len, sizeof(bit_len));
  81. hmac_hal_write_one_block_512(block);
  82. } else {
  83. size_t remaining_blocks = message_len / SHA256_BLOCK_SZ;
  84. for (int i = 1; i < remaining_blocks; i++) {
  85. hmac_hal_write_block_512(message_bytes);
  86. message_bytes += SHA256_BLOCK_SZ;
  87. hmac_hal_next_block_normal();
  88. }
  89. if (remaining_blocks) {
  90. hmac_hal_write_block_512(message_bytes);
  91. message_bytes += SHA256_BLOCK_SZ;
  92. }
  93. size_t remaining = message_len % SHA256_BLOCK_SZ;
  94. uint8_t block[SHA256_BLOCK_SZ];
  95. uint64_t bit_len = __builtin_bswap64(message_len * 8 + 512);
  96. if (remaining >= SHA256_BLOCK_SZ - SHA256_PAD_SZ) {
  97. write_and_padd(block, message_bytes, remaining);
  98. hmac_hal_next_block_normal();
  99. hmac_hal_write_block_512(block);
  100. bzero(block, SHA256_BLOCK_SZ);
  101. } else {
  102. write_and_padd(block, message_bytes, remaining);
  103. }
  104. memcpy(block + SHA256_BLOCK_SZ - sizeof(bit_len),
  105. &bit_len, sizeof(bit_len));
  106. hmac_hal_next_block_padding();
  107. hmac_hal_write_block_512(block);
  108. }
  109. hmac_hal_read_result_256(hmac);
  110. DS_RCC_ATOMIC() {
  111. ds_ll_enable_bus_clock(false);
  112. }
  113. periph_module_disable(PERIPH_SHA_MODULE);
  114. HMAC_RCC_ATOMIC() {
  115. hmac_ll_enable_bus_clock(false);
  116. }
  117. return ESP_OK;
  118. }
  119. #else /* !CONFIG_IDF_TARGET_ESP32S2 */
  120. static esp_err_t hmac_calculate(hmac_key_id_t key_id,
  121. const void *message,
  122. size_t message_len,
  123. uint8_t *hmac)
  124. {
  125. int hmac_ret;
  126. ets_hmac_enable();
  127. hmac_ret = ets_hmac_calculate_message(convert_key_type(key_id), message, message_len, hmac);
  128. ets_hmac_disable();
  129. if (hmac_ret != 0) {
  130. return ESP_FAIL;
  131. } else {
  132. return ESP_OK;
  133. }
  134. }
  135. static esp_err_t hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token)
  136. {
  137. int ets_status;
  138. esp_err_t err = ESP_OK;
  139. ets_hmac_enable();
  140. /* Token updating into HMAC module. */
  141. for (int i = 0; i < 32; i += 4) {
  142. uint32_t key_word;
  143. memcpy(&key_word, &token[i], 4);
  144. REG_WRITE(DPORT_JTAG_CTRL_0_REG + i, __builtin_bswap32(key_word));
  145. }
  146. ets_status = ets_hmac_calculate_downstream(convert_key_type(key_id), ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG);
  147. if (ets_status != ETS_OK) {
  148. err = ESP_FAIL;
  149. }
  150. ets_hmac_disable();
  151. return err;
  152. }
  153. #endif /* !CONFIG_IDF_TARGET_ESP32S2 */
  154. TEST_GROUP(hmac);
  155. TEST_SETUP(hmac)
  156. {
  157. test_utils_record_free_mem();
  158. TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL));
  159. }
  160. TEST_TEAR_DOWN(hmac)
  161. {
  162. test_utils_finish_and_evaluate_leaks(test_utils_get_leak_level(ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_ALL),
  163. test_utils_get_leak_level(ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_ALL));
  164. }
  165. TEST(hmac, hmac_downstream_jtag_enable_mode)
  166. {
  167. TEST_ASSERT_EQUAL_HEX32_MESSAGE(ESP_OK, hmac_jtag_enable(HMAC_KEY3, jtag_enable_token_data),
  168. "JTAG should be re-enabled now, please manually verify");
  169. }
  170. TEST(hmac, hmac_downstream_jtag_disable)
  171. {
  172. TEST_ASSERT_EQUAL_HEX32_MESSAGE(ESP_OK, hmac_jtag_disable(), "JTAG should be disabled now, please manually verify");
  173. }
  174. TEST(hmac, hmac_upstream_mac_generation_with_zeroes)
  175. {
  176. uint8_t hmac[32];
  177. const size_t num_zero_results = sizeof(zero_results) / sizeof(hmac_result);
  178. for (int i = 0; i < num_zero_results; i++) {
  179. TEST_ESP_OK(hmac_calculate(HMAC_KEY4, zeroes, zero_results[i].msglen, hmac));
  180. TEST_ASSERT_EQUAL_HEX8_ARRAY(zero_results[i].result, hmac, sizeof(hmac));
  181. }
  182. }
  183. TEST(hmac, hmac_upstream_MAC_generation_from_data)
  184. {
  185. uint8_t hmac[32];
  186. for (int i = 0; i < sizeof(results)/sizeof(hmac_result); i++) {
  187. TEST_ESP_OK(hmac_calculate(HMAC_KEY4, message, results[i].msglen, hmac));
  188. TEST_ASSERT_EQUAL_HEX8_ARRAY(results[i].result, hmac, sizeof(hmac));
  189. }
  190. }
  191. TEST_GROUP_RUNNER(hmac)
  192. {
  193. RUN_TEST_CASE(hmac, hmac_downstream_jtag_enable_mode);
  194. RUN_TEST_CASE(hmac, hmac_downstream_jtag_disable);
  195. RUN_TEST_CASE(hmac, hmac_upstream_mac_generation_with_zeroes);
  196. RUN_TEST_CASE(hmac, hmac_upstream_MAC_generation_from_data);
  197. }