How can I use AES-NI intrinsics on a Mac?
Asked Answered
F

1

9

I'm trying to compile a C application on a Mac. I use SSE4 and AES-NI intrinsics.

In Linux, I just call gcc with the -msse4 and -maes flags and include the wmmintrin.h header and I can call SSE intrinsics like _mm_add_epi64(a,b) or AES-NI intrinsics like _mm_aesenc_si128(a, b) and everything works fine.

On the Mac, it's harder, because Apple replaces GCC with llvm-gcc which does not support AES-NI yet. So SSE4 intrinsics work fine, but not the AES ones. Even inline assembly calls to the AES instructions are not recognized.

Intel has lots of AES example code on their website, but it's for Linux and Windows only.

I did notice the RDRAND instruction is also unsupported by llvm-gcc but Intel provides a workaround for that by using a C macro which expands into raw machine byte code. (See the rdrand.h example file in this Intel library)

Unfortunately there is no similar provided workaround for the AES-NI instructions, probably because the instructions have arguments and can't be evaluated as static machine code bytes.

Programs do exist that use AES-NI on the Mac, including Apple's own File Vault, so there must be some method that works!

To make my question concrete, how would I get the following simple call to compile using the latest Mac gcc-llvm 4.2 (latest public release in Mountain Lion xcode 4.4.1):

 __m128i A, B, C;
  /* A, B, C initialized here... */
  A = _mm_aesenc_si128(B, C);   

Thanks for any help!

Foretaste answered 28/9, 2012 at 5:51 Comment(1)
You should be using clang, not gcc.Ingunna
F
8

Apple developer support reported that it wasn't possible using Xcode. (And in fact their reply was a bit snarky and implied that AES-NI wasn't something a developer ever needed to use directly, so I shouldn't bother. Sigh, thanks, Apple.)

However, I did find two working solutions, both by simply avoiding Apple's software. One is to use Intel's own commercial C++ compiler. The other is to download and compile GCC 4.6 or 4.7 from source and use it directly. This is the option I chose. I followed this guide. The GCC compile and install (while clean) is still a hassle and workaround just to use a single CPU intrinsic, but it works. Thanks, GCC team!

Foretaste answered 29/9, 2012 at 21:39 Comment(3)
This answer has changed as it is possible with modern Xcode (4.6.3), regardless of Apple.Iaria
asm volatile ("aesenc ...." : ... ); // works on both llvm and gcc-4.4+, be sure to first check CPUID.01H:ECX.AESNI[bit 25] = 1Iaria
The takeaway is be vigilant about crypto, whether high- or low-level, as it only takes one subtle coding mistake to expose a large attack surface.Iaria

© 2022 - 2024 — McMap. All rights reserved.