matejcik 1 month ago committed by GitHub
commit c9a6826a36
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -159,12 +159,6 @@ jobs:
matrix:
model: [T2T1, T2B1]
asan: ${{ fromJSON(needs.param.outputs.asan) }}
# T2B1 fails due to rust clippy error which is hard to reproduce, see discussion here:
# https://github.com/trezor/trezor-firmware/pull/2196
# The problem might be in conflicting versions of clippy, let's see if this helps:
# https://github.com/trezor/trezor-firmware/issues/3337
exclude:
- model: T2B1
env:
TREZOR_MODEL: ${{ matrix.model == 'T2T1' && 'T' || matrix.model == 'T2B1' && 'R' || matrix.model }}
ADDRESS_SANITIZER: ${{ matrix.asan == 'asan' && '1' || '0' }}

@ -32,12 +32,12 @@
#include "storage.h"
static secbool wrapped_ui_wait_callback(uint32_t wait, uint32_t progress,
const char *message) {
enum storage_ui_message_t message) {
if (mp_obj_is_callable(MP_STATE_VM(trezorconfig_ui_wait_callback))) {
mp_obj_t args[3] = {0};
args[0] = mp_obj_new_int(wait);
args[1] = mp_obj_new_int(progress);
args[2] = mp_obj_new_str(message, strlen(message));
args[2] = mp_obj_new_int(message);
if (mp_call_function_n_kw(MP_STATE_VM(trezorconfig_ui_wait_callback), 3, 0,
args) == mp_const_true) {
return sectrue;
@ -47,7 +47,8 @@ static secbool wrapped_ui_wait_callback(uint32_t wait, uint32_t progress,
}
/// def init(
/// ui_wait_callback: Callable[[int, int, str], bool] | None = None
/// ui_wait_callback: Callable[[int, int, StorageMessage], bool] | None =
/// None
/// ) -> None:
/// """
/// Initializes the storage. Must be called before any other method is
@ -409,6 +410,21 @@ STATIC mp_obj_t mod_trezorconfig_wipe(void) {
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_wipe_obj,
mod_trezorconfig_wipe);
/// from enum import IntEnum
/// class StorageMessage(IntEnum):
/// NO_MSG = 0
/// VERIFYING_PIN_MSG = 1
/// PROCESSING_MSG = 2
/// STARTING_MSG = 3
/// WRONG_PIN_MSG = 4
STATIC const qstr mod_trezorconfig_StorageMessage_fields[] = {
MP_QSTR_NO_MSG, MP_QSTR_VERIFYING_PIN_MSG, MP_QSTR_PROCESSING_MSG,
MP_QSTR_STARTING_MSG, MP_QSTR_WRONG_PIN_MSG};
STATIC MP_DEFINE_ATTRTUPLE(
mod_trezorconfig_StorageMessage_obj, mod_trezorconfig_StorageMessage_fields,
(sizeof(mod_trezorconfig_StorageMessage_fields) / sizeof(qstr)),
MP_ROM_INT(0), MP_ROM_INT(1), MP_ROM_INT(2), MP_ROM_INT(3), MP_ROM_INT(4));
STATIC const mp_rom_map_elem_t mp_module_trezorconfig_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorconfig)},
{MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&mod_trezorconfig_init_obj)},
@ -437,6 +453,8 @@ STATIC const mp_rom_map_elem_t mp_module_trezorconfig_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR_next_counter),
MP_ROM_PTR(&mod_trezorconfig_next_counter_obj)},
{MP_ROM_QSTR(MP_QSTR_wipe), MP_ROM_PTR(&mod_trezorconfig_wipe_obj)},
{MP_ROM_QSTR(MP_QSTR_StorageMessage),
MP_ROM_PTR(&mod_trezorconfig_StorageMessage_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mp_module_trezorconfig_globals,
mp_module_trezorconfig_globals_table);

@ -538,6 +538,10 @@ static void _librust_qstrs(void) {
MP_QSTR_sign_message__verify_address;
MP_QSTR_skip_first_paint;
MP_QSTR_spending_amount;
MP_QSTR_storage_msg__processing;
MP_QSTR_storage_msg__starting;
MP_QSTR_storage_msg__verifying_pin;
MP_QSTR_storage_msg__wrong_pin;
MP_QSTR_subprompt;
MP_QSTR_subtitle;
MP_QSTR_text_mono;

@ -1234,6 +1234,10 @@ pub enum TranslatedString {
ethereum__staking_unstake = 840, // "UNSTAKE"
#[cfg(feature = "universal_fw")]
ethereum__staking_unstake_intro = 841, // "Unstake ETH from Everstake?"
storage_msg__processing = 842, // "PROCESSING"
storage_msg__starting = 843, // "STARTING UP"
storage_msg__verifying_pin = 844, // "VERIFYING PIN"
storage_msg__wrong_pin = 845, // "WRONG PIN"
}
impl TranslatedString {
@ -2463,6 +2467,10 @@ impl TranslatedString {
Self::ethereum__staking_unstake => "UNSTAKE",
#[cfg(feature = "universal_fw")]
Self::ethereum__staking_unstake_intro => "Unstake ETH from Everstake?",
Self::storage_msg__processing => "PROCESSING",
Self::storage_msg__starting => "STARTING UP",
Self::storage_msg__verifying_pin => "VERIFYING PIN",
Self::storage_msg__wrong_pin => "WRONG PIN",
}
}
@ -3693,6 +3701,10 @@ impl TranslatedString {
Qstr::MP_QSTR_ethereum__staking_unstake => Some(Self::ethereum__staking_unstake),
#[cfg(feature = "universal_fw")]
Qstr::MP_QSTR_ethereum__staking_unstake_intro => Some(Self::ethereum__staking_unstake_intro),
Qstr::MP_QSTR_storage_msg__processing => Some(Self::storage_msg__processing),
Qstr::MP_QSTR_storage_msg__starting => Some(Self::storage_msg__starting),
Qstr::MP_QSTR_storage_msg__verifying_pin => Some(Self::storage_msg__verifying_pin),
Qstr::MP_QSTR_storage_msg__wrong_pin => Some(Self::storage_msg__wrong_pin),
_ => None,
}
}

@ -3,7 +3,8 @@
use super::ffi;
use crate::error::Error;
use core::ptr;
use cstr_core::CStr;
use num_traits::FromPrimitive;
/// Result of PIN delay callback.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@ -14,13 +15,23 @@ pub enum PinCallbackResult {
Abort,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, FromPrimitive)]
pub enum PinCallbackMessage {
None,
VerifyingPIN,
Processing,
Starting,
WrongPIN,
}
/// PIN delay callback function type.
/// The storage layer will call this function while the PIN timeout is in
/// progress. This is useful for showing UI progress bar.
/// `wait` is the total number of seconds waiting.
/// `progress` is a value between 0 and 1000, where 1000 indicates 100%.
/// `message` is a message to show to the user.
pub type PinDelayCallback = fn(wait: u32, progress: u32, message: &str) -> PinCallbackResult;
pub type PinDelayCallback =
fn(wait: u32, progress: u32, message: PinCallbackMessage) -> PinCallbackResult;
pub type ExternalSalt = [u8; ffi::EXTERNAL_SALT_SIZE as usize];
@ -31,12 +42,17 @@ static mut PIN_UI_CALLBACK: Option<PinDelayCallback> = None;
unsafe extern "C" fn callback_wrapper(
wait: u32,
progress: u32,
message: *const cty::c_char,
message: ffi::storage_ui_message_t,
) -> ffi::secbool {
let message = unsafe { CStr::from_ptr(message as _) };
let result = unsafe {
PIN_UI_CALLBACK
.map(|c| c(wait, progress, message.to_str().unwrap_or("")))
.map(|c| {
c(
wait,
progress,
PinCallbackMessage::from_u32(message).unwrap_or(PinCallbackMessage::None),
)
})
.unwrap_or(PinCallbackResult::Continue)
};
if matches!(result, PinCallbackResult::Abort) {
@ -266,7 +282,7 @@ mod tests {
static mut PIN_CALLBACK_CALLED: bool = false;
fn pin_callback(_wait: u32, _progress: u32, _message: &str) -> PinCallbackResult {
fn pin_callback(_wait: u32, _progress: u32, _message: PinCallbackMessage) -> PinCallbackResult {
unsafe {
PIN_CALLBACK_CALLED = true;
}

@ -1571,18 +1571,22 @@ extern "C" fn new_show_group_share_success(
extern "C" fn new_show_progress(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let description: StrBuffer = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let indeterminate: bool = kwargs.get_or(Qstr::MP_QSTR_indeterminate, false)?;
let description: StrBuffer =
kwargs.get_or(Qstr::MP_QSTR_description, StrBuffer::empty())?;
let title: Option<StrBuffer> = kwargs
.get(Qstr::MP_QSTR_title)
.and_then(Obj::try_into_option)
.unwrap_or(None);
let mut progress =
Progress::new(indeterminate, description).with_update_description(StrBuffer::alloc);
if let Some(title) = title {
progress = progress.with_title(title);
};
// Description updates are received as &str and we need to provide a way to
// convert them to StrBuffer.
let obj = LayoutObj::new(
Progress::new(indeterminate, description)
.with_title(title)
.with_update_description(StrBuffer::alloc),
)?;
let obj = LayoutObj::new(progress)?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -2074,9 +2078,9 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// def show_progress(
/// *,
/// title: str,
/// description: str,
/// indeterminate: bool = False,
/// description: str = "",
/// title: str | None = None,
/// ) -> LayoutObj[UiResult]:
/// """Show progress loader. Please note that the number of lines reserved on screen for
/// description is determined at construction time. If you want multiline descriptions

@ -51,7 +51,7 @@ pub const HOMESCREEN_IMAGE_HEIGHT: i16 = HEIGHT;
pub const HOMESCREEN_TOIF_SIZE: i16 = 144;
pub const HOMESCREEN_TOIF_Y_OFFSET: i16 = 27;
pub const HOMESCREEN_TOIF_X_OFFSET: usize =
((WIDTH.saturating_sub(HOMESCREEN_TOIF_SIZE)) / 2) as usize;
((WIDTH as usize).saturating_sub(HOMESCREEN_TOIF_SIZE as usize)) / 2;
const HOMESCREEN_MAX_ICON_SIZE: i16 = 20;
const NOTIFICATION_HEIGHT: i16 = 36;

@ -1547,10 +1547,18 @@ extern "C" fn new_show_remaining_shares(n_args: usize, args: *const Obj, kwargs:
extern "C" fn new_show_progress(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let description: StrBuffer = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let indeterminate: bool = kwargs.get_or(Qstr::MP_QSTR_indeterminate, false)?;
let description: StrBuffer =
kwargs.get_or(Qstr::MP_QSTR_description, StrBuffer::empty())?;
let title: Option<StrBuffer> = kwargs
.get(Qstr::MP_QSTR_title)
.and_then(Obj::try_into_option)
.unwrap_or(None);
let (title, description) = if let Some(title) = title {
(title, description)
} else {
(description, StrBuffer::empty())
};
// Description updates are received as &str and we need to provide a way to
// convert them to StrBuffer.
@ -2130,9 +2138,9 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// def show_progress(
/// *,
/// title: str,
/// description: str,
/// indeterminate: bool = False,
/// description: str = "",
/// title: str | None = None,
/// ) -> LayoutObj[UiResult]:
/// """Show progress loader. Please note that the number of lines reserved on screen for
/// description is determined at construction time. If you want multiline descriptions

@ -3,7 +3,8 @@ from typing import *
# extmod/modtrezorconfig/modtrezorconfig.c
def init(
ui_wait_callback: Callable[[int, int, str], bool] | None = None
ui_wait_callback: Callable[[int, int, StorageMessage], bool] | None =
None
) -> None:
"""
Initializes the storage. Must be called before any other method is
@ -141,3 +142,13 @@ def wipe() -> None:
"""
Erases the whole config. Use with caution!
"""
from enum import IntEnum
# extmod/modtrezorconfig/modtrezorconfig.c
class StorageMessage(IntEnum):
NO_MSG = 0
VERIFYING_PIN_MSG = 1
PROCESSING_MSG = 2
STARTING_MSG = 3
WRONG_PIN_MSG = 4

@ -399,9 +399,9 @@ def show_group_share_success(
# rust/src/ui/model_tr/layout.rs
def show_progress(
*,
title: str,
description: str,
indeterminate: bool = False,
description: str = "",
title: str | None = None,
) -> LayoutObj[UiResult]:
"""Show progress loader. Please note that the number of lines reserved on screen for
description is determined at construction time. If you want multiline descriptions
@ -917,9 +917,9 @@ def show_remaining_shares(
# rust/src/ui/model_tt/layout.rs
def show_progress(
*,
title: str,
description: str,
indeterminate: bool = False,
description: str = "",
title: str | None = None,
) -> LayoutObj[UiResult]:
"""Show progress loader. Please note that the number of lines reserved on screen for
description is determined at construction time. If you want multiline descriptions

@ -756,6 +756,10 @@ class TR:
stellar__value_sha256: str = "Value (SHA-256):"
stellar__wanna_clean_value_key_template: str = "Do you want to clear value key {0}?"
stellar__your_account: str = " your account"
storage_msg__processing: str = "PROCESSING"
storage_msg__starting: str = "STARTING UP"
storage_msg__verifying_pin: str = "VERIFYING PIN"
storage_msg__wrong_pin: str = "WRONG PIN"
tezos__baker_address: str = "Baker address:"
tezos__balance: str = "Balance:"
tezos__ballot: str = "Ballot:"

@ -169,8 +169,6 @@ trezor.ui.layouts.tr.fido
import trezor.ui.layouts.tr.fido
trezor.ui.layouts.tr.homescreen
import trezor.ui.layouts.tr.homescreen
trezor.ui.layouts.tr.progress
import trezor.ui.layouts.tr.progress
trezor.ui.layouts.tr.recovery
import trezor.ui.layouts.tr.recovery
trezor.ui.layouts.tr.reset
@ -181,8 +179,6 @@ trezor.ui.layouts.tt.fido
import trezor.ui.layouts.tt.fido
trezor.ui.layouts.tt.homescreen
import trezor.ui.layouts.tt.homescreen
trezor.ui.layouts.tt.progress
import trezor.ui.layouts.tt.progress
trezor.ui.layouts.tt.recovery
import trezor.ui.layouts.tt.recovery
trezor.ui.layouts.tt.reset

@ -34,7 +34,7 @@ async def authenticate_device(msg: AuthenticateDevice) -> AuthenticityProof:
write_compact_size(h, len(msg.challenge))
h.extend(msg.challenge)
spinner = progress("", description=TR.progress__authenticity_check)
spinner = progress(TR.progress__authenticity_check)
spinner.report(0)
try:

@ -24,7 +24,7 @@ async def change_language(msg: ChangeLanguage) -> Success:
nonlocal loader
if loader is None:
workflow.close_others()
loader = progress("", TR.language__progress)
loader = progress(TR.language__progress)
loader.report(value)
if msg.data_length == 0:

@ -44,7 +44,7 @@ async def reset_device(msg: ResetDevice) -> Success:
await confirm_reset_device(title)
# Rendering empty loader so users do not feel a freezing screen
render_empty_loader(TR.progress__processing, "")
render_empty_loader(config.StorageMessage.PROCESSING_MSG)
# wipe storage to make sure the device is in a clear state
storage.reset()

@ -1,7 +1,9 @@
from typing import TYPE_CHECKING
from . import config
if TYPE_CHECKING:
from typing import Any
from typing import Any, Container
from trezor.ui.layouts.common import ProgressLayout
@ -11,13 +13,15 @@ _progress_layout: ProgressLayout | None = None
_started_with_empty_loader = False
keepalive_callback: Any = None
_ignore_loader_messages: tuple[str, ...] = ()
_ignore_loader_messages: Container[config.StorageMessage] = ()
def ignore_nonpin_loader_messages() -> None:
global _ignore_loader_messages
# TODO: handle translation of those (in C)
_ignore_loader_messages = ("Processing", "Starting up")
_ignore_loader_messages = (
config.StorageMessage.PROCESSING_MSG,
config.StorageMessage.STARTING_MSG,
)
def allow_all_loader_messages() -> None:
@ -25,7 +29,7 @@ def allow_all_loader_messages() -> None:
_ignore_loader_messages = ()
def render_empty_loader(message: str, description: str) -> None:
def render_empty_loader(message: config.StorageMessage, description: str = "") -> None:
"""Render empty loader to prevent the screen appear to be frozen."""
from trezor.ui.layouts.progress import pin_progress
@ -38,7 +42,9 @@ def render_empty_loader(message: str, description: str) -> None:
_started_with_empty_loader = True
def show_pin_timeout(seconds: int, progress: int, message: str) -> bool:
def show_pin_timeout(
seconds: int, progress: int, message: config.StorageMessage
) -> bool:
from trezor import TR
from trezor.ui.layouts.progress import pin_progress

@ -1,6 +1,100 @@
from trezor import utils
from typing import TYPE_CHECKING
if utils.UI_LAYOUT == "TT":
from .tt.progress import * # noqa: F401,F403
elif utils.UI_LAYOUT == "TR":
from .tr.progress import * # noqa: F401,F403
import trezorui2
from trezor import TR, config, ui, utils
if TYPE_CHECKING:
from typing import Any
from .common import ProgressLayout
def _storage_message_to_str(message: config.StorageMessage | None) -> str | None:
from trezor import TR
if message is None:
return None
if message == config.StorageMessage.NO_MSG:
return ""
if message == config.StorageMessage.VERIFYING_PIN_MSG:
return TR.storage_msg__verifying_pin
if message == config.StorageMessage.PROCESSING_MSG:
return TR.storage_msg__processing
if message == config.StorageMessage.STARTING_MSG:
return TR.storage_msg__starting
if message == config.StorageMessage.WRONG_PIN_MSG:
return TR.storage_msg__wrong_pin
raise RuntimeError # unknown message
class RustProgress:
def __init__(
self,
layout: Any,
):
self.layout = layout
ui.backlight_fade(ui.style.BACKLIGHT_DIM)
self.layout.attach_timer_fn(self.set_timer)
self.layout.paint()
ui.refresh()
ui.backlight_fade(ui.style.BACKLIGHT_NORMAL)
def set_timer(self, token: int, deadline: int) -> None:
raise RuntimeError # progress layouts should not set timers
def report(self, value: int, description: str | None = None):
msg = self.layout.progress_event(value, description or "")
assert msg is None
self.layout.paint()
ui.refresh()
def progress(
description: str | None = None,
title: str | None = None,
indeterminate: bool = False,
) -> ProgressLayout:
if description is None:
description = TR.progress__please_wait # def_arg
if title is not None:
title = title.upper()
elif not utils.MODEL_IS_T2B1:
# on TT, uppercase the description which ends up on top of the screen
# when no title is set
description = description.upper()
return RustProgress(
layout=trezorui2.show_progress(
description=description,
title=title,
indeterminate=indeterminate,
)
)
def bitcoin_progress(message: str) -> ProgressLayout:
return progress(message)
def coinjoin_progress(message: str) -> ProgressLayout:
return RustProgress(
layout=trezorui2.show_progress_coinjoin(title=message, indeterminate=False)
)
def pin_progress(title: config.StorageMessage, description: str) -> ProgressLayout:
return progress(description=description, title=_storage_message_to_str(title))
if not utils.BITCOIN_ONLY:
def monero_keyimage_sync_progress() -> ProgressLayout:
return progress(TR.progress__syncing)
def monero_live_refresh_progress() -> ProgressLayout:
return progress(TR.progress__refreshing, indeterminate=True)
def monero_transaction_progress_inner() -> ProgressLayout:
return progress(TR.progress__signing_transaction)

@ -1,69 +0,0 @@
from typing import TYPE_CHECKING
import trezorui2
from trezor import TR, ui, utils
if TYPE_CHECKING:
from typing import Any
from ..common import ProgressLayout
class RustProgress:
def __init__(
self,
layout: Any,
):
self.layout = layout
self.layout.attach_timer_fn(self.set_timer)
self.layout.paint()
ui.refresh()
def set_timer(self, token: int, deadline: int) -> None:
raise RuntimeError # progress layouts should not set timers
def report(self, value: int, description: str | None = None):
msg = self.layout.progress_event(value, description or "")
assert msg is None
self.layout.paint()
ui.refresh()
def progress(
message: str | None = None,
description: str | None = None,
indeterminate: bool = False,
) -> ProgressLayout:
return RustProgress(
layout=trezorui2.show_progress(
title=message.upper() if message else "",
indeterminate=indeterminate,
description=description or "",
)
)
def bitcoin_progress(description: str) -> ProgressLayout:
return progress("", description)
def coinjoin_progress(message: str) -> ProgressLayout:
return RustProgress(
layout=trezorui2.show_progress_coinjoin(title=message, indeterminate=False)
)
def pin_progress(message: str, description: str) -> ProgressLayout:
return progress(message, description)
if not utils.BITCOIN_ONLY:
def monero_keyimage_sync_progress() -> ProgressLayout:
return progress("", TR.progress__syncing)
def monero_live_refresh_progress() -> ProgressLayout:
return progress("", TR.progress__refreshing, indeterminate=True)
def monero_transaction_progress_inner() -> ProgressLayout:
return progress("", TR.progress__signing_transaction)

@ -1,72 +0,0 @@
from typing import TYPE_CHECKING
import trezorui2
from trezor import TR, ui, utils
if TYPE_CHECKING:
from typing import Any
from ..common import ProgressLayout
class RustProgress:
def __init__(
self,
layout: Any,
):
self.layout = layout
ui.backlight_fade(ui.style.BACKLIGHT_DIM)
self.layout.attach_timer_fn(self.set_timer)
self.layout.paint()
ui.refresh()
ui.backlight_fade(ui.style.BACKLIGHT_NORMAL)
def set_timer(self, token: int, deadline: int) -> None:
raise RuntimeError # progress layouts should not set timers
def report(self, value: int, description: str | None = None):
msg = self.layout.progress_event(value, description or "")
assert msg is None
self.layout.paint()
ui.refresh()
def progress(
message: str | None = None,
description: str | None = None,
indeterminate: bool = False,
) -> ProgressLayout:
message = message or TR.progress__please_wait # def_arg
return RustProgress(
layout=trezorui2.show_progress(
title=message.upper(),
indeterminate=indeterminate,
description=description or "",
)
)
def bitcoin_progress(message: str) -> ProgressLayout:
return progress(message)
def coinjoin_progress(message: str) -> ProgressLayout:
return RustProgress(
layout=trezorui2.show_progress_coinjoin(title=message, indeterminate=False)
)
def pin_progress(message: str, description: str) -> ProgressLayout:
return progress(message, description=description)
if not utils.BITCOIN_ONLY:
def monero_keyimage_sync_progress() -> ProgressLayout:
return progress("", TR.progress__syncing)
def monero_live_refresh_progress() -> ProgressLayout:
return progress("", TR.progress__refreshing, indeterminate=True)
def monero_transaction_progress_inner() -> ProgressLayout:
return progress("", TR.progress__signing_transaction)

@ -781,6 +781,10 @@
"stellar__value_sha256": "Hodnota (SHA-256):",
"stellar__wanna_clean_value_key_template": "Chcete vymazat klíč hodnoty {0}?",
"stellar__your_account": " váš účet",
"storage_msg__verifying_pin": "OVĚŘOVÁNÍ PINU",
"storage_msg__processing": "ZPRACOVÁVÁ SE",
"storage_msg__starting": "SPOUŠTĚNÍ",
"storage_msg__wrong_pin": "ŠPATNÝ PIN",
"tezos__baker_address": "Adresa bakera:",
"tezos__balance": "Zůstatek:",
"tezos__ballot": "Hlasování:",

@ -781,6 +781,10 @@
"stellar__value_sha256": "Wert (SHA-256):",
"stellar__wanna_clean_value_key_template": "Möchtest du den Wert-Key {0} löschen?",
"stellar__your_account": " dein Konto",
"storage_msg__verifying_pin": "PIN ÜBERPRÜFEN",
"storage_msg__processing": "VERARBEITUNG",
"storage_msg__starting": "STARTVORGANG",
"storage_msg__wrong_pin": "FALSCHER PIN",
"tezos__baker_address": "Baker-Adresse:",
"tezos__balance": "Guthaben:",
"tezos__ballot": "Abstimmung:",

@ -677,6 +677,10 @@
"sign_message__confirm_message": "CONFIRM MESSAGE",
"sign_message__message_size": "Message size:",
"sign_message__verify_address": "VERIFY ADDRESS",
"storage_msg__verifying_pin": "VERIFYING PIN",
"storage_msg__processing": "PROCESSING",
"storage_msg__starting": "STARTING UP",
"storage_msg__wrong_pin": "WRONG PIN",
"solana__account_index": "Account index",
"solana__associated_token_account": "Associated token account",
"solana__confirm_multisig": "Confirm multisig",

@ -781,6 +781,10 @@
"stellar__value_sha256": "Valor (SHA-256):",
"stellar__wanna_clean_value_key_template": "¿Quieres borrar la clave de valor {0}?",
"stellar__your_account": " tu cuenta",
"storage_msg__verifying_pin": "VERIFICANDO PIN",
"storage_msg__processing": "PROCESANDO",
"storage_msg__starting": "INICIANDO",
"storage_msg__wrong_pin": "PIN INCORRECTO",
"tezos__baker_address": "Dirección de panadero:",
"tezos__balance": "Saldo:",
"tezos__ballot": "Papeleta:",

@ -782,6 +782,10 @@
"stellar__wanna_clean_value_key_template": "Voulez-vous effacer la clé de valeur {0} ?",
"stellar__your_account": " votre compte",
"tezos__baker_address": "Adr. du baker :",
"storage_msg__verifying_pin": "VÉRIFICATION DU PIN",
"storage_msg__processing": "TRAITEMENT",
"storage_msg__starting": "DÉMARRAGE",
"storage_msg__wrong_pin": "PIN INCORRECT",
"tezos__balance": "Solde :",
"tezos__ballot": "Bulletin de vote :",
"tezos__confirm_delegation": "Conf. délégation",

@ -840,5 +840,9 @@
"838": "ethereum__staking_stake_address",
"839": "ethereum__staking_stake_intro",
"840": "ethereum__staking_unstake",
"841": "ethereum__staking_unstake_intro"
"841": "ethereum__staking_unstake_intro",
"842": "storage_msg__processing",
"843": "storage_msg__starting",
"844": "storage_msg__verifying_pin",
"845": "storage_msg__wrong_pin"
}

@ -1,8 +1,8 @@
{
"current": {
"merkle_root": "d349550e9ad7be0b63b06fc43c6b764d008bf4497a8e1d0374cb92119b242160",
"datetime": "2024-03-25T14:23:51.859562",
"commit": "ef11039a818bb0941191af49e0c9a0f7aae9324a"
"merkle_root": "3700c5cf563ec866319c8b3af19f4cf6d5894949bf394dd7581aa85685e042de",
"datetime": "2024-03-25T15:28:46.161035",
"commit": "709a43c84bff4c49cd4c914c82636a69b2b95f84"
},
"history": [
{

@ -150,7 +150,7 @@ const char *requestPin(PinMatrixRequestType type, const char *text) {
}
secbool protectPinUiCallback(uint32_t wait, uint32_t progress,
const char *message) {
enum storage_ui_message_t message) {
// Convert wait to secstr string.
char secstrbuf[] = _("________0 seconds");
char *secstr = secstrbuf + 9;
@ -165,7 +165,27 @@ secbool protectPinUiCallback(uint32_t wait, uint32_t progress,
secstrbuf[16] = 0;
}
oledClear();
oledDrawStringCenter(OLED_WIDTH / 2, 0 * 9, message, FONT_STANDARD);
const char *message_str = NULL;
switch (message) {
case VERIFYING_PIN_MSG:
message_str = _("Verifying PIN");
break;
case PROCESSING_MSG:
message_str = _("Processing");
break;
case STARTING_MSG:
message_str = _("Starting up");
break;
case WRONG_PIN_MSG:
message_str = _("Wrong PIN");
break;
default:
message_str = _("");
break;
}
oledDrawStringCenter(OLED_WIDTH / 2, 0 * 9, message_str, FONT_STANDARD);
oledDrawStringCenter(OLED_WIDTH / 2, 2 * 9, _("Please wait"), FONT_STANDARD);
oledDrawStringCenter(OLED_WIDTH / 2, 3 * 9, secstr, FONT_STANDARD);
oledDrawStringCenter(OLED_WIDTH / 2, 4 * 9, _("to continue ..."),

@ -23,12 +23,13 @@
#include <stdbool.h>
#include "messages-common.pb.h"
#include "secbool.h"
#include "storage.h"
#define MAX_PASSPHRASE_LEN 50
bool protectButton(ButtonRequestType type, bool confirm_only);
secbool protectPinUiCallback(uint32_t wait, uint32_t progress,
const char* message);
enum storage_ui_message_t message);
bool protectPin(bool use_cached);
bool protectChangePin(bool removal);
bool protectChangeWipeCode(bool removal);

@ -137,18 +137,12 @@ const uint8_t WIPE_CODE_EMPTY[] = {0, 0, 0, 0};
// The uint32 representation of an empty wipe code used in storage version 2.
#define V2_WIPE_CODE_EMPTY 0
// TODO: handle translation
const char *const VERIFYING_PIN_MSG = "Verifying PIN";
const char *const PROCESSING_MSG = "Processing";
const char *const STARTING_MSG = "Starting up";
const char *const WRONG_PIN_MSG = "Wrong PIN";
static secbool initialized = secfalse;
static secbool unlocked = secfalse;
static PIN_UI_WAIT_CALLBACK ui_callback = NULL;
static uint32_t ui_total = 0;
static uint32_t ui_rem = 0;
static const char *ui_message = NULL;
static enum storage_ui_message_t ui_message = NO_MSG;
static uint8_t cached_keys[KEYS_SIZE] = {0};
static uint8_t *const cached_dek = cached_keys;
static uint8_t *const cached_sak = cached_keys + DEK_SIZE;
@ -986,7 +980,7 @@ secbool storage_unlock(const uint8_t *pin, size_t pin_len,
ui_total = PIN_DERIVE_MS;
ui_rem = ui_total;
if (pin_len == 0) {
if (ui_message == NULL) {
if (ui_message == NO_MSG) {
ui_message = STARTING_MSG;
} else {
ui_message = PROCESSING_MSG;

@ -53,8 +53,16 @@ extern const uint8_t *PIN_EMPTY;
#define STORAGE_SALT_SIZE 4
#endif
enum storage_ui_message_t {
NO_MSG = 0,
VERIFYING_PIN_MSG,
PROCESSING_MSG,
STARTING_MSG,
WRONG_PIN_MSG,
};
typedef secbool (*PIN_UI_WAIT_CALLBACK)(uint32_t wait, uint32_t progress,
const char *message);
enum storage_ui_message_t message);
void storage_init(PIN_UI_WAIT_CALLBACK callback, const uint8_t *salt,
const uint16_t salt_len);

@ -154,17 +154,12 @@ const uint8_t WIPE_CODE_EMPTY[] = {0, 0, 0, 0};
#define GUARD_KEY_MODULUS 6311
#define GUARD_KEY_REMAINDER 15
const char *const VERIFYING_PIN_MSG = "Verifying PIN";
const char *const PROCESSING_MSG = "Processing";
const char *const STARTING_MSG = "Starting up";
const char *const WRONG_PIN_MSG = "Wrong PIN";
static secbool initialized = secfalse;
static secbool unlocked = secfalse;
static PIN_UI_WAIT_CALLBACK ui_callback = NULL;
static uint32_t ui_total = 0;
static uint32_t ui_rem = 0;
static const char *ui_message = NULL;
static enum storage_ui_message_t ui_message = NO_MSG;
static uint8_t cached_keys[KEYS_SIZE] = {0};
static uint8_t *const cached_dek = cached_keys;
static uint8_t *const cached_sak = cached_keys + DEK_SIZE;
@ -1258,7 +1253,7 @@ secbool storage_unlock(const uint8_t *pin, size_t pin_len,
ui_total = PIN_DERIVE_MS;
ui_rem = ui_total;
if (pin_len == 0) {
if (ui_message == NULL) {
if (ui_message == NO_MSG) {
ui_message = STARTING_MSG;
} else {
ui_message = PROCESSING_MSG;

@ -53,8 +53,16 @@ extern const uint8_t *PIN_EMPTY;
#define STORAGE_SALT_SIZE 4
#endif
enum storage_ui_message_t {
NO_MSG = 0,
VERIFYING_PIN_MSG,
PROCESSING_MSG,
STARTING_MSG,
WRONG_PIN_MSG,
};
typedef secbool (*PIN_UI_WAIT_CALLBACK)(uint32_t wait, uint32_t progress,
const char *message);
enum storage_ui_message_t message);
void storage_init(PIN_UI_WAIT_CALLBACK callback, const uint8_t *salt,
const uint16_t salt_len);

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