1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-18 05:28:40 +00:00

feat(core/headertool): detect devel signatures for more objects (fixes #2616)

[no changelog]
This commit is contained in:
matejcik 2022-12-15 14:36:04 +01:00 committed by matejcik
parent 8921a124c3
commit 5a237d6a94
3 changed files with 42 additions and 17 deletions

View File

@ -53,12 +53,18 @@ def all_zero(data: bytes) -> bool:
return all(b == 0 for b in data)
def _check_signature_any(fw: "SignableImageProto", is_devel: bool) -> Status:
def _check_signature_any(fw: "SignableImageProto", is_devel: bool = False) -> Status:
if not fw.signature_present():
return Status.MISSING
try:
fw.verify()
return Status.VALID if not is_devel else Status.DEVEL
except Exception:
pass
try:
fw.verify(public_keys=fw.public_keys(dev_keys=True))
return Status.DEVEL
except Exception:
return Status.INVALID
@ -189,7 +195,7 @@ class SignableImageProto(Protocol):
def digest(self) -> bytes:
...
def verify(self) -> None:
def verify(self, public_keys: t.Sequence[bytes] = ...) -> None:
...
def build(self) -> bytes:
@ -201,7 +207,7 @@ class SignableImageProto(Protocol):
def signature_present(self) -> bool:
...
def public_keys(self) -> t.Sequence[bytes]:
def public_keys(self, dev_keys: bool = False) -> t.Sequence[bytes]:
...
@ -267,7 +273,7 @@ class VendorHeader(firmware.VendorHeader, CosiSignedMixin):
if not terse:
output.append(f"Fingerprint: {click.style(self.digest().hex(), bold=True)}")
sig_status = _check_signature_any(self, is_devel=False)
sig_status = _check_signature_any(self)
sym = SYM_OK if sig_status.is_ok() else SYM_FAIL
output.append(f"{sym} Signature is {sig_status.value}")
@ -276,8 +282,11 @@ class VendorHeader(firmware.VendorHeader, CosiSignedMixin):
def format(self, verbose: bool = False) -> str:
return self._format(terse=False)
def public_keys(self) -> t.Sequence[bytes]:
def public_keys(self, dev_keys: bool = False) -> t.Sequence[bytes]:
if not dev_keys:
return firmware.V2_BOOTLOADER_KEYS
else:
return firmware.V2_BOOTLOADER_DEV_KEYS
class VendorFirmware(firmware.VendorFirmware, CosiSignedMixin):
@ -305,7 +314,7 @@ class VendorFirmware(firmware.VendorFirmware, CosiSignedMixin):
)
)
def public_keys(self) -> t.Sequence[bytes]:
def public_keys(self, dev_keys: bool = False) -> t.Sequence[bytes]:
return self.vendor_header.pubkeys
@ -321,24 +330,29 @@ class BootloaderImage(firmware.FirmwareImage, CosiSignedMixin):
self.header,
self.code_hashes(),
self.digest(),
_check_signature_any(self, False),
_check_signature_any(self),
)
def verify(self) -> None:
def verify(self, public_keys: t.Sequence[bytes] = ()) -> None:
self.validate_code_hashes()
if not public_keys:
public_keys = self.public_keys()
try:
cosi.verify(
self.header.signature,
self.digest(),
firmware.V2_SIGS_REQUIRED,
firmware.V2_BOARDLOADER_KEYS,
public_keys,
self.header.sigmask,
)
except Exception:
raise firmware.InvalidSignatureError("Invalid bootloader signature")
def public_keys(self) -> t.Sequence[bytes]:
def public_keys(self, dev_keys: bool = False) -> t.Sequence[bytes]:
if not dev_keys:
return firmware.V2_BOARDLOADER_KEYS
else:
return firmware.V2_BOARDLOADER_DEV_KEYS
class LegacyFirmware(firmware.LegacyFirmware):
@ -371,7 +385,7 @@ class LegacyFirmware(firmware.LegacyFirmware):
return _format_container(contents) + embedded_content
def public_keys(self) -> t.Sequence[bytes]:
def public_keys(self, dev_keys: bool = False) -> t.Sequence[bytes]:
return firmware.V1_BOOTLOADER_KEYS
def slots(self) -> t.Iterable[int]:
@ -404,10 +418,10 @@ class LegacyV2Firmware(firmware.LegacyV2Firmware):
self.header,
self.code_hashes(),
self.digest(),
_check_signature_any(self, False),
_check_signature_any(self),
)
def public_keys(self) -> t.Sequence[bytes]:
def public_keys(self, dev_keys: bool = False) -> t.Sequence[bytes]:
return firmware.V1_BOOTLOADER_KEYS
def slots(self) -> t.Iterable[int]:

View File

@ -53,6 +53,15 @@ V2_BOOTLOADER_KEYS = [
)
]
V2_BOOTLOADER_DEV_KEYS = [
bytes.fromhex(key)
for key in (
"d759793bbc13a2819a827c76adb6fba8a49aee007f49f2d0992d99b825ad2c48",
"6355691c178a8ff91007a7478afb955ef7352c63e7b25703984cf78b26e21a56",
"ee93a4f66f8d16b819bb9beb9ffccdfcdc1412e87fee6a324c2a99a1e0e67148",
)
]
V2_SIGS_REQUIRED = 2
ONEV2_CHUNK_SIZE = 1024 * 64

View File

@ -125,14 +125,16 @@ class VendorHeader(Struct):
h.update(b"\x00" * 32)
return h.digest()
def verify(self, pubkeys: t.Sequence[bytes] = consts.V2_BOOTLOADER_KEYS) -> None:
def verify(
self, public_keys: t.Sequence[bytes] = consts.V2_BOOTLOADER_KEYS
) -> None:
digest = self.digest()
try:
cosi.verify(
self.signature,
digest,
consts.V2_SIGS_REQUIRED,
pubkeys,
public_keys,
self.sigmask,
)
except Exception: