如何让OpenSSL复用输入缓冲区存储CMS结构以减少内存分配?
CMS签名验证的内存优化:复用输入缓冲区可行吗?
针对内存受限的嵌入式设备场景,现有CMS签名验证代码存在两次内存分配:d2i_CMS_ContentInfo分配的CMS结构内存,以及验证通过后为拷贝内容分配的内存。关于是否能让OpenSSL直接复用输入缓冲区,结论如下:
核心结论
OpenSSL无法直接使用输入缓冲区存储解析后的CMS结构,原因在于:
d2i_CMS_ContentInfo这类ASN.1解析函数的工作逻辑是对输入的DER编码数据进行解码、结构重组,最终生成独立的CMS_ContentInfo内存结构,输入缓冲区的原始格式与内部结构布局完全不匹配;- 解析过程中需要对数据做格式转换、字段提取等操作,无法直接复用原始输入缓冲区的内存空间。
内存优化方案
虽然不能复用输入缓冲区,但可以通过以下方式消除冗余内存开销:
1. 消除二次内存拷贝
验证通过后无需额外分配内存再拷贝内容,直接使用CMS_get0_content返回的原始数据指针即可——只要cms对象未被释放,该指针就保持有效。优化后的代码示例:
CMS_ContentInfo *cms = d2i_CMS_ContentInfo(nullptr, in, len); if (CMS_verify(cms, nullptr, store, nullptr, nullptr, 0)) { ASN1_OCTET_STRING **data = CMS_get0_content(cms); // 直接使用解析后的原始数据,无需分配新内存 process_content((*data)->data, (*data)->length); } CMS_ContentInfo_free(cms);
2. 优化首次内存分配
可以通过OpenSSL的自定义内存分配机制减少分配开销:
- 使用
CRYPTO_set_mem_functions注册设备专属的内存分配函数,比如基于内存池的分配器,避免频繁的内存申请/释放带来的碎片和开销; - 若使用OpenSSL 3.0+,可以用
d2i_CMS_ContentInfo_ex结合OSSL_LIB_CTX和内存相关的OSSL_PARAM参数,更精细化地控制内存分配行为。
内容的提问来源于stack exchange,提问作者murali
相关产品推荐
相关产品推荐

