in src/com/amazon/corretto/crypto/provider/AesGcmSpi.java [70:210]
private static native int oneShotEncrypt(
long ctxPtr,
long[] ctxPtrOut,
byte[] input,
int inputOffset,
int inputLength,
byte[] result,
int resultOffset,
int tagLen,
byte[] key,
byte[] iv
);
/**
* Performs a decryption operation in a single call. Unlike oneShotEncrypt, AAD mode is supported. The native-side
* code will take care of periodically dropping any buffer locks it has to allow GC to make progress.
*
* @param input Input plaintext to encrypt
* @param inoffset Offset within input array of start of plaintext
* @param inlen Data length to encrypt
* @param result Result array - must have room for inputLength + tagLen + resultOffset bytes
* @param resultOffset Offset of start of ciphertext in result array
* @param tagLen Length of GCM tag
* @param key AES key
* @param iv Initialization vector
* @param aadBuffer AAD data buffer; the data must start from offset zero in this buffer
* @param aadSize Size of AAD data; any data in the buffer beyond this point is ignored
* @return Actual number of bytes written
*/
private static native int oneShotDecrypt(
long ptr,
long[] ptrOut,
byte[] input,
int inoffset,
int inlen,
byte[] result,
int resultOffset,
int tagLen,
byte[] key,
byte[] iv,
byte[] aadBuffer,
int aadSize
);
/**
* Initializes state for a non-one-shot encryption operation.
*
* @param key Encryption key
* @param iv Initialization vector
* @return Native pointer to context data structure, which must be freed using releaseContext() or encryptDoFinal()
*/
private static native long encryptInit(byte[] key, byte[] iv);
/**
* Reuses an existing EVP context and initializes it for encryption given the new IV.
*
* @param ptr Context pointer
* @param iv Initialization vector
*/
private static native void encryptInit(long ptr, byte[] iv);
/**
* Processes some plaintext during a non-one-shot encryption operation. This is essentially a wrapper around
* OpenSSL's EVP_CipherUpdate.
*
* @param ptr Context pointer
* @param bytes Input data array
* @param offset Offset within input array to start reading
* @param length Number of plaintext bytes to process
* @param output Output array
* @param outputOffset Offset to start writing within output array
* @return Actual number of bytes written
*/
private static native int encryptUpdate(
long ptr,
byte[] bytes,
int offset,
int length,
byte[] output,
int outputOffset
);
/**
* Provides some AAD data to a non-one-shot encryption operation
*
* @param ptr Context pointer
* @param bytes AAD data array
* @param offset Start of AAD data within array
* @param length Amount of AAD data to ingest
*/
private static native void encryptUpdateAAD(long ptr, byte[] bytes, int offset, int length);
/**
* Finishes an encryption operation. This call will implicitly release the native context pointer, even if it fails
* and throws an exception.
*
* @param ptr Native context pointer
* @param releaseContext if true releases the context
* @param bytes Final input data (must not be null, even if no data is to be consumed)
* @param offset Offset within bytes to start reading
* @param length Length within bytes to read
* @param output Output buffer
* @param outputOffset Offset within output buffer to start writing
* @param tagLen Length of GCM tag
* @return Number of bytes written in this final operation
*/
private static native int encryptDoFinal(
long ptr,
boolean releaseContext,
byte[] bytes,
int offset,
int length,
byte[] output,
int outputOffset,
int tagLen
);
/**
* Aborts an encryption operation and releases native resources associated with it.
*
* @param ptr Native context pointer
*/
private static native void releaseContext(long ptr);
private static final int BLOCK_SIZE = 128 / 8;
private NativeResource context = null;
private SecretKey jceKey;
private byte[] iv, key;
private int tagLength;
private int opMode = -1;
private boolean hasConsumedData = false;
private boolean needReset = false;
private int keyUsageCount = 0;
private boolean contextInitialized = false;
private AccessibleByteArrayOutputStream decryptInputBuf, decryptAADBuf;
AesGcmSpi() {
Loader.checkNativeLibraryAvailability();
}