make rust_async_usb_on_request_hww use HalImpl
What changed, and why it matters
This commit is a straightforward internal code cleanup: it moves where a hardware-abstraction object is created so that a Rust library no longer directly depends on a specific device implementation. There is no user-facing change, no bug fix, and no security vulnerability visible in the diff.
No security action required. Treat as normal refactoring/dependency cleanup.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change refactors process_packet in bitbox02-rust/src/hww.rs to accept a &mut impl Hal parameter instead of instantiating BitBox02Hal internally. The C/Rust boundary in bitbox02-rust-c/src/async_usb.rs now constructs HalImpl and passes it into process_packet. Simulators are updated to import BitBox02Hal from bitbox02::hal rather than bitbox02_rust::hal. This is an architectural decoupling change with no functional or security-relevant behavior change.
Changed components
src/rust/bitbox02-rust-c/src/async_usb.rssrc/rust/bitbox02-rust/src/hal.rssrc/rust/bitbox02-rust/src/hww.rstest/simulator-graphical-bb03/src/main.rstest/simulator-graphical/src/main.rsInspect captured patch +23 / −21
diff --git a/src/rust/bitbox02-rust-c/src/async_usb.rs b/src/rust/bitbox02-rust-c/src/async_usb.rs
index 6345ff2..2d78099 100644
--- a/src/rust/bitbox02-rust-c/src/async_usb.rs
+++ b/src/rust/bitbox02-rust-c/src/async_usb.rs
@@ -2,8 +2,16 @@
#![allow(clippy::missing_safety_doc)]
+extern crate alloc;
+
+use crate::HalImpl;
+use alloc::vec::Vec;
use bitbox02_rust::async_usb::{on_next_request, spawn, waiting_for_next_request};
-use bitbox02_rust::hww::process_packet;
+
+async fn process_packet_with_hal(usb_in: Vec<u8>) -> Vec<u8> {
+ let mut hal = HalImpl::new();
+ bitbox02_rust::hww::process_packet(&mut hal, usb_in).await
+}
#[unsafe(no_mangle)]
pub extern "C" fn rust_async_usb_spin() {
@@ -46,7 +54,7 @@ pub extern "C" fn rust_async_usb_on_request_hww(usb_in: util::bytes::Bytes) {
if waiting_for_next_request() {
on_next_request(usb_in.as_ref());
} else {
- spawn(process_packet, usb_in.as_ref());
+ spawn(process_packet_with_hal, usb_in.as_ref());
}
}
diff --git a/src/rust/bitbox02-rust/src/hal.rs b/src/rust/bitbox02-rust/src/hal.rs
index fdd0d72..0ff8e44 100644
--- a/src/rust/bitbox02-rust/src/hal.rs
+++ b/src/rust/bitbox02-rust/src/hal.rs
@@ -4,4 +4,3 @@
pub mod testing;
pub use bitbox_hal::*;
-pub use bitbox02::hal::BitBox02Hal;
diff --git a/src/rust/bitbox02-rust/src/hww.rs b/src/rust/bitbox02-rust/src/hww.rs
index 1ad553b..2111f30 100644
--- a/src/rust/bitbox02-rust/src/hww.rs
+++ b/src/rust/bitbox02-rust/src/hww.rs
@@ -98,7 +98,10 @@ fn api_attestation(hal: &mut impl crate::hal::Hal, usb_in: &[u8]) -> Vec<u8> {
out
}
-async fn _process_packet(hal: &mut impl crate::hal::Hal, usb_in: Vec<u8>) -> Vec<u8> {
+/// Async HWW api processing main entry point.
+/// `usb_in` - api request bytes.
+/// Returns the usb response bytes.
+pub async fn process_packet(hal: &mut impl crate::hal::Hal, usb_in: Vec<u8>) -> Vec<u8> {
// Update the waiting screen from "See the BitBoxApp" to the logo, now that the host is
// connected. When the device is initialized, we delay this until the unlock call, otherwise
// there would be a flicker where the logo would be shown before the host invokes unlock.
@@ -119,14 +122,6 @@ async fn _process_packet(hal: &mut impl crate::hal::Hal, usb_in: Vec<u8>) -> Vec
}
}
-/// Async HWW api processing main entry point.
-/// `usb_in` - api request bytes.
-/// Returns the usb response bytes.
-pub async fn process_packet(usb_in: Vec<u8>) -> Vec<u8> {
- let hal = &mut crate::hal::BitBox02Hal::new();
- _process_packet(hal, usb_in).await
-}
-
#[cfg(test)]
mod tests {
use super::*;
@@ -147,13 +142,13 @@ mod tests {
/// encrypts the message going in and decrypts the message coming out.
fn init_noise<H: crate::hal::Hal>() -> Box<dyn FnMut(&mut H, &[u8]) -> Result<Vec<u8>, ()>> {
assert_eq!(
- block_on(_process_packet(&mut TestingHal::new(), b"h".to_vec())),
+ block_on(process_packet(&mut TestingHal::new(), b"h".to_vec())),
[OP_STATUS_SUCCESS].to_vec()
);
let mut host_noise = bitbox02_noise::testing::make_host();
let host_handshake_1 = host_noise.write_message_vec(b"").unwrap();
let bb02_handshake_1 = {
- let result = block_on(_process_packet(&mut TestingHal::new(), {
+ let result = block_on(process_packet(&mut TestingHal::new(), {
let mut m = b"H".to_vec(); // handshake opcode
m.extend_from_slice(&host_handshake_1);
m
@@ -169,7 +164,7 @@ mod tests {
host_noise.write_message_vec(&payload).unwrap()
};
- let response = block_on(_process_packet(&mut TestingHal::new(), {
+ let response = block_on(process_packet(&mut TestingHal::new(), {
let mut m = b"H".to_vec(); // handshake opcode
m.extend_from_slice(&host_handshake_2);
m
@@ -190,7 +185,7 @@ mod tests {
let mut mock_hal = TestingHal::new();
assert_eq!(
- block_on(_process_packet(&mut mock_hal, b"v".to_vec())),
+ block_on(process_packet(&mut mock_hal, b"v".to_vec())),
[OP_STATUS_SUCCESS].to_vec()
);
assert_eq!(
@@ -206,7 +201,7 @@ mod tests {
let (mut host_send, mut host_recv) = host_noise.get_ciphers();
Box::new(move |hal, msg| -> Result<Vec<u8>, ()> {
let msg_encrypted = host_send.encrypt_vec(msg);
- let response_encrypted = block_on(_process_packet(hal, {
+ let response_encrypted = block_on(process_packet(hal, {
let mut m = b"n".to_vec(); // message opcode
m.extend_from_slice(&msg_encrypted);
m
@@ -223,7 +218,7 @@ mod tests {
fn test_cant_unlock() {
mock_memory();
assert_eq!(
- block_on(_process_packet(&mut TestingHal::new(), vec![OP_UNLOCK])),
+ block_on(process_packet(&mut TestingHal::new(), vec![OP_UNLOCK])),
[OP_STATUS_FAILURE_UNINITIALIZED].to_vec()
);
}
@@ -441,7 +436,7 @@ mod tests {
.ui
.set_enter_string(Box::new(|_params| Ok("password".into())));
assert_eq!(
- block_on(_process_packet(&mut mock_hal, vec![OP_UNLOCK])),
+ block_on(process_packet(&mut mock_hal, vec![OP_UNLOCK])),
[OP_STATUS_SUCCESS].to_vec()
);
assert!(!crate::keystore::is_locked());
diff --git a/test/simulator-graphical-bb03/src/main.rs b/test/simulator-graphical-bb03/src/main.rs
index f3e412e..6cfe487 100644
--- a/test/simulator-graphical-bb03/src/main.rs
+++ b/test/simulator-graphical-bb03/src/main.rs
@@ -162,7 +162,7 @@ fn init_hww(preseed: bool) -> bool {
if preseed {
let mnemonic = "boring mistake dish oyster truth pigeon viable emerge sort crash wire portion cannon couple enact box walk height pull today solid off enable tide";
let seed = bitbox02_rust::bip39::mnemonic_to_seed(&mnemonic).unwrap();
- let mut hal = bitbox02_rust::hal::BitBox02Hal::new();
+ let mut hal = bitbox02::hal::BitBox02Hal::new();
bitbox02_rust::keystore::encrypt_and_store_seed(&mut hal, &seed, "").unwrap();
hal.memory().set_initialized().unwrap();
}
diff --git a/test/simulator-graphical/src/main.rs b/test/simulator-graphical/src/main.rs
index 85cb0a4..f92eea1 100644
--- a/test/simulator-graphical/src/main.rs
+++ b/test/simulator-graphical/src/main.rs
@@ -162,7 +162,7 @@ fn init_hww(preseed: bool) -> bool {
if preseed {
let mnemonic = "boring mistake dish oyster truth pigeon viable emerge sort crash wire portion cannon couple enact box walk height pull today solid off enable tide";
let seed = bitbox02_rust::bip39::mnemonic_to_seed(&mnemonic).unwrap();
- let mut hal = bitbox02_rust::hal::BitBox02Hal::new();
+ let mut hal = bitbox02::hal::BitBox02Hal::new();
bitbox02_rust::keystore::encrypt_and_store_seed(&mut hal, &seed, "").unwrap();
hal.memory().set_initialized().unwrap();
}
Why this scored 12/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.