1111 */
1212public 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}
0 commit comments