@@ -116,7 +116,7 @@ use aead::{
116116 PostfixTagged ,
117117 array:: { Array , ArraySize } ,
118118 consts:: U16 ,
119- inout:: InOutBuf ,
119+ inout:: { InOut , InOutBuf } ,
120120} ;
121121use core:: marker:: PhantomData ;
122122
@@ -140,6 +140,12 @@ pub type Nonce<NonceSize> = Array<u8, NonceSize>;
140140/// Deoxys tags
141141pub type Tag = Array < u8 , U16 > ;
142142
143+ type Block = Array < u8 , U16 > ;
144+
145+ type Tweak = Array < u8 , U16 > ;
146+
147+ type DeoxysKey = Array < u8 , U16 > ;
148+
143149/// Deoxys encryption modes.
144150/// This type contains the public API for a Deoxys mode, like Deoxys-I and Deoxys-II.
145151pub trait DeoxysMode < B > : modes:: DeoxysModeInternal < B >
@@ -151,21 +157,21 @@ where
151157
152158 /// Encrypts the data in place with the specified parameters
153159 /// Returns the tag
154- fn encrypt_in_place (
160+ fn encrypt_inout (
155161 nonce : & Array < u8 , Self :: NonceSize > ,
156162 associated_data : & [ u8 ] ,
157- buffer : & mut [ u8 ] ,
158- subkeys : & Array < [ u8 ; 16 ] , B :: SubkeysSize > ,
159- ) -> [ u8 ; 16 ] ;
163+ buffer : InOutBuf < ' _ , ' _ , u8 > ,
164+ subkeys : & Array < DeoxysKey , B :: SubkeysSize > ,
165+ ) -> Tag ;
160166
161167 /// Decrypts the data in place with the specified parameters
162168 /// Returns an error if the tag verification fails
163- fn decrypt_in_place (
169+ fn decrypt_inout (
164170 nonce : & Array < u8 , Self :: NonceSize > ,
165171 associated_data : & [ u8 ] ,
166- buffer : & mut [ u8 ] ,
172+ buffer : InOutBuf < ' _ , ' _ , u8 > ,
167173 tag : & Tag ,
168- subkeys : & Array < [ u8 ; 16 ] , B :: SubkeysSize > ,
174+ subkeys : & Array < DeoxysKey , B :: SubkeysSize > ,
169175 ) -> Result < ( ) , aead:: Error > ;
170176}
171177
@@ -176,47 +182,43 @@ pub trait DeoxysBcType: deoxys_bc::DeoxysBcInternal {
176182 type KeySize : ArraySize ;
177183
178184 /// Precompute the subkeys
179- fn precompute_subkeys ( key : & Array < u8 , Self :: KeySize > ) -> Array < [ u8 ; 16 ] , Self :: SubkeysSize > ;
185+ fn precompute_subkeys ( key : & Array < u8 , Self :: KeySize > ) -> Array < DeoxysKey , Self :: SubkeysSize > ;
180186
181187 /// Encrypts a block of data in place.
182- fn encrypt_in_place (
183- block : & mut [ u8 ; 16 ] ,
184- tweak : & [ u8 ; 16 ] ,
185- subkeys : & Array < [ u8 ; 16 ] , Self :: SubkeysSize > ,
188+ fn encrypt_inout (
189+ mut block : InOut < ' _ , ' _ , Block > ,
190+ tweak : & Tweak ,
191+ subkeys : & Array < DeoxysKey , Self :: SubkeysSize > ,
186192 ) {
187193 let keys = Self :: key_schedule ( tweak, subkeys) ;
188194
189- for ( b, k) in block. iter_mut ( ) . zip ( keys[ 0 ] . iter ( ) ) {
190- * b ^= k;
191- }
195+ block. xor_in2out ( & keys[ 0 ] ) ;
192196
193197 for k in & keys[ 1 ..] {
194- aes:: hazmat:: cipher_round ( block. into ( ) , k. into ( ) ) ;
198+ aes:: hazmat:: cipher_round ( block. get_out ( ) , k) ;
195199 }
196200 }
197201
198202 /// Decrypts a block of data in place.
199- fn decrypt_in_place (
200- block : & mut [ u8 ; 16 ] ,
201- tweak : & [ u8 ; 16 ] ,
202- subkeys : & Array < [ u8 ; 16 ] , Self :: SubkeysSize > ,
203+ fn decrypt_inout (
204+ mut block : InOut < ' _ , ' _ , Block > ,
205+ tweak : & Tweak ,
206+ subkeys : & Array < DeoxysKey , Self :: SubkeysSize > ,
203207 ) {
204208 let mut keys = Self :: key_schedule ( tweak, subkeys) ;
205209
206210 let r = keys. len ( ) ;
207211
208- for ( b, k) in block. iter_mut ( ) . zip ( keys[ r - 1 ] . iter ( ) ) {
209- * b ^= k;
210- }
212+ block. xor_in2out ( & keys[ r - 1 ] ) ;
211213
212- aes:: hazmat:: inv_mix_columns ( block. into ( ) ) ;
214+ aes:: hazmat:: inv_mix_columns ( block. get_out ( ) ) ;
213215
214216 for k in keys[ ..r - 1 ] . iter_mut ( ) . rev ( ) {
215- aes:: hazmat:: inv_mix_columns ( k. into ( ) ) ;
216- aes:: hazmat:: equiv_inv_cipher_round ( block. into ( ) , ( & * k ) . into ( ) ) ;
217+ aes:: hazmat:: inv_mix_columns ( k) ;
218+ aes:: hazmat:: equiv_inv_cipher_round ( block. get_out ( ) , k ) ;
217219 }
218220
219- aes:: hazmat:: mix_columns ( block. into ( ) ) ;
221+ aes:: hazmat:: mix_columns ( block. get_out ( ) ) ;
220222 }
221223}
222224
@@ -228,7 +230,7 @@ where
228230 M : DeoxysMode < B > ,
229231 B : DeoxysBcType ,
230232{
231- subkeys : Array < [ u8 ; 16 ] , B :: SubkeysSize > ,
233+ subkeys : Array < DeoxysKey , B :: SubkeysSize > ,
232234 mode : PhantomData < M > ,
233235}
234236
@@ -280,7 +282,7 @@ where
280282 associated_data : & [ u8 ] ,
281283 buffer : InOutBuf < ' _ , ' _ , u8 > ,
282284 ) -> Result < Tag , Error > {
283- Ok ( Tag :: from ( M :: encrypt_in_place (
285+ Ok ( Tag :: from ( M :: encrypt_inout (
284286 nonce,
285287 associated_data,
286288 buffer,
@@ -295,7 +297,7 @@ where
295297 buffer : InOutBuf < ' _ , ' _ , u8 > ,
296298 tag : & Tag ,
297299 ) -> Result < ( ) , Error > {
298- M :: decrypt_in_place ( nonce, associated_data, buffer, tag, & self . subkeys )
300+ M :: decrypt_inout ( nonce, associated_data, buffer, tag, & self . subkeys )
299301 }
300302}
301303
@@ -322,3 +324,115 @@ where
322324 B : DeoxysBcType ,
323325{
324326}
327+
328+ #[ cfg( all( feature = "alloc" , 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+ extern crate alloc;
339+
340+ use alloc:: { vec, vec:: Vec } ;
341+ use hex_literal:: hex;
342+
343+ use super :: * ;
344+
345+ struct MockBuffer {
346+ in_buf : Vec < u8 > ,
347+ out_buf : Vec < u8 > ,
348+ }
349+
350+ impl From < & [ u8 ] > for MockBuffer {
351+ fn from ( buf : & [ u8 ] ) -> Self {
352+ Self {
353+ in_buf : buf. to_vec ( ) ,
354+ out_buf : vec ! [ 0u8 ; buf. len( ) ] ,
355+ }
356+ }
357+ }
358+
359+ impl MockBuffer {
360+ /// Get an [`InOutBuf`] from a [`MockBuffer`]
361+ pub fn to_in_out_buf ( & mut self ) -> InOutBuf < ' _ , ' _ , u8 > {
362+ InOutBuf :: new ( self . in_buf . as_slice ( ) , self . out_buf . as_mut_slice ( ) )
363+ . expect ( "Invariant violation" )
364+ }
365+ }
366+
367+ impl AsRef < [ u8 ] > for MockBuffer {
368+ fn as_ref ( & self ) -> & [ u8 ] {
369+ & self . out_buf
370+ }
371+ }
372+
373+ #[ test]
374+ fn test_deoxys_i_128_5 ( ) {
375+ let plaintext = hex ! ( "5a4c652cb880808707230679224b11799b5883431292973215e9bd03cf3bc32fe4" ) ;
376+ let mut buffer = MockBuffer :: from ( & plaintext[ ..] ) ;
377+
378+ let aad = Vec :: new ( ) ;
379+
380+ let key = hex ! ( "101112131415161718191a1b1c1d1e1f" ) ;
381+ let key = Array ( key) ;
382+
383+ let nonce = hex ! ( "202122232425262728292a2b2c2d2e2f" ) ;
384+ let nonce = Array :: try_from ( & nonce[ ..8 ] ) . unwrap ( ) ;
385+
386+ let ciphertext_expected =
387+ hex ! ( "cded5a43d3c76e942277c2a1517530ad66037897c985305ede345903ed7585a626" ) ;
388+
389+ let tag_expected: [ u8 ; 16 ] = hex ! ( "cbf5faa6b8398c47f4278d2019161776" ) ;
390+
391+ type M = modes:: DeoxysI < deoxys_bc:: DeoxysBc256 > ;
392+ let cipher = DeoxysI128 :: new ( & key) ;
393+ let tag: Tag = M :: encrypt_inout ( & nonce, & aad, buffer. to_in_out_buf ( ) , & cipher. subkeys ) ;
394+
395+ let ciphertext = buffer. as_ref ( ) ;
396+ assert_eq ! ( ciphertext, ciphertext_expected) ;
397+ assert_eq ! ( tag, tag_expected) ;
398+
399+ let mut buffer = MockBuffer :: from ( buffer. as_ref ( ) ) ;
400+ M :: decrypt_inout ( & nonce, & aad, buffer. to_in_out_buf ( ) , & tag, & cipher. subkeys )
401+ . expect ( "decryption failed" ) ;
402+
403+ assert_eq ! ( & plaintext[ ..] , buffer. as_ref( ) ) ;
404+ }
405+
406+ #[ test]
407+ fn test_deoxys_ii_128_5 ( ) {
408+ let plaintext = hex ! ( "06ac1756eccece62bd743fa80c299f7baa3872b556130f52265919494bdc136db3" ) ;
409+ let mut buffer = MockBuffer :: from ( & plaintext[ ..] ) ;
410+
411+ let aad = Vec :: new ( ) ;
412+
413+ let key = hex ! ( "101112131415161718191a1b1c1d1e1f" ) ;
414+ let key = Array ( key) ;
415+
416+ let nonce = hex ! ( "202122232425262728292a2b2c2d2e2f" ) ;
417+ let nonce = Array :: try_from ( & nonce[ ..15 ] ) . unwrap ( ) ;
418+
419+ let ciphertext_expected =
420+ hex ! ( "82bf241958b324ed053555d23315d3cc20935527fc970ff34a9f521a95e302136d" ) ;
421+
422+ let tag_expected: [ u8 ; 16 ] = hex ! ( "0eadc8612d5208c491e93005195e9769" ) ;
423+
424+ type M = modes:: DeoxysII < deoxys_bc:: DeoxysBc256 > ;
425+ let cipher = DeoxysII128 :: new ( & key) ;
426+ let tag: Tag = M :: encrypt_inout ( & nonce, & aad, buffer. to_in_out_buf ( ) , & cipher. subkeys ) ;
427+
428+ let ciphertext = buffer. as_ref ( ) ;
429+ assert_eq ! ( ciphertext, ciphertext_expected) ;
430+ assert_eq ! ( tag, tag_expected) ;
431+
432+ let mut buffer = MockBuffer :: from ( buffer. as_ref ( ) ) ;
433+ M :: decrypt_inout ( & nonce, & aad, buffer. to_in_out_buf ( ) , & tag, & cipher. subkeys )
434+ . expect ( "decryption failed" ) ;
435+
436+ assert_eq ! ( & plaintext[ ..] , buffer. as_ref( ) ) ;
437+ }
438+ }
0 commit comments