背景
KAE(Kunpeng Accelerate Engine)加解密是鲲鹏处理器提供的硬件加速方案,可以显著降低处理器消耗,提高处理器效率。毕昇 JDK 基于 JCA 框架,为用户提供使用 KAE 来进行加解密的 KAEProvider,用户只需要在 java.security 文件中进行配置,或者简单修改代码即可使用 KAE 带来的加速效果,使用方便,更多的 KAEProvider 介绍可以参考 《毕昇 JDK8 支持鲲鹏硬件加解密特性详解和使用介绍》。目前 KAEProvider 对于 kae openssl 引擎支持较好,对于其他的 openssl 引擎(例如 uadk_engine [1] )支持还有待完善。KAEProvider 先前版本存在如下待优化点:
-
kaeprovider.conf 文件不支持用户自定义路径。
-
kae 引擎加载日志不支持用户自定义路径。
-
KAEProvider 将 openssl 引擎名称固定为 kae,无法直接使用其他 openssl 引擎(如uadk_engine)。
-
uadk_engine 引擎编译时未链接 libcryto.so,执行 ENGINE_by_id 函数过程中找不到 libcryto 相关函数符号,导致获取 uadk_engine 引擎失败。
-
KAEProvider 实现的每个算法固定使用 openssl 软算或使能 KAE 硬件加速其中的一种。以 AES 算法为例,openssl 软算性能比硬件加速高,目前 KAEProvider 实现的 AES 固定使用 openssl 软算,随着硬件升级以及硬件算法优化,当 AES 硬件加速效果比软算性能高时,用户使用 AES 进行加解密时无法切换到 KAE 硬件加速。
-
不同引擎支持的硬件加速算法不同,kae 支持的算法[2]和 uadk 支持的算法[3]不一样,kae 引擎不支持 SHA256 算法,而 uadk_engine 引擎支持。由于 KAEProvider 实现的 SHA256 算法固定使用 openssl 软算,用户在使用 uadk_engine 引擎时无法使用硬件加速功能。
-
使用 SM4 算法加密或解密 MappedByteBuffer 数据时,每次只能处理 4096 字节数据,数据量太小,KAE 硬件加速效果不明显。
新增功能介绍
- 配置 KAEProvider 调试日志
增强JDK原有的 java.security.debug 系统属性,将其值配置为 kae 时,打印 KAEProvider 调试日志,方便用户开发调试。
java -Djava.security.debug=kae ProviderTest
- 配置 kaeprovider.conf 路径
原先 kaeprovider.conf 存放在 jre/lib/ext 目录,本次易用性增强变更路径为 jre/lib 目录,同时新增系统属性 kae.conf,支持用户自定义 kaeprovider.conf 路径。
java -Djava.security.debug=kae -Dkae.conf=/home/user/kaeprovider.conf ProviderTest
- 配置引擎加载日志路径
新增属性 kae.log.file,支持用户自定义引擎加载日志。
(1)引擎加载日志路径
java -Djava.security.debug=kae -Dkae.log=true -Dkae.log.file=/home/user/logs/kae.log ProviderTest
引擎加载日志解读
日志
描述
uadk_engine engine was found
表示使用的是 uadk_engine
Non-KAEProvider
表示打印的算法不使用 KAEProvider,而是使用 JDK 实现的算法
KAEProvider
表示打印的算法使用 KAEProvider
Use openssl soft calculation
表示打印的算法使用 openssl 软算
enable KAE hardware acceleration
表示使用鲲鹏硬件加速
java -Dkae.log=true -Dkae.log.file=/home/xiezhaokun/logs/kae.log -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.md5=false ProviderTest
- 指定 openssl 引擎 id
新增属性 kae.engine.id,支持用户指定 openssl 引擎 id。新增属性 kae.libcrypto.useGlobalMode 支持用户配置加载 libcrypto 使用是 dlopen RTLD_GLOBAL 模式还是 RTLD_LOCAL 模式。dlopen 的 RTLD_GLOBAL 模式和 RTLD_LOCAL 模式说明可以参考dlopen(3) — Linux manual page[4]。
java -Dkae.log=true -Dkae.log.file=/home/xiezhaokun/logs/kae.log -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true ProviderTest
- 配置是否使能 KAE 引擎硬件加速
新增属性 kae.[algorithm].useKaeEngine 开启或禁用某类算法使用硬件加速,其中 algorithm 为 digest、aes、sm4、hmac、rsa、dh、ec。新增属性 kae.engine.disabledAlgorithms 批量禁用某些特定算法使用硬件加速。
(1)默认情况
java -Dkae.log=true -Dkae.log.file=/home/xiezhaokun/logs/kae.log -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true ProviderTest
(2)通过 kae.[algorithm].useKaeEngine 属性开启或禁用某类算法
例如:禁用摘要算法使用硬件加速、使能hmac算法使用硬件加速
java -Dkae.log=true -Dkae.log.file=/home/xiezhaokun/logs/kae.log -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.digest.useKaeEngine=false -Dkae.hmac.useKaeEngine=true ProviderTest
(3)通过 kae.engine.disabledAlgorithms 属性禁用某些特定算法使用硬件加速
例如:禁用md5、sm3算法使用硬件加速
java -Dkae.log=true -Dkae.log.file=/home/xiezhaokun/logs/kae.log -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=“md5,sm3” ProviderTest
- 配置 SM4 算法每次处理 MappedByteBuffer 数据块大小
用户使用 SM4 算法加密或解密 MappedByteBuffer 数据时,每次只能处理 4096 字节数据。本次易用性增强新增属性 kae.sm4.maxChunkSize,支持用户自定义使用 SM4 加密或解密 MappedByteBuffer 数据时每次处理的数据块大小。
java -Djava.security.debug=kae -Dkae.sm4.maxChunkSize=65536 SM4Test
测试用例代码
ProviderTest.java
import org.openeuler.security.openssl.KAEProvider;
public class ProviderTest {
public static void main(String[] args) {
new KAEProvider();
}
}
SM4Test.java
import org.openeuler.security.openssl.KAEProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
import java.security.Security;
public class SM4Test {
private static byte[] sourceBytes = “test”.getBytes();
static SecretKeySpec secretKey = new SecretKeySpec(“sm4EncryptionKey”.getBytes(), “SM4”);
public static void main(String[] args) throws Exception {
Security.insertProviderAt(new KAEProvider(), 1);
ByteBuffer input = ByteBuffer.allocateDirect(sourceBytes.length);
input.put(sourceBytes);
input.flip();
ByteBuffer output = ByteBuffer.allocateDirect(sourceBytes.length + 16);
Cipher cipher = Cipher.getInstance(“SM4”);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
cipher.update(input, output);
cipher.doFinal();
output.clear();
input.clear();
}
}
属性配置一览表
原先的KAEProvider只支持kaeprovider.conf属性配置,本次易用性增强新增支持系统属性配置功能。
- kaeprovider.conf 属性
(1)历史版本支持的属性
kae.[algorithm] 、kae.log 属性为 8u342 之前版本支持的属性,新版本也支持。kae.[algorithm] 属性配置某个算法是否使用 KAEProvider,true 表示使用 KAEProvider ,false 表示使用 JDK 软算。kae.log 属性用于配置是否开启引擎加载的日志记录,具体描述见如下表格:
属性名
值类型
默认值
描述
kae.md5
boolean
true
配置 md5 是否使用 KAEProvider
kae.sha256
boolean
true
配置 sha256 是否使用 KAEProvider
kae.sha384
boolean
true
配置 sha384 是否使用 KAEProvider
kae.sm3
boolean
true
配置 sm3 是否使用 KAEProvider
kae.rsa
boolean
true
配置 rsa 是否使用 KAEProvider
kae.aes
boolean
true
配置 aes 是否使用 KAEProvider
kae.sm4
boolean
true
配置 sm4 是否使用 KAEProvider
kae.hmac
boolean
true
配置 hmac 是否使用 KAEProvider
kae.dh
boolean
true
配置 dh 是否使用 KAEProvider
kae.ec
boolean
true
配置 ec 是否使用 KAEProvider
kae.log
boolean
true
配置是否开启引擎加载的日志记录
(2)本次易用性增强新增的属性
kae.[algorithm].useKaeEngine 属性配置某个算法是否使用 kae engine 使能 KAE 硬件加速,true 表示使用 kae engine 使能 KAE 硬件加速,false 表示使用 openssl 软算。当属性 kae.[algorithm] 值为 true 时,属性 kae.[algorithm].useKaeEngine 才会生效。
属性名
值类型
默认值
描述
kae.digest.useKaeEngine
boolean
TRUE
配置 digest 算法是否使能 KAE 硬件加速
kae.aes.useKaeEngine
boolean
FALSE
配置 aes 算法是否使能 KAE 硬件加速
kae.sm4.useKaeEngine
boolean
TRUE
配置 sm4 算法是否使能 KAE 硬件加速
kae.hmac.useKaeEngine
boolean
FALSE
配置 hmac 算法是否使能 KAE 硬件加速
kae.rsa.useKaeEngine
boolean
TRUE
配置 rsa 算法是否使能 KAE 硬件加速
kae.dh.useKaeEngine
boolean
TRUE
配置 dh 算法是否使能 KAE 硬件加速
kae.ec.useKaeEngine
boolean
FALSE
预留属性,配置 ec 算法是否使能 KAE 硬件加速(Kunpeng 920 暂时不支持 EC 算法,kae.ec=true 时,EC 算法仍然使用 openssl 软算)
kae.engine.disabledAlgorithms
String
sha256,sha384
通过该属性配置批量禁用某些特定算法,默认禁用 sha256,sha384 算法,属性可选值如下:md5,sha1,sha224,sha256,sha384,sha512,sm3,aes-128-ecb,aes-128-cbc,aes-128-ctr,aes-128-gcm,aes-192-ecb,aes-192-cbc,aes-192-ctr,aes-192-gcm,aes-256-ecb,aes-256-cbc,aes-256-ctr,aes-256-gcm,sm4-ecb,sm4-cbc,sm4-ctr,sm4-ofb,hmac-md5,hmac-sha1,hmac-sha224,hmac-sha256,hmac-sha384,hmac-sha512,rsa,dh,ec
kae.log.file
String
${user.dir}/kae.log
配置引擎加载的日志路径
kae.sm4.maxChunkSize
int
4096
配置使用 SM4 算法加密/解密 MappedByteBuffer 数据时每次处理数据块大小限制(当配置的属性值为非正整数或者超过 Integer 大小范围时使用默认值 4096)
kae.engine.id
String
kae
配置使用的引擎 id
kae.libcrypto.useGlobalMode
boolean
FALSE
配置加载 libcrypto 使用是 dlopen RTLD_GLOBAL 模式还是 RTLD_LOCAL 模式,true 表示使用使用 RTLD_GLOBAL 模式,false 表示使用 RTLD_LOCAL 模式。uadk_engine 时需要该属性值设置为 true
- 系统属性
系统属性的优先级高于 kaeprovider.conf 属性。系统属性除了支持上述的 kaeprovider.conf 属性,同时还新增如下属性配置:
属性名
值类型
默认值
描述
kae.conf
String
jre/lib/kaeprovider.conf
配置 kaeprovider.conf 文件路径
java.security.debug
String
JDK 支持的系统属性,本次新增属性值 kae,打印 KAEProvider 加载的 debug 日志
参考
-
https://gitee.com/openeuler/uadk_engine
-
https://github.com/kunpengcompute/KAE
-
https://docs.openeuler.org/zh/docs/22.03_LTS/docs/UADK/UADK-quick-start.html
-
https://man7.org/linux/man-pages/man3/dlopen.3.html
编者按:毕昇JDK 8u352 版本已发布,其中 KAEProvider 易用性增强作为新特性为用户提供丰富的配置,让 KAEProvider 更好地兼容其他 openssl 引擎,方便用户快速使用鲲鹏处理器提供的硬件加速能力,提升用户的开发效率。
原文链接:https://www.hikunpeng.com/zh/developer/techArticles/20230818-2