Skip to content

Commit 494e40b

Browse files
author
gefeili
committed
Merge branch 'main' into pqc-snova
2 parents ff08d4a + 1e78389 commit 494e40b

25 files changed

+642
-192
lines changed

core/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java

Lines changed: 64 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@
1111
*/
1212
public class BufferedBlockCipher
1313
{
14-
protected byte[] buf;
15-
protected int bufOff;
14+
protected byte[] buf;
15+
protected int bufOff;
1616

17-
protected boolean forEncryption;
18-
protected BlockCipher cipher;
17+
protected boolean forEncryption;
18+
protected BlockCipher cipher;
1919
protected MultiBlockCipher mbCipher;
2020

21-
protected boolean partialBlockOkay;
22-
protected boolean pgpCFB;
21+
protected boolean partialBlockOkay;
22+
protected boolean pgpCFB;
2323

2424
/**
2525
* constructor for subclasses
@@ -35,7 +35,7 @@ public class BufferedBlockCipher
3535
* @deprecated use the constructor on DefaultBufferedBlockCipher.
3636
*/
3737
public BufferedBlockCipher(
38-
BlockCipher cipher)
38+
BlockCipher cipher)
3939
{
4040
this.cipher = cipher;
4141

@@ -55,8 +55,8 @@ public BufferedBlockCipher(
5555
//
5656
// check if we can handle partial blocks on doFinal.
5757
//
58-
String name = cipher.getAlgorithmName();
59-
int idx = name.indexOf('/') + 1;
58+
String name = cipher.getAlgorithmName();
59+
int idx = name.indexOf('/') + 1;
6060

6161
pgpCFB = (idx > 0 && name.startsWith("PGP", idx));
6262

@@ -84,14 +84,14 @@ public BlockCipher getUnderlyingCipher()
8484
* initialise the cipher.
8585
*
8686
* @param forEncryption if true the cipher is initialised for
87-
* encryption, if false for decryption.
88-
* @param params the key and other data required by the cipher.
89-
* @exception IllegalArgumentException if the params argument is
90-
* inappropriate.
87+
* encryption, if false for decryption.
88+
* @param params the key and other data required by the cipher.
89+
* @throws IllegalArgumentException if the params argument is
90+
* inappropriate.
9191
*/
9292
public void init(
93-
boolean forEncryption,
94-
CipherParameters params)
93+
boolean forEncryption,
94+
CipherParameters params)
9595
throws IllegalArgumentException
9696
{
9797
this.forEncryption = forEncryption;
@@ -112,7 +112,7 @@ public int getBlockSize()
112112
}
113113

114114
/**
115-
* return the size of the output buffer required for an update
115+
* return the size of the output buffer required for an update
116116
* an input of len bytes.
117117
*
118118
* @param len the length of the input.
@@ -122,7 +122,7 @@ public int getBlockSize()
122122
public int getUpdateOutputSize(
123123
int len)
124124
{
125-
int total = len + bufOff;
125+
int total = len + bufOff;
126126
int leftOver;
127127

128128
if (pgpCFB)
@@ -138,7 +138,7 @@ public int getUpdateOutputSize(
138138
}
139139
else
140140
{
141-
leftOver = total % buf.length;
141+
leftOver = total % buf.length;
142142
}
143143

144144
return total - leftOver;
@@ -167,20 +167,20 @@ public int getOutputSize(
167167
/**
168168
* process a single byte, producing an output block if necessary.
169169
*
170-
* @param in the input byte.
171-
* @param out the space for any output that might be produced.
170+
* @param in the input byte.
171+
* @param out the space for any output that might be produced.
172172
* @param outOff the offset from which the output will be copied.
173173
* @return the number of output bytes copied to out.
174-
* @exception DataLengthException if there isn't enough space in out.
175-
* @exception IllegalStateException if the cipher isn't initialised.
174+
* @throws DataLengthException if there isn't enough space in out.
175+
* @throws IllegalStateException if the cipher isn't initialised.
176176
*/
177177
public int processByte(
178-
byte in,
179-
byte[] out,
180-
int outOff)
178+
byte in,
179+
byte[] out,
180+
int outOff)
181181
throws DataLengthException, IllegalStateException
182182
{
183-
int resultLen = 0;
183+
int resultLen = 0;
184184

185185
buf[bufOff++] = in;
186186

@@ -196,31 +196,31 @@ public int processByte(
196196
/**
197197
* process an array of bytes, producing output if necessary.
198198
*
199-
* @param in the input byte array.
200-
* @param inOff the offset at which the input data starts.
201-
* @param len the number of bytes to be copied out of the input array.
202-
* @param out the space for any output that might be produced.
199+
* @param in the input byte array.
200+
* @param inOff the offset at which the input data starts.
201+
* @param len the number of bytes to be copied out of the input array.
202+
* @param out the space for any output that might be produced.
203203
* @param outOff the offset from which the output will be copied.
204204
* @return the number of output bytes copied to out.
205-
* @exception DataLengthException if there isn't enough space in out.
206-
* @exception IllegalStateException if the cipher isn't initialised.
205+
* @throws DataLengthException if there isn't enough space in out.
206+
* @throws IllegalStateException if the cipher isn't initialised.
207207
*/
208208
public int processBytes(
209-
byte[] in,
210-
int inOff,
211-
int len,
212-
byte[] out,
213-
int outOff)
209+
byte[] in,
210+
int inOff,
211+
int len,
212+
byte[] out,
213+
int outOff)
214214
throws DataLengthException, IllegalStateException
215215
{
216216
if (len < 0)
217217
{
218218
throw new IllegalArgumentException("Can't have a negative input length!");
219219
}
220220

221-
int blockSize = getBlockSize();
222-
int length = getUpdateOutputSize(len);
223-
221+
int blockSize = getBlockSize();
222+
int length = getUpdateOutputSize(len);
223+
224224
if (length > 0)
225225
{
226226
if ((outOff + length) > out.length)
@@ -235,12 +235,18 @@ public int processBytes(
235235
if (len > gapLen)
236236
{
237237
System.arraycopy(in, inOff, buf, bufOff, gapLen);
238+
inOff += gapLen;
239+
len -= gapLen;
240+
if (in == out && segmentsOverlap(inOff, len, outOff, length))
241+
{
242+
in = new byte[len];
243+
System.arraycopy(out, inOff, in, 0, len);
244+
inOff = 0;
245+
}
238246

239247
resultLen += cipher.processBlock(buf, 0, out, outOff);
240248

241249
bufOff = 0;
242-
len -= gapLen;
243-
inOff += gapLen;
244250

245251
if (mbCipher != null)
246252
{
@@ -284,20 +290,20 @@ public int processBytes(
284290
/**
285291
* Process the last block in the buffer.
286292
*
287-
* @param out the array the block currently being held is copied into.
293+
* @param out the array the block currently being held is copied into.
288294
* @param outOff the offset at which the copying starts.
289295
* @return the number of output bytes copied to out.
290-
* @exception DataLengthException if there is insufficient space in out for
291-
* the output, or the input is not block size aligned and should be.
292-
* @exception IllegalStateException if the underlying cipher is not
293-
* initialised.
294-
* @exception InvalidCipherTextException if padding is expected and not found.
295-
* @exception DataLengthException if the input is not block size
296-
* aligned.
296+
* @throws DataLengthException if there is insufficient space in out for
297+
* the output, or the input is not block size aligned and should be.
298+
* @throws IllegalStateException if the underlying cipher is not
299+
* initialised.
300+
* @throws InvalidCipherTextException if padding is expected and not found.
301+
* @throws DataLengthException if the input is not block size
302+
* aligned.
297303
*/
298304
public int doFinal(
299-
byte[] out,
300-
int outOff)
305+
byte[] out,
306+
int outOff)
301307
throws DataLengthException, IllegalStateException, InvalidCipherTextException
302308
{
303309
try
@@ -351,4 +357,10 @@ public void reset()
351357
//
352358
cipher.reset();
353359
}
360+
361+
protected boolean segmentsOverlap(int inOff, int inLen, int outOff, int outLen)
362+
{
363+
// please ensure a valid check for inLen > 0 and outLen > 0 outside this function
364+
return inOff <= outOff + outLen && outOff <= inOff + inLen;
365+
}
354366
}

core/src/main/java/org/bouncycastle/crypto/DefaultBufferedBlockCipher.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,12 +237,19 @@ public int processBytes(
237237
if (len > gapLen)
238238
{
239239
System.arraycopy(in, inOff, buf, bufOff, gapLen);
240+
inOff += gapLen;
241+
len -= gapLen;
242+
if (in == out && segmentsOverlap(inOff, len, outOff, length))
243+
{
244+
in = new byte[len];
245+
System.arraycopy(out, inOff, in, 0, len);
246+
inOff = 0;
247+
}
240248

241249
resultLen += cipher.processBlock(buf, 0, out, outOff);
242250

243251
bufOff = 0;
244-
len -= gapLen;
245-
inOff += gapLen;
252+
246253

247254
if (mbCipher != null)
248255
{

core/src/main/java/org/bouncycastle/crypto/DefaultMultiBlockCipher.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@ public int processBlocks(byte[] in, int inOff, int blockCount, byte[] out, int o
2020

2121
int resultLen = 0;
2222
int blockSize = this.getMultiBlockSize();
23-
23+
int len = blockCount * blockSize;
24+
if (in == out && segmentsOverlap(inOff, len, outOff, len))
25+
{
26+
in = new byte[len];
27+
System.arraycopy(out, inOff, in, 0, len);
28+
inOff = 0;
29+
}
2430
for (int i = 0; i != blockCount; i++)
2531
{
2632
resultLen += this.processBlock(in, inOff, out, outOff + resultLen);
@@ -30,4 +36,10 @@ public int processBlocks(byte[] in, int inOff, int blockCount, byte[] out, int o
3036

3137
return resultLen;
3238
}
39+
40+
protected boolean segmentsOverlap(int inOff, int inLen, int outOff, int outLen)
41+
{
42+
// please ensure a valid check for inLen > 0 and outLen > 0 outside this function
43+
return inOff <= outOff + outLen && outOff <= inOff + inLen;
44+
}
3345
}

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,12 @@ public int processByte(byte input, byte[] output, int outOff)
587587
@Override
588588
public int processBytes(byte[] input, int inOff, int len, byte[] output, int outOff)
589589
{
590+
if (input == output && segmentsOverlap(inOff, len, outOff, processor.getUpdateOutputSize(len)))
591+
{
592+
input = new byte[len];
593+
System.arraycopy(output, inOff, input, 0, len);
594+
inOff = 0;
595+
}
590596
boolean forEncryption = checkData(false);
591597
if (forEncryption)
592598
{
@@ -733,9 +739,16 @@ protected int processEncDecBytes(byte[] input, int inOff, int len, byte[] output
733739
m_bufPos += len;
734740
return 0;
735741
}
736-
resultLength = processor.getUpdateOutputSize(len) + m_bufPos - (forEncryption ? 0 : MAC_SIZE);
742+
int length = processor.getUpdateOutputSize(len);
743+
resultLength = length + m_bufPos - (forEncryption ? 0 : MAC_SIZE);
737744
ensureSufficientOutputBuffer(output, outOff, resultLength - resultLength % BlockSize);
738745
resultLength = 0;
746+
if (input == output && segmentsOverlap(inOff, len, outOff, length))
747+
{
748+
input = new byte[len];
749+
System.arraycopy(output, inOff, input, 0, len);
750+
inOff = 0;
751+
}
739752
if (forEncryption)
740753
{
741754
if (m_bufPos > 0)
@@ -746,6 +759,7 @@ protected int processEncDecBytes(byte[] input, int inOff, int len, byte[] output
746759
processBufferEncrypt(m_buf, 0, output, outOff);
747760
resultLength = BlockSize;
748761
}
762+
749763
// The function is just an operator >= or >
750764
while (processor.isLengthExceedingBlockSize(len, BlockSize))
751765
{
@@ -1013,6 +1027,12 @@ protected void finishAAD3(State nextState, boolean isDoFinal)
10131027
m_state = nextState;
10141028
}
10151029

1030+
private boolean segmentsOverlap(int inOff, int inLen, int outOff, int outLen)
1031+
{
1032+
// please ensure a valid check for inLen > 0 and outLen > 0 outside this function
1033+
return inOff <= outOff + outLen && outOff <= inOff + inLen;
1034+
}
1035+
10161036
protected abstract void finishAAD(State nextState, boolean isDoFinal);
10171037

10181038
protected abstract void init(byte[] key, byte[] iv);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public void processFinalBlock(byte[] output, int outOff)
137137
int adlen = aadOperator.getLen();
138138
int mlen = dataOperator.getLen() - (forEncryption ? 0 : MAC_SIZE);
139139
byte[] m = ((StreamDataOperator)dataOperator).getBytes();
140-
int xlen, mOff = 0, mauth = 0;
140+
int xlen, mOff = 0, mauth = outOff;
141141
xlen = mlen;
142142
if ((adlen & 31) == 0 && adlen != 0)
143143
{

core/src/main/java/org/bouncycastle/crypto/modes/CTSBlockCipher.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,15 +146,19 @@ public int processBytes(
146146
if (len > gapLen)
147147
{
148148
System.arraycopy(in, inOff, buf, bufOff, gapLen);
149-
149+
inOff += gapLen;
150+
len -= gapLen;
151+
if (in == out && segmentsOverlap(inOff, len, outOff, length))
152+
{
153+
in = new byte[len];
154+
System.arraycopy(out, inOff, in, 0, len);
155+
inOff = 0;
156+
}
150157
resultLen += cipher.processBlock(buf, 0, out, outOff);
151158
System.arraycopy(buf, blockSize, buf, 0, blockSize);
152159

153160
bufOff = blockSize;
154161

155-
len -= gapLen;
156-
inOff += gapLen;
157-
158162
while (len > blockSize)
159163
{
160164
System.arraycopy(in, inOff, buf, bufOff, blockSize);

core/src/main/java/org/bouncycastle/crypto/modes/KXTSBlockCipher.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,12 @@ public int processBytes(byte[] input, int inOff, int len, byte[] output, int out
123123
{
124124
throw new IllegalArgumentException("Partial blocks not supported");
125125
}
126-
126+
if (input == output && segmentsOverlap(inOff, len, outOff, len))
127+
{
128+
input = new byte[len];
129+
System.arraycopy(output, inOff, input, 0, len);
130+
inOff = 0;
131+
}
127132
for (int pos = 0; pos < len; pos += blockSize)
128133
{
129134
processBlocks(input, inOff + pos, output, outOff + pos);

core/src/main/java/org/bouncycastle/crypto/modes/NISTCTSBlockCipher.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,15 +155,19 @@ public int processBytes(
155155
if (len > gapLen)
156156
{
157157
System.arraycopy(in, inOff, buf, bufOff, gapLen);
158-
158+
inOff += gapLen;
159+
len -= gapLen;
160+
if (in == out && segmentsOverlap(inOff, len, outOff, length))
161+
{
162+
in = new byte[len];
163+
System.arraycopy(out, inOff, in, 0, len);
164+
inOff = 0;
165+
}
159166
resultLen += cipher.processBlock(buf, 0, out, outOff);
160167
System.arraycopy(buf, blockSize, buf, 0, blockSize);
161168

162169
bufOff = blockSize;
163170

164-
len -= gapLen;
165-
inOff += gapLen;
166-
167171
while (len > blockSize)
168172
{
169173
System.arraycopy(in, inOff, buf, bufOff, blockSize);

0 commit comments

Comments
 (0)