@@ -65,6 +65,7 @@ private enum State
65
65
private byte [] current_mask ;
66
66
private byte [] next_mask ;
67
67
private final byte [] buffer ;
68
+ private final byte [] previous_outputMessage ;
68
69
private State m_state = State .Uninitialized ;
69
70
private final ByteArrayOutputStream aadData = new ByteArrayOutputStream ();
70
71
private int inputOff ;
@@ -135,6 +136,7 @@ public ElephantEngine(ElephantParameters parameters)
135
136
current_mask = new byte [BLOCK_SIZE ];
136
137
next_mask = new byte [BLOCK_SIZE ];
137
138
buffer = new byte [BLOCK_SIZE ];
139
+ previous_outputMessage = new byte [BLOCK_SIZE ];
138
140
initialised = false ;
139
141
reset (false );
140
142
}
@@ -285,35 +287,6 @@ private void xor_block(byte[] state, byte[] block, int bOff, int size)
285
287
}
286
288
}
287
289
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
-
317
290
@ Override
318
291
public void init (boolean forEncryption , CipherParameters params )
319
292
throws IllegalArgumentException
@@ -400,11 +373,11 @@ public int processBytes(byte[] input, int inOff, int len, byte[] output, int out
400
373
byte [] tempInput = new byte [Math .max (nblocks_c , 1 ) * BLOCK_SIZE ];
401
374
System .arraycopy (inputMessage , 0 , tempInput , 0 , inputOff );
402
375
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 );
404
377
int copyLen = rv - inputOff ;
405
378
inputOff = inputOff + len - rv ;
406
379
System .arraycopy (input , inOff + copyLen , inputMessage , 0 , inputOff );
407
- nb_its += nblocks_c + 1 ;
380
+
408
381
messageLen += rv ;
409
382
return rv ;
410
383
}
@@ -436,7 +409,7 @@ public int doFinal(byte[] output, int outOff)
436
409
int nblocks_m = (mlen % BLOCK_SIZE ) != 0 ? nblocks_c : nblocks_c - 1 ;
437
410
int nblocks_ad = 1 + (CRYPTO_NPUBBYTES + adlen ) / BLOCK_SIZE ;
438
411
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 );
440
413
tag = new byte [CRYPTO_ABYTES ];
441
414
xor_block (tag_buffer , expanded_key , 0 , BLOCK_SIZE );
442
415
permutation (tag_buffer );
@@ -531,6 +504,7 @@ private void reset(boolean clearMac)
531
504
}
532
505
aadData .reset ();
533
506
Arrays .fill (tag_buffer , (byte )0 );
507
+ Arrays .fill (previous_outputMessage , (byte )0 );
534
508
inputOff = 0 ;
535
509
nb_its = 0 ;
536
510
adOff = -1 ;
@@ -639,12 +613,18 @@ private void processAADBytes(byte[] output)
639
613
}
640
614
641
615
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 )
643
617
{
644
618
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 )
647
622
{
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
+ }
648
628
// Compute mask for the next message
649
629
lfsr_step (next_mask , current_mask );
650
630
if (i < nblocks_m )
@@ -657,23 +637,50 @@ private int processBytes(byte[] m, byte[] output, int outOff, int nb_it, int nbl
657
637
permutation (buffer );
658
638
xor_block (buffer , current_mask , 0 , BLOCK_SIZE );
659
639
xor_block (buffer , next_mask , 0 , BLOCK_SIZE );
660
- int r_size = ( i == nblocks_m - 1 ) ? mlen - i * BLOCK_SIZE : BLOCK_SIZE ;
640
+
661
641
xor_block (buffer , m , rv , r_size );
662
642
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
+
663
652
outOff += r_size ;
664
653
rv += r_size ;
665
654
}
666
655
if (i > 0 && i <= nblocks_c )
667
656
{
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 )
670
661
{
671
- get_c_block (buffer , output , original_outOff , mlen , i - 1 );
662
+ Arrays .fill (buffer , 0 , BLOCK_SIZE , (byte )0 );
663
+ buffer [0 ] = 0x01 ;
672
664
}
673
665
else
674
666
{
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
+ }
676
682
}
683
+
677
684
xor_block (buffer , previous_mask , 0 , BLOCK_SIZE );
678
685
xor_block (buffer , next_mask , 0 , BLOCK_SIZE );
679
686
permutation (buffer );
@@ -696,7 +703,9 @@ private int processBytes(byte[] m, byte[] output, int outOff, int nb_it, int nbl
696
703
previous_mask = current_mask ;
697
704
current_mask = next_mask ;
698
705
next_mask = temp ;
706
+ System .arraycopy (outputMessage , 0 , previous_outputMessage , 0 , BLOCK_SIZE );
699
707
}
708
+ nb_its = i ;
700
709
return rv ;
701
710
}
702
711
}
0 commit comments