JEP 246:利用 CPU 指令进行 GHASH 和 RSA 运算
概述
通过利用最近引入的 SPARC 和 Intel x64 CPU 指令,提升 GHASH 和 RSA 加密操作的性能。
成功指标
JDK 8 中包含的对 AES-CBC 的支持(参见 JEP 164)显示出比纯软件实现大约有 8 倍的性能提升。不同的算法会有所不同,但我们应该能看到类似的显著性能提升。
动机
我们越少使用原生库(例如 PKCS#11),因与复杂的原生 API 交互而引发的复杂代码和内存问题就越少。对原生库的 JNI 调用越少,加密操作的速度就越快。通过直接在 JVM 中实现加密操作,我们可以通过内置的提供程序来控制它们的实现和管理,从而提供开箱即用的支持。
描述
不会修改或扩展现有的 API。
算法
现有的实现会在 HotSpot 中调用 AES 指令(当这些指令被支持时)。除了 CBC 模式外,还有一些优化措施可以帮助 AES 和 CBC 快速协同工作。这些指令和优化取代了当前的 SunJCE 字节码方法。计划是为 GCM 和 RSA 实现类似的优化,这两者都可以从硬件辅助中获益良多。AES-GCM 和 RSA 都是 TLS 密码套件的一部分。
GHASH 是 GCM 的一部分,在 Intel x64 上将使用 pclmulqdq
进行加速,在 SPARC 上则使用 xmul
/xmulhi
。
通过使用位操作指令集 2,RSA 将得到加速。其他非对称算法很可能也会从这些更改中受益,但它们将通过 RSA 进行衡量。鉴于 montmul
和 montsqr
指令的复杂性和局限性,未添加 SPARC 指令。使用原生库可以在不带来负面影响的情况下提供完整的 RSA 功能。此外,由于 RSA 是一项较慢的操作,JNI 和原生 API 层在整体性能表现中可能影响较小。
提供者
算法的管理是一个随着时间的推移变得越来越复杂的重要问题。一个极端的情况是 Solaris 的默认提供程序配置。在提供程序列表中,SunPKCS11 提供程序排在 SunJCE 之前。SunPKCS11 提供程序支持 Solaris 所有硬件加速和优化的算法。要使用 JDK 8 的 AES-CBC 支持,必须将 SunJCE 移到 SunPKCS11 之前。对于只需要 AES-CBC 的应用程序(例如性能测试),不需要其他算法,所以这样可行。然而,对于使用多种算法的应用程序,其他算法将运行基于软件的非加速实现,而不是来自 SunPKCS11 的硬件加速实现。当使用 NSS(通过 SunPKCS11 提供程序配置)时,其他操作系统也可能存在这个问题。
因此,java.security
文件中新增了一项安全属性 jdk.security.provider.preferred
,用于在检查有序提供者列表之前,将某些算法和算法组定向到特定的提供者。该属性专为高级用户设计,默认情况下并未设置。由于当前使用中的 x86 和 SPARC CPU 存在许多不同版本,若设置默认值,可能会导致较旧系统出现性能下降,并且随着新 CPU 提供更多支持,还需要持续维护。此外,现有的 JDK 配置(如 FIPS 140 或其他专用提供者)可能会在不知情的情况下被导向不同的提供者。因此,默认情况下最好不设置 jdk.security.provider.preferred
属性,但允许供应商和高级用户根据其 CPU 支持情况自行设置该属性。
测试
现有的已知答案测试(KAT)应足以进行功能测试。将使用现有的基准和内部测试进行大量的性能测试。