Skip to content

Commit df4c0a9

Browse files
committed
HAL: add initial SecureChip HAL
1 parent 08e998c commit df4c0a9

File tree

4 files changed

+76
-15
lines changed

4 files changed

+76
-15
lines changed

src/rust/bitbox02-rust/src/hal.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,16 @@ pub trait Random {
3838
fn random_32_bytes(&mut self) -> Box<zeroize::Zeroizing<[u8; 32]>>;
3939
}
4040

41+
pub trait SecureChip {
42+
fn init_new_password(&mut self, password: &str) -> Result<(), bitbox02::securechip::Error>;
43+
}
44+
4145
/// Hardware abstraction layer for BitBox devices.
4246
pub trait Hal {
4347
fn ui(&mut self) -> &mut impl Ui;
4448
fn sd(&mut self) -> &mut impl Sd;
4549
fn random(&mut self) -> &mut impl Random;
50+
fn securechip(&mut self) -> &mut impl SecureChip;
4651
}
4752

4853
pub struct BitBox02Sd;
@@ -97,10 +102,19 @@ impl Random for BitBox02Random {
97102
}
98103
}
99104

105+
pub struct BitBox02SecureChip;
106+
107+
impl SecureChip for BitBox02SecureChip {
108+
fn init_new_password(&mut self, password: &str) -> Result<(), bitbox02::securechip::Error> {
109+
bitbox02::securechip::init_new_password(password)
110+
}
111+
}
112+
100113
pub struct BitBox02Hal {
101114
ui: RealWorkflows,
102115
sd: BitBox02Sd,
103116
random: BitBox02Random,
117+
securechip: BitBox02SecureChip,
104118
}
105119

106120
impl BitBox02Hal {
@@ -109,6 +123,7 @@ impl BitBox02Hal {
109123
ui: crate::workflow::RealWorkflows,
110124
sd: BitBox02Sd,
111125
random: BitBox02Random,
126+
securechip: BitBox02SecureChip,
112127
}
113128
}
114129
}
@@ -123,6 +138,9 @@ impl Hal for BitBox02Hal {
123138
fn random(&mut self) -> &mut impl Random {
124139
&mut self.random
125140
}
141+
fn securechip(&mut self) -> &mut impl SecureChip {
142+
&mut self.securechip
143+
}
126144
}
127145

128146
#[cfg(feature = "testing")]
@@ -223,10 +241,47 @@ pub mod testing {
223241
}
224242
}
225243

244+
pub struct TestingSecureChip {
245+
// Count how man seceurity events happen. The numbers were obtained by reading the security
246+
// event counter slot (0xE0C5) on a real device. We can use this to assert how many events
247+
// were used in unit tests. The number is relevant due to Optiga's throttling mechanism.
248+
event_counter: u32,
249+
}
250+
251+
impl TestingSecureChip {
252+
pub fn new() -> Self {
253+
TestingSecureChip { event_counter: 0 }
254+
}
255+
256+
/// Resets the event counter.
257+
pub fn event_counter_reset(&mut self) {
258+
self.event_counter = 0;
259+
// TODO: remove once all unit tests use the SecureChip HAL.
260+
bitbox02::securechip::fake_event_counter_reset()
261+
}
262+
263+
/// Retrieves the event counter.
264+
pub fn get_event_counter(&self) -> u32 {
265+
// TODO: remove fake_event_counter() once all unit tests use the SecureChip HAL.
266+
bitbox02::securechip::fake_event_counter() + self.event_counter
267+
}
268+
}
269+
270+
impl super::SecureChip for TestingSecureChip {
271+
fn init_new_password(
272+
&mut self,
273+
_password: &str,
274+
) -> Result<(), bitbox02::securechip::Error> {
275+
self.event_counter += 1;
276+
Ok(())
277+
}
278+
}
279+
226280
pub struct TestingHal<'a> {
227281
pub ui: crate::workflow::testing::TestingWorkflows<'a>,
228282
pub sd: TestingSd,
229283
pub random: TestingRandom,
284+
pub securechip: TestingSecureChip,
230285
}
231286

232287
impl TestingHal<'_> {
@@ -235,6 +290,7 @@ pub mod testing {
235290
ui: crate::workflow::testing::TestingWorkflows::new(),
236291
sd: TestingSd::new(),
237292
random: TestingRandom::new(),
293+
securechip: TestingSecureChip::new(),
238294
}
239295
}
240296
}
@@ -249,6 +305,9 @@ pub mod testing {
249305
fn random(&mut self) -> &mut impl super::Random {
250306
&mut self.random
251307
}
308+
fn securechip(&mut self) -> &mut impl super::SecureChip {
309+
&mut self.securechip
310+
}
252311
}
253312

254313
#[cfg(test)]

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ mod tests {
189189
Ok("password".into())
190190
}));
191191

192-
bitbox02::securechip::fake_event_counter_reset();
192+
mock_hal.securechip.event_counter_reset();
193193
assert_eq!(
194194
block_on(from_mnemonic(
195195
&mut mock_hal,
@@ -200,7 +200,7 @@ mod tests {
200200
)),
201201
Ok(Response::Success(pb::Success {}))
202202
);
203-
assert_eq!(bitbox02::securechip::fake_event_counter(), 8);
203+
assert_eq!(mock_hal.securechip.get_event_counter(), 8);
204204
drop(mock_hal); // to remove mutable borrow of counter
205205
assert_eq!(counter, 2);
206206
assert!(!crate::keystore::is_locked());

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ mod tests {
7070
Ok("password".into())
7171
}));
7272

73-
bitbox02::securechip::fake_event_counter_reset();
73+
mock_hal.securechip.event_counter_reset();
7474
assert_eq!(
7575
block_on(process(
7676
&mut mock_hal,
@@ -80,7 +80,7 @@ mod tests {
8080
)),
8181
Ok(Response::Success(pb::Success {}))
8282
);
83-
assert_eq!(bitbox02::securechip::fake_event_counter(), 9);
83+
assert_eq!(mock_hal.securechip.get_event_counter(), 9);
8484
drop(mock_hal); // to remove mutable borrow of counter
8585
assert_eq!(counter, 2);
8686
assert!(!keystore::is_locked());

src/rust/bitbox02-rust/src/keystore.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use alloc::string::String;
1919
use alloc::vec::Vec;
2020

2121
use crate::bip32;
22-
use crate::hal::Random;
22+
use crate::hal::{Random, SecureChip};
2323
pub use bitbox02::keystore::SignResult;
2424
use bitbox02::{keystore, securechip};
2525

@@ -211,7 +211,7 @@ pub fn encrypt_and_store_seed(
211211

212212
bitbox02::usb_processing::timeout_reset(LONG_TIMEOUT);
213213

214-
securechip::init_new_password(password)?;
214+
hal.securechip().init_new_password(password)?;
215215

216216
let secret = securechip::stretch_password(password)?;
217217
let iv_rand = hal.random().random_32_bytes();
@@ -1510,33 +1510,35 @@ mod tests {
15101510
lock();
15111511
let seed = &seed[..test.seed_len];
15121512

1513+
let mut mock_hal = crate::hal::testing::TestingHal::new();
1514+
15131515
assert!(
15141516
block_on(unlock_bip39(
1515-
&mut crate::hal::testing::TestingRandom::new(),
1517+
&mut mock_hal.random,
15161518
seed,
15171519
test.mnemonic_passphrase,
15181520
async || {}
15191521
))
15201522
.is_err()
15211523
);
15221524

1523-
bitbox02::securechip::fake_event_counter_reset();
1524-
assert!(encrypt_and_store_seed(&mut TestingHal::new(), seed, "foo").is_ok());
1525-
assert_eq!(bitbox02::securechip::fake_event_counter(), 7);
1525+
mock_hal.securechip.event_counter_reset();
1526+
assert!(encrypt_and_store_seed(&mut mock_hal, seed, "foo").is_ok());
1527+
assert_eq!(mock_hal.securechip.get_event_counter(), 7);
15261528

15271529
assert!(is_locked());
15281530

1529-
bitbox02::securechip::fake_event_counter_reset();
1531+
mock_hal.securechip.event_counter_reset();
15301532
assert!(
15311533
block_on(unlock_bip39(
1532-
&mut crate::hal::testing::TestingRandom::new(),
1534+
&mut mock_hal.random,
15331535
seed,
15341536
test.mnemonic_passphrase,
15351537
async || {}
15361538
))
15371539
.is_ok()
15381540
);
1539-
assert_eq!(bitbox02::securechip::fake_event_counter(), 1);
1541+
assert_eq!(mock_hal.securechip.get_event_counter(), 1);
15401542

15411543
assert!(!is_locked());
15421544
assert_eq!(
@@ -1545,9 +1547,9 @@ mod tests {
15451547
);
15461548
let keypath = &[44 + HARDENED, 0 + HARDENED, 0 + HARDENED];
15471549

1548-
bitbox02::securechip::fake_event_counter_reset();
1550+
mock_hal.securechip.event_counter_reset();
15491551
let xpub = get_xpub_once(keypath).unwrap();
1550-
assert_eq!(bitbox02::securechip::fake_event_counter(), 1);
1552+
assert_eq!(mock_hal.securechip.get_event_counter(), 1);
15511553

15521554
assert_eq!(
15531555
xpub.serialize_str(crate::bip32::XPubType::Xpub).unwrap(),

0 commit comments

Comments
 (0)