Skip to content

Commit 4ec69f2

Browse files
ligefeiBouncycastledghgit
authored andcommitted
input/output overlap for DefaultBufferedBlockCipher and PaddedBufferedBlockCipher
1 parent 8954c62 commit 4ec69f2

File tree

3 files changed

+167
-105
lines changed

3 files changed

+167
-105
lines changed

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

Lines changed: 65 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@
1414
public class DefaultBufferedBlockCipher
1515
extends BufferedBlockCipher
1616
{
17-
protected byte[] buf;
18-
protected int bufOff;
17+
protected byte[] buf;
18+
protected int bufOff;
1919

20-
protected boolean forEncryption;
21-
protected BlockCipher cipher;
20+
protected boolean forEncryption;
21+
protected BlockCipher cipher;
2222
protected MultiBlockCipher mbCipher;
2323

24-
protected boolean partialBlockOkay;
25-
protected boolean pgpCFB;
24+
protected boolean partialBlockOkay;
25+
protected boolean pgpCFB;
2626

2727
/**
2828
* constructor for subclasses
@@ -37,7 +37,7 @@ protected DefaultBufferedBlockCipher()
3737
* @param cipher the underlying block cipher this buffering object wraps.
3838
*/
3939
public DefaultBufferedBlockCipher(
40-
BlockCipher cipher)
40+
BlockCipher cipher)
4141
{
4242
this.cipher = cipher;
4343

@@ -57,8 +57,8 @@ public DefaultBufferedBlockCipher(
5757
//
5858
// check if we can handle partial blocks on doFinal.
5959
//
60-
String name = cipher.getAlgorithmName();
61-
int idx = name.indexOf('/') + 1;
60+
String name = cipher.getAlgorithmName();
61+
int idx = name.indexOf('/') + 1;
6262

6363
pgpCFB = (idx > 0 && name.startsWith("PGP", idx));
6464

@@ -86,14 +86,14 @@ public BlockCipher getUnderlyingCipher()
8686
* initialise the cipher.
8787
*
8888
* @param forEncryption if true the cipher is initialised for
89-
* encryption, if false for decryption.
90-
* @param params the key and other data required by the cipher.
91-
* @exception IllegalArgumentException if the params argument is
92-
* inappropriate.
89+
* encryption, if false for decryption.
90+
* @param params the key and other data required by the cipher.
91+
* @throws IllegalArgumentException if the params argument is
92+
* inappropriate.
9393
*/
9494
public void init(
95-
boolean forEncryption,
96-
CipherParameters params)
95+
boolean forEncryption,
96+
CipherParameters params)
9797
throws IllegalArgumentException
9898
{
9999
this.forEncryption = forEncryption;
@@ -114,7 +114,7 @@ public int getBlockSize()
114114
}
115115

116116
/**
117-
* return the size of the output buffer required for an update
117+
* return the size of the output buffer required for an update
118118
* an input of len bytes.
119119
*
120120
* @param len the length of the input.
@@ -124,7 +124,7 @@ public int getBlockSize()
124124
public int getUpdateOutputSize(
125125
int len)
126126
{
127-
int total = len + bufOff;
127+
int total = len + bufOff;
128128
int leftOver;
129129

130130
if (pgpCFB)
@@ -140,7 +140,7 @@ public int getUpdateOutputSize(
140140
}
141141
else
142142
{
143-
leftOver = total % buf.length;
143+
leftOver = total % buf.length;
144144
}
145145

146146
return total - leftOver;
@@ -169,20 +169,20 @@ public int getOutputSize(
169169
/**
170170
* process a single byte, producing an output block if necessary.
171171
*
172-
* @param in the input byte.
173-
* @param out the space for any output that might be produced.
172+
* @param in the input byte.
173+
* @param out the space for any output that might be produced.
174174
* @param outOff the offset from which the output will be copied.
175175
* @return the number of output bytes copied to out.
176-
* @exception DataLengthException if there isn't enough space in out.
177-
* @exception IllegalStateException if the cipher isn't initialised.
176+
* @throws DataLengthException if there isn't enough space in out.
177+
* @throws IllegalStateException if the cipher isn't initialised.
178178
*/
179179
public int processByte(
180-
byte in,
181-
byte[] out,
182-
int outOff)
180+
byte in,
181+
byte[] out,
182+
int outOff)
183183
throws DataLengthException, IllegalStateException
184184
{
185-
int resultLen = 0;
185+
int resultLen = 0;
186186

187187
buf[bufOff++] = in;
188188

@@ -198,31 +198,31 @@ public int processByte(
198198
/**
199199
* process an array of bytes, producing output if necessary.
200200
*
201-
* @param in the input byte array.
202-
* @param inOff the offset at which the input data starts.
203-
* @param len the number of bytes to be copied out of the input array.
204-
* @param out the space for any output that might be produced.
201+
* @param in the input byte array.
202+
* @param inOff the offset at which the input data starts.
203+
* @param len the number of bytes to be copied out of the input array.
204+
* @param out the space for any output that might be produced.
205205
* @param outOff the offset from which the output will be copied.
206206
* @return the number of output bytes copied to out.
207-
* @exception DataLengthException if there isn't enough space in out.
208-
* @exception IllegalStateException if the cipher isn't initialised.
207+
* @throws DataLengthException if there isn't enough space in out.
208+
* @throws IllegalStateException if the cipher isn't initialised.
209209
*/
210210
public int processBytes(
211-
byte[] in,
212-
int inOff,
213-
int len,
214-
byte[] out,
215-
int outOff)
211+
byte[] in,
212+
int inOff,
213+
int len,
214+
byte[] out,
215+
int outOff)
216216
throws DataLengthException, IllegalStateException
217217
{
218218
if (len < 0)
219219
{
220220
throw new IllegalArgumentException("Can't have a negative input length!");
221221
}
222222

223-
int blockSize = getBlockSize();
224-
int length = getUpdateOutputSize(len);
225-
223+
int blockSize = getBlockSize();
224+
int length = getUpdateOutputSize(len);
225+
226226
if (length > 0)
227227
{
228228
if ((outOff + length) > out.length)
@@ -237,12 +237,25 @@ 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)
243+
{
244+
int inEnd = inOff + len;
245+
int outEnd = outOff + length;
246+
if ((inOff <= outOff && outOff <= inEnd) ||
247+
(outOff <= inOff && inOff <= outEnd))
248+
{
249+
in = new byte[len];
250+
System.arraycopy(out, inOff, in, 0, len);
251+
inOff = 0;
252+
}
253+
}
240254

241255
resultLen += cipher.processBlock(buf, 0, out, outOff);
242256

243257
bufOff = 0;
244-
len -= gapLen;
245-
inOff += gapLen;
258+
246259

247260
if (mbCipher != null)
248261
{
@@ -286,20 +299,20 @@ public int processBytes(
286299
/**
287300
* Process the last block in the buffer.
288301
*
289-
* @param out the array the block currently being held is copied into.
302+
* @param out the array the block currently being held is copied into.
290303
* @param outOff the offset at which the copying starts.
291304
* @return the number of output bytes copied to out.
292-
* @exception DataLengthException if there is insufficient space in out for
293-
* the output, or the input is not block size aligned and should be.
294-
* @exception IllegalStateException if the underlying cipher is not
295-
* initialised.
296-
* @exception InvalidCipherTextException if padding is expected and not found.
297-
* @exception DataLengthException if the input is not block size
298-
* aligned.
305+
* @throws DataLengthException if there is insufficient space in out for
306+
* the output, or the input is not block size aligned and should be.
307+
* @throws IllegalStateException if the underlying cipher is not
308+
* initialised.
309+
* @throws InvalidCipherTextException if padding is expected and not found.
310+
* @throws DataLengthException if the input is not block size
311+
* aligned.
299312
*/
300313
public int doFinal(
301-
byte[] out,
302-
int outOff)
314+
byte[] out,
315+
int outOff)
303316
throws DataLengthException, IllegalStateException, InvalidCipherTextException
304317
{
305318
try

core/src/main/java/org/bouncycastle/crypto/paddings/PaddedBufferedBlockCipher.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,24 @@ public int processBytes(
202202
if (len > gapLen)
203203
{
204204
System.arraycopy(in, inOff, buf, bufOff, gapLen);
205+
inOff += gapLen;
206+
len -= gapLen;
207+
if (in == out)
208+
{
209+
int inEnd = inOff + len;
210+
int outEnd = outOff + length;
211+
if ((inOff <= outOff && outOff <= inEnd) ||
212+
(outOff <= inOff && inOff <= outEnd))
213+
{
214+
in = new byte[len];
215+
System.arraycopy(out, inOff, in, 0, len);
216+
inOff = 0;
217+
}
218+
}
205219

206220
resultLen += cipher.processBlock(buf, 0, out, outOff);
207221

208222
bufOff = 0;
209-
len -= gapLen;
210-
inOff += gapLen;
211223

212224
while (len > buf.length)
213225
{

0 commit comments

Comments
 (0)