openssl中关于Engine的用法与相关知识

Engine是OpenSSL中用以封装不同的下层密码学引擎的核心框架。所有的引擎的创建都以ENGINE *engine = ENGINE_new(); 开始。ENGINE引擎并不会提供所有的密码学变换,而是提供了一个大部分常用的密码学的封装替换功能,也就是说在ENGINE支持的范围内,密码学的功能是可以被动态替换的,这个替换的方式可以使用so库文件在运行时动态加载,并且究竟加载哪一个ENGINE,是可以通过OpenSSL的配置文件来配置的。

RSA_METHOD,DSA_METHOD, DH_METHOD, RAND_METHOD, ECDH_METHOD, ECDSA_METHOD:这些算法的替代实现

EVP_CIPHER - 对称加密算法的替代实现

EVP_DIGEST - 哈希算法的替代实现

key-loading :私钥公钥证书等加载算法的替代实现

ENGINE结构体生成了并不代表就存在了。因为Engine对应的是一个so库文件和其他的内置ENGINE。so文件在调用了ENGINE_new函数之后也并没有加载,而是在调用了ENGINE_init()才会去正式的加载对应的库文件。所以实际上创建的ENGINE只是一个结构体层面的ENGINE,ENGINE真的要生效还要等到使用ENGINE_add()函数实际的加载和装载进内部的结构体。OpenSSL的内部维护了一个ENGINE的链表,使用ENGINE_get_next() 可以遍历这个链表。

即使不使用ENGINE引擎,整个OpenSSL也是可以正常工作的,只是使用的对应的算法都是软件实现的效率比较低的算法。通常一个引擎的出现都是为了提高效率。不同的引擎下面会挂载很多对不同的算法的不同的实现方法,这些方法都是通过OpenSSL的nid子系统进行区分。使用OpenSSL的一个很重要的一直要有理解的就是nid子系统。相当于OpenSSL的内部数据库。ENGINE子系统永远是给外部提供使用的,这一点很重要,因为虽然OpenSSL的内部理论上也是存在ENGINE,也是提供很多种实现,但是实际在编译的时候都是静态的编译进OpenSSL的,ENGINE引擎的接口只是提供给需要动态加载的外部so文件使用的。所以外部的硬件驱动开发者可以开发一个so文件的ENGINE,修改OpenSSL的配置就可以达到让OpenSSL使用自己开发的ENGINE的目的,从而完成卸载加密操作的需求。例如Intel的QAT硬件加速卡就是用的这种方式提供的OpenSSL的ENGINE驱动的。

ENGINE引擎子系统对每一种密码学算法都有一些特定的默认实现,有一个初始化函数,在解析配置的时候触发,这个函数是ENGINE_load_builtin_engines。这个函数实际上调用的是OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN, NULL); 就是加载了几乎所有的使用nid注册密码学算法。这样在程序使用的时候可以获得到的默认密码学算法就可以根据当前的CPU flag或者其他的条件进行选择了。

以下是一个Intel QAT的代码片段。

CpaInstanceHandle get_next_inst(void)

{

CpaInstanceHandle instance_handle = NULL;

ENGINE* e = NULL;

if (1 == enable_instance_for_thread) {

instance_handle = pthread_getspecific(qatInstanceForThread);

if (instance_handle == NULL) {

WARN("No thread specific instance is available\n");

return instance_handle;

}

}

e = ENGINE_by_id(engine_qat_id);

if(e == NULL) {

WARN("Function ENGINE_by_id returned NULL\n");

instance_handle = NULL;

return instance_handle;

}

if(!qat_engine_init(e)){

WARN("Failure in qat_engine_init function\n");

instance_handle = NULL;

ENGINE_free(e);

return instance_handle;

}

ENGINE_free(e);

if (instance_handle == NULL)

{

if (qat_instance_handles) {

instance_handle = qat_instance_handles[curr_inst];

incr_curr_inst();

} else {

WARN("No instances are available\n");

instance_handle = NULL;

}

}

return instance_handle;

}

可以看到在qat的驱动中是直接调用的ENGINE_by_id来获得QAT ENGINE的句柄。engine_qat_id的内容是一个字符串”qat”,显然的这个字符串会提前的配置到OpenSSL的配置文件中。当OpenSSL在解析配置文件的时候,就会解析到这个引擎的信息,然后会加载该引擎到OpenSSL的上下文。当调用到驱动的初始化函数的时候,这个ENGINE已经在OpenSSL中加载好了。这里开始对其进行QAT相关的初始化。qat_engine_init就是完成这件事情的。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值