Skip to content

Commit 806a465

Browse files
author
gefeili
committed
Set aad from ByteArrayOutputStream into byte[Rkin] for XoodyakEngine. Add tests for processAADBytes
1 parent d21634c commit 806a465

File tree

2 files changed

+48
-19
lines changed

2 files changed

+48
-19
lines changed

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

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package org.bouncycastle.crypto.engines;
22

3-
import java.io.ByteArrayOutputStream;
4-
53
import org.bouncycastle.crypto.CipherParameters;
64
import org.bouncycastle.crypto.DataLengthException;
75
import org.bouncycastle.crypto.InvalidCipherTextException;
@@ -11,9 +9,9 @@
119
import org.bouncycastle.util.Pack;
1210

1311
/**
14-
* Xoodyak v1, https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/xoodyak-spec-final.pdf
12+
* Xoodyak v1, <a href="https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/xoodyak-spec-final.pdf"></a>
1513
* <p>
16-
* Xoodyak with reference to C Reference Impl from: https://github.com/XKCP/XKCP
14+
* Xoodyak with reference to C Reference Impl from: <a href="https://github.com/XKCP/XKCP"></a>
1715
* </p>
1816
*/
1917

@@ -34,9 +32,11 @@ public class XoodyakEngine
3432
private boolean aadFinished;
3533
private boolean encrypted;
3634
private boolean initialised = false;
37-
private final ByteArrayOutputStream aadData = new ByteArrayOutputStream();
35+
private final byte[] aadData = new byte[Rkin];
3836
private byte[] message;
3937
private int messageOff;
38+
private int aadOff;
39+
private byte aadcd;
4040

4141
enum MODE
4242
{
@@ -75,7 +75,13 @@ public void processAADByte(byte input)
7575
throw new IllegalArgumentException("AAD cannot be added after reading a full block(" + Rkout +
7676
" bytes) of input for " + (forEncryption ? "encryption" : "decryption"));
7777
}
78-
aadData.write(input);
78+
if (aadOff >= aadData.length)
79+
{
80+
AbsorbAny(aadData, 0, aadData.length, aadcd);
81+
aadcd = 0;
82+
aadOff = 0;
83+
}
84+
aadData[aadOff++] = input;
7985
}
8086

8187
@Override
@@ -90,15 +96,33 @@ public void processAADBytes(byte[] input, int inOff, int len)
9096
{
9197
throw new DataLengthException("input buffer too short");
9298
}
93-
aadData.write(input, inOff, len);
99+
if (aadOff + len >= Rkin)
100+
{
101+
System.arraycopy(input, inOff, aadData, aadOff, Rkin - aadOff);
102+
AbsorbAny(aadData, 0, aadData.length, aadcd);
103+
aadcd = 0;
104+
aadOff = Rkin - aadOff;
105+
inOff += aadOff;
106+
len -= aadOff;
107+
aadOff = 0;
108+
}
109+
int tmp = len / Rkin;
110+
if (tmp > 0)
111+
{
112+
tmp *= Rkin;
113+
AbsorbAny(input, inOff, tmp, aadcd);
114+
inOff += tmp;
115+
len -= tmp;
116+
}
117+
System.arraycopy(input, inOff, aadData, aadOff, len);
118+
aadOff += len;
94119
}
95120

96121
private void processAAD()
97122
{
98123
if (!aadFinished)
99124
{
100-
byte[] ad = aadData.toByteArray();
101-
AbsorbAny(ad, ad.length, Rkin, 0x03);
125+
AbsorbAny(aadData, 0, aadOff, aadcd);
102126
aadFinished = true;
103127
}
104128
}
@@ -268,7 +292,9 @@ protected void reset(boolean clearMac)
268292
phase = PhaseUp;
269293
Arrays.fill(message, (byte)0);
270294
messageOff = 0;
271-
aadData.reset();
295+
Arrays.fill(aadData, (byte)0);
296+
aadOff = 0;
297+
aadcd = (byte)0x03;
272298
//Absorb key
273299
int KLen = K.length;
274300
int IDLen = iv.length;
@@ -277,21 +303,20 @@ protected void reset(boolean clearMac)
277303
System.arraycopy(K, 0, KID, 0, KLen);
278304
System.arraycopy(iv, 0, KID, KLen, IDLen);
279305
KID[KLen + IDLen] = (byte)IDLen;
280-
AbsorbAny(KID, KLen + IDLen + 1, Rkin, 0x02);
306+
AbsorbAny(KID, 0, KLen + IDLen + 1, 0x02);
281307
super.reset(clearMac);
282308
}
283309

284-
private void AbsorbAny(byte[] X, int XLen, int r, int Cd)
310+
private void AbsorbAny(byte[] X, int Xoff, int XLen, int Cd)
285311
{
286-
int Xoff = 0;
287312
int splitLen;
288313
do
289314
{
290315
if (phase != PhaseUp)
291316
{
292317
Up(null, 0, 0);
293318
}
294-
splitLen = Math.min(XLen, r);
319+
splitLen = Math.min(XLen, Rkin);
295320
Down(X, Xoff, splitLen, Cd);
296321
Cd = 0;
297322
Xoff += splitLen;
@@ -320,8 +345,7 @@ private void Up(byte[] Yi, int YiLen, int Cu)
320345
int a10 = Pack.littleEndianToInt(state, 40);
321346
int a11 = Pack.littleEndianToInt(state, 44);
322347

323-
int MAXROUNDS = 12;
324-
for (int i = 0; i < MAXROUNDS; ++i)
348+
for (int i = 0; i < 12; ++i)
325349
{
326350
/* Theta: Column Parity Mixer */
327351
int p0 = a0 ^ a4 ^ a8;

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,13 +266,18 @@ static void checkAEADParemeter(SimpleTest test, int keySize, int ivSize, final i
266266
random.nextBytes(key);
267267
random.nextBytes(iv);
268268
random.nextBytes(plaintext);
269-
//random.nextBytes(aad);
269+
random.nextBytes(aad);
270270
cipher.init(true, new ParametersWithIV(new KeyParameter(key), iv));
271271
byte[] ciphertext1 = new byte[cipher.getOutputSize(plaintext.length)];
272-
cipher.processAADBytes(aad, 0, aad.length);
272+
for (int i = 0; i < aad.length; ++i)
273+
{
274+
cipher.processAADByte(aad[i]);
275+
}
273276
int len = cipher.processBytes(plaintext, 0, plaintext.length, ciphertext1, 0);
274277
len += cipher.doFinal(ciphertext1, len);
275-
cipher.init(true, new AEADParameters(new KeyParameter(key), macSize * 8, iv, aad));
278+
int aadSplit = random.nextInt(99);
279+
cipher.init(true, new AEADParameters(new KeyParameter(key), macSize * 8, iv, Arrays.copyOf(aad, aadSplit)));
280+
cipher.processAADBytes(aad, aadSplit, aad.length - aadSplit);
276281
byte[] ciphertext2 = new byte[cipher.getOutputSize(plaintext.length)];
277282
len = cipher.processBytes(plaintext, 0, plaintext.length, ciphertext2, 0);
278283
len += cipher.doFinal(ciphertext2, len);

0 commit comments

Comments
 (0)