feat(espefuse): Support XTS_AES_256_KEY key_purpose for ESP32P4

This commit is contained in:
KonstantinKondrashov
2023-11-07 16:04:35 +08:00
committed by Radim Karniš
parent f607f19296
commit a91eee192e
3 changed files with 74 additions and 6 deletions

View File

@@ -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_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
("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
KEY_PURPOSES_NAME = [name[0] for name in KEY_PURPOSES]

View File

@@ -5,6 +5,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
import argparse
import io
import os # noqa: F401. It is used in IDF scripts
import traceback
@@ -191,6 +192,67 @@ def adc_info(esp, efuses, args):
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):
if digest is None:
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]) :
]
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)
if len(block_name_list) != len(datafile_list) or len(block_name_list) != len(
keypurpose_list

View File

@@ -962,8 +962,8 @@ class TestBurnKeyCommands(EfuseTestCase):
self.check_data_block_in_log(output, f"{IMAGES_DIR}/192bit_2")
@pytest.mark.skipif(
arg_chip not in ["esp32s2", "esp32s3"],
reason="512 bit keys are only supported on ESP32-S2 and S3",
arg_chip not in ["esp32s2", "esp32s3", "esp32p4"],
reason="512 bit keys are only supported on ESP32-S2, S3, and P4",
)
def test_burn_key_512bit(self):
self.espefuse_py(
@@ -980,8 +980,8 @@ class TestBurnKeyCommands(EfuseTestCase):
)
@pytest.mark.skipif(
arg_chip not in ["esp32s2", "esp32s3"],
reason="512 bit keys are only supported on ESP32-S2 and S3",
arg_chip not in ["esp32s2", "esp32s3", "esp32p4"],
reason="512 bit keys are only supported on ESP32-S2, S3, and P4",
)
def test_burn_key_512bit_non_consecutive_blocks(self):
# Burn efuses seperately to test different kinds
@@ -1023,8 +1023,8 @@ class TestBurnKeyCommands(EfuseTestCase):
) in output
@pytest.mark.skipif(
arg_chip not in ["esp32s2", "esp32s3"],
reason="512 bit keys are only supported on ESP32-S2 and S3",
arg_chip not in ["esp32s2", "esp32s3", "esp32p4"],
reason="512 bit keys are only supported on ESP32-S2, S3, and P4",
)
def test_burn_key_512bit_non_consecutive_blocks_loop_around(self):
self.espefuse_py(