Maarten Bodewes Maarten Bodewes - 6 months ago 148
Java Question

AES-NI intrinsics enabled by default?

Oracle has this to say about Java 8 with regards to AES-NI:


Hardware intrinsics were added to use Advanced Encryption Standard
(AES). The UseAES and UseAESIntrinsics flags are available to enable
the hardware-based AES intrinsics for Intel hardware. The hardware
must be 2010 or newer Westmere hardware. For example, to enable
hardware AES, use the following flags:

-XX:+UseAES -XX:+UseAESIntrinsics


To disable hardware AES use the following flags:

-XX:-UseAES -XX:-UseAESIntrinsics



But it does not indicate if AES intrinsics are enabled by default (for processors that support it). So the question is simple: if the processor supports AES-NI, are AES intrinsics used?

Bonus question: is there any way to test if AES-NI is being used? I guess you can guess based on performance, but that's not an optimal or sure fire way of testing.




For readerS that are not familiar with AES-NI intrinsics: it's replacing byte code with pre-compiled machine code, using the AES-NI instruction set. This happens by the JVM, so it does not show up in the API of the Java runtime or bytecode.

Answer

The flag has a default of true and it will be set to false if the detection fails, so you can simply use +PrintFlagsFinal to see if it is used:

My Laptop without AES-NI:

C:\>"C:\Program Files\Java\jdk1.7.0_51\bin\java" -XX:+PrintFlagsFinal -version | find "UseAES"
     bool UseAES                                    = false           {product}
     bool UseAESIntrinsics                          = false           {product}
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)

Same on Desktop with AES-NI:

C:\>"C:\Program Files\Java\jdk7\bin\java" -XX:+PrintFlagsFinal -version | find "AES"
     bool UseAES                                    = true            {product}
     bool UseAESIntrinsics                          = true            {product}

java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)

C:\>"C:\Program Files (x86)\Java\jre7\bin\java" -XX:+PrintFlagsFinal -version | find "AES"
     bool UseAES                                    = true            {product}
     bool UseAESIntrinsics                          = true            {product}

java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) Client VM (build 24.51-b03, mixed mode, sharing)

So, it works for both x64 and i686 (WOW64) with recent Java 7. The feature was introduced with https://bugs.openjdk.java.net/browse/JDK-7184394 and backported to 7u40 and 7u45.


Important: AES-NI may only be available on the server VM.

This was acknowledged by Oracle after a bug report was filed. This vital piece of information was missing when they created the featues list of Java 8 where it was introduced (it later got backported to 7 as well). The server VM can be explicitly choosen by providing the -server option on the java or javaw command line.