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!

Rich Denver
  • 171
  • 1
  • 6
  • You should be using [clang](https://developer.apple.com/library/mac/#documentation/CompilerTools/Conceptual/LLVMCompilerOverview/_index.html), *not* `gcc`. – Brett Hale Sep 29 '12 at 04:38

1 Answers1

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!

Rich Denver
  • 171
  • 1
  • 6
  • 4
    This answer has changed as it is possible with modern Xcode (4.6.3), regardless of Apple. –  Jul 08 '13 at 00:25
  • asm volatile ("aesenc ...." : ... ); // works on both llvm and gcc-4.4+, be sure to first check CPUID.01H:ECX.AESNI[bit 25] = 1 –  Jul 08 '13 at 00:45
  • 1
    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. –  Jul 08 '13 at 00:55