@@ -17,8 +17,6 @@ extern crate alloc;
1717use alloc:: vec;
1818use alloc:: vec:: Vec ;
1919
20- use util:: cell:: SyncUnsafeCell ;
21-
2220use bitcoin:: secp256k1:: { All , Secp256k1 } ;
2321
2422use core:: convert:: TryInto ;
@@ -29,8 +27,6 @@ use bitbox02_sys::keystore_error_t;
2927const EC_PUBLIC_KEY_LEN : usize = 33 ;
3028pub const MAX_SEED_LENGTH : usize = bitbox02_sys:: KEYSTORE_MAX_SEED_LENGTH as usize ;
3129
32- static ROOT_FINGERPRINT : SyncUnsafeCell < Option < [ u8 ; 4 ] > > = SyncUnsafeCell :: new ( None ) ;
33-
3430pub fn _is_locked ( ) -> bool {
3531 unsafe { bitbox02_sys:: keystore_is_locked ( ) }
3632}
@@ -97,47 +93,24 @@ pub fn _unlock(password: &str) -> Result<zeroize::Zeroizing<Vec<u8>>, Error> {
9793
9894pub fn _lock ( ) {
9995 unsafe { bitbox02_sys:: keystore_lock ( ) }
100-
101- unsafe { ROOT_FINGERPRINT . write ( None ) }
10296}
10397
104- fn unlock_bip39_check ( seed : & [ u8 ] ) -> Result < ( ) , Error > {
98+ pub fn unlock_bip39_check ( seed : & [ u8 ] ) -> Result < ( ) , Error > {
10599 if unsafe { bitbox02_sys:: keystore_unlock_bip39_check ( seed. as_ptr ( ) , seed. len ( ) ) } {
106100 Ok ( ( ) )
107101 } else {
108102 Err ( Error :: CannotUnlockBIP39 )
109103 }
110104}
111105
112- fn unlock_bip39_finalize ( bip39_seed : & [ u8 ; 64 ] ) -> Result < ( ) , Error > {
106+ pub fn unlock_bip39_finalize ( bip39_seed : & [ u8 ; 64 ] ) -> Result < ( ) , Error > {
113107 if unsafe { bitbox02_sys:: keystore_unlock_bip39_finalize ( bip39_seed. as_ptr ( ) ) } {
114108 Ok ( ( ) )
115109 } else {
116110 Err ( Error :: CannotUnlockBIP39 )
117111 }
118112}
119113
120- async fn derive_bip39_seed (
121- secp : & Secp256k1 < All > ,
122- seed : & [ u8 ] ,
123- mnemonic_passphrase : & str ,
124- yield_now : impl AsyncFn ( ) ,
125- ) -> ( zeroize:: Zeroizing < [ u8 ; 64 ] > , [ u8 ; 4 ] ) {
126- let mnemonic = bip39:: Mnemonic :: from_entropy_in ( bip39:: Language :: English , seed) . unwrap ( ) ;
127- let bip39_seed: zeroize:: Zeroizing < [ u8 ; 64 ] > = zeroize:: Zeroizing :: new (
128- mnemonic
129- . to_seed_normalized_async ( mnemonic_passphrase, yield_now)
130- . await ,
131- ) ;
132- let root_fingerprint: [ u8 ; 4 ] =
133- bitcoin:: bip32:: Xpriv :: new_master ( bitcoin:: NetworkKind :: Main , bip39_seed. as_ref ( ) )
134- . unwrap ( )
135- . fingerprint ( secp)
136- . to_bytes ( ) ;
137-
138- ( bip39_seed, root_fingerprint)
139- }
140-
141114#[ cfg( feature = "testing" ) ]
142115pub fn test_get_retained_seed_encrypted ( ) -> & ' static [ u8 ] {
143116 unsafe {
@@ -156,44 +129,6 @@ pub fn test_get_retained_bip39_seed_encrypted() -> &'static [u8] {
156129 }
157130}
158131
159- /// Unlocks the bip39 seed. The input seed must be the keystore seed (i.e. must match the output
160- /// of `keystore_copy_seed()`).
161- /// `mnemonic_passphrase` is the bip39 passphrase used in the derivation. Use the empty string if no
162- /// passphrase is needed or provided.
163- pub async fn _unlock_bip39 (
164- secp : & Secp256k1 < All > ,
165- seed : & [ u8 ] ,
166- mnemonic_passphrase : & str ,
167- yield_now : impl AsyncFn ( ) ,
168- ) -> Result < ( ) , Error > {
169- unlock_bip39_check ( seed) ?;
170-
171- let ( bip39_seed, root_fingerprint) =
172- derive_bip39_seed ( secp, seed, mnemonic_passphrase, & yield_now) . await ;
173-
174- let ( bip39_seed_2, root_fingerprint_2) =
175- derive_bip39_seed ( secp, seed, mnemonic_passphrase, & yield_now) . await ;
176-
177- if bip39_seed != bip39_seed_2 || root_fingerprint != root_fingerprint_2 {
178- return Err ( Error :: Memory ) ;
179- }
180-
181- unlock_bip39_finalize ( bip39_seed. as_slice ( ) . try_into ( ) . unwrap ( ) ) ?;
182-
183- // Store root fingerprint.
184- unsafe {
185- ROOT_FINGERPRINT . write ( Some ( root_fingerprint) ) ;
186- }
187- Ok ( ( ) )
188- }
189-
190- pub fn root_fingerprint ( ) -> Result < Vec < u8 > , ( ) > {
191- if _is_locked ( ) {
192- return Err ( ( ) ) ;
193- }
194- unsafe { ROOT_FINGERPRINT . read ( ) . ok_or ( ( ) ) . map ( |fp| fp. to_vec ( ) ) }
195- }
196-
197132pub fn _create_and_store_seed ( password : & str , host_entropy : & [ u8 ] ) -> Result < ( ) , Error > {
198133 match unsafe {
199134 bitbox02_sys:: keystore_create_and_store_seed (
@@ -304,78 +239,3 @@ pub fn mock_unlocked(seed: &[u8]) {
304239 bitbox02_sys:: keystore_mock_unlocked ( seed. as_ptr ( ) , seed. len ( ) as _ , core:: ptr:: null ( ) )
305240 }
306241}
307-
308- #[ cfg( test) ]
309- mod tests {
310- use super :: * ;
311- use bitcoin:: secp256k1;
312- use util:: bb02_async:: block_on;
313-
314- #[ test]
315- fn test_derive_bip39_seed ( ) {
316- struct Test {
317- seed : & ' static str ,
318- passphrase : & ' static str ,
319- expected_bip39_seed : & ' static str ,
320- expected_root_fingerprint : & ' static str ,
321- }
322-
323- let tests = & [
324- // 16 byte seed
325- Test {
326- seed : "fb5cf00d5ea61059fa066e25a6be9544" ,
327- passphrase : "" ,
328- expected_bip39_seed : "f4577e463be595868060e5a763328153155b4167cd284998c8c6096d044742372020f5b052d0c41c1c5e6a6a7da2cb8a367aaaa074fab7773e8d5b2f684257ed" ,
329- expected_root_fingerprint : "0b2fa4e5" ,
330- } ,
331- Test {
332- seed : "fb5cf00d5ea61059fa066e25a6be9544" ,
333- passphrase : "password" ,
334- expected_bip39_seed : "5922fb7630bc7cb871af102f733b6bdb8f05945147cd4646a89056fde0bdad5c3a4ff5be3f9e7af535f570e7053b5b22472555b331bc89cb797c306f7eb6a5a1" ,
335- expected_root_fingerprint : "c4062d44" ,
336- } ,
337- // 24 byte seed
338- Test {
339- seed : "23705a91b177b49822f28b3f1a60072d113fcaff4f250191" ,
340- passphrase : "" ,
341- expected_bip39_seed : "4a2a016a6d90eb3a79b7931ca0a172df5c5bfee3e5b47f0fd84bc0791ea3bbc9476c3d5de71cdb12c37e93c2aa3d5c303257f1992aed400fc5bbfc7da787bfa7" ,
342- expected_root_fingerprint : "62fd19e0" ,
343- } ,
344- Test {
345- seed : "23705a91b177b49822f28b3f1a60072d113fcaff4f250191" ,
346- passphrase : "password" ,
347- expected_bip39_seed : "bc317ee0f88870254be32274d63ec2b0e962bf09f3ca04287912bfc843f2fab7c556f8657cadc924f99a217b0daa91898303a8414102031a125c50023e45a80b" ,
348- expected_root_fingerprint : "c745266d" ,
349- } ,
350- // 32 byte seed
351- Test {
352- seed : "bd83a008b3b78c8cc56c678d1b7bfc651cc5be8242f44b5c0db96a34ee297833" ,
353- passphrase : "" ,
354- expected_bip39_seed : "63f844e2c61ecfb20f9100de381a7a9ec875b085f5ac7735a2ba4d615a0f4147b87be402f65651969130683deeef752760c09e291604fe4b89d61ffee2630be8" ,
355- expected_root_fingerprint : "93ba3a7b" ,
356- } ,
357- Test {
358- seed : "bd83a008b3b78c8cc56c678d1b7bfc651cc5be8242f44b5c0db96a34ee297833" ,
359- passphrase : "password" ,
360- expected_bip39_seed : "42e90dacd61f3373542d212f0fb9c291dcea84a6d85034272372dde7188638a98527280d65e41599f30d3434d8ee3d4747dbb84801ff1a851d2306c7d1648374" ,
361- expected_root_fingerprint : "b95c9318" ,
362- } ,
363- ] ;
364-
365- let secp = secp256k1:: Secp256k1 :: new ( ) ;
366- for test in tests {
367- let seed = hex:: decode ( test. seed ) . unwrap ( ) ;
368- let ( bip39_seed, root_fingerprint) = block_on ( derive_bip39_seed (
369- & secp,
370- & seed,
371- test. passphrase ,
372- async || { } ,
373- ) ) ;
374- assert_eq ! ( hex:: encode( bip39_seed) . as_str( ) , test. expected_bip39_seed) ;
375- assert_eq ! (
376- hex:: encode( root_fingerprint) . as_str( ) ,
377- test. expected_root_fingerprint
378- ) ;
379- }
380- }
381- }
0 commit comments