Skip to content

Commit c6ce0bc

Browse files
KonstantinKondrashovdobairoland
authored andcommitted
feat(espefuse): Add custom key purposes for ESP32C6/C5/P4
1 parent 4a9a3d8 commit c6ce0bc

File tree

4 files changed

+56
-3
lines changed

4 files changed

+56
-3
lines changed

espefuse/efuse/esp32c5/fields.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,9 @@ def print_field(e, new_value):
432432

433433
# fmt: off
434434
class EfuseKeyPurposeField(EfuseField):
435-
KEY_PURPOSES = [
435+
key_purpose_len = 5 # bits for key purpose
436+
KeyPurposeType = tuple[str, int, str | None, str | None, str]
437+
KEY_PURPOSES: list[KeyPurposeType] = [
436438
("USER", 0, None, None, "no_need_rd_protect"), # User purposes (software-only use)
437439
("ECDSA_KEY_P256", 1, None, "Reverse", "need_rd_protect"), # ECDSA key P256
438440
("ECDSA_KEY", 1, None, "Reverse", "need_rd_protect"), # ECDSA key P256
@@ -458,6 +460,14 @@ class EfuseKeyPurposeField(EfuseField):
458460
("ECDSA_KEY_P384_H", 18, None, "Reverse", "need_rd_protect"), # ECDSA key P384 high
459461
("ECDSA_KEY_P384", -3, "VIRTUAL", None, "need_rd_protect"), # Virtual purpose splits to ECDSA_KEY_P384_L and ECDSA_KEY_P384_H
460462
]
463+
CUSTOM_KEY_PURPOSES: list[KeyPurposeType] = []
464+
for id in range(0, 1 << key_purpose_len):
465+
if id not in [p[1] for p in KEY_PURPOSES]:
466+
CUSTOM_KEY_PURPOSES.append((f"CUSTOM_{id}", id, None, None, "no_need_rd_protect"))
467+
CUSTOM_KEY_PURPOSES.append((f"CUSTOM_DIGEST_{id}", id, "DIGEST", None, "no_need_rd_protect"))
468+
CUSTOM_KEY_PURPOSES.append(("CUSTOM_MAX", (1 << key_purpose_len) - 1, None, None, "no_need_rd_protect"))
469+
CUSTOM_KEY_PURPOSES.append(("CUSTOM_DIGEST_MAX", (1 << key_purpose_len) - 1, "DIGEST", None, "no_need_rd_protect"))
470+
KEY_PURPOSES += CUSTOM_KEY_PURPOSES
461471
# fmt: on
462472
KEY_PURPOSES_NAME = [name[0] for name in KEY_PURPOSES]
463473
DIGEST_KEY_PURPOSES = [name[0] for name in KEY_PURPOSES if name[2] == "DIGEST"]

espefuse/efuse/esp32c6/fields.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,9 @@ def print_field(e, new_value):
396396

397397
# fmt: off
398398
class EfuseKeyPurposeField(EfuseField):
399-
KEY_PURPOSES = [
399+
key_purpose_len = 4 # bits for key purpose
400+
KeyPurposeType = tuple[str, int, str | None, str | None, str]
401+
KEY_PURPOSES: list[KeyPurposeType] = [
400402
("USER", 0, None, None, "no_need_rd_protect"), # User purposes (software-only use)
401403
("RESERVED", 1, None, None, "no_need_rd_protect"), # Reserved
402404
("XTS_AES_128_KEY", 4, None, "Reverse", "need_rd_protect"), # XTS_AES_128_KEY (flash/PSRAM encryption)
@@ -408,6 +410,14 @@ class EfuseKeyPurposeField(EfuseField):
408410
("SECURE_BOOT_DIGEST1", 10, "DIGEST", None, "no_need_rd_protect"), # SECURE_BOOT_DIGEST1 (Secure Boot key digest)
409411
("SECURE_BOOT_DIGEST2", 11, "DIGEST", None, "no_need_rd_protect"), # SECURE_BOOT_DIGEST2 (Secure Boot key digest)
410412
]
413+
CUSTOM_KEY_PURPOSES: list[KeyPurposeType] = []
414+
for id in range(0, 1 << key_purpose_len):
415+
if id not in [p[1] for p in KEY_PURPOSES]:
416+
CUSTOM_KEY_PURPOSES.append((f"CUSTOM_{id}", id, None, None, "no_need_rd_protect"))
417+
CUSTOM_KEY_PURPOSES.append((f"CUSTOM_DIGEST_{id}", id, "DIGEST", None, "no_need_rd_protect"))
418+
CUSTOM_KEY_PURPOSES.append(("CUSTOM_MAX", (1 << key_purpose_len) - 1, None, None, "no_need_rd_protect"))
419+
CUSTOM_KEY_PURPOSES.append(("CUSTOM_DIGEST_MAX", (1 << key_purpose_len) - 1, "DIGEST", None, "no_need_rd_protect"))
420+
KEY_PURPOSES += CUSTOM_KEY_PURPOSES
411421
# fmt: on
412422
KEY_PURPOSES_NAME = [name[0] for name in KEY_PURPOSES]
413423
DIGEST_KEY_PURPOSES = [name[0] for name in KEY_PURPOSES if name[2] == "DIGEST"]

espefuse/efuse/esp32p4/fields.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,9 @@ def print_field(e, new_value):
387387

388388
# fmt: off
389389
class EfuseKeyPurposeField(EfuseField):
390-
KEY_PURPOSES = [
390+
key_purpose_len = 4 # bits for key purpose
391+
KeyPurposeType = tuple[str, int, str | None, str | None, str]
392+
KEY_PURPOSES: list[KeyPurposeType] = [
391393
("USER", 0, None, None, "no_need_rd_protect"), # User purposes (software-only use)
392394
("ECDSA_KEY", 1, None, "Reverse", "need_rd_protect"), # ECDSA key
393395
("XTS_AES_256_KEY_1", 2, None, "Reverse", "need_rd_protect"), # XTS_AES_256_KEY_1 (flash/PSRAM encryption)
@@ -403,6 +405,14 @@ class EfuseKeyPurposeField(EfuseField):
403405
("KM_INIT_KEY", 12, None, None, "need_rd_protect"), # init key that is used for the generation of AES/ECDSA key
404406
("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
405407
]
408+
CUSTOM_KEY_PURPOSES: list[KeyPurposeType] = []
409+
for id in range(0, 1 << key_purpose_len):
410+
if id not in [p[1] for p in KEY_PURPOSES]:
411+
CUSTOM_KEY_PURPOSES.append((f"CUSTOM_{id}", id, None, None, "no_need_rd_protect"))
412+
CUSTOM_KEY_PURPOSES.append((f"CUSTOM_DIGEST_{id}", id, "DIGEST", None, "no_need_rd_protect"))
413+
CUSTOM_KEY_PURPOSES.append(("CUSTOM_MAX", (1 << key_purpose_len) - 1, None, None, "no_need_rd_protect"))
414+
CUSTOM_KEY_PURPOSES.append(("CUSTOM_DIGEST_MAX", (1 << key_purpose_len) - 1, "DIGEST", None, "no_need_rd_protect"))
415+
KEY_PURPOSES += CUSTOM_KEY_PURPOSES
406416
# fmt: on
407417
KEY_PURPOSES_NAME = [name[0] for name in KEY_PURPOSES]
408418
DIGEST_KEY_PURPOSES = [name[0] for name in KEY_PURPOSES if name[2] == "DIGEST"]

test/test_espefuse.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2285,3 +2285,26 @@ def test_extend_efuse_table_with_csv_file(self):
22852285
MY_ID_NUMK_1 1 \
22862286
MY_DATA_FIELD1 1"
22872287
)
2288+
2289+
2290+
@pytest.mark.skipif(
2291+
Command(arg_chip, "burn-key").does_not_support("CUSTOM_MAX"),
2292+
reason="Does not provides support for custom key purposes",
2293+
)
2294+
class TestCustomKeyPurposes(EfuseTestCase):
2295+
def test_custom_key_purposes(self):
2296+
self.espefuse_py(f"burn-key BLOCK_KEY0 {IMAGES_DIR}/256bit CUSTOM_MAX")
2297+
output = self.espefuse_py("-d summary")
2298+
self.check_data_block_in_log(output, f"{IMAGES_DIR}/256bit")
2299+
2300+
def test_custom_digest_key_purposes(self):
2301+
self.espefuse_py(
2302+
f"burn-key-digest BLOCK_KEY0 \
2303+
{S_IMAGES_DIR}/rsa_secure_boot_signing_key.pem \
2304+
CUSTOM_DIGEST_MAX"
2305+
)
2306+
output = self.espefuse_py("-d summary")
2307+
assert (
2308+
" = cb 27 91 a3 71 b0 c0 32 2b f7 37 04 78 ba 09 62 "
2309+
"22 4c ab 1c f2 28 78 79 e4 29 67 3e 7d a8 44 63 R/-"
2310+
) in output

0 commit comments

Comments
 (0)