krb5 commit: Use OpenSSL CMAC implementation with OpenSSL 3

Greg Hudson <[email protected]>
Newsgroups gmane.comp.encryption.kerberos.cvs
Message-ID <[email protected]>
https://github.com/krb5/krb5/commit/f1b36bb34e16ac423597c292ebfad77aa225de97
commit f1b36bb34e16ac423597c292ebfad77aa225de97
Author: Greg Hudson <[email protected]>
Date:   Tue Oct 19 10:42:34 2021 -0400

    Use OpenSSL CMAC implementation with OpenSSL 3
    
    Make krb5int_cmac_checksum() a crypto module interface.  Move the
    existing CMAC implementation from krb to builtin.  Add an OpenSSL 3
    implementation using EVP_MAC.  Only implement Camellia CBC-MAC if
    using the builtin CMAC implementation (it uses functions deprecated in
    OpenSSL 3).  Switch to using krb5int_camellia_encrypt() for
    camellia-test.c since krb5int_camellia_cbc_mac() won't always be
    available.

 src/lib/crypto/builtin/Makefile.in             |    3 +
 src/lib/crypto/builtin/cmac.c                  |  204 ++++++++++++++++++++++++
 src/lib/crypto/builtin/deps                    |   11 ++
 src/lib/crypto/builtin/enc_provider/camellia.c |    4 +-
 src/lib/crypto/crypto_tests/camellia-test.c    |    7 +-
 src/lib/crypto/krb/Makefile.in                 |    3 -
 src/lib/crypto/krb/cmac.c                      |  200 -----------------------
 src/lib/crypto/krb/crypto_int.h                |   27 ++--
 src/lib/crypto/krb/deps                        |   10 --
 src/lib/crypto/libk5crypto.exports             |    2 +-
 src/lib/crypto/openssl/Makefile.in             |    3 +
 src/lib/crypto/openssl/cmac.c                  |   93 +++++++++++
 src/lib/crypto/openssl/deps                    |   11 ++
 src/lib/crypto/openssl/enc_provider/camellia.c |   52 +++----
 14 files changed, 369 insertions(+), 261 deletions(-)

diff --git a/src/lib/crypto/builtin/Makefile.in b/src/lib/crypto/builtin/Makefile.in
index e874fd2..daf19da 100644
--- a/src/lib/crypto/builtin/Makefile.in
+++ b/src/lib/crypto/builtin/Makefile.in
@@ -8,16 +8,19 @@ LOCALINCLUDES=-I$(srcdir)/../krb $(CRYPTO_IMPL_CFLAGS)
 ##DOS##OBJFILE = ..\$(OUTPRE)builtin.lst
 
 STLIBOBJS=\
+	cmac.o	\
 	hmac.o	\
 	kdf.o \
 	pbkdf2.o
 
 OBJS=\
+	$(OUTPRE)cmac.$(OBJEXT)	\
 	$(OUTPRE)hmac.$(OBJEXT)	\
 	$(OUTPRE)kdf.$(OBJEXT) \
 	$(OUTPRE)pbkdf2.$(OBJEXT)
 
 SRCS=\
+	$(srcdir)/cmac.c	\
 	$(srcdir)/hmac.c	\
 	$(srcdir)/kdf.c		\
 	$(srcdir)/pbkdf2.c	
diff --git a/src/lib/crypto/krb/cmac.c b/src/lib/crypto/builtin/cmac.c
similarity index 99%
rename from src/lib/crypto/krb/cmac.c
rename to src/lib/crypto/builtin/cmac.c
index 67ac1a1..d719aa2 100644
--- a/src/lib/crypto/krb/cmac.c
+++ b/src/lib/crypto/builtin/cmac.c
@@ -26,6 +26,8 @@
 
 #include "crypto_int.h"
 
+#ifdef K5_BUILTIN_CMAC
+
 #define BLOCK_SIZE 16
 
 static unsigned char const_Rb[BLOCK_SIZE] = {
@@ -198,3 +200,5 @@ krb5int_cmac_checksum(const struct krb5_enc_provider *enc, krb5_key key,
 
     return 0;
 }
+
+#endif /* K5_BUILTIN_CMAC */
diff --git a/src/lib/crypto/builtin/deps b/src/lib/crypto/builtin/deps
index 0b18a19..b6b5338 100644
--- a/src/lib/crypto/builtin/deps
+++ b/src/lib/crypto/builtin/deps
@@ -1,6 +1,17 @@
 #
 # Generated makefile dependencies follow.
 #
+cmac.so cmac.po $(OUTPRE)cmac.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \
+  $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+  $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+  $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+  $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+  $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+  $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+  $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+  cmac.c
 hmac.so hmac.po $(OUTPRE)hmac.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
   $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
   $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \
diff --git a/src/lib/crypto/builtin/enc_provider/camellia.c b/src/lib/crypto/builtin/enc_provider/camellia.c
index 94361c0..801fda0 100644
--- a/src/lib/crypto/builtin/enc_provider/camellia.c
+++ b/src/lib/crypto/builtin/enc_provider/camellia.c
@@ -113,7 +113,7 @@ cbc_dec(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv)
     memcpy(iv, last_cipherblock, BLOCK_SIZE);
 }
 
-static krb5_error_code
+krb5_error_code
 krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec,
                          krb5_crypto_iov *data, size_t num_data)
 {
@@ -246,7 +246,7 @@ krb5int_camellia_decrypt(krb5_key key, const krb5_data *ivec,
     return 0;
 }
 
-krb5_error_code
+static krb5_error_code
 krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
                          size_t num_data, const krb5_data *ivec,
                          krb5_data *output)
diff --git a/src/lib/crypto/crypto_tests/camellia-test.c b/src/lib/crypto/crypto_tests/camellia-test.c
index 12aeed1..23d1466 100644
--- a/src/lib/crypto/crypto_tests/camellia-test.c
+++ b/src/lib/crypto/crypto_tests/camellia-test.c
@@ -46,13 +46,12 @@ static void enc()
 {
     krb5_key k;
     krb5_crypto_iov iov;
-    krb5_data cdata = make_data(cipher, 16);
 
+    memcpy(cipher, plain, 16);
     iov.flags = KRB5_CRYPTO_TYPE_DATA;
-    iov.data = make_data(plain, 16);
+    iov.data = make_data(cipher, 16);
     krb5_k_create_key(NULL, &enc_key, &k);
-    /* cbc-mac is the same as block encryption for a single block. */
-    krb5int_camellia_cbc_mac(k, &iov, 1, &ivec, &cdata);
+    krb5int_camellia_encrypt(k, &ivec, &iov, 1);
     krb5_k_free_key(NULL, k);
 }
 
diff --git a/src/lib/crypto/krb/Makefile.in b/src/lib/crypto/krb/Makefile.in
index 81444ab..cb2e40a 100644
--- a/src/lib/crypto/krb/Makefile.in
+++ b/src/lib/crypto/krb/Makefile.in
@@ -17,7 +17,6 @@ STLIBOBJS=\
 	checksum_length.o	\
 	cksumtype_to_string.o	\
 	cksumtypes.o		\
-	cmac.o			\
 	coll_proof_cksum.o	\
 	crypto_length.o		\
 	default_state.o 	\
@@ -74,7 +73,6 @@ OBJS=\
 	$(OUTPRE)checksum_length.$(OBJEXT)	\
 	$(OUTPRE)cksumtype_to_string.$(OBJEXT)	\
 	$(OUTPRE)cksumtypes.$(OBJEXT)		\
-	$(OUTPRE)cmac.$(OBJEXT)			\
 	$(OUTPRE)coll_proof_cksum.$(OBJEXT)	\
 	$(OUTPRE)crypto_length.$(OBJEXT)	\
 	$(OUTPRE)default_state.$(OBJEXT) 	\
@@ -131,7 +129,6 @@ SRCS=\
 	$(srcdir)/checksum_length.c	\
 	$(srcdir)/cksumtype_to_string.c	\
 	$(srcdir)/cksumtypes.c		\
-	$(srcdir)/cmac.c		\
 	$(srcdir)/coll_proof_cksum.c	\
 	$(srcdir)/crypto_length.c	\
 	$(srcdir)/default_state.c 	\
diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h
index f7980ef..3629616 100644
--- a/src/lib/crypto/krb/crypto_int.h
+++ b/src/lib/crypto/krb/crypto_int.h
@@ -44,17 +44,21 @@
  * no replacement.
  *
  * OpenSSL 3.0 adds KDF implementations matching the ones we use to derive
- * encryption and authentication keys from protocol keys.
+ * encryption and authentication keys from protocol keys.  It also adds
+ * the EVP_MAC interface which can be used for CMAC.  (We could use the CMAC
+ * interface with OpenSSL 1.1 but currently do not.)
  */
 #define K5_BUILTIN_DES_KEY_PARITY
 #define K5_BUILTIN_MD4
 #define K5_BUILTIN_RC4
 #define K5_OPENSSL_KDF
+#define K5_OPENSSL_CMAC
 #else
 #define K5_OPENSSL_DES_KEY_PARITY
 #define K5_OPENSSL_MD4
 #define K5_OPENSSL_RC4
 #define K5_BUILTIN_KDF
+#define K5_BUILTIN_CMAC
 #endif
 
 #define K5_OPENSSL_AES
@@ -70,6 +74,7 @@
 
 #define K5_BUILTIN_AES
 #define K5_BUILTIN_CAMELLIA
+#define K5_BUILTIN_CMAC
 #define K5_BUILTIN_DES
 #define K5_BUILTIN_DES_KEY_PARITY
 #define K5_BUILTIN_HMAC
@@ -400,13 +405,6 @@ krb5_error_code krb5int_derive_random(const struct krb5_enc_provider *enc,
 void krb5int_nfold(unsigned int inbits, const unsigned char *in,
                    unsigned int outbits, unsigned char *out);
 
-/* Compute a CMAC checksum over data. */
-krb5_error_code krb5int_cmac_checksum(const struct krb5_enc_provider *enc,
-                                      krb5_key key,
-                                      const krb5_crypto_iov *data,
-                                      size_t num_data,
-                                      krb5_data *output);
-
 /* Translate an RFC 3961 key usage to a Microsoft RC4 usage. */
 krb5_keyusage krb5int_arcfour_translate_usage(krb5_keyusage usage);
 
@@ -496,6 +494,12 @@ krb5_error_code krb5int_hmac(const struct krb5_hash_provider *hash,
                              krb5_key key, const krb5_crypto_iov *data,
                              size_t num_data, krb5_data *output);
 
+/* Compute a CMAC checksum over data. */
+krb5_error_code krb5int_cmac_checksum(const struct krb5_enc_provider *enc,
+                                      krb5_key key,
+                                      const krb5_crypto_iov *data,
+                                      size_t num_data, krb5_data *output);
+
 /* As above, using a keyblock as the key input. */
 krb5_error_code krb5int_hmac_keyblock(const struct krb5_hash_provider *hash,
                                       const krb5_keyblock *keyblock,
@@ -551,10 +555,9 @@ krb5_error_code krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec,
                                     krb5_crypto_iov *data, size_t num_data);
 krb5_error_code krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec,
                                     krb5_crypto_iov *data, size_t num_data);
-krb5_error_code krb5int_camellia_cbc_mac(krb5_key key,
-                                         const krb5_crypto_iov *data,
-                                         size_t num_data, const krb5_data *iv,
-                                         krb5_data *output);
+krb5_error_code krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec,
+                                         krb5_crypto_iov *data,
+                                         size_t num_data);
 
 /*** Inline helper functions ***/
 
diff --git a/src/lib/crypto/krb/deps b/src/lib/crypto/krb/deps
index 70b63a3..9292857 100644
--- a/src/lib/crypto/krb/deps
+++ b/src/lib/crypto/krb/deps
@@ -120,16 +120,6 @@ cksumtypes.so cksumtypes.po $(OUTPRE)cksumtypes.$(OBJEXT): \
   $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
   $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
   cksumtypes.c crypto_int.h
-cmac.so cmac.po $(OUTPRE)cmac.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
-  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
-  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
-  $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
-  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
-  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
-  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
-  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
-  $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
-  $(top_srcdir)/include/socket-utils.h cmac.c crypto_int.h
 coll_proof_cksum.so coll_proof_cksum.po $(OUTPRE)coll_proof_cksum.$(OBJEXT): \
   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
   $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports
index d87ddd6..052f4d4 100644
--- a/src/lib/crypto/libk5crypto.exports
+++ b/src/lib/crypto/libk5crypto.exports
@@ -88,7 +88,7 @@ krb5int_aes_encrypt
 krb5int_aes_decrypt
 krb5int_enc_des3
 krb5int_arcfour_gsscrypt
-krb5int_camellia_cbc_mac
+krb5int_camellia_encrypt
 krb5int_cmac_checksum
 krb5int_enc_aes128
 krb5int_enc_aes256
diff --git a/src/lib/crypto/openssl/Makefile.in b/src/lib/crypto/openssl/Makefile.in
index d82049f..08de047 100644
--- a/src/lib/crypto/openssl/Makefile.in
+++ b/src/lib/crypto/openssl/Makefile.in
@@ -4,18 +4,21 @@ SUBDIRS=des enc_provider hash_provider
 LOCALINCLUDES=-I$(srcdir)/../krb $(CRYPTO_IMPL_CFLAGS)
 
 STLIBOBJS=\
+	cmac.o	\
 	hmac.o	\
 	kdf.o	\
 	pbkdf2.o \
 	sha256.o
 
 OBJS=\
+	$(OUTPRE)cmac.$(OBJEXT)	\
 	$(OUTPRE)hmac.$(OBJEXT)	\
 	$(OUTPRE)kdf.$(OBJEXT)	\
 	$(OUTPRE)pbkdf2.$(OBJEXT) \
 	$(OUTPRE)sha256.$(OBJEXT)
 
 SRCS=\
+	$(srcdir)/cmac.c	\
 	$(srcdir)/hmac.c	\
 	$(srcdir)/kdf.c		\
 	$(srcdir)/pbkdf2.c	\
diff --git a/src/lib/crypto/openssl/cmac.c b/src/lib/crypto/openssl/cmac.c
new file mode 100644
index 0000000..8f2717b
--- /dev/null
+++ b/src/lib/crypto/openssl/cmac.c
@@ -0,0 +1,93 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/openssl/cmac.c - OpenSSL CMAC implementation */
+/*
+ * Copyright (C) 2021 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "crypto_int.h"
+
+#ifdef K5_OPENSSL_CMAC
+
+#include <openssl/evp.h>
+#include <openssl/params.h>
+#include <openssl/core_names.h>
+
+krb5_error_code
+krb5int_cmac_checksum(const struct krb5_enc_provider *enc, krb5_key key,
+                      const krb5_crypto_iov *data, size_t num_data,
+                      krb5_data *output)
+{
+    int ok;
+    EVP_MAC *mac = NULL;
+    EVP_MAC_CTX *ctx = NULL;
+    OSSL_PARAM params[2], *p = params;
+    size_t i = 0, md_len;
+    char *cipher;
+
+    if (enc == &krb5int_enc_camellia128)
+        cipher = "CAMELLIA-128-CBC";
+    else if (enc == &krb5int_enc_camellia256)
+        cipher = "CAMELLIA-256-CBC";
+    else
+        return KRB5_CRYPTO_INTERNAL;
+
+    mac = EVP_MAC_fetch(NULL, "CMAC", 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_CIPHER, cipher, 0);
+    *p = OSSL_PARAM_construct_end();
+
+    ok = EVP_MAC_init(ctx, key->keyblock.contents, key->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, (unsigned char *)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;
+}
+
+#endif /* K5_OPENSSL_CMAC */
diff --git a/src/lib/crypto/openssl/deps b/src/lib/crypto/openssl/deps
index 7009823..3d276a4 100644
--- a/src/lib/crypto/openssl/deps
+++ b/src/lib/crypto/openssl/deps
@@ -1,6 +1,17 @@
 #
 # Generated makefile dependencies follow.
 #
+cmac.so cmac.po $(OUTPRE)cmac.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \
+  $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+  $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+  $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+  $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+  $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+  $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+  $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+  cmac.c
 hmac.so hmac.po $(OUTPRE)hmac.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
   $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
   $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
index ac1bcbb..81f4772 100644
--- a/src/lib/crypto/openssl/enc_provider/camellia.c
+++ b/src/lib/crypto/openssl/enc_provider/camellia.c
@@ -52,31 +52,6 @@ cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
 #define NUM_BITS 8
 #define IV_CTS_BUF_SIZE 16 /* 16 - hardcoded in CRYPTO_cts128_en/decrypt */
 
-static void
-xorblock(unsigned char *out, const unsigned char *in)
-{
-    int z;
-    for (z = 0; z < CAMELLIA_BLOCK_SIZE / 4; z++) {
-        unsigned char *outptr = &out[z * 4];
-        unsigned char *inptr = (unsigned char *)&in[z * 4];
-        /*
-         * Use unaligned accesses.  On x86, this will probably still be faster
-         * than multiple byte accesses for unaligned data, and for aligned data
-         * should be far better.  (One test indicated about 2.4% faster
-         * encryption for 1024-byte messages.)
-         *
-         * If some other CPU has really slow unaligned-word or byte accesses,
-         * perhaps this function (or the load/store helpers?) should test for
-         * alignment first.
-         *
-         * If byte accesses are faster than unaligned words, we may need to
-         * conditionalize on CPU type, as that may be hard to determine
-         * automatically.
-         */
-        store_32_n(load_32_n(outptr) ^ load_32_n(inptr), outptr);
-    }
-}
-
 static const EVP_CIPHER *
 map_mode(unsigned int len)
 {
@@ -347,7 +322,7 @@ cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
 
 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
 
-static krb5_error_code
+krb5_error_code
 krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec,
                          krb5_crypto_iov *data, size_t num_data)
 {
@@ -387,7 +362,22 @@ krb5int_camellia_decrypt(krb5_key key, const krb5_data *ivec,
     return ret;
 }
 
-krb5_error_code
+#ifdef K5_BUILTIN_CMAC
+
+static void
+xorblock(uint8_t *out, const uint8_t *in)
+{
+    int z;
+
+    for (z = 0; z < CAMELLIA_BLOCK_SIZE / 4; z++) {
+        uint8_t *outptr = &out[z * 4];
+        const uint8_t *inptr = &in[z * 4];
+
+        store_32_n(load_32_n(outptr) ^ load_32_n(inptr), outptr);
+    }
+}
+
+static krb5_error_code
 krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
                          size_t num_data, const krb5_data *iv,
                          krb5_data *output)
@@ -419,6 +409,10 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
     return 0;
 }
 
+#else
+#define krb5int_camellia_cbc_mac NULL
+#endif
+
 static krb5_error_code
 krb5int_camellia_init_state (const krb5_keyblock *key, krb5_keyusage usage,
                              krb5_data *state)
@@ -435,7 +429,7 @@ const struct krb5_enc_provider krb5int_enc_camellia128 = {
     16, 16,
     krb5int_camellia_encrypt,
     krb5int_camellia_decrypt,
-    krb5int_camellia_cbc_mac,
+    krb5int_camellia_cbc_mac,   /* NULL if K5_BUILTIN_CMAC not defined */
     krb5int_camellia_init_state,
     krb5int_default_free_state
 };
@@ -445,7 +439,7 @@ const struct krb5_enc_provider krb5int_enc_camellia256 = {
     32, 32,
     krb5int_camellia_encrypt,
     krb5int_camellia_decrypt,
-    krb5int_camellia_cbc_mac,
+    krb5int_camellia_cbc_mac,   /* NULL if K5_BUILTIN_CMAC not defined */
     krb5int_camellia_init_state,
     krb5int_default_free_state
 };
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.