1818use std:: cmp:: PartialEq ;
1919use std:: fmt:: Debug ;
2020use std:: iter:: repeat;
21- use std:: thread;
22- use std:: thread:: JoinHandle ;
23-
2421use aes:: Aes256 ;
2522use base64:: { Engine as _, engine:: general_purpose} ;
2623use bcrypt:: bcrypt;
@@ -34,9 +31,7 @@ use zeroize::Zeroize;
3431use super :: errors:: { self , RustKeylockError } ;
3532use super :: protected:: RklSecret ;
3633
37- const NUMBER_OF_SALT_KEY_PAIRS : usize = 10 ;
3834type AesCtr = ctr:: Ctr64BE < Aes256 > ;
39- pub ( crate ) const BCRYPT_COST : u32 = 7 ;
4035
4136pub trait Cryptor {
4237 /// Decrypts a given array of bytes
@@ -58,11 +53,8 @@ pub struct BcryptAes {
5853 iv : Vec < u8 > ,
5954 /// The position of the salt inside the file
6055 salt_position : usize ,
61- /// A list of pairs of salt - bcrypt key.
62- ///
63- /// Each encryption process includes the creation of a new pseudo-random iv and the usage of one of the provided salt-key pairs.
64- /// With these, the data is encrypted and the encrypted bytes are returned.
65- salt_key_pairs : Vec < ( Vec < u8 > , RklSecret ) > ,
56+ /// The salt
57+ salt : Vec < u8 > ,
6658 /// A Hasher to be used to guarantee data integrity
6759 hasher : Sha3Keccak512 ,
6860 /// The hash that is retrieved by parsing the passwords file, during the application startup.
@@ -95,53 +87,31 @@ impl BcryptAes {
9587 /// * The position of the salt
9688 /// * hash for Sha3Keccak512 hashing
9789 pub fn new ( mut password : String ,
98- mut salt : Vec < u8 > ,
90+ salt : Vec < u8 > ,
9991 iv : Vec < u8 > ,
10092 mut salt_position : usize ,
101- hash_bytes : Vec < u8 > , )
102- -> BcryptAes {
103- let mut salt_key_pairs = Vec :: new ( ) ;
104- let handles: Vec < JoinHandle < ( Vec < u8 > , RklSecret ) > > = ( 0 ..NUMBER_OF_SALT_KEY_PAIRS + 1 )
105- . map ( |i| {
106- let cp = password. clone ( ) ;
107- let cs = salt. clone ( ) ;
108- let child = thread:: spawn ( move || {
109- if i == 0 {
110- // Create bcrypt password for the current encrypted data
111- // Ask for 64 bytes bcrypt key. Use 32 bytes for data encryption and 32 bytes for hash encryption.
112- let key = BcryptAes :: create_key ( cp. as_bytes ( ) , & cs, BCRYPT_COST , 64 ) ;
113- ( cs, RklSecret :: new ( key) )
114- } else {
115- // Create some new salt-key pairs to use them for encryption
116- // Ask for 64 bytes bcrypt key. Use 32 bytes for data encryption and 32 bytes for hash encryption.
117- let s = create_random ( 16 ) ;
118- let k = BcryptAes :: create_key ( cp. as_bytes ( ) , & s, BCRYPT_COST , 64 ) ;
119- ( s, RklSecret :: new ( k) )
120- }
121- } ) ;
122- child
123- } )
124- . collect ( ) ;
125- for handle in handles {
126- salt_key_pairs. push ( handle. join ( ) . unwrap ( ) ) ;
127- }
93+ hash_bytes : Vec < u8 > ,
94+ bcrypt_cost : u32 ,
95+ ) -> BcryptAes {
12896
12997 // Create the SHA3 hasher
13098 let hasher = Sha3Keccak512 :: new ( ) ;
13199
100+ // Create bcrypt password for the current encrypted data
101+ // Ask for 64 bytes bcrypt key. Use 32 bytes for data encryption and 32 bytes for hash encryption.
102+ let key = BcryptAes :: create_key ( password. as_bytes ( ) , & salt, bcrypt_cost, 64 ) ;
132103
133104 let to_ret = BcryptAes {
134- key : salt_key_pairs . remove ( 0 ) . 1 . clone ( ) ,
105+ key : RklSecret :: new ( key ) ,
135106 iv,
136107 salt_position,
137- salt_key_pairs ,
108+ salt ,
138109 hasher,
139110 hash : RklSecret :: new ( hash_bytes) ,
140111 } ;
141112
142113 // Zeroize what's not moved
143114 password. zeroize ( ) ;
144- salt. zeroize ( ) ;
145115 salt_position. zeroize ( ) ;
146116
147117 to_ret
@@ -172,19 +142,7 @@ impl Cryptor for BcryptAes {
172142 fn decrypt ( & self , input : & [ u8 ] ) -> Result < Vec < u8 > , RustKeylockError > {
173143 let bytes_to_decrypt = extract_bytes_to_decrypt ( input, self . salt_position ) ;
174144
175- // The key should be 64 bytes long (including 2 32-byte keys). If it is bigger than that, there is the legacy key in the start.
176- let legacy_handling = self . key . borrow ( ) . len ( ) > 64 ;
177-
178- let ( final_result, integrity_check_ok) = if legacy_handling {
179- let key: Vec < u8 > = self . key . borrow ( ) . iter ( )
180- . take ( 32 )
181- . cloned ( )
182- . collect ( ) ;
183- let integrity_check_ok = self . hasher . validate_hash ( & bytes_to_decrypt, self . hash . borrow ( ) ) ;
184- let final_result = self . decrypt_bytes ( & bytes_to_decrypt, & key) ?;
185-
186- ( final_result, integrity_check_ok)
187- } else {
145+ let ( final_result, integrity_check_ok) = {
188146 // The first 32 bytes of the key is for hash decryption.
189147 let hash_decryption_key: Vec < u8 > = self . key . borrow ( ) . iter ( )
190148 . take ( 32 )
@@ -216,20 +174,14 @@ impl Cryptor for BcryptAes {
216174 fn encrypt ( & self , input : & [ u8 ] ) -> Result < Vec < u8 > , RustKeylockError > {
217175 // Create a new iv
218176 let iv = create_random ( 16 ) ;
219- let mut rng = thread_rng ( ) ;
220- // Choose randomly one of the salt-key pairs
221- let idx = {
222- rng. gen_range ( 0 .. NUMBER_OF_SALT_KEY_PAIRS )
223- } ;
224- let salt_key_pair = & self . salt_key_pairs [ idx] ;
225177
226178 // The first 32 bytes is the key for hash encryption.
227- let hash_encryption_key: Vec < u8 > = salt_key_pair . 1 . borrow ( ) . iter ( )
179+ let hash_encryption_key: Vec < u8 > = self . key . borrow ( ) . iter ( )
228180 . take ( 32 )
229181 . cloned ( )
230182 . collect ( ) ;
231183 // The second 32 bytes is the key for data encryption.
232- let data_encryption_key: Vec < u8 > = salt_key_pair . 1 . borrow ( ) . iter ( )
184+ let data_encryption_key: Vec < u8 > = self . key . borrow ( ) . iter ( )
233185 . skip ( 32 )
234186 . take ( 32 )
235187 . cloned ( )
@@ -242,7 +194,7 @@ impl Cryptor for BcryptAes {
242194 let encrypted_hash_bytes = self . encrypt_bytes ( & hash_bytes, & hash_encryption_key, & iv) ?;
243195
244196 // Compose the encrypted bytes with the iv and salt
245- Ok ( compose_bytes_to_save ( & encrypted_data_bytes, self . salt_position , & salt_key_pair . 0 , & iv, & encrypted_hash_bytes) )
197+ Ok ( compose_bytes_to_save ( & encrypted_data_bytes, self . salt_position , & self . salt , & iv, & encrypted_hash_bytes) )
246198 }
247199}
248200
@@ -480,6 +432,7 @@ fn compose_bytes_to_save(data: &[u8], salt_position: usize, salt: &[u8], iv: &[u
480432#[ cfg( test) ]
481433mod test_crypt {
482434 use super :: { Cryptor , Hasher } ;
435+ const BCRYPT_COST : u32 = 1 ;
483436
484437 #[ test]
485438 fn create_random ( ) {
@@ -916,7 +869,7 @@ mod test_crypt {
916869 bytes. append ( & mut tmp) ;
917870
918871 // Create the cryptor
919- let cryptor = super :: BcryptAes :: new ( "password" . to_string ( ) , salt, iv, 1 , hash) ;
872+ let cryptor = super :: BcryptAes :: new ( "password" . to_string ( ) , salt, iv, 1 , hash, BCRYPT_COST ) ;
920873 let result = cryptor. decrypt ( & bytes) ;
921874 assert ! ( result. is_err( ) ) ;
922875 match result. err ( ) {
@@ -925,19 +878,6 @@ mod test_crypt {
925878 }
926879 }
927880
928- #[ test]
929- fn new_bcryptor_checks ( ) {
930- let iv = super :: create_random ( 16 ) ;
931- let salt = super :: create_random ( 16 ) ;
932- let hash = super :: create_random ( 64 ) ;
933- let cryptor = super :: BcryptAes :: new ( "password" . to_string ( ) , salt. clone ( ) , iv, 1 , hash) ;
934- assert ! ( cryptor. salt_key_pairs. len( ) == super :: NUMBER_OF_SALT_KEY_PAIRS ) ;
935- for skp in cryptor. salt_key_pairs {
936- assert ! ( & skp. 0 != & salt) ;
937- assert ! ( & skp. 1 != & cryptor. key) ;
938- }
939- }
940-
941881 #[ test]
942882 fn bcrypt_key_creation ( ) {
943883 let small_key = super :: BcryptAes :: create_key ( "123" . as_bytes ( ) , "saltsaltsaltsalt" . as_bytes ( ) , 3 , 12 ) ;
0 commit comments