译|王祖熙(花名:金九 )
蚂蚁集团开发工程师
负责国产化密码库 Tongsuo 的开发和维护
专注于密码学、高性能网络、网络安全等领域
本文 2179 字 阅读 6 分钟
本文翻译 OpenSSL 官网文档:https://www.openssl.org/docs/OpenSSL300Design.html
Tongsuo-8.4.0 是基于 OpenSSL-3.0.3 开发,所以本文对 Tongsuo 开发者同样适用,内容丰富,值得一读!
今天带来的是 OpenSSL 3.0.0 设计最后一部分内容 《遗留问题、遗留 Provider 模块、ENGINE API》 ,已发布文章可查看文章列表。
遗留问题
EVP 到低级 API 的桥接
在某些地方,低级 API 结构被赋值给EVP_PKEY
对象,对公共的EVP_PKEY
的影响是它必须保留指向可能的低级结构的指针,并且在 libcrypto 内部必须知道该低级结构的类型,每当具有这种指针的EVP_PKEY
用于任何计算时,都必须检查低级结构是否发生了变化,并将其数据转换为可以与新的 Provider 一起使用的参数。
确定如何检查低级结构的内容是否发生了变化的具体机制有待确定,一种可能的方法是在低级结构中设置一个 dirty 计数器,并在EVP_PKEY
结构中复制一个副本,每当低级结构发生变化时(例如,RSA_set0_key
等函数必须执行递增操作),每当EVP_PKEY
用于计算时,就会将其副本与低级脏计数器进行比较,如果它们不同,则EVP_PKEY
的 Provider 参数将使用低级结构的数据进行修改。
(另一个想法是通过遗留函数在EVP_PKEY
中放置一个回调函数,如果检测到低级别的更改,则更新参数)
EVP方法创建者
在 OpenSSL 1.1.x 中有可以轻松创建各EVP
方法结构的功能,可以像这样找到:
grep EVP_CIPHER_meth util/libcrypto.num
grep EVP_MD_meth util/libcrypto.num
grep EVP_PKEY_meth util/libcrypto.num
相关类型
低级 API 相当独立,因此除了在某些类型中添加了一个 dirty 标志外,所有低级 API 类型将保持不变。关联的EVP_CIPHER
、EVP_MD
、EVP_PKEY_METHOD
、EVP_MAC
或EVP_KDF
实例通过在遗留 Provider 模块中通过实现调度表来单独处理(见下文)。
遗留 Provider 模块
一些被认为是“遗留”的算法(例如 IDEA)且具有当前的EVP_CIPHER
、EVP_MD
、EVP_PKEY_METHOD
、EVP_MAC
或EVP_KDF
实现将移至一个名为 “Legacy” 的 Provider 模块,而不是我们的默认 Provider 模块。
以下算法的方法将成为“Legacy”Provider 模块中的调度表:
- Blowfish
- CAST
- DES(但不包括3DES)
- DSA
- IDEA
- MD2
- MD4
- MDC2
- RC2
- RC4
- RC5
- RIPEMD160
- SEED
- Whirlpool
(注意:这不是一个详尽无遗的列表,尽管对目前来说相当完整)
ENGINE API
整个 ENGINE API 将在此版本之后的主要发布中被弃用和移除,到那时,人们必须学会如何创建 Provider 模块。与此同时,它将被转变为一个工具,帮助实现者从 ENGINE 模块实现过渡到 Provider 模块实现。
由于算法构造函数将被更改为构造调度表,因此 ENGINE 类型将变为一组调度表,并且 ENGINE 构造函数的功能将更改为将它们收集到给定的 ENGINE 中。
通过这种注册方式注册的调度表将添加一个名为 “engine” 的属性,并将 ENGINE 标识作为 Provider 名称属性。这将使ENGINE_by_id
和类似功能能够找到正确的 Provider。
ENGINE 模块的入口点 bind_engine 将被替换为 Provider 模块的入口点,并且宏IMPLEMENT_DYNAMIC_BIND_FN
将被更改为构造此类入口点。此入口点将创建一个类似 Provider 的 ENGINE 结构,调用绑定函数,该函数将使用与之前相同的方法创建函数将其填充到调度表中,然后使用与以前相同的方法设置函数将所有这些收集到的调度表在 ENGINE 结构中注册,就像任何 Provider 模块一样。
与此版本的其余部分一样,我们的目标是源代码级的兼容性。
在 OpenSSL 1.1.x 及更早版本中,可以使用诸如ENGINE_get_default_RSA
和ENGINE_get_RSA
等函数,将 ENGINE 提供的方法挂钩以替代内置于 libcrypto 中的函数,前者无需修改,而后者将被更改为根据附加到引擎的相应调度表创建旧式方法(例如RSA_METHOD
)。
附录与备注部分内容请直接查看铜锁语雀: