> Did you attempt to pass NULL for the key and zero for it's length to the > EVP_MAC_init() call? Yes. We can do better. If we have to use dup/free, we can move the EVP_MAC_init() to before the dup, out of the timing path. My model is that initialization is 2 parts. The first is turning the key into a big table. The second is initializing a small amount of state that is whatever is needed/updated by EVP_MAC_update(). I was hoping that EVP_MAC_init() with NULL key would bypass the first step and do the second. If the second step involves a lot of computation we get into the space/time tradeoff of computing it during step one and saving it in case EVP_MAC_init is called with NULL key. If there was a copy operation we could use it instead of dup/free. Where is the code that does the key setup? I expect it will be obvious after I see it, but I don't know my way around that linkage yet. I'm using the default AES-128-CBC. --------- I don't think I've said it explicitly, but thanks for the change to the API for EVP_MAC_init() ---------- Should PKEY be a potentially interesting approach for something like this? I think it was suggested months ago. One advantage is that the code works with 1.1.1. It's horribly slow in 3.0 alpha14: 0.777 CMAC 7.533 PKEY 3.323 PKEY preload 0.392 EVP_MAC 0.308 EVP_MAC Preload with dup+free 0.102 EVP_MAC Preload (no dup, wrong answer) 1.1.1k: 0.285 CMAC 0.550 PKEY 0.196 PKEY preload -- These are my opinions. I hate spam.