]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Use OpenSSL CMAC implementation with OpenSSL 3 1212/head
authorGreg Hudson <ghudson@mit.edu>
Tue, 19 Oct 2021 14:42:34 +0000 (10:42 -0400)
committerGreg Hudson <ghudson@mit.edu>
Mon, 15 Nov 2021 18:04:36 +0000 (13:04 -0500)
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.

13 files changed:
src/lib/crypto/builtin/Makefile.in
src/lib/crypto/builtin/cmac.c [moved from src/lib/crypto/krb/cmac.c with 99% similarity]
src/lib/crypto/builtin/deps
src/lib/crypto/builtin/enc_provider/camellia.c
src/lib/crypto/crypto_tests/camellia-test.c
src/lib/crypto/krb/Makefile.in
src/lib/crypto/krb/crypto_int.h
src/lib/crypto/krb/deps
src/lib/crypto/libk5crypto.exports
src/lib/crypto/openssl/Makefile.in
src/lib/crypto/openssl/cmac.c [new file with mode: 0644]
src/lib/crypto/openssl/deps
src/lib/crypto/openssl/enc_provider/camellia.c

index e874fd20d0170766243eda59055e316cb235e0cb..daf19da19541cc7eaf9cb7732de09f35d067caa4 100644 (file)
@@ -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      
similarity index 99%
rename from src/lib/crypto/krb/cmac.c
rename to src/lib/crypto/builtin/cmac.c
index 67ac1a178dce67f20092b3cc88e95c9b3a298dd5..d719aa25f807106afaa09e7840b29cfed1968cd4 100644 (file)
@@ -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 */
index 0b18a199eae307b4ef8c1d5a54355a4bca2f2f62..b6b533809e7d67d391ca0e7ce25848a53459d79c 100644 (file)
@@ -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 \
index 94361c09f01c94a66120c91d32d67c10e291284c..801fda0066a14d24b97992de3725821498750998 100644 (file)
@@ -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)
index 12aeed17af81a552ee1a8b132dd47248a09c1743..23d14667e15760dc12febc9b2cda14e6131e1511 100644 (file)
@@ -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);
 }
 
index 81444ab5a5879584f85d83d8c2746ae1c4879ab7..cb2e40a3a52864dd95b45fc3115123ef5aacba25 100644 (file)
@@ -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       \
index f7980efc2178d1eac4a1e7ca8acca602e52d7dbe..3629616d964b0cc9e64c8b8b06d26987b265f332 100644 (file)
  * 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 ***/
 
index 70b63a3d84f77c56ac3f3888f107ef741e47331e..929285725f87bf399527ca3e6d01725aaecd8a1c 100644 (file)
@@ -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 \
index d87ddd61a6c97039d10bf5776849045906b88e54..052f4d4b5101bc1a500fa21db1aae917236adb0b 100644 (file)
@@ -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
index d82049fecefa9bef0c9468edfe64069687ce8cb9..08de047d0aa1275332c61c2cd7e7034a826bc69e 100644 (file)
@@ -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 (file)
index 0000000..8f2717b
--- /dev/null
@@ -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 */
index 7009823951afa20b9bbea2ee59e0b5a63fc0bd7e..3d276a4c6b00f5120100e0647eb453fe549a2361 100644 (file)
@@ -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 \
index ac1bcbbd98deddef6843157beb4f89345f63e040..81f4772ca6b5c199fa7a45082ce2545b5efb3800 100644 (file)
@@ -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
 };