diff --git a/py/bitbox02/bitbox02/bitbox02/bootloader.py b/py/bitbox02/bitbox02/bitbox02/bootloader.py index 64c83ae44..c0f47ee7e 100644 --- a/py/bitbox02/bitbox02/bitbox02/bootloader.py +++ b/py/bitbox02/bitbox02/bitbox02/bootloader.py @@ -94,6 +94,15 @@ def versions(self) -> typing.Tuple[int, int]: firmware_v, signing_pubkeys_v = struct.unpack(" str: + """ + Returns (Hardware variant). + """ + response = self._query(b"W") + if response[:1] == b"\x00": + return "ATECC" + return "Optiga" + def get_hashes( self, display_firmware_hash: bool = False, display_signing_keydata_hash: bool = False ) -> typing.Tuple[bytes, bytes]: diff --git a/py/send_message.py b/py/send_message.py index 617408d8d..dc3c5f5f7 100755 --- a/py/send_message.py +++ b/py/send_message.py @@ -1482,6 +1482,10 @@ def _get_versions(self) -> None: version = self._device.versions() print(f"Firmware version: {version[0]}, Pubkeys version: {version[1]}") + def _get_hardware(self) -> None: + hw = self._device.hardware() + print(f"Hardware variant: {hw}") + def _erase(self) -> None: self._device.erase() @@ -1506,6 +1510,7 @@ def _menu(self) -> None: choices = ( ("Boot", self._boot), ("Print versions", self._get_versions), + ("Print hardware variant", self._get_hardware), ("Erase firmware", self._erase), ("Show firmware hash at startup", self._show_fw_hash), ("Don't show firmware hash at startup", self._dont_show_fw_hash), diff --git a/src/bootloader/bootloader.c b/src/bootloader/bootloader.c index 091e32350..c36b7e93f 100644 --- a/src/bootloader/bootloader.c +++ b/src/bootloader/bootloader.c @@ -67,6 +67,8 @@ #define OP_SCREEN_ROTATE ((uint8_t)'f') /* 0x66 */ // OP_SET_SHOW_FIRMWARE_HASH - Enable or disable the flag to automatically show the firmware hash. #define OP_SET_SHOW_FIRMWARE_HASH ((uint8_t)'H') /* 0x4A */ +// OP_HARDWARE - Return the secure chip variant. +#define OP_HARDWARE ((uint8_t)'W') /* 0x57 */ // API return codes #define OP_STATUS_OK ((uint8_t)0) @@ -766,6 +768,16 @@ static size_t _api_screen_rotate(uint8_t* output) return _report_status(OP_STATUS_OK, output); } +static size_t _api_hardware(uint8_t* output) +{ + uint8_t type = 0; + if (memory_get_securechip_type() == MEMORY_SECURECHIP_TYPE_OPTIGA) { + type = 1; + } + memcpy(output + BOOT_OP_LEN, &type, 1); + return BOOT_OP_LEN + 1; +} + static size_t _api_command(const uint8_t* input, uint8_t* output, const size_t max_out_len) { memset(output, 0, max_out_len); @@ -809,6 +821,9 @@ static size_t _api_command(const uint8_t* input, uint8_t* output, const size_t m case OP_SCREEN_ROTATE: len = _api_screen_rotate(output); break; + case OP_HARDWARE: + len = _api_hardware(output); + break; default: len = _report_status(OP_STATUS_ERR_INVALID_CMD, output); _loading_ready = false;