
OpenSSL硬件加速实现

Hardware Offloading with OpenSSL
概述
安全套接字层(SSL: Secure Socket Layer)协议是应用最广泛的应用程序协议,通过使用流行的加密算法(如AES、DES和3DES)对数据进行加密来保护数据在传输过程中的安全。
除了加密以外,它还使用流行的哈希/摘要算法(如SHA1和MD5)提供消息认证服务。SSL广泛用于应用 Web 服务器(HTTP)和其他应用程序,如SMTP POP3、IMAP、代理服务器等,保护传输中的数据至关重要。
SSL协议有各种版本,如SSLv3、TLSv1.0、TLSv1.1、TLSv1.2、TLSv1.3 和 Datagram TLS(DTLS)。在所有SSL协议版本中,TLSv1.0 和 SSLv3 是常见的使用版本,并且其他版本也看到了更多的采用。
本文介绍了使用 OpenSSL 的 NXP QorIQ 平台上的 SSL 加速解决方案的架构。
OpenSSL软件架构
OpenSSL库有几个子组件,例如:
- SSL协议库
- Crypto库(对称和非对称加密支持、摘要支持等)
- 证书管理
下图展示了OpenSSL的通用互连架构,以及与硬件加速驱动程序的接口:
OpenSSL的ENGINE接口
OpenSSL加密库提供对称和非对称(PKI)加密支持,被用于各种应用程序中,如OpenSSH、OpenVPN、PGP、IKE、XML-SEC等。OpenSSL加密库提供软件支持的功能有:
- 密码算法(Cipher algorithms)
- 摘要算法(Digest algorithms)
- 随机数生成(Random number generation)
- 公钥基础设施(Public Key Infrastructure)
除了软件支持之外,OpenSSL可以通过 ENGINE 接口将这些功能卸载(offload)到硬件加速器上。ENGINE 接口提供回调钩子,将硬件加速器与加密库集成。这些回调钩子提供了与硬件加速器接口的粘合逻辑。通过 Linux 内核对密码和摘要算法的一般离线处理是可能的,这是通过 cryptodev 引擎实现的。
NXP的OpenSSL硬件卸载解决方案
NXP的OpenSSL硬件卸载解决方案中可以观察到以下层次结构:
- OpenSSL(用户空间)- 实现SSL协议
- cryptodev-engine(用户空间)- 实现OpenSSL ENGINE接口;通过ioctl与cryptodev-linux(/dev/crypto)通信,在内核中卸载密码操作
- cryptodev-linux(内核空间)- Linux模块,将来自cryptodev-engine的ioctl请求转换为对Linux Crypto API的调用
- Linux Crypto API(内核空间)- Linux内核密码抽象层
- CAAM驱动程序(内核空间)- CAAM(Cryptographic Acceleration and Assurance Module)加密引擎的Linux设备驱动程序
以下是当前SDK中可以在硬件中卸载的功能(不完整列表):
-
SSL:TLS v1.0与一次性密码模式(一个ioctl可同时进行加密和认证):
- AES128-SHA
- AES256-SHA
-
加密算法:
- AES-CBC
- 3DES
-
摘要算法:
- MD5
- SHA1
- SHA256
-
公钥算法:
- RSA
手动构建支持Cryptodev引擎的OpenSSL
这个章节是可选的,因为根文件系统可以被配置为自动包含 OpenSSL 和 cryptodev。
$ cd flexbuild
$ source setup.env
Build cryptodev-linux:
$ flex-builder -c cryptodev_linux -a arm64 # automatically setup cross-toolchain and fetch cryptodev-linux repository to build
Build OpenSSL:
$ flex-builder -c openssl -a arm64
Merge OpenSSL and cryptodev-linux components into target rootfs:
$ flex-builder -i merge-component -a arm64
Generate bootpartition tarball:
$ flex-builder -i mkbootpartition -a arm64
按照 flexbuild 文档,在主机系统上完成根文件系统和内核的构建。
手动构建
出于各种原因,可能需要手动构建或重新构建。本节描述了如何在目标系统上本地构建和安装 OpenSSL。交叉构建过程需要适当的工具链,这里不进行描述。
需要同时安装 OpenSSL 和 cryptodev,因为它们彼此依赖:
$ git clone https://source.codeaurora.org/external/qoriq/qoriq-components/openssl
$ git clone https://source.codeaurora.org/external/qoriq/qoriq-components/cryptodev-linux
构建 cryptodev 并可选择运行自测:
$ cd cryptodev-linux
$ make
$ sudo make install
$ sudo modprobe cryptodev
$ make check
构建支持 cryptodev 的 OpenSSL:
$ cd openssl
$ ./Configure -DHAVE_CRYPTODEV --prefix=/usr/local/ --openssldir=/usr/local/openssl linux-aarch64 shared
$ make
$ sudo make install
安装后,请验证二进制文件是否与 /usr/local/lib 中的正确共享库链接。
$ ldd /usr/local/bin/openssl
如果二进制文件与 /usr/lib 中的原始库链接,则可能需要调整链接器路径。将 /usr/local/lib 放在 /etc/ld.so.conf 中的 /usr/lib 之前,并更新链接器缓存:
文件:/etc/ld.so.conf
...
/usr/local/lib
...
/usr/lib
...
$ sudo ldconfig
$ ldd /usr/local/bin/openssl
OpenSSL 中的硬件卸载
概述
OpenSSL 可通过引擎接口将加密操作委托给各种硬件设备进行执行。在该接口之上实现的引擎 cryptodev 可用于将加密操作卸载(offload)到由操作系统内核控制的硬件设备上。Cryptodev 引擎最初是为 OpenBSD 开发的,后来相同的 API 被移植到 GNU/Linux 操作系统,通过 OCF 和 cryptodev-linux 等多个驱动程序来实现。
Cryptodev-linux 是一个 Linux 内核驱动程序,通过设备文件 /dev/crypto 将内部加密 API 暴露给用户空间。用户空间应用程序使用 ioctl 系统调用来要求 Linux 内核代表它们执行加密操作。Linux 内核通过在 CPU 上运行的软件实现支持多种加密算法。硬件加速器的驱动程序具有更高的优先级,并且在不需要进一步配置的情况下即可覆盖软件实现。
从任何应用程序的角度来看,都会透明地使用算法的最快实现。这种行为也转移到了 cryptodev 接口,该接口不知道算法可能在 CPU 或硬件加速器上运行的事实。因此,在运行应用程序之前,确保硬件内核驱动程序可用是应用程序操作员的工作。
简而言之,如果 NXP SEC 驱动程序未内建于内核中,则简单地运行 modprobe 即可:
# modprobe caamalg
# modprobe caamhash
# modprobe caam_pkc
NXP 平台具有多个 SEC 前端,使用不同的设备驱动程序公开:JRI(job ring), QI(queue interface), DPSECI。请参见平台和SEC指南以获取可用的Linux内核驱动程序。通常,对于任何平台,至少应该可用JR驱动程序。
对于QI前端,对称加密算法有一个名为caamalg_qi的内核模块。此驱动程序安装的算法的优先级低于caamalg,因此它们将被后者遮盖。要使用QI前端,请加载此驱动程序而不是caamalg:
# modprobe caamalg_qi
DPSECI 前端还有另一个驱动程序叫做 caamalg_qi2,目前通常始终内建于内核中。有一些简单的步骤可以确认加密硬件驱动程序是否可用。运行这些步骤有助于获得流畅的体验,如果有问题出现,也更容易进行调试。
Linux 内核可以通过 tcrypt 模块来检查和报告密码算法的可用性。在探测 tcrypt 后,加密算法将列在 /proc/crypto 中。Tcrypt 模块并不总是可用于默认内核,但它是一种简单的方法来运行测试并列出所有可用的加密算法:
$ modprobe tcrypt
$ grep aes /proc/crypto
<...>
如果CAAM设备驱动程序没有内建,则加载它们,并检查它们的中断计数:
# modprobe caamalg (or caamalg_qi)
# modprobe caamhash
# modprobe caam_pkc
<...>
# grep tls /proc/crypto
name : tls10(hmac(sha1),cbc(aes))
driver : tls10-hmac-sha1-cbc-aes-caam-qi
# grep rsa /proc/crypto
<...>
可以使用CAAM JR和QI(DPAA和DPAA2)接口的中断计数器来监视硬件操作:
# cat /proc/interrupts | grep jr
88: 0 0 0 0 26 0 0 0 OpenPIC 88 Level ffe301000.jr
89: 0 0 0 0 0 1117204 0 0 OpenPIC 89 Level ffe302000.jr
90: 0 0 0 0 0 0 24 0 OpenPIC 90 Level ffe303000.jr
91: 0 0 0 0 0 0 0 24 OpenPIC 91 Level ffe304000.jr
# cat /proc/interrupts | grep -i qman
108: 0 0 0 0 0 0 0 7508 OpenPIC 108 Level QMan portal 7
110: 0 0 0 0 0 0 7524 0 OpenPIC 110 Level QMan portal 6
112: 0 0 0 0 0 7542 0 0 OpenPIC 112 Level QMan portal 5
114: 0 0 0 0 7565 0 0 0 OpenPIC 114 Level QMan portal 4
116: 0 0 0 7576 0 0 0 0 OpenPIC 116 Level QMan portal 3
118: 0 0 7524 0 0 0 0 0 OpenPIC 118 Level QMan portal 2
120: 0 7535 0 0 0 0 0 0 OpenPIC 120 Level QMan portal 1
122: 7521 0 0 0 0 0 0 0 OpenPIC 122 Level QMan portal 0
470: 0 0 0 0 0 0 0 0 OpenPIC 2006 Edge qman-err
# cat /proc/interrupts | grep DPIO
<...>
中断计数器可能也会在与加密无关的网络操作期间增加。需要进一步分析以了解它们修改的来源。
加载 cryptodev 驱动程序并检查 OpenSSL 是否与其通信。如果未加载 cryptodev 驱动程序,则 OpenSSL 仅会报告动态引擎支持,并且所有操作都将由 OpenSSL 自身在软件中完成。
# openssl engine
(dynamic) Dynamic engine loading support
# modprobe cryptodev
# ls /dev/crypto
<...>
# openssl engine
(cryptodev) BSD cryptodev engine
(dynamic) Dynamic engine loading support
Offloading 对称和公钥算法
注意:
在LSDK中不支持Cipher AES128-SHA和AES256-SHA。
加载 cryptodev 和 SEC 驱动程序后,OpenSSL 运行通过硬件加速器进行加密操作时不需要其他配置。如果可用,OpenSSL 将自动使用 cryptodev 引擎。一些与 OpenSSL 链接的应用程序(如OpenSSH)将自动使用可用的加速器。其他一些应用程序(如nginx web服务器)可能需要在其配置文件中明确启用加速。
# modprobe cryptodev
# openssl speed -evp AES128-SHA -elapsed
<...>
# openssl speed rsa1024
<...>
在Nginx服务器中进行TLS 1.0 Offloading
Nginx默认情况下不使用任何 OpenSSL 引擎。如果要使用引擎,包括 cryptodev,它必须明确列在nginx配置文件中。以下是一个激活 cryptodev 并允许硬件加速 TLS1.0 记录层协议(record layer protocol)的 nginx 配置文件片段:
/etc/nginx/nginx.conf:
ssl_engine cryptodev;
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000; #for 4 Core CPU; For 2 Core CPU worker_cpu_affinity 01 10;
...
# HTTPS server
#
server {
listen 443;
server_name localhost;
ssl on;
ssl_certificate server.crt;
ssl_certificate_key server.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1;
ssl_ciphers AES128-SHA:AES256-SHA;
ssl_prefer_server_ciphers on;
location / {
root /var/www/localhost/html;
index index.html index.htm;
}
}
...
工作进程和亲和性(affinity )应根据平台上可用的CPU核数进行设置。有关更多详细信息,请参阅nginx文档。
TLS1.0 记录层测试
我们将只使用OpenSSL功能来验证TLS记录层(record layer)的加速。
首先创建服务器要使用的RSA公钥和私钥:
$ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
启动HTTPS网络服务器:
# modprobe cryptodev
$ openssl s_server -key key.pem -cert cert.pem -accept 44330 -www -cipher AES128-SHA -tls1
然后使用另一个控制台上的客户端连接到它:
$ openssl s_client -connect localhost:44330
(or)
$ echo "GET /" | openssl s_client -connect localhost:44330 -quiet
就像其他测试一样,可以通过列出 SEC 驱动程序的中断计数器来验证硬件卸载(hardware offloading)。
Ref:
https://docs.nxp.com/bundle/GUID-1441E561-3EAD-47FD-A50D-72E1A4E4D69E/page/GUID-4E6E5B15-46BC-4B7B-9AA3-ED8B0CC19EBF.html
https://docs.nxp.com/bundle/GUID-1441E561-3EAD-47FD-A50D-72E1A4E4D69E/page/GUID-884DEAE3-F0E3-4E42-801C-962B79008865.html
https://docs.nxp.com/bundle/GUID-1441E561-3EAD-47FD-A50D-72E1A4E4D69E/page/GUID-A27456AE-E398-4E11-ACC9-4FC468141E0D.html




更多推荐
所有评论(0)