in src/main/java/com/amazonaws/encryptionsdk/internal/BlockDecryptionHandler.java [80:141]
public synchronized ProcessingSummary processBytes(
final byte[] in, final int off, final int len, final byte[] out, final int outOff)
throws AwsCryptoException {
if (complete_) {
throw new AwsCryptoException("Ciphertext has already been processed.");
}
final byte[] bytesToParse = new byte[unparsedBytes_.length + len];
// If there were previously unparsed bytes, add them as the first
// set of bytes to be parsed in this call.
System.arraycopy(unparsedBytes_, 0, bytesToParse, 0, unparsedBytes_.length);
System.arraycopy(in, off, bytesToParse, unparsedBytes_.length, len);
long parsedBytes = 0;
// Parse available bytes. Stop parsing when there aren't enough
// bytes to complete parsing of the :
// - the blockcipher headers
// - encrypted content
while (!complete_ && parsedBytes < bytesToParse.length) {
blockHeaders_.setNonceLength(nonceLen_);
parsedBytes += blockHeaders_.deserialize(bytesToParse, (int) parsedBytes);
if (parsedBytes > Integer.MAX_VALUE) {
throw new AwsCryptoException(
"Integer overflow of the total bytes to parse and decrypt occured.");
}
// if we have all header fields, process the encrypted content.
if (blockHeaders_.isComplete() == true) {
if (blockHeaders_.getContentLength() > Integer.MAX_VALUE) {
throw new AwsCryptoException("Content length exceeds the maximum allowed value.");
}
int protectedContentLen = (int) blockHeaders_.getContentLength();
// include the tag which is added by the underlying cipher.
protectedContentLen += cryptoAlgo_.getTagLen();
if ((bytesToParse.length - parsedBytes) < protectedContentLen) {
// if we don't have all of the encrypted bytes, break
// until they become available.
break;
}
byte[] plaintext = decryptContent(bytesToParse, (int) parsedBytes, protectedContentLen);
System.arraycopy(plaintext, 0, out, outOff, plaintext.length);
complete_ = true;
return new ProcessingSummary(
plaintext.length, (int) (parsedBytes + protectedContentLen) - unparsedBytes_.length);
} else {
// if there aren't enough bytes to parse the block headers,
// we can't continue parsing.
break;
}
}
// buffer remaining bytes for parsing in the next round.
unparsedBytes_ = Arrays.copyOfRange(bytesToParse, (int) parsedBytes, bytesToParse.length);
return new ProcessingSummary(0, len);
}