test_efuse_keys.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /*
  2. * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <errno.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include "unity.h"
  13. #include "test_utils.h"
  14. #include "esp_log.h"
  15. #include "esp_efuse.h"
  16. #include "esp_efuse_table.h"
  17. #include "esp_efuse_utility.h"
  18. #include "sdkconfig.h"
  19. __attribute__((unused)) static const char* TAG = "efuse_key_test";
  20. #ifdef CONFIG_EFUSE_VIRTUAL
  21. TEST_CASE("Test keys and purposes, rd, wr, wr_key_purposes are in the initial state", "[efuse]")
  22. {
  23. esp_efuse_utility_reset();
  24. esp_efuse_utility_update_virt_blocks();
  25. esp_efuse_utility_debug_dump_blocks();
  26. for (esp_efuse_block_t num_key = EFUSE_BLK_KEY0; num_key < EFUSE_BLK_KEY_MAX; ++num_key) {
  27. printf("EFUSE_BLK_KEY%d, RD, WR, PURPOSE_USER, PURPOSE_USER WR ... \n", num_key - EFUSE_BLK_KEY0);
  28. uint8_t key[32] = { 0xEE };
  29. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_KEY0, &key, sizeof(key) * 8));
  30. TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
  31. TEST_ASSERT_FALSE(esp_efuse_get_key_dis_read(num_key));
  32. TEST_ASSERT_FALSE(esp_efuse_get_key_dis_write(num_key));
  33. TEST_ASSERT_EQUAL(ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS, esp_efuse_get_key_purpose(num_key));
  34. esp_efuse_block_t key_block = EFUSE_BLK_MAX;
  35. TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_USER, NULL));
  36. TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_USER, &key_block));
  37. TEST_ASSERT_EQUAL(EFUSE_BLK_KEY0, key_block);
  38. printf("EFUSE_BLK_KEY%d, RD, WR, PURPOSE_USER, PURPOSE_USER WR ... OK\n", num_key - EFUSE_BLK_KEY0);
  39. }
  40. }
  41. #endif // CONFIG_EFUSE_VIRTUAL
  42. // If using efuse is real, then turn off writing tests.
  43. #if CONFIG_EFUSE_VIRTUAL || CONFIG_IDF_ENV_FPGA
  44. static esp_err_t s_check_key(esp_efuse_block_t num_key, void* wr_key, esp_efuse_purpose_t purpose)
  45. {
  46. size_t offset_in_bits = 0;
  47. uint8_t key_size = 32;
  48. if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS || purpose == ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2) {
  49. key_size = 16;
  50. }
  51. if (purpose == ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2) {
  52. offset_in_bits = 16 * 8;
  53. }
  54. uint8_t rd_key[32] = { 0xEE };
  55. TEST_ESP_OK(esp_efuse_read_block(EFUSE_BLK_KEY0, &rd_key, offset_in_bits, key_size * 8));
  56. #ifndef CONFIG_IDF_ENV_FPGA
  57. TEST_ASSERT_EQUAL_HEX8_ARRAY(wr_key, rd_key, key_size);
  58. #endif // not CONFIG_IDF_ENV_FPGA
  59. TEST_ASSERT_TRUE(esp_efuse_get_key_dis_write(num_key));
  60. if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY || purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS) {
  61. TEST_ASSERT_TRUE(esp_efuse_get_key_dis_read(num_key));
  62. #if CONFIG_IDF_ENV_FPGA && !CONFIG_EFUSE_VIRTUAL
  63. TEST_ASSERT_EACH_EQUAL_HEX8(0, rd_key, key_size);
  64. #endif // CONFIG_IDF_ENV_FPGA && ! CONFIG_EFUSE_VIRTUAL
  65. } else {
  66. TEST_ASSERT_EQUAL_HEX8_ARRAY(wr_key, rd_key, key_size);
  67. }
  68. return ESP_OK;
  69. }
  70. void test_write_key(esp_efuse_block_t num_key, esp_efuse_purpose_t purpose) {
  71. int id = num_key - EFUSE_BLK_KEY0;
  72. printf("EFUSE_BLK_KEY%d, purpose=%d ... \n", id, purpose);
  73. uint8_t wr_key[32];
  74. for (int i = 0; i < sizeof(wr_key); i++) {
  75. wr_key[i] = id + 1 + i;
  76. }
  77. uint8_t key_size = sizeof(wr_key);
  78. if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS || purpose == ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2) {
  79. key_size = 16;
  80. }
  81. TEST_ASSERT_TRUE(esp_efuse_key_block_unused(num_key));
  82. TEST_ESP_OK(esp_efuse_write_key(num_key, purpose, &wr_key, key_size));
  83. TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_efuse_write_key(num_key, purpose, &wr_key, key_size));
  84. TEST_ESP_OK(s_check_key(num_key, wr_key, purpose));
  85. TEST_ASSERT_FALSE(esp_efuse_key_block_unused(num_key));
  86. printf("EFUSE_BLK_KEY%d, purpose=%d ... OK\n", id, purpose);
  87. }
  88. #ifndef CONFIG_IDF_ENV_FPGA
  89. TEST_CASE("Test esp_efuse_write_key for virt mode", "[efuse]")
  90. {
  91. uint8_t rd_key[32] = { 0xEE };
  92. esp_efuse_utility_reset();
  93. esp_efuse_utility_update_virt_blocks();
  94. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK_KEY0, ESP_EFUSE_KEY_PURPOSE_USER, &rd_key, 33));
  95. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK3, ESP_EFUSE_KEY_PURPOSE_USER, NULL, sizeof(rd_key)));
  96. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK0, ESP_EFUSE_KEY_PURPOSE_USER, &rd_key, sizeof(rd_key)));
  97. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK0, ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS, &rd_key, sizeof(rd_key)));
  98. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK0, ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2, &rd_key, sizeof(rd_key)));
  99. for (esp_efuse_purpose_t purpose = ESP_EFUSE_KEY_PURPOSE_USER; purpose < ESP_EFUSE_KEY_PURPOSE_MAX; ++purpose) {
  100. esp_efuse_utility_reset();
  101. esp_efuse_utility_update_virt_blocks();
  102. esp_efuse_utility_debug_dump_blocks();
  103. if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY) {
  104. TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_XTS_KEY_LENGTH_256));
  105. }
  106. TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
  107. test_write_key(EFUSE_BLK_KEY0, purpose);
  108. TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
  109. esp_efuse_utility_debug_dump_blocks();
  110. }
  111. }
  112. #endif // not CONFIG_IDF_ENV_FPGA
  113. TEST_CASE("Test 1 esp_efuse_write_key for FPGA", "[efuse]")
  114. {
  115. esp_efuse_utility_reset();
  116. esp_efuse_utility_update_virt_blocks();
  117. esp_efuse_utility_debug_dump_blocks();
  118. TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
  119. TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
  120. TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS, NULL));
  121. test_write_key(EFUSE_BLK_KEY0, ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS);
  122. esp_efuse_utility_debug_dump_blocks();
  123. TEST_ASSERT_FALSE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
  124. #ifdef CONFIG_IDF_ENV_FPGA
  125. TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
  126. #else
  127. TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
  128. #endif
  129. printf("reset efuses on the FPGA board for the next test\n");
  130. }
  131. TEST_CASE("Test 2 esp_efuse_write_key for FPGA", "[efuse]")
  132. {
  133. esp_efuse_utility_reset();
  134. esp_efuse_utility_update_virt_blocks();
  135. esp_efuse_utility_debug_dump_blocks();
  136. TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
  137. TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
  138. TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS, NULL));
  139. test_write_key(EFUSE_BLK_KEY0, ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2);
  140. esp_efuse_utility_debug_dump_blocks();
  141. TEST_ASSERT_FALSE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
  142. TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
  143. printf("reset efuses on the FPGA board for the next test\n");
  144. }
  145. TEST_CASE("Test 3 esp_efuse_write_key for FPGA", "[efuse]")
  146. {
  147. esp_efuse_utility_reset();
  148. esp_efuse_utility_update_virt_blocks();
  149. esp_efuse_utility_debug_dump_blocks();
  150. TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
  151. TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
  152. TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_XTS_KEY_LENGTH_256));
  153. TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY, NULL));
  154. test_write_key(EFUSE_BLK_KEY0, ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY);
  155. esp_efuse_utility_debug_dump_blocks();
  156. TEST_ASSERT_FALSE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
  157. #ifdef CONFIG_IDF_ENV_FPGA
  158. TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
  159. #else
  160. TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
  161. #endif
  162. printf("reset efuses on the FPGA board for the next test\n");
  163. }
  164. TEST_CASE("Test esp_efuse_write_keys", "[efuse]")
  165. {
  166. esp_efuse_utility_reset();
  167. esp_efuse_utility_update_virt_blocks();
  168. esp_efuse_utility_debug_dump_blocks();
  169. TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
  170. TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
  171. TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS, NULL));
  172. esp_efuse_block_t key_block = EFUSE_BLK_MAX;
  173. enum { BLOCKS_NEEDED1 = 2 };
  174. esp_efuse_purpose_t purpose1[BLOCKS_NEEDED1] = {
  175. ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS,
  176. ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2,
  177. };
  178. uint8_t keys1[BLOCKS_NEEDED1][32] = {{0xEE}};
  179. for (int num_key = 0; num_key < BLOCKS_NEEDED1; ++num_key) {
  180. for (int i = 0; i < 32; ++i) {
  181. keys1[num_key][i] = purpose1[num_key] + i + 1;
  182. }
  183. }
  184. TEST_ESP_OK(esp_efuse_write_keys(purpose1, keys1, BLOCKS_NEEDED1));
  185. TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose1[0], &key_block));
  186. TEST_ASSERT_EQUAL(EFUSE_BLK_KEY0, key_block);
  187. TEST_ESP_OK(s_check_key(EFUSE_BLK_KEY0, keys1[0], ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS));
  188. TEST_ESP_OK(s_check_key(EFUSE_BLK_KEY0, keys1[1], ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2));
  189. esp_efuse_utility_debug_dump_blocks();
  190. TEST_ASSERT_FALSE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
  191. TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
  192. enum { BLOCKS_NEEDED2 = 1 };
  193. esp_efuse_purpose_t purpose2[BLOCKS_NEEDED2] = {
  194. ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
  195. };
  196. TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_efuse_write_keys(purpose2, keys1, BLOCKS_NEEDED2));
  197. printf("reset efuses on the FPGA board for the next test\n");
  198. }
  199. TEST_CASE("Test esp_efuse_write_keys for returned errors", "[efuse]")
  200. {
  201. esp_efuse_utility_reset();
  202. esp_efuse_utility_update_virt_blocks();
  203. esp_efuse_utility_debug_dump_blocks();
  204. TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
  205. TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
  206. enum { BLOCKS_NEEDED = 2 };
  207. esp_efuse_purpose_t purpose[BLOCKS_NEEDED] = {
  208. ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS,
  209. ESP_EFUSE_KEY_PURPOSE_MAX, // it leads ESP_ERR_INVALID_ARG in esp_efuse_write_keys
  210. };
  211. uint8_t keys[BLOCKS_NEEDED][32];
  212. for (int num_key = 0; num_key < BLOCKS_NEEDED; ++num_key) {
  213. for (int i = 0; i < 32; ++i) {
  214. keys[num_key][i] = purpose[num_key] + i + 1;
  215. }
  216. }
  217. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(NULL, keys, BLOCKS_NEEDED));
  218. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(purpose, NULL, BLOCKS_NEEDED));
  219. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(purpose, keys, BLOCKS_NEEDED)); // ESP_EFUSE_KEY_PURPOSE_MAX is not a valid purpose.
  220. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(purpose, keys, 3));
  221. TEST_ASSERT_TRUE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
  222. TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
  223. TEST_ESP_OK(esp_efuse_write_keys(purpose, keys, 1));
  224. esp_efuse_utility_debug_dump_blocks();
  225. TEST_ASSERT_FALSE(esp_efuse_key_block_unused(EFUSE_BLK_KEY0));
  226. #ifdef CONFIG_IDF_ENV_FPGA
  227. TEST_ASSERT_TRUE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
  228. #else
  229. TEST_ASSERT_FALSE(esp_efuse_block_is_empty(EFUSE_BLK_KEY0));
  230. #endif
  231. }
  232. #endif // CONFIG_EFUSE_VIRTUAL || CONFIG_IDF_ENV_FPGA