5959
6060use crate :: * ;
6161
62+ use aead:: Tag ;
6263use core:: marker:: PhantomData ;
6364
6465pub use Eax as EaxOnline ;
@@ -141,27 +142,29 @@ impl CipherOp for Decrypt {}
141142/// [`Eax`]: ../struct.Eax.html
142143/// [`Decrypt`]: struct.Decrypt.html
143144/// [`finish`]: #method.finish
144- pub struct Eax < Cipher , Op >
145+ pub struct Eax < Cipher , Op , M = U16 >
145146where
146147 Cipher : BlockCipher < BlockSize = U16 > + NewBlockCipher + Clone ,
147148 Cipher :: ParBlocks : ArrayLength < Block < Cipher > > ,
148149 Op : CipherOp ,
150+ M : TagSize ,
149151{
150- imp : EaxImpl < Cipher > ,
152+ imp : EaxImpl < Cipher , M > ,
151153 /// Denotes whether this stream is used for encryption or decryption.
152154 marker : PhantomData < Op > ,
153155}
154156
155- impl < Cipher , Op > Eax < Cipher , Op >
157+ impl < Cipher , Op , M > Eax < Cipher , Op , M >
156158where
157159 Cipher : BlockCipher < BlockSize = U16 > + NewBlockCipher + Clone ,
158160 Cipher :: ParBlocks : ArrayLength < Block < Cipher > > ,
159161 Op : CipherOp ,
162+ M : TagSize ,
160163{
161164 /// Creates a stateful EAX instance that is capable of processing both
162165 /// the associated data and the plaintext in an "on-line" fashion.
163166 pub fn with_key_and_nonce ( key : & Key < Cipher > , nonce : & Nonce < Cipher :: BlockSize > ) -> Self {
164- let imp = EaxImpl :: < Cipher > :: with_key_and_nonce ( key, nonce) ;
167+ let imp = EaxImpl :: < Cipher , M > :: with_key_and_nonce ( key, nonce) ;
165168
166169 Self {
167170 imp,
@@ -182,15 +185,16 @@ where
182185 ///
183186 ///[`finish`]: #method.finish
184187 #[ inline]
185- pub fn tag_clone ( & self ) -> Tag {
188+ pub fn tag_clone ( & self ) -> Tag < M > {
186189 self . imp . tag_clone ( )
187190 }
188191}
189192
190- impl < Cipher > Eax < Cipher , Encrypt >
193+ impl < Cipher , M > Eax < Cipher , Encrypt , M >
191194where
192195 Cipher : BlockCipher < BlockSize = U16 > + NewBlockCipher + Clone ,
193196 Cipher :: ParBlocks : ArrayLength < Block < Cipher > > ,
197+ M : TagSize ,
194198{
195199 /// Applies encryption to the plaintext.
196200 #[ inline]
@@ -203,15 +207,16 @@ where
203207 /// This *must* be called after the stream encryption is finished.
204208 #[ must_use = "tag must be saved to later verify decrypted data" ]
205209 #[ inline]
206- pub fn finish ( self ) -> Tag {
210+ pub fn finish ( self ) -> Tag < M > {
207211 self . imp . tag ( )
208212 }
209213}
210214
211- impl < Cipher > Eax < Cipher , Decrypt >
215+ impl < Cipher , M > Eax < Cipher , Decrypt , M >
212216where
213217 Cipher : BlockCipher < BlockSize = U16 > + NewBlockCipher + Clone ,
214218 Cipher :: ParBlocks : ArrayLength < Block < Cipher > > ,
219+ M : TagSize ,
215220{
216221 /// Applies decryption to the ciphertext **without** verifying the
217222 /// authenticity of decrypted message.
@@ -246,7 +251,7 @@ where
246251 ///
247252 /// This *must* be called after the stream decryption is finished.
248253 #[ must_use = "decrypted data stream must be verified for authenticity" ]
249- pub fn finish ( self , expected : & Tag ) -> Result < ( ) , Error > {
254+ pub fn finish ( self , expected : & Tag < M > ) -> Result < ( ) , Error > {
250255 self . imp . verify_ct ( expected)
251256 }
252257}
@@ -256,10 +261,11 @@ where
256261/// Main reason behind extracting the logic to a single, separate type is to
257262/// facilitate testing of the internal logic.
258263#[ doc( hidden) ]
259- struct EaxImpl < Cipher >
264+ struct EaxImpl < Cipher , M >
260265where
261266 Cipher : BlockCipher < BlockSize = U16 > + NewBlockCipher + Clone ,
262267 Cipher :: ParBlocks : ArrayLength < Block < Cipher > > ,
268+ M : TagSize ,
263269{
264270 nonce : Nonce < Cipher :: BlockSize > ,
265271 data : Cmac < Cipher > ,
@@ -268,12 +274,14 @@ where
268274 // HACK: Needed for the test harness due to AEAD trait online/offline interface mismatch
269275 #[ cfg( test) ]
270276 key : Key < Cipher > ,
277+ _tag_size : PhantomData < M > ,
271278}
272279
273- impl < Cipher > EaxImpl < Cipher >
280+ impl < Cipher , M > EaxImpl < Cipher , M >
274281where
275282 Cipher : BlockCipher < BlockSize = U16 > + NewBlockCipher + Clone ,
276283 Cipher :: ParBlocks : ArrayLength < Block < Cipher > > ,
284+ M : TagSize ,
277285{
278286 /// Creates a stateful EAX instance that is capable of processing both
279287 /// the associated data and the plaintext in an "on-line" fashion.
@@ -310,6 +318,7 @@ where
310318 ctr : cipher,
311319 #[ cfg( test) ]
312320 key : key. clone ( ) ,
321+ _tag_size : Default :: default ( ) ,
313322 }
314323 }
315324
@@ -335,25 +344,27 @@ where
335344
336345 /// Derives the tag from the encrypted/decrypted message so far.
337346 #[ inline]
338- fn tag ( self ) -> Tag {
347+ fn tag ( self ) -> Tag < M > {
339348 let h = self . data . finalize ( ) . into_bytes ( ) ;
340349 let c = self . message . finalize ( ) . into_bytes ( ) ;
341350
342- self . nonce . zip ( h, |a, b| a ^ b) . zip ( c, |a, b| a ^ b)
351+ let full_tag = self . nonce . zip ( h, |a, b| a ^ b) . zip ( c, |a, b| a ^ b) ;
352+ Tag :: < M > :: clone_from_slice ( & full_tag[ ..M :: to_usize ( ) ] )
343353 }
344354
345355 /// Derives the tag from the encrypted/decrypted message so far.
346356 #[ inline]
347- fn tag_clone ( & self ) -> Tag {
357+ fn tag_clone ( & self ) -> Tag < M > {
348358 let h = self . data . clone ( ) . finalize ( ) . into_bytes ( ) ;
349359 let c = self . message . clone ( ) . finalize ( ) . into_bytes ( ) ;
350360
351- self . nonce . zip ( h, |a, b| a ^ b) . zip ( c, |a, b| a ^ b)
361+ let full_tag = self . nonce . zip ( h, |a, b| a ^ b) . zip ( c, |a, b| a ^ b) ;
362+ Tag :: < M > :: clone_from_slice ( & full_tag[ ..M :: to_usize ( ) ] )
352363 }
353364
354365 /// Finishes the decryption stream, verifying whether the associated and
355366 /// decrypted data stream has not been tampered with.
356- fn verify_ct ( self , expected : & Tag ) -> Result < ( ) , Error > {
367+ fn verify_ct ( self , expected : & Tag < M > ) -> Result < ( ) , Error > {
357368 // Check MAC using secure comparison
358369 use subtle:: ConstantTimeEq ;
359370
@@ -376,10 +387,11 @@ mod test_impl {
376387 use super :: * ;
377388 use aead:: AeadMutInPlace ;
378389
379- impl < Cipher > NewAead for EaxImpl < Cipher >
390+ impl < Cipher , M > NewAead for EaxImpl < Cipher , M >
380391 where
381392 Cipher : BlockCipher < BlockSize = U16 > + NewBlockCipher + Clone ,
382393 Cipher :: ParBlocks : ArrayLength < Block < Cipher > > ,
394+ M : TagSize ,
383395 {
384396 type KeySize = Cipher :: KeySize ;
385397
@@ -395,21 +407,22 @@ mod test_impl {
395407 }
396408 }
397409
398- impl < Cipher > AeadMutInPlace for super :: EaxImpl < Cipher >
410+ impl < Cipher , M > AeadMutInPlace for super :: EaxImpl < Cipher , M >
399411 where
400412 Cipher : BlockCipher < BlockSize = U16 > + NewBlockCipher + Clone ,
401413 Cipher :: ParBlocks : ArrayLength < Block < Cipher > > ,
414+ M : TagSize ,
402415 {
403416 type NonceSize = Cipher :: BlockSize ;
404- type TagSize = < Cmac < Cipher > as Mac > :: OutputSize ;
417+ type TagSize = M ;
405418 type CiphertextOverhead = U0 ;
406419
407420 fn encrypt_in_place_detached (
408421 & mut self ,
409422 nonce : & Nonce < Self :: NonceSize > ,
410423 associated_data : & [ u8 ] ,
411424 buffer : & mut [ u8 ] ,
412- ) -> Result < Tag , Error > {
425+ ) -> Result < Tag < M > , Error > {
413426 // HACK: Reinitialize the instance
414427 * self = Self :: with_key_and_nonce ( & self . key . clone ( ) , nonce) ;
415428
@@ -424,7 +437,7 @@ mod test_impl {
424437 nonce : & Nonce < Self :: NonceSize > ,
425438 associated_data : & [ u8 ] ,
426439 buffer : & mut [ u8 ] ,
427- expected_tag : & Tag ,
440+ expected_tag : & Tag < M > ,
428441 ) -> Result < ( ) , Error > {
429442 // HACK: Reinitialize the instance
430443 * self = Self :: with_key_and_nonce ( & self . key . clone ( ) , nonce) ;
0 commit comments