in src/com/amazon/corretto/crypto/provider/RsaCipher.java [162:227]
protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, final byte[] output,
final int outputOffset)
throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
synchronized (lock_) {
assertInitialized();
try {
parseKey();
} catch (final InvalidKeyException e) {
throw new IllegalStateException(e);
}
if (buffer_.size() != 0) { // Not one-shot
if (input != null) {
buffer_.write(input, inputOffset, inputLen);
}
input = buffer_.getDataBuffer();
inputOffset = 0;
inputLen = buffer_.size();
}
// One-shot, no input. Cipher only calls engineDoFinal with null input in doFinal overloads
// that don't take an input buffer, and in those cases, inputOffset and inputLen are 0.
// We set them here anyways to be safe, because the API makes no such guarantee.
else if (input == null) {
input = Utils.EMPTY_ARRAY;
inputOffset = 0;
inputLen = 0;
}
if (output.length - outputOffset < engineGetOutputSize(inputLen)) {
throw new ShortBufferException();
}
if (mode_ == Cipher.ENCRYPT_MODE || mode_ == Cipher.WRAP_MODE) {
if (inputLen > keySizeBytes_ - padding_.paddingLength) {
throw new IllegalBlockSizeException("Data must not be longer than "
+ (keySizeBytes_ - padding_.paddingLength) + " bytes");
}
// We're allowed to pad NO_PADDING with zero bytes on the left.
// This is because RSA fundamentally works on positive integers so
// adding new high-order zero bytes does not change the numeric value
// of the input and thus does not change the output.
if (padding_.equals(Padding.NO_PADDING) && inputLen < keySizeBytes_) {
byte[] tmp = new byte[keySizeBytes_];
System.arraycopy(input, inputOffset, tmp, keySizeBytes_ - inputLen, inputLen);
input = tmp;
inputOffset = 0;
inputLen = keySizeBytes_;
}
} else {
if (inputLen > keySizeBytes_) {
throw new IllegalBlockSizeException("Data must not be longer than " + keySizeBytes_ + " bytes");
}
}
final int result;
if (nativeKey_ != null) {
result = cipherWithNativeKey(input, inputOffset, inputLen, output, outputOffset);
} else if (!reUseKey_) {
result = cipherWithRawParams(input, inputOffset, inputLen, output, outputOffset);
reUseKey_ = true;
} else {
result = cipherAndCreateNativeKey(input, inputOffset, inputLen, output, outputOffset);
}
buffer_ = new AccessibleByteArrayOutputStream();
return result;
}
}