hal: move hal traits/types from bitbox02-rust to new bitbox-hal
What changed, and why it matters
This commit is a routine code reorganization: it moves hardware-abstraction trait definitions (interfaces describing how the firmware talks to the screen, secure chip, memory, SD card, random number generator and system reboot) from one internal Rust crate to a newly created crate called bitbox-hal. No behavior of the actual device code is changed; it is purely a dependency and file move to avoid circular imports in the future.
No security action required. Treat as normal refactoring; standard code-review and CI verification are sufficient.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff creates a new workspace crate bitbox-hal containing the existing Memory, Random, Sd, SecureChip, System, and Ui traits (plus Hal, HalSubsystems, and related types) that were previously under bitbox02-rust/src/hal/. bitbox02-rust now depends on bitbox-hal and re-exports its contents via pub use bitbox_hal::*. Cargo workspace and lock files are updated accordingly. No implementation logic, trait signatures, or security-sensitive code paths are modified.
Changed components
src/rust/bitbox-hal (new crate)src/rust/bitbox02-rust/src/hal.rssrc/rust/Cargo.tomlsrc/rust/Cargo.locktest/simulator-graphical/Cargo.locktest/simulator-graphical-bb03/Cargo.lockInspect captured patch +400 / −351
diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock
index 04e5d44..ba8cc4f 100644
--- a/src/rust/Cargo.lock
+++ b/src/rust/Cargo.lock
@@ -120,6 +120,13 @@ dependencies = [
"util",
]
+[[package]]
+name = "bitbox-hal"
+version = "0.1.0"
+dependencies = [
+ "zeroize",
+]
+
[[package]]
name = "bitbox-secp256k1"
version = "0.1.0"
@@ -161,6 +168,7 @@ dependencies = [
"bip39",
"bitbox-aes",
"bitbox-executor",
+ "bitbox-hal",
"bitbox-secp256k1",
"bitbox02",
"bitbox02-noise",
diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml
index de495e7..0645e31 100644
--- a/src/rust/Cargo.toml
+++ b/src/rust/Cargo.toml
@@ -5,6 +5,7 @@
members = [
"bitbox02-rust-c",
"bitbox02-rust",
+ "bitbox-hal",
"bitbox-framed-serial-link",
"util",
"bitbox02-noise",
diff --git a/src/rust/bitbox-hal/Cargo.toml b/src/rust/bitbox-hal/Cargo.toml
new file mode 100644
index 0000000..bd9ae91
--- /dev/null
+++ b/src/rust/bitbox-hal/Cargo.toml
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: Apache-2.0
+
+[package]
+name = "bitbox-hal"
+version = "0.1.0"
+authors = ["Shift Crypto AG <support@bitbox.swiss>"]
+edition = "2024"
+license = "Apache-2.0"
+
+[dependencies]
+zeroize = { workspace = true }
+
+[features]
+app-u2f = []
diff --git a/src/rust/bitbox-hal/src/lib.rs b/src/rust/bitbox-hal/src/lib.rs
new file mode 100644
index 0000000..9620e3d
--- /dev/null
+++ b/src/rust/bitbox-hal/src/lib.rs
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: Apache-2.0
+
+#![no_std]
+
+extern crate alloc;
+
+pub mod memory;
+pub mod random;
+pub mod sd;
+pub mod securechip;
+pub mod system;
+pub mod ui;
+
+pub use memory::Memory;
+pub use random::Random;
+pub use sd::Sd;
+pub use securechip::SecureChip;
+pub use system::System;
+pub use ui::Ui;
+
+pub struct HalSubsystems<
+ 'a,
+ Ui: ui::Ui,
+ Random: random::Random,
+ Sd: sd::Sd,
+ SecureChip: securechip::SecureChip,
+ Memory: memory::Memory,
+ System: system::System,
+> {
+ pub ui: &'a mut Ui,
+ pub random: &'a mut Random,
+ pub sd: &'a mut Sd,
+ pub securechip: &'a mut SecureChip,
+ pub memory: &'a mut Memory,
+ pub system: &'a mut System,
+}
+
+/// Hardware abstraction layer for BitBox devices.
+pub trait Hal {
+ type Ui: ui::Ui;
+ type Random: random::Random;
+ type Sd: sd::Sd;
+ type SecureChip: securechip::SecureChip;
+ type Memory: memory::Memory;
+ type System: system::System;
+
+ fn subsystems(
+ &mut self,
+ ) -> HalSubsystems<
+ '_,
+ Self::Ui,
+ Self::Random,
+ Self::Sd,
+ Self::SecureChip,
+ Self::Memory,
+ Self::System,
+ >;
+
+ fn ui(&mut self) -> &mut Self::Ui {
+ self.subsystems().ui
+ }
+
+ fn random(&mut self) -> &mut Self::Random {
+ self.subsystems().random
+ }
+
+ fn sd(&mut self) -> &mut Self::Sd {
+ self.subsystems().sd
+ }
+
+ fn securechip(&mut self) -> &mut Self::SecureChip {
+ self.subsystems().securechip
+ }
+
+ fn memory(&mut self) -> &mut Self::Memory {
+ self.subsystems().memory
+ }
+
+ fn system(&mut self) -> &mut Self::System {
+ self.subsystems().system
+ }
+}
diff --git a/src/rust/bitbox-hal/src/memory.rs b/src/rust/bitbox-hal/src/memory.rs
new file mode 100644
index 0000000..232de91
--- /dev/null
+++ b/src/rust/bitbox-hal/src/memory.rs
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: Apache-2.0
+
+use alloc::string::String;
+use alloc::vec::Vec;
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum PasswordStretchAlgo {
+ V0,
+ V1,
+}
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum SecurechipType {
+ Atecc,
+ Optiga,
+}
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum Platform {
+ BitBox02,
+ BitBox02Plus,
+}
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum Error {
+ InvalidInput,
+ Full,
+ DuplicateName,
+ Unknown,
+}
+
+pub trait Memory {
+ fn ble_enabled(&mut self) -> bool;
+ fn ble_enable(&mut self, enable: bool) -> Result<(), ()>;
+ fn get_securechip_type(&mut self) -> Result<SecurechipType, ()>;
+ fn get_platform(&mut self) -> Result<Platform, ()>;
+ fn get_device_name(&mut self) -> String;
+ fn set_device_name(&mut self, name: &str) -> Result<(), Error>;
+ fn is_mnemonic_passphrase_enabled(&mut self) -> bool;
+ fn set_mnemonic_passphrase_enabled(&mut self, enabled: bool) -> Result<(), ()>;
+ fn set_seed_birthdate(&mut self, timestamp: u32) -> Result<(), ()>;
+ fn get_seed_birthdate(&mut self) -> u32;
+ fn is_seeded(&mut self) -> bool;
+ fn is_initialized(&mut self) -> bool;
+ fn set_initialized(&mut self) -> Result<(), ()>;
+ fn get_encrypted_seed_and_hmac(&mut self) -> Result<(Vec<u8>, PasswordStretchAlgo), ()>;
+ fn set_encrypted_seed_and_hmac(
+ &mut self,
+ data: &[u8],
+ password_stretch_algo: PasswordStretchAlgo,
+ ) -> Result<(), ()>;
+ fn reset_hww(&mut self) -> Result<(), ()>;
+ fn get_unlock_attempts(&mut self) -> u8;
+ fn increment_unlock_attempts(&mut self);
+ fn reset_unlock_attempts(&mut self);
+ fn get_salt_root(&mut self) -> Result<zeroize::Zeroizing<Vec<u8>>, ()>;
+ fn get_attestation_pubkey_and_certificate(
+ &mut self,
+ pubkey_out: &mut [u8; 64],
+ certificate_out: &mut [u8; 64],
+ root_pubkey_identifier_out: &mut [u8; 32],
+ ) -> Result<(), ()>;
+ fn get_attestation_bootloader_hash(&mut self) -> [u8; 32];
+ fn multisig_set_by_hash(&mut self, hash: &[u8; 32], name: &str) -> Result<(), Error>;
+ fn multisig_get_by_hash(&self, hash: &[u8; 32]) -> Option<String>;
+}
diff --git a/src/rust/bitbox-hal/src/random.rs b/src/rust/bitbox-hal/src/random.rs
new file mode 100644
index 0000000..1536f76
--- /dev/null
+++ b/src/rust/bitbox-hal/src/random.rs
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: Apache-2.0
+
+use alloc::boxed::Box;
+
+pub trait Random {
+ fn random_32_bytes(&mut self) -> Box<zeroize::Zeroizing<[u8; 32]>>;
+ fn mcu_32_bytes(&mut self, out: &mut [u8; 32]);
+}
diff --git a/src/rust/bitbox-hal/src/sd.rs b/src/rust/bitbox-hal/src/sd.rs
new file mode 100644
index 0000000..aecf115
--- /dev/null
+++ b/src/rust/bitbox-hal/src/sd.rs
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: Apache-2.0
+
+use alloc::string::String;
+use alloc::vec::Vec;
+
+#[allow(async_fn_in_trait)]
+pub trait Sd {
+ async fn sdcard_inserted(&mut self) -> bool;
+ async fn list_subdir(&mut self, subdir: Option<&str>) -> Result<Vec<String>, ()>;
+ async fn erase_file_in_subdir(&mut self, filename: &str, dir: &str) -> Result<(), ()>;
+ async fn load_bin(
+ &mut self,
+ filename: &str,
+ dir: &str,
+ ) -> Result<zeroize::Zeroizing<Vec<u8>>, ()>;
+ async fn write_bin(&mut self, filename: &str, dir: &str, data: &[u8]) -> Result<(), ()>;
+}
diff --git a/src/rust/bitbox-hal/src/securechip.rs b/src/rust/bitbox-hal/src/securechip.rs
new file mode 100644
index 0000000..ed64b1c
--- /dev/null
+++ b/src/rust/bitbox-hal/src/securechip.rs
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: Apache-2.0
+
+use alloc::vec::Vec;
+
+use super::memory::PasswordStretchAlgo;
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum Model {
+ Atecc608A,
+ Atecc608B,
+ OptigaTrustM3,
+}
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum Error {
+ SecureChip(SecureChipError),
+ Status(i32),
+}
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[repr(i32)]
+// Keep in sync with securechip.h's securechip_error_t.
+pub enum SecureChipError {
+ // Errors common to any securechip implementation
+ Ifs = -1,
+ InvalidArgs = -2,
+ ConfigMismatch = -3,
+ Salt = -4,
+ // Currently only used by Optiga, but it is in the common errors so that the API of the
+ // securechip is consistent and the caller does not need to distinguish between the chips at
+ // the callsite.
+ IncorrectPassword = -6,
+ // The password stretch algo is not supported
+ InvalidPasswordStretchAlgo = -7,
+ Memory = -8,
+ // Errors specific to the ATECC
+ AteccZoneUnlockedConfig = -100,
+ AteccZoneUnlockedData = -101,
+ AteccSlotUnlockedIo = -103,
+ AteccSlotUnlockedAuth = -104,
+ AteccSlotUnlockedEnc = -105,
+ AteccResetKeys = -106,
+ // Errors specific to the Optiga
+ OptigaCreate = -201,
+ OptigaUnexpectedMetadata = -204,
+ OptigaPal = -205,
+ OptigaUnexpectedLen = -206,
+}
+
+pub trait SecureChip {
+ fn init_new_password(
+ &mut self,
+ password: &str,
+ password_stretch_algo: PasswordStretchAlgo,
+ ) -> Result<zeroize::Zeroizing<Vec<u8>>, Error>;
+ fn stretch_password(
+ &mut self,
+ password: &str,
+ password_stretch_algo: PasswordStretchAlgo,
+ ) -> Result<zeroize::Zeroizing<Vec<u8>>, Error>;
+ fn kdf(&mut self, msg: &[u8]) -> Result<zeroize::Zeroizing<Vec<u8>>, Error>;
+ fn attestation_sign(
+ &mut self,
+ challenge: &[u8; 32],
+ signature: &mut [u8; 64],
+ ) -> Result<(), ()>;
+ fn monotonic_increments_remaining(&mut self) -> Result<u32, ()>;
+ fn model(&mut self) -> Result<Model, ()>;
+ fn reset_keys(&mut self) -> Result<(), ()>;
+ #[cfg(feature = "app-u2f")]
+ fn u2f_counter_set(&mut self, counter: u32) -> Result<(), ()>;
+}
diff --git a/src/rust/bitbox-hal/src/system.rs b/src/rust/bitbox-hal/src/system.rs
new file mode 100644
index 0000000..a2e6bee
--- /dev/null
+++ b/src/rust/bitbox-hal/src/system.rs
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: Apache-2.0
+
+pub trait System {
+ fn reboot_to_bootloader(&mut self) -> !;
+}
diff --git a/src/rust/bitbox-hal/src/ui.rs b/src/rust/bitbox-hal/src/ui.rs
new file mode 100644
index 0000000..c41baa8
--- /dev/null
+++ b/src/rust/bitbox-hal/src/ui.rs
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: Apache-2.0
+
+use alloc::string::String;
+
+pub struct UserAbort;
+
+#[derive(Copy, Clone, Default)]
+pub enum Font {
+ #[default]
+ Default,
+ Password11X12,
+ Monogram5X9,
+}
+
+#[derive(Default)]
+pub struct ConfirmParams<'a> {
+ /// The confirmation title of the screen. Max 200 chars, otherwise **panic**.
+ pub title: &'a str,
+ pub title_autowrap: bool,
+ /// The confirmation body of the screen. Max 200 chars, otherwise **panic**.
+ pub body: &'a str,
+ pub font: Font,
+ /// If true, the body is horizontally scrollable.
+ pub scrollable: bool,
+ /// If true, require the hold gesture to confirm instead of tap.
+ pub longtouch: bool,
+ /// If true, the user can only confirm, not reject.
+ pub accept_only: bool,
+ /// if true, the accept icon is a right arrow instead of a checkmark (indicating going to the
+ /// "next" screen).
+ pub accept_is_nextarrow: bool,
+ /// Print the value of this variable in the corner. Will not print when 0
+ pub display_size: usize,
+}
+
+#[derive(Default)]
+pub struct EnterStringParams<'a> {
+ /// The confirmation title of the screen. Max 200 chars, otherwise **panic**.
+ pub title: &'a str,
+ /// Currently specialized to the BIP39 wordlist: a list of BIP39 word indices. Can be extended if needed.
+ pub wordlist: Option<&'a [u16]>,
+ pub number_input: bool,
+ pub hide: bool,
+ pub special_chars: bool,
+ pub longtouch: bool,
+ pub cancel_is_backbutton: bool,
+ pub default_to_digits: bool,
+}
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub enum TrinaryChoice {
+ Left,
+ Middle,
+ 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.
+ async fn confirm(&mut self, params: &ConfirmParams<'_>) -> Result<(), UserAbort>;
+
+ async fn verify_recipient(&mut self, recipient: &str, amount: &str) -> Result<(), UserAbort>;
+
+ async fn verify_total_fee(
+ &mut self,
+ total: &str,
+ fee: &str,
+ longtouch: bool,
+ ) -> Result<(), UserAbort>;
+
+ async fn status(&mut self, title: &str, status_success: bool);
+
+ /// If `can_cancel` is `Yes`, the workflow can be cancelled.
+ /// If it is `No`, the result is always `Ok(())`.
+ /// If `preset` is not empty, it must be part of `params.wordlist` and will be pre-entered.
+ async fn enter_string(
+ &mut self,
+ params: &EnterStringParams<'_>,
+ can_cancel: CanCancel,
+ preset: &str,
+ ) -> Result<zeroize::Zeroizing<String>, UserAbort>;
+
+ async fn insert_sdcard(&mut self) -> Result<(), UserAbort>;
+
+ /// Returns the index of the word chosen by the user.
+ async fn menu(&mut self, words: &[&str], title: Option<&str>) -> Result<u8, UserAbort>;
+
+ async fn trinary_choice(
+ &mut self,
+ message: &str,
+ label_left: Option<&str>,
+ label_middle: Option<&str>,
+ label_right: Option<&str>,
+ ) -> TrinaryChoice;
+
+ /// Display the BIP39 mnemonic to the user.
+ async fn show_mnemonic(&mut self, words: &[&str]) -> Result<(), UserAbort>;
+
+ /// Display these BIP39 mnemonic word choices to the user as part of the quiz to confirm the
+ /// user backuped up the mnemonic correctly.
+ async fn quiz_mnemonic_word(&mut self, choices: &[&str], title: &str) -> Result<u8, UserAbort>;
+}
diff --git a/src/rust/bitbox02-rust/Cargo.toml b/src/rust/bitbox02-rust/Cargo.toml
index d6c5389..4639a70 100644
--- a/src/rust/bitbox02-rust/Cargo.toml
+++ b/src/rust/bitbox02-rust/Cargo.toml
@@ -14,6 +14,7 @@ license = "Apache-2.0"
doctest = false
[dependencies]
+bitbox-hal = { path = "../bitbox-hal" }
bitbox02 = { path = "../bitbox02" }
bitbox-secp256k1 = { path = "../bitbox-secp256k1" }
util = { path = "../util" }
@@ -81,6 +82,7 @@ app-litecoin = [
]
app-u2f = [
+ "bitbox-hal/app-u2f",
"bitbox02/app-u2f",
]
diff --git a/src/rust/bitbox02-rust/src/hal.rs b/src/rust/bitbox02-rust/src/hal.rs
index 764f4a6..791d78b 100644
--- a/src/rust/bitbox02-rust/src/hal.rs
+++ b/src/rust/bitbox02-rust/src/hal.rs
@@ -1,83 +1,9 @@
// SPDX-License-Identifier: Apache-2.0
pub mod bitbox02;
-pub mod memory;
-pub mod random;
-pub mod sd;
-pub mod securechip;
-pub mod system;
-pub mod ui;
#[cfg(feature = "testing")]
pub mod testing;
+pub use bitbox_hal::*;
pub use bitbox02::BitBox02Hal;
-pub use memory::Memory;
-pub use random::Random;
-pub use sd::Sd;
-pub use securechip::SecureChip;
-pub use system::System;
-pub use ui::Ui;
-
-pub struct HalSubsystems<
- 'a,
- Ui: ui::Ui,
- Random: random::Random,
- Sd: sd::Sd,
- SecureChip: securechip::SecureChip,
- Memory: memory::Memory,
- System: system::System,
-> {
- pub ui: &'a mut Ui,
- pub random: &'a mut Random,
- pub sd: &'a mut Sd,
- pub securechip: &'a mut SecureChip,
- pub memory: &'a mut Memory,
- pub system: &'a mut System,
-}
-
-/// Hardware abstraction layer for BitBox devices.
-pub trait Hal {
- type Ui: ui::Ui;
- type Random: random::Random;
- type Sd: sd::Sd;
- type SecureChip: securechip::SecureChip;
- type Memory: memory::Memory;
- type System: system::System;
-
- fn subsystems(
- &mut self,
- ) -> HalSubsystems<
- '_,
- Self::Ui,
- Self::Random,
- Self::Sd,
- Self::SecureChip,
- Self::Memory,
- Self::System,
- >;
-
- fn ui(&mut self) -> &mut Self::Ui {
- self.subsystems().ui
- }
-
- fn random(&mut self) -> &mut Self::Random {
- self.subsystems().random
- }
-
- fn sd(&mut self) -> &mut Self::Sd {
- self.subsystems().sd
- }
-
- fn securechip(&mut self) -> &mut Self::SecureChip {
- self.subsystems().securechip
- }
-
- fn memory(&mut self) -> &mut Self::Memory {
- self.subsystems().memory
- }
-
- fn system(&mut self) -> &mut Self::System {
- self.subsystems().system
- }
-}
diff --git a/src/rust/bitbox02-rust/src/hal/memory.rs b/src/rust/bitbox02-rust/src/hal/memory.rs
deleted file mode 100644
index 232de91..0000000
--- a/src/rust/bitbox02-rust/src/hal/memory.rs
+++ /dev/null
@@ -1,66 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-use alloc::string::String;
-use alloc::vec::Vec;
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub enum PasswordStretchAlgo {
- V0,
- V1,
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub enum SecurechipType {
- Atecc,
- Optiga,
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub enum Platform {
- BitBox02,
- BitBox02Plus,
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub enum Error {
- InvalidInput,
- Full,
- DuplicateName,
- Unknown,
-}
-
-pub trait Memory {
- fn ble_enabled(&mut self) -> bool;
- fn ble_enable(&mut self, enable: bool) -> Result<(), ()>;
- fn get_securechip_type(&mut self) -> Result<SecurechipType, ()>;
- fn get_platform(&mut self) -> Result<Platform, ()>;
- fn get_device_name(&mut self) -> String;
- fn set_device_name(&mut self, name: &str) -> Result<(), Error>;
- fn is_mnemonic_passphrase_enabled(&mut self) -> bool;
- fn set_mnemonic_passphrase_enabled(&mut self, enabled: bool) -> Result<(), ()>;
- fn set_seed_birthdate(&mut self, timestamp: u32) -> Result<(), ()>;
- fn get_seed_birthdate(&mut self) -> u32;
- fn is_seeded(&mut self) -> bool;
- fn is_initialized(&mut self) -> bool;
- fn set_initialized(&mut self) -> Result<(), ()>;
- fn get_encrypted_seed_and_hmac(&mut self) -> Result<(Vec<u8>, PasswordStretchAlgo), ()>;
- fn set_encrypted_seed_and_hmac(
- &mut self,
- data: &[u8],
- password_stretch_algo: PasswordStretchAlgo,
- ) -> Result<(), ()>;
- fn reset_hww(&mut self) -> Result<(), ()>;
- fn get_unlock_attempts(&mut self) -> u8;
- fn increment_unlock_attempts(&mut self);
- fn reset_unlock_attempts(&mut self);
- fn get_salt_root(&mut self) -> Result<zeroize::Zeroizing<Vec<u8>>, ()>;
- fn get_attestation_pubkey_and_certificate(
- &mut self,
- pubkey_out: &mut [u8; 64],
- certificate_out: &mut [u8; 64],
- root_pubkey_identifier_out: &mut [u8; 32],
- ) -> Result<(), ()>;
- fn get_attestation_bootloader_hash(&mut self) -> [u8; 32];
- fn multisig_set_by_hash(&mut self, hash: &[u8; 32], name: &str) -> Result<(), Error>;
- fn multisig_get_by_hash(&self, hash: &[u8; 32]) -> Option<String>;
-}
diff --git a/src/rust/bitbox02-rust/src/hal/random.rs b/src/rust/bitbox02-rust/src/hal/random.rs
deleted file mode 100644
index 1536f76..0000000
--- a/src/rust/bitbox02-rust/src/hal/random.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-use alloc::boxed::Box;
-
-pub trait Random {
- fn random_32_bytes(&mut self) -> Box<zeroize::Zeroizing<[u8; 32]>>;
- fn mcu_32_bytes(&mut self, out: &mut [u8; 32]);
-}
diff --git a/src/rust/bitbox02-rust/src/hal/sd.rs b/src/rust/bitbox02-rust/src/hal/sd.rs
deleted file mode 100644
index aecf115..0000000
--- a/src/rust/bitbox02-rust/src/hal/sd.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-use alloc::string::String;
-use alloc::vec::Vec;
-
-#[allow(async_fn_in_trait)]
-pub trait Sd {
- async fn sdcard_inserted(&mut self) -> bool;
- async fn list_subdir(&mut self, subdir: Option<&str>) -> Result<Vec<String>, ()>;
- async fn erase_file_in_subdir(&mut self, filename: &str, dir: &str) -> Result<(), ()>;
- async fn load_bin(
- &mut self,
- filename: &str,
- dir: &str,
- ) -> Result<zeroize::Zeroizing<Vec<u8>>, ()>;
- async fn write_bin(&mut self, filename: &str, dir: &str, data: &[u8]) -> Result<(), ()>;
-}
diff --git a/src/rust/bitbox02-rust/src/hal/securechip.rs b/src/rust/bitbox02-rust/src/hal/securechip.rs
deleted file mode 100644
index ed64b1c..0000000
--- a/src/rust/bitbox02-rust/src/hal/securechip.rs
+++ /dev/null
@@ -1,72 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-use alloc::vec::Vec;
-
-use super::memory::PasswordStretchAlgo;
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub enum Model {
- Atecc608A,
- Atecc608B,
- OptigaTrustM3,
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub enum Error {
- SecureChip(SecureChipError),
- Status(i32),
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-#[repr(i32)]
-// Keep in sync with securechip.h's securechip_error_t.
-pub enum SecureChipError {
- // Errors common to any securechip implementation
- Ifs = -1,
- InvalidArgs = -2,
- ConfigMismatch = -3,
- Salt = -4,
- // Currently only used by Optiga, but it is in the common errors so that the API of the
- // securechip is consistent and the caller does not need to distinguish between the chips at
- // the callsite.
- IncorrectPassword = -6,
- // The password stretch algo is not supported
- InvalidPasswordStretchAlgo = -7,
- Memory = -8,
- // Errors specific to the ATECC
- AteccZoneUnlockedConfig = -100,
- AteccZoneUnlockedData = -101,
- AteccSlotUnlockedIo = -103,
- AteccSlotUnlockedAuth = -104,
- AteccSlotUnlockedEnc = -105,
- AteccResetKeys = -106,
- // Errors specific to the Optiga
- OptigaCreate = -201,
- OptigaUnexpectedMetadata = -204,
- OptigaPal = -205,
- OptigaUnexpectedLen = -206,
-}
-
-pub trait SecureChip {
- fn init_new_password(
- &mut self,
- password: &str,
- password_stretch_algo: PasswordStretchAlgo,
- ) -> Result<zeroize::Zeroizing<Vec<u8>>, Error>;
- fn stretch_password(
- &mut self,
- password: &str,
- password_stretch_algo: PasswordStretchAlgo,
- ) -> Result<zeroize::Zeroizing<Vec<u8>>, Error>;
- fn kdf(&mut self, msg: &[u8]) -> Result<zeroize::Zeroizing<Vec<u8>>, Error>;
- fn attestation_sign(
- &mut self,
- challenge: &[u8; 32],
- signature: &mut [u8; 64],
- ) -> Result<(), ()>;
- fn monotonic_increments_remaining(&mut self) -> Result<u32, ()>;
- fn model(&mut self) -> Result<Model, ()>;
- fn reset_keys(&mut self) -> Result<(), ()>;
- #[cfg(feature = "app-u2f")]
- fn u2f_counter_set(&mut self, counter: u32) -> Result<(), ()>;
-}
diff --git a/src/rust/bitbox02-rust/src/hal/system.rs b/src/rust/bitbox02-rust/src/hal/system.rs
deleted file mode 100644
index a2e6bee..0000000
--- a/src/rust/bitbox02-rust/src/hal/system.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-pub trait System {
- fn reboot_to_bootloader(&mut self) -> !;
-}
diff --git a/src/rust/bitbox02-rust/src/hal/ui.rs b/src/rust/bitbox02-rust/src/hal/ui.rs
deleted file mode 100644
index c41baa8..0000000
--- a/src/rust/bitbox02-rust/src/hal/ui.rs
+++ /dev/null
@@ -1,108 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-use alloc::string::String;
-
-pub struct UserAbort;
-
-#[derive(Copy, Clone, Default)]
-pub enum Font {
- #[default]
- Default,
- Password11X12,
- Monogram5X9,
-}
-
-#[derive(Default)]
-pub struct ConfirmParams<'a> {
- /// The confirmation title of the screen. Max 200 chars, otherwise **panic**.
- pub title: &'a str,
- pub title_autowrap: bool,
- /// The confirmation body of the screen. Max 200 chars, otherwise **panic**.
- pub body: &'a str,
- pub font: Font,
- /// If true, the body is horizontally scrollable.
- pub scrollable: bool,
- /// If true, require the hold gesture to confirm instead of tap.
- pub longtouch: bool,
- /// If true, the user can only confirm, not reject.
- pub accept_only: bool,
- /// if true, the accept icon is a right arrow instead of a checkmark (indicating going to the
- /// "next" screen).
- pub accept_is_nextarrow: bool,
- /// Print the value of this variable in the corner. Will not print when 0
- pub display_size: usize,
-}
-
-#[derive(Default)]
-pub struct EnterStringParams<'a> {
- /// The confirmation title of the screen. Max 200 chars, otherwise **panic**.
- pub title: &'a str,
- /// Currently specialized to the BIP39 wordlist: a list of BIP39 word indices. Can be extended if needed.
- pub wordlist: Option<&'a [u16]>,
- pub number_input: bool,
- pub hide: bool,
- pub special_chars: bool,
- pub longtouch: bool,
- pub cancel_is_backbutton: bool,
- pub default_to_digits: bool,
-}
-
-#[derive(Copy, Clone, Eq, PartialEq)]
-pub enum TrinaryChoice {
- Left,
- Middle,
- 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.
- async fn confirm(&mut self, params: &ConfirmParams<'_>) -> Result<(), UserAbort>;
-
- async fn verify_recipient(&mut self, recipient: &str, amount: &str) -> Result<(), UserAbort>;
-
- async fn verify_total_fee(
- &mut self,
- total: &str,
- fee: &str,
- longtouch: bool,
- ) -> Result<(), UserAbort>;
-
- async fn status(&mut self, title: &str, status_success: bool);
-
- /// If `can_cancel` is `Yes`, the workflow can be cancelled.
- /// If it is `No`, the result is always `Ok(())`.
- /// If `preset` is not empty, it must be part of `params.wordlist` and will be pre-entered.
- async fn enter_string(
- &mut self,
- params: &EnterStringParams<'_>,
- can_cancel: CanCancel,
- preset: &str,
- ) -> Result<zeroize::Zeroizing<String>, UserAbort>;
-
- async fn insert_sdcard(&mut self) -> Result<(), UserAbort>;
-
- /// Returns the index of the word chosen by the user.
- async fn menu(&mut self, words: &[&str], title: Option<&str>) -> Result<u8, UserAbort>;
-
- async fn trinary_choice(
- &mut self,
- message: &str,
- label_left: Option<&str>,
- label_middle: Option<&str>,
- label_right: Option<&str>,
- ) -> TrinaryChoice;
-
- /// Display the BIP39 mnemonic to the user.
- async fn show_mnemonic(&mut self, words: &[&str]) -> Result<(), UserAbort>;
-
- /// Display these BIP39 mnemonic word choices to the user as part of the quiz to confirm the
- /// user backuped up the mnemonic correctly.
- async fn quiz_mnemonic_word(&mut self, choices: &[&str], title: &str) -> Result<u8, UserAbort>;
-}
diff --git a/test/simulator-graphical-bb03/Cargo.lock b/test/simulator-graphical-bb03/Cargo.lock
index 2c4cb6c..8c2c4a5 100644
--- a/test/simulator-graphical-bb03/Cargo.lock
+++ b/test/simulator-graphical-bb03/Cargo.lock
@@ -345,6 +345,13 @@ dependencies = [
"util",
]
+[[package]]
+name = "bitbox-hal"
+version = "0.1.0"
+dependencies = [
+ "zeroize",
+]
+
[[package]]
name = "bitbox-secp256k1"
version = "0.1.0"
@@ -381,6 +388,7 @@ dependencies = [
"bip39",
"bitbox-aes",
"bitbox-executor",
+ "bitbox-hal",
"bitbox-secp256k1",
"bitbox02",
"bitbox02-noise",
diff --git a/test/simulator-graphical/Cargo.lock b/test/simulator-graphical/Cargo.lock
index ed5d921..c51abc2 100644
--- a/test/simulator-graphical/Cargo.lock
+++ b/test/simulator-graphical/Cargo.lock
@@ -307,6 +307,13 @@ dependencies = [
"util",
]
+[[package]]
+name = "bitbox-hal"
+version = "0.1.0"
+dependencies = [
+ "zeroize",
+]
+
[[package]]
name = "bitbox-secp256k1"
version = "0.1.0"
@@ -343,6 +350,7 @@ dependencies = [
"bip39",
"bitbox-aes",
"bitbox-executor",
+ "bitbox-hal",
"bitbox-secp256k1",
"bitbox02",
"bitbox02-noise",
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.