Dear, The documentation recommends not to use, for instance, EVP_sha256() __each time__ it is needed when setting up a EVP_MD_CTX like in this partial code (intentionally without error conditions tests): EVP_MD_CTX* ctx = EVP_MD_CTX_new(); EVP_DigestInit_ex(ctx, EVP_sha256(), nullptr); But that it would be wiser to use EVP_MD_fetch() and cache that while it fits, like in some cache structure which would hold a hand of algorithms useful to the repetitive task: EVP_MD* evp_sha256 = EVP_MD_fetch(nullptr, "SHA-256", nullptr); And so, reuse that pointer in EVP_DigestInit_ex() to spare a call to EVP_sha256() or EVP_MD_fetch() each time. When using the EVP_MAC_ interfaces, I can follow the same principle for the EVP_MAC* itself which will be passed to EVP_MAC_CTX_new(), after calling and caching EVP_MAC_fetch(nullptr, "HMAC", nullptr). Yet, I find no way of setting the digest algorithm to use for this hmac, other than by text through OSSL_PARAM: const OSSL_PARAM params[] = { {"digest", OSSL_PARAM_UTF8_STRING, (void*)"SHA-256", 7, 0}, {nullptr, 0, nullptr, 0, 0} }; Is this really intentional? Is there an other way? If, for a hmac, it is perfectly acceptable, having no other way, to select the hash algorithm through text search each time it is needed, then why would this be less acceptable for EVP_MD_ interfaces themselves? I have no functional issue. It works. The API just leaves me puzzled. ______________ Olivier Mascia