Skip to content

JEP 246: Leverage CPU Instructions for GHASH and RSA | 利用 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 密码套件的一部分。

使用 pclmulqdq 在 Intel x64 上加速 GCM 的一部分 GHASH,在 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)应足以进行功能测试。将进行大量的性能测试,使用现有的基准测试和内部测试。