JNIEXPORT int JNICALL Java_com_amazon_corretto_crypto_provider_AesGcmSpi_oneShotEncrypt()

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;
    }
}