【问题标题】:Does iPhone support hardware-accelerated AES Encryption?iPhone 是否支持硬件加速的 AES 加密?
【发布时间】:2020-01-20 14:37:58
【问题描述】:

我可以在 iPhone/iPad 上找到对“硬件加速 AES 加密”的引用。但我能找到的用于 AES 加密 (CCCrypt) 的 API 根本不涉及硬件加速。

有谁知道这些 API 是硬件加速的 API 还是其他 API?

【问题讨论】:

  • 我的理解是Apple不会告诉你它是否是硬件加速的,但只会向你提供CommonCryptor的东西......我想它会在支持它的设备上进行硬件加速,如果没有,请计划软件。
  • 值得注意的是,CryptoExercise 代码 (SecKeyWrapper.h:60-62) 中出现了以下 cmets: // 为该示例选择的对称密钥和摘要算法是 AES 和 SHA1 . // 这背后的原因是因为 iPhone 和 iPod touch 具有用于这些特定算法的 // 硬件加速器,因此非常节能。

标签: ios aes hardware-acceleration cryptography


【解决方案1】:

是的。

从 4.3 开始,如果消息具有 >64 个块(即 1024 字节),则 AES 的 CCCrypt 函数将使用硬件加速实现。 (这是由ioctling 和/dev/aes_0 完成的,顺便说一句。)

除了 AES,当输入大于 4096 字节时,SHA-1 也是硬件加速的。

【讨论】:

  • 你有任何指向 Apple 文档的链接吗?
  • @Bala: SHA-1: 有一个CC_SHA1_USE_HARDWARE_THRESHOLD = 4096 写在opensource.apple.com/source/CommonCrypto/CommonCrypto-36064/…; AES:不幸的是,它没有在任何地方记录,也没有发布任何源代码。你需要反汇编 libSystem.B.dylib 才能得到这个。
  • 谢谢。我不明白为什么苹果选择 4096 作为门槛。也许是硬件 SHA-1 芯片的极限?
  • @Bala:我认为这只是效率问题。与外部硬件通信不是免费的。
  • @KennyTM:很可能。我一直在尝试使用这个 API,但没有成功使用硬件加速 AES(即使我尝试加密的块大于 1024)。当我尝试单步执行 aes_cc_encrypt 时,我看到 (a) 我看到的代码与我在 opensource.apple.com/source/CommonCrypto/CommonCrypto-36064/… 看到的不匹配,并且 (b) 它没有采用“硬件”路径。您是否自己尝试过并让它发挥作用?
【解决方案2】:

API 的全部意义在于您无需关心支持它的实现细节。实现者(在本例中为 Apple)将使用在所使用的任何硬件上提供最佳性能和能源使用特性的任何实现。这可能是硬件实现,也可能是软件实现,这可能取决于您调用函数的块大小。

【讨论】:

  • “你不需要关心实现细节......” - goto fail 赢了!
【解决方案3】:

iPhone 是否支持硬件加速的 AES 加密?

这取决于 iPhone 版本和硬件,但在 2015 年大部分是 YES。

Apple 将其用于托管设备的快速“远程擦除”功能。这个想法是一切都被加密,并且密钥存储在由可擦除存储支持的密钥包中(“effaçable”是法语的“可擦除”)。如需更多信息,请参阅 Jean-Baptiste Bédrune 和 Jean Sigwald iPhone data protection in depth;还有 Dino Zavi 的 Apple iOS 4 Security Evaluation

电路放置在存储和内存之间的 DMA 数据路径上,因此任何穿过该路径的内容都会被加密或解密。

如果设备丢失或被盗,则可以向设备发送命令以擦除保存用于加密和解密的密钥的密钥包。因为钥匙包有可擦掉的存储空间,钥匙不会因为磨损均衡而移动。

Apple 似乎从 iOS 设备上的至少两个来源提供了硬件加速 AES。两者都由 Apple 的 CommonCrypto 框架包装。程序员似乎至少可以使用一个,而不需要 CommonCrypto。


第一个硬件加速源

第一个来源是 ARMv8 及更高版本中可用的标准 ARM 加密。当定义 __ARM_FEATURE_CRYPTO 时,这些指令既可以作为 C/C++ 内部函数使用,也可以作为程序集使用:

$ 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

顺便说一句,当__ARM_FEATURE_CRYPTO 被定义时,您应该也可以访问硬件加速的 SHA-1 和 SHA-2。


第二个硬件加速源

第二个来源似乎是自定义的,它存在于 ARMv7 及更低版本中。我不确定如何获得这个加密货币(也许opensource.apple.com 有答案):

$ 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

还有:

$ 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

一个相关的问题是Which hardware chip/vendor does Apple use for its hardware-accelerated AES/SHA-1 encryption?


这里有一些代码we are using for iOS。它测试 ARM Crypto 指令的运行时支持。因为代码是基于内在的,所以相同的代码用于 iOS、Linux、Windows Phone 和 Windows Store。在 iOS 的情况下,它在指定 -arch arm64 时使用。

#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
}

这是在编译期间从命令行看到的样子:

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.

【讨论】:

    猜你喜欢
    • 2016-05-12
    • 2015-10-04
    • 1970-01-01
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-27
    • 2013-02-14
    相关资源
    最近更新 更多