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