@@ -34,18 +34,19 @@ const CHACHA20_CIPHER_NAME: &'static str = "ChaCha20Poly1305";
3434impl < T :  EntropySource >  StorableBuilder < T >  { 
3535	/// Creates a [`Storable`] that can be serialized and stored as `value` in [`PutObjectRequest`]. 
3636 	/// 
37-  	/// Uses ChaCha20 for encrypting `input` and Poly1305 for generating a mac/tag. 
37+  	/// Uses ChaCha20 for encrypting `input` and Poly1305 for generating a mac/tag with associated 
38+  	/// data `aad` (usually the storage key). 
3839 	/// 
3940 	/// Refer to docs on [`Storable`] for more information. 
4041 	/// 
4142 	/// [`PutObjectRequest`]: crate::types::PutObjectRequest 
42-  	pub  fn  build ( & self ,  input :  Vec < u8 > ,  version :  i64 )  -> Storable  { 
43+  	pub  fn  build ( & self ,  input :  Vec < u8 > ,  version :  i64 ,   aad :   & [ u8 ] )  -> Storable  { 
4344		let  mut  nonce = vec ! [ 0u8 ;  12 ] ; 
4445		self . entropy_source . fill_bytes ( & mut  nonce[ 4 ..] ) ; 
4546
4647		let  mut  data_blob = PlaintextBlob  {  value :  input,  version } . encode_to_vec ( ) ; 
4748
48- 		let  mut  cipher = ChaCha20Poly1305 :: new ( & self . data_encryption_key ,  & nonce,  & [ ] ) ; 
49+ 		let  mut  cipher = ChaCha20Poly1305 :: new ( & self . data_encryption_key ,  & nonce,  aad ) ; 
4950		let  mut  tag = vec ! [ 0u8 ;  16 ] ; 
5051		cipher. encrypt_inplace ( & mut  data_blob,  & mut  tag) ; 
5152		Storable  { 
@@ -62,10 +63,10 @@ impl<T: EntropySource> StorableBuilder<T> {
6263 	/// corresponding version as stored at the time of [`PutObjectRequest`]. 
6364 	/// 
6465 	/// [`PutObjectRequest`]: crate::types::PutObjectRequest 
65-  	pub  fn  deconstruct ( & self ,  mut  storable :  Storable )  -> io:: Result < ( Vec < u8 > ,  i64 ) >  { 
66+  	pub  fn  deconstruct ( & self ,  mut  storable :  Storable ,   aad :   & [ u8 ] )  -> io:: Result < ( Vec < u8 > ,  i64 ) >  { 
6667		let  encryption_metadata = storable. encryption_metadata . unwrap ( ) ; 
6768		let  mut  cipher =
68- 			ChaCha20Poly1305 :: new ( & self . data_encryption_key ,  & encryption_metadata. nonce ,  & [ ] ) ; 
69+ 			ChaCha20Poly1305 :: new ( & self . data_encryption_key ,  & encryption_metadata. nonce ,  aad ) ; 
6970
7071		cipher
7172			. decrypt_inplace ( & mut  storable. data ,  encryption_metadata. tag . borrow ( ) ) 
@@ -103,10 +104,38 @@ mod tests {
103104		} ; 
104105		let  expected_data = b"secret" . to_vec ( ) ; 
105106		let  expected_version = 8 ; 
106- 		let  storable = storable_builder. build ( expected_data. clone ( ) ,  expected_version) ; 
107+ 		let  aad = b"A" ; 
108+ 		let  storable = storable_builder. build ( expected_data. clone ( ) ,  expected_version,  aad) ; 
107109
108- 		let  ( actual_data,  actual_version)  = storable_builder. deconstruct ( storable) . unwrap ( ) ; 
110+ 		let  ( actual_data,  actual_version)  = storable_builder. deconstruct ( storable,  aad ) . unwrap ( ) ; 
109111		assert_eq ! ( actual_data,  expected_data) ; 
110112		assert_eq ! ( actual_version,  expected_version) ; 
111113	} 
114+ 
115+ 	#[ test]  
116+ 	fn  decrypt_key_mismatch_fails ( )  { 
117+ 		let  test_entropy_provider = TestEntropyProvider ; 
118+ 		let  mut  data_key = [ 0u8 ;  32 ] ; 
119+ 		test_entropy_provider. fill_bytes ( & mut  data_key) ; 
120+ 		let  storable_builder = StorableBuilder  { 
121+ 			data_encryption_key :  data_key, 
122+ 			entropy_source :  test_entropy_provider, 
123+ 		} ; 
124+ 
125+ 		let  expected_data_a = b"secret_a" . to_vec ( ) ; 
126+ 		let  expected_version_a = 8 ; 
127+ 		let  aad_a = b"A" ; 
128+ 		let  storable_a = storable_builder. build ( expected_data_a. clone ( ) ,  expected_version_a,  aad_a) ; 
129+ 
130+ 		let  expected_data_b = b"secret_b" . to_vec ( ) ; 
131+ 		let  expected_version_b = 8 ; 
132+ 		let  aad_b = b"B" ; 
133+ 		let  storable_b = storable_builder. build ( expected_data_b. clone ( ) ,  expected_version_b,  aad_b) ; 
134+ 
135+ 		let  ( actual_data,  actual_version)  =
136+ 			storable_builder. deconstruct ( storable_a,  aad_a) . unwrap ( ) ; 
137+ 		assert_eq ! ( actual_data,  expected_data_a) ; 
138+ 		assert_eq ! ( actual_version,  expected_version_a) ; 
139+ 		assert ! ( storable_builder. deconstruct( storable_b,  aad_a) . is_err( ) ) ; 
140+ 	} 
112141} 
0 commit comments