Nginx+Openssl+Intel QAT异步密码调用研究

caocao1年前教程228

在线wifi跑包 金刚包跑包 cap跑包 hccapx ewsa在线 就来 曹操wifi

各位好 又见面了 我是曹操 今天给大家带来一篇新的教程

希望各位细心学习 低调用网

握手包分析提取密码软件

在我们还在关注网络IO的时候,Intel已经在搞密码IO了。不得不说老外在技术上确实比较NB。国内的密码应用比老外还是差了一截。

前段时间基于openssl(版本比较老,好像是1.0.x吧,等我做完已经1.1.1了)开发了个SSL产品,稍微考虑和实现了一下密码计算的IO问题。

技术的创新(如果这也算的话)都是逼出来的,大致上都与性能有关。在开发时,采用的是流水线工作方式,一个线程绑定一个核(Tilera平台)。最后发现一个问题:CPU核不够用。为啥:一个核对应了一路硬件资源(加解密),要把所有的硬件资源用起来,CPU核不够了。

于是先解决SSL加解密核不够用的问题,想法很简单:加解密不能阻塞。SSL调用加解密后,立即返回,后面再继续往下做。这样,每个核可以对应多个加解密硬件资源,减少核需求。

那么,问题来了:

问题1:如何保存现场和恢复现场。怎么解决呢?现在想来还是有点幼稚(知识面还是窄),也很老土(后面有更好的方法),也是相当的麻烦,那就是:在SSL中添加数据结构,手工保存需要保存的一些变量。折腾了一下,也算完成。

问题2:什么时候去恢复现场?Openssl的SSLread和SSLwrite函数,在遇到网络IO时,会返回PENDING,然后需要用户二次调用。我也学它吧。修改源码,在加密和解密时会也返回一个ENC/DEC_PENGDING错误,加解密函数需要后面继续二次调用,才能完成。恢复现场的时机,在我这里其实变成了轮询。

当加解密搞完之后,本想把SSL握手过程也这么搞一遍。发现这是一个不可能完成的任务,因为握手里面的状态(以调用密码运算为分割点)太多了。

后来查了下网上的资料,发现intel已经搞定了。

如果密码接口这一层要改成异步的话,所有的上层调用都需要支持。

intel 提供QAT硬件,并开源了软件实现;openssl从1.1.0开始,支持异步,很好的解决了保存现场,恢复现场,以及何时去恢复现场的问题;intel 提供了qat的openssl引擎;intel为nginx做了修改,基于事件驱动,将openssl引擎用了起来,支持异步。

先说说intel的QAT是如何支持异步的。他所有的密码运算接口,都有一个回调函数和上下文。当密码运算完成时,该回调函数会被调用。在intel 的qat引擎中,该函数会写一个由eventfd创建的句柄,通知fd监视者,这样就解决了“恢复时机”的问题。

至于保存和恢复现场,由openssl的异步接口实现:ASYNCstartjob和ASYNCpause函数实现。ASYNCstartjob用于启动或者恢复任务。ASYNCpause用于纤程切换,在将数据发给硬件之后,调用 ASYNCpause,保存现场,返回到ASYNCstartjob,进而返回到上层。上层再次调用 ASYNCstartjob时,会恢复由ASYNCpause所保存的现场,继续往下执行。

如下图所示:

nginx+openssl+intel qat 过程如下:

1.nginx调用SSLaccept做握手,openssl用ASYNCstartjob启动握手过程,这时其实有个纤程切换,切换到具体的ssl握手函数; 2.握手函数执行硬件计算,调用qat引擎,最终调用qat的rsa密码函数(在之前会通过eventfd创建一个句柄)直接返回,然后调用ASYNCpause,执行纤程切换,由回到ASYNCstartjob调用的地方,返回上层SSLERRORWANTASYNC; 3.nginx发现密码运行处于pending状态,调用 ngxsslasyncprocessfds,将前面eventfd创建的句柄加入到epoll的监视集合;并将其事件设置为ssl握手; 4.硬件完成后,调用rsa密码函数设置的回调函数,write一下那个fd; 4.nginx监视到该fd可读,读出数据,继续调用握手函数,进而调用ASYNCstartjob恢复由ASYNCpause保存的现场,程序往下执行。

疑问:由于没有intel的qat硬件,自己模拟的intel 的qat的接口也没写完,从源码上分析了QAT的硬件引擎,发现它用eventfd创建fd时,先用固定id进行查找,找到了就直接用,找不到才创建。那么,当有两个SSL连接都调用了密码运算,如果共用一个fd的话,fd可读时,算谁的?按照我的理解,是否每个SSL连接都有一个独立的fd?

展望:intel的QAT看上去还是挺复杂的,需要制定一个类似pkcs11一样的比较简单的异步密码运算接口。目前主流的密码运算接口还都是阻塞式调用。在我实现的加解密接口中,参考了linux aio接口的命名方式。大致如下:

int AIOencrypt(aioctx *ctx); int AIOdecrypt(aioctx *ctx); int AIOreturn(aioctx *ctx); int AIOcancle(aioctx *ctx);

这里对内存有要求,输入输出内存必须是malloc出来的堆内存,以确保内存是有效内存。由于要支持加解密接口输入大数据,会多包发送,当有错误时,可通过AIO_cancle来取消后续的数据传输和计算(避免浪费硬件资源)。对于上下文的保存,可与硬件进行约定,预留8字节(void *),这样很容易恢复上下文(intel qat怎么做的不清楚)。

相关文章

Kali最新版下载安装教程(2022.3),虚拟机VirtualBox

Kali最新版下载安装教程(2022.3),虚拟机VirtualBox

在线wifi跑包 金刚包跑包 cap跑包 hccapx ewsa在线 就来 曹操wifi 各位好 又见面了 我是曹操 今天给大家带来一篇新的教程 希望各位细心学习 低调用网 最近我需要在Linux上...

NO.28——Kali Linux无线渗透暴力破解WIFI密码

NO.28——Kali Linux无线渗透暴力破解WIFI密码

在线wifi跑包 金刚包跑包 cap跑包 hccapx ewsa在线 就来 曹操wifi 各位好 又见面了 我是曹操 今天给大家带来一篇新的教程 希望各位细心学习 低调用网 # crunch 8 8...

WEF:一款功能强大的Wi-Fi安全测试框架

WEF:一款功能强大的Wi-Fi安全测试框架

在线wifi跑包 金刚包跑包 cap跑包 hccapx ewsa在线 就来 曹操wifi 各位好 又见面了 我是曹操 今天给大家带来一篇新的教程 希望各位细心学习 低调用网 git clone ht...

全新 Kali Linux 系统安装指南

在线wifi跑包 金刚包跑包 cap跑包 hccapx ewsa在线 就来 曹操wifi 各位好 又见面了 我是曹操 今天给大家带来一篇新的教程 希望各位细心学习 低调用网 Kali Linux 系...