Problems with AES-GCM native acceleration

Adam Petcher adam.petcher at oracle.com
Wed Nov 14 16:41:01 UTC 2018


I'm adding back in hotspot-dev, because this is a somewhat tricky topic 
related to intrinsics and JIT. Hopefully, a Hotspot expert can correct 
anything that I say below that is wrong, and suggest any solutions that 
I missed.

The AES acceleration is implemented in a HotSpot intrinsic. In order for 
it to kick in, the code must be JIT compiled by the VM. As I understand 
it, this only happens to some particular method after it has been called 
a certain number of times. The rules that determine this number are 
somewhat complicated, but I think you can guarantee JIT in the default 
configuration by calling a method 10,000 times.

The doFinal method calls the update method, so either one should trigger 
the acceleration as long as you call it enough. Breaking the message up 
into smaller chunks and calling update on each one works only because it 
ends up calling the update method more. You should be able to trigger 
the acceleration by calling doFinal more, too.

The reason why the workaround doesn't work with decryption is that the 
decryption routine buffers the ciphertext and then decrypts it all at 
the end. So calling update multiple times and then calling doFinal at 
the end is essentially the same as calling doFinal once with the entire 
ciphertext.

So here are some solutions that you may want to try:

1) In your benchmark, run at least 10,000 "warmup" iterations of 
whatever you are trying to do at the beginning, without timing it. This 
is a good idea for benchmarks, anyway. If it helps, you can try using 
smaller buffers in your "warmup" phase in order to get it to complete 
faster.

2) Try -XX:CompileThreshold=(some number smaller than 10000) as an 
argument to java. This will make JIT kick in sooner across the board. 
Obviously, this should be done carefully in production, since it will 
impact the performance of the entire program.

3) I haven't tried this, but running with an AOTed java.base module may 
also help. See the section titled "Steps to generate and use an AOT 
library for the java.base module" in the AOT JEP[1].

"Fixing" this issue in the JDK is non-trivial, because it gets into the 
behavior of the VM and JIT. I don't really like the idea of modifying 
doFinal (to break up the operation into multiple update calls) or 
modifying the decryption operation (to decrypt immediately and buffer 
plaintext) in order to work around this issue. Perhaps there is a better 
way for the VM to handle cases like this, in which a method is not 
called often, but the interpreted execution takes a long time to 
complete when it is called. Perhaps a VM expert will have some 
additional thoughts here.

[1] https://openjdk.java.net/jeps/295

On 11/14/2018 9:49 AM, Severin Gehwolf wrote:
> Dropping hotspot-dev and adding security-dev.
>
> On Wed, 2018-11-14 at 14:39 +0200, Gidon Gershinsky wrote:
>> Hi,
>>
>> We are working on an encryption mechanism at the Apache Parquet -
>> that will enable efficient analytics on encrypted data by frameworks
>> such as Apache Spark.
>> https://github.com/apache/parquet-format/blob/encryption/Encryption.md
>> https://www.slideshare.net/databricks/efficient-spark-analytics-on-encrypted-data-with-gidon-gershinsky
>>
>> We came across an AES-related issue in the Java HostSpot engine that
>> looks like a substantial problem for us in both Spark and Parquet
>> workloads. The bug report had been accepted a while ago:
>> https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8201633
>>
>> The fix should hopefully be rather straightforward though.
>> Could you help us with that? I have a couple of small samples
>> reproducing the problem.
>>
>> (If I'm writing to a wrong mailing list - I apologize, please point
>> me in the right direction).
>>
>> Cheers, Gidon.



More information about the security-dev mailing list