bitbox02_rust/hal: move workflow::trinary_input_string::CanCancel to hal::ui
What changed, and why it matters
This commit is a straightforward internal code reorganization. It moves a small setting called CanCancel (which controls whether a user can cancel a text-entry screen) from one Rust module to another so the hardware abstraction layer can stand on its own. No behavior changes, no security fixes, and no bug fixes are visible in the diff.
No security action needed. Treat as normal refactoring during code review.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change relocates the CanCancel enum from workflow::trinary_input_string into hal::ui, deletes the now-empty workflow::trinary_input_string module, and updates all import/use paths across 13 files. The enum’s variants, derives, and usage sites remain identical. Function signatures and logic are unchanged.
Changed components
src/rust/bitbox02-rust/src/hal/ui.rssrc/rust/bitbox02-rust/src/hal/bitbox02/ui.rssrc/rust/bitbox02-rust/src/hal/testing/ui.rssrc/rust/bitbox02-rust/src/workflow/trinary_input_string.rssrc/rust/bitbox02-rust/src/workflow/unlock.rssrc/rust/bitbox02-rust/src/workflow/password.rssrc/rust/bitbox02-rust/src/workflow/mnemonic.rssrc/rust/bitbox02-rust/src/hww/api/backup.rssrc/rust/bitbox02-rust/src/hww/api/bip85.rssrc/rust/bitbox02-rust/src/hww/api/bitcoin/registration.rssrc/rust/bitbox02-rust/src/hww/api/change_password.rssrc/rust/bitbox02-rust/src/hww/api/show_mnemonic.rsInspect captured patch +37 / −60
diff --git a/src/rust/bitbox02-rust/src/hal/bitbox02/ui.rs b/src/rust/bitbox02-rust/src/hal/bitbox02/ui.rs
index 2fc9d8d..b36bb75 100644
--- a/src/rust/bitbox02-rust/src/hal/bitbox02/ui.rs
+++ b/src/rust/bitbox02-rust/src/hal/bitbox02/ui.rs
@@ -3,8 +3,7 @@
use alloc::string::String;
use crate::hal::Ui;
-use crate::hal::ui::{ConfirmParams, EnterStringParams, Font, TrinaryChoice, UserAbort};
-use crate::workflow::trinary_input_string;
+use crate::hal::ui::{CanCancel, ConfirmParams, EnterStringParams, Font, TrinaryChoice, UserAbort};
pub struct BitBox02Ui;
@@ -95,13 +94,13 @@ impl Ui for BitBox02Ui {
async fn enter_string(
&mut self,
params: &EnterStringParams<'_>,
- can_cancel: trinary_input_string::CanCancel,
+ can_cancel: CanCancel,
preset: &str,
) -> Result<zeroize::Zeroizing<String>, UserAbort> {
let params = to_bitbox02_trinary_input_string_params(params);
let can_cancel = match can_cancel {
- trinary_input_string::CanCancel::Yes => true,
- trinary_input_string::CanCancel::No => false,
+ CanCancel::Yes => true,
+ CanCancel::No => false,
};
bitbox02::ui::trinary_input_string(¶ms, can_cancel, preset)
.await
diff --git a/src/rust/bitbox02-rust/src/hal/testing/ui.rs b/src/rust/bitbox02-rust/src/hal/testing/ui.rs
index bfa116a..59fa3a1 100644
--- a/src/rust/bitbox02-rust/src/hal/testing/ui.rs
+++ b/src/rust/bitbox02-rust/src/hal/testing/ui.rs
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
use crate::hal::Ui;
-use crate::hal::ui::{ConfirmParams, EnterStringParams, TrinaryChoice, UserAbort};
-use crate::workflow::trinary_input_string;
+use crate::hal::ui::{CanCancel, ConfirmParams, EnterStringParams, TrinaryChoice, UserAbort};
use alloc::boxed::Box;
use alloc::string::String;
@@ -114,7 +113,7 @@ impl Ui for TestingUi<'_> {
async fn enter_string(
&mut self,
params: &EnterStringParams<'_>,
- _can_cancel: trinary_input_string::CanCancel,
+ _can_cancel: CanCancel,
_preset: &str,
) -> Result<zeroize::Zeroizing<String>, UserAbort> {
self._enter_string.as_mut().unwrap()(params).map(zeroize::Zeroizing::new)
diff --git a/src/rust/bitbox02-rust/src/hal/ui.rs b/src/rust/bitbox02-rust/src/hal/ui.rs
index 87d32d3..061edae 100644
--- a/src/rust/bitbox02-rust/src/hal/ui.rs
+++ b/src/rust/bitbox02-rust/src/hal/ui.rs
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
-use crate::workflow::{mnemonic, trinary_input_string};
+use crate::workflow::mnemonic;
use alloc::string::String;
@@ -56,6 +56,12 @@ pub enum TrinaryChoice {
Right,
}
+#[derive(Copy, Clone)]
+pub enum CanCancel {
+ No,
+ Yes,
+}
+
#[allow(async_fn_in_trait)]
pub trait Ui {
/// Returns `Ok(())` if the user accepts, `Err(UserAbort)` if the user rejects.
@@ -78,7 +84,7 @@ pub trait Ui {
async fn enter_string(
&mut self,
params: &EnterStringParams<'_>,
- can_cancel: trinary_input_string::CanCancel,
+ can_cancel: CanCancel,
preset: &str,
) -> Result<zeroize::Zeroizing<String>, UserAbort>;
diff --git a/src/rust/bitbox02-rust/src/hww/api/backup.rs b/src/rust/bitbox02-rust/src/hww/api/backup.rs
index 542dab3..66a5481 100644
--- a/src/rust/bitbox02-rust/src/hww/api/backup.rs
+++ b/src/rust/bitbox02-rust/src/hww/api/backup.rs
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
use super::Error;
-use crate::hal::ui::ConfirmParams;
+use crate::hal::ui::{CanCancel, ConfirmParams};
use crate::pb;
use alloc::vec::Vec;
@@ -89,7 +89,7 @@ pub async fn create(
let is_initialized = hal.memory().is_initialized();
let seed = if is_initialized {
- unlock::unlock_keystore(hal, "Unlock device", unlock::CanCancel::Yes).await?
+ unlock::unlock_keystore(hal, "Unlock device", CanCancel::Yes).await?
} else {
let seed = crate::keystore::copy_seed(hal)?;
// Yield now to give executor a chance to process USB/BLE communication, as copy_seed() causes
diff --git a/src/rust/bitbox02-rust/src/hww/api/bip85.rs b/src/rust/bitbox02-rust/src/hww/api/bip85.rs
index 2819a5f..65fbf69 100644
--- a/src/rust/bitbox02-rust/src/hww/api/bip85.rs
+++ b/src/rust/bitbox02-rust/src/hww/api/bip85.rs
@@ -31,8 +31,7 @@ pub async fn process(
/// Derives and displays a BIP-39 seed according to BIP-85:
/// https://github.com/bitcoin/bips/blob/master/bip-0085.mediawiki#bip39.
async fn process_bip39(hal: &mut impl crate::hal::Hal) -> Result<(), Error> {
- use crate::hal::ui::TrinaryChoice;
- use crate::workflow::trinary_input_string;
+ use crate::hal::ui::{CanCancel, TrinaryChoice};
hal.ui()
.confirm(&ConfirmParams {
@@ -82,7 +81,7 @@ async fn process_bip39(hal: &mut impl crate::hal::Hal) -> Result<(), Error> {
longtouch: true,
..Default::default()
},
- trinary_input_string::CanCancel::Yes,
+ CanCancel::Yes,
"",
)
.await?;
diff --git a/src/rust/bitbox02-rust/src/hww/api/bitcoin/registration.rs b/src/rust/bitbox02-rust/src/hww/api/bitcoin/registration.rs
index 40eb0de..37f54fc 100644
--- a/src/rust/bitbox02-rust/src/hww/api/bitcoin/registration.rs
+++ b/src/rust/bitbox02-rust/src/hww/api/bitcoin/registration.rs
@@ -14,8 +14,8 @@ use pb::btc_script_config::Config;
use super::multisig::SortXpubs;
+use crate::hal::ui::CanCancel;
use crate::hal::{Memory, Ui};
-use crate::workflow::trinary_input_string;
pub fn process_is_script_config_registered(
hal: &mut impl crate::hal::Hal,
@@ -80,7 +80,7 @@ async fn get_name(
longtouch: true,
..Default::default()
},
- trinary_input_string::CanCancel::Yes,
+ CanCancel::Yes,
"",
)
.await?;
diff --git a/src/rust/bitbox02-rust/src/hww/api/change_password.rs b/src/rust/bitbox02-rust/src/hww/api/change_password.rs
index ab47f9f..5c487ed 100644
--- a/src/rust/bitbox02-rust/src/hww/api/change_password.rs
+++ b/src/rust/bitbox02-rust/src/hww/api/change_password.rs
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
use super::Error;
-use crate::hal::ui::ConfirmParams;
+use crate::hal::ui::{CanCancel, ConfirmParams};
use crate::pb;
use pb::response::Response;
@@ -21,7 +21,7 @@ pub async fn process(hal: &mut impl crate::hal::Hal) -> Result<Response, Error>
})
.await?;
// Unlock with old password
- let seed = unlock::unlock_keystore(hal, "Unlock device", unlock::CanCancel::Yes).await?;
+ let seed = unlock::unlock_keystore(hal, "Unlock device", CanCancel::Yes).await?;
// Enter and confirm new password
let new_password = password::enter_twice(hal).await?;
diff --git a/src/rust/bitbox02-rust/src/hww/api/show_mnemonic.rs b/src/rust/bitbox02-rust/src/hww/api/show_mnemonic.rs
index 3a56d46..8949099 100644
--- a/src/rust/bitbox02-rust/src/hww/api/show_mnemonic.rs
+++ b/src/rust/bitbox02-rust/src/hww/api/show_mnemonic.rs
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
-use crate::hal::ui::ConfirmParams;
+use crate::hal::ui::{CanCancel, ConfirmParams};
use alloc::vec::Vec;
use super::Error;
@@ -18,7 +18,7 @@ use crate::workflow::unlock;
pub async fn process(hal: &mut impl crate::hal::Hal) -> Result<Response, Error> {
let mnemonic_sentence = {
let seed = if hal.memory().is_initialized() {
- unlock::unlock_keystore(hal, "Unlock device", unlock::CanCancel::Yes).await?
+ unlock::unlock_keystore(hal, "Unlock device", CanCancel::Yes).await?
} else {
crate::keystore::copy_seed(hal)?
};
diff --git a/src/rust/bitbox02-rust/src/workflow.rs b/src/rust/bitbox02-rust/src/workflow.rs
index 8380a6f..43b1524 100644
--- a/src/rust/bitbox02-rust/src/workflow.rs
+++ b/src/rust/bitbox02-rust/src/workflow.rs
@@ -9,7 +9,6 @@ pub mod orientation_screen;
pub mod pairing;
pub mod password;
pub mod transaction;
-pub mod trinary_input_string;
pub mod unlock;
pub mod unlock_animation;
pub mod verify_message;
diff --git a/src/rust/bitbox02-rust/src/workflow/mnemonic.rs b/src/rust/bitbox02-rust/src/workflow/mnemonic.rs
index 1add239..09fc028 100644
--- a/src/rust/bitbox02-rust/src/workflow/mnemonic.rs
+++ b/src/rust/bitbox02-rust/src/workflow/mnemonic.rs
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
-use super::trinary_input_string;
-use crate::hal::ui::{ConfirmParams, TrinaryChoice, UserAbort};
+use crate::hal::ui::{CanCancel, ConfirmParams, TrinaryChoice, UserAbort};
use alloc::string::String;
use alloc::vec::Vec;
@@ -241,7 +240,7 @@ async fn get_12th_18th_word(
wordlist: Some(&choices),
..Default::default()
},
- trinary_input_string::CanCancel::Yes,
+ CanCancel::Yes,
"",
)
.await?;
@@ -315,7 +314,7 @@ pub async fn get(
wordlist: Some(&bip39_wordlist),
..Default::default()
},
- trinary_input_string::CanCancel::Yes,
+ CanCancel::Yes,
preset,
)
.await
diff --git a/src/rust/bitbox02-rust/src/workflow/password.rs b/src/rust/bitbox02-rust/src/workflow/password.rs
index b15c42c..34a610c 100644
--- a/src/rust/bitbox02-rust/src/workflow/password.rs
+++ b/src/rust/bitbox02-rust/src/workflow/password.rs
@@ -1,13 +1,10 @@
// SPDX-License-Identifier: Apache-2.0
-use super::trinary_input_string;
use crate::hal::Ui;
-use crate::hal::ui::{ConfirmParams, UserAbort};
+use crate::hal::ui::{CanCancel, ConfirmParams, UserAbort};
use crate::hal::{Memory, memory::SecurechipType};
-pub use trinary_input_string::CanCancel;
-
use alloc::string::String;
async fn prompt_cancel(hal: &mut impl crate::hal::Hal) -> Result<(), crate::hal::ui::UserAbort> {
diff --git a/src/rust/bitbox02-rust/src/workflow/trinary_input_string.rs b/src/rust/bitbox02-rust/src/workflow/trinary_input_string.rs
deleted file mode 100644
index 1b0ceb3..0000000
--- a/src/rust/bitbox02-rust/src/workflow/trinary_input_string.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-#[derive(Copy, Clone)]
-pub enum CanCancel {
- No,
- Yes,
-}
diff --git a/src/rust/bitbox02-rust/src/workflow/unlock.rs b/src/rust/bitbox02-rust/src/workflow/unlock.rs
index 314aa4d..08fd8db 100644
--- a/src/rust/bitbox02-rust/src/workflow/unlock.rs
+++ b/src/rust/bitbox02-rust/src/workflow/unlock.rs
@@ -1,12 +1,10 @@
// SPDX-License-Identifier: Apache-2.0
use crate::general::abort;
-use crate::hal::ui::ConfirmParams;
+use crate::hal::ui::{CanCancel, ConfirmParams};
use crate::hal::{Memory, Ui};
use crate::workflow::password;
-pub use password::CanCancel;
-
use alloc::vec::Vec;
/// Confirm the entered mnemonic passphrase with the user. Returns true if the user confirmed it,
@@ -60,7 +58,7 @@ impl core::convert::From<password::EnterError> for UnlockError {
async fn maybe_confirm_remaining_unlock_attempts(
hal: &mut impl crate::hal::Hal,
- can_cancel: password::CanCancel,
+ can_cancel: CanCancel,
) -> Result<(), crate::hal::ui::UserAbort> {
let remaining = crate::keystore::get_remaining_unlock_attempts(hal);
if remaining >= crate::keystore::MAX_UNLOCK_ATTEMPTS {
@@ -86,7 +84,7 @@ async fn maybe_confirm_remaining_unlock_attempts(
body: &body,
accept_is_nextarrow: true,
longtouch: remaining == 1,
- accept_only: matches!(can_cancel, password::CanCancel::No),
+ accept_only: matches!(can_cancel, CanCancel::No),
..Default::default()
})
.await
@@ -103,7 +101,7 @@ async fn maybe_confirm_remaining_unlock_attempts(
pub async fn unlock_keystore(
hal: &mut impl crate::hal::Hal,
title: &str,
- can_cancel: password::CanCancel,
+ can_cancel: CanCancel,
) -> Result<zeroize::Zeroizing<Vec<u8>>, UnlockError> {
maybe_confirm_remaining_unlock_attempts(hal, can_cancel)
.await
@@ -145,7 +143,7 @@ pub async fn unlock_bip39(hal: &mut impl crate::hal::Hal, seed: &[u8]) {
hal,
"Optional passphrase",
password::PasswordType::Bip39Passphrase,
- password::CanCancel::No,
+ CanCancel::No,
)
.await
.expect("not cancelable and does not call memory functions");
@@ -197,7 +195,7 @@ pub async fn unlock(hal: &mut impl crate::hal::Hal) -> Result<(), ()> {
// Loop unlock until the password is correct or the device resets.
loop {
- if let Ok(seed) = unlock_keystore(hal, "Enter password", password::CanCancel::No).await {
+ if let Ok(seed) = unlock_keystore(hal, "Enter password", CanCancel::No).await {
unlock_bip39(hal, &seed).await;
return Ok(());
}
@@ -285,11 +283,7 @@ mod tests {
mock_hal.securechip.event_counter_reset();
assert!(matches!(
- block_on(unlock_keystore(
- &mut mock_hal,
- "title",
- password::CanCancel::No,
- )),
+ block_on(unlock_keystore(&mut mock_hal, "title", CanCancel::No,)),
Err(UnlockError::IncorrectPassword),
));
assert_eq!(mock_hal.securechip.get_event_counter(), 4);
@@ -336,11 +330,7 @@ mod tests {
}));
assert!(matches!(
- block_on(unlock_keystore(
- &mut mock_hal,
- "title",
- password::CanCancel::No,
- )),
+ block_on(unlock_keystore(&mut mock_hal, "title", CanCancel::No,)),
Err(UnlockError::IncorrectPassword),
));
@@ -374,11 +364,7 @@ mod tests {
mock_hal.ui.abort_nth(0);
assert!(matches!(
- block_on(unlock_keystore(
- &mut mock_hal,
- "title",
- password::CanCancel::No,
- )),
+ block_on(unlock_keystore(&mut mock_hal, "title", CanCancel::No,)),
Err(UnlockError::UserAbort),
));
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.