]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Prefer openssl's EVP_MAC interface for HMAC
authorRobbie Harwood <rharwood@redhat.com>
Tue, 13 Jul 2021 19:07:39 +0000 (15:07 -0400)
committerGreg Hudson <ghudson@mit.edu>
Mon, 15 Nov 2021 16:26:38 +0000 (11:26 -0500)
OpenSSL 3 has deprecated the HMAC interface.

src/lib/crypto/openssl/hmac.c

index 4dbb23657eb1b3dc0ffc8b033b8bd4b2ab0bff74..bf12b8d6a0aa77b912c0d3f44eb786d806a0c6af 100644 (file)
 
 #ifdef K5_OPENSSL_HMAC
 
-#include <openssl/hmac.h>
 #include <openssl/evp.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/params.h>
+#include <openssl/core_names.h>
+#else
+#include <openssl/hmac.h>
+#endif
 
 #if OPENSSL_VERSION_NUMBER < 0x10100000L
 
@@ -100,20 +105,75 @@ compat_hmac_ctx_free(HMAC_CTX *ctx)
 static const EVP_MD *
 map_digest(const struct krb5_hash_provider *hash)
 {
-    if (!strncmp(hash->hash_name, "SHA1",4))
+    if (hash == &krb5int_hash_sha1)
         return EVP_sha1();
-    else if (!strncmp(hash->hash_name, "SHA-256",7))
+    else if (hash == &krb5int_hash_sha256)
         return EVP_sha256();
-    else if (!strncmp(hash->hash_name, "SHA-384",7))
+    else if (hash == &krb5int_hash_sha384)
         return EVP_sha384();
-    else if (!strncmp(hash->hash_name, "MD5", 3))
+    else if (hash == &krb5int_hash_md5)
         return EVP_md5();
-    else if (!strncmp(hash->hash_name, "MD4", 3))
+    else if (hash == &krb5int_hash_md4)
         return EVP_md4();
     else
         return NULL;
 }
 
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+
+krb5_error_code
+krb5int_hmac_keyblock(const struct krb5_hash_provider *hash,
+                      const krb5_keyblock *keyblock,
+                      const krb5_crypto_iov *data, size_t num_data,
+                      krb5_data *output)
+{
+    int ok;
+    const EVP_MD *md = map_digest(hash);
+    EVP_MAC *mac = NULL;
+    EVP_MAC_CTX *ctx = NULL;
+    OSSL_PARAM params[2], *p = params;
+    size_t i = 0, md_len;
+
+    if (md == NULL || keyblock->length > hash->blocksize)
+        return KRB5_CRYPTO_INTERNAL;
+    if (output->length < hash->hashsize)
+        return KRB5_BAD_MSIZE;
+
+    mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+    if (mac == NULL)
+        return KRB5_CRYPTO_INTERNAL;
+
+    ctx = EVP_MAC_CTX_new(mac);
+    if (ctx == NULL) {
+        ok = 0;
+        goto cleanup;
+    }
+
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_DIGEST,
+                                            (char *)EVP_MD_get0_name(md), 0);
+    *p = OSSL_PARAM_construct_end();
+
+    ok = EVP_MAC_init(ctx, keyblock->contents, keyblock->length, params);
+    for (i = 0; ok && i < num_data; i++) {
+        const krb5_crypto_iov *iov = &data[i];
+        if (!SIGN_IOV(iov))
+            continue;
+        ok = EVP_MAC_update(ctx, (uint8_t *)iov->data.data, iov->data.length);
+    }
+    ok = ok && EVP_MAC_final(ctx, (uint8_t *)output->data, &md_len,
+                             output->length);
+    if (!ok)
+        goto cleanup;
+    output->length = md_len;
+
+cleanup:
+    EVP_MAC_free(mac);
+    EVP_MAC_CTX_free(ctx);
+    return ok ? 0 : KRB5_CRYPTO_INTERNAL;
+}
+
+#else /* OPENSSL_VERSION_NUMBER < 0x30000000L */
+
 krb5_error_code
 krb5int_hmac_keyblock(const struct krb5_hash_provider *hash,
                       const krb5_keyblock *keyblock,
@@ -158,6 +218,8 @@ krb5int_hmac_keyblock(const struct krb5_hash_provider *hash,
     return ok ? 0 : KRB5_CRYPTO_INTERNAL;
 }
 
+#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
+
 krb5_error_code
 krb5int_hmac(const struct krb5_hash_provider *hash, krb5_key key,
              const krb5_crypto_iov *data, size_t num_data,