@@ -18,7 +18,60 @@ pub mod ed25519;
1818use alloc:: vec:: Vec ;
1919
2020use crate :: bip32;
21- use bitbox02:: keystore;
21+ use bitbox02:: { keystore, memory, securechip} ;
22+
23+ #[ derive( Debug ) ]
24+ pub enum Error {
25+ AlreadyInitialized ,
26+ Memory ,
27+ SeedSize ,
28+ SecureChip ,
29+ IncorrectPassword ,
30+ }
31+
32+ fn validate_seed_length ( len : usize ) -> Result < ( ) , Error > {
33+ match len {
34+ 16 | 24 | 32 => Ok ( ( ) ) ,
35+ _ => Err ( Error :: SeedSize ) ,
36+ }
37+ }
38+
39+ fn get_and_decrypt_seed ( password : & str ) -> Result < zeroize:: Zeroizing < Vec < u8 > > , Error > {
40+ let encrypted_seed_and_hmac =
41+ memory:: get_encrypted_seed_and_hmac ( ) . map_err ( |_| Error :: Memory ) ?;
42+
43+ // TODO check actual SC result
44+ let secret: zeroize:: Zeroizing < Vec < u8 > > =
45+ securechip:: stretch_password ( password) . map_err ( |_| Error :: SecureChip ) ?;
46+ let seed = bitbox_aes:: decrypt_with_hmac ( & secret, & encrypted_seed_and_hmac)
47+ . map_err ( |_| Error :: IncorrectPassword ) ?;
48+ validate_seed_length ( seed. len ( ) ) ?;
49+ Ok ( seed)
50+ }
51+
52+ pub fn encrypt_and_store_seed ( seed : & [ u8 ] , password : & str ) -> Result < ( ) , Error > {
53+ if memory:: is_initialized ( ) {
54+ return Err ( Error :: AlreadyInitialized ) ;
55+ }
56+ keystore:: lock ( ) ;
57+ validate_seed_length ( seed. len ( ) ) ?;
58+ securechip:: init_new_password ( password) . map_err ( |_| Error :: SecureChip ) ?;
59+ let secret: zeroize:: Zeroizing < Vec < u8 > > =
60+ securechip:: stretch_password ( password) . map_err ( |_| Error :: SecureChip ) ?;
61+ // TODO: set IV randomly using random_32_bytes().
62+ let iv = & [ 0u8 ; 16 ] ;
63+ let encrypted_seed: Vec < u8 > =
64+ bitbox_aes:: encrypt_with_hmac ( iv, secret. as_slice ( ) . try_into ( ) . unwrap ( ) , seed) ;
65+ memory:: set_encrypted_seed_and_hmac ( & encrypted_seed) . map_err ( |_| Error :: Memory ) ?;
66+
67+ // Verify seed.
68+ if get_and_decrypt_seed ( password) ?. as_slice ( ) != seed {
69+ // TODO: reset hww
70+ return Err ( Error :: Memory ) ;
71+ }
72+
73+ Ok ( ( ) )
74+ }
2275
2376/// Derives an xpub from the keystore seed at the given keypath.
2477pub fn get_xpub ( keypath : & [ u32 ] ) -> Result < bip32:: Xpub , ( ) > {
0 commit comments