mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-08-02 11:58:32 +00:00
test(core/sdbackup): reset, recovery
- BIP39 recovery test (MNEMONIC12 backup block written directly to mocked SD card) - BIP39 reset-recovery test - 3-of-5 shamir reset-recovery test - WIP: InputFlows will be updated and polished with UX improvements later
This commit is contained in:
parent
a0ef80baeb
commit
144a4e812d
@ -190,9 +190,14 @@ message DebugLinkEraseSdCard {
|
|||||||
* @next Success
|
* @next Success
|
||||||
*/
|
*/
|
||||||
message DebugLinkInsertSdCard {
|
message DebugLinkInsertSdCard {
|
||||||
optional uint32 serial_number = 1; // mocked serial number of the card (e.g.: 1, 2, 3,...)
|
optional uint32 serial_number = 1; // mocked serial number of the card (range 1-16)
|
||||||
optional uint32 capacity_bytes = 2; // capacity of the card in bytes
|
optional uint32 capacity_bytes = 2; // capacity of the mocked card in bytes
|
||||||
optional uint32 manuf_ID = 3; // mocked manufacturer ID
|
optional uint32 manuf_ID = 3; // mocked manufacturer ID
|
||||||
|
repeated DebugLinkSdCardDataBlock data_blocks = 4; // data written directly to individual memory blocks
|
||||||
|
message DebugLinkSdCardDataBlock {
|
||||||
|
required uint32 number = 1;
|
||||||
|
required bytes data = 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -205,7 +210,6 @@ message DebugLinkWatchLayout {
|
|||||||
// if false, stop.
|
// if false, stop.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request: Remove all the previous debug event state
|
* Request: Remove all the previous debug event state
|
||||||
* @start
|
* @start
|
||||||
|
@ -5,7 +5,7 @@ from typing import *
|
|||||||
def insert(
|
def insert(
|
||||||
card_sn: int,
|
card_sn: int,
|
||||||
capacity_bytes: int | None = 122_945_536,
|
capacity_bytes: int | None = 122_945_536,
|
||||||
manuf_id: int | None = 27,
|
manuf_id: int | None = 39,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Inserts SD card to the emulator.
|
Inserts SD card to the emulator.
|
||||||
|
@ -241,15 +241,14 @@ if __debug__:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
sdcard.power_on()
|
sdcard.power_on()
|
||||||
|
# trash the whole card
|
||||||
|
assert sdcard.capacity() >= sdcard.BLOCK_SIZE
|
||||||
|
empty_block = bytes([0xFF] * sdcard.BLOCK_SIZE)
|
||||||
|
for i in range(sdcard.capacity() // sdcard.BLOCK_SIZE):
|
||||||
|
sdcard.write(i, empty_block)
|
||||||
|
# make filesystem
|
||||||
if msg.format:
|
if msg.format:
|
||||||
io.fatfs.mkfs()
|
io.fatfs.mkfs()
|
||||||
else:
|
|
||||||
# trash first 1 MB of data to destroy the FAT filesystem
|
|
||||||
assert sdcard.capacity() >= 1024 * 1024
|
|
||||||
empty_block = bytes([0xFF] * sdcard.BLOCK_SIZE)
|
|
||||||
for i in range(1024 * 1024 // sdcard.BLOCK_SIZE):
|
|
||||||
sdcard.write(i, empty_block)
|
|
||||||
|
|
||||||
except OSError:
|
except OSError:
|
||||||
raise wire.ProcessError("SD card operation failed")
|
raise wire.ProcessError("SD card operation failed")
|
||||||
finally:
|
finally:
|
||||||
@ -268,6 +267,12 @@ if __debug__:
|
|||||||
capacity_bytes=msg.capacity_bytes,
|
capacity_bytes=msg.capacity_bytes,
|
||||||
manuf_id=msg.manuf_ID,
|
manuf_id=msg.manuf_ID,
|
||||||
)
|
)
|
||||||
|
if msg.data_blocks is not None:
|
||||||
|
sdcard = io.sdcard
|
||||||
|
sdcard.power_on()
|
||||||
|
for block in msg.data_blocks:
|
||||||
|
sdcard.write(block.number, block.data)
|
||||||
|
sdcard.power_off()
|
||||||
|
|
||||||
return Success()
|
return Success()
|
||||||
|
|
||||||
|
@ -2927,10 +2927,12 @@ if TYPE_CHECKING:
|
|||||||
serial_number: "int | None"
|
serial_number: "int | None"
|
||||||
capacity_bytes: "int | None"
|
capacity_bytes: "int | None"
|
||||||
manuf_ID: "int | None"
|
manuf_ID: "int | None"
|
||||||
|
data_blocks: "list[DebugLinkSdCardDataBlock]"
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
data_blocks: "list[DebugLinkSdCardDataBlock] | None" = None,
|
||||||
serial_number: "int | None" = None,
|
serial_number: "int | None" = None,
|
||||||
capacity_bytes: "int | None" = None,
|
capacity_bytes: "int | None" = None,
|
||||||
manuf_ID: "int | None" = None,
|
manuf_ID: "int | None" = None,
|
||||||
@ -2961,6 +2963,22 @@ if TYPE_CHECKING:
|
|||||||
def is_type_of(cls, msg: Any) -> TypeGuard["DebugLinkResetDebugEvents"]:
|
def is_type_of(cls, msg: Any) -> TypeGuard["DebugLinkResetDebugEvents"]:
|
||||||
return isinstance(msg, cls)
|
return isinstance(msg, cls)
|
||||||
|
|
||||||
|
class DebugLinkSdCardDataBlock(protobuf.MessageType):
|
||||||
|
number: "int"
|
||||||
|
data: "bytes"
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
number: "int",
|
||||||
|
data: "bytes",
|
||||||
|
) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_type_of(cls, msg: Any) -> TypeGuard["DebugLinkSdCardDataBlock"]:
|
||||||
|
return isinstance(msg, cls)
|
||||||
|
|
||||||
class EosGetPublicKey(protobuf.MessageType):
|
class EosGetPublicKey(protobuf.MessageType):
|
||||||
address_n: "list[int]"
|
address_n: "list[int]"
|
||||||
show_display: "bool | None"
|
show_display: "bool | None"
|
||||||
|
@ -25,7 +25,7 @@ if TYPE_CHECKING:
|
|||||||
P = ParamSpec("P")
|
P = ParamSpec("P")
|
||||||
R = TypeVar("R")
|
R = TypeVar("R")
|
||||||
|
|
||||||
SD_CARD_HOT_SWAPPABLE = False
|
SD_CARD_HOT_SWAPPABLE = True
|
||||||
|
|
||||||
|
|
||||||
class FilesystemWrapper:
|
class FilesystemWrapper:
|
||||||
|
@ -746,6 +746,7 @@ class DebugLink:
|
|||||||
serial_number: int = 1,
|
serial_number: int = 1,
|
||||||
capacity_bytes: Optional[int] = None,
|
capacity_bytes: Optional[int] = None,
|
||||||
manuf_ID: Optional[int] = None,
|
manuf_ID: Optional[int] = None,
|
||||||
|
data_blocks: Optional[List[messages.DebugLinkSdCardDataBlock]] = None,
|
||||||
) -> messages.Success:
|
) -> messages.Success:
|
||||||
if not self.model == "T":
|
if not self.model == "T":
|
||||||
raise RuntimeError("SD card not supported by this device.")
|
raise RuntimeError("SD card not supported by this device.")
|
||||||
@ -756,6 +757,7 @@ class DebugLink:
|
|||||||
serial_number=serial_number,
|
serial_number=serial_number,
|
||||||
capacity_bytes=capacity_bytes,
|
capacity_bytes=capacity_bytes,
|
||||||
manuf_ID=manuf_ID,
|
manuf_ID=manuf_ID,
|
||||||
|
data_blocks=data_blocks,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4091,15 +4091,18 @@ class DebugLinkInsertSdCard(protobuf.MessageType):
|
|||||||
1: protobuf.Field("serial_number", "uint32", repeated=False, required=False, default=None),
|
1: protobuf.Field("serial_number", "uint32", repeated=False, required=False, default=None),
|
||||||
2: protobuf.Field("capacity_bytes", "uint32", repeated=False, required=False, default=None),
|
2: protobuf.Field("capacity_bytes", "uint32", repeated=False, required=False, default=None),
|
||||||
3: protobuf.Field("manuf_ID", "uint32", repeated=False, required=False, default=None),
|
3: protobuf.Field("manuf_ID", "uint32", repeated=False, required=False, default=None),
|
||||||
|
4: protobuf.Field("data_blocks", "DebugLinkSdCardDataBlock", repeated=True, required=False, default=None),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
data_blocks: Optional[Sequence["DebugLinkSdCardDataBlock"]] = None,
|
||||||
serial_number: Optional["int"] = None,
|
serial_number: Optional["int"] = None,
|
||||||
capacity_bytes: Optional["int"] = None,
|
capacity_bytes: Optional["int"] = None,
|
||||||
manuf_ID: Optional["int"] = None,
|
manuf_ID: Optional["int"] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
self.data_blocks: Sequence["DebugLinkSdCardDataBlock"] = data_blocks if data_blocks is not None else []
|
||||||
self.serial_number = serial_number
|
self.serial_number = serial_number
|
||||||
self.capacity_bytes = capacity_bytes
|
self.capacity_bytes = capacity_bytes
|
||||||
self.manuf_ID = manuf_ID
|
self.manuf_ID = manuf_ID
|
||||||
@ -4123,6 +4126,23 @@ class DebugLinkResetDebugEvents(protobuf.MessageType):
|
|||||||
MESSAGE_WIRE_TYPE = 9008
|
MESSAGE_WIRE_TYPE = 9008
|
||||||
|
|
||||||
|
|
||||||
|
class DebugLinkSdCardDataBlock(protobuf.MessageType):
|
||||||
|
MESSAGE_WIRE_TYPE = None
|
||||||
|
FIELDS = {
|
||||||
|
1: protobuf.Field("number", "uint32", repeated=False, required=True),
|
||||||
|
2: protobuf.Field("data", "bytes", repeated=False, required=True),
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
number: "int",
|
||||||
|
data: "bytes",
|
||||||
|
) -> None:
|
||||||
|
self.number = number
|
||||||
|
self.data = data
|
||||||
|
|
||||||
|
|
||||||
class EosGetPublicKey(protobuf.MessageType):
|
class EosGetPublicKey(protobuf.MessageType):
|
||||||
MESSAGE_WIRE_TYPE = 600
|
MESSAGE_WIRE_TYPE = 600
|
||||||
FIELDS = {
|
FIELDS = {
|
||||||
|
@ -3220,6 +3220,8 @@ pub struct DebugLinkInsertSdCard {
|
|||||||
pub capacity_bytes: ::std::option::Option<u32>,
|
pub capacity_bytes: ::std::option::Option<u32>,
|
||||||
// @@protoc_insertion_point(field:hw.trezor.messages.debug.DebugLinkInsertSdCard.manuf_ID)
|
// @@protoc_insertion_point(field:hw.trezor.messages.debug.DebugLinkInsertSdCard.manuf_ID)
|
||||||
pub manuf_ID: ::std::option::Option<u32>,
|
pub manuf_ID: ::std::option::Option<u32>,
|
||||||
|
// @@protoc_insertion_point(field:hw.trezor.messages.debug.DebugLinkInsertSdCard.data_blocks)
|
||||||
|
pub data_blocks: ::std::vec::Vec<debug_link_insert_sd_card::DebugLinkSdCardDataBlock>,
|
||||||
// special fields
|
// special fields
|
||||||
// @@protoc_insertion_point(special_field:hw.trezor.messages.debug.DebugLinkInsertSdCard.special_fields)
|
// @@protoc_insertion_point(special_field:hw.trezor.messages.debug.DebugLinkInsertSdCard.special_fields)
|
||||||
pub special_fields: ::protobuf::SpecialFields,
|
pub special_fields: ::protobuf::SpecialFields,
|
||||||
@ -3294,7 +3296,7 @@ impl DebugLinkInsertSdCard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
|
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
|
||||||
let mut fields = ::std::vec::Vec::with_capacity(3);
|
let mut fields = ::std::vec::Vec::with_capacity(4);
|
||||||
let mut oneofs = ::std::vec::Vec::with_capacity(0);
|
let mut oneofs = ::std::vec::Vec::with_capacity(0);
|
||||||
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
|
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
|
||||||
"serial_number",
|
"serial_number",
|
||||||
@ -3311,6 +3313,11 @@ impl DebugLinkInsertSdCard {
|
|||||||
|m: &DebugLinkInsertSdCard| { &m.manuf_ID },
|
|m: &DebugLinkInsertSdCard| { &m.manuf_ID },
|
||||||
|m: &mut DebugLinkInsertSdCard| { &mut m.manuf_ID },
|
|m: &mut DebugLinkInsertSdCard| { &mut m.manuf_ID },
|
||||||
));
|
));
|
||||||
|
fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>(
|
||||||
|
"data_blocks",
|
||||||
|
|m: &DebugLinkInsertSdCard| { &m.data_blocks },
|
||||||
|
|m: &mut DebugLinkInsertSdCard| { &mut m.data_blocks },
|
||||||
|
));
|
||||||
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<DebugLinkInsertSdCard>(
|
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<DebugLinkInsertSdCard>(
|
||||||
"DebugLinkInsertSdCard",
|
"DebugLinkInsertSdCard",
|
||||||
fields,
|
fields,
|
||||||
@ -3323,6 +3330,11 @@ impl ::protobuf::Message for DebugLinkInsertSdCard {
|
|||||||
const NAME: &'static str = "DebugLinkInsertSdCard";
|
const NAME: &'static str = "DebugLinkInsertSdCard";
|
||||||
|
|
||||||
fn is_initialized(&self) -> bool {
|
fn is_initialized(&self) -> bool {
|
||||||
|
for v in &self.data_blocks {
|
||||||
|
if !v.is_initialized() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3338,6 +3350,9 @@ impl ::protobuf::Message for DebugLinkInsertSdCard {
|
|||||||
24 => {
|
24 => {
|
||||||
self.manuf_ID = ::std::option::Option::Some(is.read_uint32()?);
|
self.manuf_ID = ::std::option::Option::Some(is.read_uint32()?);
|
||||||
},
|
},
|
||||||
|
34 => {
|
||||||
|
self.data_blocks.push(is.read_message()?);
|
||||||
|
},
|
||||||
tag => {
|
tag => {
|
||||||
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
|
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
|
||||||
},
|
},
|
||||||
@ -3359,6 +3374,10 @@ impl ::protobuf::Message for DebugLinkInsertSdCard {
|
|||||||
if let Some(v) = self.manuf_ID {
|
if let Some(v) = self.manuf_ID {
|
||||||
my_size += ::protobuf::rt::uint32_size(3, v);
|
my_size += ::protobuf::rt::uint32_size(3, v);
|
||||||
}
|
}
|
||||||
|
for value in &self.data_blocks {
|
||||||
|
let len = value.compute_size();
|
||||||
|
my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len;
|
||||||
|
};
|
||||||
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
|
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
|
||||||
self.special_fields.cached_size().set(my_size as u32);
|
self.special_fields.cached_size().set(my_size as u32);
|
||||||
my_size
|
my_size
|
||||||
@ -3374,6 +3393,9 @@ impl ::protobuf::Message for DebugLinkInsertSdCard {
|
|||||||
if let Some(v) = self.manuf_ID {
|
if let Some(v) = self.manuf_ID {
|
||||||
os.write_uint32(3, v)?;
|
os.write_uint32(3, v)?;
|
||||||
}
|
}
|
||||||
|
for v in &self.data_blocks {
|
||||||
|
::protobuf::rt::write_message_field_with_cached_size(4, v, os)?;
|
||||||
|
};
|
||||||
os.write_unknown_fields(self.special_fields.unknown_fields())?;
|
os.write_unknown_fields(self.special_fields.unknown_fields())?;
|
||||||
::std::result::Result::Ok(())
|
::std::result::Result::Ok(())
|
||||||
}
|
}
|
||||||
@ -3394,6 +3416,7 @@ impl ::protobuf::Message for DebugLinkInsertSdCard {
|
|||||||
self.serial_number = ::std::option::Option::None;
|
self.serial_number = ::std::option::Option::None;
|
||||||
self.capacity_bytes = ::std::option::Option::None;
|
self.capacity_bytes = ::std::option::Option::None;
|
||||||
self.manuf_ID = ::std::option::Option::None;
|
self.manuf_ID = ::std::option::Option::None;
|
||||||
|
self.data_blocks.clear();
|
||||||
self.special_fields.clear();
|
self.special_fields.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3402,6 +3425,7 @@ impl ::protobuf::Message for DebugLinkInsertSdCard {
|
|||||||
serial_number: ::std::option::Option::None,
|
serial_number: ::std::option::Option::None,
|
||||||
capacity_bytes: ::std::option::Option::None,
|
capacity_bytes: ::std::option::Option::None,
|
||||||
manuf_ID: ::std::option::Option::None,
|
manuf_ID: ::std::option::Option::None,
|
||||||
|
data_blocks: ::std::vec::Vec::new(),
|
||||||
special_fields: ::protobuf::SpecialFields::new(),
|
special_fields: ::protobuf::SpecialFields::new(),
|
||||||
};
|
};
|
||||||
&instance
|
&instance
|
||||||
@ -3425,6 +3449,210 @@ impl ::protobuf::reflect::ProtobufValue for DebugLinkInsertSdCard {
|
|||||||
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
|
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Nested message and enums of message `DebugLinkInsertSdCard`
|
||||||
|
pub mod debug_link_insert_sd_card {
|
||||||
|
// @@protoc_insertion_point(message:hw.trezor.messages.debug.DebugLinkInsertSdCard.DebugLinkSdCardDataBlock)
|
||||||
|
#[derive(PartialEq,Clone,Default,Debug)]
|
||||||
|
pub struct DebugLinkSdCardDataBlock {
|
||||||
|
// message fields
|
||||||
|
// @@protoc_insertion_point(field:hw.trezor.messages.debug.DebugLinkInsertSdCard.DebugLinkSdCardDataBlock.number)
|
||||||
|
pub number: ::std::option::Option<u32>,
|
||||||
|
// @@protoc_insertion_point(field:hw.trezor.messages.debug.DebugLinkInsertSdCard.DebugLinkSdCardDataBlock.data)
|
||||||
|
pub data: ::std::option::Option<::std::vec::Vec<u8>>,
|
||||||
|
// special fields
|
||||||
|
// @@protoc_insertion_point(special_field:hw.trezor.messages.debug.DebugLinkInsertSdCard.DebugLinkSdCardDataBlock.special_fields)
|
||||||
|
pub special_fields: ::protobuf::SpecialFields,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ::std::default::Default for &'a DebugLinkSdCardDataBlock {
|
||||||
|
fn default() -> &'a DebugLinkSdCardDataBlock {
|
||||||
|
<DebugLinkSdCardDataBlock as ::protobuf::Message>::default_instance()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DebugLinkSdCardDataBlock {
|
||||||
|
pub fn new() -> DebugLinkSdCardDataBlock {
|
||||||
|
::std::default::Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
// required uint32 number = 1;
|
||||||
|
|
||||||
|
pub fn number(&self) -> u32 {
|
||||||
|
self.number.unwrap_or(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_number(&mut self) {
|
||||||
|
self.number = ::std::option::Option::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_number(&self) -> bool {
|
||||||
|
self.number.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Param is passed by value, moved
|
||||||
|
pub fn set_number(&mut self, v: u32) {
|
||||||
|
self.number = ::std::option::Option::Some(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// required bytes data = 2;
|
||||||
|
|
||||||
|
pub fn data(&self) -> &[u8] {
|
||||||
|
match self.data.as_ref() {
|
||||||
|
Some(v) => v,
|
||||||
|
None => &[],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_data(&mut self) {
|
||||||
|
self.data = ::std::option::Option::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_data(&self) -> bool {
|
||||||
|
self.data.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Param is passed by value, moved
|
||||||
|
pub fn set_data(&mut self, v: ::std::vec::Vec<u8>) {
|
||||||
|
self.data = ::std::option::Option::Some(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutable pointer to the field.
|
||||||
|
// If field is not initialized, it is initialized with default value first.
|
||||||
|
pub fn mut_data(&mut self) -> &mut ::std::vec::Vec<u8> {
|
||||||
|
if self.data.is_none() {
|
||||||
|
self.data = ::std::option::Option::Some(::std::vec::Vec::new());
|
||||||
|
}
|
||||||
|
self.data.as_mut().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take field
|
||||||
|
pub fn take_data(&mut self) -> ::std::vec::Vec<u8> {
|
||||||
|
self.data.take().unwrap_or_else(|| ::std::vec::Vec::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(in super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
|
||||||
|
let mut fields = ::std::vec::Vec::with_capacity(2);
|
||||||
|
let mut oneofs = ::std::vec::Vec::with_capacity(0);
|
||||||
|
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
|
||||||
|
"number",
|
||||||
|
|m: &DebugLinkSdCardDataBlock| { &m.number },
|
||||||
|
|m: &mut DebugLinkSdCardDataBlock| { &mut m.number },
|
||||||
|
));
|
||||||
|
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
|
||||||
|
"data",
|
||||||
|
|m: &DebugLinkSdCardDataBlock| { &m.data },
|
||||||
|
|m: &mut DebugLinkSdCardDataBlock| { &mut m.data },
|
||||||
|
));
|
||||||
|
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<DebugLinkSdCardDataBlock>(
|
||||||
|
"DebugLinkInsertSdCard.DebugLinkSdCardDataBlock",
|
||||||
|
fields,
|
||||||
|
oneofs,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::Message for DebugLinkSdCardDataBlock {
|
||||||
|
const NAME: &'static str = "DebugLinkSdCardDataBlock";
|
||||||
|
|
||||||
|
fn is_initialized(&self) -> bool {
|
||||||
|
if self.number.is_none() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if self.data.is_none() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> {
|
||||||
|
while let Some(tag) = is.read_raw_tag_or_eof()? {
|
||||||
|
match tag {
|
||||||
|
8 => {
|
||||||
|
self.number = ::std::option::Option::Some(is.read_uint32()?);
|
||||||
|
},
|
||||||
|
18 => {
|
||||||
|
self.data = ::std::option::Option::Some(is.read_bytes()?);
|
||||||
|
},
|
||||||
|
tag => {
|
||||||
|
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
::std::result::Result::Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute sizes of nested messages
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
fn compute_size(&self) -> u64 {
|
||||||
|
let mut my_size = 0;
|
||||||
|
if let Some(v) = self.number {
|
||||||
|
my_size += ::protobuf::rt::uint32_size(1, v);
|
||||||
|
}
|
||||||
|
if let Some(v) = self.data.as_ref() {
|
||||||
|
my_size += ::protobuf::rt::bytes_size(2, &v);
|
||||||
|
}
|
||||||
|
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
|
||||||
|
self.special_fields.cached_size().set(my_size as u32);
|
||||||
|
my_size
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> {
|
||||||
|
if let Some(v) = self.number {
|
||||||
|
os.write_uint32(1, v)?;
|
||||||
|
}
|
||||||
|
if let Some(v) = self.data.as_ref() {
|
||||||
|
os.write_bytes(2, v)?;
|
||||||
|
}
|
||||||
|
os.write_unknown_fields(self.special_fields.unknown_fields())?;
|
||||||
|
::std::result::Result::Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn special_fields(&self) -> &::protobuf::SpecialFields {
|
||||||
|
&self.special_fields
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields {
|
||||||
|
&mut self.special_fields
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new() -> DebugLinkSdCardDataBlock {
|
||||||
|
DebugLinkSdCardDataBlock::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear(&mut self) {
|
||||||
|
self.number = ::std::option::Option::None;
|
||||||
|
self.data = ::std::option::Option::None;
|
||||||
|
self.special_fields.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_instance() -> &'static DebugLinkSdCardDataBlock {
|
||||||
|
static instance: DebugLinkSdCardDataBlock = DebugLinkSdCardDataBlock {
|
||||||
|
number: ::std::option::Option::None,
|
||||||
|
data: ::std::option::Option::None,
|
||||||
|
special_fields: ::protobuf::SpecialFields::new(),
|
||||||
|
};
|
||||||
|
&instance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::MessageFull for DebugLinkSdCardDataBlock {
|
||||||
|
fn descriptor() -> ::protobuf::reflect::MessageDescriptor {
|
||||||
|
static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new();
|
||||||
|
descriptor.get(|| super::file_descriptor().message_by_package_relative_name("DebugLinkInsertSdCard.DebugLinkSdCardDataBlock").unwrap()).clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::std::fmt::Display for DebugLinkSdCardDataBlock {
|
||||||
|
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||||
|
::protobuf::text_format::fmt(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::reflect::ProtobufValue for DebugLinkSdCardDataBlock {
|
||||||
|
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// @@protoc_insertion_point(message:hw.trezor.messages.debug.DebugLinkWatchLayout)
|
// @@protoc_insertion_point(message:hw.trezor.messages.debug.DebugLinkWatchLayout)
|
||||||
#[derive(PartialEq,Clone,Default,Debug)]
|
#[derive(PartialEq,Clone,Default,Debug)]
|
||||||
pub struct DebugLinkWatchLayout {
|
pub struct DebugLinkWatchLayout {
|
||||||
@ -3714,13 +3942,17 @@ static file_descriptor_proto_data: &'static [u8] = b"\
|
|||||||
\x01(\rR\x07address\x12\x16\n\x06memory\x18\x02\x20\x01(\x0cR\x06memory\
|
\x01(\rR\x07address\x12\x16\n\x06memory\x18\x02\x20\x01(\x0cR\x06memory\
|
||||||
\x12\x14\n\x05flash\x18\x03\x20\x01(\x08R\x05flash\"-\n\x13DebugLinkFlas\
|
\x12\x14\n\x05flash\x18\x03\x20\x01(\x08R\x05flash\"-\n\x13DebugLinkFlas\
|
||||||
hErase\x12\x16\n\x06sector\x18\x01\x20\x01(\rR\x06sector\".\n\x14DebugLi\
|
hErase\x12\x16\n\x06sector\x18\x01\x20\x01(\rR\x06sector\".\n\x14DebugLi\
|
||||||
nkEraseSdCard\x12\x16\n\x06format\x18\x01\x20\x01(\x08R\x06format\"~\n\
|
nkEraseSdCard\x12\x16\n\x06format\x18\x01\x20\x01(\x08R\x06format\"\xb1\
|
||||||
\x15DebugLinkInsertSdCard\x12#\n\rserial_number\x18\x01\x20\x01(\rR\x0cs\
|
\x02\n\x15DebugLinkInsertSdCard\x12#\n\rserial_number\x18\x01\x20\x01(\r\
|
||||||
erialNumber\x12%\n\x0ecapacity_bytes\x18\x02\x20\x01(\rR\rcapacityBytes\
|
R\x0cserialNumber\x12%\n\x0ecapacity_bytes\x18\x02\x20\x01(\rR\rcapacity\
|
||||||
\x12\x19\n\x08manuf_ID\x18\x03\x20\x01(\rR\x07manufID\",\n\x14DebugLinkW\
|
Bytes\x12\x19\n\x08manuf_ID\x18\x03\x20\x01(\rR\x07manufID\x12i\n\x0bdat\
|
||||||
atchLayout\x12\x14\n\x05watch\x18\x01\x20\x01(\x08R\x05watch\"\x1b\n\x19\
|
a_blocks\x18\x04\x20\x03(\x0b2H.hw.trezor.messages.debug.DebugLinkInsert\
|
||||||
DebugLinkResetDebugEventsB=\n#com.satoshilabs.trezor.lib.protobufB\x12Tr\
|
SdCard.DebugLinkSdCardDataBlockR\ndataBlocks\x1aF\n\x18DebugLinkSdCardDa\
|
||||||
ezorMessageDebug\x80\xa6\x1d\x01\
|
taBlock\x12\x16\n\x06number\x18\x01\x20\x02(\rR\x06number\x12\x12\n\x04d\
|
||||||
|
ata\x18\x02\x20\x02(\x0cR\x04data\",\n\x14DebugLinkWatchLayout\x12\x14\n\
|
||||||
|
\x05watch\x18\x01\x20\x01(\x08R\x05watch\"\x1b\n\x19DebugLinkResetDebugE\
|
||||||
|
ventsB=\n#com.satoshilabs.trezor.lib.protobufB\x12TrezorMessageDebug\x80\
|
||||||
|
\xa6\x1d\x01\
|
||||||
";
|
";
|
||||||
|
|
||||||
/// `FileDescriptorProto` object which was a source for this generated file
|
/// `FileDescriptorProto` object which was a source for this generated file
|
||||||
@ -3741,7 +3973,7 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor {
|
|||||||
deps.push(super::messages::file_descriptor().clone());
|
deps.push(super::messages::file_descriptor().clone());
|
||||||
deps.push(super::messages_common::file_descriptor().clone());
|
deps.push(super::messages_common::file_descriptor().clone());
|
||||||
deps.push(super::messages_management::file_descriptor().clone());
|
deps.push(super::messages_management::file_descriptor().clone());
|
||||||
let mut messages = ::std::vec::Vec::with_capacity(16);
|
let mut messages = ::std::vec::Vec::with_capacity(17);
|
||||||
messages.push(DebugLinkDecision::generated_message_descriptor_data());
|
messages.push(DebugLinkDecision::generated_message_descriptor_data());
|
||||||
messages.push(DebugLinkLayout::generated_message_descriptor_data());
|
messages.push(DebugLinkLayout::generated_message_descriptor_data());
|
||||||
messages.push(DebugLinkReseedRandom::generated_message_descriptor_data());
|
messages.push(DebugLinkReseedRandom::generated_message_descriptor_data());
|
||||||
@ -3758,6 +3990,7 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor {
|
|||||||
messages.push(DebugLinkInsertSdCard::generated_message_descriptor_data());
|
messages.push(DebugLinkInsertSdCard::generated_message_descriptor_data());
|
||||||
messages.push(DebugLinkWatchLayout::generated_message_descriptor_data());
|
messages.push(DebugLinkWatchLayout::generated_message_descriptor_data());
|
||||||
messages.push(DebugLinkResetDebugEvents::generated_message_descriptor_data());
|
messages.push(DebugLinkResetDebugEvents::generated_message_descriptor_data());
|
||||||
|
messages.push(debug_link_insert_sd_card::DebugLinkSdCardDataBlock::generated_message_descriptor_data());
|
||||||
let mut enums = ::std::vec::Vec::with_capacity(3);
|
let mut enums = ::std::vec::Vec::with_capacity(3);
|
||||||
enums.push(debug_link_decision::DebugSwipeDirection::generated_enum_descriptor_data());
|
enums.push(debug_link_decision::DebugSwipeDirection::generated_enum_descriptor_data());
|
||||||
enums.push(debug_link_decision::DebugButton::generated_enum_descriptor_data());
|
enums.push(debug_link_decision::DebugButton::generated_enum_descriptor_data());
|
||||||
|
@ -215,6 +215,7 @@ def client(
|
|||||||
# we need to reseed before the wipe
|
# we need to reseed before the wipe
|
||||||
_raw_client.debug.reseed(0)
|
_raw_client.debug.reseed(0)
|
||||||
|
|
||||||
|
# Insert SD card if needed
|
||||||
sd_marker = request.node.get_closest_marker("sd_card")
|
sd_marker = request.node.get_closest_marker("sd_card")
|
||||||
if sd_marker:
|
if sd_marker:
|
||||||
_raw_client.debug.insert_sd_card(1)
|
_raw_client.debug.insert_sd_card(1)
|
||||||
|
@ -1,34 +1,44 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from trezorlib import device
|
from trezorlib import device, messages
|
||||||
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||||
from trezorlib.messages import BackupType
|
from trezorlib.messages import BackupType
|
||||||
|
|
||||||
|
from ...common import MNEMONIC12
|
||||||
|
from ...input_flows import InputFlowBip39RecoverySdCard
|
||||||
|
|
||||||
pytestmark = [pytest.mark.skip_t1, pytest.mark.skip_tr]
|
pytestmark = [pytest.mark.skip_t1, pytest.mark.skip_tr]
|
||||||
|
|
||||||
|
|
||||||
|
def prepare_data_for_sdcard() -> bytes:
|
||||||
|
# MNEMONIC12 backup block
|
||||||
|
backup_block_str = "54525A4D000000004C616C636F686F6C20776F6D616E206162757365206D75737420647572696E67206D6F6E69746F72206E6F626C652061637475616C206D6978656420747261646520616E676572206169736C654B1118DAD99C3A21E85AC1CBAE3D41F8BA02BE5E6B8422B3225C9DB53C316D8A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
return bytes.fromhex(backup_block_str)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.setup_client(uninitialized=True)
|
@pytest.mark.setup_client(uninitialized=True)
|
||||||
@pytest.mark.sd_card(formatted=False)
|
@pytest.mark.sd_card(formatted=False)
|
||||||
def test_sd_backup_end_to_end(client: Client):
|
def test_sdrecover_tt_nopin_nopassphrase(client: Client):
|
||||||
with client:
|
with client:
|
||||||
device.reset(client, pin_protection=False, label="SD card")
|
# put seed writing directly to the first backup block
|
||||||
|
mnemonic_data_bytes = prepare_data_for_sdcard()
|
||||||
|
backup_block = messages.DebugLinkSdCardDataBlock(
|
||||||
|
number=65525 + 552 + 63, data=mnemonic_data_bytes
|
||||||
|
)
|
||||||
|
client.debug.insert_sd_card(serial_number=1, data_blocks=[backup_block])
|
||||||
|
|
||||||
assert client.features.initialized is True
|
IF = InputFlowBip39RecoverySdCard(client)
|
||||||
assert client.features.needs_backup is False
|
client.set_input_flow(IF.get())
|
||||||
assert client.features.unfinished_backup is False
|
device.recover(
|
||||||
assert client.features.no_backup is False
|
client,
|
||||||
assert client.features.backup_type is BackupType.Bip39
|
pin_protection=False,
|
||||||
|
passphrase_protection=False,
|
||||||
|
label="SD recovery",
|
||||||
|
)
|
||||||
|
|
||||||
with client:
|
assert client.debug.state().mnemonic_secret.decode() == MNEMONIC12
|
||||||
device.wipe(client)
|
|
||||||
|
|
||||||
# assert client.features.initialized is False
|
assert client.features.pin_protection is False
|
||||||
# assert client.features.no_backup is True
|
assert client.features.passphrase_protection is False
|
||||||
|
assert client.features.backup_type is messages.BackupType.Bip39
|
||||||
with client:
|
assert client.features.label == "SD recovery"
|
||||||
device.recover(client, pin_protection=False)
|
|
||||||
|
|
||||||
state = client.debug.state()
|
|
||||||
print(f"mnemonic is {state.mnemonic_secret}")
|
|
||||||
# assert state.mnemonic_type is backup_type
|
|
||||||
# assert state.mnemonic_secret == secret
|
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from trezorlib import btc, device, messages
|
||||||
|
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||||
|
from trezorlib.messages import BackupType
|
||||||
|
from trezorlib.tools import parse_path
|
||||||
|
|
||||||
|
from ...common import WITH_MOCK_URANDOM
|
||||||
|
from ...input_flows import InputFlowBip39RecoverySdCard, InputFlowBip39ResetBackupSdCard
|
||||||
|
|
||||||
|
pytestmark = [pytest.mark.skip_t1, pytest.mark.skip_tr]
|
||||||
|
|
||||||
|
# NOTE: Test adapted from test_reset_recovery_bip39.py
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.setup_client(uninitialized=True)
|
||||||
|
@pytest.mark.sd_card(formatted=False)
|
||||||
|
def test_reset_recovery_sdcard(client: Client):
|
||||||
|
reset(client)
|
||||||
|
address_before = btc.get_address(client, "Bitcoin", parse_path("m/44h/0h/0h/0/0"))
|
||||||
|
|
||||||
|
device.wipe(client)
|
||||||
|
recover(client)
|
||||||
|
address_after = btc.get_address(client, "Bitcoin", parse_path("m/44h/0h/0h/0/0"))
|
||||||
|
assert address_before == address_after
|
||||||
|
|
||||||
|
|
||||||
|
def reset(client: Client, strength: int = 128, skip_backup: bool = False) -> None:
|
||||||
|
with WITH_MOCK_URANDOM, client:
|
||||||
|
IF = InputFlowBip39ResetBackupSdCard(client)
|
||||||
|
client.set_input_flow(IF.get())
|
||||||
|
|
||||||
|
# No PIN, no passphrase, don't display random
|
||||||
|
device.reset(
|
||||||
|
client,
|
||||||
|
display_random=False,
|
||||||
|
strength=strength,
|
||||||
|
passphrase_protection=False,
|
||||||
|
pin_protection=False,
|
||||||
|
label="test",
|
||||||
|
language="en-US",
|
||||||
|
backup_type=BackupType.Bip39,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check if device is properly initialized
|
||||||
|
assert client.features.initialized is True
|
||||||
|
assert client.features.needs_backup is False
|
||||||
|
assert client.features.pin_protection is False
|
||||||
|
assert client.features.passphrase_protection is False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def recover(client: Client):
|
||||||
|
with client:
|
||||||
|
IF = InputFlowBip39RecoverySdCard(client)
|
||||||
|
client.set_input_flow(IF.get())
|
||||||
|
client.watch_layout()
|
||||||
|
ret = device.recover(client, pin_protection=False, label="label")
|
||||||
|
|
||||||
|
# Workflow successfully ended
|
||||||
|
assert ret == messages.Success(message="Device recovered")
|
||||||
|
assert client.features.pin_protection is False
|
||||||
|
assert client.features.passphrase_protection is False
|
@ -0,0 +1,70 @@
|
|||||||
|
import itertools
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from trezorlib import btc, device, messages
|
||||||
|
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||||
|
from trezorlib.messages import BackupType
|
||||||
|
from trezorlib.tools import parse_path
|
||||||
|
|
||||||
|
from ...common import WITH_MOCK_URANDOM
|
||||||
|
from ...input_flows import (
|
||||||
|
InputFlowSlip39BasicRecoverySdCard,
|
||||||
|
InputFlowSlip39BasicResetRecoverySdCard,
|
||||||
|
)
|
||||||
|
|
||||||
|
# NOTE: Test adapted from test_reset_recovery_slip39_basic.py
|
||||||
|
|
||||||
|
pytestmark = [pytest.mark.skip_t1, pytest.mark.skip_tr]
|
||||||
|
sdcard_serial_numbers = [1, 2, 3, 4, 5]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.setup_client(uninitialized=True)
|
||||||
|
@WITH_MOCK_URANDOM
|
||||||
|
def test_reset_recovery(client: Client):
|
||||||
|
reset(client)
|
||||||
|
address_before = btc.get_address(client, "Bitcoin", parse_path("m/44h/0h/0h/0/0"))
|
||||||
|
|
||||||
|
for selected_sdcards in itertools.combinations(sdcard_serial_numbers, 3):
|
||||||
|
device.wipe(client)
|
||||||
|
recover(client, selected_sdcards)
|
||||||
|
address_after = btc.get_address(
|
||||||
|
client, "Bitcoin", parse_path("m/44h/0h/0h/0/0")
|
||||||
|
)
|
||||||
|
assert address_before == address_after
|
||||||
|
|
||||||
|
|
||||||
|
def reset(client: Client, strength: int = 128) -> list[str]:
|
||||||
|
with client:
|
||||||
|
IF = InputFlowSlip39BasicResetRecoverySdCard(client, sdcard_serial_numbers)
|
||||||
|
client.set_input_flow(IF.get())
|
||||||
|
|
||||||
|
# No PIN, no passphrase, don't display random
|
||||||
|
device.reset(
|
||||||
|
client,
|
||||||
|
display_random=False,
|
||||||
|
strength=strength,
|
||||||
|
passphrase_protection=False,
|
||||||
|
pin_protection=False,
|
||||||
|
label="test",
|
||||||
|
language="en-US",
|
||||||
|
backup_type=BackupType.Slip39_Basic,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check if device is properly initialized
|
||||||
|
assert client.features.initialized is True
|
||||||
|
assert client.features.needs_backup is False
|
||||||
|
assert client.features.pin_protection is False
|
||||||
|
assert client.features.passphrase_protection is False
|
||||||
|
|
||||||
|
|
||||||
|
def recover(client: Client, sdcards: list[int]):
|
||||||
|
with client:
|
||||||
|
IF = InputFlowSlip39BasicRecoverySdCard(client, sdcards)
|
||||||
|
client.set_input_flow(IF.get())
|
||||||
|
ret = device.recover(client, pin_protection=False, label="label")
|
||||||
|
|
||||||
|
# Workflow successfully ended
|
||||||
|
assert ret == messages.Success(message="Device recovered")
|
||||||
|
assert client.features.pin_protection is False
|
||||||
|
assert client.features.passphrase_protection is False
|
@ -7,12 +7,10 @@ pytestmark = [pytest.mark.skip_t1, pytest.mark.skip_tr]
|
|||||||
|
|
||||||
@pytest.mark.sd_card(formatted=True)
|
@pytest.mark.sd_card(formatted=True)
|
||||||
def test_sd_eject(client: Client):
|
def test_sd_eject(client: Client):
|
||||||
print(client.features)
|
|
||||||
assert client.features.sd_card_present is True
|
assert client.features.sd_card_present is True
|
||||||
|
|
||||||
client.debug.eject_sd_card()
|
client.debug.eject_sd_card()
|
||||||
client.refresh_features()
|
client.refresh_features()
|
||||||
print(client.features)
|
|
||||||
assert client.features.sd_card_present is False
|
assert client.features.sd_card_present is False
|
||||||
|
|
||||||
client.debug.insert_sd_card(2)
|
client.debug.insert_sd_card(2)
|
||||||
|
@ -913,13 +913,14 @@ class InputFlowBip39Backup(InputFlowBase):
|
|||||||
self.mnemonic = None
|
self.mnemonic = None
|
||||||
|
|
||||||
def input_flow_common(self) -> BRGeneratorType:
|
def input_flow_common(self) -> BRGeneratorType:
|
||||||
# choose Words
|
|
||||||
yield
|
|
||||||
self.debug.press_no()
|
|
||||||
|
|
||||||
# 1. Confirm Reset
|
# 1. Confirm Reset
|
||||||
yield from click_through(self.debug, screens=1, code=B.ResetDevice)
|
yield from click_through(self.debug, screens=1, code=B.ResetDevice)
|
||||||
|
|
||||||
|
# 2. Choose Words
|
||||||
|
yield
|
||||||
|
self.debug.press_no()
|
||||||
|
|
||||||
# mnemonic phrases and rest
|
# mnemonic phrases and rest
|
||||||
self.mnemonic = yield from get_mnemonic_and_confirm_success(self.debug)
|
self.mnemonic = yield from get_mnemonic_and_confirm_success(self.debug)
|
||||||
|
|
||||||
@ -935,11 +936,39 @@ class InputFlowBip39ResetBackup(InputFlowBase):
|
|||||||
# 2. Backup your seed
|
# 2. Backup your seed
|
||||||
# 3. Confirm warning
|
# 3. Confirm warning
|
||||||
yield from click_through(self.debug, screens=3, code=B.ResetDevice)
|
yield from click_through(self.debug, screens=3, code=B.ResetDevice)
|
||||||
|
# 4. Choose Words
|
||||||
|
yield
|
||||||
|
self.debug.press_no()
|
||||||
|
|
||||||
# mnemonic phrases and rest
|
# mnemonic phrases and rest
|
||||||
self.mnemonic = yield from get_mnemonic_and_confirm_success(self.debug)
|
self.mnemonic = yield from get_mnemonic_and_confirm_success(self.debug)
|
||||||
|
|
||||||
|
|
||||||
|
class InputFlowBip39ResetBackupSdCard(InputFlowBase):
|
||||||
|
def __init__(self, client: Client):
|
||||||
|
super().__init__(client)
|
||||||
|
|
||||||
|
def input_flow_common(self) -> BRGeneratorType:
|
||||||
|
|
||||||
|
# 1. Confirm Reset
|
||||||
|
yield from click_through(self.debug, screens=3, code=B.ResetDevice)
|
||||||
|
|
||||||
|
# 2. Choose SD Card
|
||||||
|
yield
|
||||||
|
self.debug.press_yes()
|
||||||
|
|
||||||
|
# 3. Go through format screens
|
||||||
|
yield from click_through(self.debug, screens=2, code=B.Other)
|
||||||
|
|
||||||
|
br = yield # confirm recovery seed check
|
||||||
|
assert br.code == B.Success
|
||||||
|
self.debug.press_yes()
|
||||||
|
|
||||||
|
br = yield # confirm success
|
||||||
|
assert br.code == B.Success
|
||||||
|
self.debug.press_yes()
|
||||||
|
|
||||||
|
|
||||||
class InputFlowBip39ResetPIN(InputFlowBase):
|
class InputFlowBip39ResetPIN(InputFlowBase):
|
||||||
def __init__(self, client: Client):
|
def __init__(self, client: Client):
|
||||||
super().__init__(client)
|
super().__init__(client)
|
||||||
@ -1014,6 +1043,9 @@ def load_5_shares(
|
|||||||
mnemonics: list[str] = []
|
mnemonics: list[str] = []
|
||||||
|
|
||||||
for _ in range(5):
|
for _ in range(5):
|
||||||
|
# Choose Words
|
||||||
|
yield
|
||||||
|
debug.press_no()
|
||||||
# Phrase screen
|
# Phrase screen
|
||||||
mnemonic = yield from read_and_confirm_mnemonic(debug)
|
mnemonic = yield from read_and_confirm_mnemonic(debug)
|
||||||
assert mnemonic is not None
|
assert mnemonic is not None
|
||||||
@ -1143,6 +1175,9 @@ def load_5_groups_5_shares(
|
|||||||
|
|
||||||
for _g in range(5):
|
for _g in range(5):
|
||||||
for _s in range(5):
|
for _s in range(5):
|
||||||
|
# Choose Words
|
||||||
|
yield
|
||||||
|
debug.press_no()
|
||||||
# Phrase screen
|
# Phrase screen
|
||||||
mnemonic = yield from read_and_confirm_mnemonic(debug)
|
mnemonic = yield from read_and_confirm_mnemonic(debug)
|
||||||
assert mnemonic is not None
|
assert mnemonic is not None
|
||||||
@ -1154,6 +1189,52 @@ def load_5_groups_5_shares(
|
|||||||
return mnemonics
|
return mnemonics
|
||||||
|
|
||||||
|
|
||||||
|
class InputFlowSlip39BasicResetRecoverySdCard(InputFlowBase):
|
||||||
|
def __init__(self, client: Client, sdcard_numbers):
|
||||||
|
super().__init__(client)
|
||||||
|
self.sdcard_numbers = sdcard_numbers
|
||||||
|
|
||||||
|
def input_flow_tt(self) -> BRGeneratorType:
|
||||||
|
# 1. Confirm Reset
|
||||||
|
# 2. Backup your seed
|
||||||
|
# 3. Confirm warning
|
||||||
|
# 4. shares info
|
||||||
|
# 5. Set & Confirm number of shares
|
||||||
|
# 6. threshold info
|
||||||
|
# 7. Set & confirm threshold value
|
||||||
|
# 8. Confirm show seeds
|
||||||
|
yield from click_through(self.debug, screens=8, code=B.ResetDevice)
|
||||||
|
|
||||||
|
# Mnemonic phrases
|
||||||
|
yield from load_5_shares_to_sdcards(self.debug, self.sdcard_numbers)
|
||||||
|
|
||||||
|
br = yield # safety warning
|
||||||
|
assert br.code == B.Success
|
||||||
|
self.debug.press_yes()
|
||||||
|
|
||||||
|
|
||||||
|
def load_5_shares_to_sdcards(debug: DebugLink, sdcard_numbers: list[int]) -> None:
|
||||||
|
for n in sdcard_numbers:
|
||||||
|
# Insert the card and erase (i.e. assume empty card)
|
||||||
|
debug.insert_sd_card(n)
|
||||||
|
debug.erase_sd_card(format=False)
|
||||||
|
|
||||||
|
# Choose SD card
|
||||||
|
yield
|
||||||
|
debug.press_yes()
|
||||||
|
|
||||||
|
# Go through format screens
|
||||||
|
yield from click_through(debug, screens=2, code=B.Other)
|
||||||
|
|
||||||
|
# Confirm continue
|
||||||
|
br = yield
|
||||||
|
assert br.code == B.Success
|
||||||
|
debug.press_yes()
|
||||||
|
|
||||||
|
# Eject the card
|
||||||
|
debug.eject_sd_card()
|
||||||
|
|
||||||
|
|
||||||
class InputFlowSlip39AdvancedBackup(InputFlowBase):
|
class InputFlowSlip39AdvancedBackup(InputFlowBase):
|
||||||
def __init__(self, client: Client, click_info: bool):
|
def __init__(self, client: Client, click_info: bool):
|
||||||
super().__init__(client)
|
super().__init__(client)
|
||||||
@ -1328,11 +1409,29 @@ class InputFlowBip39Recovery(InputFlowBase):
|
|||||||
yield from self.REC.confirm_recovery()
|
yield from self.REC.confirm_recovery()
|
||||||
if self.pin is not None:
|
if self.pin is not None:
|
||||||
yield from self.PIN.setup_new_pin(self.pin)
|
yield from self.PIN.setup_new_pin(self.pin)
|
||||||
|
# Choose Words
|
||||||
|
yield
|
||||||
|
self.debug.press_no()
|
||||||
yield from self.REC.setup_bip39_recovery(len(self.mnemonic))
|
yield from self.REC.setup_bip39_recovery(len(self.mnemonic))
|
||||||
yield from self.REC.input_mnemonic(self.mnemonic)
|
yield from self.REC.input_mnemonic(self.mnemonic)
|
||||||
yield from self.REC.success_wallet_recovered()
|
yield from self.REC.success_wallet_recovered()
|
||||||
|
|
||||||
|
|
||||||
|
class InputFlowBip39RecoverySdCard(InputFlowBase):
|
||||||
|
def __init__(self, client: Client, pin: str | None = None):
|
||||||
|
super().__init__(client)
|
||||||
|
self.pin = pin
|
||||||
|
|
||||||
|
def input_flow_common(self) -> BRGeneratorType:
|
||||||
|
yield from self.REC.confirm_recovery()
|
||||||
|
if self.pin is not None:
|
||||||
|
yield from self.PIN.setup_new_pin(self.pin)
|
||||||
|
# Choose "SD card"
|
||||||
|
yield
|
||||||
|
self.debug.press_yes()
|
||||||
|
yield from self.REC.success_wallet_recovered()
|
||||||
|
|
||||||
|
|
||||||
class InputFlowSlip39AdvancedRecoveryDryRun(InputFlowBase):
|
class InputFlowSlip39AdvancedRecoveryDryRun(InputFlowBase):
|
||||||
def __init__(self, client: Client, shares: list[str], mismatch: bool = False):
|
def __init__(self, client: Client, shares: list[str], mismatch: bool = False):
|
||||||
super().__init__(client)
|
super().__init__(client)
|
||||||
@ -1478,6 +1577,35 @@ class InputFlowSlip39BasicRecovery(InputFlowBase):
|
|||||||
yield from self.REC.success_wallet_recovered()
|
yield from self.REC.success_wallet_recovered()
|
||||||
|
|
||||||
|
|
||||||
|
class InputFlowSlip39BasicRecoverySdCard(InputFlowBase):
|
||||||
|
def __init__(self, client: Client, sdcard_numbers: list[int], pin: str | None = None):
|
||||||
|
super().__init__(client)
|
||||||
|
self.sdcard_numbers = sdcard_numbers
|
||||||
|
self.pin = pin
|
||||||
|
|
||||||
|
def input_flow_common(self) -> BRGeneratorType:
|
||||||
|
yield from self.REC.confirm_recovery()
|
||||||
|
if self.pin is not None:
|
||||||
|
yield from self.PIN.setup_new_pin(self.pin)
|
||||||
|
|
||||||
|
# "Words" counterpart:
|
||||||
|
# yield from self.REC.setup_slip39_recovery(self.word_count)
|
||||||
|
# yield from self.REC.input_all_slip39_shares(self.shares)
|
||||||
|
|
||||||
|
# choose SD card
|
||||||
|
for n in self.sdcard_numbers:
|
||||||
|
self.debug.eject_sd_card()
|
||||||
|
self.debug.insert_sd_card(n)
|
||||||
|
# choose SD card
|
||||||
|
yield
|
||||||
|
self.debug.press_yes()
|
||||||
|
# enter next share
|
||||||
|
yield
|
||||||
|
self.debug.press_yes()
|
||||||
|
|
||||||
|
yield from self.REC.success_wallet_recovered()
|
||||||
|
|
||||||
|
|
||||||
class InputFlowSlip39BasicRecoveryAbort(InputFlowBase):
|
class InputFlowSlip39BasicRecoveryAbort(InputFlowBase):
|
||||||
def __init__(self, client: Client):
|
def __init__(self, client: Client):
|
||||||
super().__init__(client)
|
super().__init__(client)
|
||||||
|
Loading…
Reference in New Issue
Block a user