@@ -23,10 +23,9 @@ use bitbox02::keystore;
2323
2424use util:: bip32:: HARDENED ;
2525
26- use crate :: hash:: Sha512 ;
2726use crate :: secp256k1:: SECP256K1 ;
2827
29- use hmac :: { Mac , SimpleHmac , digest :: FixedOutput } ;
28+ use bitcoin :: hashes :: { Hash , HashEngine , Hmac , HmacEngine , sha512 } ;
3029
3130/// Returns the keystore's seed encoded as a BIP-39 mnemonic.
3231pub fn get_bip39_mnemonic ( ) -> Result < zeroize:: Zeroizing < String > , ( ) > {
@@ -138,12 +137,12 @@ pub fn root_fingerprint() -> Result<Vec<u8>, ()> {
138137
139138fn bip85_entropy ( keypath : & [ u32 ] ) -> Result < zeroize:: Zeroizing < Vec < u8 > > , ( ) > {
140139 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+ ) )
147146}
148147
149148/// Computes a BIP39 mnemonic according to BIP-85:
@@ -224,6 +223,19 @@ pub fn secp256k1_schnorr_sign(
224223 Ok ( sig. serialize ( ) )
225224}
226225
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+
227239/// # Safety
228240///
229241/// 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(
243255 }
244256}
245257
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+
246270#[ cfg( test) ]
247271mod tests {
248272 use super :: * ;
@@ -584,7 +608,7 @@ mod tests {
584608 test. expected_xpub,
585609 ) ;
586610 assert_eq ! (
587- hex:: encode( keystore :: get_u2f_seed( ) . unwrap( ) ) ,
611+ hex:: encode( get_u2f_seed( ) . unwrap( ) ) ,
588612 test. expected_u2f_seed_hex,
589613 ) ;
590614 }
0 commit comments