@@ -65,6 +65,7 @@ private enum State
6565 private byte [] current_mask ;
6666 private byte [] next_mask ;
6767 private final byte [] buffer ;
68+ private final byte [] previous_outputMessage ;
6869 private State m_state = State .Uninitialized ;
6970 private final ByteArrayOutputStream aadData = new ByteArrayOutputStream ();
7071 private int inputOff ;
@@ -135,6 +136,7 @@ public ElephantEngine(ElephantParameters parameters)
135136 current_mask = new byte [BLOCK_SIZE ];
136137 next_mask = new byte [BLOCK_SIZE ];
137138 buffer = new byte [BLOCK_SIZE ];
139+ previous_outputMessage = new byte [BLOCK_SIZE ];
138140 initialised = false ;
139141 reset (false );
140142 }
@@ -285,35 +287,6 @@ private void xor_block(byte[] state, byte[] block, int bOff, int size)
285287 }
286288 }
287289
288- // Return the ith ciphertext block.
289- // clen is the length of the ciphertext in bytes
290- private void get_c_block (byte [] output , byte [] c , int cOff , int clen , int i )
291- {
292- int block_offset = i * BLOCK_SIZE ;
293- // If clen is divisible by BLOCK_SIZE, add an additional padding block
294- if (block_offset == clen )
295- {
296- Arrays .fill (output , 0 , BLOCK_SIZE , (byte )0 );
297- output [0 ] = 0x01 ;
298- return ;
299- }
300- int r_clen = clen - block_offset ;
301- // Fill with ciphertext if available
302- if (BLOCK_SIZE <= r_clen )
303- { // enough ciphertext
304- System .arraycopy (c , cOff + block_offset , output , 0 , BLOCK_SIZE );
305- }
306- else
307- { // not enough ciphertext, need to pad
308- if (r_clen > 0 ) // c might be nullptr
309- {
310- System .arraycopy (c , cOff + block_offset , output , 0 , r_clen );
311- Arrays .fill (output , r_clen , BLOCK_SIZE , (byte )0 );
312- output [r_clen ] = 0x01 ;
313- }
314- }
315- }
316-
317290 @ Override
318291 public void init (boolean forEncryption , CipherParameters params )
319292 throws IllegalArgumentException
@@ -400,11 +373,11 @@ public int processBytes(byte[] input, int inOff, int len, byte[] output, int out
400373 byte [] tempInput = new byte [Math .max (nblocks_c , 1 ) * BLOCK_SIZE ];
401374 System .arraycopy (inputMessage , 0 , tempInput , 0 , inputOff );
402375 System .arraycopy (input , inOff , tempInput , inputOff , Math .min (len , tempInput .length ));
403- int rv = processBytes (tempInput , output , outOff , nb_it , nblocks_m , nblocks_c , mlen , nblocks_ad );
376+ int rv = processBytes (tempInput , output , outOff , nb_it , nblocks_m , nblocks_c , mlen , nblocks_ad , false );
404377 int copyLen = rv - inputOff ;
405378 inputOff = inputOff + len - rv ;
406379 System .arraycopy (input , inOff + copyLen , inputMessage , 0 , inputOff );
407- nb_its += nblocks_c + 1 ;
380+
408381 messageLen += rv ;
409382 return rv ;
410383 }
@@ -436,7 +409,7 @@ public int doFinal(byte[] output, int outOff)
436409 int nblocks_m = (mlen % BLOCK_SIZE ) != 0 ? nblocks_c : nblocks_c - 1 ;
437410 int nblocks_ad = 1 + (CRYPTO_NPUBBYTES + adlen ) / BLOCK_SIZE ;
438411 int nb_it = Math .max (nblocks_c + 1 , nblocks_ad - 1 );
439- outOff += processBytes (inputMessage , output , outOff , nb_it , nblocks_m , nblocks_c , mlen , nblocks_ad );
412+ outOff += processBytes (inputMessage , output , outOff , nb_it , nblocks_m , nblocks_c , mlen , nblocks_ad , true );
440413 tag = new byte [CRYPTO_ABYTES ];
441414 xor_block (tag_buffer , expanded_key , 0 , BLOCK_SIZE );
442415 permutation (tag_buffer );
@@ -531,6 +504,7 @@ private void reset(boolean clearMac)
531504 }
532505 aadData .reset ();
533506 Arrays .fill (tag_buffer , (byte )0 );
507+ Arrays .fill (previous_outputMessage , (byte )0 );
534508 inputOff = 0 ;
535509 nb_its = 0 ;
536510 adOff = -1 ;
@@ -639,12 +613,18 @@ private void processAADBytes(byte[] output)
639613 }
640614
641615 private int processBytes (byte [] m , byte [] output , int outOff , int nb_it , int nblocks_m , int nblocks_c , int mlen ,
642- int nblocks_ad )
616+ int nblocks_ad , boolean isDofinal )
643617 {
644618 int rv = 0 ;
645- int original_outOff = outOff ;
646- for (int i = nb_its ; i < nb_it ; ++i )
619+ byte [] outputMessage = new byte [BLOCK_SIZE ];
620+ int i ;
621+ for (i = nb_its ; i < nb_it ; ++i )
647622 {
623+ int r_size = (i == nblocks_m - 1 ) ? mlen - i * BLOCK_SIZE : BLOCK_SIZE ;
624+ if (!isDofinal && (r_size % BLOCK_SIZE != 0 || mlen <= i * BLOCK_SIZE ))
625+ {
626+ break ;
627+ }
648628 // Compute mask for the next message
649629 lfsr_step (next_mask , current_mask );
650630 if (i < nblocks_m )
@@ -657,23 +637,50 @@ private int processBytes(byte[] m, byte[] output, int outOff, int nb_it, int nbl
657637 permutation (buffer );
658638 xor_block (buffer , current_mask , 0 , BLOCK_SIZE );
659639 xor_block (buffer , next_mask , 0 , BLOCK_SIZE );
660- int r_size = ( i == nblocks_m - 1 ) ? mlen - i * BLOCK_SIZE : BLOCK_SIZE ;
640+
661641 xor_block (buffer , m , rv , r_size );
662642 System .arraycopy (buffer , 0 , output , outOff , r_size );
643+ if (forEncryption )
644+ {
645+ System .arraycopy (buffer , 0 , outputMessage , 0 , r_size );
646+ }
647+ else
648+ {
649+ System .arraycopy (m , rv , outputMessage , 0 , r_size );
650+ }
651+
663652 outOff += r_size ;
664653 rv += r_size ;
665654 }
666655 if (i > 0 && i <= nblocks_c )
667656 {
668- // Compute tag for ciphertext block
669- if (forEncryption )
657+ //get_c_block: Compute tag for ciphertext block
658+ int block_offset = (i - 1 ) * BLOCK_SIZE ;
659+ // If clen is divisible by BLOCK_SIZE, add an additional padding block
660+ if (block_offset == mlen )
670661 {
671- get_c_block (buffer , output , original_outOff , mlen , i - 1 );
662+ Arrays .fill (buffer , 0 , BLOCK_SIZE , (byte )0 );
663+ buffer [0 ] = 0x01 ;
672664 }
673665 else
674666 {
675- get_c_block (buffer , m , 0 , mlen , i - 1 );
667+ int r_clen = mlen - block_offset ;
668+ // Fill with ciphertext if available
669+ if (BLOCK_SIZE <= r_clen )
670+ { // enough ciphertext
671+ System .arraycopy (previous_outputMessage , 0 , buffer , 0 , BLOCK_SIZE );
672+ }
673+ else
674+ { // not enough ciphertext, need to pad
675+ if (r_clen > 0 ) // c might be nullptr
676+ {
677+ System .arraycopy (previous_outputMessage , 0 , buffer , 0 , r_clen );
678+ Arrays .fill (buffer , r_clen , BLOCK_SIZE , (byte )0 );
679+ buffer [r_clen ] = 0x01 ;
680+ }
681+ }
676682 }
683+
677684 xor_block (buffer , previous_mask , 0 , BLOCK_SIZE );
678685 xor_block (buffer , next_mask , 0 , BLOCK_SIZE );
679686 permutation (buffer );
@@ -696,7 +703,9 @@ private int processBytes(byte[] m, byte[] output, int outOff, int nb_it, int nbl
696703 previous_mask = current_mask ;
697704 current_mask = next_mask ;
698705 next_mask = temp ;
706+ System .arraycopy (outputMessage , 0 , previous_outputMessage , 0 , BLOCK_SIZE );
699707 }
708+ nb_its = i ;
700709 return rv ;
701710 }
702711}
0 commit comments