@@ -306,7 +306,16 @@ public virtual int ProcessByte(
306
306
bufBlock [ bufOff ] = input ;
307
307
if ( ++ bufOff == bufBlock . Length )
308
308
{
309
- OutputBlock ( output , outOff ) ;
309
+ ProcessBlock ( bufBlock , 0 , output , outOff ) ;
310
+ if ( forEncryption )
311
+ {
312
+ bufOff = 0 ;
313
+ }
314
+ else
315
+ {
316
+ Array . Copy ( bufBlock , BlockSize , bufBlock , 0 , macSize ) ;
317
+ bufOff = macSize ;
318
+ }
310
319
return BlockSize ;
311
320
}
312
321
return 0 ;
@@ -321,41 +330,58 @@ public virtual int ProcessBytes(
321
330
{
322
331
CheckStatus ( ) ;
323
332
324
- if ( input . Length < ( inOff + len ) )
325
- throw new DataLengthException ( "Input buffer too short" ) ;
333
+ Check . DataLength ( input , inOff , len , "input buffer too short" ) ;
326
334
327
335
int resultLen = 0 ;
328
336
329
- for ( int i = 0 ; i < len ; ++ i )
337
+ if ( forEncryption )
330
338
{
331
- bufBlock [ bufOff ] = input [ inOff + i ] ;
332
- if ( ++ bufOff == bufBlock . Length )
339
+ if ( bufOff != 0 )
333
340
{
334
- OutputBlock ( output , outOff + resultLen ) ;
335
- resultLen += BlockSize ;
341
+ while ( len > 0 )
342
+ {
343
+ -- len ;
344
+ bufBlock [ bufOff ] = input [ inOff ++ ] ;
345
+ if ( ++ bufOff == BlockSize )
346
+ {
347
+ ProcessBlock ( bufBlock , 0 , output , outOff ) ;
348
+ bufOff = 0 ;
349
+ resultLen += BlockSize ;
350
+ break ;
351
+ }
352
+ }
336
353
}
337
- }
338
354
339
- return resultLen ;
340
- }
355
+ while ( len >= BlockSize )
356
+ {
357
+ ProcessBlock ( input , inOff , output , outOff + resultLen ) ;
358
+ inOff += BlockSize ;
359
+ len -= BlockSize ;
360
+ resultLen += BlockSize ;
361
+ }
341
362
342
- private void OutputBlock ( byte [ ] output , int offset )
343
- {
344
- Check . OutputLength ( output , offset , BlockSize , "Output buffer too short" ) ;
345
- if ( totalLength == 0 )
346
- {
347
- InitCipher ( ) ;
348
- }
349
- gCTRBlock ( bufBlock , output , offset ) ;
350
- if ( forEncryption )
351
- {
352
- bufOff = 0 ;
363
+ if ( len > 0 )
364
+ {
365
+ Array . Copy ( input , inOff , bufBlock , 0 , len ) ;
366
+ bufOff = len ;
367
+ }
353
368
}
354
369
else
355
370
{
356
- Array . Copy ( bufBlock , BlockSize , bufBlock , 0 , macSize ) ;
357
- bufOff = macSize ;
371
+ for ( int i = 0 ; i < len ; ++ i )
372
+ {
373
+ bufBlock [ bufOff ] = input [ inOff + i ] ;
374
+ if ( ++ bufOff == bufBlock . Length )
375
+ {
376
+ ProcessBlock ( bufBlock , 0 , output , outOff + resultLen ) ;
377
+ Array . Copy ( bufBlock , BlockSize , bufBlock , 0 , macSize ) ;
378
+ bufOff = macSize ;
379
+ resultLen += BlockSize ;
380
+ }
381
+ }
358
382
}
383
+
384
+ return resultLen ;
359
385
}
360
386
361
387
public int DoFinal ( byte [ ] output , int outOff )
@@ -385,7 +411,7 @@ public int DoFinal(byte[] output, int outOff)
385
411
386
412
if ( extra > 0 )
387
413
{
388
- gCTRPartial ( bufBlock , 0 , extra , output , outOff ) ;
414
+ ProcessPartial ( bufBlock , 0 , extra , output , outOff ) ;
389
415
}
390
416
391
417
atLength += ( uint ) atBlockPos ;
@@ -515,27 +541,50 @@ private void Reset(
515
541
}
516
542
}
517
543
518
- private void gCTRBlock ( byte [ ] block , byte [ ] output , int outOff )
544
+ private void ProcessBlock ( byte [ ] buf , int bufOff , byte [ ] output , int outOff )
519
545
{
520
- byte [ ] tmp = GetNextCounterBlock ( ) ;
546
+ Check . OutputLength ( output , outOff , BlockSize , "Output buffer too short" ) ;
521
547
522
- GcmUtilities . Xor ( tmp , block ) ;
523
- Array . Copy ( tmp , 0 , output , outOff , BlockSize ) ;
548
+ if ( totalLength == 0 )
549
+ {
550
+ InitCipher ( ) ;
551
+ }
552
+
553
+ byte [ ] ctrBlock = new byte [ BlockSize ] ;
554
+ GetNextCtrBlock ( ctrBlock ) ;
524
555
525
- gHASHBlock ( S , forEncryption ? tmp : block ) ;
556
+ if ( forEncryption )
557
+ {
558
+ GcmUtilities . Xor ( ctrBlock , buf , bufOff ) ;
559
+ gHASHBlock ( S , ctrBlock ) ;
560
+ Array . Copy ( ctrBlock , 0 , output , outOff , BlockSize ) ;
561
+ }
562
+ else
563
+ {
564
+ gHASHBlock ( S , buf , bufOff ) ;
565
+ GcmUtilities . Xor ( ctrBlock , 0 , buf , bufOff , output , outOff ) ;
566
+ }
526
567
527
568
totalLength += BlockSize ;
528
569
}
529
570
530
- private void gCTRPartial ( byte [ ] buf , int off , int len , byte [ ] output , int outOff )
571
+ private void ProcessPartial ( byte [ ] buf , int off , int len , byte [ ] output , int outOff )
531
572
{
532
- byte [ ] tmp = GetNextCounterBlock ( ) ;
573
+ byte [ ] ctrBlock = new byte [ BlockSize ] ;
574
+ GetNextCtrBlock ( ctrBlock ) ;
533
575
534
- GcmUtilities . Xor ( tmp , buf , off , len ) ;
535
- Array . Copy ( tmp , 0 , output , outOff , len ) ;
536
-
537
- gHASHPartial ( S , forEncryption ? tmp : buf , 0 , len ) ;
576
+ if ( forEncryption )
577
+ {
578
+ GcmUtilities . Xor ( buf , off , ctrBlock , 0 , len ) ;
579
+ gHASHPartial ( S , buf , off , len ) ;
580
+ }
581
+ else
582
+ {
583
+ gHASHPartial ( S , buf , off , len ) ;
584
+ GcmUtilities . Xor ( buf , off , ctrBlock , 0 , len ) ;
585
+ }
538
586
587
+ Array . Copy ( buf , off , output , outOff , len ) ;
539
588
totalLength += ( uint ) len ;
540
589
}
541
590
@@ -554,13 +603,19 @@ private void gHASHBlock(byte[] Y, byte[] b)
554
603
multiplier . MultiplyH ( Y ) ;
555
604
}
556
605
606
+ private void gHASHBlock ( byte [ ] Y , byte [ ] b , int off )
607
+ {
608
+ GcmUtilities . Xor ( Y , b , off ) ;
609
+ multiplier . MultiplyH ( Y ) ;
610
+ }
611
+
557
612
private void gHASHPartial ( byte [ ] Y , byte [ ] b , int off , int len )
558
613
{
559
614
GcmUtilities . Xor ( Y , b , off , len ) ;
560
615
multiplier . MultiplyH ( Y ) ;
561
616
}
562
617
563
- private byte [ ] GetNextCounterBlock ( )
618
+ private void GetNextCtrBlock ( byte [ ] block )
564
619
{
565
620
if ( blocksRemaining == 0 )
566
621
throw new InvalidOperationException ( "Attempt to process too many blocks" ) ;
@@ -573,10 +628,7 @@ private byte[] GetNextCounterBlock()
573
628
c += counter [ 13 ] ; counter [ 13 ] = ( byte ) c ; c >>= 8 ;
574
629
c += counter [ 12 ] ; counter [ 12 ] = ( byte ) c ;
575
630
576
- byte [ ] tmp = new byte [ BlockSize ] ;
577
- // TODO Sure would be nice if ciphers could operate on int[]
578
- cipher . ProcessBlock ( counter , 0 , tmp , 0 ) ;
579
- return tmp ;
631
+ cipher . ProcessBlock ( counter , 0 , block , 0 ) ;
580
632
}
581
633
582
634
private void CheckStatus ( )
0 commit comments