1 /*
2  * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <stdio.h>
7 #include <ctype.h>
8 #include <errno.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include "unity.h"
13 #include "test_utils.h"
14 #include "esp_log.h"
15 #include "esp_efuse.h"
16 #include "esp_efuse_table.h"
17 #include "esp_efuse_utility.h"
18 #include "sdkconfig.h"
19 
20 __attribute__((unused)) static const char* TAG = "efuse_test";
21 
22 
23 #ifndef CONFIG_IDF_TARGET_ESP32
24 
25 TEST_CASE("Test keys and purposes, rd, wr, wr_key_purposes are in the initial state", "[efuse]")
26 {
27     esp_efuse_utility_reset();
28     esp_efuse_utility_update_virt_blocks();
29     esp_efuse_utility_debug_dump_blocks();
30 
31     for (esp_efuse_block_t num_key = EFUSE_BLK_KEY0; num_key < EFUSE_BLK_KEY_MAX; ++num_key) {
32         printf("EFUSE_BLK_KEY%d, RD, WR, PURPOSE_USER, PURPOSE_USER WR ... \n", num_key - EFUSE_BLK_KEY0);
33         uint8_t key[32] = { 0xEE };
34         TEST_ESP_OK(esp_efuse_read_field_blob(esp_efuse_get_key(num_key), &key, sizeof(key) * 8));
35         TEST_ASSERT_EACH_EQUAL_HEX8(0, key, sizeof(key));
36         TEST_ASSERT_FALSE(esp_efuse_get_key_dis_read(num_key));
37         TEST_ASSERT_FALSE(esp_efuse_get_key_dis_write(num_key));
38         TEST_ASSERT_EQUAL(ESP_EFUSE_KEY_PURPOSE_USER, esp_efuse_get_key_purpose(num_key));
39         TEST_ASSERT_FALSE(esp_efuse_get_keypurpose_dis_write(num_key));
40 
41         esp_efuse_block_t key_block = EFUSE_BLK_MAX;
42         TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_USER, NULL));
43         TEST_ASSERT_TRUE(esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_USER, &key_block));
44         TEST_ASSERT_EQUAL(EFUSE_BLK_KEY0, key_block);
45         TEST_ASSERT_EQUAL(EFUSE_BLK_KEY0, esp_efuse_find_unused_key_block());
46 
47         printf("EFUSE_BLK_KEY%d, RD, WR, PURPOSE_USER, PURPOSE_USER WR ... OK\n", num_key - EFUSE_BLK_KEY0);
48     }
49 }
50 
51 // If using efuse is real, then turn off writing tests.
52 #if CONFIG_EFUSE_VIRTUAL || CONFIG_IDF_ENV_FPGA
53 
s_check_key(esp_efuse_block_t num_key,void * wr_key)54 static esp_err_t s_check_key(esp_efuse_block_t num_key, void* wr_key)
55 {
56     uint8_t rd_key[32] = { 0xEE };
57     esp_efuse_purpose_t purpose = esp_efuse_get_key_purpose(num_key);
58     TEST_ESP_OK(esp_efuse_read_field_blob(esp_efuse_get_key(num_key), &rd_key, sizeof(rd_key) * 8));
59 #ifndef CONFIG_IDF_ENV_FPGA
60     TEST_ASSERT_EQUAL_HEX8_ARRAY(wr_key, rd_key, sizeof(wr_key));
61 #endif // not CONFIG_IDF_ENV_FPGA
62 
63     TEST_ASSERT_TRUE(esp_efuse_get_key_dis_write(num_key));
64     if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY ||
65 #ifdef SOC_FLASH_ENCRYPTION_XTS_AES_256
66             purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 ||
67             purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 ||
68 #endif
69             purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL ||
70             purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG ||
71             purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE ||
72             purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_UP) {
73         TEST_ASSERT_TRUE(esp_efuse_get_key_dis_read(num_key));
74 #if CONFIG_IDF_ENV_FPGA && !CONFIG_EFUSE_VIRTUAL
75         TEST_ASSERT_EACH_EQUAL_HEX8(0, rd_key, sizeof(rd_key));
76 #endif // CONFIG_IDF_ENV_FPGA && ! CONFIG_EFUSE_VIRTUAL
77     } else {
78         TEST_ASSERT_FALSE(esp_efuse_get_key_dis_read(num_key));
79         TEST_ASSERT_EQUAL_HEX8_ARRAY(wr_key, rd_key, sizeof(wr_key));
80     }
81 
82     TEST_ASSERT_EQUAL(purpose, esp_efuse_get_key_purpose(num_key));
83     esp_efuse_purpose_t purpose2 = 0;
84     TEST_ESP_OK(esp_efuse_read_field_blob(esp_efuse_get_purpose_field(num_key), &purpose2, 4));
85     TEST_ASSERT_EQUAL(purpose, purpose2);
86     TEST_ASSERT_TRUE(esp_efuse_get_keypurpose_dis_write(num_key));
87     return ESP_OK;
88 }
89 
test_write_key(esp_efuse_block_t num_key,esp_efuse_purpose_t purpose)90 void test_write_key(esp_efuse_block_t num_key, esp_efuse_purpose_t purpose) {
91     int id = num_key - EFUSE_BLK_KEY0;
92     printf("EFUSE_BLK_KEY%d, purpose=%d ... \n", id, purpose);
93 
94     uint8_t wr_key[32];
95     for (int i = 0; i < sizeof(wr_key); i++) {
96         wr_key[i] = id + 1 + i;
97     }
98 
99     TEST_ASSERT_TRUE(esp_efuse_key_block_unused(num_key));
100 
101     TEST_ESP_OK(esp_efuse_write_key(num_key, purpose, &wr_key, sizeof(wr_key)));
102     TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_efuse_write_key(num_key, purpose, &wr_key, sizeof(wr_key)));
103 
104     TEST_ESP_OK(s_check_key(num_key, wr_key));
105 
106     TEST_ASSERT_FALSE(esp_efuse_key_block_unused(num_key));
107 
108     printf("EFUSE_BLK_KEY%d, purpose=%d ... OK\n", id, purpose);
109 }
110 
111 #ifndef CONFIG_IDF_ENV_FPGA
112 TEST_CASE("Test esp_efuse_write_key for virt mode", "[efuse]")
113 {
114     uint8_t rd_key[32] = { 0xEE };
115     int tmp_purpose = 0;
116     TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK3, tmp_purpose,  &rd_key, sizeof(rd_key)));
117     TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK_KEY0, tmp_purpose, &rd_key, 33));
118     TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_key(EFUSE_BLK10, tmp_purpose, &rd_key, sizeof(rd_key)));
119 
120     for (esp_efuse_purpose_t purpose = ESP_EFUSE_KEY_PURPOSE_RESERVED; purpose < ESP_EFUSE_KEY_PURPOSE_MAX; ++purpose) {
121         esp_efuse_utility_reset();
122         esp_efuse_utility_update_virt_blocks();
123         esp_efuse_utility_debug_dump_blocks();
124 
125         TEST_ASSERT_FALSE(esp_efuse_find_purpose(purpose, NULL));
126 
127         for (esp_efuse_block_t num_key = (EFUSE_BLK_KEY_MAX - 1); num_key >= EFUSE_BLK_KEY0; --num_key) {
128             int id = num_key - EFUSE_BLK_KEY0;
129             TEST_ASSERT_EQUAL(id + 1, esp_efuse_count_unused_key_blocks());
130             test_write_key(num_key, purpose);
131             TEST_ASSERT_EQUAL(id, esp_efuse_count_unused_key_blocks());
132 
133             esp_efuse_block_t key_block = EFUSE_BLK_KEY_MAX;
134             TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose, &key_block));
135             TEST_ASSERT_EQUAL(num_key, key_block);
136         }
137         esp_efuse_utility_debug_dump_blocks();
138     }
139 }
140 #endif // not CONFIG_IDF_ENV_FPGA
141 
142 TEST_CASE("Test 1 esp_efuse_write_key for FPGA", "[efuse]")
143 {
144     esp_efuse_utility_reset();
145     esp_efuse_utility_update_virt_blocks();
146     esp_efuse_utility_debug_dump_blocks();
147     TEST_ASSERT_EQUAL_MESSAGE(EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0, esp_efuse_count_unused_key_blocks(), "Efuses should be in initial state");
148 
149     esp_efuse_purpose_t purpose [] = {
150         ESP_EFUSE_KEY_PURPOSE_USER,
151         ESP_EFUSE_KEY_PURPOSE_RESERVED,
152 #ifdef SOC_FLASH_ENCRYPTION_XTS_AES_256
153         ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1,
154         ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2,
155 #else
156         ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
157         ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
158 #endif
159         ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
160         ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL,
161     };
162 
163     int max_keys = EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0;
164     for (esp_efuse_block_t num_key = EFUSE_BLK_KEY0; num_key < EFUSE_BLK_KEY_MAX; ++num_key) {
165         int id = num_key - EFUSE_BLK_KEY0;
166         TEST_ASSERT_EQUAL(EFUSE_BLK_KEY_MAX - num_key, esp_efuse_count_unused_key_blocks());
167         test_write_key(num_key, purpose[id]);
168         TEST_ASSERT_EQUAL(EFUSE_BLK_KEY_MAX - num_key - 1, esp_efuse_count_unused_key_blocks());
169         TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose[id], NULL));
170         TEST_ASSERT_EQUAL(--max_keys, esp_efuse_count_unused_key_blocks());
171     }
172     esp_efuse_utility_debug_dump_blocks();
173     printf("reset efuses on the FPGA board for the next test\n");
174 }
175 
176 TEST_CASE("Test 2 esp_efuse_write_key for FPGA", "[efuse]")
177 {
178     esp_efuse_utility_reset();
179     esp_efuse_utility_update_virt_blocks();
180     esp_efuse_utility_debug_dump_blocks();
181     TEST_ASSERT_EQUAL_MESSAGE(EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0, esp_efuse_count_unused_key_blocks(), "Efuses should be in initial state");
182 
183     esp_efuse_purpose_t purpose [] = {
184         ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG,
185         ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE,
186         ESP_EFUSE_KEY_PURPOSE_HMAC_UP,
187         ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0,
188         ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1,
189         ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2,
190     };
191 
192     TEST_ASSERT_EQUAL(EFUSE_BLK_KEY0, esp_efuse_find_unused_key_block());
193     int max_keys = EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0;
194     for (esp_efuse_block_t num_key = EFUSE_BLK_KEY0; num_key < EFUSE_BLK_KEY_MAX; ++num_key) {
195         int id = num_key - EFUSE_BLK_KEY0;
196         TEST_ASSERT_EQUAL(EFUSE_BLK_KEY_MAX - num_key, esp_efuse_count_unused_key_blocks());
197         test_write_key(num_key, purpose[id]);
198         TEST_ASSERT_EQUAL(EFUSE_BLK_KEY_MAX - num_key - 1, esp_efuse_count_unused_key_blocks());
199         TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose[id], NULL));
200         TEST_ASSERT_EQUAL(--max_keys, esp_efuse_count_unused_key_blocks());
201         if (esp_efuse_count_unused_key_blocks()) {
202             TEST_ASSERT_EQUAL(num_key + 1, esp_efuse_find_unused_key_block());
203         } else {
204             TEST_ASSERT_EQUAL(EFUSE_BLK_KEY_MAX, esp_efuse_find_unused_key_block());
205         }
206     }
207     esp_efuse_utility_debug_dump_blocks();
208     printf("reset efuses on the FPGA board for the next test\n");
209 }
210 
211 TEST_CASE("Test esp_efuse_write_keys", "[efuse]")
212 {
213     esp_efuse_utility_reset();
214     esp_efuse_utility_update_virt_blocks();
215     esp_efuse_utility_debug_dump_blocks();
216     TEST_ASSERT_EQUAL_MESSAGE(EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0, esp_efuse_count_unused_key_blocks(), "Efuses should be in initial state");
217     esp_efuse_block_t key_block = EFUSE_BLK_MAX;
218 
219     enum { BLOCKS_NEEDED1 = 2 };
220 #ifdef SOC_FLASH_ENCRYPTION_XTS_AES_256
221     esp_efuse_purpose_t purpose1[BLOCKS_NEEDED1] = {
222             ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1,
223             ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2,
224     };
225 #else
226     esp_efuse_purpose_t purpose1[BLOCKS_NEEDED1] = {
227         ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
228         ESP_EFUSE_KEY_PURPOSE_RESERVED
229     };
230 #endif
231     uint8_t keys1[BLOCKS_NEEDED1][32] = {{0xEE}};
232 
233     for (int num_key = 0; num_key < BLOCKS_NEEDED1; ++num_key) {
234         for (int i = 0; i < 32; ++i) {
235             keys1[num_key][i] = purpose1[num_key] + i + 1;
236         }
237     }
238 
239     TEST_ESP_OK(esp_efuse_write_keys(purpose1, keys1, BLOCKS_NEEDED1));
240 
241     TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose1[0], &key_block));
242     TEST_ASSERT_EQUAL(EFUSE_BLK_KEY0, key_block);
243     TEST_ESP_OK(s_check_key(key_block, keys1[0]));
244 
245     TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose1[1], &key_block));
246     TEST_ASSERT_EQUAL(EFUSE_BLK_KEY1, key_block);
247     TEST_ESP_OK(s_check_key(key_block, keys1[1]));
248     esp_efuse_utility_debug_dump_blocks();
249 
250     TEST_ASSERT_EQUAL(EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0 - 2, esp_efuse_count_unused_key_blocks());
251 
252     enum { BLOCKS_NEEDED2 = 3 };
253     esp_efuse_purpose_t purpose2[BLOCKS_NEEDED2] = {
254             ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0,
255             ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1,
256             ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2,
257     };
258     uint8_t keys2[BLOCKS_NEEDED2][32] = {{0xDD}};
259 
260     for (int num_key = 0; num_key < BLOCKS_NEEDED2; ++num_key) {
261         for (int i = 0; i < 32; ++i) {
262             keys2[num_key][i] = purpose2[num_key] + i + 1;
263         }
264     }
265 
266     TEST_ESP_OK(esp_efuse_write_keys(purpose2, keys2, BLOCKS_NEEDED2));
267 
268     TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose2[0], &key_block));
269     TEST_ASSERT_EQUAL(EFUSE_BLK_KEY2, key_block);
270     TEST_ESP_OK(s_check_key(key_block, keys2[0]));
271 
272     TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose2[1], &key_block));
273     TEST_ASSERT_EQUAL(EFUSE_BLK_KEY3, key_block);
274     TEST_ESP_OK(s_check_key(key_block, keys2[1]));
275 
276     TEST_ASSERT_TRUE(esp_efuse_find_purpose(purpose2[2], &key_block));
277     TEST_ASSERT_EQUAL(EFUSE_BLK_KEY4, key_block);
278     TEST_ESP_OK(s_check_key(key_block, keys2[2]));
279     esp_efuse_utility_debug_dump_blocks();
280     TEST_ASSERT_EQUAL(EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0 - 2 - 3, esp_efuse_count_unused_key_blocks());
281 
282     printf("reset efuses on the FPGA board for the next test\n");
283 }
284 
285 TEST_CASE("Test esp_efuse_write_keys for returned errors", "[efuse]")
286 {
287     esp_efuse_utility_reset();
288     esp_efuse_utility_update_virt_blocks();
289     esp_efuse_utility_debug_dump_blocks();
290     TEST_ASSERT_EQUAL_MESSAGE(EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0, esp_efuse_count_unused_key_blocks(), "Efuses should be in initial state");
291 
292     enum { BLOCKS_NEEDED = 4 };
293     esp_efuse_purpose_t purpose[BLOCKS_NEEDED] = {
294         ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0,
295         ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1,
296         ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2,
297         ESP_EFUSE_KEY_PURPOSE_MAX,                 // it leads  ESP_ERR_INVALID_ARG in esp_efuse_write_keys
298     };
299     uint8_t keys[BLOCKS_NEEDED][32] = {{0xEE}};
300 
301     TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(NULL, keys, BLOCKS_NEEDED));
302     TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(purpose, NULL, BLOCKS_NEEDED));
303     TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(purpose, keys, (EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0) + 1));
304     TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_keys(purpose, keys, BLOCKS_NEEDED)); // ESP_EFUSE_KEY_PURPOSE_MAX is not a valid purpose.
305     TEST_ASSERT_EQUAL(EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0, esp_efuse_count_unused_key_blocks());
306     TEST_ESP_OK(esp_efuse_write_keys(purpose, keys, BLOCKS_NEEDED - 1));
307     TEST_ASSERT_EQUAL((EFUSE_BLK_KEY_MAX - EFUSE_BLK_KEY0) - (BLOCKS_NEEDED - 1), esp_efuse_count_unused_key_blocks());
308     unsigned unused_keys = esp_efuse_count_unused_key_blocks();
309     TEST_ESP_ERR(ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS, esp_efuse_write_keys(purpose, keys, unused_keys + 1));
310 }
311 
312 TEST_CASE("Test revocation APIs", "[efuse]")
313 {
314     esp_efuse_utility_reset();
315     esp_efuse_utility_update_virt_blocks();
316     esp_efuse_utility_debug_dump_blocks();
317 
318     TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(0));
319     TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(1));
320     TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(2));
321 
322     TEST_ASSERT_FALSE(esp_efuse_get_write_protect_of_digest_revoke(0));
323     TEST_ASSERT_FALSE(esp_efuse_get_write_protect_of_digest_revoke(1));
324     TEST_ASSERT_FALSE(esp_efuse_get_write_protect_of_digest_revoke(2));
325 
326     // esp_efuse_get_digest_revoke(3); // assert
327 
328     TEST_ESP_OK(esp_efuse_set_digest_revoke(0));
329     TEST_ASSERT_TRUE(esp_efuse_get_digest_revoke(0));
330 
331     TEST_ESP_OK(esp_efuse_set_digest_revoke(1));
332     TEST_ASSERT_TRUE(esp_efuse_get_digest_revoke(1));
333 
334     TEST_ESP_OK(esp_efuse_set_digest_revoke(2));
335     TEST_ASSERT_TRUE(esp_efuse_get_digest_revoke(2));
336 
337     TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_set_digest_revoke(3));
338 
339     TEST_ESP_OK(esp_efuse_set_write_protect_of_digest_revoke(0));
340     TEST_ASSERT_TRUE(esp_efuse_get_write_protect_of_digest_revoke(0));
341     TEST_ESP_OK(esp_efuse_set_write_protect_of_digest_revoke(1));
342     TEST_ASSERT_TRUE(esp_efuse_get_write_protect_of_digest_revoke(1));
343     TEST_ESP_OK(esp_efuse_set_write_protect_of_digest_revoke(2));
344     TEST_ASSERT_TRUE(esp_efuse_get_write_protect_of_digest_revoke(2));
345     TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_set_write_protect_of_digest_revoke(3));
346 }
347 
348 TEST_CASE("Test set_write_protect_of_digest_revoke", "[efuse]")
349 {
350     esp_efuse_utility_reset();
351     esp_efuse_utility_update_virt_blocks();
352     esp_efuse_utility_debug_dump_blocks();
353 
354     TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(0));
355     TEST_ASSERT_FALSE(esp_efuse_get_write_protect_of_digest_revoke(0));
356     TEST_ESP_OK(esp_efuse_set_write_protect_of_digest_revoke(0));
357     TEST_ASSERT_TRUE(esp_efuse_get_write_protect_of_digest_revoke(0));
358 
359     TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(1));
360     TEST_ASSERT_FALSE(esp_efuse_get_write_protect_of_digest_revoke(1));
361     TEST_ESP_OK(esp_efuse_set_write_protect_of_digest_revoke(1));
362     TEST_ASSERT_TRUE(esp_efuse_get_write_protect_of_digest_revoke(1));
363 
364     TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(2));
365     TEST_ASSERT_FALSE(esp_efuse_get_write_protect_of_digest_revoke(2));
366     TEST_ESP_OK(esp_efuse_set_write_protect_of_digest_revoke(2));
367     TEST_ASSERT_TRUE(esp_efuse_get_write_protect_of_digest_revoke(2));
368 
369     TEST_ESP_OK(esp_efuse_set_digest_revoke(0));
370     TEST_ESP_OK(esp_efuse_set_digest_revoke(1));
371     TEST_ESP_OK(esp_efuse_set_digest_revoke(2));
372 
373 #if CONFIG_IDF_ENV_FPGA && !CONFIG_EFUSE_VIRTUAL
374     // the write protection bits are set and the revocation bits will not be changed.
375     TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(0));
376     TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(1));
377     TEST_ASSERT_FALSE(esp_efuse_get_digest_revoke(2));
378 #else
379     TEST_ASSERT_TRUE(esp_efuse_get_digest_revoke(0));
380     TEST_ASSERT_TRUE(esp_efuse_get_digest_revoke(1));
381     TEST_ASSERT_TRUE(esp_efuse_get_digest_revoke(2));
382 #endif // CONFIG_IDF_ENV_FPGA && !CONFIG_EFUSE_VIRTUAL
383 }
384 
385 #endif // CONFIG_EFUSE_VIRTUAL || CONFIG_IDF_ENV_FPGA
386 
387 #endif // not CONFIG_IDF_TARGET_ESP32
388