@@ -118,6 +118,7 @@ use aead::{
118118 consts:: U16 ,
119119} ;
120120use core:: marker:: PhantomData ;
121+ use inout:: { InOut , InOutBuf } ;
121122
122123/// Deoxys-I with 128-bit keys
123124pub type DeoxysI128 = Deoxys < modes:: DeoxysI < deoxys_bc:: DeoxysBc256 > , deoxys_bc:: DeoxysBc256 > ;
@@ -156,19 +157,19 @@ where
156157
157158 /// Encrypts the data in place with the specified parameters
158159 /// Returns the tag
159- fn encrypt_in_place (
160+ fn encrypt_inout (
160161 nonce : & Array < u8 , Self :: NonceSize > ,
161162 associated_data : & [ u8 ] ,
162- buffer : & mut [ u8 ] ,
163+ buffer : InOutBuf < ' _ , ' _ , u8 > ,
163164 subkeys : & Array < DeoxysKey , B :: SubkeysSize > ,
164165 ) -> Tag ;
165166
166167 /// Decrypts the data in place with the specified parameters
167168 /// Returns an error if the tag verification fails
168- fn decrypt_in_place (
169+ fn decrypt_inout (
169170 nonce : & Array < u8 , Self :: NonceSize > ,
170171 associated_data : & [ u8 ] ,
171- buffer : & mut [ u8 ] ,
172+ buffer : InOutBuf < ' _ , ' _ , u8 > ,
172173 tag : & Tag ,
173174 subkeys : & Array < DeoxysKey , B :: SubkeysSize > ,
174175 ) -> Result < ( ) , aead:: Error > ;
@@ -184,44 +185,40 @@ pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal {
184185 fn precompute_subkeys ( key : & Array < u8 , Self :: KeySize > ) -> Array < DeoxysKey , Self :: SubkeysSize > ;
185186
186187 /// Encrypts a block of data in place.
187- fn encrypt_in_place (
188- block : & mut Block ,
188+ fn encrypt_inout (
189+ mut block : InOut < ' _ , ' _ , Block > ,
189190 tweak : & Tweak ,
190191 subkeys : & Array < DeoxysKey , Self :: SubkeysSize > ,
191192 ) {
192193 let keys = Self :: key_schedule ( tweak, subkeys) ;
193194
194- for ( b, k) in block. iter_mut ( ) . zip ( keys[ 0 ] . iter ( ) ) {
195- * b ^= k;
196- }
195+ block. xor_in2out ( & keys[ 0 ] ) ;
197196
198197 for k in & keys[ 1 ..] {
199- aes:: hazmat:: cipher_round ( block, k) ;
198+ aes:: hazmat:: cipher_round ( block. get_out ( ) , k) ;
200199 }
201200 }
202201
203202 /// Decrypts a block of data in place.
204- fn decrypt_in_place (
205- block : & mut Block ,
203+ fn decrypt_inout (
204+ mut block : InOut < ' _ , ' _ , Block > ,
206205 tweak : & Tweak ,
207206 subkeys : & Array < DeoxysKey , Self :: SubkeysSize > ,
208207 ) {
209208 let mut keys = Self :: key_schedule ( tweak, subkeys) ;
210209
211210 let r = keys. len ( ) ;
212211
213- for ( b, k) in block. iter_mut ( ) . zip ( keys[ r - 1 ] . iter ( ) ) {
214- * b ^= k;
215- }
212+ block. xor_in2out ( & keys[ r - 1 ] ) ;
216213
217- aes:: hazmat:: inv_mix_columns ( block) ;
214+ aes:: hazmat:: inv_mix_columns ( block. get_out ( ) ) ;
218215
219216 for k in keys[ ..r - 1 ] . iter_mut ( ) . rev ( ) {
220217 aes:: hazmat:: inv_mix_columns ( k) ;
221- aes:: hazmat:: equiv_inv_cipher_round ( block, k) ;
218+ aes:: hazmat:: equiv_inv_cipher_round ( block. get_out ( ) , k) ;
222219 }
223220
224- aes:: hazmat:: mix_columns ( block) ;
221+ aes:: hazmat:: mix_columns ( block. get_out ( ) ) ;
225222 }
226223}
227224
@@ -285,10 +282,10 @@ where
285282 associated_data : & [ u8 ] ,
286283 buffer : & mut [ u8 ] ,
287284 ) -> Result < Tag , Error > {
288- Ok ( Tag :: from ( M :: encrypt_in_place (
285+ Ok ( Tag :: from ( M :: encrypt_inout (
289286 nonce,
290287 associated_data,
291- buffer,
288+ buffer. into ( ) ,
292289 & self . subkeys ,
293290 ) ) )
294291 }
@@ -300,7 +297,7 @@ where
300297 buffer : & mut [ u8 ] ,
301298 tag : & Tag ,
302299 ) -> Result < ( ) , Error > {
303- M :: decrypt_in_place ( nonce, associated_data, buffer, tag, & self . subkeys )
300+ M :: decrypt_inout ( nonce, associated_data, buffer. into ( ) , tag, & self . subkeys )
304301 }
305302}
306303
@@ -327,3 +324,114 @@ where
327324 B : DeoxysBcType ,
328325{
329326}
327+
328+ #[ cfg( test) ]
329+ mod tests {
330+ //! this module is here to test the inout behavior which is not currently exposed.
331+ //! it will be once we port over to the API made in RustCrypto/traits#1793.
332+ //!
333+ //! This is to drop once https://github.com/RustCrypto/traits/pull/1797 is made available.
334+ //!
335+ //! It duplicates test vectors from `tests/deoxys_i_128.rs` and provides a mock buffer backing
336+ //! for InOut.
337+
338+ use hex_literal:: hex;
339+
340+ use super :: * ;
341+
342+ struct MockBuffer {
343+ in_buf : [ u8 ; 33 ] ,
344+ out_buf : [ u8 ; 33 ] ,
345+ }
346+
347+ impl From < & [ u8 ] > for MockBuffer {
348+ fn from ( buf : & [ u8 ] ) -> Self {
349+ let mut in_buf = [ 0u8 ; 33 ] ;
350+ in_buf. copy_from_slice ( buf) ;
351+ Self {
352+ in_buf,
353+ out_buf : [ 0u8 ; 33 ] ,
354+ }
355+ }
356+ }
357+
358+ impl MockBuffer {
359+ /// Get an [`InOutBuf`] from a [`MockBuffer`]
360+ pub fn to_in_out_buf ( & mut self ) -> InOutBuf < ' _ , ' _ , u8 > {
361+ InOutBuf :: new ( self . in_buf . as_slice ( ) , self . out_buf . as_mut_slice ( ) )
362+ . expect ( "Invariant violation" )
363+ }
364+ }
365+
366+ impl AsRef < [ u8 ] > for MockBuffer {
367+ fn as_ref ( & self ) -> & [ u8 ] {
368+ & self . out_buf
369+ }
370+ }
371+
372+ #[ test]
373+ fn test_deoxys_i_128_5 ( ) {
374+ let plaintext = hex ! ( "5a4c652cb880808707230679224b11799b5883431292973215e9bd03cf3bc32fe4" ) ;
375+ let mut buffer = MockBuffer :: from ( & plaintext[ ..] ) ;
376+
377+ let aad = [ ] ;
378+
379+ let key = hex ! ( "101112131415161718191a1b1c1d1e1f" ) ;
380+ let key = Array ( key) ;
381+
382+ let nonce = hex ! ( "202122232425262728292a2b2c2d2e2f" ) ;
383+ let nonce = Array :: try_from ( & nonce[ ..8 ] ) . unwrap ( ) ;
384+
385+ let ciphertext_expected =
386+ hex ! ( "cded5a43d3c76e942277c2a1517530ad66037897c985305ede345903ed7585a626" ) ;
387+
388+ let tag_expected: [ u8 ; 16 ] = hex ! ( "cbf5faa6b8398c47f4278d2019161776" ) ;
389+
390+ type M = modes:: DeoxysI < deoxys_bc:: DeoxysBc256 > ;
391+ let cipher = DeoxysI128 :: new ( & key) ;
392+ let tag: Tag = M :: encrypt_inout ( & nonce, & aad, buffer. to_in_out_buf ( ) , & cipher. subkeys ) ;
393+
394+ let ciphertext = buffer. as_ref ( ) ;
395+ assert_eq ! ( ciphertext, ciphertext_expected) ;
396+ assert_eq ! ( tag, tag_expected) ;
397+
398+ let mut buffer = MockBuffer :: from ( buffer. as_ref ( ) ) ;
399+ M :: decrypt_inout ( & nonce, & aad, buffer. to_in_out_buf ( ) , & tag, & cipher. subkeys )
400+ . expect ( "decryption failed" ) ;
401+
402+ assert_eq ! ( & plaintext[ ..] , buffer. as_ref( ) ) ;
403+ }
404+
405+ #[ test]
406+ fn test_deoxys_ii_128_5 ( ) {
407+ let plaintext = hex ! ( "06ac1756eccece62bd743fa80c299f7baa3872b556130f52265919494bdc136db3" ) ;
408+ let mut buffer = MockBuffer :: from ( & plaintext[ ..] ) ;
409+
410+ let aad = [ ] ;
411+
412+ let key = hex ! ( "101112131415161718191a1b1c1d1e1f" ) ;
413+ let key = Array ( key) ;
414+
415+ let nonce = hex ! ( "202122232425262728292a2b2c2d2e2f" ) ;
416+ let nonce = Array :: try_from ( & nonce[ ..15 ] ) . unwrap ( ) ;
417+
418+ let ciphertext_expected =
419+ hex ! ( "82bf241958b324ed053555d23315d3cc20935527fc970ff34a9f521a95e302136d" ) ;
420+
421+ let tag_expected: [ u8 ; 16 ] = hex ! ( "0eadc8612d5208c491e93005195e9769" ) ;
422+
423+ type M = modes:: DeoxysII < deoxys_bc:: DeoxysBc256 > ;
424+ let cipher = DeoxysII128 :: new ( & key) ;
425+ let tag: Tag = M :: encrypt_inout ( & nonce, & aad, buffer. to_in_out_buf ( ) , & cipher. subkeys ) ;
426+
427+ let ciphertext = buffer. as_ref ( ) ;
428+ assert_eq ! ( ciphertext, ciphertext_expected) ;
429+ assert_eq ! ( tag, tag_expected) ;
430+
431+ let mut buffer = MockBuffer :: from ( buffer. as_ref ( ) ) ;
432+ M :: decrypt_inout ( & nonce, & aad, buffer. to_in_out_buf ( ) , & tag, & cipher. subkeys )
433+ . expect ( "decryption failed" ) ;
434+
435+ assert_eq ! ( & plaintext[ ..] , buffer. as_ref( ) ) ;
436+ }
437+ }
0 commit comments