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库有几个子组件,例如:

  1. SSL协议库
  2. Crypto库(对称和非对称加密支持、摘要支持等)
  3. 证书管理

下图展示了OpenSSL的通用互连架构,以及与硬件加速驱动程序的接口:

在这里插入图片描述

OpenSSL的ENGINE接口

OpenSSL加密库提供对称和非对称(PKI)加密支持,被用于各种应用程序中,如OpenSSH、OpenVPN、PGP、IKE、XML-SEC等。OpenSSL加密库提供软件支持的功能有:

  1. 密码算法(Cipher algorithms)
  2. 摘要算法(Digest algorithms)
  3. 随机数生成(Random number generation)
  4. 公钥基础设施(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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值