esp_efuse_api_key_esp32.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "esp_efuse.h"
  7. #include "esp_efuse_utility.h"
  8. #include "soc/efuse_periph.h"
  9. #include "assert.h"
  10. #include "sdkconfig.h"
  11. #include "esp_efuse_table.h"
  12. static __attribute__((unused)) const char *TAG = "efuse";
  13. /**
  14. * @brief Keys and their attributes are packed into a structure
  15. */
  16. typedef struct {
  17. const esp_efuse_desc_t** key_rd_dis; /**< Read protection of a key */
  18. const esp_efuse_desc_t** key_wr_dis; /**< Write protection of a key*/
  19. } esp_efuse_keys_t;
  20. const esp_efuse_keys_t s_table[EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0] = {
  21. {ESP_EFUSE_RD_DIS_BLK1, ESP_EFUSE_WR_DIS_BLK1},
  22. {ESP_EFUSE_RD_DIS_BLK2, ESP_EFUSE_WR_DIS_BLK2},
  23. {ESP_EFUSE_RD_DIS_BLK3, ESP_EFUSE_WR_DIS_BLK3},
  24. };
  25. // Sets a write protection for the whole block.
  26. esp_err_t esp_efuse_set_write_protect(esp_efuse_block_t blk)
  27. {
  28. if (blk == EFUSE_BLK0 || blk >= EFUSE_BLK_MAX) {
  29. return ESP_ERR_NOT_SUPPORTED;
  30. }
  31. unsigned idx = blk - EFUSE_BLK1;
  32. return esp_efuse_write_field_cnt(s_table[idx].key_wr_dis, 1);
  33. }
  34. // read protect for blk.
  35. esp_err_t esp_efuse_set_read_protect(esp_efuse_block_t blk)
  36. {
  37. if (blk == EFUSE_BLK0 || blk >= EFUSE_BLK_MAX) {
  38. return ESP_ERR_NOT_SUPPORTED;
  39. }
  40. unsigned idx = blk - EFUSE_BLK1;
  41. return esp_efuse_write_field_cnt(s_table[idx].key_rd_dis, 1);
  42. }
  43. // get efuse coding_scheme.
  44. esp_efuse_coding_scheme_t esp_efuse_get_coding_scheme(esp_efuse_block_t blk)
  45. {
  46. esp_efuse_coding_scheme_t scheme;
  47. if (blk == EFUSE_BLK0) {
  48. scheme = EFUSE_CODING_SCHEME_NONE;
  49. } else {
  50. uint32_t coding_scheme = REG_GET_FIELD(EFUSE_BLK0_RDATA6_REG, EFUSE_CODING_SCHEME);
  51. if (coding_scheme == EFUSE_CODING_SCHEME_VAL_NONE ||
  52. coding_scheme == (EFUSE_CODING_SCHEME_VAL_34 | EFUSE_CODING_SCHEME_VAL_REPEAT)) {
  53. scheme = EFUSE_CODING_SCHEME_NONE;
  54. } else if (coding_scheme == EFUSE_CODING_SCHEME_VAL_34) {
  55. scheme = EFUSE_CODING_SCHEME_3_4;
  56. } else {
  57. scheme = EFUSE_CODING_SCHEME_REPEAT;
  58. }
  59. }
  60. return scheme;
  61. }
  62. bool esp_efuse_block_is_empty(esp_efuse_block_t block)
  63. {
  64. unsigned blk_len_bit = 256;
  65. uint32_t key[8];
  66. if (esp_efuse_get_coding_scheme(block) == EFUSE_CODING_SCHEME_3_4) {
  67. blk_len_bit = 192;
  68. }
  69. esp_err_t err = esp_efuse_read_block(block, &key, 0, blk_len_bit);
  70. if (err != ESP_OK) {
  71. return false;
  72. }
  73. unsigned zeros = 0;
  74. for (unsigned i = 0; i < blk_len_bit / 32; ++i) {
  75. if (key[i] == 0) {
  76. ++zeros;
  77. }
  78. }
  79. if (zeros == blk_len_bit / 32) {
  80. return true;
  81. }
  82. return false;
  83. }
  84. bool esp_efuse_get_key_dis_read(esp_efuse_block_t block)
  85. {
  86. assert(block >= EFUSE_BLK_KEY0 && block < EFUSE_BLK_KEY_MAX);
  87. unsigned idx = block - EFUSE_BLK_KEY0;
  88. return esp_efuse_read_field_bit(s_table[idx].key_rd_dis);
  89. }
  90. esp_err_t esp_efuse_set_key_dis_read(esp_efuse_block_t block)
  91. {
  92. if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
  93. return ESP_ERR_INVALID_ARG;
  94. }
  95. unsigned idx = block - EFUSE_BLK_KEY0;
  96. return esp_efuse_write_field_bit(s_table[idx].key_rd_dis);
  97. }
  98. bool esp_efuse_get_key_dis_write(esp_efuse_block_t block)
  99. {
  100. assert(block >= EFUSE_BLK_KEY0 && block < EFUSE_BLK_KEY_MAX);
  101. unsigned idx = block - EFUSE_BLK_KEY0;
  102. return esp_efuse_read_field_bit(s_table[idx].key_wr_dis);
  103. }
  104. esp_err_t esp_efuse_set_key_dis_write(esp_efuse_block_t block)
  105. {
  106. if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
  107. return ESP_ERR_INVALID_ARG;
  108. }
  109. unsigned idx = block - EFUSE_BLK_KEY0;
  110. return esp_efuse_write_field_bit(s_table[idx].key_wr_dis);
  111. }
  112. bool esp_efuse_key_block_unused(esp_efuse_block_t block)
  113. {
  114. if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX) {
  115. return false; // Not a key block
  116. }
  117. if (esp_efuse_get_key_dis_read(block) || esp_efuse_get_key_dis_write(block) ||
  118. !esp_efuse_block_is_empty(block)) {
  119. return false; // Block in use!
  120. }
  121. return true; // Unused
  122. }
  123. esp_efuse_purpose_t esp_efuse_get_key_purpose(esp_efuse_block_t block)
  124. {
  125. esp_efuse_purpose_t ret_purpose;
  126. if (block == EFUSE_BLK0) {
  127. ret_purpose = ESP_EFUSE_KEY_PURPOSE_SYSTEM;
  128. } else if (block == EFUSE_BLK_ENCRYPT_FLASH) {
  129. ret_purpose = ESP_EFUSE_KEY_PURPOSE_FLASH_ENCRYPTION;
  130. } else if (block == EFUSE_BLK_SECURE_BOOT) {
  131. ret_purpose = ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2;
  132. } else if (block == EFUSE_BLK3) {
  133. ret_purpose = ESP_EFUSE_KEY_PURPOSE_USER;
  134. } else {
  135. ret_purpose = ESP_EFUSE_KEY_PURPOSE_MAX;
  136. }
  137. return ret_purpose;
  138. }
  139. bool esp_efuse_get_keypurpose_dis_write(esp_efuse_block_t block)
  140. {
  141. (void)block;
  142. return true;
  143. }
  144. bool esp_efuse_find_purpose(esp_efuse_purpose_t purpose, esp_efuse_block_t *block)
  145. {
  146. esp_efuse_block_t dummy;
  147. if (block == NULL) {
  148. block = &dummy;
  149. }
  150. for (esp_efuse_block_t b = EFUSE_BLK_KEY0; b < EFUSE_BLK_KEY_MAX; b++) {
  151. if (esp_efuse_get_key_purpose(b) == purpose) {
  152. *block = b;
  153. return true;
  154. }
  155. }
  156. return false;
  157. }
  158. esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpose, const void *key, size_t key_size_bytes)
  159. {
  160. esp_err_t err = ESP_OK;
  161. if (block < EFUSE_BLK_KEY0 || block >= EFUSE_BLK_KEY_MAX || key_size_bytes > 32 || purpose >= ESP_EFUSE_KEY_PURPOSE_MAX
  162. || esp_efuse_get_key_purpose(block) != purpose) {
  163. return ESP_ERR_INVALID_ARG;
  164. }
  165. esp_efuse_batch_write_begin();
  166. if (!esp_efuse_key_block_unused(block)) {
  167. err = ESP_ERR_INVALID_STATE;
  168. } else {
  169. ESP_EFUSE_CHK(esp_efuse_write_block(block, key, 0, key_size_bytes * 8));
  170. ESP_EFUSE_CHK(esp_efuse_set_key_dis_write(block));
  171. if (purpose == ESP_EFUSE_KEY_PURPOSE_FLASH_ENCRYPTION) {
  172. ESP_EFUSE_CHK(esp_efuse_set_key_dis_read(block));
  173. }
  174. return esp_efuse_batch_write_commit();
  175. }
  176. err_exit:
  177. esp_efuse_batch_write_cancel();
  178. return err;
  179. }
  180. esp_err_t esp_efuse_write_keys(const esp_efuse_purpose_t purposes[], uint8_t keys[][32], unsigned number_of_keys)
  181. {
  182. esp_err_t err = ESP_FAIL;
  183. if (number_of_keys == 0 || number_of_keys > (EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0) || keys == NULL || purposes == NULL) {
  184. return ESP_ERR_INVALID_ARG;
  185. }
  186. size_t key_size = 32;
  187. esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK_KEY0);
  188. if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
  189. key_size = 24;
  190. }
  191. esp_efuse_purpose_t purpose = 0;
  192. esp_efuse_block_t block = EFUSE_BLK_KEY0;
  193. esp_efuse_batch_write_begin();
  194. for (unsigned i_key = 0; (block < EFUSE_BLK_KEY_MAX) && (i_key < number_of_keys); block++) {
  195. purpose = purposes[i_key];
  196. if (esp_efuse_get_key_purpose(block) == purpose) {
  197. ESP_LOGI(TAG, "Writing EFUSE_BLK_KEY%d with purpose %d", block - EFUSE_BLK_KEY0, purpose);
  198. ESP_EFUSE_CHK(esp_efuse_write_key(block, purpose, keys[i_key], key_size));
  199. i_key++;
  200. }
  201. }
  202. return esp_efuse_batch_write_commit();
  203. err_exit:
  204. ESP_LOGE(TAG, "Failed to write EFUSE_BLK_KEY%d with purpose %d. Can't continue.", block - EFUSE_BLK_KEY0, purpose);
  205. esp_efuse_batch_write_cancel();
  206. return err;
  207. }
  208. #if CONFIG_ESP32_REV_MIN_3
  209. esp_err_t esp_secure_boot_read_key_digests(ets_secure_boot_key_digests_t *trusted_keys)
  210. {
  211. if (trusted_keys == NULL) {
  212. return ESP_FAIL;
  213. }
  214. trusted_keys->key_digests[0] = (const void *)esp_efuse_utility_get_read_register_address(EFUSE_BLK_SECURE_BOOT);
  215. return ESP_OK;
  216. }
  217. #endif // CONFIG_ESP32_REV_MIN_3