OpenSSL HMAC函数中的意外复杂性 [英] Accidental Complexity in OpenSSL HMAC functions
问题描述
SSL文档分析
这个问题与OpenSSL中HMAC例程的使用有关.
This question is pertaining the usage of the HMAC routines in OpenSSL.
由于Openssl文档在某些方面有些薄弱,因此分析表明使用:
Since Openssl documentation is a tad on the weak side in certain areas, profiling has revealed that using the:
unsigned char *HMAC(const EVP_MD *evp_md, const void *key,
int key_len, const unsigned char *d, int n,
unsigned char *md, unsigned int *md_len);
在此处中,显示我图书馆的40%运行时致力于创建和删除 HMAC_CTX 的幕后功绩.
From here, shows 40% of my library runtime is devoted to creating and taking down HMAC_CTX's behind the scenes.
还有两个附加功能可以专门创建和销毁 HMAC_CTX :
There are also two additional function to create and destroy a HMAC_CTX explicetly:
HMAC_CTX_init()初始化HMAC_CTX 第一次使用之前.必须调用它.
HMAC_CTX_init() initialises a HMAC_CTX before first use. It must be called.
HMAC_CTX_cleanup()删除密钥并 来自HMAC_CTX的其他数据和 释放任何关联的资源.它 HMAC_CTX为否时必须调用 需要更长的时间.
HMAC_CTX_cleanup() erases the key and other data from the HMAC_CTX and releases any associated resources. It must be called when an HMAC_CTX is no longer required.
这两个函数调用的前缀为:
These two function calls are prefixed with:
在以下情况下可以使用以下功能 消息未完全存储 在内存中
The following functions may be used if the message is not completely stored in memory
我的数据完全适合内存,因此我选择了HMAC功能-其签名如上所示.
My data fits entirely in memory, so I choose the HMAC function -- the one whose signature is shown above.
如手册页所述,上下文是通过以下两个功能来使用的:
The context, as described by the man page, is made use of by using the following two functions:
HMAC_Update()可以重复调用 与大量的消息是 已验证(数据中为len字节).
HMAC_Update() can be called repeatedly with chunks of the message to be authenticated (len bytes at data).
HMAC_Final()放置消息 md中的验证码,必须 哈希函数有空间 输出.
HMAC_Final() places the message authentication code in md, which must have space for the hash function output.
应用范围
我的应用程序生成了一个真实的(HMAC,也被用于随机数)CBC-BF加密的协议缓冲区字符串.该代码将与各种Web服务器和框架进行交互,Windows/Linux作为OS,nginx,Apache和IIS作为Web服务器以及Python/.NET和C ++ Web服务器过滤器.
My application generates a authentic (HMAC, which is also used a nonce), CBC-BF encrypted protocol buffer string. The code will be interfaced with various web-servers and frameworks Windows / Linux as OS, nginx, Apache and IIS as webservers and Python / .NET and C++ web-server filters.
上面的描述应阐明该库需要是线程安全的,并且潜在具有可恢复的处理状态-即,轻量级线程共享一个OS线程(这可能会使线程本地内存无法使用图片).
The description above should clarify that the library needs to be thread safe, and potentially have resumeable processing state -- i.e., lightweight threads sharing a OS thread (which might leave thread local memory out of the picture).
问题
如何以(1)线程安全/(2)可恢复状态的方式摆脱每次调用的 40%开销? (2)是可选的,因为我可以一次性获得所有源数据,并且可以确保在不放弃线程中间摘要创建控制的情况下就地创建了摘要.所以,
How do I get rid of the 40% overhead on each invocation in a (1) thread-safe / (2) resume-able state way ? (2) is optional since I have all of the source-data present in one go, and can make sure a digest is created in place without relinquishing control of the thread mid-digest-creation. So,
(1)可以使用线程本地内存来完成-但是如何重用CTX的内存呢? HMAC_final()调用会使CTX可重用吗?
(1) can probably be done using thread local memory -- but how do I resuse the CTX's ? does the HMAC_final() call make the CTX reusable ?.
(2)可选:在这种情况下,我将不得不创建一个CTX池.
(2) optional: in this case I would have to create a pool of CTX's.
(3)HMAC函数如何执行此操作?它会在函数调用范围内创建CTX并将其销毁吗?
(3) how does the HMAC function do this ? does it create a CTX in the scope of the function call and destroy it ?
伪代码和注释将很有用.
推荐答案
OpenSSL 0.9.8g中HMAC_Init_ex()
函数的文档说:
The documentation for the HMAC_Init_ex()
function in OpenSSL 0.9.8g says:
HMAC_Init_ex()
初始化或重复使用HMAC_CTX
结构使用功能evp_md
和键key
.可以是NULL
,在这种情况下是现有的 将被重复使用.
HMAC_Init_ex()
initializes or reuses aHMAC_CTX
structure to use the functionevp_md
and keykey
. Either can beNULL
, in which case the existing one will be reused.
(强调我的).因此,这意味着您可以一次用HMAC_CTX_Init()
初始化一个HMAC_CTX
,然后保留它以创建多个HMAC,只要您不对其调用HMAC_CTX_cleanup()
并使用HMAC_Init_ex()
开始每个HMAC.
(Emphasis mine). So this means that you can initialise a HMAC_CTX
with HMAC_CTX_Init()
once, then keep it around to create multiple HMACs with, as long as you don't call HMAC_CTX_cleanup()
on it and you start off each HMAC with HMAC_Init_ex()
.
所以,是的,您应该能够使用线程本地内存中的HMAC_CTX
做您想做的事情.
So yes, you should be able to do what you want with a HMAC_CTX
in thread-local memory.
这篇关于OpenSSL HMAC函数中的意外复杂性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!