@@ -38,10 +38,12 @@ protected static class AADOperatorType
3838 public static final int DEFAULT = 0 ;
3939 public static final int COUNTER = 1 ;//add a counter to count the size of AAD
4040 public static final int STREAM = 2 ; //process AAD data during the process data, used for elephant
41+ public static final int DATA_LIMIT = 3 ;// count AAD data to the counter, used for AsconAEAD128
4142
4243 public static final AADOperatorType Default = new AADOperatorType (DEFAULT );
4344 public static final AADOperatorType Counter = new AADOperatorType (COUNTER );
4445 public static final AADOperatorType Stream = new AADOperatorType (STREAM );
46+ public static final AADOperatorType DataLimit = new AADOperatorType (DATA_LIMIT );
4547
4648 private final int ord ;
4749
@@ -57,11 +59,13 @@ protected static class DataOperatorType
5759 public static final int COUNTER = 1 ;
5860 public static final int STREAM = 2 ;
5961 public static final int STREAM_CIPHER = 3 ;
62+ public static final int DATA_LIMIT = 4 ; // count AAD data to the counter, used for AsconAEAD128
6063
6164 public static final DataOperatorType Default = new DataOperatorType (DEFAULT );
6265 public static final DataOperatorType Counter = new DataOperatorType (COUNTER );
6366 public static final DataOperatorType Stream = new DataOperatorType (STREAM );
6467 public static final DataOperatorType StreamCipher = new DataOperatorType (STREAM_CIPHER );
68+ public static final DataOperatorType DataLimit = new DataOperatorType (DATA_LIMIT );
6569
6670 private final int ord ;
6771
@@ -121,7 +125,8 @@ protected static class State
121125 protected AADOperator aadOperator ;
122126 protected DataOperator dataOperator ;
123127 //Only AsconAEAD128 uses this counter;
124- protected Counter decryptionFailureCounter = null ;
128+ protected DecryptionFailureCounter decryptionFailureCounter = null ;
129+ protected DataLimitCounter dataLimitCounter = null ;
125130
126131 @ Override
127132 public String getAlgorithmName ()
@@ -210,6 +215,10 @@ else if (params instanceof ParametersWithIV)
210215
211216 m_state = forEncryption ? State .EncInit : State .DecInit ;
212217 init (k , npub );
218+ if (dataLimitCounter != null )
219+ {
220+ dataLimitCounter .increment (npub .length );
221+ }
213222 reset (true );
214223 if (initialAssociatedText != null )
215224 {
@@ -290,6 +299,10 @@ protected void setInnerMembers(ProcessingBufferType type, AADOperatorType aadOpe
290299 AADBufferSize = 0 ;
291300 aadOperator = new StreamAADOperator ();
292301 break ;
302+ case AADOperatorType .DATA_LIMIT :
303+ m_aad = new byte [AADBufferSize ];
304+ aadOperator = new DataLimitAADOperator ();
305+ break ;
293306 }
294307
295308 switch (dataOperatorType .ord )
@@ -311,6 +324,10 @@ protected void setInnerMembers(ProcessingBufferType type, AADOperatorType aadOpe
311324 m_buf = new byte [m_bufferSizeDecrypt ];
312325 dataOperator = new StreamCipherOperator ();
313326 break ;
327+ case DataOperatorType .DATA_LIMIT :
328+ m_buf = new byte [m_bufferSizeDecrypt ];
329+ dataOperator = new DataLimitDataOperator ();
330+ break ;
314331 }
315332 }
316333
@@ -511,6 +528,34 @@ public int getLen()
511528 }
512529 }
513530
531+ private class DataLimitAADOperator
532+ implements AADOperator
533+ {
534+ @ Override
535+ public void processAADByte (byte input )
536+ {
537+ dataLimitCounter .increment ();
538+ processor .processAADByte (input );
539+ }
540+
541+ @ Override
542+ public void processAADBytes (byte [] input , int inOff , int len )
543+ {
544+ dataLimitCounter .increment (len );
545+ processAadBytes (input , inOff , len );
546+ }
547+
548+ public void reset ()
549+ {
550+ }
551+
552+ @ Override
553+ public int getLen ()
554+ {
555+ return m_aadPos ;
556+ }
557+ }
558+
514559 protected interface DataOperator
515560 {
516561 int processByte (byte input , byte [] output , int outOff );
@@ -707,7 +752,34 @@ public void reset()
707752 }
708753 }
709754
710- protected static class Counter
755+ private class DataLimitDataOperator
756+ implements DataOperator
757+ {
758+ public int processByte (byte input , byte [] output , int outOff )
759+ {
760+ dataLimitCounter .increment ();
761+ return processor .processByte (input , output , outOff );
762+ }
763+
764+ public int processBytes (byte [] input , int inOff , int len , byte [] output , int outOff )
765+ {
766+ dataLimitCounter .increment (len );
767+ return processEncDecBytes (input , inOff , len , output , outOff );
768+ }
769+
770+ @ Override
771+ public int getLen ()
772+ {
773+ return m_bufPos ;
774+ }
775+
776+ @ Override
777+ public void reset ()
778+ {
779+ }
780+ }
781+
782+ protected static class DecryptionFailureCounter
711783 {
712784 private int n ;
713785 private int [] counter ;
@@ -739,19 +811,92 @@ public boolean increment()
739811 break ;
740812 }
741813 }
742- for (i = 1 ; i < counter .length ; ++i )
814+ int r = n & 31 ;
815+ return i <= 0 && counter [0 ] == (r == 0 ? 0 : (1 << r ));
816+ }
817+
818+ // In case when we need to use this counter to count data limit
819+ // public boolean increment(int delta)
820+ // {
821+ // // Convert to long to handle unsigned arithmetic
822+ // long carry = delta & 0xFFFFFFFFL;
823+ // // Process each word starting from LSB
824+ // int i = counter.length;
825+ // while (carry != 0 && --i >= 0)
826+ // {
827+ // long sum = (counter[i] & 0xFFFFFFFFL) + carry;
828+ // counter[i] = (int)sum;
829+ // carry = sum >>> 32;
830+ // }
831+ //
832+ // // Final limit check if we didn't overflow
833+ // return carry != 0 || checkLimit();
834+ // }
835+ //
836+ // private boolean checkLimit()
837+ // {
838+ // int bitIndex = ((n - 1) & 31) + 1;
839+ // long bound = 1L << bitIndex;
840+ // long val = counter[0] & 0xFFFFFFFFL;
841+ // if (val > bound)
842+ // {
843+ // return true;
844+ // }
845+ // if (val < bound)
846+ // {
847+ // return false;
848+ // }
849+ // // Check if we've reached/exceeded 2^n
850+ // for (int i = 1; i < counter.length; ++i)
851+ // {
852+ // val = counter[i] & 0xFFFFFFFFL;
853+ // if (val > 0)
854+ // {
855+ // return true;
856+ // }
857+ // }
858+ // return true; // Exactly equal to 2^n
859+ // }
860+
861+ public void reset ()
862+ {
863+ Arrays .fill (counter , 0 );
864+ }
865+ }
866+
867+ protected static class DataLimitCounter
868+ {
869+ //if the maximum exceed Long.MAX_VALUE, Improve DecryptionFailureCounter and use it instead
870+ private long count ;
871+ private long max ;
872+ private int n ;
873+
874+ public void init (int n )
875+ {
876+ this .n = n ;
877+ this .max = 1L << n ;
878+ }
879+
880+ public void increment ()
881+ {
882+ if (++count > max )
743883 {
744- if (counter [i ] != 0 )
745- {
746- return false ;
747- }
884+ throw new IllegalStateException ("Total data limit exceeded: maximum 2^" + n + " bytes per key (including nonce, AAD, and message)" );
885+ }
886+ }
887+
888+ public void increment (int n )
889+ {
890+ count += n ;
891+ if (count > max )
892+ {
893+ throw new IllegalStateException ("Total data limit exceeded: maximum 2^" + n + " bytes per key (including nonce, AAD, and message)" );
748894 }
749- return counter [0 ] != ((n & 31 ) == 0 ? 0 : 1 << (n & 31 ));
750895 }
751896
752897 public void reset ()
753898 {
754- Arrays . fill ( counter , 0 ) ;
899+ count = 0 ;
755900 }
756901 }
757902
0 commit comments