1 /*
2  * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #include <stdbool.h>
10 #include <stdint.h>
11 
12 #include "esp_err.h"
13 #include "esp_log.h"
14 #include "soc/soc_caps.h"
15 #include "sdkconfig.h"
16 #include "esp_efuse_chip.h"
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 #define ESP_ERR_EFUSE                              0x1600                     /*!< Base error code for efuse api. */
23 #define ESP_OK_EFUSE_CNT                          (ESP_ERR_EFUSE + 0x01)      /*!< OK the required number of bits is set. */
24 #define ESP_ERR_EFUSE_CNT_IS_FULL                 (ESP_ERR_EFUSE + 0x02)      /*!< Error field is full. */
25 #define ESP_ERR_EFUSE_REPEATED_PROG               (ESP_ERR_EFUSE + 0x03)      /*!< Error repeated programming of programmed bits is strictly forbidden. */
26 #define ESP_ERR_CODING                            (ESP_ERR_EFUSE + 0x04)      /*!< Error while a encoding operation. */
27 #define ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS      (ESP_ERR_EFUSE + 0x05)      /*!< Error not enough unused key blocks available */
28 #define ESP_ERR_DAMAGED_READING                   (ESP_ERR_EFUSE + 0x06)      /*!< Error. Burn or reset was done during a reading operation leads to damage read data. This error is internal to the efuse component and not returned by any public API. */
29 
30 /**
31  * @brief Type definition for an eFuse field
32  */
33 typedef struct {
34     esp_efuse_block_t   efuse_block: 8; /**< Block of eFuse */
35     uint8_t             bit_start;      /**< Start bit [0..255] */
36     uint16_t            bit_count;      /**< Length of bit field [1..-]*/
37 } esp_efuse_desc_t;
38 
39 /**
40  * @brief Type definition for ROM log scheme
41  */
42 typedef enum {
43     ESP_EFUSE_ROM_LOG_ALWAYS_ON,    /**< Always enable ROM logging */
44     ESP_EFUSE_ROM_LOG_ON_GPIO_LOW,  /**< ROM logging is enabled when specific GPIO level is low during start up */
45     ESP_EFUSE_ROM_LOG_ON_GPIO_HIGH, /**< ROM logging is enabled when specific GPIO level is high during start up */
46     ESP_EFUSE_ROM_LOG_ALWAYS_OFF    /**< Disable ROM logging permanently */
47 } esp_efuse_rom_log_scheme_t;
48 
49 #if CONFIG_ESP32_REV_MIN_FULL >= 300 || !CONFIG_IDF_TARGET_ESP32
50 /**
51  * @brief Pointers to the trusted key digests.
52  *
53  * The number of digests depends on the SOC's capabilities.
54  */
55 typedef struct {
56     const void *key_digests[SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS]; /**< Pointers to the key digests */
57 } esp_secure_boot_key_digests_t;
58 #endif
59 
60 /**
61  * @brief   Reads bits from EFUSE field and writes it into an array.
62  *
63  * The number of read bits will be limited to the minimum value
64  * from the description of the bits in "field" structure or "dst_size_bits" required size.
65  * Use "esp_efuse_get_field_size()" function to determine the length of the field.
66  *
67  * @note Please note that reading in the batch mode does not show uncommitted changes.
68  *
69  * @param[in]  field          A pointer to the structure describing the fields of efuse.
70  * @param[out] dst            A pointer to array that will contain the result of reading.
71  * @param[in]  dst_size_bits  The number of bits required to read.
72  *                            If the requested number of bits is greater than the field,
73  *                            the number will be limited to the field size.
74  *
75  * @return
76  *    - ESP_OK: The operation was successfully completed.
77  *    - ESP_ERR_INVALID_ARG: Error in the passed arguments.
78  */
79 esp_err_t esp_efuse_read_field_blob(const esp_efuse_desc_t* field[], void* dst, size_t dst_size_bits);
80 
81 
82 /**
83  * @brief Read a single bit eFuse field as a boolean value.
84  *
85  * @note The value must exist and must be a single bit wide. If there is any possibility of an error
86  * in the provided arguments, call esp_efuse_read_field_blob() and check the returned value instead.
87  *
88  * @note If assertions are enabled and the parameter is invalid, execution will abort
89  * @note Please note that reading in the batch mode does not show uncommitted changes.
90  *
91  * @param[in]  field          A pointer to the structure describing the fields of efuse.
92  * @return
93  *    - true: The field parameter is valid and the bit is set.
94  *    - false: The bit is not set, or the parameter is invalid and assertions are disabled.
95  *
96  */
97 bool esp_efuse_read_field_bit(const esp_efuse_desc_t *field[]);
98 
99 /**
100  * @brief   Reads bits from EFUSE field and returns number of bits programmed as "1".
101  *
102  * If the bits are set not sequentially, they will still be counted.
103  * @note Please note that reading in the batch mode does not show uncommitted changes.
104  *
105  * @param[in]  field          A pointer to the structure describing the fields of efuse.
106  * @param[out] out_cnt        A pointer that will contain the number of programmed as "1" bits.
107  *
108  * @return
109  *    - ESP_OK: The operation was successfully completed.
110  *    - ESP_ERR_INVALID_ARG: Error in the passed arguments.
111  */
112 esp_err_t esp_efuse_read_field_cnt(const esp_efuse_desc_t* field[], size_t* out_cnt);
113 
114 /**
115  * @brief   Writes array to EFUSE field.
116  *
117  * The number of write bits will be limited to the minimum value
118  * from the description of the bits in "field" structure or "src_size_bits" required size.
119  * Use "esp_efuse_get_field_size()" function to determine the length of the field.
120  * After the function is completed, the writing registers are cleared.
121  * @param[in]  field          A pointer to the structure describing the fields of efuse.
122  * @param[in]  src            A pointer to array that contains the data for writing.
123  * @param[in]  src_size_bits  The number of bits required to write.
124  *
125  * @return
126  *    - ESP_OK: The operation was successfully completed.
127  *    - ESP_ERR_INVALID_ARG: Error in the passed arguments.
128  *    - ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.
129  *    - ESP_ERR_CODING: Error range of data does not match the coding scheme.
130  */
131 esp_err_t esp_efuse_write_field_blob(const esp_efuse_desc_t* field[], const void* src, size_t src_size_bits);
132 
133 /**
134  * @brief   Writes a required count of bits as "1" to EFUSE field.
135  *
136  * If there are no free bits in the field to set the required number of bits to "1",
137  * ESP_ERR_EFUSE_CNT_IS_FULL error is returned, the field will not be partially recorded.
138  * After the function is completed, the writing registers are cleared.
139  * @param[in]  field          A pointer to the structure describing the fields of efuse.
140  * @param[in]  cnt            Required number of programmed as "1" bits.
141  *
142  * @return
143  *    - ESP_OK: The operation was successfully completed.
144  *    - ESP_ERR_INVALID_ARG: Error in the passed arguments.
145  *    - ESP_ERR_EFUSE_CNT_IS_FULL: Not all requested cnt bits is set.
146  */
147 esp_err_t esp_efuse_write_field_cnt(const esp_efuse_desc_t* field[], size_t cnt);
148 
149 /**
150  * @brief Write a single bit eFuse field to 1
151  *
152  * For use with eFuse fields that are a single bit. This function will write the bit to value 1 if
153  * it is not already set, or does nothing if the bit is already set.
154  *
155  * This is equivalent to calling esp_efuse_write_field_cnt() with the cnt parameter equal to 1,
156  * except that it will return ESP_OK if the field is already set to 1.
157  *
158  * @param[in] field Pointer to the structure describing the efuse field.
159  *
160  * @return
161  * - ESP_OK: The operation was successfully completed, or the bit was already set to value 1.
162  * - ESP_ERR_INVALID_ARG: Error in the passed arugments, including if the efuse field is not 1 bit wide.
163  */
164 esp_err_t esp_efuse_write_field_bit(const esp_efuse_desc_t* field[]);
165 
166 /**
167  * @brief   Sets a write protection for the whole block.
168  *
169  * After that, it is impossible to write to this block.
170  * The write protection does not apply to block 0.
171  * @param[in]  blk          Block number of eFuse. (EFUSE_BLK1, EFUSE_BLK2 and EFUSE_BLK3)
172  *
173  * @return
174  *    - ESP_OK: The operation was successfully completed.
175  *    - ESP_ERR_INVALID_ARG: Error in the passed arguments.
176  *    - ESP_ERR_EFUSE_CNT_IS_FULL: Not all requested cnt bits is set.
177  *    - ESP_ERR_NOT_SUPPORTED: The block does not support this command.
178  */
179 esp_err_t esp_efuse_set_write_protect(esp_efuse_block_t blk);
180 
181 /**
182  * @brief   Sets a read protection for the whole block.
183  *
184  * After that, it is impossible to read from this block.
185  * The read protection does not apply to block 0.
186  * @param[in]  blk          Block number of eFuse. (EFUSE_BLK1, EFUSE_BLK2 and EFUSE_BLK3)
187  *
188  * @return
189  *    - ESP_OK: The operation was successfully completed.
190  *    - ESP_ERR_INVALID_ARG: Error in the passed arguments.
191  *    - ESP_ERR_EFUSE_CNT_IS_FULL: Not all requested cnt bits is set.
192  *    - ESP_ERR_NOT_SUPPORTED: The block does not support this command.
193  */
194 esp_err_t esp_efuse_set_read_protect(esp_efuse_block_t blk);
195 
196 /**
197  * @brief   Returns the number of bits used by field.
198  *
199  * @param[in]  field          A pointer to the structure describing the fields of efuse.
200  *
201  * @return Returns the number of bits used by field.
202  */
203 int esp_efuse_get_field_size(const esp_efuse_desc_t* field[]);
204 
205 /**
206  * @brief   Returns value of efuse register.
207  *
208  * This is a thread-safe implementation.
209  * Example: EFUSE_BLK2_RDATA3_REG where (blk=2, num_reg=3)
210  * @note Please note that reading in the batch mode does not show uncommitted changes.
211  *
212  * @param[in]  blk     Block number of eFuse.
213  * @param[in]  num_reg The register number in the block.
214  *
215  * @return Value of register
216  */
217 uint32_t esp_efuse_read_reg(esp_efuse_block_t blk, unsigned int num_reg);
218 
219 /**
220  * @brief   Write value to efuse register.
221  *
222  * Apply a coding scheme if necessary.
223  * This is a thread-safe implementation.
224  * Example: EFUSE_BLK3_WDATA0_REG where (blk=3, num_reg=0)
225  * @param[in]  blk     Block number of eFuse.
226  * @param[in]  num_reg The register number in the block.
227  * @param[in]  val     Value to write.
228  *
229  * @return
230  *      - ESP_OK: The operation was successfully completed.
231  *      - ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.
232  */
233 esp_err_t esp_efuse_write_reg(esp_efuse_block_t blk, unsigned int num_reg, uint32_t val);
234 
235 /**
236  * @brief   Return efuse coding scheme for blocks.
237  *
238  * @note The coding scheme is applicable only to 1, 2 and 3 blocks. For 0 block, the coding scheme is always ``NONE``.
239  *
240  * @param[in]  blk     Block number of eFuse.
241  * @return Return efuse coding scheme for blocks
242  */
243 esp_efuse_coding_scheme_t esp_efuse_get_coding_scheme(esp_efuse_block_t blk);
244 
245 /**
246  * @brief   Read key to efuse block starting at the offset and the required size.
247  *
248  * @note Please note that reading in the batch mode does not show uncommitted changes.
249  *
250  * @param[in]  blk             Block number of eFuse.
251  * @param[in]  dst_key         A pointer to array that will contain the result of reading.
252  * @param[in]  offset_in_bits  Start bit in block.
253  * @param[in]  size_bits       The number of bits required to read.
254  *
255  * @return
256  *    - ESP_OK: The operation was successfully completed.
257  *    - ESP_ERR_INVALID_ARG: Error in the passed arguments.
258  *    - ESP_ERR_CODING: Error range of data does not match the coding scheme.
259  */
260 esp_err_t esp_efuse_read_block(esp_efuse_block_t blk, void* dst_key, size_t offset_in_bits, size_t size_bits);
261 
262 /**
263  * @brief   Write key to efuse block starting at the offset and the required size.
264  *
265  * @param[in]  blk             Block number of eFuse.
266  * @param[in]  src_key         A pointer to array that contains the key for writing.
267  * @param[in]  offset_in_bits  Start bit in block.
268  * @param[in]  size_bits       The number of bits required to write.
269  *
270  * @return
271  *    - ESP_OK: The operation was successfully completed.
272  *    - ESP_ERR_INVALID_ARG: Error in the passed arguments.
273  *    - ESP_ERR_CODING: Error range of data does not match the coding scheme.
274  *    - ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits
275  */
276 esp_err_t esp_efuse_write_block(esp_efuse_block_t blk, const void* src_key, size_t offset_in_bits, size_t size_bits);
277 
278 /**
279  * @brief   Returns chip package from efuse
280  *
281  * @return chip package
282  */
283 uint32_t esp_efuse_get_pkg_ver(void);
284 
285 
286 /**
287  *  @brief Reset efuse write registers
288  *
289  * Efuse write registers are written to zero, to negate
290  * any changes that have been staged here.
291  *
292  * @note This function is not threadsafe, if calling code updates
293  * efuse values from multiple tasks then this is caller's
294  * responsibility to serialise.
295  */
296 void esp_efuse_reset(void);
297 
298 #ifdef CONFIG_IDF_TARGET_ESP32
299 /**
300  *  @brief Disable BASIC ROM Console via efuse
301  *
302  * By default, if booting from flash fails the ESP32 will boot a
303  * BASIC console in ROM.
304  *
305  * Call this function (from bootloader or app) to permanently disable the console on this chip.
306  *
307  */
308 void esp_efuse_disable_basic_rom_console(void);
309 #endif
310 
311 
312 /**
313  *  @brief Disable ROM Download Mode via eFuse
314  *
315  * Permanently disables the ROM Download Mode feature. Once disabled, if the SoC is booted with
316  * strapping pins set for ROM Download Mode then an error is printed instead.
317  *
318  * @note Not all SoCs support this option. An error will be returned if called on an ESP32
319  * with a silicon revision lower than 3, as these revisions do not support this option.
320  *
321  * @note If ROM Download Mode is already disabled, this function does nothing and returns success.
322  *
323  * @return
324  * - ESP_OK If the eFuse was successfully burned, or had already been burned.
325  * - ESP_ERR_NOT_SUPPORTED (ESP32 only) This SoC is not capable of disabling UART download mode
326  * - ESP_ERR_INVALID_STATE (ESP32 only) This eFuse is write protected and cannot be written
327  */
328 esp_err_t esp_efuse_disable_rom_download_mode(void);
329 
330 /**
331  * @brief Set boot ROM log scheme via eFuse
332  *
333  * @note By default, the boot ROM will always print to console. This API can be called to set the log scheme only once per chip,
334  *       once the value is changed from the default it can't be changed again.
335  *
336  * @param log_scheme Supported ROM log scheme
337  * @return
338  *      - ESP_OK If the eFuse was successfully burned, or had already been burned.
339  *      - ESP_ERR_NOT_SUPPORTED (ESP32 only) This SoC is not capable of setting ROM log scheme
340  *      - ESP_ERR_INVALID_STATE This eFuse is write protected or has been burned already
341  */
342 esp_err_t esp_efuse_set_rom_log_scheme(esp_efuse_rom_log_scheme_t log_scheme);
343 
344 #if SOC_SUPPORTS_SECURE_DL_MODE
345 /**
346  *  @brief Switch ROM Download Mode to Secure Download mode via eFuse
347  *
348  * Permanently enables Secure Download mode. This mode limits the use of ROM Download Mode functions
349  * to simple flash read, write and erase operations, plus a command to return a summary of currently
350  * enabled security features.
351  *
352  * @note If Secure Download mode is already enabled, this function does nothing and returns success.
353  *
354  * @note Disabling the ROM Download Mode also disables Secure Download Mode.
355  *
356  * @return
357  * - ESP_OK If the eFuse was successfully burned, or had already been burned.
358  * - ESP_ERR_INVALID_STATE ROM Download Mode has been disabled via eFuse, so Secure Download mode is unavailable.
359  */
360 esp_err_t esp_efuse_enable_rom_secure_download_mode(void);
361 #endif
362 
363 
364 /**
365  *  @brief Return secure_version from efuse field.
366  * @return Secure version from efuse field
367  */
368 uint32_t esp_efuse_read_secure_version(void);
369 
370 /**
371  *  @brief Check secure_version from app and secure_version and from efuse field.
372  *
373  * @param secure_version Secure version from app.
374  * @return
375  *          - True: If version of app is equal or more then secure_version from efuse.
376  */
377 bool esp_efuse_check_secure_version(uint32_t secure_version);
378 
379 /**
380  *  @brief Write efuse field by secure_version value.
381  *
382  * Update the secure_version value is available if the coding scheme is None.
383  * Note: Do not use this function in your applications. This function is called as part of the other API.
384  *
385  * @param[in] secure_version Secure version from app.
386  * @return
387  *          - ESP_OK: Successful.
388  *          - ESP_FAIL: secure version of app cannot be set to efuse field.
389  *          - ESP_ERR_NOT_SUPPORTED: Anti rollback is not supported with the 3/4 and Repeat coding scheme.
390  */
391 esp_err_t esp_efuse_update_secure_version(uint32_t secure_version);
392 
393 #if defined(BOOTLOADER_BUILD) && defined(CONFIG_EFUSE_VIRTUAL) && !defined(CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH)
394 /**
395  *  @brief Initializes eFuses API to keep eFuses in RAM.
396  *
397  * This function just copies all eFuses to RAM. IDF eFuse APIs perform all operators with RAM instead of real eFuse.
398  * (Used only in bootloader).
399  */
400 void esp_efuse_init_virtual_mode_in_ram(void);
401 #endif
402 
403 #ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
404 /**
405  *  @brief Initializes variables: offset and size to simulate the work of an eFuse.
406  *
407  * Note: To simulate the work of an eFuse need to set CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH option
408  * and to add in the partition.csv file a line `efuse_em, data, efuse,   ,   0x2000,`.
409  *
410  * @param[in] offset The starting address of the partition where the eFuse data will be located.
411  * @param[in] size The size of the partition.
412  */
413 void esp_efuse_init_virtual_mode_in_flash(uint32_t offset, uint32_t size);
414 #endif
415 
416 /**
417  *  @brief Set the batch mode of writing fields.
418  *
419  * This mode allows you to write the fields in the batch mode when need to burn several efuses at one time.
420  * To enable batch mode call begin() then perform as usually the necessary operations
421  * read and write and at the end call commit() to actually burn all written efuses.
422  * The batch mode can be used nested. The commit will be done by the last commit() function.
423  * The number of begin() functions should be equal to the number of commit() functions.
424  *
425  * @note Please note that reading in the batch mode does not show uncommitted changes.
426  *
427  * Note: If batch mode is enabled by the first task, at this time the second task cannot write/read efuses.
428  * The second task will wait for the first task to complete the batch operation.
429  *
430  * \code{c}
431  * // Example of using the batch writing mode.
432  *
433  * // set the batch writing mode
434  * esp_efuse_batch_write_begin();
435  *
436  * // use any writing functions as usual
437  * esp_efuse_write_field_blob(ESP_EFUSE_...);
438  * esp_efuse_write_field_cnt(ESP_EFUSE_...);
439  * esp_efuse_set_write_protect(EFUSE_BLKx);
440  * esp_efuse_write_reg(EFUSE_BLKx, ...);
441  * esp_efuse_write_block(EFUSE_BLKx, ...);
442  * esp_efuse_write(ESP_EFUSE_1, 3);  // ESP_EFUSE_1 == 1, here we write a new value = 3. The changes will be burn by the commit() function.
443  * esp_efuse_read_...(ESP_EFUSE_1);  // this function returns ESP_EFUSE_1 == 1 because uncommitted changes are not readable, it will be available only after commit.
444  * ...
445  *
446  * // esp_efuse_batch_write APIs can be called recursively.
447  * esp_efuse_batch_write_begin();
448  * esp_efuse_set_write_protect(EFUSE_BLKx);
449  * esp_efuse_batch_write_commit(); // the burn will be skipped here, it will be done in the last commit().
450  *
451  * ...
452  *
453  * // Write all of these fields to the efuse registers
454  * esp_efuse_batch_write_commit();
455  * esp_efuse_read_...(ESP_EFUSE_1);  // this function returns ESP_EFUSE_1 == 3.
456  *
457  * \endcode
458  *
459  * @return
460  *          - ESP_OK: Successful.
461  */
462 esp_err_t esp_efuse_batch_write_begin(void);
463 
464 /**
465  *  @brief Reset the batch mode of writing fields.
466  *
467  * It will reset the batch writing mode and any written changes.
468  *
469  * @return
470  *          - ESP_OK: Successful.
471  *          - ESP_ERR_INVALID_STATE: Tha batch mode was not set.
472  */
473 esp_err_t esp_efuse_batch_write_cancel(void);
474 
475 /**
476  *  @brief Writes all prepared data for the batch mode.
477  *
478  * Must be called to ensure changes are written to the efuse registers.
479  * After this the batch writing mode will be reset.
480  *
481  * @return
482  *          - ESP_OK: Successful.
483  *          - ESP_ERR_INVALID_STATE: The deferred writing mode was not set.
484  */
485 esp_err_t esp_efuse_batch_write_commit(void);
486 
487 /**
488  *  @brief Checks that the given block is empty.
489  *
490  * @return
491  *          - True: The block is empty.
492  *          - False: The block is not empty or was an error.
493  */
494 bool esp_efuse_block_is_empty(esp_efuse_block_t block);
495 
496 /**
497  * @brief Returns a read protection for the key block.
498  *
499  * @param[in] block A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX
500  *
501  * @return True: The key block is read protected
502  *         False: The key block is readable.
503  */
504 bool esp_efuse_get_key_dis_read(esp_efuse_block_t block);
505 
506 /**
507  * @brief Sets a read protection for the key block.
508  *
509  * @param[in] block A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX
510  *
511  * @return
512  *    - ESP_OK: Successful.
513  *    - ESP_ERR_INVALID_ARG: Error in the passed arguments.
514  *    - ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.
515  *    - ESP_ERR_CODING: Error range of data does not match the coding scheme.
516  */
517 esp_err_t esp_efuse_set_key_dis_read(esp_efuse_block_t block);
518 
519 /**
520  * @brief Returns a write protection for the key block.
521  *
522  * @param[in] block A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX
523  *
524  * @return True: The key block is write protected
525  *         False: The key block is writeable.
526  */
527 bool esp_efuse_get_key_dis_write(esp_efuse_block_t block);
528 
529 /**
530  * @brief Sets a write protection for the key block.
531  *
532  * @param[in] block A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX
533  *
534  * @return
535  *    - ESP_OK: Successful.
536  *    - ESP_ERR_INVALID_ARG: Error in the passed arguments.
537  *    - ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.
538  *    - ESP_ERR_CODING: Error range of data does not match the coding scheme.
539  */
540 esp_err_t esp_efuse_set_key_dis_write(esp_efuse_block_t block);
541 
542 /**
543  * @brief Returns true if the key block is unused, false otherwise.
544  *
545  * An unused key block is all zero content, not read or write protected,
546  * and has purpose 0 (ESP_EFUSE_KEY_PURPOSE_USER)
547  *
548  * @param block key block to check.
549  *
550  * @return
551  *         - True if key block is unused,
552  *         - False if key block is used or the specified block index is not a key block.
553  */
554 bool esp_efuse_key_block_unused(esp_efuse_block_t block);
555 
556 /**
557  * @brief Find a key block with the particular purpose set.
558  *
559  * @param[in] purpose Purpose to search for.
560  * @param[out] block Pointer in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX which will be set to the key block if found.
561  *                   Can be NULL, if only need to test the key block exists.
562  *
563  * @return
564  *         - True: If found,
565  *         - False: If not found (value at block pointer is unchanged).
566  */
567 bool esp_efuse_find_purpose(esp_efuse_purpose_t purpose, esp_efuse_block_t *block);
568 
569 /**
570  * @brief Returns a write protection of the key purpose field for an efuse key block.
571  *
572  * @param[in] block A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX
573  *
574  * @note For ESP32: no keypurpose, it returns always True.
575  *
576  * @return True: The key purpose is write protected.
577  *         False: The key purpose is writeable.
578  */
579 bool esp_efuse_get_keypurpose_dis_write(esp_efuse_block_t block);
580 
581 /**
582  * @brief Returns the current purpose set for an efuse key block.
583  *
584  * @param[in] block A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX
585  *
586  * @return
587  *         - Value: If Successful, it returns the value of the purpose related to the given key block.
588  *         - ESP_EFUSE_KEY_PURPOSE_MAX: Otherwise.
589  */
590 esp_efuse_purpose_t esp_efuse_get_key_purpose(esp_efuse_block_t block);
591 
592 #if SOC_EFUSE_KEY_PURPOSE_FIELD
593 /**
594  * @brief Returns a pointer to a key purpose for an efuse key block.
595  *
596  * @param[in] block A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX
597  *
598  * To get the value of this field use esp_efuse_read_field_blob() or esp_efuse_get_key_purpose().
599  *
600  * @return Pointer: If Successful returns a pointer to the corresponding efuse field otherwise NULL.
601  */
602 const esp_efuse_desc_t **esp_efuse_get_purpose_field(esp_efuse_block_t block);
603 
604 /**
605  * @brief Returns a pointer to a key block.
606  *
607  * @param[in] block A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX
608  *
609  * @return Pointer: If Successful returns a pointer to the corresponding efuse field otherwise NULL.
610  */
611 const esp_efuse_desc_t** esp_efuse_get_key(esp_efuse_block_t block);
612 
613 /**
614  * @brief Sets a key purpose for an efuse key block.
615  *
616  * @param[in] block A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX
617  * @param[in] purpose Key purpose.
618  *
619  * @return
620  *    - ESP_OK: Successful.
621  *    - ESP_ERR_INVALID_ARG: Error in the passed arguments.
622  *    - ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.
623  *    - ESP_ERR_CODING: Error range of data does not match the coding scheme.
624  */
625 esp_err_t esp_efuse_set_key_purpose(esp_efuse_block_t block, esp_efuse_purpose_t purpose);
626 
627 /**
628  * @brief Sets a write protection of the key purpose field for an efuse key block.
629  *
630  * @param[in] block A key block in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX
631  *
632  * @return
633  *    - ESP_OK: Successful.
634  *    - ESP_ERR_INVALID_ARG: Error in the passed arguments.
635  *    - ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.
636  *    - ESP_ERR_CODING: Error range of data does not match the coding scheme.
637  */
638 esp_err_t esp_efuse_set_keypurpose_dis_write(esp_efuse_block_t block);
639 
640 /**
641  * @brief Search for an unused key block and return the first one found.
642  *
643  * See esp_efuse_key_block_unused for a description of an unused key block.
644  *
645  * @return First unused key block, or EFUSE_BLK_KEY_MAX if no unused key block is found.
646  */
647 esp_efuse_block_t esp_efuse_find_unused_key_block(void);
648 
649 /**
650  * @brief Return the number of unused efuse key blocks in the range EFUSE_BLK_KEY0..EFUSE_BLK_KEY_MAX
651  */
652 unsigned esp_efuse_count_unused_key_blocks(void);
653 
654 #endif // SOC_EFUSE_KEY_PURPOSE_FIELD
655 
656 #if SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY
657 /**
658  * @brief Returns the status of the Secure Boot public key digest revocation bit.
659  *
660  * @param[in] num_digest The number of digest in range 0..2
661  *
662  * @return
663  *         - True: If key digest is revoked,
664  *         - False; If key digest is not revoked.
665  */
666 bool esp_efuse_get_digest_revoke(unsigned num_digest);
667 
668 /**
669  * @brief Sets the Secure Boot public key digest revocation bit.
670  *
671  * @param[in] num_digest The number of digest in range 0..2
672  *
673  * @return
674  *    - ESP_OK: Successful.
675  *    - ESP_ERR_INVALID_ARG: Error in the passed arguments.
676  *    - ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.
677  *    - ESP_ERR_CODING: Error range of data does not match the coding scheme.
678  */
679 esp_err_t esp_efuse_set_digest_revoke(unsigned num_digest);
680 
681 /**
682  * @brief Returns a write protection of the Secure Boot public key digest revocation bit.
683  *
684  * @param[in] num_digest The number of digest in range 0..2
685  *
686  * @return True: The revocation bit is write protected.
687  *         False: The revocation bit is writeable.
688  */
689 bool esp_efuse_get_write_protect_of_digest_revoke(unsigned num_digest);
690 
691 /**
692  * @brief Sets a write protection of the Secure Boot public key digest revocation bit.
693  *
694  * @param[in] num_digest The number of digest in range 0..2
695  *
696  * @return
697  *    - ESP_OK: Successful.
698  *    - ESP_ERR_INVALID_ARG: Error in the passed arguments.
699  *    - ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.
700  *    - ESP_ERR_CODING: Error range of data does not match the coding scheme.
701  */
702 esp_err_t esp_efuse_set_write_protect_of_digest_revoke(unsigned num_digest);
703 
704 #endif // SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY
705 
706 /**
707  * @brief Program a block of key data to an efuse block
708  *
709  * The burn of a key, protection bits, and a purpose happens in batch mode.
710  *
711  * @note This API also enables the read protection efuse bit for certain key blocks like XTS-AES, HMAC, ECDSA etc.
712  * This ensures that the key is only accessible to hardware peripheral.
713  *
714  * @note For SoC's with capability `SOC_EFUSE_ECDSA_USE_HARDWARE_K` (e.g., ESP32-H2), this API writes an additional
715  * efuse bit for ECDSA key purpose to enforce hardware TRNG generated k mode in the peripheral.
716  *
717  * @param[in] block Block to read purpose for. Must be in range EFUSE_BLK_KEY0 to EFUSE_BLK_KEY_MAX. Key block must be unused (esp_efuse_key_block_unused).
718  * @param[in] purpose Purpose to set for this key. Purpose must be already unset.
719  * @param[in] key Pointer to data to write.
720  * @param[in] key_size_bytes Bytes length of data to write.
721  *
722  * @return
723  *    - ESP_OK: Successful.
724  *    - ESP_ERR_INVALID_ARG: Error in the passed arguments.
725  *    - ESP_ERR_INVALID_STATE: Error in efuses state, unused block not found.
726  *    - ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.
727  *    - ESP_ERR_CODING: Error range of data does not match the coding scheme.
728  */
729 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);
730 
731 /**
732  * @brief Program keys to unused efuse blocks
733  *
734  * The burn of keys, protection bits, and purposes happens in batch mode.
735  *
736  * @note This API also enables the read protection efuse bit for certain key blocks like XTS-AES, HMAC, ECDSA etc.
737  * This ensures that the key is only accessible to hardware peripheral.
738  *
739  * @note For SoC's with capability `SOC_EFUSE_ECDSA_USE_HARDWARE_K` (e.g., ESP32-H2), this API writes an additional
740  * efuse bit for ECDSA key purpose to enforce hardware TRNG generated k mode in the peripheral.
741  *
742  * @param[in] purposes Array of purposes (purpose[number_of_keys]).
743  * @param[in] keys Array of keys (uint8_t keys[number_of_keys][32]). Each key is 32 bytes long.
744  * @param[in] number_of_keys The number of keys to write (up to 6 keys).
745  *
746  * @return
747  *    - ESP_OK: Successful.
748  *    - ESP_ERR_INVALID_ARG: Error in the passed arguments.
749  *    - ESP_ERR_INVALID_STATE: Error in efuses state, unused block not found.
750  *    - ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS: Error not enough unused key blocks available
751  *    - ESP_ERR_EFUSE_REPEATED_PROG: Error repeated programming of programmed bits is strictly forbidden.
752  *    - ESP_ERR_CODING: Error range of data does not match the coding scheme.
753  */
754 esp_err_t esp_efuse_write_keys(const esp_efuse_purpose_t purposes[], uint8_t keys[][32], unsigned number_of_keys);
755 
756 
757 #if CONFIG_ESP32_REV_MIN_FULL >= 300 || !CONFIG_IDF_TARGET_ESP32
758 /**
759  * @brief Read key digests from efuse. Any revoked/missing digests will be marked as NULL
760  *
761  * @param[out] trusted_key_digests Trusted keys digests, stored in this parameter after successfully
762  *                                 completing this function.
763  *                                 The number of digests depends on the SOC's capabilities.
764  *
765  * @return
766  *    - ESP_OK: Successful.
767  *    - ESP_FAIL: If trusted_keys is NULL or there is no valid digest.
768  */
769 esp_err_t esp_secure_boot_read_key_digests(esp_secure_boot_key_digests_t *trusted_key_digests);
770 #endif
771 
772 /**
773  * @brief   Checks eFuse errors in BLOCK0.
774  *
775  * @note Refers to ESP32-C3 only.
776  *
777  * It does a BLOCK0 check if eFuse EFUSE_ERR_RST_ENABLE is set.
778  * If BLOCK0 has an error, it prints the error and returns ESP_FAIL, which should be treated as esp_restart.
779  *
780  * @return
781  *         - ESP_OK: No errors in BLOCK0.
782  *         - ESP_FAIL: Error in BLOCK0 requiring reboot.
783  */
784 esp_err_t esp_efuse_check_errors(void);
785 
786 #ifdef __cplusplus
787 }
788 #endif
789