21

I could find references to "hardware-accelerated AES encryption" on an iPhone/iPad. But the APIs that I could find to do the AES encryption (CCCrypt) don't talk about hardware-acceleration at all.

Does anyone have any idea if these APIs are the ones that are hardware-accelerated or are there other ones?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Bala
  • 341
  • 1
  • 2
  • 6
  • 2
    My understanding is Apple won't tell you whether it's hardware-accelerated or not, but will provide only CommonCryptor stuff to you... I suppose it'll be hardware-accelerated on devices that support it, plan software if not. – Romain Mar 21 '11 at 09:29
  • 1
    It is noteworthy that the following comments appear in the CryptoExercise code (SecKeyWrapper.h:60-62): __// The chosen symmetric key and digest algorithm chosen for this sample is AES and SHA1. // The reasoning behind this was due to the fact that the iPhone and iPod touch have // hardware accelerators for those particular algorithms and therefore are energy efficient.__ – Robert Travis Pierce Jul 24 '12 at 16:22

3 Answers3

24

Yes.

As of 4.3, if the message has >64 blocks (i.e. 1024 bytes), the CCCrypt function for AES will use the hardware-accelerated implementation. (This is done by ioctling with /dev/aes_0, BTW.)

Besides AES, SHA-1 is also hardware-accelerated when the input is > 4096 bytes.

kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
  • 2
    Do you have any link to Apple documentation that says so? – Bala Mar 24 '11 at 14:55
  • 1
    @Bala: SHA-1: There is a `CC_SHA1_USE_HARDWARE_THRESHOLD` = 4096 written in http://opensource.apple.com/source/CommonCrypto/CommonCrypto-36064/Source/Digest/sha1.c; AES: Unfortunately it isn't documented anywhere, nor there are any source code published. You need to disassemble libSystem.B.dylib to get this. – kennytm Mar 24 '11 at 15:02
  • Thanks. I'm puzzled as to why Apple chose 4096 as the threshold. Maybe its the limit of the hardware SHA-1 chip? – Bala Mar 25 '11 at 22:45
  • @Bala: I ***think*** it's just an efficiency concern. Communicating with external hardware isn't free. – kennytm Mar 26 '11 at 06:50
  • @KennyTM: Most likely. I have been trying to use this API but haven't been successful using the hardware accelerated AES (even though the block that I'm trying to encrypt is greater than 1024). When I tried to step through aes_cc_encrypt, I see (a) The code I see doesn't match with what I see at http://opensource.apple.com/source/CommonCrypto/CommonCrypto-36064/Source/GladmanAES/ccNewGladman.c and (b) It doesn't take the "hardware" path. Have you tried this yourself and gotten it to work? – Bala Mar 29 '11 at 14:45
  • I have posted a follow-up question to this here: http://stackoverflow.com/questions/5479335/which-hardware-chip-vendor-does-apple-use-for-its-hardware-accelerated-aes-sha-1 – Bala Mar 29 '11 at 21:47
  • Is there a way to put the hardware engine in CFB (cipher feedback) mode? There is an option `kCCOptionECBMode` to use ECB (instead of the default CBC mode) according to the header file. – Martijn Thé Apr 28 '11 at 07:00
  • @MartijnThé - the AES hardware usually operates in ECB mode. Its up to the programmer to add the mode layer logic. According to the Crypto++ wiki, [VIA Padlock provides ECB, CBC and OFB](http://www.cryptopp.com/wiki/VIA_Padlock) acceleration, but that does not mean it performs everything. Since the time between x86 Padlock and other commodity accelerators, like x86 AES-NI and ARM Crypto, the accelerated assistance has become more basic. – jww Jun 15 '16 at 14:42
3

The whole point of an API is that you don't need to care about the implementation details that back it. The implementor (Apple, in this case) will use whatever implementation gives the best performance and energy usage characteristics on whatever hardware is in use. That might be a hardware implementation, or it might be a software implementation, it might depend on the block size for which you are calling the function.

Stephen Canon
  • 103,815
  • 19
  • 183
  • 269
  • *"You don't need to care about the implementation details..."* - [`goto fail`](http://nakedsecurity.sophos.com/2014/02/24/anatomy-of-a-goto-fail-apples-ssl-bug-explained-plus-an-unofficial-patch/) for the win! – jww May 15 '16 at 13:39
2

Does iPhone support hardware-accelerated AES Encryption?

It depends on the iPhone version and hardware, but mostly YES in 2015.

Apple uses it for the quick "remote wipe" feature for managed devices. The idea is everything is encrypted, and the keys are stored in a keybag backed by effaceable storage ("effaçable" is French for "erasable"). For more information, see Jean-Baptiste Bédrune and Jean Sigwald iPhone data protection in depth; and Dino Zavi's Apple iOS 4 Security Evaluation.

The circuit is placed on the DMA datapath between storage and memory so anything traversing the path is encrypted or decrypted.

If the device is lost or stolen, then a command can be sent to the device to erase the keybag holding the keys used for encryption and decryption. Because the keybag is backed by effaceable storage, the keys don't move around due to wear leveling.

It appears Apple provides hardware accelerated AES from at least two sources on iOS devices. Both are wrapped by Apple's CommonCrypto framework. At least one appears to be available to the programmer without the need for CommonCrypto.


First hardware accelerated source

The first source is standard ARM crypto available in ARMv8 and above. The instructions are available as both C/C++ intinsics and assembly when __ARM_FEATURE_CRYPTO is defined:

$ clang++ -arch arm64 -dM -E - < /dev/null | sort | egrep -i '(arm|aarch|neon)'
#define __AARCH64EL__ 1
#define __AARCH64_SIMD__ 1
#define __ARM64_ARCH_8__ 1
#define __ARM_64BIT_STATE 1
#define __ARM_ACLE 200
#define __ARM_ALIGN_MAX_STACK_PWR 4
#define __ARM_ARCH 8
#define __ARM_ARCH_ISA_A64 1
#define __ARM_ARCH_PROFILE 'A'
#define __ARM_FEATURE_CLZ 1
#define __ARM_FEATURE_CRYPTO 1
#define __ARM_FEATURE_DIV 1
#define __ARM_FEATURE_FMA 1
#define __ARM_FEATURE_UNALIGNED 1
#define __ARM_FP 0xe
#define __ARM_FP16_FORMAT_IEEE 1
#define __ARM_FP_FENV_ROUNDING 1
#define __ARM_NEON 1
#define __ARM_NEON_FP 7
#define __ARM_NEON__ 1
#define __ARM_PCS_AAPCS64 1
#define __ARM_SIZEOF_MINIMAL_ENUM 4
#define __ARM_SIZEOF_WCHAR_T 4
#define __aarch64__ 1
#define __arm64 1
#define __arm64__ 1

By the way, when __ARM_FEATURE_CRYPTO is defined, you should have access to hardware accelerated SHA-1 and SHA-2, also.


Second hardware accelerated source

The second source appears to be custom, and its present in ARMv7s and below. I'm not sure how to get to this crypto (maybe opensource.apple.com has the answer):

$ clang++ -arch armv7s -dM -E - < /dev/null | sort | egrep -i '(arm|aarch|neon|crc|crypto)'
#define __ARMEL__ 1
#define __ARM_ARCH 7
#define __ARM_ARCH_7S__ 1
#define __ARM_ARCH_EXT_IDIV__ 1
#define __ARM_NEON 1
#define __ARM_NEON__ 1
#define __ARM_SIZEOF_MINIMAL_ENUM 4
#define __ARM_SIZEOF_WCHAR_T 4
#define __ARM_VFPV4__ 1
#define __arm 1
#define __arm__ 1

And:

$ clang++ -arch armv7 -dM -E - < /dev/null | sort | egrep -i '(arm|aarch|neon|crc|crypto)'
#define __ARMEL__ 1
#define __ARM_ARCH 7
#define __ARM_ARCH_7A__ 1
#define __ARM_ARCH_PROFILE A
#define __ARM_NEON 1
#define __ARM_NEON__ 1
#define __ARM_SIZEOF_MINIMAL_ENUM 4
#define __ARM_SIZEOF_WCHAR_T 4
#define __ARM_VFPV3__ 1
#define __arm 1
#define __arm__ 1

A related question is Which hardware chip/vendor does Apple use for its hardware-accelerated AES/SHA-1 encryption?


Here's some code we are using for iOS. It test for runtime support of ARM Crypto instructions. Because the code is intrinsic-based, the same code is used for iOS, Linux, Windows Phone and Windows Store. In the case of iOS, its used when -arch arm64 is specified.

#if (BOOL_ARM32 || BOOL_ARM64) && (/* other support tests */)
# define BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE 1
#endif
...

static bool TryCrypto()
{
#if (BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE)
# if defined(_WIN32) || defined(_WIN64)
    __try
    {
        // AES encrypt and decrypt
        static const uint8x16_t data = vdupq_n_u8(0), key = vdupq_n_u8(0); 
        uint8x16_t r1 = vaeseq_u8(data, key);
        uint8x16_t r2 = vaesdq_u8(data, key);
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        return false;
    }
    return true;
# else
    // longjmp and clobber warnings. Volatile is required.
    volatile bool result = true;

    SigHandler oldHandler = signal(SIGILL, SigIllHandlerCrypto);
    if (oldHandler == SIG_ERR)
        result = false;

    if (setjmp(s_jmpNoCrypto))
        result = false;
    else
    {
        // AES encrypt and decrypt
        static const uint8x16_t data = vdupq_n_u8(0), key = vdupq_n_u8(0); 
        uint8x16_t r1 = vaeseq_u8(data, key);
        uint8x16_t r2 = vaesdq_u8(data, key);
    }

    signal(SIGILL, oldHandler);
    return result;
# endif
#else
    return false;
#endif
}

And here's what it looks like from the command line during a compile:

clang++ -DNDEBUG -g2 -O3 -fPIC -pipe -Wall -miphoneos-version-min=7 -arch arm64 -stdlib=libc++ -isysroot
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.2.sdk
-c cpu.cpp
cpu.cpp:438:14: warning: unused variable 'r1' [-Wunused-variable]
                uint8x16_t r1 = vaeseq_u8(data, key);
                           ^
cpu.cpp:439:14: warning: unused variable 'r2' [-Wunused-variable]
                uint8x16_t r2 = vaesdq_u8(data, key);
                           ^
2 warnings generated.
Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885