1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-23 23:18:16 +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) 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(): if not fw.signature_present():
return Status.MISSING return Status.MISSING
try: try:
fw.verify() fw.verify()
return Status.VALID if not is_devel else Status.DEVEL 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: except Exception:
return Status.INVALID return Status.INVALID
@ -189,7 +195,7 @@ class SignableImageProto(Protocol):
def digest(self) -> bytes: def digest(self) -> bytes:
... ...
def verify(self) -> None: def verify(self, public_keys: t.Sequence[bytes] = ...) -> None:
... ...
def build(self) -> bytes: def build(self) -> bytes:
@ -201,7 +207,7 @@ class SignableImageProto(Protocol):
def signature_present(self) -> bool: 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: if not terse:
output.append(f"Fingerprint: {click.style(self.digest().hex(), bold=True)}") 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 sym = SYM_OK if sig_status.is_ok() else SYM_FAIL
output.append(f"{sym} Signature is {sig_status.value}") 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: def format(self, verbose: bool = False) -> str:
return self._format(terse=False) return self._format(terse=False)
def public_keys(self) -> t.Sequence[bytes]: def public_keys(self, dev_keys: bool = False) -> t.Sequence[bytes]:
return firmware.V2_BOOTLOADER_KEYS if not dev_keys:
return firmware.V2_BOOTLOADER_KEYS
else:
return firmware.V2_BOOTLOADER_DEV_KEYS
class VendorFirmware(firmware.VendorFirmware, CosiSignedMixin): 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 return self.vendor_header.pubkeys
@ -321,24 +330,29 @@ class BootloaderImage(firmware.FirmwareImage, CosiSignedMixin):
self.header, self.header,
self.code_hashes(), self.code_hashes(),
self.digest(), 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() self.validate_code_hashes()
if not public_keys:
public_keys = self.public_keys()
try: try:
cosi.verify( cosi.verify(
self.header.signature, self.header.signature,
self.digest(), self.digest(),
firmware.V2_SIGS_REQUIRED, firmware.V2_SIGS_REQUIRED,
firmware.V2_BOARDLOADER_KEYS, public_keys,
self.header.sigmask, self.header.sigmask,
) )
except Exception: except Exception:
raise firmware.InvalidSignatureError("Invalid bootloader signature") raise firmware.InvalidSignatureError("Invalid bootloader signature")
def public_keys(self) -> t.Sequence[bytes]: def public_keys(self, dev_keys: bool = False) -> t.Sequence[bytes]:
return firmware.V2_BOARDLOADER_KEYS if not dev_keys:
return firmware.V2_BOARDLOADER_KEYS
else:
return firmware.V2_BOARDLOADER_DEV_KEYS
class LegacyFirmware(firmware.LegacyFirmware): class LegacyFirmware(firmware.LegacyFirmware):
@ -371,7 +385,7 @@ class LegacyFirmware(firmware.LegacyFirmware):
return _format_container(contents) + embedded_content 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 return firmware.V1_BOOTLOADER_KEYS
def slots(self) -> t.Iterable[int]: def slots(self) -> t.Iterable[int]:
@ -404,10 +418,10 @@ class LegacyV2Firmware(firmware.LegacyV2Firmware):
self.header, self.header,
self.code_hashes(), self.code_hashes(),
self.digest(), 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 return firmware.V1_BOOTLOADER_KEYS
def slots(self) -> t.Iterable[int]: 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 V2_SIGS_REQUIRED = 2
ONEV2_CHUNK_SIZE = 1024 * 64 ONEV2_CHUNK_SIZE = 1024 * 64

View File

@ -125,14 +125,16 @@ class VendorHeader(Struct):
h.update(b"\x00" * 32) h.update(b"\x00" * 32)
return h.digest() 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() digest = self.digest()
try: try:
cosi.verify( cosi.verify(
self.signature, self.signature,
digest, digest,
consts.V2_SIGS_REQUIRED, consts.V2_SIGS_REQUIRED,
pubkeys, public_keys,
self.sigmask, self.sigmask,
) )
except Exception: except Exception: