mirror of
https://github.com/espressif/esptool.git
synced 2025-10-19 20:13:00 +08:00
feat(esptool): Print key_purpose name for get_security_info cmd
This commit is contained in:
@@ -1284,7 +1284,16 @@ def get_security_info(esp, args):
|
||||
print(title)
|
||||
print("=" * len(title))
|
||||
print("Flags: {:#010x} ({})".format(si["flags"], bin(si["flags"])))
|
||||
print("Key Purposes: {}".format(si["key_purposes"]))
|
||||
if esp.KEY_PURPOSES:
|
||||
print(f"Key Purposes: {si['key_purposes']}")
|
||||
desc = "\n ".join(
|
||||
[
|
||||
f"BLOCK_KEY{key_num} - {esp.KEY_PURPOSES.get(purpose, 'UNKNOWN')}"
|
||||
for key_num, purpose in enumerate(si["key_purposes"])
|
||||
if key_num <= esp.EFUSE_MAX_KEY
|
||||
]
|
||||
)
|
||||
print(f" {desc}")
|
||||
if si["chip_id"] is not None and si["api_version"] is not None:
|
||||
print("Chip ID: {}".format(si["chip_id"]))
|
||||
print("API Version: {}".format(si["api_version"]))
|
||||
|
@@ -5,7 +5,7 @@
|
||||
|
||||
import struct
|
||||
import time
|
||||
from typing import Optional
|
||||
from typing import Dict, Optional
|
||||
|
||||
from ..loader import ESPLoader
|
||||
from ..util import FatalError, NotSupportedError
|
||||
@@ -125,6 +125,8 @@ class ESP32ROM(ESPLoader):
|
||||
|
||||
UF2_FAMILY_ID = 0x1C5F21B0
|
||||
|
||||
KEY_PURPOSES: Dict[int, str] = {}
|
||||
|
||||
""" Try to read the BLOCK1 (encryption key) and check if it is valid """
|
||||
|
||||
def is_flash_encryption_key_valid(self):
|
||||
|
@@ -5,6 +5,7 @@
|
||||
|
||||
import struct
|
||||
import time
|
||||
from typing import Dict
|
||||
|
||||
from .esp32c3 import ESP32C3ROM
|
||||
from ..loader import ESPLoader
|
||||
@@ -64,6 +65,8 @@ class ESP32C2ROM(ESP32C3ROM):
|
||||
|
||||
UF2_FAMILY_ID = 0x2B88D29C
|
||||
|
||||
KEY_PURPOSES: Dict[int, str] = {}
|
||||
|
||||
def get_pkg_version(self):
|
||||
num_word = 1
|
||||
return (self.read_reg(self.EFUSE_BLOCK2_ADDR + (4 * num_word)) >> 22) & 0x07
|
||||
|
@@ -4,6 +4,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import struct
|
||||
from typing import Dict
|
||||
|
||||
from .esp32 import ESP32ROM
|
||||
from ..loader import ESPLoader
|
||||
@@ -99,6 +100,20 @@ class ESP32C3ROM(ESP32ROM):
|
||||
|
||||
UF2_FAMILY_ID = 0xD42BA06C
|
||||
|
||||
EFUSE_MAX_KEY = 5
|
||||
KEY_PURPOSES: Dict[int, str] = {
|
||||
0: "USER/EMPTY",
|
||||
1: "RESERVED",
|
||||
4: "XTS_AES_128_KEY",
|
||||
5: "HMAC_DOWN_ALL",
|
||||
6: "HMAC_DOWN_JTAG",
|
||||
7: "HMAC_DOWN_DIGITAL_SIGNATURE",
|
||||
8: "HMAC_UP",
|
||||
9: "SECURE_BOOT_DIGEST0",
|
||||
10: "SECURE_BOOT_DIGEST1",
|
||||
11: "SECURE_BOOT_DIGEST2",
|
||||
}
|
||||
|
||||
def get_pkg_version(self):
|
||||
num_word = 3
|
||||
return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 21) & 0x07
|
||||
@@ -179,8 +194,10 @@ class ESP32C3ROM(ESP32ROM):
|
||||
)
|
||||
|
||||
def get_key_block_purpose(self, key_block):
|
||||
if key_block < 0 or key_block > 5:
|
||||
raise FatalError("Valid key block numbers must be in range 0-5")
|
||||
if key_block < 0 or key_block > self.EFUSE_MAX_KEY:
|
||||
raise FatalError(
|
||||
f"Valid key block numbers must be in range 0-{self.EFUSE_MAX_KEY}"
|
||||
)
|
||||
|
||||
reg, shift = [
|
||||
(self.EFUSE_PURPOSE_KEY0_REG, self.EFUSE_PURPOSE_KEY0_SHIFT),
|
||||
@@ -194,7 +211,9 @@ class ESP32C3ROM(ESP32ROM):
|
||||
|
||||
def is_flash_encryption_key_valid(self):
|
||||
# Need to see an AES-128 key
|
||||
purposes = [self.get_key_block_purpose(b) for b in range(6)]
|
||||
purposes = [
|
||||
self.get_key_block_purpose(b) for b in range(self.EFUSE_MAX_KEY + 1)
|
||||
]
|
||||
|
||||
return any(p == self.PURPOSE_VAL_XTS_AES128_KEY for p in purposes)
|
||||
|
||||
|
@@ -4,6 +4,7 @@
|
||||
|
||||
import struct
|
||||
import time
|
||||
from typing import Dict
|
||||
|
||||
from .esp32c6 import ESP32C6ROM
|
||||
from ..loader import ESPLoader
|
||||
@@ -52,6 +53,23 @@ class ESP32C5ROM(ESP32C6ROM):
|
||||
|
||||
UF2_FAMILY_ID = 0xF71C0343
|
||||
|
||||
EFUSE_MAX_KEY = 5
|
||||
KEY_PURPOSES: Dict[int, str] = {
|
||||
0: "USER/EMPTY",
|
||||
1: "ECDSA_KEY",
|
||||
2: "XTS_AES_256_KEY_1",
|
||||
3: "XTS_AES_256_KEY_2",
|
||||
4: "XTS_AES_128_KEY",
|
||||
5: "HMAC_DOWN_ALL",
|
||||
6: "HMAC_DOWN_JTAG",
|
||||
7: "HMAC_DOWN_DIGITAL_SIGNATURE",
|
||||
8: "HMAC_UP",
|
||||
9: "SECURE_BOOT_DIGEST0",
|
||||
10: "SECURE_BOOT_DIGEST1",
|
||||
11: "SECURE_BOOT_DIGEST2",
|
||||
12: "KM_INIT_KEY",
|
||||
}
|
||||
|
||||
def get_chip_description(self):
|
||||
chip_name = {
|
||||
0: "ESP32-C5",
|
||||
|
@@ -4,6 +4,7 @@
|
||||
|
||||
import struct
|
||||
import time
|
||||
from typing import Dict
|
||||
|
||||
from .esp32c6 import ESP32C6ROM
|
||||
from ..loader import ESPLoader
|
||||
@@ -41,6 +42,23 @@ class ESP32C5BETA3ROM(ESP32C6ROM):
|
||||
[0x600FE000, 0x60100000, "MEM_INTERNAL2"],
|
||||
]
|
||||
|
||||
EFUSE_MAX_KEY = 5
|
||||
KEY_PURPOSES: Dict[int, str] = {
|
||||
0: "USER/EMPTY",
|
||||
1: "ECDSA_KEY",
|
||||
2: "XTS_AES_256_KEY_1",
|
||||
3: "XTS_AES_256_KEY_2",
|
||||
4: "XTS_AES_128_KEY",
|
||||
5: "HMAC_DOWN_ALL",
|
||||
6: "HMAC_DOWN_JTAG",
|
||||
7: "HMAC_DOWN_DIGITAL_SIGNATURE",
|
||||
8: "HMAC_UP",
|
||||
9: "SECURE_BOOT_DIGEST0",
|
||||
10: "SECURE_BOOT_DIGEST1",
|
||||
11: "SECURE_BOOT_DIGEST2",
|
||||
12: "KM_INIT_KEY",
|
||||
}
|
||||
|
||||
def get_chip_description(self):
|
||||
chip_name = {
|
||||
0: "ESP32-C5 beta3 (QFN40)",
|
||||
|
@@ -161,8 +161,10 @@ class ESP32C6ROM(ESP32C3ROM):
|
||||
)
|
||||
|
||||
def get_key_block_purpose(self, key_block):
|
||||
if key_block < 0 or key_block > 5:
|
||||
raise FatalError("Valid key block numbers must be in range 0-5")
|
||||
if key_block < 0 or key_block > self.EFUSE_MAX_KEY:
|
||||
raise FatalError(
|
||||
f"Valid key block numbers must be in range 0-{self.EFUSE_MAX_KEY}"
|
||||
)
|
||||
|
||||
reg, shift = [
|
||||
(self.EFUSE_PURPOSE_KEY0_REG, self.EFUSE_PURPOSE_KEY0_SHIFT),
|
||||
@@ -176,7 +178,9 @@ class ESP32C6ROM(ESP32C3ROM):
|
||||
|
||||
def is_flash_encryption_key_valid(self):
|
||||
# Need to see an AES-128 key
|
||||
purposes = [self.get_key_block_purpose(b) for b in range(6)]
|
||||
purposes = [
|
||||
self.get_key_block_purpose(b) for b in range(self.EFUSE_MAX_KEY + 1)
|
||||
]
|
||||
|
||||
return any(p == self.PURPOSE_VAL_XTS_AES128_KEY for p in purposes)
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import struct
|
||||
from typing import Dict
|
||||
|
||||
from .esp32c6 import ESP32C6ROM
|
||||
|
||||
@@ -60,6 +61,26 @@ class ESP32C61ROM(ESP32C6ROM):
|
||||
|
||||
UF2_FAMILY_ID = 0x77D850C4
|
||||
|
||||
EFUSE_MAX_KEY = 5
|
||||
KEY_PURPOSES: Dict[int, str] = {
|
||||
0: "USER/EMPTY",
|
||||
1: "ECDSA_KEY",
|
||||
2: "XTS_AES_256_KEY_1",
|
||||
3: "XTS_AES_256_KEY_2",
|
||||
4: "XTS_AES_128_KEY",
|
||||
5: "HMAC_DOWN_ALL",
|
||||
6: "HMAC_DOWN_JTAG",
|
||||
7: "HMAC_DOWN_DIGITAL_SIGNATURE",
|
||||
8: "HMAC_UP",
|
||||
9: "SECURE_BOOT_DIGEST0",
|
||||
10: "SECURE_BOOT_DIGEST1",
|
||||
11: "SECURE_BOOT_DIGEST2",
|
||||
12: "KM_INIT_KEY",
|
||||
13: "XTS_AES_256_KEY_1_PSRAM",
|
||||
14: "XTS_AES_256_KEY_2_PSRAM",
|
||||
15: "XTS_AES_128_KEY_PSRAM",
|
||||
}
|
||||
|
||||
def get_chip_description(self):
|
||||
chip_name = {
|
||||
0: "ESP32-C61",
|
||||
|
@@ -3,6 +3,8 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
from typing import Dict
|
||||
|
||||
from .esp32c6 import ESP32C6ROM
|
||||
from ..util import FatalError
|
||||
|
||||
@@ -32,6 +34,22 @@ class ESP32H2ROM(ESP32C6ROM):
|
||||
|
||||
UF2_FAMILY_ID = 0x332726F6
|
||||
|
||||
EFUSE_MAX_KEY = 5
|
||||
KEY_PURPOSES: Dict[int, str] = {
|
||||
0: "USER/EMPTY",
|
||||
1: "ECDSA_KEY",
|
||||
2: "XTS_AES_256_KEY_1",
|
||||
3: "XTS_AES_256_KEY_2",
|
||||
4: "XTS_AES_128_KEY",
|
||||
5: "HMAC_DOWN_ALL",
|
||||
6: "HMAC_DOWN_JTAG",
|
||||
7: "HMAC_DOWN_DIGITAL_SIGNATURE",
|
||||
8: "HMAC_UP",
|
||||
9: "SECURE_BOOT_DIGEST0",
|
||||
10: "SECURE_BOOT_DIGEST1",
|
||||
11: "SECURE_BOOT_DIGEST2",
|
||||
}
|
||||
|
||||
def get_pkg_version(self):
|
||||
num_word = 4
|
||||
return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 0) & 0x07
|
||||
|
@@ -4,6 +4,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import struct
|
||||
from typing import Dict
|
||||
|
||||
from .esp32c3 import ESP32C3ROM
|
||||
from ..util import FatalError, NotImplementedInROMError
|
||||
@@ -77,6 +78,21 @@ class ESP32H2BETA1ROM(ESP32C3ROM):
|
||||
"12m": 0x2,
|
||||
}
|
||||
|
||||
EFUSE_MAX_KEY = 5
|
||||
KEY_PURPOSES: Dict[int, str] = {
|
||||
0: "USER/EMPTY",
|
||||
1: "ECDSA_KEY",
|
||||
2: "RESERVED",
|
||||
4: "XTS_AES_128_KEY",
|
||||
5: "HMAC_DOWN_ALL",
|
||||
6: "HMAC_DOWN_JTAG",
|
||||
7: "HMAC_DOWN_DIGITAL_SIGNATURE",
|
||||
8: "HMAC_UP",
|
||||
9: "SECURE_BOOT_DIGEST0",
|
||||
10: "SECURE_BOOT_DIGEST1",
|
||||
11: "SECURE_BOOT_DIGEST2",
|
||||
}
|
||||
|
||||
def get_pkg_version(self):
|
||||
num_word = 4
|
||||
return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 0) & 0x07
|
||||
@@ -121,8 +137,10 @@ class ESP32H2BETA1ROM(ESP32C3ROM):
|
||||
return None # doesn't exist on ESP32-H2
|
||||
|
||||
def get_key_block_purpose(self, key_block):
|
||||
if key_block < 0 or key_block > 5:
|
||||
raise FatalError("Valid key block numbers must be in range 0-5")
|
||||
if key_block < 0 or key_block > self.EFUSE_MAX_KEY:
|
||||
raise FatalError(
|
||||
f"Valid key block numbers must be in range 0-{self.EFUSE_MAX_KEY}"
|
||||
)
|
||||
|
||||
reg, shift = [
|
||||
(self.EFUSE_PURPOSE_KEY0_REG, self.EFUSE_PURPOSE_KEY0_SHIFT),
|
||||
@@ -136,7 +154,9 @@ class ESP32H2BETA1ROM(ESP32C3ROM):
|
||||
|
||||
def is_flash_encryption_key_valid(self):
|
||||
# Need to see an AES-128 key
|
||||
purposes = [self.get_key_block_purpose(b) for b in range(6)]
|
||||
purposes = [
|
||||
self.get_key_block_purpose(b) for b in range(self.EFUSE_MAX_KEY + 1)
|
||||
]
|
||||
|
||||
return any(p == self.PURPOSE_VAL_XTS_AES128_KEY for p in purposes)
|
||||
|
||||
|
@@ -4,6 +4,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import struct
|
||||
from typing import Dict
|
||||
|
||||
from .esp32 import ESP32ROM
|
||||
from ..loader import ESPLoader
|
||||
@@ -85,6 +86,23 @@ class ESP32P4ROM(ESP32ROM):
|
||||
|
||||
UF2_FAMILY_ID = 0x3D308E94
|
||||
|
||||
EFUSE_MAX_KEY = 5
|
||||
KEY_PURPOSES: Dict[int, str] = {
|
||||
0: "USER/EMPTY",
|
||||
1: "ECDSA_KEY",
|
||||
2: "XTS_AES_256_KEY_1",
|
||||
3: "XTS_AES_256_KEY_2",
|
||||
4: "XTS_AES_128_KEY",
|
||||
5: "HMAC_DOWN_ALL",
|
||||
6: "HMAC_DOWN_JTAG",
|
||||
7: "HMAC_DOWN_DIGITAL_SIGNATURE",
|
||||
8: "HMAC_UP",
|
||||
9: "SECURE_BOOT_DIGEST0",
|
||||
10: "SECURE_BOOT_DIGEST1",
|
||||
11: "SECURE_BOOT_DIGEST2",
|
||||
12: "KM_INIT_KEY",
|
||||
}
|
||||
|
||||
def get_pkg_version(self):
|
||||
num_word = 2
|
||||
return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 27) & 0x07
|
||||
@@ -139,8 +157,10 @@ class ESP32P4ROM(ESP32ROM):
|
||||
)
|
||||
|
||||
def get_key_block_purpose(self, key_block):
|
||||
if key_block < 0 or key_block > 5:
|
||||
raise FatalError("Valid key block numbers must be in range 0-5")
|
||||
if key_block < 0 or key_block > self.EFUSE_MAX_KEY:
|
||||
raise FatalError(
|
||||
f"Valid key block numbers must be in range 0-{self.EFUSE_MAX_KEY}"
|
||||
)
|
||||
|
||||
reg, shift = [
|
||||
(self.EFUSE_PURPOSE_KEY0_REG, self.EFUSE_PURPOSE_KEY0_SHIFT),
|
||||
@@ -154,7 +174,9 @@ class ESP32P4ROM(ESP32ROM):
|
||||
|
||||
def is_flash_encryption_key_valid(self):
|
||||
# Need to see either an AES-128 key or two AES-256 keys
|
||||
purposes = [self.get_key_block_purpose(b) for b in range(6)]
|
||||
purposes = [
|
||||
self.get_key_block_purpose(b) for b in range(self.EFUSE_MAX_KEY + 1)
|
||||
]
|
||||
|
||||
if any(p == self.PURPOSE_VAL_XTS_AES128_KEY for p in purposes):
|
||||
return True
|
||||
|
@@ -5,6 +5,7 @@
|
||||
|
||||
import os
|
||||
import struct
|
||||
from typing import Dict
|
||||
|
||||
from .esp32 import ESP32ROM
|
||||
from ..loader import ESPLoader
|
||||
@@ -107,6 +108,22 @@ class ESP32S2ROM(ESP32ROM):
|
||||
|
||||
UF2_FAMILY_ID = 0xBFDD4EEE
|
||||
|
||||
EFUSE_MAX_KEY = 5
|
||||
KEY_PURPOSES: Dict[int, str] = {
|
||||
0: "USER/EMPTY",
|
||||
1: "RESERVED",
|
||||
2: "XTS_AES_256_KEY_1",
|
||||
3: "XTS_AES_256_KEY_2",
|
||||
4: "XTS_AES_128_KEY",
|
||||
5: "HMAC_DOWN_ALL",
|
||||
6: "HMAC_DOWN_JTAG",
|
||||
7: "HMAC_DOWN_DIGITAL_SIGNATURE",
|
||||
8: "HMAC_UP",
|
||||
9: "SECURE_BOOT_DIGEST0",
|
||||
10: "SECURE_BOOT_DIGEST1",
|
||||
11: "SECURE_BOOT_DIGEST2",
|
||||
}
|
||||
|
||||
def get_pkg_version(self):
|
||||
num_word = 4
|
||||
return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 0) & 0x0F
|
||||
@@ -224,8 +241,10 @@ class ESP32S2ROM(ESP32ROM):
|
||||
)
|
||||
|
||||
def get_key_block_purpose(self, key_block):
|
||||
if key_block < 0 or key_block > 5:
|
||||
raise FatalError("Valid key block numbers must be in range 0-5")
|
||||
if key_block < 0 or key_block > self.EFUSE_MAX_KEY:
|
||||
raise FatalError(
|
||||
f"Valid key block numbers must be in range 0-{self.EFUSE_MAX_KEY}"
|
||||
)
|
||||
|
||||
reg, shift = [
|
||||
(self.EFUSE_PURPOSE_KEY0_REG, self.EFUSE_PURPOSE_KEY0_SHIFT),
|
||||
@@ -239,7 +258,9 @@ class ESP32S2ROM(ESP32ROM):
|
||||
|
||||
def is_flash_encryption_key_valid(self):
|
||||
# Need to see either an AES-128 key or two AES-256 keys
|
||||
purposes = [self.get_key_block_purpose(b) for b in range(6)]
|
||||
purposes = [
|
||||
self.get_key_block_purpose(b) for b in range(self.EFUSE_MAX_KEY + 1)
|
||||
]
|
||||
|
||||
if any(p == self.PURPOSE_VAL_XTS_AES128_KEY for p in purposes):
|
||||
return True
|
||||
|
@@ -5,6 +5,7 @@
|
||||
|
||||
import os
|
||||
import struct
|
||||
from typing import Dict
|
||||
|
||||
from .esp32 import ESP32ROM
|
||||
from ..loader import ESPLoader
|
||||
@@ -123,6 +124,22 @@ class ESP32S3ROM(ESP32ROM):
|
||||
|
||||
UF2_FAMILY_ID = 0xC47E5767
|
||||
|
||||
EFUSE_MAX_KEY = 5
|
||||
KEY_PURPOSES: Dict[int, str] = {
|
||||
0: "USER/EMPTY",
|
||||
1: "RESERVED",
|
||||
2: "XTS_AES_256_KEY_1",
|
||||
3: "XTS_AES_256_KEY_2",
|
||||
4: "XTS_AES_128_KEY",
|
||||
5: "HMAC_DOWN_ALL",
|
||||
6: "HMAC_DOWN_JTAG",
|
||||
7: "HMAC_DOWN_DIGITAL_SIGNATURE",
|
||||
8: "HMAC_UP",
|
||||
9: "SECURE_BOOT_DIGEST0",
|
||||
10: "SECURE_BOOT_DIGEST1",
|
||||
11: "SECURE_BOOT_DIGEST2",
|
||||
}
|
||||
|
||||
def get_pkg_version(self):
|
||||
num_word = 3
|
||||
return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 21) & 0x07
|
||||
@@ -227,8 +244,10 @@ class ESP32S3ROM(ESP32ROM):
|
||||
return None # doesn't exist on ESP32-S3
|
||||
|
||||
def get_key_block_purpose(self, key_block):
|
||||
if key_block < 0 or key_block > 5:
|
||||
raise FatalError("Valid key block numbers must be in range 0-5")
|
||||
if key_block < 0 or key_block > self.EFUSE_MAX_KEY:
|
||||
raise FatalError(
|
||||
f"Valid key block numbers must be in range 0-{self.EFUSE_MAX_KEY}"
|
||||
)
|
||||
|
||||
reg, shift = [
|
||||
(self.EFUSE_PURPOSE_KEY0_REG, self.EFUSE_PURPOSE_KEY0_SHIFT),
|
||||
@@ -242,7 +261,9 @@ class ESP32S3ROM(ESP32ROM):
|
||||
|
||||
def is_flash_encryption_key_valid(self):
|
||||
# Need to see either an AES-128 key or two AES-256 keys
|
||||
purposes = [self.get_key_block_purpose(b) for b in range(6)]
|
||||
purposes = [
|
||||
self.get_key_block_purpose(b) for b in range(self.EFUSE_MAX_KEY + 1)
|
||||
]
|
||||
|
||||
if any(p == self.PURPOSE_VAL_XTS_AES128_KEY for p in purposes):
|
||||
return True
|
||||
|
@@ -670,7 +670,8 @@ class TestSecurityInfo(EsptoolTestCase):
|
||||
res = self.run_esptool("get_security_info")
|
||||
assert "Flags" in res
|
||||
assert "Crypt Count" in res
|
||||
assert "Key Purposes" in res
|
||||
if arg_chip != "esp32c2":
|
||||
assert "Key Purposes" in res
|
||||
if arg_chip != "esp32s2":
|
||||
try:
|
||||
esp = esptool.get_default_connected_device(
|
||||
|
Reference in New Issue
Block a user