in csrc/aes_gcm.cpp [144:198]
JNIEXPORT int JNICALL Java_com_amazon_corretto_crypto_provider_AesGcmSpi_oneShotEncrypt(
JNIEnv *pEnv,
jclass,
jlong ctxPtr,
jlongArray ctxOut,
jbyteArray inputArray,
jint inoffset,
jint inlen,
jbyteArray resultArray,
jint resultOffset,
jint tagLen,
jbyteArray keyArray,
jbyteArray ivArray
)
{
try {
raii_env env(pEnv);
java_buffer input = java_buffer::from_array(env, inputArray, inoffset, inlen);
java_buffer result = java_buffer::from_array(env, resultArray, resultOffset);
java_buffer iv = java_buffer::from_array(env, ivArray);
raii_cipher_ctx ctx;
if (ctxPtr) {
ctx.borrow(reinterpret_cast<EVP_CIPHER_CTX*>(ctxPtr));
jni_borrow ivBorrow(env, iv, "iv");
if (unlikely(!EVP_CipherInit_ex(ctx, NULL, NULL, NULL, ivBorrow.data(), NATIVE_MODE_ENCRYPT))) {
throw java_ex::from_openssl(EX_RUNTIME_CRYPTO, "Failed to set IV");
}
} else {
ctx.init();
EVP_CIPHER_CTX_init(ctx);
java_buffer key = java_buffer::from_array(env, keyArray);
initContext(env, ctx, NATIVE_MODE_ENCRYPT, key, iv);
}
int outoffset = updateLoop(env, result, input, ctx);
if (outoffset < 0) return 0;
result = result.subrange(outoffset);
int finalOffset = cryptFinish(env, NATIVE_MODE_ENCRYPT, result, tagLen, ctx);
if (!ctxPtr && ctxOut) {
// Context is new, but caller does want it back
jlong tmpPtr = reinterpret_cast<jlong>(ctx.take());
env->SetLongArrayRegion(ctxOut, 0 /* start position */, 1 /* number of elements */, &tmpPtr);
}
return finalOffset + outoffset;
} catch (java_ex &ex) {
ex.throw_to_java(pEnv);
return -1;
}
}