From ed3af0f60b04ea7d02f995abad9bfb0c8f9b1e1a Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Mon, 3 Apr 2023 21:41:43 +0800 Subject: [PATCH] espefuse: Prevent burning XTS_AES keys into BLOCK9 (BLOCK_KEY5) eFuse module has a hardware bug. It is related to ESP32-C3, S3, H2 chips: - BLOCK9 (BLOCK_KEY5) can not be used by XTS_AES keys. S2 does not have such a hardware bug. --- espressif/efuse/esp32c3/fields.py | 8 ++++++++ espressif/efuse/esp32h2beta1/fields.py | 8 ++++++++ espressif/efuse/esp32s3/fields.py | 8 ++++++++ espressif/efuse/esp32s3beta2/fields.py | 8 ++++++++ test/test_espefuse_host.py | 28 ++++++++++++++++++++++++-- 5 files changed, 58 insertions(+), 2 deletions(-) diff --git a/espressif/efuse/esp32c3/fields.py b/espressif/efuse/esp32c3/fields.py index d05188276..39f128a95 100644 --- a/espressif/efuse/esp32c3/fields.py +++ b/espressif/efuse/esp32c3/fields.py @@ -337,6 +337,14 @@ def get(self, from_read=True): return p[0] return "FORBIDDEN_STATE" + def get_name(self, raw_val): + for key in self.KEY_PURPOSES: + if key[1] == raw_val: + return key[0] + def save(self, new_value): raw_val = int(self.check_format(str(new_value))) + str_new_value = self.get_name(raw_val) + if self.name == "KEY_PURPOSE_5" and str_new_value.startswith("XTS_AES"): + raise esptool.FatalError("%s can not have %s key due to a hardware bug (please see TRM for more details)" % (self.name, str_new_value)) return super(EfuseKeyPurposeField, self).save(raw_val) diff --git a/espressif/efuse/esp32h2beta1/fields.py b/espressif/efuse/esp32h2beta1/fields.py index a418d2c59..685df7f54 100644 --- a/espressif/efuse/esp32h2beta1/fields.py +++ b/espressif/efuse/esp32h2beta1/fields.py @@ -337,6 +337,14 @@ def get(self, from_read=True): return p[0] return "FORBIDDEN_STATE" + def get_name(self, raw_val): + for key in self.KEY_PURPOSES: + if key[1] == raw_val: + return key[0] + def save(self, new_value): raw_val = int(self.check_format(str(new_value))) + str_new_value = self.get_name(raw_val) + if self.name == "KEY_PURPOSE_5" and str_new_value.startswith("XTS_AES"): + raise esptool.FatalError("%s can not have %s key due to a hardware bug (please see TRM for more details)" % (self.name, str_new_value)) return super(EfuseKeyPurposeField, self).save(raw_val) diff --git a/espressif/efuse/esp32s3/fields.py b/espressif/efuse/esp32s3/fields.py index bea6c454c..0da7d266e 100644 --- a/espressif/efuse/esp32s3/fields.py +++ b/espressif/efuse/esp32s3/fields.py @@ -344,6 +344,14 @@ def get(self, from_read=True): return p[0] return "FORBIDDEN_STATE" + def get_name(self, raw_val): + for key in self.KEY_PURPOSES: + if key[1] == raw_val: + return key[0] + def save(self, new_value): raw_val = int(self.check_format(str(new_value))) + str_new_value = self.get_name(raw_val) + if self.name == "KEY_PURPOSE_5" and str_new_value.startswith("XTS_AES"): + raise esptool.FatalError("%s can not have %s key due to a hardware bug (please see TRM for more details)" % (self.name, str_new_value)) return super(EfuseKeyPurposeField, self).save(raw_val) diff --git a/espressif/efuse/esp32s3beta2/fields.py b/espressif/efuse/esp32s3beta2/fields.py index 9dec47339..4af70d08c 100644 --- a/espressif/efuse/esp32s3beta2/fields.py +++ b/espressif/efuse/esp32s3beta2/fields.py @@ -344,6 +344,14 @@ def get(self, from_read=True): return p[0] return "FORBIDDEN_STATE" + def get_name(self, raw_val): + for key in self.KEY_PURPOSES: + if key[1] == raw_val: + return key[0] + def save(self, new_value): raw_val = int(self.check_format(str(new_value))) + str_new_value = self.get_name(raw_val) + if self.name == "KEY_PURPOSE_5" and str_new_value.startswith("XTS_AES"): + raise esptool.FatalError("%s can not have %s key due to a hardware bug (please see TRM for more details)" % (self.name, str_new_value)) return super(EfuseKeyPurposeField, self).save(raw_val) diff --git a/test/test_espefuse_host.py b/test/test_espefuse_host.py index 248713bf0..18f5394c8 100755 --- a/test/test_espefuse_host.py +++ b/test/test_espefuse_host.py @@ -588,7 +588,7 @@ def test_burn_key_512bit_non_consecutive_blocks(self): self.espefuse_py('burn_key \ BLOCK_KEY3 images/efuse/256bit USER --no-read-protect --no-write-protect') self.espefuse_py('burn_key \ - BLOCK_KEY4 images/efuse/256bit SECURE_BOOT_DIGEST0') + BLOCK_KEY5 images/efuse/256bit SECURE_BOOT_DIGEST0') self.espefuse_py('burn_key \ BLOCK_KEY1 images/efuse/256bit_1_256bit_2_combined XTS_AES_256_KEY --no-read-protect --no-write-protect') @@ -599,7 +599,7 @@ def test_burn_key_512bit_non_consecutive_blocks(self): self.check_data_block_in_log(output, "images/efuse/256bit_2", reverse_order=True) self.assertIn('[5 ] read_regs: bcbd11bf b8b9babb b4b5b6b7 b0b1b2b3 acadaeaf a8a9aaab a4a5a6a7 11a1a2a3', output) - self.assertIn('[9 ] read_regs: bcbd22bf b8b9babb b4b5b6b7 b0b1b2b3 acadaeaf a8a9aaab a4a5a6a7 22a1a2a3', output) + self.assertIn('[8 ] read_regs: bcbd22bf b8b9babb b4b5b6b7 b0b1b2b3 acadaeaf a8a9aaab a4a5a6a7 22a1a2a3', output) @unittest.skipUnless(chip_target in ["esp32s2", "esp32s3"], "512 bit keys are only supported on ESP32-S2 and S3") def test_burn_key_512bit_non_consecutive_blocks_loop_around(self): @@ -1067,6 +1067,30 @@ def test_not_burn_cmds(self): check_error') +@unittest.skipIf( + chip_target not in ["esp32c3", "esp32h2beta1", "esp32s3", "esp32s3beta2"], + reason="These chips have a hardware bug that limits the use of the KEY5", +) +class TestKeyPurposes(EfuseTestCase): + def test_burn_xts_aes_key_purpose(self): + self.espefuse_py( + "burn_efuse KEY_PURPOSE_5 XTS_AES_128_KEY", + check_msg="A fatal error occurred: " + "KEY_PURPOSE_5 can not have XTS_AES_128_KEY " + "key due to a hardware bug (please see TRM for more details)", + ret_code=2, + ) + + def test_burn_xts_aes_key(self): + self.espefuse_py( + "burn_key BLOCK_KEY5 images/efuse/256bit XTS_AES_128_KEY", + check_msg="A fatal error occurred: " + "KEY_PURPOSE_5 can not have XTS_AES_128_KEY " + "key due to a hardware bug (please see TRM for more details)", + ret_code=2, + ) + + if __name__ == '__main__': if len(sys.argv) > 1: chip_target = sys.argv[1]