- unsigned char tmpdata[len];
-
- EVP_MD_CTX ctx;
-
- if(!EVP_DigestInit(&ctx, digest->digest)
- || !EVP_DigestUpdate(&ctx, indata, inlen)
- || !EVP_DigestFinal(&ctx, tmpdata, NULL)) {
- logger(LOG_DEBUG, "Error creating digest: %s", ERR_error_string(ERR_get_error(), NULL));
- return false;
+ unsigned char *tmpdata = alloca(len);
+
+ if(digest->hmac_ctx) {
+ bool ok;
+
+#if OPENSSL_VERSION_MAJOR < 3
+ ok = HMAC_Init_ex(digest->hmac_ctx, NULL, 0, NULL, NULL)
+ && HMAC_Update(digest->hmac_ctx, indata, inlen)
+ && HMAC_Final(digest->hmac_ctx, tmpdata, NULL);
+#else
+ EVP_MAC_CTX *mac_ctx = EVP_MAC_CTX_dup(digest->hmac_ctx);
+
+ ok = mac_ctx
+ && EVP_MAC_update(mac_ctx, indata, inlen)
+ && EVP_MAC_final(mac_ctx, tmpdata, NULL, len);
+
+ EVP_MAC_CTX_free(mac_ctx);
+#endif
+
+ if(!ok) {
+ openssl_err("create HMAC");
+ return false;
+ }
+ } else {
+ if(!digest->md_ctx) {
+ digest->md_ctx = EVP_MD_CTX_create();
+ }
+
+ if(!digest->md_ctx) {
+ abort();
+ }
+
+ if(!EVP_DigestInit(digest->md_ctx, digest->digest)
+ || !EVP_DigestUpdate(digest->md_ctx, indata, inlen)
+ || !EVP_DigestFinal(digest->md_ctx, tmpdata, NULL)) {
+ openssl_err("create digest");
+ return false;
+ }