11package org .bouncycastle .crypto ;
22
3- import org .bouncycastle .util .Arrays ;
4-
53/**
64 * A wrapper class that allows block ciphers to be used to process data in
75 * a piecemeal fashion. The BufferedBlockCipher outputs a block only when the
@@ -168,27 +166,26 @@ public int getOutputSize(
168166 /**
169167 * process a single byte, producing an output block if necessary.
170168 *
171- * @param in the input byte.
172- * @param out the space for any output that might be produced.
169+ * @param in the input byte.
170+ * @param out the space for any output that might be produced.
173171 * @param outOff the offset from which the output will be copied.
174172 * @return the number of output bytes copied to out.
175- * @throws DataLengthException if there isn't enough space in out.
176- * @throws IllegalStateException if the cipher isn't initialised.
173+ * @exception DataLengthException if there isn't enough space in out.
174+ * @exception IllegalStateException if the cipher isn't initialised.
177175 */
178176 public int processByte (
179- byte in ,
180- byte [] out ,
181- int outOff )
177+ byte in ,
178+ byte [] out ,
179+ int outOff )
182180 throws DataLengthException , IllegalStateException
183181 {
184- int resultLen = 0 ;
182+ int resultLen = 0 ;
185183
186184 buf [bufOff ++] = in ;
187185
188186 if (bufOff == buf .length )
189187 {
190- resultLen = cipher .processBlock (buf , 0 , out , outOff );
191- bufOff = 0 ;
188+ resultLen = processBuffer (out , outOff );
192189 }
193190
194191 return resultLen ;
@@ -197,30 +194,30 @@ public int processByte(
197194 /**
198195 * process an array of bytes, producing output if necessary.
199196 *
200- * @param in the input byte array.
201- * @param inOff the offset at which the input data starts.
202- * @param len the number of bytes to be copied out of the input array.
203- * @param out the space for any output that might be produced.
197+ * @param in the input byte array.
198+ * @param inOff the offset at which the input data starts.
199+ * @param len the number of bytes to be copied out of the input array.
200+ * @param out the space for any output that might be produced.
204201 * @param outOff the offset from which the output will be copied.
205202 * @return the number of output bytes copied to out.
206- * @throws DataLengthException if there isn't enough space in out.
207- * @throws IllegalStateException if the cipher isn't initialised.
203+ * @exception DataLengthException if there isn't enough space in out.
204+ * @exception IllegalStateException if the cipher isn't initialised.
208205 */
209206 public int processBytes (
210- byte [] in ,
211- int inOff ,
212- int len ,
213- byte [] out ,
214- int outOff )
207+ byte [] in ,
208+ int inOff ,
209+ int len ,
210+ byte [] out ,
211+ int outOff )
215212 throws DataLengthException , IllegalStateException
216213 {
217214 if (len < 0 )
218215 {
219216 throw new IllegalArgumentException ("Can't have a negative input length!" );
220217 }
221218
222- int blockSize = getBlockSize ();
223- int length = getUpdateOutputSize (len );
219+ int blockSize = getBlockSize ();
220+ int length = getUpdateOutputSize (len );
224221
225222 if (length > 0 )
226223 {
@@ -235,29 +232,35 @@ public int processBytes(
235232
236233 if (len > gapLen )
237234 {
238- System .arraycopy (in , inOff , buf , bufOff , gapLen );
239- inOff += gapLen ;
240- len -= gapLen ;
241- if (in == out && Arrays .segmentsOverlap (inOff , len , outOff , length ))
235+ if (bufOff != 0 )
236+ {
237+ System .arraycopy (in , inOff , buf , bufOff , gapLen );
238+ inOff += gapLen ;
239+ len -= gapLen ;
240+ }
241+
242+ if (in == out )
242243 {
243244 in = new byte [len ];
244245 System .arraycopy (out , inOff , in , 0 , len );
245246 inOff = 0 ;
246247 }
247248
248- resultLen += cipher .processBlock (buf , 0 , out , outOff );
249-
250- bufOff = 0 ;
249+ // if bufOff non-zero buffer must now be full
250+ if (bufOff != 0 )
251+ {
252+ resultLen += processBuffer (out , outOff );
253+ }
251254
252255 if (mbCipher != null )
253256 {
254- int blockCount = len / mbCipher .getMultiBlockSize ();
257+ int blockCount = ( len / mbCipher .getMultiBlockSize ()) * ( mbCipher . getMultiBlockSize () / blockSize );
255258
256259 if (blockCount > 0 )
257260 {
258261 resultLen += mbCipher .processBlocks (in , inOff , blockCount , out , outOff + resultLen );
259262
260- int processed = blockCount * mbCipher . getMultiBlockSize () ;
263+ int processed = blockCount * blockSize ;
261264
262265 len -= processed ;
263266 inOff += processed ;
@@ -281,13 +284,25 @@ public int processBytes(
281284
282285 if (bufOff == buf .length )
283286 {
284- resultLen += cipher .processBlock (buf , 0 , out , outOff + resultLen );
285- bufOff = 0 ;
287+ resultLen += processBuffer (out , outOff + resultLen );
286288 }
287289
288290 return resultLen ;
289291 }
290292
293+ private int processBuffer (byte [] out , int outOff )
294+ {
295+ bufOff = 0 ;
296+ if (mbCipher != null )
297+ {
298+ return mbCipher .processBlocks (buf , 0 , buf .length / mbCipher .getBlockSize (), out , outOff );
299+ }
300+ else
301+ {
302+ return cipher .processBlock (buf , 0 , out , outOff );
303+ }
304+ }
305+
291306 /**
292307 * Process the last block in the buffer.
293308 *
@@ -318,15 +333,26 @@ public int doFinal(
318333
319334 if (bufOff != 0 )
320335 {
321- if (!partialBlockOkay )
336+ int index = 0 ;
337+ if (mbCipher != null )
322338 {
323- throw new DataLengthException ("data not block size aligned" );
339+ int nBlocks = bufOff / mbCipher .getBlockSize ();
340+ resultLen += mbCipher .processBlocks (buf , 0 , nBlocks , out , outOff );
341+ index = nBlocks * mbCipher .getBlockSize ();
324342 }
325343
326- cipher .processBlock (buf , 0 , buf , 0 );
327- resultLen = bufOff ;
328- bufOff = 0 ;
329- System .arraycopy (buf , 0 , out , outOff , resultLen );
344+ if (bufOff != index )
345+ {
346+ if (!partialBlockOkay )
347+ {
348+ throw new DataLengthException ("data not block size aligned" );
349+ }
350+
351+ cipher .processBlock (buf , index , buf , index );
352+ System .arraycopy (buf , index , out , outOff + resultLen , bufOff - index );
353+ resultLen += bufOff - index ;
354+ bufOff = 0 ;
355+ }
330356 }
331357
332358 return resultLen ;
0 commit comments