aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Howard <lukeh@padl.com>2010-05-13 23:12:26 +0000
committerLuke Howard <lukeh@padl.com>2010-05-13 23:12:26 +0000
commit2a03253b1d561cdd1d1c58d5a4cb110955bc2805 (patch)
tree67ff99835d5036c3ea10ced28ee3ed41d3c119d5
parent90ce6ad65aa7af3db6c8b298e0c295c51be85698 (diff)
downloadkrb5-2a03253b1d561cdd1d1c58d5a4cb110955bc2805.zip
krb5-2a03253b1d561cdd1d1c58d5a4cb110955bc2805.tar.gz
krb5-2a03253b1d561cdd1d1c58d5a4cb110955bc2805.tar.bz2
CCM PRF is now CMAC (similar to RFC 4615)
git-svn-id: svn://anonsvn.mit.edu/krb5/users/lhoward/camellia-ccm@24024 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/lib/crypto/krb/checksum/Makefile.in10
-rw-r--r--src/lib/crypto/krb/checksum/cmac.c243
-rw-r--r--src/lib/crypto/krb/cksumtypes.c16
-rw-r--r--src/lib/crypto/krb/cksumtypes.h6
-rw-r--r--src/lib/crypto/krb/dk/checksum_cmac.c219
-rw-r--r--src/lib/crypto/krb/dk/dk.h8
-rw-r--r--src/lib/crypto/krb/prf/ccm_prf.c10
7 files changed, 283 insertions, 229 deletions
diff --git a/src/lib/crypto/krb/checksum/Makefile.in b/src/lib/crypto/krb/checksum/Makefile.in
index 61b41f2..826afd1 100644
--- a/src/lib/crypto/krb/checksum/Makefile.in
+++ b/src/lib/crypto/krb/checksum/Makefile.in
@@ -10,12 +10,14 @@ DEFS=
PROG_LIBPATH=-L$(TOPLIBD)
PROG_RPATH=$(KRB5_LIBDIR)
-STLIBOBJS= cbc.o confounder.o hmac_md5.o unkeyed.o
+STLIBOBJS= cbc.o cmac.o confounder.o hmac_md5.o unkeyed.o
-OBJS= $(OUTPRE)cbc.$(OBJEXT) $(OUTPRE)confounder.$(OBJEXT) \
- $(OUTPRE)hmac_md5.$(OBJEXT) $(OUTPRE)unkeyed.$(OBJEXT)
+OBJS= $(OUTPRE)cbc.$(OBJEXT) $(OUTPRE)cmac.$(OBJECT) \
+ $(OUTPRE)confounder.$(OBJEXT) $(OUTPRE)hmac_md5.$(OBJEXT) \
+ $(OUTPRE)unkeyed.$(OBJEXT)
-SRCS= $(srcdir)/cbc.c $(srcdir)/confounder.c $(srcdir)/hmac_md5.c \
+SRCS= $(srcdir)/cbc.c $(srcdir)/cmac.c \
+ $(srcdir)/confounder.c $(srcdir)/hmac_md5.c \
$(srcdir)/unkeyed.c
##DOS##LIBOBJS = $(OBJS)
diff --git a/src/lib/crypto/krb/checksum/cmac.c b/src/lib/crypto/krb/checksum/cmac.c
new file mode 100644
index 0000000..2356198
--- /dev/null
+++ b/src/lib/crypto/krb/checksum/cmac.c
@@ -0,0 +1,243 @@
+/*
+ * lib/crypto/krb/checksum/cmac.c
+ *
+ * Copyright 2010 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+/*
+ * Portions Copyright (C) The Internet Society (2006).
+ *
+ * This document is subject to the rights, licenses and restrictions
+ * contained in BCP 78, and except as set forth therein, the authors
+ * retain all their rights.
+ *
+ * This document and the information contained herein are provided on an
+ * "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+ * OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
+ * ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+ * INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "k5-int.h"
+#include "etypes.h"
+#include "aead.h"
+#include "etypes.h"
+#include "cksumtypes.h"
+
+#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
+
+#define BLOCK_SIZE 16
+
+static unsigned char const_Rb[BLOCK_SIZE] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87
+};
+
+static unsigned char const_Zero[BLOCK_SIZE] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static void
+xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
+{
+ int z;
+
+ for (z = 0; z < BLOCK_SIZE / 4; z++) {
+ unsigned char *aptr = &a[z * 4];
+ unsigned char *bptr = &b[z * 4];
+ unsigned char *outptr = &out[z * 4];
+
+ store_32_n(load_32_n(aptr) ^ load_32_n(bptr), outptr);
+ }
+}
+
+static void
+leftshift_onebit(unsigned char *input, unsigned char *output)
+{
+ int i;
+ unsigned char overflow = 0;
+
+ for (i = BLOCK_SIZE - 1; i >= 0; i--) {
+ output[i] = input[i] << 1;
+ output[i] |= overflow;
+ overflow = (input[i] & 0x80) ? 1 : 0;
+ }
+}
+
+static krb5_error_code
+generate_subkey(const struct krb5_enc_provider *enc,
+ krb5_key key,
+ unsigned char *K1,
+ unsigned char *K2)
+{
+ unsigned char Z[BLOCK_SIZE];
+ unsigned char L[BLOCK_SIZE];
+ unsigned char tmp[BLOCK_SIZE];
+ krb5_crypto_iov iov[1];
+ krb5_data d;
+ krb5_error_code ret;
+
+ memset(Z, 0, sizeof(Z));
+ iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[0].data = make_data((char *)Z, sizeof(Z));
+
+ d = make_data((char *)L, BLOCK_SIZE);
+
+ /*
+ * CBC in terms of CBC-MAC; at the cost of an additional XOR,
+ * this avoids needing to extend the SPI interface (because we
+ * need both the CBC-MAC function from the CCM provider and
+ * the CBC function from the CTS provider).
+ */
+ ret = enc->cbc_mac(key, iov, 1, NULL, &d);
+ if (ret != 0)
+ return ret;
+
+ xor_128(const_Zero, L, L);
+
+ if ((L[0] & 0x80) == 0) {
+ leftshift_onebit(L, K1);
+ } else {
+ leftshift_onebit(L, tmp);
+ xor_128(tmp, const_Rb, K1);
+ }
+
+ if ((K1[0] & 0x80) == 0) {
+ leftshift_onebit(K1, K2);
+ } else {
+ leftshift_onebit(K1, tmp);
+ xor_128(tmp, const_Rb, K2);
+ }
+
+ return 0;
+}
+
+static void
+padding(unsigned char *lastb, unsigned char *pad, int length)
+{
+ int j;
+
+ /* original last block */
+ for (j = 0; j < BLOCK_SIZE; j++) {
+ if (j < length) {
+ pad[j] = lastb[j];
+ } else if (j == length) {
+ pad[j] = 0x80;
+ } else {
+ pad[j] = 0x00;
+ }
+ }
+}
+
+/*
+ * Implementation of CMAC algorithm. When used with AES, this function
+ * is compatible with RFC 4493.
+ */
+krb5_error_code
+krb5int_cmac_checksum(const struct krb5_cksumtypes *ctp,
+ krb5_key key, krb5_keyusage usage,
+ const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output)
+{
+ const struct krb5_enc_provider *enc = ctp->enc;
+ unsigned char Y[BLOCK_SIZE], M_last[BLOCK_SIZE], padded[BLOCK_SIZE];
+ unsigned char K1[BLOCK_SIZE], K2[BLOCK_SIZE];
+ unsigned char input[BLOCK_SIZE];
+ unsigned int n, i, flag;
+ krb5_error_code ret;
+ struct iov_block_state iov_state;
+ unsigned int length;
+ krb5_data ivec;
+ krb5_crypto_iov iov[1];
+ krb5_data d;
+
+ assert(enc->cbc_mac != NULL);
+
+ if (enc->block_size != BLOCK_SIZE)
+ return KRB5_BAD_MSIZE;
+
+ for (i = 0, length = 0; i < num_data; i++) {
+ const krb5_crypto_iov *piov = &data[i];
+
+ if (SIGN_IOV(piov))
+ length += piov->data.length;
+ }
+
+ ret = generate_subkey(enc, key, K1, K2);
+ if (ret != 0)
+ return ret;
+
+ n = (length + BLOCK_SIZE - 1) / BLOCK_SIZE;
+
+ if (n == 0) {
+ n = 1;
+ flag = 0;
+ } else {
+ flag = ((length % BLOCK_SIZE) == 0);
+ }
+
+ iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[0].data = make_data((char *)input, BLOCK_SIZE);
+
+ memset(Y, 0, BLOCK_SIZE);
+
+ ivec = make_data((char *)Y, BLOCK_SIZE);
+ d = make_data((char *)Y, BLOCK_SIZE);
+
+ IOV_BLOCK_STATE_INIT(&iov_state);
+ iov_state.include_sign_only = 1;
+
+ for (i = 0; i < n - 1; i++) {
+ krb5int_c_iov_get_block(input, BLOCK_SIZE, data, num_data, &iov_state);
+
+ ret = enc->cbc_mac(key, iov, 1, &ivec, &d);
+ if (ret != 0)
+ return ret;
+ }
+
+ krb5int_c_iov_get_block(input, BLOCK_SIZE, data, num_data, &iov_state);
+
+ if (flag) {
+ /* last block is complete block */
+ xor_128(input, K1, M_last);
+ } else {
+ padding(input, padded, length % BLOCK_SIZE);
+ xor_128(padded, K2, M_last);
+ }
+
+ iov[0].data = make_data((char *)M_last, BLOCK_SIZE);
+
+ ret = enc->cbc_mac(key, iov, 1, &ivec, &d);
+ if (ret != 0)
+ return ret;
+
+ assert(output->length >= d.length);
+
+ output->length = d.length;
+ memcpy(output->data, d.data, d.length);
+
+ return ret;
+}
+
diff --git a/src/lib/crypto/krb/cksumtypes.c b/src/lib/crypto/krb/cksumtypes.c
index f0f4076..d757889 100644
--- a/src/lib/crypto/krb/cksumtypes.c
+++ b/src/lib/crypto/krb/cksumtypes.c
@@ -103,14 +103,14 @@ const struct krb5_cksumtypes krb5int_cksumtypes_list[] = {
{ CKSUMTYPE_CMAC_128_AES128,
"cmac-128-aes128", { 0 }, "CMAC AES128 key",
&krb5int_enc_aes128_ctr, NULL,
- krb5int_cmac_checksum, NULL,
- 16, 16, 0, &krb5int_enc_aes128 },
+ krb5int_dk_cmac_checksum, NULL,
+ 16, 16, 0 },
{ CKSUMTYPE_CMAC_128_AES256,
"cmac-128-aes256", { 0 }, "CMAC AES256 key",
&krb5int_enc_aes256_ctr, NULL,
- krb5int_cmac_checksum, NULL,
- 16, 16, 0, &krb5int_enc_aes256 },
+ krb5int_dk_cmac_checksum, NULL,
+ 16, 16, 0 },
#endif /* AES_CCM */
{ CKSUMTYPE_MD5_HMAC_ARCFOUR,
@@ -134,14 +134,14 @@ const struct krb5_cksumtypes krb5int_cksumtypes_list[] = {
{ CKSUMTYPE_CMAC_128_CAMELLIA128,
"cmac-128-camellia128", { 0 }, "CMAC Camellia128 key",
&krb5int_enc_camellia128_ctr, NULL,
- krb5int_cmac_checksum, NULL,
- 16, 16, 0, &krb5int_enc_camellia128 },
+ krb5int_dk_cmac_checksum, NULL,
+ 16, 16, 0 },
{ CKSUMTYPE_CMAC_128_CAMELLIA256,
"cmac-128-camellia256", { 0 }, "CMAC Camellia256 key",
&krb5int_enc_camellia256_ctr, NULL,
- krb5int_cmac_checksum, NULL,
- 16, 16, 0, &krb5int_enc_camellia256 },
+ krb5int_dk_cmac_checksum, NULL,
+ 16, 16, 0 },
};
const size_t krb5int_cksumtypes_length =
diff --git a/src/lib/crypto/krb/cksumtypes.h b/src/lib/crypto/krb/cksumtypes.h
index 8c32f66..ebc4e87 100644
--- a/src/lib/crypto/krb/cksumtypes.h
+++ b/src/lib/crypto/krb/cksumtypes.h
@@ -97,6 +97,12 @@ krb5_error_code krb5int_hmacmd5_checksum(const struct krb5_cksumtypes *ctp,
size_t num_data,
krb5_data *output);
+krb5_error_code krb5int_cmac_checksum(const struct krb5_cksumtypes *ctp,
+ krb5_key key, krb5_keyusage usage,
+ const krb5_crypto_iov *data,
+ size_t num_data,
+ krb5_data *output);
+
krb5_error_code krb5int_confounder_checksum(const struct krb5_cksumtypes *ctp,
krb5_key key, krb5_keyusage usage,
const krb5_crypto_iov *data,
diff --git a/src/lib/crypto/krb/dk/checksum_cmac.c b/src/lib/crypto/krb/dk/checksum_cmac.c
index d520920..a38f05f 100644
--- a/src/lib/crypto/krb/dk/checksum_cmac.c
+++ b/src/lib/crypto/krb/dk/checksum_cmac.c
@@ -23,21 +23,6 @@
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*/
-/*
- * Portions Copyright (C) The Internet Society (2006).
- *
- * This document is subject to the rights, licenses and restrictions
- * contained in BCP 78, and except as set forth therein, the authors
- * retain all their rights.
- *
- * This document and the information contained herein are provided on an
- * "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
- * OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
- * ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
- * INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
- * INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
- * WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- */
#include "k5-int.h"
#include "etypes.h"
@@ -47,200 +32,11 @@
#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
-#define BLOCK_SIZE 16
-
-static unsigned char const_Rb[BLOCK_SIZE] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87
-};
-
-static unsigned char const_Zero[BLOCK_SIZE] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static void
-xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
-{
- int z;
-
- for (z = 0; z < BLOCK_SIZE / 4; z++) {
- unsigned char *aptr = &a[z * 4];
- unsigned char *bptr = &b[z * 4];
- unsigned char *outptr = &out[z * 4];
-
- store_32_n(load_32_n(aptr) ^ load_32_n(bptr), outptr);
- }
-}
-
-static void
-leftshift_onebit(unsigned char *input, unsigned char *output)
-{
- int i;
- unsigned char overflow = 0;
-
- for (i = BLOCK_SIZE - 1; i >= 0; i--) {
- output[i] = input[i] << 1;
- output[i] |= overflow;
- overflow = (input[i] & 0x80) ? 1 : 0;
- }
-}
-
-static krb5_error_code
-generate_subkey(const struct krb5_cksumtypes *ctp,
- krb5_key key,
- unsigned char *K1,
- unsigned char *K2)
-{
- unsigned char Z[BLOCK_SIZE];
- unsigned char L[BLOCK_SIZE];
- unsigned char tmp[BLOCK_SIZE];
- krb5_crypto_iov iov[1];
- krb5_data d;
- krb5_error_code ret;
-
- memset(Z, 0, sizeof(Z));
- iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
- iov[0].data = make_data((char *)Z, sizeof(Z));
-
- d = make_data((char *)L, BLOCK_SIZE);
-
- /*
- * CBC in terms of CBC-MAC; at the cost of an additional XOR,
- * this avoids needing to extend the SPI interface (because we
- * need both the CBC-MAC function from the CCM provider and
- * the CBC function from the CTS provider).
- */
- ret = ctp->enc->cbc_mac(key, iov, 1, NULL, &d);
- if (ret != 0)
- return ret;
-
- xor_128(const_Zero, L, L);
-
- if ((L[0] & 0x80) == 0) {
- leftshift_onebit(L, K1);
- } else {
- leftshift_onebit(L, tmp);
- xor_128(tmp, const_Rb, K1);
- }
-
- if ((K1[0] & 0x80) == 0) {
- leftshift_onebit(K1, K2);
- } else {
- leftshift_onebit(K1, tmp);
- xor_128(tmp, const_Rb, K2);
- }
-
- return 0;
-}
-
-static void
-padding(unsigned char *lastb, unsigned char *pad, int length)
-{
- int j;
-
- /* original last block */
- for (j = 0; j < BLOCK_SIZE; j++) {
- if (j < length) {
- pad[j] = lastb[j];
- } else if (j == length) {
- pad[j] = 0x80;
- } else {
- pad[j] = 0x00;
- }
- }
-}
-
-/*
- * Implementation of CMAC algorithm. When used with AES, this function
- * is compatible with RFC 4493.
- */
-static krb5_error_code
-cmac128_checksum(const struct krb5_cksumtypes *ctp, krb5_key key,
- const krb5_crypto_iov *data, size_t num_data,
- krb5_data *output)
-{
- unsigned char Y[BLOCK_SIZE], M_last[BLOCK_SIZE], padded[BLOCK_SIZE];
- unsigned char K1[BLOCK_SIZE], K2[BLOCK_SIZE];
- unsigned char input[BLOCK_SIZE];
- unsigned int n, i, flag;
- krb5_error_code ret;
- struct iov_block_state iov_state;
- unsigned int length;
- krb5_data ivec;
- krb5_crypto_iov iov[1];
- krb5_data d;
-
- assert(ctp->enc->cbc_mac != NULL);
-
- for (i = 0, length = 0; i < num_data; i++) {
- const krb5_crypto_iov *piov = &data[i];
-
- if (SIGN_IOV(piov))
- length += piov->data.length;
- }
-
- ret = generate_subkey(ctp, key, K1, K2);
- if (ret != 0)
- return ret;
-
- n = (length + BLOCK_SIZE - 1) / BLOCK_SIZE;
-
- if (n == 0) {
- n = 1;
- flag = 0;
- } else {
- flag = ((length % BLOCK_SIZE) == 0);
- }
-
- iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
- iov[0].data = make_data((char *)input, BLOCK_SIZE);
-
- memset(Y, 0, BLOCK_SIZE);
-
- ivec = make_data((char *)Y, BLOCK_SIZE);
- d = make_data((char *)Y, BLOCK_SIZE);
-
- IOV_BLOCK_STATE_INIT(&iov_state);
- iov_state.include_sign_only = 1;
-
- for (i = 0; i < n - 1; i++) {
- krb5int_c_iov_get_block(input, BLOCK_SIZE, data, num_data, &iov_state);
-
- ret = ctp->enc->cbc_mac(key, iov, 1, &ivec, &d);
- if (ret != 0)
- return ret;
- }
-
- krb5int_c_iov_get_block(input, BLOCK_SIZE, data, num_data, &iov_state);
-
- if (flag) {
- /* last block is complete block */
- xor_128(input, K1, M_last);
- } else {
- padding(input, padded, length % BLOCK_SIZE);
- xor_128(padded, K2, M_last);
- }
-
- iov[0].data = make_data((char *)M_last, BLOCK_SIZE);
-
- ret = ctp->enc->cbc_mac(key, iov, 1, &ivec, &d);
- if (ret != 0)
- return ret;
-
- assert(output->length >= d.length);
-
- output->length = d.length;
- memcpy(output->data, d.data, d.length);
-
- return ret;
-}
-
krb5_error_code
-krb5int_cmac_checksum(const struct krb5_cksumtypes *ctp,
- krb5_key key, krb5_keyusage usage,
- const krb5_crypto_iov *data, size_t num_data,
- krb5_data *output)
+krb5int_dk_cmac_checksum(const struct krb5_cksumtypes *ctp,
+ krb5_key key, krb5_keyusage usage,
+ const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output)
{
const struct krb5_keytypes *ktp;
const struct krb5_enc_provider *enc;
@@ -249,9 +45,6 @@ krb5int_cmac_checksum(const struct krb5_cksumtypes *ctp,
krb5_data datain;
krb5_key kc;
- if (ctp->compute_size != BLOCK_SIZE)
- return KRB5_BAD_MSIZE;
-
/* Use the key's enctype (more flexible than setting an enctype in ctp). */
ktp = find_enctype(key->keyblock.enctype);
if (ktp == NULL)
@@ -259,6 +52,8 @@ krb5int_cmac_checksum(const struct krb5_cksumtypes *ctp,
enc = ktp->enc;
if (key->keyblock.length != enc->keylength)
return KRB5_BAD_KEYSIZE;
+ if (ctp->compute_size != enc->block_size)
+ return KRB5_BAD_MSIZE;
/* Derive the key. */
datain = make_data(constantdata, K5CLENGTH);
@@ -269,7 +64,7 @@ krb5int_cmac_checksum(const struct krb5_cksumtypes *ctp,
return ret;
/* Hash the data. */
- ret = cmac128_checksum(ctp, kc, data, num_data, output);
+ ret = krb5int_cmac_checksum(ctp, kc, usage, data, num_data, output);
if (ret != 0)
memset(output->data, 0, output->length);
diff --git a/src/lib/crypto/krb/dk/dk.h b/src/lib/crypto/krb/dk/dk.h
index 360492b..04223e6 100644
--- a/src/lib/crypto/krb/dk/dk.h
+++ b/src/lib/crypto/krb/dk/dk.h
@@ -107,7 +107,7 @@ krb5int_ccm_decrypt(const struct krb5_keytypes *ktp,
size_t num_data);
krb5_error_code
-krb5int_cmac_checksum(const struct krb5_cksumtypes *ctp,
- krb5_key key, krb5_keyusage usage,
- const krb5_crypto_iov *data, size_t num_data,
- krb5_data *output);
+krb5int_dk_cmac_checksum(const struct krb5_cksumtypes *ctp,
+ krb5_key key, krb5_keyusage usage,
+ const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output);
diff --git a/src/lib/crypto/krb/prf/ccm_prf.c b/src/lib/crypto/krb/prf/ccm_prf.c
index b384e07..aeef7a5 100644
--- a/src/lib/crypto/krb/prf/ccm_prf.c
+++ b/src/lib/crypto/krb/prf/ccm_prf.c
@@ -37,11 +37,15 @@ krb5_error_code
krb5int_ccm_prf(const struct krb5_keytypes *ktp, krb5_key key,
const krb5_data *in, krb5_data *out)
{
+ struct krb5_cksumtypes ctp;
krb5_crypto_iov iov;
krb5_data prfconst = make_data("prf", 3);
krb5_key kp = NULL;
krb5_error_code ret;
+ if (ktp->prf_length != ktp->enc->block_size)
+ return KRB5_BAD_MSIZE;
+
iov.flags = KRB5_CRYPTO_TYPE_DATA;
iov.data = *in;
@@ -50,7 +54,11 @@ krb5int_ccm_prf(const struct krb5_keytypes *ktp, krb5_key key,
if (ret != 0)
goto cleanup;
- ret = ktp->enc->cbc_mac(kp, &iov, 1, NULL, out);
+ memset(&ctp, 0, sizeof(ctp));
+ ctp.enc = ktp->enc;
+
+ /* Similar to RFC 4615, PRF is CMAC of input */
+ ret = krb5int_cmac_checksum(&ctp, kp, 0, &iov, 1, out);
if (ret != 0)
goto cleanup;