Skip to content

Commit 1d5735c

Browse files
author
gefeili
committed
Change ISAPEngine.aadData from ByteArrayOutputStream to byte[ISAP_rH_SZ]
1 parent 44ed712 commit 1d5735c

File tree

2 files changed

+131
-33
lines changed

2 files changed

+131
-33
lines changed

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

Lines changed: 124 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.bouncycastle.crypto.DataLengthException;
77
import org.bouncycastle.crypto.InvalidCipherTextException;
88
import org.bouncycastle.crypto.OutputLengthException;
9+
import org.bouncycastle.util.Arrays;
910
import org.bouncycastle.util.Pack;
1011

1112
/**
@@ -51,18 +52,22 @@ public ISAPEngine(IsapType isapType)
5152
algorithmName = "ISAP-K-128 AEAD";
5253
break;
5354
}
55+
aadData = new byte[ISAP_rH_SZ];
5456
}
5557

5658
private boolean initialised;
5759
final int ISAP_STATE_SZ = 40;
5860
private byte[] k;
5961
private byte[] npub;
60-
private final ByteArrayOutputStream aadData = new ByteArrayOutputStream();
62+
//private final ByteArrayOutputStream aadData = new ByteArrayOutputStream();
63+
private final byte[] aadData;
64+
private int aadOff;
6165
private final ByteArrayOutputStream message = new ByteArrayOutputStream();
6266
private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
6367
private int ISAP_rH;
6468
private int ISAP_rH_SZ;
6569
private ISAP_AEAD ISAPAEAD;
70+
private boolean aadFinished;
6671

6772
private interface ISAP_AEAD
6873
{
@@ -73,6 +78,10 @@ private interface ISAP_AEAD
7378
void isap_mac(byte[] ad, int adlen, byte[] c, int clen, byte[] tag);
7479

7580
void reset();
81+
82+
void absorbMacBlock(byte[] input, int inOff);
83+
84+
void swapInternalState();
7685
}
7786

7887
private abstract class ISAPAEAD_A
@@ -83,7 +92,7 @@ private abstract class ISAPAEAD_A
8392
protected long ISAP_IV1_64;
8493
protected long ISAP_IV2_64;
8594
protected long ISAP_IV3_64;
86-
protected long x0, x1, x2, x3, x4, t0, t1, t2, t3, t4;
95+
protected long x0, x1, x2, x3, x4, t0, t1, t2, t3, t4, macx0, macx1, macx2, macx3, macx4;
8796

8897
public ISAPAEAD_A()
8998
{
@@ -97,13 +106,38 @@ public void init()
97106
k64 = new long[getLongSize(k.length)];
98107
Pack.bigEndianToLong(npub, 0, npub64);
99108
Pack.bigEndianToLong(k, 0, k64);
100-
reset();
109+
//reset();
101110
}
102111

103112
protected abstract void PX1();
104113

105114
protected abstract void PX2();
106115

116+
public void swapInternalState()
117+
{
118+
t0 = x0;
119+
t1 = x1;
120+
t2 = x2;
121+
t3 = x3;
122+
t4 = x4;
123+
x0 = macx0;
124+
x1 = macx1;
125+
x2 = macx2;
126+
x3 = macx3;
127+
x4 = macx4;
128+
macx0 = t0;
129+
macx1 = t1;
130+
macx2 = t2;
131+
macx3 = t3;
132+
macx4 = t4;
133+
}
134+
135+
public void absorbMacBlock(byte[] input, int inOff)
136+
{
137+
x0 ^= Pack.bigEndianToLong(input, inOff);
138+
P12();
139+
}
140+
107141
protected void ABSORB_MAC(byte[] src, int len)
108142
{
109143
long[] src64 = new long[src.length >> 3];
@@ -127,11 +161,12 @@ protected void ABSORB_MAC(byte[] src, int len)
127161
public void isap_mac(byte[] ad, int adlen, byte[] c, int clen, byte[] tag)
128162
{
129163
// Init State
130-
x0 = npub64[0];
131-
x1 = npub64[1];
132-
x2 = ISAP_IV1_64;
133-
x3 = x4 = 0;
134-
P12();
164+
// x0 = npub64[0];
165+
// x1 = npub64[1];
166+
// x2 = ISAP_IV1_64;
167+
// x3 = x4 = 0;
168+
// P12();
169+
135170
ABSORB_MAC(ad, adlen);
136171
// Domain seperation
137172
x4 ^= 1L;
@@ -198,6 +233,13 @@ public void reset()
198233
x3 = npub64[0];
199234
x4 = npub64[1];
200235
PX1();
236+
swapInternalState();
237+
// Init State for mac
238+
x0 = npub64[0];
239+
x1 = npub64[1];
240+
x2 = ISAP_IV1_64;
241+
x3 = x4 = 0;
242+
P12();
201243
}
202244

203245
private int getLongSize(int x)
@@ -306,8 +348,11 @@ private abstract class ISAPAEAD_K
306348
private final int[] KeccakF400RoundConstants = {0x0001, 0x8082, 0x808a, 0x8000, 0x808b, 0x0001, 0x8081, 0x8009,
307349
0x008a, 0x0088, 0x8009, 0x000a, 0x808b, 0x008b, 0x8089, 0x8003, 0x8002, 0x0080, 0x800a, 0x000a};
308350
protected short[] SX = new short[25];
351+
protected short[] macSX = new short[25];
309352
protected short[] E = new short[25];
310353
protected short[] C = new short[5];
354+
protected short[] macE = new short[25];
355+
protected short[] macC = new short[5];
311356

312357
public ISAPAEAD_K()
313358
{
@@ -321,18 +366,35 @@ public void init()
321366
byteToShort(k, k16, k16.length);
322367
iv16 = new short[npub.length >> 1];
323368
byteToShort(npub, iv16, iv16.length);
324-
reset();
369+
//reset();
325370
}
326371

327372
public void reset()
328373
{
329374
// Init state
330-
SX = new short[25];
331-
E = new short[25];
332-
C = new short[5];
375+
Arrays.fill(SX, (byte)0);
333376
isap_rk(ISAP_IV3_16, npub, IV_SIZE, SX, ISAP_STATE_SZ_CRYPTO_NPUBBYTES, C);
334377
System.arraycopy(iv16, 0, SX, 17, 8);
335378
PermuteRoundsKX(SX, E, C);
379+
// Init state for mac
380+
swapInternalState();
381+
Arrays.fill(SX, 12, 25, (short) 0);
382+
System.arraycopy(iv16, 0, SX, 0, 8);
383+
System.arraycopy(ISAP_IV1_16, 0, SX, 8, 4);
384+
PermuteRoundsHX(SX, E, C);
385+
}
386+
387+
public void swapInternalState()
388+
{
389+
short[] tmp = SX;
390+
SX = macSX;
391+
macSX = tmp;
392+
tmp = E;
393+
E = macE;
394+
macE = tmp;
395+
tmp = C;
396+
C = macC;
397+
macC = tmp;
336398
}
337399

338400
protected abstract void PermuteRoundsHX(short[] SX, short[] E, short[] C);
@@ -341,6 +403,12 @@ public void reset()
341403

342404
protected abstract void PermuteRoundsBX(short[] SX, short[] E, short[] C);
343405

406+
public void absorbMacBlock(byte[] input, int inOff)
407+
{
408+
byteToShortXor(input, inOff, SX, ISAP_rH_SZ >> 1);
409+
PermuteRoundsHX(SX, E, C);
410+
}
411+
344412
protected void ABSORB_MAC(short[] SX, byte[] src, int len, short[] E, short[] C)
345413
{
346414
int rem_bytes = len;
@@ -349,14 +417,14 @@ protected void ABSORB_MAC(short[] SX, byte[] src, int len, short[] E, short[] C)
349417
{
350418
if (rem_bytes > ISAP_rH_SZ)
351419
{
352-
byteToShortXor(src, SX, ISAP_rH_SZ >> 1);
420+
byteToShortXor(src, idx, SX, ISAP_rH_SZ >> 1);
353421
idx += ISAP_rH_SZ;
354422
rem_bytes -= ISAP_rH_SZ;
355423
PermuteRoundsHX(SX, E, C);
356424
}
357425
else if (rem_bytes == ISAP_rH_SZ)
358426
{
359-
byteToShortXor(src, SX, ISAP_rH_SZ >> 1);
427+
byteToShortXor(src, idx, SX, ISAP_rH_SZ >> 1);
360428
PermuteRoundsHX(SX, E, C);
361429
SX[0] ^= 0x80;
362430
PermuteRoundsHX(SX, E, C);
@@ -397,11 +465,6 @@ public void isap_rk(short[] iv16, byte[] y, int ylen, short[] out16, int outlen,
397465

398466
public void isap_mac(byte[] ad, int adlen, byte[] c, int clen, byte[] tag)
399467
{
400-
SX = new short[25];
401-
// Init state
402-
System.arraycopy(iv16, 0, SX, 0, 8);
403-
System.arraycopy(ISAP_IV1_16, 0, SX, 8, 4);
404-
PermuteRoundsHX(SX, E, C);
405468
// Absorb AD
406469
ABSORB_MAC(SX, ad, adlen, E, C);
407470
// Domain seperation
@@ -443,11 +506,11 @@ public void isap_enc(byte[] m, int mOff, int mlen, byte[] c, int cOff, int clen)
443506
}
444507
}
445508

446-
private void byteToShortXor(byte[] input, short[] output, int outLen)
509+
private void byteToShortXor(byte[] input, int inOff, short[] output, int outLen)
447510
{
448511
for (int i = 0; i < outLen; ++i)
449512
{
450-
output[i] ^= Pack.littleEndianToShort(input, (i << 1));
513+
output[i] ^= Pack.littleEndianToShort(input, inOff + (i << 1));
451514
}
452515
}
453516

@@ -790,7 +853,12 @@ public void init(boolean forEncryption, CipherParameters params)
790853
@Override
791854
public void processAADByte(byte in)
792855
{
793-
aadData.write(in);
856+
if (aadOff >= aadData.length)
857+
{
858+
aadOff = 0;
859+
ISAPAEAD.absorbMacBlock(aadData, 0);
860+
}
861+
aadData[aadOff++] = in;
794862
}
795863

796864
@Override
@@ -800,8 +868,24 @@ public void processAADBytes(byte[] in, int inOff, int len)
800868
{
801869
throw new DataLengthException("input buffer too short" + (forEncryption ? "encryption" : "decryption"));
802870
}
803-
804-
aadData.write(in, inOff, len);
871+
int tmp;
872+
if (aadOff + len >= ISAP_rH_SZ)
873+
{
874+
tmp = ISAP_rH_SZ - aadOff;
875+
System.arraycopy(in, inOff, aadData, aadOff, tmp);
876+
ISAPAEAD.absorbMacBlock(aadData, 0);
877+
inOff += tmp;
878+
len -= tmp;
879+
aadOff = 0;
880+
}
881+
while (len > ISAP_rH_SZ)
882+
{
883+
ISAPAEAD.absorbMacBlock(in, inOff);
884+
inOff += ISAP_rH_SZ;
885+
len -= ISAP_rH_SZ;
886+
}
887+
System.arraycopy(in, inOff, aadData, aadOff, len);
888+
aadOff += len;
805889
}
806890

807891
@Override
@@ -816,6 +900,11 @@ public int processBytes(byte[] input, int inOff, int len, byte[] output, int out
816900
{
817901
throw new DataLengthException("input buffer too short");
818902
}
903+
if(!aadFinished)
904+
{
905+
ISAPAEAD.swapInternalState();
906+
aadFinished = true;
907+
}
819908
message.write(input, inOff, len);
820909
if (forEncryption)
821910
{
@@ -847,7 +936,7 @@ public int doFinal(byte[] output, int outOff)
847936
}
848937
int len;
849938
byte[] c;
850-
byte[] ad = aadData.toByteArray();
939+
851940
if (forEncryption)
852941
{
853942
byte[] enc_input = message.toByteArray();
@@ -857,11 +946,13 @@ public int doFinal(byte[] output, int outOff)
857946
throw new OutputLengthException("output buffer is too short");
858947
}
859948
ISAPAEAD.isap_enc(enc_input, 0, len, output, outOff, output.length);
949+
860950
outputStream.write(output, outOff, len);
861951
outOff += len;
862952
c = outputStream.toByteArray();
863953
mac = new byte[MAC_SIZE];
864-
ISAPAEAD.isap_mac(ad, ad.length, c, c.length, mac);
954+
ISAPAEAD.swapInternalState();
955+
ISAPAEAD.isap_mac(aadData, aadOff, c, c.length, mac);
865956
System.arraycopy(mac, 0, output, outOff, 16);
866957
len += 16;
867958
}
@@ -874,7 +965,8 @@ public int doFinal(byte[] output, int outOff)
874965
{
875966
throw new OutputLengthException("output buffer is too short");
876967
}
877-
ISAPAEAD.isap_mac(ad, ad.length, c, len, mac);
968+
ISAPAEAD.swapInternalState();
969+
ISAPAEAD.isap_mac(aadData, aadOff, c, len, mac);
878970
ISAPAEAD.reset();
879971
for (int i = 0; i < 16; ++i)
880972
{
@@ -883,6 +975,7 @@ public int doFinal(byte[] output, int outOff)
883975
throw new IllegalArgumentException("Mac does not match");
884976
}
885977
}
978+
ISAPAEAD.swapInternalState();
886979
ISAPAEAD.isap_enc(c, 0, len, output, outOff, output.length);
887980
}
888981
return len;
@@ -907,11 +1000,14 @@ protected void reset(boolean clearMac)
9071000
{
9081001
throw new IllegalArgumentException("Need call init function before encryption/decryption");
9091002
}
910-
aadData.reset();
1003+
Arrays.fill(aadData, (byte)0);
9111004
ISAPAEAD.reset();
9121005
message.reset();
9131006
outputStream.reset();
1007+
aadOff = 0;
1008+
aadFinished = false;
9141009
super.reset(clearMac);
1010+
9151011
}
9161012

9171013
public int getBlockSize()

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ public String getName()
3232
public void performTest()
3333
throws Exception
3434
{
35+
testVectors("isapa128av20", IsapType.ISAP_A_128A);
36+
testVectors("isapa128v20", IsapType.ISAP_A_128);
37+
testVectors("isapk128av20", IsapType.ISAP_K_128A);
38+
testVectors("isapk128v20", IsapType.ISAP_K_128);
3539
ISAPEngine ISAP = new ISAPEngine(IsapType.ISAP_K_128A);
3640
testExceptions(ISAP, ISAP.getKeyBytesSize(), ISAP.getIVBytesSize(), ISAP.getBlockSize());
3741
testParameters(ISAP, 16, 16, 16);
@@ -45,10 +49,7 @@ public void performTest()
4549
testExceptions(ISAP, ISAP.getKeyBytesSize(), ISAP.getIVBytesSize(), ISAP.getBlockSize());
4650
testParameters(ISAP, 16, 16, 16);
4751
testExceptions(new ISAPDigest(), 32);
48-
testVectors("isapa128av20", IsapType.ISAP_A_128A);
49-
testVectors("isapa128v20", IsapType.ISAP_A_128);
50-
testVectors("isapk128av20", IsapType.ISAP_K_128A);
51-
testVectors("isapk128v20", IsapType.ISAP_K_128);
52+
5253
testVectors();
5354
CipherTest.checkCipher(32, 16, 100, 128, new CipherTest.Instance()
5455
{
@@ -107,7 +108,7 @@ private void testVectors(String filename, IsapType isapType)
107108
int a = line.indexOf('=');
108109
if (a < 0)
109110
{
110-
// if (!map.get("Count").equals("265"))
111+
// if (!map.get("Count").equals("19"))
111112
// {
112113
// continue;
113114
// }
@@ -143,6 +144,7 @@ private void testVectors(String filename, IsapType isapType)
143144
{
144145
mismatch("Reccover Keystream " + map.get("Count"), (String)map.get("PT"), pt_recovered);
145146
}
147+
//System.out.println("Keystream " + map.get("Count") + " pass");
146148
isap.reset();
147149
map.clear();
148150

0 commit comments

Comments
 (0)