730 buffered -= len; |
730 buffered -= len; |
731 if (buffered != 0) { |
731 if (buffered != 0) { |
732 System.arraycopy(buffer, len, buffer, 0, buffered); |
732 System.arraycopy(buffer, len, buffer, 0, buffered); |
733 } |
733 } |
734 } else { // len > buffered |
734 } else { // len > buffered |
735 if (buffered == 0) { |
735 if ((input != output) && (buffered == 0)) { |
736 // all to-be-processed data are from 'input' |
736 // all to-be-processed data are from 'input' |
|
737 // however, note that if 'input' and 'output' are the same, |
|
738 // then they can't be passed directly to the underlying cipher |
|
739 // engine operations as data may be overwritten before they |
|
740 // are read. |
737 if (decrypting) { |
741 if (decrypting) { |
738 outLen = cipher.decrypt(input, inputOffset, len, output, outputOffset); |
742 outLen = cipher.decrypt(input, inputOffset, len, output, outputOffset); |
739 } else { |
743 } else { |
740 outLen = cipher.encrypt(input, inputOffset, len, output, outputOffset); |
744 outLen = cipher.encrypt(input, inputOffset, len, output, outputOffset); |
741 } |
745 } |
742 inputOffset += len; |
746 inputOffset += len; |
743 inputLen -= len; |
747 inputLen -= len; |
744 } else { |
748 } else { |
745 // assemble the data using both 'buffer' and 'input' |
749 // assemble the data using both 'buffer' and 'input' |
746 byte[] in = new byte[len]; |
750 byte[] in = new byte[len]; |
747 System.arraycopy(buffer, 0, in, 0, buffered); |
|
748 int inConsumed = len - buffered; |
751 int inConsumed = len - buffered; |
749 System.arraycopy(input, inputOffset, in, buffered, inConsumed); |
752 if (buffered != 0) { |
750 buffered = 0; |
753 System.arraycopy(buffer, 0, in, 0, buffered); |
751 inputOffset += inConsumed; |
754 buffered = 0; |
752 inputLen -= inConsumed; |
755 } |
|
756 if (inConsumed != 0) { |
|
757 System.arraycopy(input, inputOffset, in, len - inConsumed, inConsumed); |
|
758 inputOffset += inConsumed; |
|
759 inputLen -= inConsumed; |
|
760 } |
753 if (decrypting) { |
761 if (decrypting) { |
754 outLen = cipher.decrypt(in, 0, len, output, outputOffset); |
762 outLen = cipher.decrypt(in, 0, len, output, outputOffset); |
755 } else { |
763 } else { |
756 outLen = cipher.encrypt(in, 0, len, output, outputOffset); |
764 outLen = cipher.encrypt(in, 0, len, output, outputOffset); |
757 } |
765 } |
905 throw new IllegalBlockSizeException |
913 throw new IllegalBlockSizeException |
906 ("Input length must be multiple of " + blockSize + |
914 ("Input length must be multiple of " + blockSize + |
907 " when decrypting with padded cipher"); |
915 " when decrypting with padded cipher"); |
908 } |
916 } |
909 |
917 |
910 // prepare the final input avoiding copying if possible |
918 /* |
|
919 * prepare the final input, assemble a new buffer if any |
|
920 * of the following is true: |
|
921 * - 'input' and 'output' are the same buffer |
|
922 * - there are internally buffered bytes |
|
923 * - doing encryption and padding is needed |
|
924 */ |
911 byte[] finalBuf = input; |
925 byte[] finalBuf = input; |
912 int finalOffset = inputOffset; |
926 int finalOffset = inputOffset; |
913 int finalBufLen = inputLen; |
927 int finalBufLen = inputLen; |
914 if ((buffered != 0) || (!decrypting && padding != null)) { |
928 if ((input == output) || (buffered != 0) || |
|
929 (!decrypting && padding != null)) { |
915 if (decrypting || padding == null) { |
930 if (decrypting || padding == null) { |
916 paddingLen = 0; |
931 paddingLen = 0; |
917 } |
932 } |
918 finalBuf = new byte[len + paddingLen]; |
933 finalBuf = new byte[len + paddingLen]; |
919 finalOffset = 0; |
934 finalOffset = 0; |