feat(core): expose flash area API to Python

and add debuglink messages for reading/writing flash

this also refactors get_firmware_hash to use the flash area API instead of the original hardcoded function
pull/3565/head
matejcik 3 months ago
parent e000b526cc
commit 5bd75adfdf

@ -132,47 +132,118 @@ message DebugLinkLog {
}
/**
* Request: Read memory from device
* Location in the flash memory.enum
* @embed
*/
message FlashMemoryLocation {
/// Selector of the area
required FlashArea area = 1;
/// Offset from area start
required uint32 offset = 2;
enum FlashArea {
Boardloader = 0;
Bootloader = 1;
StorageA = 2;
StorageB = 3;
Firmware = 4;
Translations = 5;
}
}
/**
* Request: Read memory from device (legacy)
* @start
* @next DebugLinkMemory
*/
message DebugLinkMemoryRead {
option deprecated = true;
optional uint32 address = 1;
optional uint32 length = 2;
}
/**
* Request: Read flash contents from device (trezor-core)
* @start
* @next DebugLinkMemory
*/
message DebugLinkFlashRead {
/// Flash memory location
required FlashMemoryLocation location = 1;
/// Length of the memory to read. If unspecified, the whole area is read.
optional uint32 length = 2;
/// If true, only the hash of the memory contents will be returned.
/// Useful if the memory is large and the hash is enough to verify the contents.
optional bool hashed = 3 [default = false];
}
/**
* Response: Device sends memory back
* @end
*/
message DebugLinkMemory {
optional bytes memory = 1;
optional bytes hash = 2;
}
/**
* Request: Write memory to device.
* Request: Write memory to device (legacy).
* WARNING: Writing to the wrong location can irreparably break the device.
* @start
* @next Success
* @next Failure
*/
message DebugLinkMemoryWrite {
option deprecated = true;
optional uint32 address = 1;
optional bytes memory = 2;
optional bool flash = 3;
}
/**
* Request: Erase block of flash on device
* Request: Write to device flash memory (trezor-core).
* WARNING: Writing to the wrong location can irreparably break the device.
* @start
* @next Success
* @next Failure
*/
message DebugLinkFlashWrite {
/// Flash memory location
required FlashMemoryLocation location = 1;
/// Contents of the memory to flash.
required bytes memory = 2;
}
/**
* Request: Erase block of flash on device (legacy)
* WARNING: Writing to the wrong location can irreparably break the device.
* @start
* @next Success
* @next Failure
*/
message DebugLinkFlashErase {
message DebugLinkFlashEraseLegacy {
option deprecated = true;
optional uint32 sector = 1;
}
/**
* Request: Erase block of flash on device (trezor-core)
* WARNING: Writing to the wrong location can irreparably break the device.
* @start
* @next Success
* @next Failure
*/
message DebugLinkFlashErase {
/// Flash memory location
required FlashMemoryLocation location = 1;
/// Erase whole area or just the sector at the given offset.
/// If the offset is not a start of a sector, error is returned.
optional bool whole_area = 2 [default = false];
}
/**
* Request: Erase the SD card

@ -179,16 +179,19 @@ enum MessageType {
MessageType_DebugLinkState = 102 [(bitcoin_only) = true, (wire_debug_out) = true];
MessageType_DebugLinkStop = 103 [(bitcoin_only) = true, (wire_debug_in) = true];
MessageType_DebugLinkLog = 104 [(bitcoin_only) = true, (wire_debug_out) = true];
MessageType_DebugLinkMemoryRead = 110 [(bitcoin_only) = true, (wire_debug_in) = true];
MessageType_DebugLinkMemoryRead = 110 [(bitcoin_only) = true, (wire_debug_in) = true, deprecated = true];
MessageType_DebugLinkMemory = 111 [(bitcoin_only) = true, (wire_debug_out) = true];
MessageType_DebugLinkMemoryWrite = 112 [(bitcoin_only) = true, (wire_debug_in) = true];
MessageType_DebugLinkFlashErase = 113 [(bitcoin_only) = true, (wire_debug_in) = true];
MessageType_DebugLinkMemoryWrite = 112 [(bitcoin_only) = true, (wire_debug_in) = true, deprecated = true];
MessageType_DebugLinkFlashEraseLegacy = 113 [(bitcoin_only) = true, (wire_debug_in) = true, deprecated = true];
MessageType_DebugLinkLayout = 9001 [(bitcoin_only) = true, (wire_debug_out) = true];
MessageType_DebugLinkReseedRandom = 9002 [(bitcoin_only) = true, (wire_debug_in) = true];
MessageType_DebugLinkRecordScreen = 9003 [(bitcoin_only) = true, (wire_debug_in) = true];
MessageType_DebugLinkEraseSdCard = 9005 [(bitcoin_only) = true, (wire_debug_in) = true];
MessageType_DebugLinkWatchLayout = 9006 [(bitcoin_only) = true, (wire_debug_in) = true];
MessageType_DebugLinkResetDebugEvents = 9007 [(bitcoin_only) = true, (wire_debug_in) = true];
MessageType_DebugLinkFlashRead = 9008 [(bitcoin_only) = true, (wire_debug_in) = true];
MessageType_DebugLinkFlashWrite = 9009 [(bitcoin_only) = true, (wire_debug_in) = true];
MessageType_DebugLinkFlashErase = 9010 [(bitcoin_only) = true, (wire_debug_in) = true];
// Ethereum
MessageType_EthereumGetPublicKey = 450 [(wire_in) = true];

@ -17,7 +17,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "blake2s.h"
#include "common.h"
#include "flash_otp.h"
#include "model.h"
#include "embed/extmod/trezorobj.h"
@ -118,3 +123,303 @@ STATIC const mp_obj_type_t mod_trezorio_FlashOTP_type = {
.make_new = mod_trezorio_FlashOTP_make_new,
.locals_dict = (void *)&mod_trezorio_FlashOTP_locals_dict,
};
/// class FlashArea:
/// """
/// Area of the flash memory
/// """
typedef struct _mp_obj_FlashArea_t {
mp_obj_base_t base;
const flash_area_t *area;
} mp_obj_FlashArea_t;
#define FLASH_READ_CHUNK_SIZE 1024
#define CHUNKS_PER_PROGRESS_STEP ((1024 / FLASH_READ_CHUNK_SIZE) * 16)
static void ui_progress(mp_obj_t ui_wait_callback, uint32_t current) {
if (mp_obj_is_callable(ui_wait_callback)) {
mp_call_function_1_protected(ui_wait_callback, mp_obj_new_int(current));
}
}
/// def size(self) -> int:
/// """
/// Returns size of the flash area
/// """
STATIC mp_obj_t mod_trezorio_FlashArea_size(mp_obj_t obj_self) {
mp_obj_FlashArea_t *self = (mp_obj_FlashArea_t *)MP_OBJ_TO_PTR(obj_self);
return MP_OBJ_NEW_SMALL_INT(flash_area_get_size(self->area));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_FlashArea_size_obj,
mod_trezorio_FlashArea_size);
/// def hash(
/// self,
/// offset: int,
/// length: int,
/// challenge: bytes | None = None,
/// callback: Callable[[int], None] | None = None,
/// ) -> bytes:
/// """
/// Computes a Blake2s hash of a segment of the flash area.
/// Offset and length must be aligned to 1024 bytes.
/// An optional challenge can be used as the Blake2s key.
/// The progress callback will be invoked every 16 kB with the number of
/// bytes processed so far.
/// """
STATIC mp_obj_t mod_trezorio_FlashArea_hash(size_t n_args,
const mp_obj_t *args) {
mp_obj_FlashArea_t *self = (mp_obj_FlashArea_t *)MP_OBJ_TO_PTR(args[0]);
uint32_t offset = trezor_obj_get_uint(args[1]);
uint32_t length = trezor_obj_get_uint(args[2]);
if (offset % FLASH_READ_CHUNK_SIZE != 0 ||
length % FLASH_READ_CHUNK_SIZE != 0) {
mp_raise_ValueError("Offset and length must be aligned to 1024 bytes.");
}
mp_buffer_info_t challenge = {0};
if (n_args > 3 && args[3] != mp_const_none) {
mp_get_buffer_raise(args[3], &challenge, MP_BUFFER_READ);
}
mp_obj_t ui_wait_callback = mp_const_none;
if (n_args > 4) {
ui_wait_callback = args[4];
}
BLAKE2S_CTX ctx;
if (challenge.len != 0) {
if (blake2s_InitKey(&ctx, BLAKE2S_DIGEST_LENGTH, challenge.buf,
challenge.len) != 0) {
mp_raise_msg(&mp_type_ValueError, "Invalid challenge.");
}
} else {
blake2s_Init(&ctx, BLAKE2S_DIGEST_LENGTH);
}
uint32_t area_size = flash_area_get_size(self->area);
if (offset > area_size || area_size - offset < length) {
mp_raise_ValueError("Read too long.");
}
const uint32_t chunks = length / FLASH_READ_CHUNK_SIZE;
ui_progress(ui_wait_callback, 0);
for (int i = 0; i < chunks; i++) {
const uint32_t current_offset = offset + i * FLASH_READ_CHUNK_SIZE;
const void *data = flash_area_get_address(self->area, current_offset,
FLASH_READ_CHUNK_SIZE);
if (data == NULL) {
mp_raise_msg(&mp_type_RuntimeError, "Failed to read flash.");
}
blake2s_Update(&ctx, data, FLASH_READ_CHUNK_SIZE);
if (i % CHUNKS_PER_PROGRESS_STEP == 0) {
ui_progress(ui_wait_callback, i * FLASH_READ_CHUNK_SIZE);
}
}
ui_progress(ui_wait_callback, length);
vstr_t vstr = {0};
vstr_init_len(&vstr, BLAKE2S_DIGEST_LENGTH);
if (blake2s_Final(&ctx, vstr.buf, vstr.len) != 0) {
vstr_clear(&vstr);
mp_raise_msg(&mp_type_RuntimeError, "Failed to finalize hash.");
}
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorio_FlashArea_hash_obj, 3,
5, mod_trezorio_FlashArea_hash);
/// if __debug__:
/// def read(self, offset: int, data: bytearray) -> None:
/// """
/// Reads data from flash area. Will read exact length of data
/// bytearray. Offset and length of data must be aligned to 1024 bytes.
/// """
#if DEBUG
STATIC mp_obj_t mod_trezorio_FlashArea_read(mp_obj_t obj_self,
mp_obj_t obj_offset,
mp_obj_t obj_data) {
mp_obj_FlashArea_t *self = (mp_obj_FlashArea_t *)MP_OBJ_TO_PTR(obj_self);
uint32_t offset = trezor_obj_get_uint(obj_offset);
mp_buffer_info_t data = {0};
mp_get_buffer_raise(obj_data, &data, MP_BUFFER_WRITE);
if (offset % FLASH_READ_CHUNK_SIZE != 0 ||
data.len % FLASH_READ_CHUNK_SIZE != 0) {
mp_raise_ValueError("Offset and length must be aligned to 1024 bytes.");
}
uint32_t area_size = flash_area_get_size(self->area);
if (offset > area_size || area_size - offset < data.len) {
mp_raise_ValueError("Read too long.");
}
uint32_t chunks = data.len / FLASH_READ_CHUNK_SIZE;
for (int i = 0; i < chunks; i++) {
const uint32_t current_offset = offset + i * FLASH_READ_CHUNK_SIZE;
const void *data = flash_area_get_address(&FIRMWARE_AREA, current_offset,
FLASH_READ_CHUNK_SIZE);
if (data == NULL) {
mp_raise_msg(&mp_type_RuntimeError, "Failed to read flash.");
}
memcpy(data.buf + i * FLASH_READ_CHUNK_SIZE, data, FLASH_READ_CHUNK_SIZE);
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorio_FlashArea_read_obj,
mod_trezorio_FlashArea_read);
/// if __debug__:
/// def write(self, offset: int, data: bytes) -> None:
/// """
/// Writes data to flash area.
/// Offset and written data size must be a multiple of FLASH_BLOCK_SIZE,
/// that is, 4 bytes on F4 or 16 bytes on U5.
/// """
STATIC mp_obj_t mod_trezorio_FlashArea_write(mp_obj_t obj_self,
mp_obj_t obj_offset,
mp_obj_t obj_data) {
mp_obj_FlashArea_t *self = (mp_obj_FlashArea_t *)MP_OBJ_TO_PTR(obj_self);
uint32_t offset = trezor_obj_get_uint(obj_offset);
mp_buffer_info_t data = {0};
mp_get_buffer_raise(obj_data, &data, MP_BUFFER_READ);
if (data.len % FLASH_BLOCK_SIZE != 0) {
mp_raise_ValueError("Write size must be a multiple of write unit.");
}
uint32_t area_size = flash_area_get_size(self->area);
if (offset > area_size || area_size - offset < data.len) {
mp_raise_ValueError("Write too long.");
}
uint32_t blocks = data.len / FLASH_BLOCK_SIZE;
const flash_block_t *data_as_blocks = (const flash_block_t *)data.buf;
ensure(flash_unlock_write(), NULL);
for (int i = 0; i < blocks; i++) {
if (sectrue != flash_area_write_block(self->area,
offset + i * FLASH_BLOCK_SIZE,
data_as_blocks[i])) {
ensure(flash_lock_write(), NULL);
mp_raise_ValueError("Write failed.");
}
}
ensure(flash_lock_write(), NULL);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorio_FlashArea_write_obj,
mod_trezorio_FlashArea_write);
/// if __debug__:
/// def erase_sector(self, offset: int) -> None:
/// """
/// Erases a flash area sector starting at specified offset.
/// """
STATIC mp_obj_t mod_trezorio_FlashArea_erase_sector(mp_obj_t obj_self,
mp_obj_t obj_offset) {
mp_obj_FlashArea_t *self = (mp_obj_FlashArea_t *)MP_OBJ_TO_PTR(obj_self);
uint32_t offset = trezor_obj_get_uint(obj_offset);
uint32_t bytes_erased = 0;
if (sectrue != flash_area_erase_partial(self->area, offset, &bytes_erased)) {
mp_raise_ValueError("Erase failed.");
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_FlashArea_erase_sector_obj,
mod_trezorio_FlashArea_erase_sector);
/// if __debug__:
/// def erase(self) -> None:
/// """
/// Erases the whole flash area.
/// """
STATIC mp_obj_t mod_trezorio_FlashArea_erase(mp_obj_t obj_self) {
mp_obj_FlashArea_t *self = (mp_obj_FlashArea_t *)MP_OBJ_TO_PTR(obj_self);
if (sectrue != flash_area_erase(self->area, NULL)) {
mp_raise_ValueError("Erase failed.");
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_FlashArea_erase_obj,
mod_trezorio_FlashArea_erase);
#endif // DEBUG
STATIC const mp_rom_map_elem_t mod_trezorio_FlashArea_locals_dict_table[] = {
{MP_ROM_QSTR(MP_QSTR_size), MP_ROM_PTR(&mod_trezorio_FlashArea_size_obj)},
{MP_ROM_QSTR(MP_QSTR_hash), MP_ROM_PTR(&mod_trezorio_FlashArea_hash_obj)},
#if DEBUG
{MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mod_trezorio_FlashArea_read_obj)},
{MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mod_trezorio_FlashArea_write_obj)},
{MP_ROM_QSTR(MP_QSTR_erase_sector),
MP_ROM_PTR(&mod_trezorio_FlashArea_erase_sector_obj)},
{MP_ROM_QSTR(MP_QSTR_erase), MP_ROM_PTR(&mod_trezorio_FlashArea_erase_obj)},
#endif
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_FlashArea_locals_dict,
mod_trezorio_FlashArea_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorio_FlashArea_type = {
{&mp_type_type},
.name = MP_QSTR_FlashArea,
.locals_dict = (void *)&mod_trezorio_FlashArea_locals_dict,
};
#define FLASH_AREA(name, area_id) \
STATIC const mp_obj_FlashArea_t mod_trezorio_flash_area_##name = { \
.base = {.type = MP_ROM_PTR(&mod_trezorio_FlashArea_type)}, \
.area = &area_id, \
};
/// mock:global
/// package: trezorio.flash_area
/// from . import FlashArea
/// BOARDLOADER: FlashArea
/// BOOTLOADER: FlashArea
/// FIRMWARE: FlashArea
/// TRANSLATIONS: FlashArea
/// if __debug__:
/// STORAGE_A: FlashArea
/// STORAGE_B: FlashArea
FLASH_AREA(BOARDLOADER, BOARDLOADER_AREA)
FLASH_AREA(BOOTLOADER, BOOTLOADER_AREA)
FLASH_AREA(FIRMWARE, FIRMWARE_AREA)
FLASH_AREA(TRANSLATIONS, TRANSLATIONS_AREA)
#if DEBUG
FLASH_AREA(STORAGE_A, STORAGE_AREAS[0])
FLASH_AREA(STORAGE_B, STORAGE_AREAS[1])
#endif
#define MP_ROM_FLASH_AREA(name) \
{ MP_ROM_QSTR(MP_QSTR_##name), MP_ROM_PTR(&mod_trezorio_flash_area_##name) }
STATIC const mp_rom_map_elem_t mod_trezorio_flash_area_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_flash_area)},
MP_ROM_FLASH_AREA(BOARDLOADER),
MP_ROM_FLASH_AREA(BOOTLOADER),
MP_ROM_FLASH_AREA(FIRMWARE),
MP_ROM_FLASH_AREA(TRANSLATIONS),
#if DEBUG
MP_ROM_FLASH_AREA(STORAGE_A),
MP_ROM_FLASH_AREA(STORAGE_B),
#endif
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_flash_area_globals,
mod_trezorio_flash_area_globals_table);
const mp_obj_module_t mod_trezorio_flash_area = {
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mod_trezorio_flash_area_globals,
};

@ -57,7 +57,7 @@ bool usb_connected_previously = true;
#endif
/// package: trezorio.__init__
/// from . import fatfs, sdcard
/// from . import fatfs, sdcard, flash_area
/// POLL_READ: int # wait until interface is readable and return read data
/// POLL_WRITE: int # wait until interface is writable
@ -106,6 +106,7 @@ STATIC const mp_rom_map_elem_t mp_module_trezorio_globals_table[] = {
#endif
{MP_ROM_QSTR(MP_QSTR_FlashOTP), MP_ROM_PTR(&mod_trezorio_FlashOTP_type)},
{MP_ROM_QSTR(MP_QSTR_flash_area), MP_ROM_PTR(&mod_trezorio_flash_area)},
{MP_ROM_QSTR(MP_QSTR_USB), MP_ROM_PTR(&mod_trezorio_USB_type)},
{MP_ROM_QSTR(MP_QSTR_HID), MP_ROM_PTR(&mod_trezorio_HID_type)},

@ -48,16 +48,6 @@
#include "secret.h"
#endif
#define FW_HASHING_CHUNK_SIZE 1024
static void ui_progress(mp_obj_t ui_wait_callback, uint32_t current,
uint32_t total) {
if (mp_obj_is_callable(ui_wait_callback)) {
mp_call_function_2_protected(ui_wait_callback, mp_obj_new_int(current),
mp_obj_new_int(total));
}
}
/// def consteq(sec: bytes, pub: bytes) -> bool:
/// """
/// Compares the private information in `sec` with public, user-provided
@ -145,68 +135,6 @@ STATIC mp_obj_t mod_trezorutils_halt(size_t n_args, const mp_obj_t *args) {
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorutils_halt_obj, 0, 1,
mod_trezorutils_halt);
/// def firmware_hash(
/// challenge: bytes | None = None,
/// callback: Callable[[int, int], None] | None = None,
/// ) -> bytes:
/// """
/// Computes the Blake2s hash of the firmware with an optional challenge as
/// the key.
/// """
STATIC mp_obj_t mod_trezorutils_firmware_hash(size_t n_args,
const mp_obj_t *args) {
BLAKE2S_CTX ctx;
mp_buffer_info_t chal = {0};
if (n_args > 0 && args[0] != mp_const_none) {
mp_get_buffer_raise(args[0], &chal, MP_BUFFER_READ);
}
if (chal.len != 0) {
if (blake2s_InitKey(&ctx, BLAKE2S_DIGEST_LENGTH, chal.buf, chal.len) != 0) {
mp_raise_msg(&mp_type_ValueError, "Invalid challenge.");
}
} else {
blake2s_Init(&ctx, BLAKE2S_DIGEST_LENGTH);
}
mp_obj_t ui_wait_callback = mp_const_none;
if (n_args > 1 && args[1] != mp_const_none) {
ui_wait_callback = args[1];
}
uint32_t firmware_size = flash_area_get_size(&FIRMWARE_AREA);
uint32_t chunks = firmware_size / FW_HASHING_CHUNK_SIZE;
ensure((firmware_size % FW_HASHING_CHUNK_SIZE == 0) * sectrue,
"Cannot compute FW hash.");
ui_progress(ui_wait_callback, 0, chunks);
for (int i = 0; i < chunks; i++) {
const void *data = flash_area_get_address(
&FIRMWARE_AREA, i * FW_HASHING_CHUNK_SIZE, FW_HASHING_CHUNK_SIZE);
if (data == NULL) {
mp_raise_msg(&mp_type_RuntimeError, "Failed to read firmware.");
}
blake2s_Update(&ctx, data, FW_HASHING_CHUNK_SIZE);
if (i % 128 == 0) {
ui_progress(ui_wait_callback, i + 1, chunks);
}
}
ui_progress(ui_wait_callback, chunks, chunks);
vstr_t vstr = {0};
vstr_init_len(&vstr, BLAKE2S_DIGEST_LENGTH);
if (blake2s_Final(&ctx, vstr.buf, vstr.len) != 0) {
vstr_clear(&vstr);
mp_raise_msg(&mp_type_RuntimeError, "Failed to finalize firmware hash.");
}
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorutils_firmware_hash_obj, 0,
2, mod_trezorutils_firmware_hash);
/// def firmware_vendor() -> str:
/// """
/// Returns the firmware vendor string from the vendor header.
@ -411,8 +339,6 @@ STATIC const mp_rom_map_elem_t mp_module_trezorutils_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR_consteq), MP_ROM_PTR(&mod_trezorutils_consteq_obj)},
{MP_ROM_QSTR(MP_QSTR_memcpy), MP_ROM_PTR(&mod_trezorutils_memcpy_obj)},
{MP_ROM_QSTR(MP_QSTR_halt), MP_ROM_PTR(&mod_trezorutils_halt_obj)},
{MP_ROM_QSTR(MP_QSTR_firmware_hash),
MP_ROM_PTR(&mod_trezorutils_firmware_hash_obj)},
{MP_ROM_QSTR(MP_QSTR_firmware_vendor),
MP_ROM_PTR(&mod_trezorutils_firmware_vendor_obj)},
{MP_ROM_QSTR(MP_QSTR_reboot_to_bootloader),

@ -31,6 +31,56 @@ class FlashOTP:
"""
# extmod/modtrezorio/modtrezorio-flash.h
class FlashArea:
"""
Area of the flash memory
"""
def size(self) -> int:
"""
Returns size of the flash area
"""
def hash(
self,
offset: int,
length: int,
challenge: bytes | None = None,
callback: Callable[[int], None] | None = None,
) -> bytes:
"""
Computes a Blake2s hash of a segment of the flash area.
Offset and length must be aligned to 1024 bytes.
An optional challenge can be used as the Blake2s key.
The progress callback will be invoked every 16 kB with the current
position.
"""
if __debug__:
def read(self, offset: int, data: bytearray) -> None:
"""
Reads data from flash area. Will read exact length of data
bytearray. Offset and length of data must be aligned to 1024 bytes.
"""
if __debug__:
def write(self, offset: int, data: bytes) -> None:
"""
Writes data to flash area.
Offset and written data size must be a multiple of FLASH_BLOCK_SIZE,
that is, 4 bytes on F4 or 16 bytes on U5.
"""
if __debug__:
def erase_sector(self, offset: int) -> None:
"""
Erases a flash area sector starting at specified offset.
"""
if __debug__:
def erase(self) -> None:
"""
Erases the whole flash area.
"""
# extmod/modtrezorio/modtrezorio-hid.h
class HID:
"""
@ -190,7 +240,7 @@ class WebUSB:
"""
Sends message using USB WebUSB (device) or UDP (emulator).
"""
from . import fatfs, sdcard
from . import fatfs, sdcard, flash_area
POLL_READ: int # wait until interface is readable and return read data
POLL_WRITE: int # wait until interface is writable
TOUCH: int # interface id of the touch events

@ -0,0 +1,9 @@
from typing import *
from . import FlashArea
BOARDLOADER: FlashArea
BOOTLOADER: FlashArea
FIRMWARE: FlashArea
TRANSLATIONS: FlashArea
if __debug__:
STORAGE_A: FlashArea
STORAGE_B: FlashArea

@ -42,17 +42,6 @@ def halt(msg: str | None = None) -> None:
"""
# extmod/modtrezorutils/modtrezorutils.c
def firmware_hash(
challenge: bytes | None = None,
callback: Callable[[int, int], None] | None = None,
) -> bytes:
"""
Computes the Blake2s hash of the firmware with an optional challenge as
the key.
"""
# extmod/modtrezorutils/modtrezorutils.c
def firmware_vendor() -> str:
"""

@ -109,6 +109,8 @@ trezor.enums.DecredStakingSpendType
import trezor.enums.DecredStakingSpendType
trezor.enums.FailureType
import trezor.enums.FailureType
trezor.enums.FlashArea
import trezor.enums.FlashArea
trezor.enums.HomescreenFormat
import trezor.enums.HomescreenFormat
trezor.enums.InputScriptType

@ -9,9 +9,9 @@ if __debug__:
import trezorui2
from storage import debug as storage
from storage.debug import debug_events
from trezor import log, loop, utils, wire
from trezor.enums import MessageType
from trezor.messages import DebugLinkLayout, Success
from trezor import io, log, loop, utils, wire
from trezor.enums import FlashArea, MessageType
from trezor.messages import DebugLinkLayout, DebugLinkMemory, Success
from trezor.ui import display
from trezor.wire import context
@ -21,6 +21,9 @@ if __debug__:
from trezor.messages import (
DebugLinkDecision,
DebugLinkEraseSdCard,
DebugLinkFlashErase,
DebugLinkFlashRead,
DebugLinkFlashWrite,
DebugLinkGetState,
DebugLinkRecordScreen,
DebugLinkReseedRandom,
@ -241,8 +244,6 @@ if __debug__:
return Success()
async def dispatch_DebugLinkEraseSdCard(msg: DebugLinkEraseSdCard) -> Success:
from trezor import io
sdcard = io.sdcard # local_cache_attribute
try:
@ -262,6 +263,66 @@ if __debug__:
sdcard.power_off()
return Success()
def get_flash_area(area: FlashArea) -> io.FlashArea:
if area == FlashArea.Boardloader:
return io.flash_area.BOARDLOADER
if area == FlashArea.Bootloader:
return io.flash_area.BOOTLOADER
if area == FlashArea.Firmware:
return io.flash_area.FIRMWARE
if area == FlashArea.StorageA:
return io.flash_area.STORAGE_A
if area == FlashArea.StorageB:
return io.flash_area.STORAGE_B
if area == FlashArea.Translations:
return io.flash_area.TRANSLATIONS
raise ValueError
async def dispatch_DebugLinkFlashRead(msg: DebugLinkFlashRead) -> DebugLinkMemory:
try:
area = get_flash_area(msg.location.area)
if msg.length is not None:
length = msg.length
else:
length = area.size() - msg.location.offset
if msg.hashed:
return DebugLinkMemory(hash=area.hash(msg.location.offset, length))
else:
data = utils.empty_bytearray(length)
area.read(msg.location.offset, data)
return DebugLinkMemory(memory=data)
except Exception as e:
raise wire.ProcessError(e.args[0])
async def dispatch_DebugLinkFlashWrite(msg: DebugLinkFlashWrite) -> Success:
from trezor import translations
try:
translations.deinit()
area = get_flash_area(msg.location.area)
area.write(msg.location.offset, msg.memory)
return Success()
except Exception as e:
raise wire.ProcessError(e.args[0])
finally:
translations.init()
async def dispatch_DebugLinkFlashErase(msg: DebugLinkFlashErase) -> Success:
from trezor import translations
try:
translations.deinit()
area = get_flash_area(msg.location.area)
if msg.whole_area:
area.erase()
else:
area.erase_sector(msg.location.offset)
return Success()
except Exception as e:
raise wire.ProcessError(e.args[0])
finally:
translations.init()
def boot() -> None:
register = workflow_handlers.register # local_cache_attribute
@ -274,6 +335,9 @@ if __debug__:
register(
MessageType.DebugLinkResetDebugEvents, dispatch_DebugLinkResetDebugEvents
)
register(MessageType.DebugLinkFlashRead, dispatch_DebugLinkFlashRead)
register(MessageType.DebugLinkFlashWrite, dispatch_DebugLinkFlashWrite)
register(MessageType.DebugLinkFlashErase, dispatch_DebugLinkFlashErase)
loop.schedule(debuglink_decision_dispatcher())
if storage.layout_watcher is not LAYOUT_WATCHER_NONE:

@ -2,32 +2,25 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from trezor.messages import FirmwareHash, GetFirmwareHash
from trezor.ui.layouts.common import ProgressLayout
_progress_obj: ProgressLayout | None = None
async def get_firmware_hash(msg: GetFirmwareHash) -> FirmwareHash:
from trezor import wire, workflow
from trezor import io, wire, workflow
from trezor.messages import FirmwareHash
from trezor.ui.layouts.progress import progress
from trezor.utils import firmware_hash
workflow.close_others()
global _progress_obj
_progress_obj = progress()
progress_obj = progress()
try:
hash = firmware_hash(msg.challenge, _render_progress)
area = io.flash_area.FIRMWARE
area_size = area.size()
def report(byte: int) -> None:
progress_obj.report(1000 * byte // area_size)
hash = area.hash(0, area.size(), msg.challenge, report)
except ValueError as e:
raise wire.DataError(str(e))
finally:
_progress_obj = None
return FirmwareHash(hash=hash)
def _render_progress(progress: int, total: int) -> None:
global _progress_obj
if _progress_obj is not None:
_progress_obj.report(1000 * progress // total)

@ -0,0 +1,10 @@
# Automatically generated by pb2py
# fmt: off
# isort:skip_file
Boardloader = 0
Bootloader = 1
StorageA = 2
StorageB = 3
Firmware = 4
Translations = 5

@ -87,16 +87,16 @@ DebugLinkGetState = 101
DebugLinkState = 102
DebugLinkStop = 103
DebugLinkLog = 104
DebugLinkMemoryRead = 110
DebugLinkMemory = 111
DebugLinkMemoryWrite = 112
DebugLinkFlashErase = 113
DebugLinkLayout = 9001
DebugLinkReseedRandom = 9002
DebugLinkRecordScreen = 9003
DebugLinkEraseSdCard = 9005
DebugLinkWatchLayout = 9006
DebugLinkResetDebugEvents = 9007
DebugLinkFlashRead = 9008
DebugLinkFlashWrite = 9009
DebugLinkFlashErase = 9010
if not utils.BITCOIN_ONLY:
SetU2FCounter = 63
GetNextU2FCounter = 80

@ -113,13 +113,16 @@ if TYPE_CHECKING:
DebugLinkMemoryRead = 110
DebugLinkMemory = 111
DebugLinkMemoryWrite = 112
DebugLinkFlashErase = 113
DebugLinkFlashEraseLegacy = 113
DebugLinkLayout = 9001
DebugLinkReseedRandom = 9002
DebugLinkRecordScreen = 9003
DebugLinkEraseSdCard = 9005
DebugLinkWatchLayout = 9006
DebugLinkResetDebugEvents = 9007
DebugLinkFlashRead = 9008
DebugLinkFlashWrite = 9009
DebugLinkFlashErase = 9010
EthereumGetPublicKey = 450
EthereumPublicKey = 451
EthereumGetAddress = 56
@ -482,6 +485,14 @@ if TYPE_CHECKING:
MIDDLE_BTN = 1
RIGHT_BTN = 2
class FlashArea(IntEnum):
Boardloader = 0
Bootloader = 1
StorageA = 2
StorageB = 3
Firmware = 4
Translations = 5
class EthereumDefinitionType(IntEnum):
NETWORK = 0
TOKEN = 1

@ -42,6 +42,7 @@ if TYPE_CHECKING:
from trezor.enums import EthereumDataType # noqa: F401
from trezor.enums import EthereumDefinitionType # noqa: F401
from trezor.enums import FailureType # noqa: F401
from trezor.enums import FlashArea # noqa: F401
from trezor.enums import HomescreenFormat # noqa: F401
from trezor.enums import InputScriptType # noqa: F401
from trezor.enums import MessageType # noqa: F401
@ -2891,29 +2892,49 @@ if TYPE_CHECKING:
def is_type_of(cls, msg: Any) -> TypeGuard["DebugLinkLog"]:
return isinstance(msg, cls)
class DebugLinkMemoryRead(protobuf.MessageType):
address: "int | None"
class FlashMemoryLocation(protobuf.MessageType):
area: "FlashArea"
offset: "int"
def __init__(
self,
*,
area: "FlashArea",
offset: "int",
) -> None:
pass
@classmethod
def is_type_of(cls, msg: Any) -> TypeGuard["FlashMemoryLocation"]:
return isinstance(msg, cls)
class DebugLinkFlashRead(protobuf.MessageType):
location: "FlashMemoryLocation"
length: "int | None"
hashed: "bool"
def __init__(
self,
*,
address: "int | None" = None,
location: "FlashMemoryLocation",
length: "int | None" = None,
hashed: "bool | None" = None,
) -> None:
pass
@classmethod
def is_type_of(cls, msg: Any) -> TypeGuard["DebugLinkMemoryRead"]:
def is_type_of(cls, msg: Any) -> TypeGuard["DebugLinkFlashRead"]:
return isinstance(msg, cls)
class DebugLinkMemory(protobuf.MessageType):
memory: "bytes | None"
hash: "bytes | None"
def __init__(
self,
*,
memory: "bytes | None" = None,
hash: "bytes | None" = None,
) -> None:
pass
@ -2921,31 +2942,31 @@ if TYPE_CHECKING:
def is_type_of(cls, msg: Any) -> TypeGuard["DebugLinkMemory"]:
return isinstance(msg, cls)
class DebugLinkMemoryWrite(protobuf.MessageType):
address: "int | None"
memory: "bytes | None"
flash: "bool | None"
class DebugLinkFlashWrite(protobuf.MessageType):
location: "FlashMemoryLocation"
memory: "bytes"
def __init__(
self,
*,
address: "int | None" = None,
memory: "bytes | None" = None,
flash: "bool | None" = None,
location: "FlashMemoryLocation",
memory: "bytes",
) -> None:
pass
@classmethod
def is_type_of(cls, msg: Any) -> TypeGuard["DebugLinkMemoryWrite"]:
def is_type_of(cls, msg: Any) -> TypeGuard["DebugLinkFlashWrite"]:
return isinstance(msg, cls)
class DebugLinkFlashErase(protobuf.MessageType):
sector: "int | None"
location: "FlashMemoryLocation"
whole_area: "bool"
def __init__(
self,
*,
sector: "int | None" = None,
location: "FlashMemoryLocation",
whole_area: "bool | None" = None,
) -> None:
pass

@ -15,7 +15,6 @@ from trezorutils import ( # noqa: F401
bootloader_locked,
check_firmware_header,
consteq,
firmware_hash,
firmware_vendor,
halt,
memcpy,

@ -94,7 +94,7 @@ void fsm_msgDebugLinkMemoryWrite(const DebugLinkMemoryWrite *msg) {
}
}
void fsm_msgDebugLinkFlashErase(const DebugLinkFlashErase *msg) {
void fsm_msgDebugLinkFlashEraseLegacy(const DebugLinkFlashEraseLegacy *msg) {
svc_flash_unlock();
svc_flash_erase_sector(msg->sector);
uint32_t dummy = svc_flash_lock();

@ -4,6 +4,7 @@ endif
SKIPPED_MESSAGES := Binance Cardano DebugMonero Eos Monero Ontology Ripple SdProtect Tezos WebAuthn \
DebugLinkRecordScreen DebugLinkEraseSdCard DebugLinkWatchLayout \
DebugLinkFlashErase DebugLinkFlashRead DebugLinkFlashWrite \
DebugLinkLayout DebugLinkResetDebugEvents GetNonce \
TxAckInput TxAckOutput TxAckPrev TxAckPaymentRequest \
EthereumSignTypedData EthereumTypedDataStructRequest EthereumTypedDataStructAck \

@ -15,6 +15,7 @@ DebugLinkLog.bucket max_size:33
DebugLinkLog.text max_size:256
DebugLinkMemory.memory max_size:1024
DebugLinkMemory.hash max_size:32
DebugLinkMemoryWrite.memory max_size:1024
# Unused messages.

@ -14,6 +14,8 @@
# You should have received a copy of the License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
from __future__ import annotations
import json
import logging
import re
@ -428,6 +430,8 @@ class DebugLink:
f"received message: {msg.__class__.__name__}",
extra={"protobuf": msg},
)
if isinstance(msg, messages.Failure):
raise TrezorFailure(msg)
return msg
def state(self) -> messages.DebugLinkState:
@ -711,17 +715,33 @@ class DebugLink:
self.t1_take_screenshots = False
@expect(messages.DebugLinkMemory, field="memory", ret_type=bytes)
def memory_read(self, address: int, length: int) -> protobuf.MessageType:
return self._call(messages.DebugLinkMemoryRead(address=address, length=length))
def memory_write(self, address: int, memory: bytes, flash: bool = False) -> None:
self._call(
messages.DebugLinkMemoryWrite(address=address, memory=memory, flash=flash),
nowait=True,
def flash_read(
self, area: messages.FlashArea, offset: int = 0, length: int | None = None
) -> protobuf.MessageType:
location = messages.FlashMemoryLocation(area=area, offset=offset)
return self._call(messages.DebugLinkFlashRead(location=location, length=length))
@expect(messages.DebugLinkMemory, field="hash", ret_type=bytes)
def flash_hash(
self, area: messages.FlashArea, offset: int = 0, length: int | None = None
) -> protobuf.MessageType:
location = messages.FlashMemoryLocation(area=area, offset=offset)
return self._call(
messages.DebugLinkFlashRead(location=location, length=length, hashed=True)
)
def flash_erase(self, sector: int) -> None:
self._call(messages.DebugLinkFlashErase(sector=sector), nowait=True)
def flash_erase(self, area: messages.FlashArea, offset: int) -> None:
location = messages.FlashMemoryLocation(area=area, offset=offset)
self._call(messages.DebugLinkFlashErase(location=location, whole_area=False))
def flash_erase_area(self, area: messages.FlashArea) -> None:
location = messages.FlashMemoryLocation(area=area, offset=0)
self._call(messages.DebugLinkFlashErase(location=location, whole_area=True))
def storage_hash(self) -> bytes:
storage_hash_a = self.flash_hash(messages.FlashArea.StorageA)
storage_hash_b = self.flash_hash(messages.FlashArea.StorageB)
return storage_hash_a + storage_hash_b
@expect(messages.Success)
def erase_sd_card(self, format: bool = True) -> messages.Success:

@ -121,13 +121,16 @@ class MessageType(IntEnum):
DebugLinkMemoryRead = 110
DebugLinkMemory = 111
DebugLinkMemoryWrite = 112
DebugLinkFlashErase = 113
DebugLinkFlashEraseLegacy = 113
DebugLinkLayout = 9001
DebugLinkReseedRandom = 9002
DebugLinkRecordScreen = 9003
DebugLinkEraseSdCard = 9005
DebugLinkWatchLayout = 9006
DebugLinkResetDebugEvents = 9007
DebugLinkFlashRead = 9008
DebugLinkFlashWrite = 9009
DebugLinkFlashErase = 9010
EthereumGetPublicKey = 450
EthereumPublicKey = 451
EthereumGetAddress = 56
@ -521,6 +524,15 @@ class DebugPhysicalButton(IntEnum):
RIGHT_BTN = 2
class FlashArea(IntEnum):
Boardloader = 0
Bootloader = 1
StorageA = 2
StorageB = 3
Firmware = 4
Translations = 5
class EthereumDefinitionType(IntEnum):
NETWORK = 0
TOKEN = 1
@ -4066,6 +4078,23 @@ class DebugLinkLog(protobuf.MessageType):
self.text = text
class FlashMemoryLocation(protobuf.MessageType):
MESSAGE_WIRE_TYPE = None
FIELDS = {
1: protobuf.Field("area", "FlashArea", repeated=False, required=True),
2: protobuf.Field("offset", "uint32", repeated=False, required=True),
}
def __init__(
self,
*,
area: "FlashArea",
offset: "int",
) -> None:
self.area = area
self.offset = offset
class DebugLinkMemoryRead(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 110
FIELDS = {
@ -4083,18 +4112,41 @@ class DebugLinkMemoryRead(protobuf.MessageType):
self.length = length
class DebugLinkFlashRead(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 9008
FIELDS = {
1: protobuf.Field("location", "FlashMemoryLocation", repeated=False, required=True),
2: protobuf.Field("length", "uint32", repeated=False, required=False, default=None),
3: protobuf.Field("hashed", "bool", repeated=False, required=False, default=False),
}
def __init__(
self,
*,
location: "FlashMemoryLocation",
length: Optional["int"] = None,
hashed: Optional["bool"] = False,
) -> None:
self.location = location
self.length = length
self.hashed = hashed
class DebugLinkMemory(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 111
FIELDS = {
1: protobuf.Field("memory", "bytes", repeated=False, required=False, default=None),
2: protobuf.Field("hash", "bytes", repeated=False, required=False, default=None),
}
def __init__(
self,
*,
memory: Optional["bytes"] = None,
hash: Optional["bytes"] = None,
) -> None:
self.memory = memory
self.hash = hash
class DebugLinkMemoryWrite(protobuf.MessageType):
@ -4117,7 +4169,24 @@ class DebugLinkMemoryWrite(protobuf.MessageType):
self.flash = flash
class DebugLinkFlashErase(protobuf.MessageType):
class DebugLinkFlashWrite(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 9009
FIELDS = {
1: protobuf.Field("location", "FlashMemoryLocation", repeated=False, required=True),
2: protobuf.Field("memory", "bytes", repeated=False, required=True),
}
def __init__(
self,
*,
location: "FlashMemoryLocation",
memory: "bytes",
) -> None:
self.location = location
self.memory = memory
class DebugLinkFlashEraseLegacy(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 113
FIELDS = {
1: protobuf.Field("sector", "uint32", repeated=False, required=False, default=None),
@ -4131,6 +4200,23 @@ class DebugLinkFlashErase(protobuf.MessageType):
self.sector = sector
class DebugLinkFlashErase(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 9010
FIELDS = {
1: protobuf.Field("location", "FlashMemoryLocation", repeated=False, required=True),
2: protobuf.Field("whole_area", "bool", repeated=False, required=False, default=False),
}
def __init__(
self,
*,
location: "FlashMemoryLocation",
whole_area: Optional["bool"] = False,
) -> None:
self.location = location
self.whole_area = whole_area
class DebugLinkEraseSdCard(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 9005
FIELDS = {

@ -1,67 +0,0 @@
#!/usr/bin/env python3
# This file is part of the Trezor project.
#
# Copyright (C) 2012-2022 SatoshiLabs and contributors
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License version 3
# as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
import sys
from trezorlib.debuglink import DebugLink
from trezorlib.transport import enumerate_devices
# fmt: off
sectoraddrs = [0x8000000, 0x8004000, 0x8008000, 0x800c000,
0x8010000, 0x8020000, 0x8040000, 0x8060000,
0x8080000, 0x80a0000, 0x80c0000, 0x80f0000]
sectorlens = [0x4000, 0x4000, 0x4000, 0x4000,
0x8000, 0x10000, 0x10000, 0x10000,
0x10000, 0x10000, 0x10000, 0x10000]
# fmt: on
def find_debug() -> DebugLink:
for device in enumerate_devices():
try:
debug_transport = device.find_debug()
debug = DebugLink(debug_transport, auto_interact=False)
debug.open()
return debug
except Exception:
continue
else:
print("No suitable Trezor device found")
sys.exit(1)
def main() -> None:
debug = find_debug()
sector = int(sys.argv[1])
f = open(sys.argv[2], "rb")
content = f.read(sectorlens[sector])
if len(content) != sectorlens[sector]:
print("Not enough bytes in file")
return
debug.flash_erase(sector)
step = 0x400
for offset in range(0, sectorlens[sector], step):
debug.memory_write(
sectoraddrs[sector] + offset, content[offset : offset + step], flash=True
)
if __name__ == "__main__":
main()

@ -1,64 +0,0 @@
#!/usr/bin/env python3
# This file is part of the Trezor project.
#
# Copyright (C) 2012-2022 SatoshiLabs and contributors
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License version 3
# as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
import sys
from trezorlib.debuglink import DebugLink
from trezorlib.transport import enumerate_devices
# usage examples
# read entire bootloader: ./mem_read.py 8000000 8000
# read initial stack pointer: ./mem_read.py 8000000 4
# an entire bootloader can be later disassembled with:
# arm-none-eabi-objdump -D -b binary -m arm -M force-thumb memory.dat
# note that in order for this to work, your trezor device must
# be running a firmware that was built with debug link enabled
def find_debug() -> DebugLink:
for device in enumerate_devices():
try:
debug_transport = device.find_debug()
debug = DebugLink(debug_transport, auto_interact=False)
debug.open()
return debug
except Exception:
continue
else:
print("No suitable Trezor device found")
sys.exit(1)
def main() -> None:
debug = find_debug()
arg1 = int(sys.argv[1], 16)
arg2 = int(sys.argv[2], 16)
step = 0x400 if arg2 >= 0x400 else arg2
f = open("memory.dat", "wb")
for addr in range(arg1, arg1 + arg2, step):
mem = debug.memory_read(addr, step)
f.write(mem)
f.close()
if __name__ == "__main__":
main()

@ -1,45 +0,0 @@
#!/usr/bin/env python3
# This file is part of the Trezor project.
#
# Copyright (C) 2012-2022 SatoshiLabs and contributors
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License version 3
# as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
import sys
from trezorlib.debuglink import DebugLink
from trezorlib.transport import enumerate_devices
def find_debug() -> DebugLink:
for device in enumerate_devices():
try:
debug_transport = device.find_debug()
debug = DebugLink(debug_transport, auto_interact=False)
debug.open()
return debug
except Exception:
continue
else:
print("No suitable Trezor device found")
sys.exit(1)
def main() -> None:
debug = find_debug()
debug.memory_write(int(sys.argv[1], 16), bytes.fromhex(sys.argv[2]), flash=True)
if __name__ == "__main__":
main()

@ -75,13 +75,16 @@ trezor_message_impl! {
DebugLinkMemoryRead => MessageType_DebugLinkMemoryRead,
DebugLinkMemory => MessageType_DebugLinkMemory,
DebugLinkMemoryWrite => MessageType_DebugLinkMemoryWrite,
DebugLinkFlashErase => MessageType_DebugLinkFlashErase,
DebugLinkFlashEraseLegacy => MessageType_DebugLinkFlashEraseLegacy,
DebugLinkLayout => MessageType_DebugLinkLayout,
DebugLinkReseedRandom => MessageType_DebugLinkReseedRandom,
DebugLinkRecordScreen => MessageType_DebugLinkRecordScreen,
DebugLinkEraseSdCard => MessageType_DebugLinkEraseSdCard,
DebugLinkWatchLayout => MessageType_DebugLinkWatchLayout,
DebugLinkResetDebugEvents => MessageType_DebugLinkResetDebugEvents,
DebugLinkFlashRead => MessageType_DebugLinkFlashRead,
DebugLinkFlashWrite => MessageType_DebugLinkFlashWrite,
DebugLinkFlashErase => MessageType_DebugLinkFlashErase,
}
#[cfg(feature = "binance")]

@ -212,8 +212,8 @@ pub enum MessageType {
MessageType_DebugLinkMemory = 111,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_DebugLinkMemoryWrite)
MessageType_DebugLinkMemoryWrite = 112,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_DebugLinkFlashErase)
MessageType_DebugLinkFlashErase = 113,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_DebugLinkFlashEraseLegacy)
MessageType_DebugLinkFlashEraseLegacy = 113,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_DebugLinkLayout)
MessageType_DebugLinkLayout = 9001,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_DebugLinkReseedRandom)
@ -226,6 +226,12 @@ pub enum MessageType {
MessageType_DebugLinkWatchLayout = 9006,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_DebugLinkResetDebugEvents)
MessageType_DebugLinkResetDebugEvents = 9007,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_DebugLinkFlashRead)
MessageType_DebugLinkFlashRead = 9008,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_DebugLinkFlashWrite)
MessageType_DebugLinkFlashWrite = 9009,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_DebugLinkFlashErase)
MessageType_DebugLinkFlashErase = 9010,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_EthereumGetPublicKey)
MessageType_EthereumGetPublicKey = 450,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_EthereumPublicKey)
@ -617,13 +623,16 @@ impl ::protobuf::Enum for MessageType {
110 => ::std::option::Option::Some(MessageType::MessageType_DebugLinkMemoryRead),
111 => ::std::option::Option::Some(MessageType::MessageType_DebugLinkMemory),
112 => ::std::option::Option::Some(MessageType::MessageType_DebugLinkMemoryWrite),
113 => ::std::option::Option::Some(MessageType::MessageType_DebugLinkFlashErase),
113 => ::std::option::Option::Some(MessageType::MessageType_DebugLinkFlashEraseLegacy),
9001 => ::std::option::Option::Some(MessageType::MessageType_DebugLinkLayout),
9002 => ::std::option::Option::Some(MessageType::MessageType_DebugLinkReseedRandom),
9003 => ::std::option::Option::Some(MessageType::MessageType_DebugLinkRecordScreen),
9005 => ::std::option::Option::Some(MessageType::MessageType_DebugLinkEraseSdCard),
9006 => ::std::option::Option::Some(MessageType::MessageType_DebugLinkWatchLayout),
9007 => ::std::option::Option::Some(MessageType::MessageType_DebugLinkResetDebugEvents),
9008 => ::std::option::Option::Some(MessageType::MessageType_DebugLinkFlashRead),
9009 => ::std::option::Option::Some(MessageType::MessageType_DebugLinkFlashWrite),
9010 => ::std::option::Option::Some(MessageType::MessageType_DebugLinkFlashErase),
450 => ::std::option::Option::Some(MessageType::MessageType_EthereumGetPublicKey),
451 => ::std::option::Option::Some(MessageType::MessageType_EthereumPublicKey),
56 => ::std::option::Option::Some(MessageType::MessageType_EthereumGetAddress),
@ -866,13 +875,16 @@ impl ::protobuf::Enum for MessageType {
"MessageType_DebugLinkMemoryRead" => ::std::option::Option::Some(MessageType::MessageType_DebugLinkMemoryRead),
"MessageType_DebugLinkMemory" => ::std::option::Option::Some(MessageType::MessageType_DebugLinkMemory),
"MessageType_DebugLinkMemoryWrite" => ::std::option::Option::Some(MessageType::MessageType_DebugLinkMemoryWrite),
"MessageType_DebugLinkFlashErase" => ::std::option::Option::Some(MessageType::MessageType_DebugLinkFlashErase),
"MessageType_DebugLinkFlashEraseLegacy" => ::std::option::Option::Some(MessageType::MessageType_DebugLinkFlashEraseLegacy),
"MessageType_DebugLinkLayout" => ::std::option::Option::Some(MessageType::MessageType_DebugLinkLayout),
"MessageType_DebugLinkReseedRandom" => ::std::option::Option::Some(MessageType::MessageType_DebugLinkReseedRandom),
"MessageType_DebugLinkRecordScreen" => ::std::option::Option::Some(MessageType::MessageType_DebugLinkRecordScreen),
"MessageType_DebugLinkEraseSdCard" => ::std::option::Option::Some(MessageType::MessageType_DebugLinkEraseSdCard),
"MessageType_DebugLinkWatchLayout" => ::std::option::Option::Some(MessageType::MessageType_DebugLinkWatchLayout),
"MessageType_DebugLinkResetDebugEvents" => ::std::option::Option::Some(MessageType::MessageType_DebugLinkResetDebugEvents),
"MessageType_DebugLinkFlashRead" => ::std::option::Option::Some(MessageType::MessageType_DebugLinkFlashRead),
"MessageType_DebugLinkFlashWrite" => ::std::option::Option::Some(MessageType::MessageType_DebugLinkFlashWrite),
"MessageType_DebugLinkFlashErase" => ::std::option::Option::Some(MessageType::MessageType_DebugLinkFlashErase),
"MessageType_EthereumGetPublicKey" => ::std::option::Option::Some(MessageType::MessageType_EthereumGetPublicKey),
"MessageType_EthereumPublicKey" => ::std::option::Option::Some(MessageType::MessageType_EthereumPublicKey),
"MessageType_EthereumGetAddress" => ::std::option::Option::Some(MessageType::MessageType_EthereumGetAddress),
@ -1114,13 +1126,16 @@ impl ::protobuf::Enum for MessageType {
MessageType::MessageType_DebugLinkMemoryRead,
MessageType::MessageType_DebugLinkMemory,
MessageType::MessageType_DebugLinkMemoryWrite,
MessageType::MessageType_DebugLinkFlashErase,
MessageType::MessageType_DebugLinkFlashEraseLegacy,
MessageType::MessageType_DebugLinkLayout,
MessageType::MessageType_DebugLinkReseedRandom,
MessageType::MessageType_DebugLinkRecordScreen,
MessageType::MessageType_DebugLinkEraseSdCard,
MessageType::MessageType_DebugLinkWatchLayout,
MessageType::MessageType_DebugLinkResetDebugEvents,
MessageType::MessageType_DebugLinkFlashRead,
MessageType::MessageType_DebugLinkFlashWrite,
MessageType::MessageType_DebugLinkFlashErase,
MessageType::MessageType_EthereumGetPublicKey,
MessageType::MessageType_EthereumPublicKey,
MessageType::MessageType_EthereumGetAddress,
@ -1368,157 +1383,160 @@ impl ::protobuf::EnumFull for MessageType {
MessageType::MessageType_DebugLinkMemoryRead => 89,
MessageType::MessageType_DebugLinkMemory => 90,
MessageType::MessageType_DebugLinkMemoryWrite => 91,
MessageType::MessageType_DebugLinkFlashErase => 92,
MessageType::MessageType_DebugLinkFlashEraseLegacy => 92,
MessageType::MessageType_DebugLinkLayout => 93,
MessageType::MessageType_DebugLinkReseedRandom => 94,
MessageType::MessageType_DebugLinkRecordScreen => 95,
MessageType::MessageType_DebugLinkEraseSdCard => 96,
MessageType::MessageType_DebugLinkWatchLayout => 97,
MessageType::MessageType_DebugLinkResetDebugEvents => 98,
MessageType::MessageType_EthereumGetPublicKey => 99,
MessageType::MessageType_EthereumPublicKey => 100,
MessageType::MessageType_EthereumGetAddress => 101,
MessageType::MessageType_EthereumAddress => 102,
MessageType::MessageType_EthereumSignTx => 103,
MessageType::MessageType_EthereumSignTxEIP1559 => 104,
MessageType::MessageType_EthereumTxRequest => 105,
MessageType::MessageType_EthereumTxAck => 106,
MessageType::MessageType_EthereumSignMessage => 107,
MessageType::MessageType_EthereumVerifyMessage => 108,
MessageType::MessageType_EthereumMessageSignature => 109,
MessageType::MessageType_EthereumSignTypedData => 110,
MessageType::MessageType_EthereumTypedDataStructRequest => 111,
MessageType::MessageType_EthereumTypedDataStructAck => 112,
MessageType::MessageType_EthereumTypedDataValueRequest => 113,
MessageType::MessageType_EthereumTypedDataValueAck => 114,
MessageType::MessageType_EthereumTypedDataSignature => 115,
MessageType::MessageType_EthereumSignTypedHash => 116,
MessageType::MessageType_NEMGetAddress => 117,
MessageType::MessageType_NEMAddress => 118,
MessageType::MessageType_NEMSignTx => 119,
MessageType::MessageType_NEMSignedTx => 120,
MessageType::MessageType_NEMDecryptMessage => 121,
MessageType::MessageType_NEMDecryptedMessage => 122,
MessageType::MessageType_TezosGetAddress => 123,
MessageType::MessageType_TezosAddress => 124,
MessageType::MessageType_TezosSignTx => 125,
MessageType::MessageType_TezosSignedTx => 126,
MessageType::MessageType_TezosGetPublicKey => 127,
MessageType::MessageType_TezosPublicKey => 128,
MessageType::MessageType_StellarSignTx => 129,
MessageType::MessageType_StellarTxOpRequest => 130,
MessageType::MessageType_StellarGetAddress => 131,
MessageType::MessageType_StellarAddress => 132,
MessageType::MessageType_StellarCreateAccountOp => 133,
MessageType::MessageType_StellarPaymentOp => 134,
MessageType::MessageType_StellarPathPaymentStrictReceiveOp => 135,
MessageType::MessageType_StellarManageSellOfferOp => 136,
MessageType::MessageType_StellarCreatePassiveSellOfferOp => 137,
MessageType::MessageType_StellarSetOptionsOp => 138,
MessageType::MessageType_StellarChangeTrustOp => 139,
MessageType::MessageType_StellarAllowTrustOp => 140,
MessageType::MessageType_StellarAccountMergeOp => 141,
MessageType::MessageType_StellarManageDataOp => 142,
MessageType::MessageType_StellarBumpSequenceOp => 143,
MessageType::MessageType_StellarManageBuyOfferOp => 144,
MessageType::MessageType_StellarPathPaymentStrictSendOp => 145,
MessageType::MessageType_StellarClaimClaimableBalanceOp => 146,
MessageType::MessageType_StellarSignedTx => 147,
MessageType::MessageType_CardanoGetPublicKey => 148,
MessageType::MessageType_CardanoPublicKey => 149,
MessageType::MessageType_CardanoGetAddress => 150,
MessageType::MessageType_CardanoAddress => 151,
MessageType::MessageType_CardanoTxItemAck => 152,
MessageType::MessageType_CardanoTxAuxiliaryDataSupplement => 153,
MessageType::MessageType_CardanoTxWitnessRequest => 154,
MessageType::MessageType_CardanoTxWitnessResponse => 155,
MessageType::MessageType_CardanoTxHostAck => 156,
MessageType::MessageType_CardanoTxBodyHash => 157,
MessageType::MessageType_CardanoSignTxFinished => 158,
MessageType::MessageType_CardanoSignTxInit => 159,
MessageType::MessageType_CardanoTxInput => 160,
MessageType::MessageType_CardanoTxOutput => 161,
MessageType::MessageType_CardanoAssetGroup => 162,
MessageType::MessageType_CardanoToken => 163,
MessageType::MessageType_CardanoTxCertificate => 164,
MessageType::MessageType_CardanoTxWithdrawal => 165,
MessageType::MessageType_CardanoTxAuxiliaryData => 166,
MessageType::MessageType_CardanoPoolOwner => 167,
MessageType::MessageType_CardanoPoolRelayParameters => 168,
MessageType::MessageType_CardanoGetNativeScriptHash => 169,
MessageType::MessageType_CardanoNativeScriptHash => 170,
MessageType::MessageType_CardanoTxMint => 171,
MessageType::MessageType_CardanoTxCollateralInput => 172,
MessageType::MessageType_CardanoTxRequiredSigner => 173,
MessageType::MessageType_CardanoTxInlineDatumChunk => 174,
MessageType::MessageType_CardanoTxReferenceScriptChunk => 175,
MessageType::MessageType_CardanoTxReferenceInput => 176,
MessageType::MessageType_RippleGetAddress => 177,
MessageType::MessageType_RippleAddress => 178,
MessageType::MessageType_RippleSignTx => 179,
MessageType::MessageType_RippleSignedTx => 180,
MessageType::MessageType_MoneroTransactionInitRequest => 181,
MessageType::MessageType_MoneroTransactionInitAck => 182,
MessageType::MessageType_MoneroTransactionSetInputRequest => 183,
MessageType::MessageType_MoneroTransactionSetInputAck => 184,
MessageType::MessageType_MoneroTransactionInputViniRequest => 185,
MessageType::MessageType_MoneroTransactionInputViniAck => 186,
MessageType::MessageType_MoneroTransactionAllInputsSetRequest => 187,
MessageType::MessageType_MoneroTransactionAllInputsSetAck => 188,
MessageType::MessageType_MoneroTransactionSetOutputRequest => 189,
MessageType::MessageType_MoneroTransactionSetOutputAck => 190,
MessageType::MessageType_MoneroTransactionAllOutSetRequest => 191,
MessageType::MessageType_MoneroTransactionAllOutSetAck => 192,
MessageType::MessageType_MoneroTransactionSignInputRequest => 193,
MessageType::MessageType_MoneroTransactionSignInputAck => 194,
MessageType::MessageType_MoneroTransactionFinalRequest => 195,
MessageType::MessageType_MoneroTransactionFinalAck => 196,
MessageType::MessageType_MoneroKeyImageExportInitRequest => 197,
MessageType::MessageType_MoneroKeyImageExportInitAck => 198,
MessageType::MessageType_MoneroKeyImageSyncStepRequest => 199,
MessageType::MessageType_MoneroKeyImageSyncStepAck => 200,
MessageType::MessageType_MoneroKeyImageSyncFinalRequest => 201,
MessageType::MessageType_MoneroKeyImageSyncFinalAck => 202,
MessageType::MessageType_MoneroGetAddress => 203,
MessageType::MessageType_MoneroAddress => 204,
MessageType::MessageType_MoneroGetWatchKey => 205,
MessageType::MessageType_MoneroWatchKey => 206,
MessageType::MessageType_DebugMoneroDiagRequest => 207,
MessageType::MessageType_DebugMoneroDiagAck => 208,
MessageType::MessageType_MoneroGetTxKeyRequest => 209,
MessageType::MessageType_MoneroGetTxKeyAck => 210,
MessageType::MessageType_MoneroLiveRefreshStartRequest => 211,
MessageType::MessageType_MoneroLiveRefreshStartAck => 212,
MessageType::MessageType_MoneroLiveRefreshStepRequest => 213,
MessageType::MessageType_MoneroLiveRefreshStepAck => 214,
MessageType::MessageType_MoneroLiveRefreshFinalRequest => 215,
MessageType::MessageType_MoneroLiveRefreshFinalAck => 216,
MessageType::MessageType_EosGetPublicKey => 217,
MessageType::MessageType_EosPublicKey => 218,
MessageType::MessageType_EosSignTx => 219,
MessageType::MessageType_EosTxActionRequest => 220,
MessageType::MessageType_EosTxActionAck => 221,
MessageType::MessageType_EosSignedTx => 222,
MessageType::MessageType_BinanceGetAddress => 223,
MessageType::MessageType_BinanceAddress => 224,
MessageType::MessageType_BinanceGetPublicKey => 225,
MessageType::MessageType_BinancePublicKey => 226,
MessageType::MessageType_BinanceSignTx => 227,
MessageType::MessageType_BinanceTxRequest => 228,
MessageType::MessageType_BinanceTransferMsg => 229,
MessageType::MessageType_BinanceOrderMsg => 230,
MessageType::MessageType_BinanceCancelMsg => 231,
MessageType::MessageType_BinanceSignedTx => 232,
MessageType::MessageType_WebAuthnListResidentCredentials => 233,
MessageType::MessageType_WebAuthnCredentials => 234,
MessageType::MessageType_WebAuthnAddResidentCredential => 235,
MessageType::MessageType_WebAuthnRemoveResidentCredential => 236,
MessageType::MessageType_SolanaGetPublicKey => 237,
MessageType::MessageType_SolanaPublicKey => 238,
MessageType::MessageType_SolanaGetAddress => 239,
MessageType::MessageType_SolanaAddress => 240,
MessageType::MessageType_SolanaSignTx => 241,
MessageType::MessageType_SolanaTxSignature => 242,
MessageType::MessageType_DebugLinkFlashRead => 99,
MessageType::MessageType_DebugLinkFlashWrite => 100,
MessageType::MessageType_DebugLinkFlashErase => 101,
MessageType::MessageType_EthereumGetPublicKey => 102,
MessageType::MessageType_EthereumPublicKey => 103,
MessageType::MessageType_EthereumGetAddress => 104,
MessageType::MessageType_EthereumAddress => 105,
MessageType::MessageType_EthereumSignTx => 106,
MessageType::MessageType_EthereumSignTxEIP1559 => 107,
MessageType::MessageType_EthereumTxRequest => 108,
MessageType::MessageType_EthereumTxAck => 109,
MessageType::MessageType_EthereumSignMessage => 110,
MessageType::MessageType_EthereumVerifyMessage => 111,
MessageType::MessageType_EthereumMessageSignature => 112,
MessageType::MessageType_EthereumSignTypedData => 113,
MessageType::MessageType_EthereumTypedDataStructRequest => 114,
MessageType::MessageType_EthereumTypedDataStructAck => 115,
MessageType::MessageType_EthereumTypedDataValueRequest => 116,
MessageType::MessageType_EthereumTypedDataValueAck => 117,
MessageType::MessageType_EthereumTypedDataSignature => 118,
MessageType::MessageType_EthereumSignTypedHash => 119,
MessageType::MessageType_NEMGetAddress => 120,
MessageType::MessageType_NEMAddress => 121,
MessageType::MessageType_NEMSignTx => 122,
MessageType::MessageType_NEMSignedTx => 123,
MessageType::MessageType_NEMDecryptMessage => 124,
MessageType::MessageType_NEMDecryptedMessage => 125,
MessageType::MessageType_TezosGetAddress => 126,
MessageType::MessageType_TezosAddress => 127,
MessageType::MessageType_TezosSignTx => 128,
MessageType::MessageType_TezosSignedTx => 129,
MessageType::MessageType_TezosGetPublicKey => 130,
MessageType::MessageType_TezosPublicKey => 131,
MessageType::MessageType_StellarSignTx => 132,
MessageType::MessageType_StellarTxOpRequest => 133,
MessageType::MessageType_StellarGetAddress => 134,
MessageType::MessageType_StellarAddress => 135,
MessageType::MessageType_StellarCreateAccountOp => 136,
MessageType::MessageType_StellarPaymentOp => 137,
MessageType::MessageType_StellarPathPaymentStrictReceiveOp => 138,
MessageType::MessageType_StellarManageSellOfferOp => 139,
MessageType::MessageType_StellarCreatePassiveSellOfferOp => 140,
MessageType::MessageType_StellarSetOptionsOp => 141,
MessageType::MessageType_StellarChangeTrustOp => 142,
MessageType::MessageType_StellarAllowTrustOp => 143,
MessageType::MessageType_StellarAccountMergeOp => 144,
MessageType::MessageType_StellarManageDataOp => 145,
MessageType::MessageType_StellarBumpSequenceOp => 146,
MessageType::MessageType_StellarManageBuyOfferOp => 147,
MessageType::MessageType_StellarPathPaymentStrictSendOp => 148,
MessageType::MessageType_StellarClaimClaimableBalanceOp => 149,
MessageType::MessageType_StellarSignedTx => 150,
MessageType::MessageType_CardanoGetPublicKey => 151,
MessageType::MessageType_CardanoPublicKey => 152,
MessageType::MessageType_CardanoGetAddress => 153,
MessageType::MessageType_CardanoAddress => 154,
MessageType::MessageType_CardanoTxItemAck => 155,
MessageType::MessageType_CardanoTxAuxiliaryDataSupplement => 156,
MessageType::MessageType_CardanoTxWitnessRequest => 157,
MessageType::MessageType_CardanoTxWitnessResponse => 158,
MessageType::MessageType_CardanoTxHostAck => 159,
MessageType::MessageType_CardanoTxBodyHash => 160,
MessageType::MessageType_CardanoSignTxFinished => 161,
MessageType::MessageType_CardanoSignTxInit => 162,
MessageType::MessageType_CardanoTxInput => 163,
MessageType::MessageType_CardanoTxOutput => 164,
MessageType::MessageType_CardanoAssetGroup => 165,
MessageType::MessageType_CardanoToken => 166,
MessageType::MessageType_CardanoTxCertificate => 167,
MessageType::MessageType_CardanoTxWithdrawal => 168,
MessageType::MessageType_CardanoTxAuxiliaryData => 169,
MessageType::MessageType_CardanoPoolOwner => 170,
MessageType::MessageType_CardanoPoolRelayParameters => 171,
MessageType::MessageType_CardanoGetNativeScriptHash => 172,
MessageType::MessageType_CardanoNativeScriptHash => 173,
MessageType::MessageType_CardanoTxMint => 174,
MessageType::MessageType_CardanoTxCollateralInput => 175,
MessageType::MessageType_CardanoTxRequiredSigner => 176,
MessageType::MessageType_CardanoTxInlineDatumChunk => 177,
MessageType::MessageType_CardanoTxReferenceScriptChunk => 178,
MessageType::MessageType_CardanoTxReferenceInput => 179,
MessageType::MessageType_RippleGetAddress => 180,
MessageType::MessageType_RippleAddress => 181,
MessageType::MessageType_RippleSignTx => 182,
MessageType::MessageType_RippleSignedTx => 183,
MessageType::MessageType_MoneroTransactionInitRequest => 184,
MessageType::MessageType_MoneroTransactionInitAck => 185,
MessageType::MessageType_MoneroTransactionSetInputRequest => 186,
MessageType::MessageType_MoneroTransactionSetInputAck => 187,
MessageType::MessageType_MoneroTransactionInputViniRequest => 188,
MessageType::MessageType_MoneroTransactionInputViniAck => 189,
MessageType::MessageType_MoneroTransactionAllInputsSetRequest => 190,
MessageType::MessageType_MoneroTransactionAllInputsSetAck => 191,
MessageType::MessageType_MoneroTransactionSetOutputRequest => 192,
MessageType::MessageType_MoneroTransactionSetOutputAck => 193,
MessageType::MessageType_MoneroTransactionAllOutSetRequest => 194,
MessageType::MessageType_MoneroTransactionAllOutSetAck => 195,
MessageType::MessageType_MoneroTransactionSignInputRequest => 196,
MessageType::MessageType_MoneroTransactionSignInputAck => 197,
MessageType::MessageType_MoneroTransactionFinalRequest => 198,
MessageType::MessageType_MoneroTransactionFinalAck => 199,
MessageType::MessageType_MoneroKeyImageExportInitRequest => 200,
MessageType::MessageType_MoneroKeyImageExportInitAck => 201,
MessageType::MessageType_MoneroKeyImageSyncStepRequest => 202,
MessageType::MessageType_MoneroKeyImageSyncStepAck => 203,
MessageType::MessageType_MoneroKeyImageSyncFinalRequest => 204,
MessageType::MessageType_MoneroKeyImageSyncFinalAck => 205,
MessageType::MessageType_MoneroGetAddress => 206,
MessageType::MessageType_MoneroAddress => 207,
MessageType::MessageType_MoneroGetWatchKey => 208,
MessageType::MessageType_MoneroWatchKey => 209,
MessageType::MessageType_DebugMoneroDiagRequest => 210,
MessageType::MessageType_DebugMoneroDiagAck => 211,
MessageType::MessageType_MoneroGetTxKeyRequest => 212,
MessageType::MessageType_MoneroGetTxKeyAck => 213,
MessageType::MessageType_MoneroLiveRefreshStartRequest => 214,
MessageType::MessageType_MoneroLiveRefreshStartAck => 215,
MessageType::MessageType_MoneroLiveRefreshStepRequest => 216,
MessageType::MessageType_MoneroLiveRefreshStepAck => 217,
MessageType::MessageType_MoneroLiveRefreshFinalRequest => 218,
MessageType::MessageType_MoneroLiveRefreshFinalAck => 219,
MessageType::MessageType_EosGetPublicKey => 220,
MessageType::MessageType_EosPublicKey => 221,
MessageType::MessageType_EosSignTx => 222,
MessageType::MessageType_EosTxActionRequest => 223,
MessageType::MessageType_EosTxActionAck => 224,
MessageType::MessageType_EosSignedTx => 225,
MessageType::MessageType_BinanceGetAddress => 226,
MessageType::MessageType_BinanceAddress => 227,
MessageType::MessageType_BinanceGetPublicKey => 228,
MessageType::MessageType_BinancePublicKey => 229,
MessageType::MessageType_BinanceSignTx => 230,
MessageType::MessageType_BinanceTxRequest => 231,
MessageType::MessageType_BinanceTransferMsg => 232,
MessageType::MessageType_BinanceOrderMsg => 233,
MessageType::MessageType_BinanceCancelMsg => 234,
MessageType::MessageType_BinanceSignedTx => 235,
MessageType::MessageType_WebAuthnListResidentCredentials => 236,
MessageType::MessageType_WebAuthnCredentials => 237,
MessageType::MessageType_WebAuthnAddResidentCredential => 238,
MessageType::MessageType_WebAuthnRemoveResidentCredential => 239,
MessageType::MessageType_SolanaGetPublicKey => 240,
MessageType::MessageType_SolanaPublicKey => 241,
MessageType::MessageType_SolanaGetAddress => 242,
MessageType::MessageType_SolanaAddress => 243,
MessageType::MessageType_SolanaSignTx => 244,
MessageType::MessageType_SolanaTxSignature => 245,
};
Self::enum_descriptor().value_by_index(index)
}
@ -1568,7 +1586,7 @@ pub mod exts {
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x0emessages.proto\x12\x12hw.trezor.messages\x1a\x20google/protobuf/de\
scriptor.proto*\x9aT\n\x0bMessageType\x12(\n\x16MessageType_Initialize\
scriptor.proto*\xb5U\n\x0bMessageType\x12(\n\x16MessageType_Initialize\
\x10\0\x1a\x0c\x80\xa6\x1d\x01\xb0\xb5\x18\x01\x90\xb5\x18\x01\x12\x1e\n\
\x10MessageType_Ping\x10\x01\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12\
%\n\x13MessageType_Success\x10\x02\x1a\x0c\x80\xa6\x1d\x01\xa8\xb5\x18\
@ -1673,27 +1691,31 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x1d\x01\xb0\xb5\x18\x01\xa0\xb5\x18\x01\x12(\n\x1aMessageType_DebugLink\
State\x10f\x1a\x08\x80\xa6\x1d\x01\xa8\xb5\x18\x01\x12'\n\x19MessageType\
_DebugLinkStop\x10g\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12&\n\x18Me\
ssageType_DebugLinkLog\x10h\x1a\x08\x80\xa6\x1d\x01\xa8\xb5\x18\x01\x12-\
\n\x1fMessageType_DebugLinkMemoryRead\x10n\x1a\x08\x80\xa6\x1d\x01\xa0\
\xb5\x18\x01\x12)\n\x1bMessageType_DebugLinkMemory\x10o\x1a\x08\x80\xa6\
\x1d\x01\xa8\xb5\x18\x01\x12.\n\x20MessageType_DebugLinkMemoryWrite\x10p\
\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12-\n\x1fMessageType_DebugLink\
FlashErase\x10q\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12*\n\x1bMessag\
eType_DebugLinkLayout\x10\xa9F\x1a\x08\x80\xa6\x1d\x01\xa8\xb5\x18\x01\
\x120\n!MessageType_DebugLinkReseedRandom\x10\xaaF\x1a\x08\x80\xa6\x1d\
\x01\xa0\xb5\x18\x01\x120\n!MessageType_DebugLinkRecordScreen\x10\xabF\
\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12/\n\x20MessageType_DebugLink\
EraseSdCard\x10\xadF\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12/\n\x20M\
essageType_DebugLinkWatchLayout\x10\xaeF\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\
\x18\x01\x124\n%MessageType_DebugLinkResetDebugEvents\x10\xafF\x1a\x08\
\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12+\n\x20MessageType_EthereumGetPublic\
Key\x10\xc2\x03\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_EthereumPu\
blicKey\x10\xc3\x03\x1a\x04\x98\xb5\x18\x01\x12(\n\x1eMessageType_Ethere\
umGetAddress\x108\x1a\x04\x90\xb5\x18\x01\x12%\n\x1bMessageType_Ethereum\
Address\x109\x1a\x04\x98\xb5\x18\x01\x12$\n\x1aMessageType_EthereumSignT\
x\x10:\x1a\x04\x90\xb5\x18\x01\x12,\n!MessageType_EthereumSignTxEIP1559\
\x10\xc4\x03\x1a\x04\x90\xb5\x18\x01\x12'\n\x1dMessageType_EthereumTxReq\
uest\x10;\x1a\x04\x98\xb5\x18\x01\x12#\n\x19MessageType_EthereumTxAck\
ssageType_DebugLinkLog\x10h\x1a\x08\x80\xa6\x1d\x01\xa8\xb5\x18\x01\x12/\
\n\x1fMessageType_DebugLinkMemoryRead\x10n\x1a\n\x08\x01\x80\xa6\x1d\x01\
\xa0\xb5\x18\x01\x12)\n\x1bMessageType_DebugLinkMemory\x10o\x1a\x08\x80\
\xa6\x1d\x01\xa8\xb5\x18\x01\x120\n\x20MessageType_DebugLinkMemoryWrite\
\x10p\x1a\n\x08\x01\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x125\n%MessageType_D\
ebugLinkFlashEraseLegacy\x10q\x1a\n\x08\x01\x80\xa6\x1d\x01\xa0\xb5\x18\
\x01\x12*\n\x1bMessageType_DebugLinkLayout\x10\xa9F\x1a\x08\x80\xa6\x1d\
\x01\xa8\xb5\x18\x01\x120\n!MessageType_DebugLinkReseedRandom\x10\xaaF\
\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x120\n!MessageType_DebugLinkRec\
ordScreen\x10\xabF\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12/\n\x20Mes\
sageType_DebugLinkEraseSdCard\x10\xadF\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\
\x18\x01\x12/\n\x20MessageType_DebugLinkWatchLayout\x10\xaeF\x1a\x08\x80\
\xa6\x1d\x01\xa0\xb5\x18\x01\x124\n%MessageType_DebugLinkResetDebugEvent\
s\x10\xafF\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12-\n\x1eMessageType\
_DebugLinkFlashRead\x10\xb0F\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12\
.\n\x1fMessageType_DebugLinkFlashWrite\x10\xb1F\x1a\x08\x80\xa6\x1d\x01\
\xa0\xb5\x18\x01\x12.\n\x1fMessageType_DebugLinkFlashErase\x10\xb2F\x1a\
\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12+\n\x20MessageType_EthereumGetPu\
blicKey\x10\xc2\x03\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_Ethere\
umPublicKey\x10\xc3\x03\x1a\x04\x98\xb5\x18\x01\x12(\n\x1eMessageType_Et\
hereumGetAddress\x108\x1a\x04\x90\xb5\x18\x01\x12%\n\x1bMessageType_Ethe\
reumAddress\x109\x1a\x04\x98\xb5\x18\x01\x12$\n\x1aMessageType_EthereumS\
ignTx\x10:\x1a\x04\x90\xb5\x18\x01\x12,\n!MessageType_EthereumSignTxEIP1\
559\x10\xc4\x03\x1a\x04\x90\xb5\x18\x01\x12'\n\x1dMessageType_EthereumTx\
Request\x10;\x1a\x04\x98\xb5\x18\x01\x12#\n\x19MessageType_EthereumTxAck\
\x10<\x1a\x04\x90\xb5\x18\x01\x12)\n\x1fMessageType_EthereumSignMessage\
\x10@\x1a\x04\x90\xb5\x18\x01\x12+\n!MessageType_EthereumVerifyMessage\
\x10A\x1a\x04\x90\xb5\x18\x01\x12.\n$MessageType_EthereumMessageSignatur\

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save