Skip to content

Commit c28cc55

Browse files
committed
Merge branch 'pw'
2 parents 0700002 + efe6bac commit c28cc55

File tree

12 files changed

+112
-33
lines changed

12 files changed

+112
-33
lines changed

src/rust/bitbox02-rust/src/hww/api/error.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,23 @@ impl core::convert::From<crate::workflow::cancel::Error> for Error {
4848
}
4949
}
5050

51+
impl core::convert::From<crate::workflow::password::EnterError> for Error {
52+
fn from(error: crate::workflow::password::EnterError) -> Self {
53+
match error {
54+
crate::workflow::password::EnterError::Memory => Error::Memory,
55+
crate::workflow::password::EnterError::Cancelled => Error::UserAbort,
56+
}
57+
}
58+
}
59+
5160
impl core::convert::From<crate::workflow::password::EnterTwiceError> for Error {
5261
fn from(error: crate::workflow::password::EnterTwiceError) -> Self {
5362
match error {
5463
crate::workflow::password::EnterTwiceError::DoNotMatch => {
5564
// For backwards compatibility.
5665
Error::Generic
5766
}
58-
crate::workflow::password::EnterTwiceError::Cancelled => {
59-
// Added in v9.13.0.
60-
Error::UserAbort
61-
}
67+
crate::workflow::password::EnterTwiceError::EnterError(err) => err.into(),
6268
}
6369
}
6470
}
@@ -108,6 +114,7 @@ impl core::convert::From<UnlockError> for Error {
108114
fn from(error: UnlockError) -> Self {
109115
match error {
110116
UnlockError::UserAbort => Error::UserAbort,
117+
UnlockError::Memory => Error::Memory,
111118
UnlockError::IncorrectPassword | UnlockError::Generic => Error::Generic,
112119
}
113120
}

src/rust/bitbox02-rust/src/hww/api/restore.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ pub async fn from_mnemonic(
140140
})
141141
.await?;
142142
}
143-
Err(password::EnterTwiceError::Cancelled) => return Err(Error::UserAbort),
143+
Err(err @ password::EnterTwiceError::EnterError(_)) => return Err(err.into()),
144144
Ok(password) => break password,
145145
}
146146
};

src/rust/bitbox02-rust/src/workflow/password.rs

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,33 +27,58 @@ async fn prompt_cancel(hal: &mut impl crate::hal::Hal) -> Result<(), confirm::Us
2727
.await
2828
}
2929

30+
pub enum PasswordType {
31+
/// The password to be entered is the device unlock password.
32+
DevicePassword,
33+
/// The password to be entered is the BIP39 passphrase.
34+
Bip39Passphrase,
35+
}
36+
37+
#[derive(Debug)]
38+
pub enum EnterError {
39+
Memory,
40+
Cancelled,
41+
}
42+
3043
/// If `can_cancel` is `Yes`, the workflow can be cancelled.
3144
/// If it is no, the result is always `Ok(())`.
3245
///
3346
/// Example:
3447
/// ```no_run
35-
/// let pw = enter("Enter password", true, CanCancel::No).await.unwrap();
48+
/// let pw = enter(hal, "Enter password", PassswordType::DevicePassword, CanCancel::No).await.unwrap();
3649
/// // use pw.
3750
/// ```
3851
pub async fn enter(
3952
hal: &mut impl crate::hal::Hal,
4053
title: &str,
41-
special_chars: bool,
54+
password_type: PasswordType,
4255
can_cancel: CanCancel,
43-
) -> Result<zeroize::Zeroizing<String>, Error> {
56+
) -> Result<zeroize::Zeroizing<String>, EnterError> {
4457
let params = trinary_input_string::Params {
4558
title,
4659
hide: true,
47-
special_chars,
60+
special_chars: match password_type {
61+
PasswordType::DevicePassword => false,
62+
PasswordType::Bip39Passphrase => true,
63+
},
4864
longtouch: true,
65+
default_to_digits: match password_type {
66+
PasswordType::DevicePassword => {
67+
match bitbox02::memory::get_securechip_type().map_err(|_| EnterError::Memory)? {
68+
bitbox02::memory::SecurechipType::Atecc => false,
69+
bitbox02::memory::SecurechipType::Optiga => true,
70+
}
71+
}
72+
PasswordType::Bip39Passphrase => false,
73+
},
4974
..Default::default()
5075
};
5176

5277
loop {
5378
match hal.ui().enter_string(&params, can_cancel, "").await {
54-
o @ Ok(_) => return o,
79+
Ok(pw) => return Ok(pw),
5580
Err(Error::Cancelled) => match prompt_cancel(hal).await {
56-
Ok(()) => return Err(Error::Cancelled),
81+
Ok(()) => return Err(EnterError::Cancelled),
5782
Err(confirm::UserAbort) => {}
5883
},
5984
}
@@ -62,14 +87,12 @@ pub async fn enter(
6287

6388
pub enum EnterTwiceError {
6489
DoNotMatch,
65-
Cancelled,
90+
EnterError(EnterError),
6691
}
6792

68-
impl core::convert::From<Error> for EnterTwiceError {
69-
fn from(error: Error) -> Self {
70-
match error {
71-
Error::Cancelled => EnterTwiceError::Cancelled,
72-
}
93+
impl core::convert::From<EnterError> for EnterTwiceError {
94+
fn from(error: EnterError) -> Self {
95+
EnterTwiceError::EnterError(error)
7396
}
7497
}
7598

@@ -84,8 +107,20 @@ impl core::convert::From<Error> for EnterTwiceError {
84107
pub async fn enter_twice(
85108
hal: &mut impl crate::hal::Hal,
86109
) -> Result<zeroize::Zeroizing<String>, EnterTwiceError> {
87-
let password = enter(hal, "Set password", false, CanCancel::Yes).await?;
88-
let password_repeat = enter(hal, "Repeat password", false, CanCancel::Yes).await?;
110+
let password = enter(
111+
hal,
112+
"Set password",
113+
PasswordType::DevicePassword,
114+
CanCancel::Yes,
115+
)
116+
.await?;
117+
let password_repeat = enter(
118+
hal,
119+
"Repeat password",
120+
PasswordType::DevicePassword,
121+
CanCancel::Yes,
122+
)
123+
.await?;
89124
if password.as_str() != password_repeat.as_str() {
90125
hal.ui().status("Passwords\ndo not match", false).await;
91126
return Err(EnterTwiceError::DoNotMatch);
@@ -104,7 +139,7 @@ pub async fn enter_twice(
104139
{
105140
Ok(()) => break,
106141
Err(confirm::UserAbort) => match prompt_cancel(hal).await {
107-
Ok(()) => return Err(EnterTwiceError::Cancelled),
142+
Ok(()) => return Err(EnterTwiceError::EnterError(EnterError::Cancelled)),
108143
Err(confirm::UserAbort) => {}
109144
},
110145
}

src/rust/bitbox02-rust/src/workflow/unlock.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,16 @@ async fn confirm_mnemonic_passphrase(
5555
pub enum UnlockError {
5656
UserAbort,
5757
IncorrectPassword,
58+
Memory,
5859
Generic,
5960
}
6061

61-
impl core::convert::From<super::cancel::Error> for UnlockError {
62-
fn from(_error: super::cancel::Error) -> Self {
63-
UnlockError::UserAbort
62+
impl core::convert::From<password::EnterError> for UnlockError {
63+
fn from(error: password::EnterError) -> Self {
64+
match error {
65+
password::EnterError::Cancelled => UnlockError::UserAbort,
66+
password::EnterError::Memory => UnlockError::Memory,
67+
}
6468
}
6569
}
6670

@@ -76,7 +80,13 @@ pub async fn unlock_keystore(
7680
title: &str,
7781
can_cancel: password::CanCancel,
7882
) -> Result<(), UnlockError> {
79-
let password = password::enter(hal, title, false, can_cancel).await?;
83+
let password = password::enter(
84+
hal,
85+
title,
86+
password::PasswordType::DevicePassword,
87+
can_cancel,
88+
)
89+
.await?;
8090

8191
match keystore::unlock(&password) {
8292
Ok(()) => Ok(()),
@@ -106,10 +116,14 @@ pub async fn unlock_bip39(hal: &mut impl crate::hal::Hal) {
106116
if bitbox02::memory::is_mnemonic_passphrase_enabled() {
107117
// Loop until the user confirms.
108118
loop {
109-
mnemonic_passphrase =
110-
password::enter(hal, "Optional passphrase", true, password::CanCancel::No)
111-
.await
112-
.expect("not cancelable");
119+
mnemonic_passphrase = password::enter(
120+
hal,
121+
"Optional passphrase",
122+
password::PasswordType::Bip39Passphrase,
123+
password::CanCancel::No,
124+
)
125+
.await
126+
.expect("not cancelable and does not call memory functions");
113127

114128
if let Ok(()) = confirm_mnemonic_passphrase(hal, mnemonic_passphrase.as_str()).await {
115129
break;

src/rust/bitbox02-sys/build.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ const ALLOWLIST_VARS: &[&str] = &[
4040
"MEMORY_SPI_BLE_FIRMWARE_2_ADDR",
4141
"MEMORY_PLATFORM_BITBOX02",
4242
"MEMORY_PLATFORM_BITBOX02_PLUS",
43+
"MEMORY_SECURECHIP_TYPE_ATECC",
44+
"MEMORY_SECURECHIP_TYPE_OPTIGA",
4345
];
4446

4547
const ALLOWLIST_TYPES: &[&str] = &[
@@ -110,6 +112,7 @@ const ALLOWLIST_FNS: &[&str] = &[
110112
"memory_get_ble_metadata",
111113
"memory_set_ble_metadata",
112114
"memory_get_platform",
115+
"memory_get_securechip_type",
113116
"memory_spi_get_active_ble_firmware_version",
114117
"spi_mem_write",
115118
"menu_create",

src/rust/bitbox02/src/memory.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,19 @@ pub fn get_platform() -> Result<Platform, ()> {
175175
}
176176
}
177177

178+
pub enum SecurechipType {
179+
Atecc,
180+
Optiga,
181+
}
182+
183+
pub fn get_securechip_type() -> Result<SecurechipType, ()> {
184+
match unsafe { bitbox02_sys::memory_get_securechip_type() as u32 } {
185+
bitbox02_sys::MEMORY_SECURECHIP_TYPE_ATECC => Ok(SecurechipType::Atecc),
186+
bitbox02_sys::MEMORY_SECURECHIP_TYPE_OPTIGA => Ok(SecurechipType::Optiga),
187+
_ => Err(()),
188+
}
189+
}
190+
178191
pub fn get_ble_metadata() -> BleMetadata {
179192
let mut metadata = core::mem::MaybeUninit::uninit();
180193

src/rust/bitbox02/src/ui/types.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ pub struct TrinaryInputStringParams<'a> {
107107
pub special_chars: bool,
108108
pub longtouch: bool,
109109
pub cancel_is_backbutton: bool,
110+
pub default_to_digits: bool,
110111
}
111112

112113
impl<'a> TrinaryInputStringParams<'a> {
@@ -138,6 +139,7 @@ impl<'a> TrinaryInputStringParams<'a> {
138139
special_chars: self.special_chars,
139140
longtouch: self.longtouch,
140141
cancel_is_backbutton: self.cancel_is_backbutton,
142+
default_to_digits: self.default_to_digits,
141143
})
142144
}
143145
}

src/ui/components/keyboard_switch.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ static component_functions_t _component_functions = {
152152
component_t* keyboard_switch_create(
153153
slider_location_t location,
154154
bool special_chars,
155+
bool default_to_digits,
155156
component_t* parent)
156157
{
157158
component_t* keyboard_switch = malloc(sizeof(component_t));
@@ -167,7 +168,7 @@ component_t* keyboard_switch_create(
167168
memset(ks_data, 0, sizeof(keyboard_switch_data_t));
168169

169170
ks_data->location = location;
170-
ks_data->mode = LOWER_CASE;
171+
ks_data->mode = default_to_digits ? DIGITS : LOWER_CASE;
171172
ks_data->active = false;
172173
ks_data->special_chars = special_chars;
173174

src/ui/components/keyboard_switch.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ typedef enum { LOWER_CASE, UPPER_CASE, DIGITS, SPECIAL_CHARS } keyboard_mode_t;
2525
/**
2626
* Creates a keyboard switch component.
2727
* @param[in] location The slider location.
28-
* @param[in] make special chars keyboard mode available.
28+
* @param[in] special_chars make special chars keyboard mode available.
29+
* @param[in] default_to_digits start with the digits keyboard instead of the lowercase keyboard.
2930
* @param[in] parent The parent component.
3031
*/
3132
component_t* keyboard_switch_create(
3233
slider_location_t location,
3334
bool special_chars,
35+
bool default_to_digits,
3436
component_t* parent);
3537

3638
/**

src/ui/components/trinary_input_string.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,8 +490,8 @@ component_t* trinary_input_string_create(
490490
ui_util_add_sub_component(component, data->confirm_component);
491491

492492
if (params->wordlist == NULL && !params->number_input) {
493-
data->keyboard_switch_component =
494-
keyboard_switch_create(top_slider, params->special_chars, component);
493+
data->keyboard_switch_component = keyboard_switch_create(
494+
top_slider, params->special_chars, params->default_to_digits, component);
495495
ui_util_add_sub_component(component, data->keyboard_switch_component);
496496
}
497497

0 commit comments

Comments
 (0)