Skip to content

Commit bf6d41f

Browse files
author
gefeili
committed
TAdd DecryptionFailureCounter to doFinal of decryption
1 parent 0bd3e09 commit bf6d41f

File tree

3 files changed

+67
-42
lines changed

3 files changed

+67
-42
lines changed

core/src/main/java/org/bouncycastle/crypto/engines/AEADBaseEngine.java

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ protected static class State
120120
protected AADProcessingBuffer processor;
121121
protected AADOperator aadOperator;
122122
protected DataOperator dataOperator;
123+
//Only AsconAEAD128 uses this counter;
124+
protected DecryptionFailureCounter decryptionFailureCounter = null;
123125

124126
@Override
125127
public String getAlgorithmName()
@@ -705,17 +707,28 @@ public void reset()
705707
}
706708
}
707709

708-
protected class DecryptionFailureCounter
710+
protected static class DecryptionFailureCounter
709711
{
710-
public DecryptionFailureCounter(int n)
712+
private int n;
713+
private int[] counter;
714+
715+
public void init(int n)
711716
{
712-
this.n = n;
713-
counter = new int[(n + 31) >>> 5];
717+
if (this.n != n)
718+
{
719+
this.n = n;
720+
int len = (n + 31) >>> 5;
721+
if (counter == null || len != counter.length)
722+
{
723+
counter = new int[len];
724+
}
725+
else
726+
{
727+
reset();
728+
}
729+
}
714730
}
715731

716-
private final int n;
717-
private final int[] counter;
718-
719732
public boolean increment()
720733
{
721734
int i = counter.length;
@@ -726,25 +739,14 @@ public boolean increment()
726739
break;
727740
}
728741
}
729-
if ((n & 31) == 0)
730-
{
731-
for (i = 0; i < counter.length; ++i)
732-
{
733-
if (counter[i] != 0)
734-
{
735-
return false;
736-
}
737-
}
738-
return true;
739-
}
740742
for (i = 1; i < counter.length; ++i)
741743
{
742744
if (counter[i] != 0)
743745
{
744746
return false;
745747
}
746748
}
747-
return counter[0] != (1 << (n & 31));
749+
return counter[0] != ((n & 31) == 0 ? 0 : 1 << (n & 31));
748750
}
749751

750752
public void reset()
@@ -953,6 +955,10 @@ public int doFinal(byte[] output, int outOff)
953955
{
954956
if (!Arrays.constantTimeAreEqual(MAC_SIZE, mac, 0, m_buf, m_bufPos))
955957
{
958+
if (decryptionFailureCounter != null && decryptionFailureCounter.increment())
959+
{
960+
throw new InvalidCipherTextException(algorithmName + " decryption failure limit exceeded");
961+
}
956962
throw new InvalidCipherTextException(algorithmName + " mac does not match");
957963
}
958964
}

core/src/main/java/org/bouncycastle/crypto/engines/AsconAEAD128.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public AsconAEAD128()
2828
dsep = -9223372036854775808L; //0x80L << 56
2929
macSizeLowerBound = 4;
3030
setInnerMembers(ProcessingBufferType.Immediate, AADOperatorType.Default, DataOperatorType.Default);
31+
decryptionFailureCounter = new DecryptionFailureCounter();
3132
}
3233

3334
protected long pad(int i)
@@ -141,8 +142,16 @@ private void finishData(State nextState)
141142
protected void init(byte[] key, byte[] iv)
142143
throws IllegalArgumentException
143144
{
144-
K0 = Pack.littleEndianToLong(key, 0);
145-
K1 = Pack.littleEndianToLong(key, 8);
145+
int lambda = (MAC_SIZE << 3) - 32;
146+
long K0 = Pack.littleEndianToLong(key, 0);
147+
long K1 = Pack.littleEndianToLong(key, 8);
148+
decryptionFailureCounter.init(lambda);
149+
if (this.K0 != K0 || this.K1 != K1)
150+
{
151+
decryptionFailureCounter.reset();
152+
this.K0 = K0;
153+
this.K1 = K1;
154+
}
146155
N0 = Pack.littleEndianToLong(iv, 0);
147156
N1 = Pack.littleEndianToLong(iv, 8);
148157
}

core/src/test/java/org/bouncycastle/crypto/test/AsconTest.java

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,18 +1357,28 @@ private static void initEngine(AEADCipher ascon, boolean forEncryption)
13571357
ascon.init(forEncryption, parameters);
13581358
}
13591359

1360-
protected class DecryptionFailureCounter
1360+
protected static class DecryptionFailureCounter
13611361
{
1362-
public DecryptionFailureCounter(int n)
1362+
int n;
1363+
int[] counter;
1364+
1365+
public void init(int n)
13631366
{
1364-
this.n = n;
1365-
counter = new int[(n + 31) >>> 5];
1367+
if (this.n != n)
1368+
{
1369+
this.n = n;
1370+
int len = (n + 31) >>> 5;
1371+
if (counter == null || len != counter.length)
1372+
{
1373+
counter = new int[len];
1374+
}
1375+
else
1376+
{
1377+
reset();
1378+
}
1379+
}
13661380
}
13671381

1368-
public final int n;
1369-
1370-
public final int[] counter;
1371-
13721382
public boolean increment()
13731383
{
13741384
int i = counter.length;
@@ -1379,25 +1389,14 @@ public boolean increment()
13791389
break;
13801390
}
13811391
}
1382-
if ((n & 31) == 0)
1383-
{
1384-
for (i = 0; i < counter.length; ++i)
1385-
{
1386-
if (counter[i] != 0)
1387-
{
1388-
return false;
1389-
}
1390-
}
1391-
return true;
1392-
}
13931392
for (i = 1; i < counter.length; ++i)
13941393
{
13951394
if (counter[i] != 0)
13961395
{
13971396
return false;
13981397
}
13991398
}
1400-
return counter[0] != (1 << (n & 31));
1399+
return counter[0] != ((n & 31) == 0 ? 0 : 1 << (n & 31));
14011400
}
14021401

14031402
public void reset()
@@ -1409,10 +1408,21 @@ public void reset()
14091408
public void testDecryptionFailureCounter()
14101409
{
14111410
int n = 34;
1412-
DecryptionFailureCounter counter = new DecryptionFailureCounter(n);
1411+
DecryptionFailureCounter counter = new DecryptionFailureCounter();
1412+
counter.init(n);
14131413
counter.counter[counter.counter.length - 1] = -2;
14141414
counter.counter[0] = 1;
14151415
isTrue(!counter.increment());
14161416
isTrue(counter.increment());
1417+
1418+
counter.init(32);
1419+
counter.counter[counter.counter.length - 1] = -1;
1420+
isTrue(!counter.increment());
1421+
isTrue(counter.increment());
1422+
1423+
counter.init(5);
1424+
counter.counter[counter.counter.length - 1] = (1 << 5) - 1;
1425+
isTrue(!counter.increment());
1426+
isTrue(counter.increment());
14171427
}
14181428
}

0 commit comments

Comments
 (0)