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