@@ -132,24 +132,44 @@ impl<Ids: KeyIds> KeyStoreContext<'_, Ids> {
132
132
///
133
133
/// # Arguments
134
134
///
135
- /// * `encryption_key ` - The key id used to decrypt the `encrypted_key `. It must already exist
135
+ /// * `wrapping_key ` - The key id used to decrypt the `wrapped_key `. It must already exist
136
136
/// in the context
137
137
/// * `new_key_id` - The key id where the decrypted key will be stored. If it already exists, it
138
138
/// will be overwritten
139
- /// * `encrypted_key ` - The key to decrypt
139
+ /// * `wrapped_key ` - The key to decrypt
140
140
pub fn unwrap_symmetric_key (
141
141
& mut self ,
142
- encryption_key : Ids :: Symmetric ,
142
+ wrapping_key : Ids :: Symmetric ,
143
143
new_key_id : Ids :: Symmetric ,
144
- encrypted_key : & EncString ,
144
+ wrapped_key : & EncString ,
145
145
) -> Result < Ids :: Symmetric > {
146
- let mut new_key_material =
147
- self . decrypt_data_with_symmetric_key ( encryption_key, encrypted_key) ?;
146
+ let wrapping_key = self . get_symmetric_key ( wrapping_key) ?;
147
+
148
+ let key = match ( wrapped_key, wrapping_key) {
149
+ ( EncString :: Aes256Cbc_B64 { iv, data } , SymmetricCryptoKey :: Aes256CbcKey ( key) ) => {
150
+ SymmetricCryptoKey :: try_from ( crate :: aes:: decrypt_aes256 ( iv, data. clone ( ) , & key. enc_key ) ?) ?
151
+ }
152
+ (
153
+ EncString :: Aes256Cbc_HmacSha256_B64 { iv, mac, data } ,
154
+ SymmetricCryptoKey :: Aes256CbcHmacKey ( key) ,
155
+ ) => {
156
+ SymmetricCryptoKey :: try_from ( crate :: aes:: decrypt_aes256_hmac ( iv, mac, data. clone ( ) , & key. mac_key , & key. enc_key ) ?) ?
157
+ }
158
+ ( EncString :: Cose_Encrypt0_B64 { data } , SymmetricCryptoKey :: XChaCha20Poly1305Key ( key) ) => {
159
+ let ( content_bytes, content_format) = crate :: cose:: decrypt_xchacha20_poly1305 ( data, key) ?;
160
+ match content_format {
161
+ ContentFormat :: OctetStream => SymmetricCryptoKey :: try_from ( content_bytes) ?,
162
+ ContentFormat :: CoseKey => SymmetricCryptoKey :: try_from_cose ( & content_bytes) ?,
163
+ _ => return Err ( CryptoError :: InvalidKey )
164
+ }
165
+ }
166
+ _ => return Err ( CryptoError :: InvalidKey ) ,
167
+ } ;
148
168
149
169
#[ allow( deprecated) ]
150
170
self . set_symmetric_key (
151
171
new_key_id,
152
- SymmetricCryptoKey :: try_from ( new_key_material . as_mut_slice ( ) ) ? ,
172
+ key ,
153
173
) ?;
154
174
155
175
// Returning the new key identifier for convenience
@@ -179,7 +199,7 @@ impl<Ids: KeyIds> KeyStoreContext<'_, Ids> {
179
199
// or `Aes256CbcKey`, or by specifying the content format to be CoseKey, in case the
180
200
// wrapped key is a `XChaCha20Poly1305Key`.
181
201
match ( wrapping_key_instance, key_to_wrap_instance) {
182
- ( Aes256CbcHmacKey ( _) , Aes256CbcHmacKey ( _) | Aes256CbcKey ( _) ) => self
202
+ ( Aes256CbcHmacKey ( _) , Aes256CbcHmacKey ( _) | Aes256CbcKey ( _) | XChaCha20Poly1305Key ( _ ) ) => self
183
203
. encrypt_data_with_symmetric_key (
184
204
wrapping_key,
185
205
key_to_wrap_instance. to_encoded ( ) . as_slice ( ) ,
@@ -368,6 +388,10 @@ impl<Ids: KeyIds> KeyStoreContext<'_, Ids> {
368
388
EncString :: Aes256Cbc_HmacSha256_B64 { iv, mac, data } ,
369
389
SymmetricCryptoKey :: Aes256CbcHmacKey ( key) ,
370
390
) => crate :: aes:: decrypt_aes256_hmac ( iv, mac, data. clone ( ) , & key. mac_key , & key. enc_key ) ,
391
+ ( EncString :: Cose_Encrypt0_B64 { data } , SymmetricCryptoKey :: XChaCha20Poly1305Key ( key) ) => {
392
+ let ( data, _) = crate :: cose:: decrypt_xchacha20_poly1305 ( data, key) ?;
393
+ Ok ( data)
394
+ }
371
395
_ => Err ( CryptoError :: InvalidKey ) ,
372
396
}
373
397
}
@@ -468,4 +492,44 @@ mod tests {
468
492
// Assert that the decrypted data is the same
469
493
assert_eq ! ( decrypted1. 0 , decrypted2. 0 ) ;
470
494
}
495
+
496
+ #[ test]
497
+ fn test_wrap_unwrap_aes256_cbc_hmac ( ) {
498
+ let store: KeyStore < TestIds > = KeyStore :: default ( ) ;
499
+ let mut ctx = store. context_mut ( ) ;
500
+
501
+ // Aes256 CBC HMAC keys
502
+ let key_aes_1_id = TestSymmKey :: A ( 1 ) ;
503
+ let key_aes_1 = SymmetricCryptoKey :: make_aes256_cbc_hmac_key ( ) ;
504
+ ctx. set_symmetric_key ( key_aes_1_id, key_aes_1. clone ( ) ) . unwrap ( ) ;
505
+ let key_aes_2_id = TestSymmKey :: A ( 2 ) ;
506
+ let key_aes_2 = SymmetricCryptoKey :: make_aes256_cbc_hmac_key ( ) ;
507
+ ctx. set_symmetric_key ( key_aes_2_id, key_aes_2. clone ( ) ) . unwrap ( ) ;
508
+
509
+ // XChaCha20 Poly1305 keys
510
+ let key_xchacha_3_id = TestSymmKey :: A ( 3 ) ;
511
+ let key_xchacha_3 = SymmetricCryptoKey :: make_xchacha20_poly1305_key ( ) ;
512
+ ctx. set_symmetric_key ( key_xchacha_3_id, key_xchacha_3. clone ( ) ) . unwrap ( ) ;
513
+ let key_xchacha_4_id = TestSymmKey :: A ( 4 ) ;
514
+ let key_xchacha_4 = SymmetricCryptoKey :: make_xchacha20_poly1305_key ( ) ;
515
+ ctx. set_symmetric_key ( key_xchacha_4_id, key_xchacha_4. clone ( ) ) . unwrap ( ) ;
516
+
517
+ // Wrap and unwrap the keys
518
+ let wrapped_key_1_2 = ctx. wrap_symmetric_key ( key_aes_1_id, key_aes_2_id) . unwrap ( ) ;
519
+ let wrapped_key_1_3 = ctx. wrap_symmetric_key ( key_aes_1_id, key_xchacha_3_id) . unwrap ( ) ;
520
+ let wrapped_key_3_1 = ctx. wrap_symmetric_key ( key_xchacha_3_id, key_aes_1_id) . unwrap ( ) ;
521
+ let wrapped_key_3_4 = ctx. wrap_symmetric_key ( key_xchacha_3_id, key_xchacha_4_id) . unwrap ( ) ;
522
+
523
+ // Unwrap the keys
524
+ let unwrapped_key_2 = ctx. unwrap_symmetric_key ( key_aes_1_id, key_aes_2_id, & wrapped_key_1_2) . unwrap ( ) ;
525
+ let unwrapped_key_3 = ctx. unwrap_symmetric_key ( key_aes_1_id, key_xchacha_3_id, & wrapped_key_1_3) . unwrap ( ) ;
526
+ let unwrapped_key_1 = ctx. unwrap_symmetric_key ( key_xchacha_3_id, key_aes_1_id, & wrapped_key_3_1) . unwrap ( ) ;
527
+ let unwrapped_key_4 = ctx. unwrap_symmetric_key ( key_xchacha_3_id, key_xchacha_4_id, & wrapped_key_3_4) . unwrap ( ) ;
528
+
529
+ // Assert that the unwrapped keys are the same as the original keys
530
+ assert_eq ! ( unwrapped_key_2, key_aes_2_id) ;
531
+ assert_eq ! ( unwrapped_key_3, key_xchacha_3_id) ;
532
+ assert_eq ! ( unwrapped_key_1, key_aes_1_id) ;
533
+ assert_eq ! ( unwrapped_key_4, key_xchacha_4_id) ;
534
+ }
471
535
}
0 commit comments