Skip to content

Commit 3726726

Browse files
KonstantinKondrashovKonstantin Kondrashov
authored andcommitted
feat(espefuse): Support efuse for ESP32-C5 ECO2 (v1.0)
1 parent 5241cba commit 3726726

File tree

5 files changed

+241
-135
lines changed

5 files changed

+241
-135
lines changed

espefuse/efuse/esp32c5/fields.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,12 @@ def print_field(e, new_value):
405405
class EfuseKeyPurposeField(EfuseField):
406406
KEY_PURPOSES = [
407407
("USER", 0, None, None, "no_need_rd_protect"), # User purposes (software-only use)
408-
("ECDSA_KEY", 1, None, "Reverse", "need_rd_protect"), # ECDSA key
408+
("ECDSA_KEY", 1, None, "Reverse", "need_rd_protect"), # ECDSA key P256
409+
("ECDSA_KEY_P256", 1, None, "Reverse", "need_rd_protect"), # ECDSA key P256
409410
("RESERVED", 1, None, None, "no_need_rd_protect"), # Reserved
411+
("XTS_AES_256_KEY_1", 2, None, "Reverse", "need_rd_protect"), # XTS_AES_256_KEY_1 (flash/PSRAM encryption)
412+
("XTS_AES_256_KEY_2", 3, None, "Reverse", "need_rd_protect"), # XTS_AES_256_KEY_2 (flash/PSRAM encryption)
413+
("XTS_AES_256_KEY", -1, "VIRTUAL", None, "no_need_rd_protect"), # Virtual purpose splits to XTS_AES_256_KEY_1 and XTS_AES_256_KEY_2
410414
("XTS_AES_128_KEY", 4, None, "Reverse", "need_rd_protect"), # XTS_AES_128_KEY (flash/PSRAM encryption)
411415
("HMAC_DOWN_ALL", 5, None, None, "need_rd_protect"), # HMAC Downstream mode
412416
("HMAC_DOWN_JTAG", 6, None, None, "need_rd_protect"), # JTAG soft enable key (uses HMAC Downstream mode)
@@ -415,6 +419,14 @@ class EfuseKeyPurposeField(EfuseField):
415419
("SECURE_BOOT_DIGEST0", 9, "DIGEST", None, "no_need_rd_protect"), # SECURE_BOOT_DIGEST0 (Secure Boot key digest)
416420
("SECURE_BOOT_DIGEST1", 10, "DIGEST", None, "no_need_rd_protect"), # SECURE_BOOT_DIGEST1 (Secure Boot key digest)
417421
("SECURE_BOOT_DIGEST2", 11, "DIGEST", None, "no_need_rd_protect"), # SECURE_BOOT_DIGEST2 (Secure Boot key digest)
422+
("KM_INIT_KEY", 12, None, None, "need_rd_protect"), # init key that is used for the generation of AES/ECDSA key
423+
("XTS_AES_256_PSRAM_KEY_1", 13, None, "Reverse", "need_rd_protect"), # XTS_AES_256_PSRAM_KEY_1 (PSRAM encryption)
424+
("XTS_AES_256_PSRAM_KEY_2", 14, None, "Reverse", "need_rd_protect"), # XTS_AES_256_PSRAM_KEY_1 (PSRAM encryption)
425+
# ("XTS_AES_256_PSRAM_KEY", -2, "VIRTUAL", None, "no_need_rd_protect"), # Virtual purpose splits to XTS_AES_256_PSRAM_KEY_1 and XTS_AES_256_PSRAM_KEY_1
426+
("XTS_AES_128_PSRAM_KEY", 15, None, "Reverse", "need_rd_protect"), # XTS_AES_128_PSRAM_KEY (PSRAM encryption)
427+
("ECDSA_KEY_P192", 16, None, "Reverse", "need_rd_protect"), # ECDSA key P192
428+
("ECDSA_KEY_P384_L", 17, None, "Reverse", "need_rd_protect"), # ECDSA key P384 low
429+
("ECDSA_KEY_P384_H", 18, None, "Reverse", "need_rd_protect"), # ECDSA key P384 high
418430
]
419431
# fmt: on
420432
KEY_PURPOSES_NAME = [name[0] for name in KEY_PURPOSES]

espefuse/efuse/esp32c5/mem_definition.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,20 @@ class EfuseDefineRegisters(EfuseRegistersBase):
2525
EFUSE_CHECK_VALUE0_REG = DR_REG_EFUSE_BASE + 0x020
2626
EFUSE_CLK_REG = DR_REG_EFUSE_BASE + 0x1C8
2727
EFUSE_CONF_REG = DR_REG_EFUSE_BASE + 0x1CC
28-
EFUSE_STATUS_REG = DR_REG_EFUSE_BASE + 0x1D0
29-
EFUSE_CMD_REG = DR_REG_EFUSE_BASE + 0x1D4
30-
EFUSE_RD_RS_ERR0_REG = DR_REG_EFUSE_BASE + 0x1C0
31-
EFUSE_RD_RS_ERR1_REG = DR_REG_EFUSE_BASE + 0x1C4
28+
EFUSE_STATUS_REG = DR_REG_EFUSE_BASE + 0x1D4
29+
EFUSE_CMD_REG = DR_REG_EFUSE_BASE + 0x1D8
30+
EFUSE_RD_RS_ERR0_REG = DR_REG_EFUSE_BASE + 0x190
31+
EFUSE_RD_RS_ERR1_REG = DR_REG_EFUSE_BASE + 0x194
3232
EFUSE_RD_REPEAT_ERR0_REG = DR_REG_EFUSE_BASE + 0x17C
3333
EFUSE_RD_REPEAT_ERR1_REG = DR_REG_EFUSE_BASE + 0x180
3434
EFUSE_RD_REPEAT_ERR2_REG = DR_REG_EFUSE_BASE + 0x184
3535
EFUSE_RD_REPEAT_ERR3_REG = DR_REG_EFUSE_BASE + 0x188
3636
EFUSE_RD_REPEAT_ERR4_REG = DR_REG_EFUSE_BASE + 0x18C
37-
EFUSE_DAC_CONF_REG = DR_REG_EFUSE_BASE + 0x1E8
38-
EFUSE_RD_TIM_CONF_REG = DR_REG_EFUSE_BASE + 0x1EC
39-
EFUSE_WR_TIM_CONF1_REG = DR_REG_EFUSE_BASE + 0x1F0
40-
EFUSE_WR_TIM_CONF2_REG = DR_REG_EFUSE_BASE + 0x1F4
41-
EFUSE_DATE_REG = DR_REG_EFUSE_BASE + 0x1FC
37+
EFUSE_DAC_CONF_REG = DR_REG_EFUSE_BASE + 0x1EC
38+
EFUSE_RD_TIM_CONF_REG = DR_REG_EFUSE_BASE + 0x1F0
39+
EFUSE_WR_TIM_CONF1_REG = DR_REG_EFUSE_BASE + 0x1F4
40+
EFUSE_WR_TIM_CONF2_REG = DR_REG_EFUSE_BASE + 0x1F8
41+
EFUSE_DATE_REG = DR_REG_EFUSE_BASE + 0x198
4242
EFUSE_WRITE_OP_CODE = 0x5A5A
4343
EFUSE_READ_OP_CODE = 0x5AA5
4444
EFUSE_PGM_CMD_MASK = 0x3

espefuse/efuse/esp32c5/operations.py

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# SPDX-License-Identifier: GPL-2.0-or-later
66

77
import argparse
8+
import io
89
import os # noqa: F401. It is used in IDF scripts
910
import traceback
1011

@@ -199,6 +200,67 @@ def adc_info(esp, efuses, args):
199200
print(f"{efuse.name:<30} = ", efuses[efuse.name].get())
200201

201202

203+
def key_block_is_unused(block, key_purpose_block):
204+
if not block.is_readable() or not block.is_writeable():
205+
return False
206+
207+
if key_purpose_block.get() != "USER" or not key_purpose_block.is_writeable():
208+
return False
209+
210+
if not block.get_bitstring().all(False):
211+
return False
212+
213+
return True
214+
215+
216+
def get_next_key_block(efuses, current_key_block, block_name_list):
217+
key_blocks = [b for b in efuses.blocks if b.key_purpose_name]
218+
start = key_blocks.index(current_key_block)
219+
220+
# Sort key blocks so that we pick the next free block (and loop around if necessary)
221+
key_blocks = key_blocks[start:] + key_blocks[0:start]
222+
223+
# Exclude any other blocks that will be be burned
224+
key_blocks = [b for b in key_blocks if b.name not in block_name_list]
225+
226+
for block in key_blocks:
227+
key_purpose_block = efuses[block.key_purpose_name]
228+
if key_block_is_unused(block, key_purpose_block):
229+
return block
230+
231+
return None
232+
233+
234+
def split_512_bit_key(efuses, block_name_list, datafile_list, keypurpose_list):
235+
i = keypurpose_list.index("XTS_AES_256_KEY")
236+
block_name = block_name_list[i]
237+
238+
block_num = efuses.get_index_block_by_name(block_name)
239+
block = efuses.blocks[block_num]
240+
241+
data = datafile_list[i].read()
242+
if len(data) != 64:
243+
raise esptool.FatalError(
244+
"Incorrect key file size %d, XTS_AES_256_KEY should be 64 bytes" % len(data)
245+
)
246+
247+
key_block_2 = get_next_key_block(efuses, block, block_name_list)
248+
if not key_block_2:
249+
raise esptool.FatalError("XTS_AES_256_KEY requires two free keyblocks")
250+
251+
keypurpose_list.append("XTS_AES_256_KEY_1")
252+
datafile_list.append(io.BytesIO(data[:32]))
253+
block_name_list.append(block_name)
254+
255+
keypurpose_list.append("XTS_AES_256_KEY_2")
256+
datafile_list.append(io.BytesIO(data[32:]))
257+
block_name_list.append(key_block_2.name)
258+
259+
keypurpose_list.pop(i)
260+
datafile_list.pop(i)
261+
block_name_list.pop(i)
262+
263+
202264
def burn_key(esp, efuses, args, digest=None):
203265
if digest is None:
204266
datafile_list = args.keyfile[
@@ -214,6 +276,11 @@ def burn_key(esp, efuses, args, digest=None):
214276
0 : len([name for name in args.keypurpose if name is not None]) :
215277
]
216278

279+
if "XTS_AES_256_KEY" in keypurpose_list:
280+
# XTS_AES_256_KEY is not an actual HW key purpose, needs to be split into
281+
# XTS_AES_256_KEY_1 and XTS_AES_256_KEY_2
282+
split_512_bit_key(efuses, block_name_list, datafile_list, keypurpose_list)
283+
217284
util.check_duplicate_name_in_list(block_name_list)
218285
if len(block_name_list) != len(datafile_list) or len(block_name_list) != len(
219286
keypurpose_list
@@ -240,7 +307,7 @@ def burn_key(esp, efuses, args, digest=None):
240307
block = efuses.blocks[block_num]
241308

242309
if digest is None:
243-
if keypurpose == "ECDSA_KEY":
310+
if keypurpose.startswith("ECDSA_KEY"):
244311
sk = espsecure.load_ecdsa_signing_key(datafile)
245312
data = espsecure.get_ecdsa_signing_key_raw_bytes(sk)
246313
if len(data) == 24:

0 commit comments

Comments
 (0)