@@ -23,10 +23,9 @@ use bitbox02::keystore;
23
23
24
24
use util:: bip32:: HARDENED ;
25
25
26
- use crate :: hash:: Sha512 ;
27
26
use crate :: secp256k1:: SECP256K1 ;
28
27
29
- use hmac :: { Mac , SimpleHmac , digest :: FixedOutput } ;
28
+ use bitcoin :: hashes :: { Hash , HashEngine , Hmac , HmacEngine , sha512 } ;
30
29
31
30
/// Returns the keystore's seed encoded as a BIP-39 mnemonic.
32
31
pub fn get_bip39_mnemonic ( ) -> Result < zeroize:: Zeroizing < String > , ( ) > {
@@ -138,12 +137,12 @@ pub fn root_fingerprint() -> Result<Vec<u8>, ()> {
138
137
139
138
fn bip85_entropy ( keypath : & [ u32 ] ) -> Result < zeroize:: Zeroizing < Vec < u8 > > , ( ) > {
140
139
let priv_key = secp256k1_get_private_key_twice ( keypath) ?;
141
- let mut mac = SimpleHmac :: < Sha512 > :: new_from_slice ( b"bip-entropy-from-k" ) . unwrap ( ) ;
142
- mac . update ( & priv_key ) ;
143
- let mut out = zeroize :: Zeroizing :: new ( vec ! [ 0u8 ; 64 ] ) ;
144
- let fixed_out : & mut [ u8 ; 64 ] = out . as_mut_slice ( ) . try_into ( ) . unwrap ( ) ;
145
- mac . finalize_into ( fixed_out . into ( ) ) ;
146
- Ok ( out )
140
+
141
+ let mut engine = HmacEngine :: < sha512 :: Hash > :: new ( b"bip-entropy-from-k" ) ;
142
+ engine . input ( & priv_key ) ;
143
+ Ok ( zeroize :: Zeroizing :: new (
144
+ Hmac :: from_engine ( engine ) . to_byte_array ( ) . to_vec ( ) ,
145
+ ) )
147
146
}
148
147
149
148
/// Computes a BIP39 mnemonic according to BIP-85:
@@ -224,6 +223,19 @@ pub fn secp256k1_schnorr_sign(
224
223
Ok ( sig. serialize ( ) )
225
224
}
226
225
226
+ /// Get the seed to be used for u2f
227
+ #[ cfg( feature = "app-u2f" ) ]
228
+ pub fn get_u2f_seed ( ) -> Result < zeroize:: Zeroizing < Vec < u8 > > , ( ) > {
229
+ let bip39_seed = keystore:: copy_bip39_seed ( ) ?;
230
+
231
+ let mut engine = HmacEngine :: < bitcoin:: hashes:: sha256:: Hash > :: new ( & bip39_seed) ;
232
+ // Null-terminator for backwards compatibility from the time when this was coded in C.
233
+ engine. input ( b"u2f\0 " ) ;
234
+ Ok ( zeroize:: Zeroizing :: new (
235
+ Hmac :: from_engine ( engine) . to_byte_array ( ) . to_vec ( ) ,
236
+ ) )
237
+ }
238
+
227
239
/// # Safety
228
240
///
229
241
/// keypath pointer has point to a buffer of length `keypath_len` uint32 elements.
@@ -243,6 +255,18 @@ pub unsafe extern "C" fn rust_secp256k1_get_private_key(
243
255
}
244
256
}
245
257
258
+ #[ cfg( feature = "app-u2f" ) ]
259
+ #[ unsafe( no_mangle) ]
260
+ pub extern "C" fn rust_keystore_get_u2f_seed ( mut seed_out : util:: bytes:: BytesMut ) -> bool {
261
+ match get_u2f_seed ( ) {
262
+ Ok ( seed) => {
263
+ seed_out. as_mut ( ) . copy_from_slice ( & seed) ;
264
+ true
265
+ }
266
+ Err ( _) => false ,
267
+ }
268
+ }
269
+
246
270
#[ cfg( test) ]
247
271
mod tests {
248
272
use super :: * ;
@@ -584,7 +608,7 @@ mod tests {
584
608
test. expected_xpub,
585
609
) ;
586
610
assert_eq ! (
587
- hex:: encode( keystore :: get_u2f_seed( ) . unwrap( ) ) ,
611
+ hex:: encode( get_u2f_seed( ) . unwrap( ) ) ,
588
612
test. expected_u2f_seed_hex,
589
613
) ;
590
614
}
0 commit comments