hal: split HAL sub-traits into modules
What changed, and why it matters
This commit is a simple code reorganization: it takes several related pieces of a hardware abstraction layer (HAL) that were all written in one large file and splits them into smaller, separate files. No behavior of the device or its security functions was changed. It is comparable to moving chapters of a book into individual files without rewriting the text.
No security action needed. Treat as routine maintenance/refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change is a pure refactor of Rust trait definitions in bitbox02-rust/src/hal.rs. The Sd, Random, SecureChip, Memory, and System traits are moved into new modules (hal/memory.rs, hal/random.rs, hal/sd.rs, hal/securechip.rs, hal/system.rs) and re-exported from hal.rs. Trait signatures, visibility, feature gates, and use statements are preserved. The only functional difference is a minor cleanup in get_encrypted_seed_and_hmac, where the return type tuple changes from (alloc::vec::Vec
Changed components
src/rust/bitbox02-rust/src/hal.rssrc/rust/bitbox02-rust/src/hal/memory.rssrc/rust/bitbox02-rust/src/hal/random.rssrc/rust/bitbox02-rust/src/hal/sd.rssrc/rust/bitbox02-rust/src/hal/securechip.rssrc/rust/bitbox02-rust/src/hal/system.rsInspect captured patch +115 / −89
diff --git a/src/rust/bitbox02-rust/src/hal.rs b/src/rust/bitbox02-rust/src/hal.rs
index ae1b9ec..8d4e16b 100644
--- a/src/rust/bitbox02-rust/src/hal.rs
+++ b/src/rust/bitbox02-rust/src/hal.rs
@@ -1,11 +1,22 @@
// SPDX-License-Identifier: Apache-2.0
+pub mod memory;
+pub mod random;
+pub mod sd;
+pub mod securechip;
+pub mod system;
pub mod ui;
-pub use ui::Ui;
#[cfg(feature = "testing")]
pub mod testing;
+pub use memory::Memory;
+pub use random::Random;
+pub use sd::Sd;
+pub use securechip::SecureChip;
+pub use system::System;
+pub use ui::Ui;
+
use alloc::boxed::Box;
use alloc::string::String;
use alloc::vec::Vec;
@@ -17,94 +28,6 @@ use crate::workflow::{
trinary_input_string,
};
-#[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<(), ()>;
-}
-
-pub trait Random {
- fn random_32_bytes(&mut self) -> Box<zeroize::Zeroizing<[u8; 32]>>;
-}
-
-pub trait SecureChip {
- fn init_new_password(
- &mut self,
- password: &str,
- password_stretch_algo: bitbox02::memory::PasswordStretchAlgo,
- ) -> Result<zeroize::Zeroizing<Vec<u8>>, bitbox02::securechip::Error>;
- fn stretch_password(
- &mut self,
- password: &str,
- password_stretch_algo: bitbox02::memory::PasswordStretchAlgo,
- ) -> Result<zeroize::Zeroizing<Vec<u8>>, bitbox02::securechip::Error>;
- fn kdf(
- &mut self,
- msg: &[u8],
- ) -> Result<zeroize::Zeroizing<Vec<u8>>, bitbox02::securechip::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<bitbox02::securechip::Model, ()>;
- fn reset_keys(&mut self) -> Result<(), ()>;
- #[cfg(feature = "app-u2f")]
- fn u2f_counter_set(&mut self, counter: u32) -> Result<(), ()>;
-}
-
-pub trait Memory {
- fn get_securechip_type(&mut self) -> Result<bitbox02::memory::SecurechipType, ()>;
- fn get_platform(&mut self) -> Result<bitbox02::memory::Platform, ()>;
- fn get_device_name(&mut self) -> String;
- fn set_device_name(&mut self, name: &str) -> Result<(), bitbox02::memory::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<(alloc::vec::Vec<u8>, bitbox02::memory::PasswordStretchAlgo), ()>;
- fn set_encrypted_seed_and_hmac(
- &mut self,
- data: &[u8],
- password_stretch_algo: bitbox02::memory::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<(), bitbox02::memory::MemoryError>;
- fn multisig_get_by_hash(&self, hash: &[u8; 32]) -> Option<String>;
-}
-
-pub trait System {
- fn reboot_to_bootloader(&mut self) -> !;
-}
-
/// Hardware abstraction layer for BitBox devices.
pub trait Hal {
fn ui(&mut self) -> &mut impl Ui;
diff --git a/src/rust/bitbox02-rust/src/hal/memory.rs b/src/rust/bitbox02-rust/src/hal/memory.rs
new file mode 100644
index 0000000..759af70
--- /dev/null
+++ b/src/rust/bitbox02-rust/src/hal/memory.rs
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: Apache-2.0
+
+use alloc::string::String;
+use alloc::vec::Vec;
+
+pub trait Memory {
+ fn get_securechip_type(&mut self) -> Result<bitbox02::memory::SecurechipType, ()>;
+ fn get_platform(&mut self) -> Result<bitbox02::memory::Platform, ()>;
+ fn get_device_name(&mut self) -> String;
+ fn set_device_name(&mut self, name: &str) -> Result<(), bitbox02::memory::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>, bitbox02::memory::PasswordStretchAlgo), ()>;
+ fn set_encrypted_seed_and_hmac(
+ &mut self,
+ data: &[u8],
+ password_stretch_algo: bitbox02::memory::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<(), bitbox02::memory::MemoryError>;
+ 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
new file mode 100644
index 0000000..84e534f
--- /dev/null
+++ b/src/rust/bitbox02-rust/src/hal/random.rs
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: Apache-2.0
+
+use alloc::boxed::Box;
+
+pub trait Random {
+ fn random_32_bytes(&mut self) -> Box<zeroize::Zeroizing<[u8; 32]>>;
+}
diff --git a/src/rust/bitbox02-rust/src/hal/sd.rs b/src/rust/bitbox02-rust/src/hal/sd.rs
new file mode 100644
index 0000000..aecf115
--- /dev/null
+++ b/src/rust/bitbox02-rust/src/hal/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/bitbox02-rust/src/hal/securechip.rs b/src/rust/bitbox02-rust/src/hal/securechip.rs
new file mode 100644
index 0000000..8f30596
--- /dev/null
+++ b/src/rust/bitbox02-rust/src/hal/securechip.rs
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: Apache-2.0
+
+use alloc::vec::Vec;
+
+pub trait SecureChip {
+ fn init_new_password(
+ &mut self,
+ password: &str,
+ password_stretch_algo: bitbox02::memory::PasswordStretchAlgo,
+ ) -> Result<zeroize::Zeroizing<Vec<u8>>, bitbox02::securechip::Error>;
+ fn stretch_password(
+ &mut self,
+ password: &str,
+ password_stretch_algo: bitbox02::memory::PasswordStretchAlgo,
+ ) -> Result<zeroize::Zeroizing<Vec<u8>>, bitbox02::securechip::Error>;
+ fn kdf(
+ &mut self,
+ msg: &[u8],
+ ) -> Result<zeroize::Zeroizing<Vec<u8>>, bitbox02::securechip::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<bitbox02::securechip::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
new file mode 100644
index 0000000..a2e6bee
--- /dev/null
+++ b/src/rust/bitbox02-rust/src/hal/system.rs
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: Apache-2.0
+
+pub trait System {
+ fn reboot_to_bootloader(&mut self) -> !;
+}
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.