krb5 commit: Prefer openssl's EVP_MAC interface for HMAC

Greg Hudson <[email protected]>
Newsgroups gmane.comp.encryption.kerberos.cvs
Message-ID <[email protected]>
https://github.com/krb5/krb5/commit/d66e96a8f1b339b4ca058d46a7267a18b923cb48
commit d66e96a8f1b339b4ca058d46a7267a18b923cb48
Author: Robbie Harwood <[email protected]>
Date:   Tue Jul 13 15:07:39 2021 -0400

    Prefer openssl's EVP_MAC interface for HMAC
    
    OpenSSL 3 has deprecated the HMAC interface.

 src/lib/crypto/openssl/hmac.c |   74 +++++++++++++++++++++++++++++++++++++---
 1 files changed, 68 insertions(+), 6 deletions(-)

diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
index 4dbb236..bf12b8d 100644
--- a/src/lib/crypto/openssl/hmac.c
+++ b/src/lib/crypto/openssl/hmac.c
@@ -55,8 +55,13 @@
 
 #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,
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.