mirror of
https://github.com/espressif/esptool.git
synced 2025-10-20 13:23:38 +08:00
feat(espefuse): Support XTS_AES_256_KEY key_purpose for ESP32P4
This commit is contained in:

committed by
Radim Karniš

parent
f607f19296
commit
a91eee192e
@@ -387,6 +387,7 @@ class EfuseKeyPurposeField(EfuseField):
|
|||||||
("SECURE_BOOT_DIGEST1", 10, "DIGEST", None, "no_need_rd_protect"), # SECURE_BOOT_DIGEST1 (Secure Boot key digest)
|
("SECURE_BOOT_DIGEST1", 10, "DIGEST", None, "no_need_rd_protect"), # SECURE_BOOT_DIGEST1 (Secure Boot key digest)
|
||||||
("SECURE_BOOT_DIGEST2", 11, "DIGEST", None, "no_need_rd_protect"), # SECURE_BOOT_DIGEST2 (Secure Boot key digest)
|
("SECURE_BOOT_DIGEST2", 11, "DIGEST", None, "no_need_rd_protect"), # SECURE_BOOT_DIGEST2 (Secure Boot key digest)
|
||||||
("KM_INIT_KEY", 12, None, None, "need_rd_protect"), # init key that is used for the generation of AES/ECDSA key
|
("KM_INIT_KEY", 12, None, None, "need_rd_protect"), # init key that is used for the generation of AES/ECDSA key
|
||||||
|
("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
|
||||||
]
|
]
|
||||||
# fmt: on
|
# fmt: on
|
||||||
KEY_PURPOSES_NAME = [name[0] for name in KEY_PURPOSES]
|
KEY_PURPOSES_NAME = [name[0] for name in KEY_PURPOSES]
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import io
|
||||||
import os # noqa: F401. It is used in IDF scripts
|
import os # noqa: F401. It is used in IDF scripts
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
@@ -191,6 +192,67 @@ def adc_info(esp, efuses, args):
|
|||||||
print("not supported yet")
|
print("not supported yet")
|
||||||
|
|
||||||
|
|
||||||
|
def key_block_is_unused(block, key_purpose_block):
|
||||||
|
if not block.is_readable() or not block.is_writeable():
|
||||||
|
return False
|
||||||
|
|
||||||
|
if key_purpose_block.get() != "USER" or not key_purpose_block.is_writeable():
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not block.get_bitstring().all(False):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def get_next_key_block(efuses, current_key_block, block_name_list):
|
||||||
|
key_blocks = [b for b in efuses.blocks if b.key_purpose_name]
|
||||||
|
start = key_blocks.index(current_key_block)
|
||||||
|
|
||||||
|
# Sort key blocks so that we pick the next free block (and loop around if necessary)
|
||||||
|
key_blocks = key_blocks[start:] + key_blocks[0:start]
|
||||||
|
|
||||||
|
# Exclude any other blocks that will be be burned
|
||||||
|
key_blocks = [b for b in key_blocks if b.name not in block_name_list]
|
||||||
|
|
||||||
|
for block in key_blocks:
|
||||||
|
key_purpose_block = efuses[block.key_purpose_name]
|
||||||
|
if key_block_is_unused(block, key_purpose_block):
|
||||||
|
return block
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def split_512_bit_key(efuses, block_name_list, datafile_list, keypurpose_list):
|
||||||
|
i = keypurpose_list.index("XTS_AES_256_KEY")
|
||||||
|
block_name = block_name_list[i]
|
||||||
|
|
||||||
|
block_num = efuses.get_index_block_by_name(block_name)
|
||||||
|
block = efuses.blocks[block_num]
|
||||||
|
|
||||||
|
data = datafile_list[i].read()
|
||||||
|
if len(data) != 64:
|
||||||
|
raise esptool.FatalError(
|
||||||
|
"Incorrect key file size %d, XTS_AES_256_KEY should be 64 bytes" % len(data)
|
||||||
|
)
|
||||||
|
|
||||||
|
key_block_2 = get_next_key_block(efuses, block, block_name_list)
|
||||||
|
if not key_block_2:
|
||||||
|
raise esptool.FatalError("XTS_AES_256_KEY requires two free keyblocks")
|
||||||
|
|
||||||
|
keypurpose_list.append("XTS_AES_256_KEY_1")
|
||||||
|
datafile_list.append(io.BytesIO(data[:32]))
|
||||||
|
block_name_list.append(block_name)
|
||||||
|
|
||||||
|
keypurpose_list.append("XTS_AES_256_KEY_2")
|
||||||
|
datafile_list.append(io.BytesIO(data[32:]))
|
||||||
|
block_name_list.append(key_block_2.name)
|
||||||
|
|
||||||
|
keypurpose_list.pop(i)
|
||||||
|
datafile_list.pop(i)
|
||||||
|
block_name_list.pop(i)
|
||||||
|
|
||||||
|
|
||||||
def burn_key(esp, efuses, args, digest=None):
|
def burn_key(esp, efuses, args, digest=None):
|
||||||
if digest is None:
|
if digest is None:
|
||||||
datafile_list = args.keyfile[
|
datafile_list = args.keyfile[
|
||||||
@@ -206,6 +268,11 @@ def burn_key(esp, efuses, args, digest=None):
|
|||||||
0 : len([name for name in args.keypurpose if name is not None]) :
|
0 : len([name for name in args.keypurpose if name is not None]) :
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if "XTS_AES_256_KEY" in keypurpose_list:
|
||||||
|
# XTS_AES_256_KEY is not an actual HW key purpose, needs to be split into
|
||||||
|
# XTS_AES_256_KEY_1 and XTS_AES_256_KEY_2
|
||||||
|
split_512_bit_key(efuses, block_name_list, datafile_list, keypurpose_list)
|
||||||
|
|
||||||
util.check_duplicate_name_in_list(block_name_list)
|
util.check_duplicate_name_in_list(block_name_list)
|
||||||
if len(block_name_list) != len(datafile_list) or len(block_name_list) != len(
|
if len(block_name_list) != len(datafile_list) or len(block_name_list) != len(
|
||||||
keypurpose_list
|
keypurpose_list
|
||||||
|
@@ -962,8 +962,8 @@ class TestBurnKeyCommands(EfuseTestCase):
|
|||||||
self.check_data_block_in_log(output, f"{IMAGES_DIR}/192bit_2")
|
self.check_data_block_in_log(output, f"{IMAGES_DIR}/192bit_2")
|
||||||
|
|
||||||
@pytest.mark.skipif(
|
@pytest.mark.skipif(
|
||||||
arg_chip not in ["esp32s2", "esp32s3"],
|
arg_chip not in ["esp32s2", "esp32s3", "esp32p4"],
|
||||||
reason="512 bit keys are only supported on ESP32-S2 and S3",
|
reason="512 bit keys are only supported on ESP32-S2, S3, and P4",
|
||||||
)
|
)
|
||||||
def test_burn_key_512bit(self):
|
def test_burn_key_512bit(self):
|
||||||
self.espefuse_py(
|
self.espefuse_py(
|
||||||
@@ -980,8 +980,8 @@ class TestBurnKeyCommands(EfuseTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@pytest.mark.skipif(
|
@pytest.mark.skipif(
|
||||||
arg_chip not in ["esp32s2", "esp32s3"],
|
arg_chip not in ["esp32s2", "esp32s3", "esp32p4"],
|
||||||
reason="512 bit keys are only supported on ESP32-S2 and S3",
|
reason="512 bit keys are only supported on ESP32-S2, S3, and P4",
|
||||||
)
|
)
|
||||||
def test_burn_key_512bit_non_consecutive_blocks(self):
|
def test_burn_key_512bit_non_consecutive_blocks(self):
|
||||||
# Burn efuses seperately to test different kinds
|
# Burn efuses seperately to test different kinds
|
||||||
@@ -1023,8 +1023,8 @@ class TestBurnKeyCommands(EfuseTestCase):
|
|||||||
) in output
|
) in output
|
||||||
|
|
||||||
@pytest.mark.skipif(
|
@pytest.mark.skipif(
|
||||||
arg_chip not in ["esp32s2", "esp32s3"],
|
arg_chip not in ["esp32s2", "esp32s3", "esp32p4"],
|
||||||
reason="512 bit keys are only supported on ESP32-S2 and S3",
|
reason="512 bit keys are only supported on ESP32-S2, S3, and P4",
|
||||||
)
|
)
|
||||||
def test_burn_key_512bit_non_consecutive_blocks_loop_around(self):
|
def test_burn_key_512bit_non_consecutive_blocks_loop_around(self):
|
||||||
self.espefuse_py(
|
self.espefuse_py(
|
||||||
|
Reference in New Issue
Block a user