Implement Camellia-CTS-CMAC instead of Camellia-CCM
authorGreg Hudson <ghudson@mit.edu>
Sat, 20 Nov 2010 00:31:46 +0000 (00:31 +0000)
committerGreg Hudson <ghudson@mit.edu>
Sat, 20 Nov 2010 00:31:46 +0000 (00:31 +0000)
Replace the Camellia-CCM enctypes with Camellia-CTS-CMAC.  Still not
compiled in by default since we don't have enctype assignments yet.

ticket: 6822
target_verion: 1.9
tags: pullup

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24524 dc483132-0cff-0310-8789-dd5450dbe970

43 files changed:
src/include/k5-int.h
src/lib/crypto/builtin/camellia/camellia-gen.c
src/lib/crypto/builtin/camellia/camellia.c
src/lib/crypto/builtin/enc_provider/Makefile.in
src/lib/crypto/builtin/enc_provider/camellia.c [new file with mode: 0644]
src/lib/crypto/builtin/enc_provider/camellia_ctr.c [deleted file]
src/lib/crypto/builtin/enc_provider/enc_provider.h
src/lib/crypto/crypto_tests/Makefile.in
src/lib/crypto/crypto_tests/camellia-test.c
src/lib/crypto/crypto_tests/t_camellia_ccm.c [deleted file]
src/lib/crypto/crypto_tests/t_cksums.c [new file with mode: 0644]
src/lib/crypto/crypto_tests/t_cmac.c
src/lib/crypto/crypto_tests/t_decrypt.c [new file with mode: 0644]
src/lib/crypto/crypto_tests/t_derive.c [new file with mode: 0644]
src/lib/crypto/crypto_tests/t_encrypt.c
src/lib/crypto/crypto_tests/t_short.c
src/lib/crypto/crypto_tests/t_str2key.c
src/lib/crypto/krb/checksum/cmac.c
src/lib/crypto/krb/cksumtypes.c
src/lib/crypto/krb/dk/Makefile.in
src/lib/crypto/krb/dk/checksum_cmac.c
src/lib/crypto/krb/dk/derive.c
src/lib/crypto/krb/dk/dk.h
src/lib/crypto/krb/dk/dk_ccm.c [deleted file]
src/lib/crypto/krb/dk/dk_cmac.c [new file with mode: 0644]
src/lib/crypto/krb/dk/stringtokey.c
src/lib/crypto/krb/etypes.c
src/lib/crypto/krb/prf/cmac_prf.c
src/lib/crypto/libk5crypto.exports
src/lib/crypto/nss/enc_provider/camellia.c
src/lib/crypto/nss/enc_provider/enc_gen.c
src/lib/crypto/nss/enc_provider/enc_provider.h
src/lib/crypto/nss/nss_gen.h
src/lib/crypto/openssl/enc_provider/Makefile.in
src/lib/crypto/openssl/enc_provider/camellia.c [new file with mode: 0644]
src/lib/crypto/openssl/enc_provider/camellia_ctr.c [deleted file]
src/lib/crypto/openssl/enc_provider/enc_provider.h
src/lib/krb5/krb/init_ctx.c
src/lib/krb5/krb/t_etypes.c
src/tests/dejagnu/config/default.exp
src/util/k5test.py
src/windows/identity/plugins/krb5/datarep.c
src/windows/identity/plugins/krb5/lang/en_us/langres.rc

index db879663b4a51f48acd6b4c2ecdd13a54a0b0e97..446c1fa740eba566975bee4ec4235c91c19cc8fe 100644 (file)
@@ -2687,23 +2687,23 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
 #if 0
 /*
  * There are no IANA assignments for these enctypes or cksumtypes yet.  They
- * must be defined to local-use negative numbers at build time for Camellia-CCM
+ * must be defined to local-use negative numbers at build time for Camellia
  * support to function at the moment.  If one is defined, they should all be
  * defined.  When IANA assignments exist, these definitions should move to the
- * appropriate places in krb5.hin and all CAMELLIA_CCM conditional code should
- * be made unconditional.
+ * appropriate places in krb5.hin and all CAMELLIA conditional code should be
+ * made unconditional.
  *
  * The present code is experimental and may not be compatible with the
  * standardized version.
  */
-#define ENCTYPE_CAMELLIA128_CCM_128 -XXX /* Camellia CCM mode, 128-bit key */
-#define ENCTYPE_CAMELLIA256_CCM_128 -YYY /* Camellia CCM mode, 256-bit key */
-#define CKSUMTYPE_CMAC_128_CAMELLIA128  -XXX  /* CMAC, 128-bit Camellia key */
-#define CKSUMTYPE_CMAC_128_CAMELLIA256  -YYY  /* CMAC, 256-bit Camellia key */
+#define ENCTYPE_CAMELLIA128_CTS_CMAC -XXX /* Camellia CTS mode, 128-bit key */
+#define ENCTYPE_CAMELLIA256_CTS_CMAC -YYY /* Camellia CTS mode, 256-bit key */
+#define CKSUMTYPE_CMAC_CAMELLIA128 -XXX   /* CMAC, 128-bit Camellia key */
+#define CKSUMTYPE_CMAC_CAMELLIA256 -YYY   /* CMAC, 256-bit Camellia key */
 #endif
 
-#ifdef ENCTYPE_CAMELLIA128_CCM_128
-#define CAMELLIA_CCM
+#ifdef ENCTYPE_CAMELLIA128_CTS_CMAC
+#define CAMELLIA
 #endif
 
 struct _krb5_kt {       /* should move into k5-int.h */
index bbe64d039fcd396f2213de23599857b8b7462cbd..a9831671515850d5adf1f4c273d5c47de9bdeece 100644 (file)
@@ -8,7 +8,7 @@
 #include <unistd.h>
 #include "camellia.h"
 
-#ifdef CAMELLIA_CCM
+#ifdef CAMELLIA
 
 #define B 16U
 unsigned char key[16];
@@ -316,11 +316,11 @@ static void cts_test ()
     printf ("\n");
 }
 
-#endif /* CAMELLIA_CCM */
+#endif /* CAMELLIA */
 
 int main ()
 {
-#ifdef CAMELLIA_CCM
+#ifdef CAMELLIA
     init ();
     fips_test ();
 
index 1b8cc46dddf12f1d2a7badc68e3c0b236d0d95d2..30998d0437d2341fee6651148502b82225f5e785 100644 (file)
@@ -36,7 +36,8 @@
 
 #include "camellia.h"
 
-#ifdef CAMELLIA_CCM
+#include "k5-int.h" /* Only for CAMELLIA; remove later. */
+#ifdef CAMELLIA
 
 /* key constants */
 
@@ -1540,4 +1541,4 @@ camellia_dec_blk(const unsigned char in_blk[],  unsigned char out_blk[],
     return camellia_good;
 }
 
-#endif /* CAMELLIA_CCM */
+#endif /* CAMELLIA */
index f3d4a0b2c354b2c8c70f85544ad83c9ceae864da..aadec6e6a818007b9502045e9aa60577454bf536 100644 (file)
@@ -21,20 +21,20 @@ STLIBOBJS= \
        des3.o  \
        rc4.o   \
        aes.o   \
-       camellia_ctr.o
+       camellia.o
 
 OBJS= \
        $(OUTPRE)des.$(OBJEXT)  \
        $(OUTPRE)des3.$(OBJEXT)         \
        $(OUTPRE)aes.$(OBJEXT)  \
-       $(OUTPRE)camellia_ctr.$(OBJEXT) \
+       $(OUTPRE)camellia.$(OBJEXT)     \
        $(OUTPRE)rc4.$(OBJEXT)
 
 SRCS= \
        $(srcdir)/des.c         \
        $(srcdir)/des3.c        \
        $(srcdir)/aes.c         \
-       $(srcdir)/camellia_ctr.c\
+       $(srcdir)/camellia.c    \
        $(srcdir)/rc4.c
 
 ##DOS##LIBOBJS = $(OBJS)
diff --git a/src/lib/crypto/builtin/enc_provider/camellia.c b/src/lib/crypto/builtin/enc_provider/camellia.c
new file mode 100644 (file)
index 0000000..566f2d7
--- /dev/null
@@ -0,0 +1,366 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/enc_provider/camellia.c - Camellia enc provider definition */
+/*
+ * Copyright (C) 2009, 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.
+ */
+
+#include "k5-int.h"
+#include "enc_provider.h"
+#include "camellia.h"
+#include <aead.h>
+#include <rand2key.h>
+
+#ifdef CAMELLIA
+
+/*
+ * Private per-key data to cache after first generation.  We don't want to mess
+ * with the imported Cemallia implementation too much, so we'll just use two
+ * copies of its context, one for encryption and one for decryption, and use
+ * the #rounds field as a flag for whether we've initialized each half.
+ */
+struct camellia_key_info_cache {
+    camellia_ctx enc_ctx, dec_ctx;
+};
+#define CACHE(X) ((struct camellia_key_info_cache *)((X)->cache))
+
+static inline void
+enc(unsigned char *out, const unsigned char *in, camellia_ctx *ctx)
+{
+    if (camellia_enc_blk(in, out, ctx) != camellia_good)
+        abort();
+}
+
+static inline void
+dec(unsigned char *out, const unsigned char *in, camellia_ctx *ctx)
+{
+    if (camellia_dec_blk(in, out, ctx) != camellia_good)
+        abort();
+}
+
+static void
+xorblock(unsigned char *out, const unsigned char *in)
+{
+    int z;
+    for (z = 0; z < BLOCK_SIZE/4; z++) {
+        unsigned char *outptr = &out[z*4];
+        const unsigned char *inptr = &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 krb5_error_code
+krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec,
+                        krb5_crypto_iov *data, size_t num_data)
+{
+    unsigned char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE];
+    int nblocks = 0, blockno;
+    size_t input_length, i;
+    struct iov_block_state input_pos, output_pos;
+
+    if (key->cache == NULL) {
+        key->cache = malloc(sizeof(struct camellia_key_info_cache));
+        if (key->cache == NULL)
+            return ENOMEM;
+        CACHE(key)->enc_ctx.keybitlen = CACHE(key)->dec_ctx.keybitlen = 0;
+    }
+    if (CACHE(key)->enc_ctx.keybitlen == 0) {
+        if (camellia_enc_key(key->keyblock.contents, key->keyblock.length,
+                            &CACHE(key)->enc_ctx) != camellia_good)
+            abort();
+    }
+    if (ivec != NULL)
+        memcpy(tmp, ivec->data, BLOCK_SIZE);
+    else
+        memset(tmp, 0, BLOCK_SIZE);
+
+    for (i = 0, input_length = 0; i < num_data; i++) {
+        krb5_crypto_iov *iov = &data[i];
+
+        if (ENCRYPT_IOV(iov))
+            input_length += iov->data.length;
+    }
+
+    IOV_BLOCK_STATE_INIT(&input_pos);
+    IOV_BLOCK_STATE_INIT(&output_pos);
+
+    nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
+    if (nblocks == 1) {
+        krb5int_c_iov_get_block(tmp, BLOCK_SIZE, data, num_data, &input_pos);
+        enc(tmp2, tmp, &CACHE(key)->enc_ctx);
+        krb5int_c_iov_put_block(data, num_data, tmp2, BLOCK_SIZE, &output_pos);
+    } else if (nblocks > 1) {
+        unsigned char blockN2[BLOCK_SIZE];   /* second last */
+        unsigned char blockN1[BLOCK_SIZE];   /* last block */
+
+        for (blockno = 0; blockno < nblocks - 2; blockno++) {
+            unsigned char blockN[BLOCK_SIZE], *block;
+
+            krb5int_c_iov_get_block_nocopy(blockN, BLOCK_SIZE,
+                                           data, num_data, &input_pos, &block);
+            xorblock(tmp, block);
+            enc(block, tmp, &CACHE(key)->enc_ctx);
+            krb5int_c_iov_put_block_nocopy(data, num_data, blockN, BLOCK_SIZE,
+                                           &output_pos, block);
+
+            /* Set up for next block.  */
+            memcpy(tmp, block, BLOCK_SIZE);
+        }
+
+        /* Do final CTS step for last two blocks (the second of which
+           may or may not be incomplete).  */
+
+        /* First, get the last two blocks */
+        memset(blockN1, 0, sizeof(blockN1)); /* pad last block with zeros */
+        krb5int_c_iov_get_block(blockN2, BLOCK_SIZE, data, num_data,
+                                &input_pos);
+        krb5int_c_iov_get_block(blockN1, BLOCK_SIZE, data, num_data,
+                                &input_pos);
+
+        /* Encrypt second last block */
+        xorblock(tmp, blockN2);
+        enc(tmp2, tmp, &CACHE(key)->enc_ctx);
+        memcpy(blockN2, tmp2, BLOCK_SIZE); /* blockN2 now contains first block */
+        memcpy(tmp, tmp2, BLOCK_SIZE);
+
+        /* Encrypt last block */
+        xorblock(tmp, blockN1);
+        enc(tmp2, tmp, &CACHE(key)->enc_ctx);
+        memcpy(blockN1, tmp2, BLOCK_SIZE);
+
+        /* Put the last two blocks back into the iovec (reverse order) */
+        krb5int_c_iov_put_block(data, num_data, blockN1, BLOCK_SIZE,
+                                &output_pos);
+        krb5int_c_iov_put_block(data, num_data, blockN2, BLOCK_SIZE,
+                                &output_pos);
+
+        if (ivec != NULL)
+            memcpy(ivec->data, blockN1, BLOCK_SIZE);
+    }
+
+    return 0;
+}
+
+static krb5_error_code
+krb5int_camellia_decrypt(krb5_key key, const krb5_data *ivec,
+                        krb5_crypto_iov *data, size_t num_data)
+{
+    unsigned char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE], tmp3[BLOCK_SIZE];
+    int nblocks = 0, blockno;
+    unsigned int i;
+    size_t input_length;
+    struct iov_block_state input_pos, output_pos;
+
+    if (key->cache == NULL) {
+        key->cache = malloc(sizeof(struct camellia_key_info_cache));
+        if (key->cache == NULL)
+            return ENOMEM;
+        CACHE(key)->enc_ctx.keybitlen = CACHE(key)->dec_ctx.keybitlen = 0;
+    }
+    if (CACHE(key)->dec_ctx.keybitlen == 0) {
+        if (camellia_dec_key(key->keyblock.contents, key->keyblock.length,
+                            &CACHE(key)->dec_ctx) != camellia_good)
+            abort();
+    }
+
+    if (ivec != NULL)
+        memcpy(tmp, ivec->data, BLOCK_SIZE);
+    else
+        memset(tmp, 0, BLOCK_SIZE);
+
+    for (i = 0, input_length = 0; i < num_data; i++) {
+        krb5_crypto_iov *iov = &data[i];
+
+        if (ENCRYPT_IOV(iov))
+            input_length += iov->data.length;
+    }
+
+    IOV_BLOCK_STATE_INIT(&input_pos);
+    IOV_BLOCK_STATE_INIT(&output_pos);
+
+    nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
+    if (nblocks == 1) {
+        krb5int_c_iov_get_block(tmp, BLOCK_SIZE, data, num_data, &input_pos);
+        dec(tmp2, tmp, &CACHE(key)->dec_ctx);
+        krb5int_c_iov_put_block(data, num_data, tmp2, BLOCK_SIZE, &output_pos);
+    } else if (nblocks > 1) {
+        unsigned char blockN2[BLOCK_SIZE];   /* second last */
+        unsigned char blockN1[BLOCK_SIZE];   /* last block */
+
+        for (blockno = 0; blockno < nblocks - 2; blockno++) {
+            unsigned char blockN[BLOCK_SIZE], *block;
+
+            krb5int_c_iov_get_block_nocopy(blockN, BLOCK_SIZE,
+                                           data, num_data, &input_pos, &block);
+            memcpy(tmp2, block, BLOCK_SIZE);
+            dec(block, block, &CACHE(key)->dec_ctx);
+            xorblock(block, tmp);
+            memcpy(tmp, tmp2, BLOCK_SIZE);
+            krb5int_c_iov_put_block_nocopy(data, num_data, blockN, BLOCK_SIZE,
+                                           &output_pos, block);
+        }
+
+        /* Do last two blocks, the second of which (next-to-last block
+           of plaintext) may be incomplete.  */
+
+        /* First, get the last two encrypted blocks */
+        memset(blockN1, 0, sizeof(blockN1)); /* pad last block with zeros */
+        krb5int_c_iov_get_block(blockN2, BLOCK_SIZE, data, num_data,
+                                &input_pos);
+        krb5int_c_iov_get_block(blockN1, BLOCK_SIZE, data, num_data,
+                                &input_pos);
+
+        if (ivec != NULL)
+            memcpy(ivec->data, blockN2, BLOCK_SIZE);
+
+        /* Decrypt second last block */
+        dec(tmp2, blockN2, &CACHE(key)->dec_ctx);
+        /* Set tmp2 to last (possibly partial) plaintext block, and
+           save it.  */
+        xorblock(tmp2, blockN1);
+        memcpy(blockN2, tmp2, BLOCK_SIZE);
+
+        /* Maybe keep the trailing part, and copy in the last
+           ciphertext block.  */
+        input_length %= BLOCK_SIZE;
+        memcpy(tmp2, blockN1, input_length ? input_length : BLOCK_SIZE);
+        dec(tmp3, tmp2, &CACHE(key)->dec_ctx);
+        xorblock(tmp3, tmp);
+        memcpy(blockN1, tmp3, BLOCK_SIZE);
+
+        /* Put the last two blocks back into the iovec */
+        krb5int_c_iov_put_block(data, num_data, blockN1, BLOCK_SIZE,
+                                &output_pos);
+        krb5int_c_iov_put_block(data, num_data, blockN2, BLOCK_SIZE,
+                                &output_pos);
+    }
+
+    return 0;
+}
+
+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)
+{
+    camellia_ctx ctx;
+    unsigned char blockY[BLOCK_SIZE];
+    struct iov_block_state iov_state;
+
+    if (output->length < BLOCK_SIZE)
+        return KRB5_BAD_MSIZE;
+
+    if (camellia_enc_key(key->keyblock.contents,
+                         key->keyblock.length, &ctx) != camellia_good)
+        abort();
+
+    if (iv != NULL)
+        memcpy(blockY, iv->data, BLOCK_SIZE);
+    else
+        memset(blockY, 0, BLOCK_SIZE);
+
+    IOV_BLOCK_STATE_INIT(&iov_state);
+    for (;;) {
+        unsigned char blockB[BLOCK_SIZE];
+
+        if (!krb5int_c_iov_get_block(blockB, BLOCK_SIZE, data, num_data,
+                                    &iov_state))
+            break;
+
+        xorblock(blockB, blockY);
+        if (camellia_enc_blk(blockB, blockY, &ctx) != camellia_good)
+            abort();
+    }
+
+    output->length = BLOCK_SIZE;
+    memcpy(output->data, blockY, BLOCK_SIZE);
+
+    return 0;
+}
+
+static krb5_error_code
+camellia_init_state(const krb5_keyblock *key, krb5_keyusage usage,
+                   krb5_data *state)
+{
+    state->length = 16;
+    state->data = malloc(16);
+    if (state->data == NULL)
+        return ENOMEM;
+    memset(state->data, 0, state->length);
+    return 0;
+}
+
+const struct krb5_enc_provider krb5int_enc_camellia128 = {
+    16,
+    16, 16,
+    krb5int_camellia_encrypt,
+    krb5int_camellia_decrypt,
+    krb5int_camellia_cbc_mac,
+    krb5int_camellia_make_key,
+    camellia_init_state,
+    krb5int_default_free_state,
+};
+
+const struct krb5_enc_provider krb5int_enc_camellia256 = {
+    16,
+    32, 32,
+    krb5int_camellia_encrypt,
+    krb5int_camellia_decrypt,
+    krb5int_camellia_cbc_mac,
+    krb5int_camellia_make_key,
+    camellia_init_state,
+    krb5int_default_free_state
+};
+
+#else /* CAMELLIA */
+
+/* These won't be used, but are still in the export table. */
+
+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)
+{
+    return EINVAL;
+}
+
+const struct krb5_enc_provider krb5int_enc_camellia128 = {
+};
+
+const struct krb5_enc_provider krb5int_enc_camellia256 = {
+};
+
+#endif /* CAMELLIA */
diff --git a/src/lib/crypto/builtin/enc_provider/camellia_ctr.c b/src/lib/crypto/builtin/enc_provider/camellia_ctr.c
deleted file mode 100644 (file)
index 8171ab6..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * lib/crypto/builtin/enc_provider/camellia_ctr.c
- *
- * Copyright (C) 2003, 2007-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.
- */
-
-#include "k5-int.h"
-#include "enc_provider.h"
-#include "camellia.h"
-#include <aead.h>
-#include <rand2key.h>
-
-#ifdef CAMELLIA_CCM
-
-static void
-xorblock(unsigned char *out, const unsigned char *in)
-{
-    int z;
-    for (z = 0; z < 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);
-    }
-}
-
-/* Get the current counter block number from the IV */
-static inline void getctrblockno(krb5_ui_8 *pblockno,
-                                const unsigned char ctr[BLOCK_SIZE])
-{
-    *pblockno = load_64_be(&ctr[BLOCK_SIZE - 8]);
-}
-
-/* Store the current counter block number in the IV */
-static inline void putctrblockno(krb5_ui_8 blockno,
-                                unsigned char ctr[BLOCK_SIZE])
-{
-    store_64_be(blockno, &ctr[BLOCK_SIZE - 8]);
-}
-
-/*
- * ivec must be a correctly formatted counter block per NIST SP800-38C A.3.
- */
-static krb5_error_code
-krb5int_camellia_encrypt_ctr(krb5_key key, const krb5_data *ivec,
-                             krb5_crypto_iov *data, size_t num_data)
-{
-    camellia_ctx ctx;
-    unsigned char ctr[BLOCK_SIZE];
-    krb5_ui_8 blockno;
-    struct iov_block_state input_pos, output_pos;
-
-    if (camellia_enc_key(key->keyblock.contents,
-                         key->keyblock.length, &ctx) != camellia_good)
-        abort();
-
-    IOV_BLOCK_STATE_INIT(&input_pos);
-    IOV_BLOCK_STATE_INIT(&output_pos);
-
-    /* Don't encrypt the header (B0), and use zero instead of IOV padding. */
-    input_pos.ignore_header = output_pos.ignore_header = 1;
-    input_pos.pad_to_boundary = output_pos.pad_to_boundary = 1;
-
-    if (ivec == NULL)
-       return EINVAL;
-    if (ivec->length != BLOCK_SIZE)
-        return KRB5_BAD_MSIZE;
-
-    memcpy(ctr, ivec->data, BLOCK_SIZE);
-
-    getctrblockno(&blockno, ctr);
-
-    for (;;) {
-        unsigned char storage[BLOCK_SIZE], *block;
-        unsigned char ectr[BLOCK_SIZE];
-
-        if (!krb5int_c_iov_get_block_nocopy(storage, BLOCK_SIZE, data,
-                                           num_data, &input_pos, &block))
-            break;
-
-        if (camellia_enc_blk(ctr, ectr, &ctx) != camellia_good)
-            abort();
-
-        xorblock(block, ectr);
-        krb5int_c_iov_put_block_nocopy(data, num_data, storage, BLOCK_SIZE,
-                                       &output_pos, block);
-        putctrblockno(++blockno, ctr);
-    }
-
-    if (ivec != NULL)
-        memcpy(ivec->data, ctr, sizeof(ctr));
-
-    return 0;
-}
-
-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)
-{
-    camellia_ctx ctx;
-    unsigned char blockY[BLOCK_SIZE];
-    struct iov_block_state iov_state;
-
-    if (output->length < BLOCK_SIZE)
-        return KRB5_BAD_MSIZE;
-
-    if (camellia_enc_key(key->keyblock.contents,
-                         key->keyblock.length, &ctx) != camellia_good)
-        abort();
-
-    if (iv != NULL)
-        memcpy(blockY, iv->data, BLOCK_SIZE);
-    else
-        memset(blockY, 0, BLOCK_SIZE);
-
-    IOV_BLOCK_STATE_INIT(&iov_state);
-
-    /*
-     * The CCM header may not fit in a block, because it includes a variable
-     * length encoding of the associated data length.  This encoding plus the
-     * associated data itself is padded to the block size.
-     */
-    iov_state.include_sign_only = 1;
-    iov_state.pad_to_boundary = 1;
-
-    for (;;) {
-        unsigned char blockB[BLOCK_SIZE];
-
-        if (!krb5int_c_iov_get_block(blockB, BLOCK_SIZE, data, num_data,
-                                    &iov_state))
-            break;
-
-        xorblock(blockB, blockY);
-
-        if (camellia_enc_blk(blockB, blockY, &ctx) != camellia_good)
-            abort();
-    }
-
-    output->length = BLOCK_SIZE;
-    memcpy(output->data, blockY, BLOCK_SIZE);
-
-    return 0;
-}
-
-static krb5_error_code
-krb5int_camellia_init_state_ctr(const krb5_keyblock *key, krb5_keyusage usage,
-                               krb5_data *state)
-{
-    return alloc_data(state, 16);
-}
-
-const struct krb5_enc_provider krb5int_enc_camellia128_ctr = {
-    16,
-    16, 16,
-    krb5int_camellia_encrypt_ctr,
-    krb5int_camellia_encrypt_ctr,
-    krb5int_camellia_cbc_mac,
-    krb5int_camellia_make_key,
-    krb5int_camellia_init_state_ctr,
-    krb5int_default_free_state,
-    NULL
-};
-
-const struct krb5_enc_provider krb5int_enc_camellia256_ctr = {
-    16,
-    32, 32,
-    krb5int_camellia_encrypt_ctr,
-    krb5int_camellia_encrypt_ctr,
-    krb5int_camellia_cbc_mac,
-    krb5int_camellia_make_key,
-    krb5int_camellia_init_state_ctr,
-    krb5int_default_free_state,
-    NULL
-};
-
-#else /* CAMELLIA_CCM */
-
-/* These won't be used, but is still in the export table. */
-
-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)
-{
-    return EINVAL;
-}
-
-const struct krb5_enc_provider krb5int_enc_camellia128_ctr = {
-};
-
-#endif /* CAMELLIA_CCM */
index 39175d1b912ae5657ee973937a25e95769482e65..e7afb31019d2165e8ce035d4b9ce36c5294739d9 100644 (file)
@@ -32,7 +32,7 @@ extern const struct krb5_enc_provider krb5int_enc_des3;
 extern const struct krb5_enc_provider krb5int_enc_arcfour;
 extern const struct krb5_enc_provider krb5int_enc_aes128;
 extern const struct krb5_enc_provider krb5int_enc_aes256;
-#ifdef CAMELLIA_CCM
-extern const struct krb5_enc_provider krb5int_enc_camellia128_ctr;
-extern const struct krb5_enc_provider krb5int_enc_camellia256_ctr;
+#ifdef CAMELLIA
+extern const struct krb5_enc_provider krb5int_enc_camellia128;
+extern const struct krb5_enc_provider krb5int_enc_camellia256;
 #endif
index 158972bbe27397f7b5423297e46b24fd0dda72a5..06b1745e9227a9b8c8dbd895f0ff8d043f72a93b 100644 (file)
@@ -18,6 +18,7 @@ DEFS=
 EXTRADEPSRCS=\
        $(srcdir)/t_nfold.c     \
        $(srcdir)/t_encrypt.c   \
+       $(srcdir)/t_decrypt.c   \
        $(srcdir)/t_prf.c       \
        $(srcdir)/t_prng.c      \
        $(srcdir)/t_cmac.c      \
@@ -28,11 +29,13 @@ EXTRADEPSRCS=\
        $(srcdir)/aes-test.c    \
        $(srcdir)/camellia-test.c       \
        $(srcdir)/t_cksum.c     \
+       $(srcdir)/t_cksums.c    \
        $(srcdir)/t_crc.c       \
        $(srcdir)/t_mddriver.c  \
        $(srcdir)/t_kperf.c     \
        $(srcdir)/t_short.c     \
        $(srcdir)/t_str2key.c   \
+       $(srcdir)/t_derive.c    \
        $(srcdir)/t_fork.c      \
        $(srcdir)/ytest.c       
 
@@ -50,14 +53,15 @@ EXTRADEPSRCS=\
 #
 # We use the NSS PRNG when NSS is the crypto back end, so don't test
 # against the expected output for Yarrow.
-check-unix:: t_nfold t_encrypt t_prf t_prng t_cmac t_hmac \
-               t_cksum4 t_cksum5 \
+check-unix:: t_nfold t_encrypt t_decrypt t_prf t_prng t_cmac t_hmac \
+               t_cksum4 t_cksum5 t_cksums \
                aes-test  \
                camellia-test  \
                t_mddriver4 t_mddriver \
-               t_crc t_cts t_short t_str2key t_fork t_camellia_ccm
+               t_crc t_cts t_short t_str2key t_derive t_fork
        $(RUN_SETUP) $(VALGRIND) ./t_nfold
        $(RUN_SETUP) $(VALGRIND) ./t_encrypt
+       $(RUN_SETUP) $(VALGRIND) ./t_decrypt
        $(RUN_SETUP) $(VALGRIND) ./t_prng <$(srcdir)/t_prng.seed >t_prng.output
        if [ @PRNG_ALG@ = yarrow ]; then \
                diff t_prng.output $(srcdir)/t_prng.expected; \
@@ -68,6 +72,7 @@ check-unix:: t_nfold t_encrypt t_prf t_prng t_cmac t_hmac \
        diff t_prf.output $(srcdir)/t_prf.expected
        $(RUN_SETUP) $(VALGRIND) ./t_cksum4 "this is a test" e3f76a07f3401e3536b43a3f54226c39422c35682c354835
        $(RUN_SETUP) $(VALGRIND) ./t_cksum5 "this is a test" e3f76a07f3401e351143ee6f4c09be1edb4264d55015db53
+       $(RUN_SETUP) $(VALGRIND) ./t_cksums
        $(RUN_SETUP) $(VALGRIND) ./t_crc
        $(RUN_SETUP) $(VALGRIND) ./t_cts
        $(RUN_SETUP) $(VALGRIND) ./aes-test -k > vk.txt
@@ -75,14 +80,14 @@ check-unix:: t_nfold t_encrypt t_prf t_prng t_cmac t_hmac \
        $(RUN_SETUP) $(VALGRIND) ./aes-test > vt.txt
        cmp vt.txt $(srcdir)/expect-vt.txt
        $(RUN_SETUP) $(VALGRIND) ./camellia-test > camellia-vt.txt
-# Enable this when Camellia-CCM becomes unconditional.
+# Enable this when Camellia becomes unconditional.
 #      cmp camellia-vt.txt $(srcdir)/camellia-expect-vt.txt
        $(RUN_SETUP) $(VALGRIND) $(C)t_mddriver4 -x
        $(RUN_SETUP) $(VALGRIND) $(C)t_mddriver -x
        $(RUN_SETUP) $(VALGRIND) ./t_short
        $(RUN_SETUP) $(VALGRIND) ./t_str2key
+       $(RUN_SETUP) $(VALGRIND) ./t_derive
        $(RUN_SETUP) $(VALGRIND) ./t_fork
-       $(RUN_SETUP) $(VALGRIND) ./t_camellia_ccm
 
 
 
@@ -98,6 +103,9 @@ nfold.$(OBJEXT): $(srcdir)/../krb/nfold.c
 t_encrypt$(EXEEXT): t_encrypt.$(OBJEXT) $(CRYPTO_DEPLIB) $(SUPPORT_DEPLIB)
        $(CC_LINK) -o $@ t_encrypt.$(OBJEXT)  -lkrb5 -lk5crypto -lcom_err $(SUPPORT_LIB)
 
+t_decrypt$(EXEEXT): t_decrypt.$(OBJEXT) $(CRYPTO_DEPLIB) $(SUPPORT_DEPLIB)
+       $(CC_LINK) -o $@ t_decrypt.$(OBJEXT)  -lkrb5 -lk5crypto -lcom_err $(SUPPORT_LIB)
+
 t_prf$(EXEEXT): t_prf.$(OBJEXT) $(SUPPORT_DEPLIB)
        $(CC_LINK) -o $@ t_prf.$(OBJEXT)  -lkrb5 -lk5crypto -lcom_err $(SUPPORT_LIB)
 
@@ -136,6 +144,9 @@ t_cksum4: t_cksum4.o $(CRYTPO_DEPLIB)
 t_cksum5: t_cksum5.o $(CRYPTO_DEPLIB)
        $(CC_LINK) -o t_cksum5 t_cksum5.o $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(LIBS)
 
+t_cksums: t_cksums.o $(CRYTPO_DEPLIB)
+       $(CC_LINK) -o t_cksums t_cksums.o -lkrb5 $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(LIBS)
+
 t_crc: t_crc.o $(CRYPTO_DEPLIB) $(SUPPORT_DEPLIB)
        $(CC_LINK) -o $@ t_crc.o $(K5CRYPTO_LIB) $(SUPPORT_LIB)
 
@@ -160,12 +171,12 @@ t_kperf: t_kperf.o $(SUPPORT_DEPLIB) $(CRYPTO_DEPLIB)
 t_str2key$(EXEEXT): t_str2key.$(OBJEXT) $(SUPPORT_DEPLIB)
        $(CC_LINK) -o $@ t_str2key.$(OBJEXT)  -lkrb5 -lk5crypto -lcom_err $(SUPPORT_LIB)
 
+t_derive$(EXEEXT): t_derive.$(OBJEXT) $(SUPPORT_DEPLIB)
+       $(CC_LINK) -o $@ t_derive.$(OBJEXT)  -lkrb5 -lk5crypto -lcom_err $(SUPPORT_LIB)
+
 t_fork$(EXEEXT): t_fork.$(OBJEXT) $(SUPPORT_DEPLIB)
        $(CC_LINK) -o $@ t_fork.$(OBJEXT) -lkrb5 -lk5crypto -lcom_err $(SUPPORT_LIB)
 
-t_camellia_ccm$(EXEEXT): t_camellia_ccm.$(OBJEXT) $(SUPPORT_DEPLIB)
-       $(CC_LINK) -o $@ t_camellia_ccm.$(OBJEXT)  -lkrb5 -lk5crypto -lcom_err $(SUPPORT_LIB)
-
 ytest: ytest.o shs.o $(SUPPORT_DEPLIB) $(CRYPTO_DEPLIB)
        $(CC_LINK) -o ytest ytest.o  $(SUPPORT_LIB)  $(CRYPTO_DEPLIB)
 
@@ -173,15 +184,14 @@ ytest: ytest.o shs.o $(SUPPORT_DEPLIB) $(CRYPTO_DEPLIB)
 
 clean::
        $(RM) t_nfold.o t_nfold nfold.$(OBJEXT) t_encrypt t_encrypt.o \
-               t_prng.o t_prng t_cmac.o t_cmac t_hmac.o t_hmac \
-               t_pkcs5.o t_pkcs5 pbkdf2.o t_prf t_prf.o \
+               t_decrypt.o t_decrypt t_prng.o t_prng t_cmac.o t_cmac \
+               t_hmac.o t_hmac t_pkcs5.o t_pkcs5 pbkdf2.o t_prf t_prf.o \
                aes-test.o aes-test vt.txt vk.txt kresults.out \
-               t_cksum.o t_cksum \
                t_crc.o t_crc t_cts.o t_cts \
                t_mddriver4.o t_mddriver4 t_mddriver.o t_mddriver \
-               t_cksum4 t_cksum4.o t_cksum5 t_cksum5.o \
+               t_cksum4 t_cksum4.o t_cksum5 t_cksum5.o t_cksums t_cksums.o \
                t_kperf.o t_kperf t_short t_short.o t_str2key t_str2key.o \
-               t_fork t_fork.o t_camellia_ccm t_camellia_ccm.o \
+               t_derive t_derive.o t_fork t_fork.o \
                t_mddriver$(EXEEXT) $(OUTPRE)t_mddriver.$(OBJEXT)
 
        -$(RM) t_prng.output
index 8ea8c46605d3ef09ad17b3ec5c1e1df3e8040a71..a84587352470daa13961784003d446f633d1769a 100644 (file)
@@ -31,7 +31,7 @@
 #include <stdio.h>
 #include "k5-int.h"
 
-#ifdef CAMELLIA_CCM
+#ifdef CAMELLIA
 
 static char key[32];
 static char plain[16], cipher[16], zero[16];
@@ -125,11 +125,11 @@ static void vt_test()
     vt_test_1(32);
 }
 
-#endif /* CAMELLIA_CCM */
+#endif /* CAMELLIA */
 
 int main (int argc, char *argv[])
 {
-#ifdef CAMELLIA_CCM
+#ifdef CAMELLIA
     if (argc > 2 || (argc == 2 && strcmp(argv[1], "-k"))) {
        fprintf(stderr,
                "usage:\t%s -k\tfor variable-key tests\n"
@@ -142,6 +142,6 @@ int main (int argc, char *argv[])
        vk_test();
     else
        vt_test();
-#endif /* CAMELLIA_CCM */
+#endif /* CAMELLIA */
     return 0;
 }
diff --git a/src/lib/crypto/crypto_tests/t_camellia_ccm.c b/src/lib/crypto/crypto_tests/t_camellia_ccm.c
deleted file mode 100644 (file)
index e3827ec..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
- * lib/crypto/crypto_tests/t_camellia_ccm.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.
- *
- *
- * Test vectors for camellia-ccm enctypes.
- *
- * Currently we have no way of controlling the random generated during
- * encryption.  This test program can be used to generate test vectors with
- * random nonces, and to verify existing test vectors via decryption.
- *
- * Usage:
- *   ./t_camellia_ccm -ge <usage> <text> <additional>
- *   ./t_camellia_ccm -gc <usage> <text>
- *   ./t_camellia_ccm
- */
-
-#include "k5-int.h"
-
-#ifdef CAMELLIA_CCM
-
-static krb5_keyblock key_128 = {
-    KV5M_KEYBLOCK,
-    ENCTYPE_CAMELLIA128_CCM_128,
-    16, (unsigned char *)
-    "\xF0\x10\x02\xD2\xB1\xF9\xA1\xAD\xE2\x57\xEE\xF7\x52\x9C\x2A\x16"
-};
-
-static krb5_keyblock key_256 = {
-    KV5M_KEYBLOCK,
-    ENCTYPE_CAMELLIA256_CCM_128,
-    32, (unsigned char *)
-    "\xD7\xEF\x37\xE2\xD1\x05\x5E\xB7\xD7\x6B\x06\x39\x6E\xF7\x00\x52"
-    "\x3D\xA4\xB0\xB7\xA0\x53\xF5\xCC\x5F\xAE\x4A\x39\xCF\xC5\x75\x0F"
-};
-
-static struct enc_test {
-    krb5_keyusage usage;
-    char *input;
-    char *addl;
-    krb5_data cipher_128;
-    krb5_data cipher_256;
-} enc_tests[] = {
-    {
-        0, "", "",
-        { KV5M_DATA, 28,
-          "\x44\xE7\x08\x7D\xDF\x12\x8F\x02\x56\x10\xF5\x34"
-          "\xA1\x0C\x14\x58\x97\x38\xDD\x6B\x0D\x44\x12\x87\xAC\x2C\xC8\xD8" },
-        { KV5M_DATA, 28,
-          "\xE1\x8C\x74\x93\xA7\x15\x58\x11\x58\x6A\xB4\x0E"
-          "\x82\xC1\xFD\xB6\xA7\x05\x5B\x78\xD3\x1D\xE2\x34\xBA\xC3\xC0\x5A" }
-    },
-    {
-        1, "input", "additional",
-        { KV5M_DATA, 33,
-          "\x44\xE7\x08\x7D\xDF\x12\x8F\x02\x56\x10\xF5\x34"
-          "\x32\x69\x98\x26\xE4"
-          "\xE4\x4E\x85\x75\xA0\x37\x60\xDF\x0A\x96\xEC\x24\xB2\xBE\x4A\xA4" },
-        { KV5M_DATA, 33,
-          "\xE1\x8C\x74\x93\xA7\x15\x58\x11\x58\x6A\xB4\x0E"
-          "\x55\x9E\xB8\xB8\x22"
-          "\x7C\xD0\x38\x61\xC6\x81\x3C\x64\xB1\x72\xE3\x3D\x38\x36\x42\x72" }
-    },
-    {
-        100,
-        "this input spans multiple blocks",
-        "the additional data also spans multiple blocks",
-        { KV5M_DATA, 60,
-          "\x44\xE7\x08\x7D\xDF\x12\x8F\x02\x56\x10\xF5\x34"
-          "\x29\x1B\xAF\x6E\x2E\x31\xC6\xDD\xB2\xC9\xE1\xDD\xB4\x82\xAD\x5E"
-          "\x87\xE2\x9A\x65\xF5\x53\x28\x75\x84\x40\x96\x1B\x56\x02\xAD\x31"
-          "\xDD\x15\x22\x61\xB6\x10\xAD\x80\x42\x44\x32\x85\xFD\xFA\x82\x1A" },
-        { KV5M_DATA, 60,
-          "\xE1\x8C\x74\x93\xA7\x15\x58\x11\x58\x6A\xB4\x0E"
-          "\xD0\x9E\x5A\xFB\xFB\x56\x13\x5F\xB6\x29\x07\x0A\x54\x80\xAE\xB9"
-          "\x37\xC5\x25\x6E\xA3\x65\xD4\x2D\x92\x0A\x15\xF9\xED\x6B\x07\xC3"
-          "\x3D\x6B\x68\x9C\x2D\xC9\x7C\x69\x86\xAA\x7C\xCC\x37\x75\x33\x1C" }
-    }
-};
-
-static struct cksum_test {
-    krb5_keyusage usage;
-    char *input;
-    unsigned char expected_128[16];
-    unsigned char expected_256[16];
-} cksum_tests[] = {
-    {
-        0, "",
-        "\xEE\x29\xC4\x6D\xA1\x37\x1D\x27\xD7\x32\x12\xFA\x14\xE8\x25\xB3",
-        "\x19\x7A\xD0\x4B\x76\x82\x99\xA8\xD7\xBD\x51\x2C\xA8\x65\x65\x5D"
-    },
-    {
-        5, "input",
-        "\xA4\x40\x3B\x18\xC2\xAE\xFF\x04\xEA\x9E\xE2\x8F\xB0\x1F\x1C\x26",
-        "\xC2\x11\x53\x9B\x99\xC2\x76\xDB\xC4\x55\x4F\x73\xFE\xD9\x76\x38"
-    },
-    {
-        99, "a somewhat longer input spanning multiple blocks",
-        "\x4A\x29\x54\x12\x9D\xF8\x0D\x04\x33\x2C\xD2\xA6\xC4\x14\x10\xDA",
-        "\x0F\xAD\xE4\x38\xEA\xB4\xCB\x3C\x29\x5F\xBE\x69\x6F\xA4\x9F\x52"
-    }
-};
-
-static void
-print_hex(const char *heading, unsigned char *data, size_t len)
-{
-    size_t i;
-
-    printf("  %s:\n    ", heading);
-    for (i = 0; i < len; i++) {
-        printf("%02X", data[i]);
-        if (i + 1 < len)
-            printf("%s", (i % 16) == 15 ? "\n    " : " ");
-    }
-    printf("\n");
-}
-
-static void
-generate_enc1(krb5_context context, krb5_keyusage usage, char *text,
-              char *addl, krb5_keyblock *keyblock)
-{
-    krb5_crypto_iov iov[4];
-    unsigned char nonce[12], tag[16];
-    char *ciphertext = strdup(text);
-
-    iov[0].flags = KRB5_CRYPTO_TYPE_HEADER;
-    iov[0].data = make_data(nonce, sizeof(nonce));
-    iov[1].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
-    iov[1].data = string2data(addl);
-    iov[2].flags = KRB5_CRYPTO_TYPE_DATA;
-    iov[2].data = string2data(ciphertext);
-    iov[3].flags = KRB5_CRYPTO_TYPE_TRAILER;
-    iov[3].data = make_data(tag, sizeof(tag));
-    assert(krb5_c_encrypt_iov(context, keyblock, usage, NULL, iov, 4) == 0);
-    print_hex("Nonce", nonce, sizeof(nonce));
-    print_hex("Ciphertext", (unsigned char *)ciphertext, strlen(ciphertext));
-    print_hex("Tag", tag, sizeof(tag));
-}
-
-static void
-generate_enc(krb5_context context, krb5_keyusage usage, char *text, char *addl)
-{
-    printf("camellia128-ccm-128 ciphertext:\n");
-    generate_enc1(context, usage, text, addl, &key_128);
-    printf("camellia256-ccm-128 ciphertext:\n");
-    generate_enc1(context, usage, text, addl, &key_256);
-}
-
-static void
-generate_cksum1(krb5_context context, krb5_keyusage usage, char *text,
-                krb5_keyblock *keyblock)
-{
-    krb5_checksum sum;
-    krb5_data input = string2data(text);
-
-    assert(krb5_c_make_checksum(context, 0, keyblock, usage, &input,
-                                &sum) == 0);
-    print_hex("Checksum", sum.contents, sum.length);
-    krb5_free_checksum_contents(context, &sum);
-}
-
-static void
-generate_cksum(krb5_context context, krb5_keyusage usage, char *text)
-{
-    printf("cmac-128-camellia128 checksum:\n");
-    generate_cksum1(context, usage, text, &key_128);
-    printf("cmac-128-camellia256 checksum:\n");
-    generate_cksum1(context, usage, text, &key_256);
-}
-
-static void
-verify_enc1(krb5_context context, krb5_keyblock *keyblock, krb5_keyusage usage,
-            krb5_data *cipher, char *input, char *addl)
-{
-    krb5_crypto_iov iov[3];
-
-    iov[0].flags = KRB5_CRYPTO_TYPE_STREAM;
-    assert(alloc_data(&iov[0].data, cipher->length) == 0);
-    memcpy(iov[0].data.data, cipher->data, cipher->length);
-    iov[1].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
-    iov[1].data = string2data(addl);
-    iov[2].flags = KRB5_CRYPTO_TYPE_DATA;
-    assert(krb5_c_decrypt_iov(context, keyblock, usage, NULL, iov, 3) == 0);
-    assert(data_eq_string(iov[2].data, input));
-}
-
-static void
-verify_enc(krb5_context context)
-{
-    size_t i;
-    struct enc_test *test;
-
-    for (i = 0; i < sizeof(enc_tests) / sizeof(*enc_tests); i++) {
-        test = &enc_tests[i];
-        verify_enc1(context, &key_128, test->usage, &test->cipher_128,
-                    test->input, test->addl);
-        verify_enc1(context, &key_256, test->usage, &test->cipher_256,
-                    test->input, test->addl);
-    }
-}
-
-static void
-verify_cksum1(krb5_context context, krb5_keyblock *keyblock,
-              krb5_keyusage usage, char *text, unsigned char *expected)
-{
-    krb5_checksum sum;
-    krb5_data input = string2data(text);
-
-    assert(krb5_c_make_checksum(context, 0, keyblock, usage, &input,
-                                &sum) == 0);
-    assert(sum.length == 16);
-    assert(memcmp(sum.contents, expected, 16) == 0);
-    krb5_free_checksum_contents(context, &sum);
-}
-
-static void
-verify_cksum(krb5_context context)
-{
-    size_t i;
-    struct cksum_test *test;
-
-    for (i = 0; i < sizeof(cksum_tests) / sizeof(*cksum_tests); i++) {
-        test = &cksum_tests[i];
-        verify_cksum1(context, &key_128, test->usage, test->input,
-                      test->expected_128);
-        verify_cksum1(context, &key_256, test->usage, test->input,
-                      test->expected_256);
-    }
-}
-
-#endif /* CAMELLIA_CCM */
-
-int
-main(int argc, char **argv)
-{
-#ifdef CAMELLIA_CCM
-    krb5_context context = NULL;
-    krb5_data seed = string2data("seed");
-
-    assert(krb5_c_random_seed(context, &seed) == 0);
-    if (argc >= 5 && strcmp(argv[1], "-ge") == 0) {
-        generate_enc(context, atoi(argv[2]), argv[3], argv[4]);
-    } else if (argc >= 4 && strcmp(argv[1], "-gc") == 0) {
-        generate_cksum(context, atoi(argv[2]), argv[3]);
-    } else {
-        verify_enc(context);
-        verify_cksum(context);
-    }
-#endif /* CAMELLIA_CCM */
-    return 0;
-}
diff --git a/src/lib/crypto/crypto_tests/t_cksums.c b/src/lib/crypto/crypto_tests/t_cksums.c
new file mode 100644 (file)
index 0000000..868d91b
--- /dev/null
@@ -0,0 +1,220 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/crypto-tests/t_cksums.c - Test known checksum results */
+/*
+ * Copyright (C) 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.
+ */
+
+/*
+ * This harness tests checksum results against known values.  With the -v flag,
+ * results for all tests are displayed.  This harness only works for
+ * deterministic checksums; for rsa-md4-des and rsa-md5-des, see t_cksum.c.
+ */
+
+#include "k5-int.h"
+
+struct test {
+    char *plaintext;
+    krb5_cksumtype sumtype;
+    krb5_enctype enctype;
+    krb5_keyusage usage;
+    krb5_data keybits;
+    krb5_data cksum;
+} test_cases[] = {
+    {
+       "abc",
+       CKSUMTYPE_CRC32, 0, 0, { KV5M_DATA, 0, "" },
+       { KV5M_DATA, 4,
+          "\xD0\x98\x65\xCA" }
+    },
+    {
+       "one",
+       CKSUMTYPE_RSA_MD4, 0, 0, { KV5M_DATA, 0, "" },
+       { KV5M_DATA, 16,
+          "\x30\x5D\xCC\x2C\x0F\xDD\x53\x39\x96\x95\x52\xC7\xB8\x99\x63\x48" }
+    },
+    {
+       "two three four five",
+       CKSUMTYPE_RSA_MD5, 0, 0, { KV5M_DATA, 0, "" },
+       { KV5M_DATA, 16,
+          "\xBA\xB5\x32\x15\x51\xE1\x08\x44\x90\x86\x96\x35\xB3\xC2\x68\x15" }
+    },
+    {
+       "",
+       CKSUMTYPE_NIST_SHA, 0, 0, { KV5M_DATA, 0, "" },
+       { KV5M_DATA, 20,
+          "\xDA\x39\xA3\xEE\x5E\x6B\x4B\x0D\x32\x55\xBF\xEF\x95\x60\x18\x90"
+          "\xAF\xD8\x07\x09" }
+    },
+    {
+       "six seven",
+       CKSUMTYPE_HMAC_SHA1_DES3, ENCTYPE_DES3_CBC_SHA1, 2,
+        { KV5M_DATA, 24,
+          "\x7A\x25\xDF\x89\x92\x29\x6D\xCE\xDA\x0E\x13\x5B\xC4\x04\x6E\x23"
+          "\x75\xB3\xC1\x4C\x98\xFB\xC1\x62" },
+       { KV5M_DATA, 20,
+          "\x0E\xEF\xC9\xC3\xE0\x49\xAA\xBC\x1B\xA5\xC4\x01\x67\x7D\x9A\xB6"
+          "\x99\x08\x2B\xB4" }
+    },
+    {
+       "eight nine ten eleven twelve thirteen",
+       CKSUMTYPE_HMAC_SHA1_96_AES128, ENCTYPE_AES128_CTS_HMAC_SHA1_96, 3,
+        { KV5M_DATA, 16,
+          "\x90\x62\x43\x0C\x8C\xDA\x33\x88\x92\x2E\x6D\x6A\x50\x9F\x5B\x7A" },
+       { KV5M_DATA, 12,
+          "\x01\xA4\xB0\x88\xD4\x56\x28\xF6\x94\x66\x14\xE3" }
+    },
+    {
+       "fourteen",
+       CKSUMTYPE_HMAC_SHA1_96_AES256, ENCTYPE_AES256_CTS_HMAC_SHA1_96, 4,
+        { KV5M_DATA, 32,
+          "\xB1\xAE\x4C\xD8\x46\x2A\xFF\x16\x77\x05\x3C\xC9\x27\x9A\xAC\x30"
+          "\xB7\x96\xFB\x81\xCE\x21\x47\x4D\xD3\xDD\xBC\xFE\xA4\xEC\x76\xD7" },
+       { KV5M_DATA, 12,
+          "\xE0\x87\x39\xE3\x27\x9E\x29\x03\xEC\x8E\x38\x36" }
+    },
+    {
+       "fifteen sixteen",
+       CKSUMTYPE_MD5_HMAC_ARCFOUR, ENCTYPE_ARCFOUR_HMAC, 5,
+        { KV5M_DATA, 16,
+          "\xF7\xD3\xA1\x55\xAF\x5E\x23\x8A\x0B\x7A\x87\x1A\x96\xBA\x2A\xB2" },
+       { KV5M_DATA, 16,
+          "\x9F\x41\xDF\x30\x49\x07\xDE\x73\x54\x47\x00\x1F\xD2\xA1\x97\xB9" }
+    },
+    {
+       "seventeen eighteen nineteen twenty",
+       CKSUMTYPE_HMAC_MD5_ARCFOUR, ENCTYPE_ARCFOUR_HMAC, 6,
+        { KV5M_DATA, 16,
+          "\xF7\xD3\xA1\x55\xAF\x5E\x23\x8A\x0B\x7A\x87\x1A\x96\xBA\x2A\xB2" },
+       { KV5M_DATA, 16,
+          "\xEB\x38\xCC\x97\xE2\x23\x0F\x59\xDA\x41\x17\xDC\x58\x59\xD7\xEC" }
+    },
+#ifdef CAMELLIA
+    {
+       "abcdefghijk",
+       CKSUMTYPE_CMAC_CAMELLIA128, ENCTYPE_CAMELLIA128_CTS_CMAC, 7,
+        { KV5M_DATA, 16,
+          "\x1D\xC4\x6A\x8D\x76\x3F\x4F\x93\x74\x2B\xCB\xA3\x38\x75\x76\xC3" },
+       { KV5M_DATA, 16,
+          "\x11\x78\xE6\xC5\xC4\x7A\x8C\x1A\xE0\xC4\xB9\xC7\xD4\xEB\x7B\x6B" }
+    },
+    {
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+       CKSUMTYPE_CMAC_CAMELLIA128, ENCTYPE_CAMELLIA128_CTS_CMAC, 8,
+        { KV5M_DATA, 16,
+          "\x50\x27\xBC\x23\x1D\x0F\x3A\x9D\x23\x33\x3F\x1C\xA6\xFD\xBE\x7C" },
+       { KV5M_DATA, 16,
+          "\xD1\xB3\x4F\x70\x04\xA7\x31\xF2\x3A\x0C\x00\xBF\x6C\x3F\x75\x3A" }
+    },
+    {
+       "123456789",
+       CKSUMTYPE_CMAC_CAMELLIA256, ENCTYPE_CAMELLIA256_CTS_CMAC, 9,
+        { KV5M_DATA, 32,
+          "\xB6\x1C\x86\xCC\x4E\x5D\x27\x57\x54\x5A\xD4\x23\x39\x9F\xB7\x03"
+          "\x1E\xCA\xB9\x13\xCB\xB9\x00\xBD\x7A\x3C\x6D\xD8\xBF\x92\x01\x5B" },
+       { KV5M_DATA, 16,
+          "\x87\xA1\x2C\xFD\x2B\x96\x21\x48\x10\xF0\x1C\x82\x6E\x77\x44\xB1" }
+    },
+    {
+       "!@#$%^&*()!@#$%^&*()!@#$%^&*()",
+       CKSUMTYPE_CMAC_CAMELLIA256, ENCTYPE_CAMELLIA256_CTS_CMAC, 10,
+        { KV5M_DATA, 32,
+          "\x32\x16\x4C\x5B\x43\x4D\x1D\x15\x38\xE4\xCF\xD9\xBE\x80\x40\xFE"
+          "\x8C\x4A\xC7\xAC\xC4\xB9\x3D\x33\x14\xD2\x13\x36\x68\x14\x7A\x05" },
+       { KV5M_DATA, 16,
+          "\x3F\xA0\xB4\x23\x55\xE5\x2B\x18\x91\x87\x29\x4A\xA2\x52\xAB\x64" }
+    },
+#endif
+};
+
+static void
+printhex(const char *head, void *data, size_t len)
+{
+    size_t i;
+
+    printf("%s", head);
+    for (i = 0; i < len; i++) {
+#if 0                           /* For convenience when updating test cases. */
+        printf("\\x%02X", ((unsigned char*)data)[i]);
+#else
+        printf("%02X", ((unsigned char*)data)[i]);
+        if (i % 16 == 15 && i + 1 < len)
+            printf("\n%*s", (int)strlen(head), "");
+        else if (i + 1 < len)
+            printf(" ");
+#endif
+    }
+    printf("\n");
+}
+
+int
+main(int argc, char **argv)
+{
+    krb5_context context = NULL;
+    size_t i;
+    struct test *test;
+    krb5_keyblock kb, *kbp;
+    krb5_data plain;
+    krb5_checksum cksum;
+    krb5_boolean verbose = FALSE;
+    int status = 0;
+
+    if (argc >= 2 && strcmp(argv[1], "-v") == 0)
+        verbose = TRUE;
+    for (i = 0; i < sizeof(test_cases) / sizeof(*test_cases); i++) {
+        test = &test_cases[i];
+       if (test->enctype != 0) {
+           kb.magic = KV5M_KEYBLOCK;
+           kb.enctype = test->enctype;
+           kb.length = test->keybits.length;
+           kb.contents = (unsigned char *)test->keybits.data;
+           kbp = &kb;
+       } else
+           kbp = NULL;
+       plain = string2data(test->plaintext);
+       assert(krb5_c_make_checksum(context, test->sumtype, kbp, test->usage,
+                                   &plain, &cksum) == 0);
+       if (verbose) {
+            char buf[64];
+           krb5_cksumtype_to_string(test->sumtype, buf, sizeof(buf));
+            printf("\nTest %d:\n", (int)i);
+            printf("Plaintext: %s\n", test->plaintext);
+            printf("Checksum type: %s\n", buf);
+           if (test->enctype != 0) {
+               krb5_enctype_to_name(test->enctype, FALSE, buf, sizeof(buf));
+               printf("Enctype: %s\n", buf);
+               printhex("Key: ", test->keybits.data, test->keybits.length);
+               printf("Key usage: %d\n", (int)test->usage);
+           }
+           printhex("Checksum: ", cksum.contents, cksum.length);
+       }
+       if (test->cksum.length != cksum.length ||
+           memcmp(test->cksum.data, cksum.contents, cksum.length) != 0) {
+            printf("derive test %d failed\n", (int)i);
+            status = 1;
+            if (!verbose)
+                break;
+        }
+       krb5_free_checksum_contents(context, &cksum);
+    }
+    return status;
+}
index 139372c1ce79b753203c8020029a8617b324dd3b..47afd53f3efe6ff3d6233fc119c13f188c2dbe4e 100644 (file)
@@ -42,7 +42,7 @@
 #include "enc_provider.h"
 #include "cksumtypes.h"
 
-#ifdef CAMELLIA_CCM
+#ifdef CAMELLIA
 
 /* All examples use the following Camellia-128 key. */
 static unsigned char keybytes[] = {
@@ -100,23 +100,23 @@ check_result(const char *name, const unsigned char *result,
     }
 }
 
-#endif /* CAMELLIA_CCM */
+#endif /* CAMELLIA */
 
 int
 main(int argc, char **argv)
 {
-#ifdef CAMELLIA_CCM
+#ifdef CAMELLIA
     krb5_context context = NULL;
     krb5_keyblock keyblock;
     krb5_key key;
-    const struct krb5_enc_provider *enc = &krb5int_enc_camellia128_ctr;
+    const struct krb5_enc_provider *enc = &krb5int_enc_camellia128;
     krb5_crypto_iov iov;
     unsigned char resultbuf[16];
     krb5_data result = make_data(resultbuf, 16);
 
     /* Create the example key. */
     keyblock.magic = KV5M_KEYBLOCK;
-    keyblock.enctype = ENCTYPE_CAMELLIA128_CCM_128;
+    keyblock.enctype = ENCTYPE_CAMELLIA128_CTS_CMAC;
     keyblock.length = 16;
     keyblock.contents = keybytes;
     assert(krb5_k_create_key(context, &keyblock, &key) == 0);
@@ -144,6 +144,6 @@ main(int argc, char **argv)
 
     printf("All CMAC tests passed.\n");
     krb5_k_free_key(context, key);
-#endif /* CAMELLIA_CCM */
+#endif /* CAMELLIA */
     return 0;
 }
diff --git a/src/lib/crypto/crypto_tests/t_decrypt.c b/src/lib/crypto/crypto_tests/t_decrypt.c
new file mode 100644 (file)
index 0000000..ae93772
--- /dev/null
@@ -0,0 +1,671 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/crypto_tests/t_decrypt.c - Test decrypting known ciphertexts */
+/*
+ * Copyright (C) 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.
+ */
+
+/*
+ * This harness decrypts known ciphertexts to detect changes in encryption code
+ * which are self-compatible but not compatible across versions.  With the -g
+ * flag, the program generates a set of test cases.
+ */
+
+#include "k5-int.h"
+
+struct test {
+    krb5_enctype enctype;
+    const char *plaintext;
+    krb5_keyusage usage;
+    krb5_data keybits;
+    krb5_data ciphertext;
+} test_cases[] = {
+    {
+        ENCTYPE_DES_CBC_CRC,
+        "", 0,
+        { KV5M_DATA, 8,
+          "\x45\xE6\x08\x7C\xDF\x13\x8F\xB5" },
+        { KV5M_DATA, 16,
+          "\x28\xF6\xB0\x9A\x01\x2B\xCC\xF7\x2F\xB0\x51\x22\xB2\x83\x9E\x6E" }
+    },
+    {
+        ENCTYPE_DES_CBC_CRC,
+        "1", 1,
+        { KV5M_DATA, 8,
+          "\x92\xA7\x15\x58\x10\x58\x6B\x2F" },
+        { KV5M_DATA, 16,
+          "\xB4\xC8\x71\xC2\xF3\xE7\xBF\x76\x05\xEF\xD6\x2F\x2E\xEE\xC2\x05" }
+    },
+    {
+        ENCTYPE_DES_CBC_CRC,
+        "9 bytesss", 2,
+        { KV5M_DATA, 8,
+          "\xA4\xB9\x51\x4A\x61\x64\x64\x23" },
+        { KV5M_DATA, 24,
+          "\x5F\x14\xC3\x51\x78\xD3\x3D\x7C\xDE\x0E\xC1\x69\xC6\x23\xCC\x83"
+          "\x21\xB7\xB8\xBD\x34\xEA\x7E\xFE" }
+    },
+    {
+        ENCTYPE_DES_CBC_CRC,
+        "13 bytes byte", 3,
+        { KV5M_DATA, 8,
+          "\x2F\x16\xA2\xA7\xFD\xB0\x57\x68" },
+        { KV5M_DATA, 32,
+          "\x0B\x58\x8E\x38\xD9\x71\x43\x3C\x9D\x86\xD8\xBA\xEB\xF6\x3E\x4C"
+          "\x1A\x01\x66\x6E\x76\xD8\xA5\x4A\x32\x93\xF7\x26\x79\xED\x88\xC9" }
+    },
+    {
+        ENCTYPE_DES_CBC_CRC,
+        "30 bytes bytes bytes bytes byt", 4,
+        { KV5M_DATA, 8,
+          "\xBC\x8F\x70\xFD\x20\x97\xD6\x7C" },
+        { KV5M_DATA, 48,
+          "\x38\xD6\x32\xD2\xC2\x0A\x7C\x2E\xA2\x50\xFC\x8E\xCE\x42\x93\x8E"
+          "\x92\xA9\xF5\xD3\x02\x50\x26\x65\xC1\xA3\x37\x29\xC1\x05\x0D\xC2"
+          "\x05\x62\x98\xFB\xFB\x16\x82\xCE\xEB\x65\xE5\x92\x04\xFD\xA7\xDF" }
+    },
+
+    {
+        ENCTYPE_DES_CBC_MD4,
+        "", 0,
+        { KV5M_DATA, 8,
+          "\x13\xEF\x45\xD0\xD6\xD9\xA1\x5D" },
+        { KV5M_DATA, 24,
+          "\x1F\xB2\x02\xBF\x07\xAF\x30\x47\xFB\x78\x01\xE5\x88\x56\x86\x86"
+          "\xBA\x63\xD7\x8B\xE3\xE8\x7D\xC7" }
+    },
+    {
+        ENCTYPE_DES_CBC_MD4,
+        "1", 1,
+        { KV5M_DATA, 8,
+          "\x64\x68\x86\x54\xDC\x26\x9E\x67" },
+        { KV5M_DATA, 32,
+          "\x1F\x6C\xB9\xCE\xCB\x73\xF7\x55\xAB\xFD\xB3\xD5\x65\xBD\x31\xD5"
+          "\xA2\xE6\x4B\xFE\x44\xC4\x91\xE2\x0E\xEB\xE5\xBD\x20\xE4\xD2\xA9" }
+    },
+    {
+        ENCTYPE_DES_CBC_MD4,
+        "9 bytesss", 2,
+        { KV5M_DATA, 8,
+          "\x68\x04\xFB\x26\xDF\x8A\x4C\x32" },
+        { KV5M_DATA, 40,
+          "\x08\xA5\x3D\x62\xFE\xC3\x33\x8A\xD1\xD2\x18\xE6\x0D\xBD\xD3\xB2"
+          "\x12\x94\x06\x79\xD1\x25\xE0\x62\x1B\x3B\xAB\x46\x80\xCE\x03\x67"
+          "\x6A\x2C\x42\x0E\x9B\xE7\x84\xEB" }
+    },
+    {
+        ENCTYPE_DES_CBC_MD4,
+        "13 bytes byte", 3,
+        { KV5M_DATA, 8,
+          "\x23\x4A\x43\x6E\xC7\x2F\xA8\x0B" },
+        { KV5M_DATA, 40,
+          "\x17\xCD\x45\xE1\x4F\xF0\x6B\x28\x40\xA6\x03\x6E\x9A\xA7\xA4\x14"
+          "\x4E\x29\x76\x81\x44\xA0\xC1\x82\x7D\x8C\x4B\xC7\xC9\x90\x6E\x72"
+          "\xCD\x4D\xC3\x28\xF6\x64\x8C\x99" }
+    },
+    {
+        ENCTYPE_DES_CBC_MD4,
+        "30 bytes bytes bytes bytes byt", 4,
+        { KV5M_DATA, 8,
+          "\x1F\xD5\xF7\x43\x34\xC4\xFB\x8C" },
+        { KV5M_DATA, 56,
+          "\x51\x13\x4C\xD8\x95\x1E\x9D\x57\xC0\xA3\x60\x53\xE0\x4C\xE0\x3E"
+          "\xCB\x84\x22\x48\x8F\xDD\xC5\xC0\x74\xC4\xD8\x5E\x60\xA2\xAE\x42"
+          "\x3C\x3C\x70\x12\x01\x31\x4F\x36\x2C\xB0\x74\x48\x09\x16\x79\xC6"
+          "\xA4\x96\xC1\x1D\x7B\x93\xC7\x1B" }
+    },
+
+    {
+        ENCTYPE_DES_CBC_MD5,
+        "", 0,
+        { KV5M_DATA, 8,
+          "\x4A\x54\x5E\x0B\xF7\xA2\x26\x31" },
+        { KV5M_DATA, 24,
+          "\x78\x4C\xD8\x15\x91\xA0\x34\xBE\x82\x55\x6F\x56\xDC\xA3\x22\x4B"
+          "\x62\xD9\x95\x6F\xA9\x0B\x1B\x93" }
+    },
+    {
+        ENCTYPE_DES_CBC_MD5,
+        "1", 1,
+        { KV5M_DATA, 8,
+          "\xD5\x80\x4A\x26\x9D\xC4\xE6\x45" },
+        { KV5M_DATA, 32,
+          "\xFF\xA2\x5C\x7B\xE2\x87\x59\x6B\xFE\x58\x12\x6E\x90\xAA\xA0\xF1"
+          "\x2D\x9A\x82\xA0\xD8\x6D\xF6\xD5\xF9\x07\x4B\x6B\x39\x9E\x7F\xF1" }
+    },
+    {
+        ENCTYPE_DES_CBC_MD5,
+        "9 bytesss", 2,
+        { KV5M_DATA, 8,
+          "\xC8\x31\x2F\x7F\x83\xEA\x46\x40" },
+        { KV5M_DATA, 40,
+          "\xE7\x85\x03\x37\xF2\xCC\x5E\x3F\x35\xCE\x3D\x69\xE2\xC3\x29\x86"
+          "\x38\xA7\xAA\x44\xB8\x78\x03\x1E\x39\x85\x1E\x47\xC1\x5B\x5D\x0E"
+          "\xE7\xE7\xAC\x54\xDE\x11\x1D\x80" }
+    },
+    {
+        ENCTYPE_DES_CBC_MD5,
+        "13 bytes byte", 3,
+        { KV5M_DATA, 8,
+          "\x7F\xDA\x3E\x62\xAD\x8A\xF1\x8C" },
+        { KV5M_DATA, 40,
+          "\xD7\xA8\x03\x2E\x19\x99\x4C\x92\x87\x77\x50\x65\x95\xFB\xDA\x98"
+          "\x83\x15\x8A\x85\x14\x54\x8E\x29\x6E\x91\x1C\x29\xF4\x65\xC6\x72"
+          "\x36\x60\x00\x55\x8B\xFC\x2E\x88" }
+    },
+    {
+        ENCTYPE_DES_CBC_MD5,
+        "30 bytes bytes bytes bytes byt", 4,
+        { KV5M_DATA, 8,
+          "\xD3\xD6\x83\x29\x70\xA7\x37\x52" },
+        { KV5M_DATA, 56,
+          "\x8A\x48\x16\x6A\x4C\x6F\xEA\xE6\x07\xA8\xCF\x68\xB3\x81\xC0\x75"
+          "\x5E\x40\x2B\x19\xDB\xC0\xF8\x1A\x7D\x7C\xA1\x9A\x25\xE0\x52\x23"
+          "\xF6\x06\x44\x09\xBF\x5A\x4F\x50\xAC\xD8\x26\x63\x9F\xFA\x76\x73"
+          "\xFD\x32\x4E\xC1\x9E\x42\x95\x02" }
+    },
+
+    {
+        ENCTYPE_DES3_CBC_SHA1,
+        "", 0,
+        { KV5M_DATA, 24,
+          "\x7A\x25\xDF\x89\x92\x29\x6D\xCE\xDA\x0E\x13\x5B\xC4\x04\x6E\x23"
+          "\x75\xB3\xC1\x4C\x98\xFB\xC1\x62" },
+        { KV5M_DATA, 28,
+          "\x54\x8A\xF4\xD5\x04\xF7\xD7\x23\x30\x3F\x12\x17\x5F\xE8\x38\x6B"
+          "\x7B\x53\x35\xA9\x67\xBA\xD6\x1F\x3B\xF0\xB1\x43" }
+    },
+    {
+        ENCTYPE_DES3_CBC_SHA1,
+        "1", 1,
+        { KV5M_DATA, 24,
+          "\xBC\x07\x83\x89\x15\x13\xD5\xCE\x57\xBC\x13\x8F\xD3\xC1\x1A\xE6"
+          "\x40\x45\x23\x85\x32\x29\x62\xB6" },
+        { KV5M_DATA, 36,
+          "\x9C\x3C\x1D\xBA\x47\x47\xD8\x5A\xF2\x91\x6E\x47\x45\xF2\xDC\xE3"
+          "\x80\x46\x79\x6E\x51\x04\xBC\xCD\xFB\x66\x9A\x91\xD4\x4B\xC3\x56"
+          "\x66\x09\x45\xC7" }
+    },
+    {
+        ENCTYPE_DES3_CBC_SHA1,
+        "9 bytesss", 2,
+        { KV5M_DATA, 24,
+          "\x2F\xD0\xF7\x25\xCE\x04\x10\x0D\x2F\xC8\xA1\x80\x98\x83\x1F\x85"
+          "\x0B\x45\xD9\xEF\x85\x0B\xD9\x20" },
+        { KV5M_DATA, 44,
+          "\xCF\x91\x44\xEB\xC8\x69\x79\x81\x07\x5A\x8B\xAD\x8D\x74\xE5\xD7"
+          "\xD5\x91\xEB\x7D\x97\x70\xC7\xAD\xA2\x5E\xE8\xC5\xB3\xD6\x94\x44"
+          "\xDF\xEC\x79\xA5\xB7\xA0\x14\x82\xD9\xAF\x74\xE6" }
+    },
+    {
+        ENCTYPE_DES3_CBC_SHA1,
+        "13 bytes byte", 3,
+        { KV5M_DATA, 24,
+          "\x0D\xD5\x20\x94\xE0\xF4\x1C\xEC\xCB\x5B\xE5\x10\xA7\x64\xB3\x51"
+          "\x76\xE3\x98\x13\x32\xF1\xE5\x98" },
+        { KV5M_DATA, 44,
+          "\x83\x9A\x17\x08\x1E\xCB\xAF\xBC\xDC\x91\xB8\x8C\x69\x55\xDD\x3C"
+          "\x45\x14\x02\x3C\xF1\x77\xB7\x7B\xF0\xD0\x17\x7A\x16\xF7\x05\xE8"
+          "\x49\xCB\x77\x81\xD7\x6A\x31\x6B\x19\x3F\x8D\x30" }
+    },
+    {
+        ENCTYPE_DES3_CBC_SHA1,
+        "30 bytes bytes bytes bytes byt", 4,
+        { KV5M_DATA, 24,
+          "\xF1\x16\x86\xCB\xBC\x9E\x23\xEA\x54\xFE\xCD\x2A\x3D\xCD\xFB\x20"
+          "\xB6\xFE\x98\xBF\x26\x45\xC4\xC4" },
+        { KV5M_DATA, 60,
+          "\x89\x43\x3E\x83\xFD\x0E\xA3\x66\x6C\xFF\xCD\x18\xD8\xDE\xEB\xC5"
+          "\x3B\x9A\x34\xED\xBE\xB1\x59\xD9\xF6\x67\xC6\xC2\xB9\xA9\x64\x40"
+          "\x1D\x55\xE7\xE9\xC6\x8D\x64\x8D\x65\xC3\xAA\x84\xFF\xA3\x79\x0C"
+          "\x14\xA8\x64\xDA\x80\x73\xA9\xA9\x5C\x4B\xA2\xBC" }
+    },
+
+    {
+        ENCTYPE_ARCFOUR_HMAC,
+        "", 0,
+        { KV5M_DATA, 16,
+          "\xF8\x1F\xEC\x39\x25\x5F\x57\x84\xE8\x50\xC4\x37\x7C\x88\xBD\x85" },
+        { KV5M_DATA, 24,
+          "\x02\xC1\xEB\x15\x58\x61\x44\x12\x2E\xC7\x17\x76\x3D\xD3\x48\xBF"
+          "\x00\x43\x4D\xDC\x65\x85\x95\x4C" }
+    },
+    {
+        ENCTYPE_ARCFOUR_HMAC,
+        "1", 1,
+        { KV5M_DATA, 16,
+          "\x67\xD1\x30\x0D\x28\x12\x23\x86\x7F\x96\x47\xFF\x48\x72\x12\x73" },
+        { KV5M_DATA, 25,
+          "\x61\x56\xE0\xCC\x04\xE0\xA0\x87\x4F\x9F\xDA\x00\x8F\x49\x8A\x7A"
+          "\xDB\xBC\x80\xB7\x0B\x14\xDD\xDB\xC0" }
+    },
+    {
+        ENCTYPE_ARCFOUR_HMAC,
+        "9 bytesss", 2,
+        { KV5M_DATA, 16,
+          "\x3E\x40\xAB\x60\x93\x69\x52\x81\xB3\xAC\x1A\x93\x04\x22\x4D\x98" },
+        { KV5M_DATA, 33,
+          "\x0F\x9A\xD1\x21\xD9\x9D\x4A\x09\x44\x8E\x4F\x1F\x71\x8C\x4F\x5C"
+          "\xBE\x60\x96\x26\x2C\x66\xF2\x9D\xF2\x32\xA8\x7C\x9F\x98\x75\x5D"
+          "\x55" }
+    },
+    {
+        ENCTYPE_ARCFOUR_HMAC,
+        "13 bytes byte", 3,
+        { KV5M_DATA, 16,
+          "\x4B\xA2\xFB\xF0\x37\x9F\xAE\xD8\x7A\x25\x4D\x3B\x35\x3D\x5A\x7E" },
+        { KV5M_DATA, 37,
+          "\x61\x2C\x57\x56\x8B\x17\xA7\x03\x52\xBA\xE8\xCF\x26\xFB\x94\x59"
+          "\xA6\xF3\x35\x3C\xD3\x5F\xD4\x39\xDB\x31\x07\xCB\xEC\x76\x5D\x32"
+          "\x6D\xFC\x04\xC1\xDD" }
+    },
+    {
+        ENCTYPE_ARCFOUR_HMAC,
+        "30 bytes bytes bytes bytes byt", 4,
+        { KV5M_DATA, 16,
+          "\x68\xF2\x63\xDB\x3F\xCE\x15\xD0\x31\xC9\xEA\xB0\x2D\x67\x10\x7A" },
+        { KV5M_DATA, 54,
+          "\x95\xF9\x04\x7C\x3A\xD7\x58\x91\xC2\xE9\xB0\x4B\x16\x56\x6D\xC8"
+          "\xB6\xEB\x9C\xE4\x23\x1A\xFB\x25\x42\xEF\x87\xA7\xB5\xA0\xF2\x60"
+          "\xA9\x9F\x04\x60\x50\x8D\xE0\xCE\xCC\x63\x2D\x07\xC3\x54\x12\x4E"
+          "\x46\xC5\xD2\x23\x4E\xB8" }
+    },
+
+    {
+        ENCTYPE_ARCFOUR_HMAC_EXP,
+        "", 0,
+        { KV5M_DATA, 16,
+          "\xF7\xD3\xA1\x55\xAF\x5E\x23\x8A\x0B\x7A\x87\x1A\x96\xBA\x2A\xB2" },
+        { KV5M_DATA, 24,
+          "\x28\x27\xF0\xE9\x0F\x62\xE7\x46\x0C\x4E\x2F\xB3\x9F\x96\x57\xBA"
+          "\x8B\xFA\xA9\x91\xD7\xFD\xAD\xFF" }
+    },
+    {
+        ENCTYPE_ARCFOUR_HMAC_EXP,
+        "1", 1,
+        { KV5M_DATA, 16,
+          "\xDE\xEA\xA0\x60\x7D\xB7\x99\xE2\xFD\xD6\xDB\x29\x86\xBB\x8D\x65" },
+        { KV5M_DATA, 25,
+          "\x3D\xDA\x39\x2E\x2E\x27\x5A\x4D\x75\x18\x3F\xA6\x32\x8A\x0A\x4E"
+          "\x6B\x75\x2D\xF6\xCD\x2A\x25\xFA\x4E" }
+    },
+    {
+        ENCTYPE_ARCFOUR_HMAC_EXP,
+        "9 bytesss", 2,
+        { KV5M_DATA, 16,
+          "\x33\xAD\x7F\xC2\x67\x86\x15\x56\x9B\x2B\x09\x83\x6E\x0A\x3A\xB6" },
+        { KV5M_DATA, 33,
+          "\x09\xD1\x36\xAC\x48\x5D\x92\x64\x4E\xC6\x70\x1D\x6A\x0D\x03\xE8"
+          "\x98\x2D\x7A\x3C\xA7\xEF\xD0\xF8\xF4\xF8\x36\x60\xEF\x42\x77\xBB"
+          "\x81" }
+    },
+    {
+        ENCTYPE_ARCFOUR_HMAC_EXP,
+        "13 bytes byte", 3,
+        { KV5M_DATA, 16,
+          "\x39\xF2\x5C\xD4\xF0\xD4\x1B\x2B\x2D\x9D\x30\x0F\xCB\x29\x81\xCB" },
+        { KV5M_DATA, 37,
+          "\x91\x23\x88\xD7\xC0\x76\x12\x81\x9E\x3B\x64\x0F\xF5\xCE\xCD\xAF"
+          "\x72\xE5\xA5\x9D\xF1\x0F\x10\x91\xA6\xBE\xC3\x9C\xAA\xD7\x48\xAF"
+          "\x9B\xD2\xD8\xD5\x46" }
+    },
+    {
+        ENCTYPE_ARCFOUR_HMAC_EXP,
+        "30 bytes bytes bytes bytes byt", 4,
+        { KV5M_DATA, 16,
+          "\x9F\x72\x55\x42\xD9\xF7\x2A\xA1\xF3\x86\xCB\xE7\x89\x69\x84\xFC" },
+        { KV5M_DATA, 54,
+          "\x78\xB3\x5A\x08\xB0\x8B\xE2\x65\xAE\xB4\x14\x5F\x07\x65\x13\xB6"
+          "\xB5\x6E\xFE\xD3\xF7\x52\x65\x74\xAF\x74\xF7\xD2\xF9\xBA\xE9\x6E"
+          "\xAB\xB7\x6F\x2D\x87\x38\x6D\x2E\x93\xE3\xA7\x7B\x99\x91\x9F\x1D"
+          "\x97\x64\x90\xE2\xBD\x45" }
+    },
+
+    {
+        ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+        "", 0,
+        { KV5M_DATA, 16,
+          "\x5A\x5C\x0F\x0B\xA5\x4F\x38\x28\xB2\x19\x5E\x66\xCA\x24\xA2\x89" },
+        { KV5M_DATA, 28,
+          "\x49\xFF\x8E\x11\xC1\x73\xD9\x58\x3A\x32\x54\xFB\xE7\xB1\xF1\xDF"
+          "\x36\xC5\x38\xE8\x41\x67\x84\xA1\x67\x2E\x66\x76" }
+    },
+    {
+        ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+        "1", 1,
+        { KV5M_DATA, 16,
+          "\x98\x45\x0E\x3F\x3B\xAA\x13\xF5\xC9\x9B\xEB\x93\x69\x81\xB0\x6F" },
+        { KV5M_DATA, 29,
+          "\xF8\x67\x42\xF5\x37\xB3\x5D\xC2\x17\x4A\x4D\xBA\xA9\x20\xFA\xF9"
+          "\x04\x20\x90\xB0\x65\xE1\xEB\xB1\xCA\xD9\xA6\x53\x94" }
+    },
+    {
+        ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+        "9 bytesss", 2,
+        { KV5M_DATA, 16,
+          "\x90\x62\x43\x0C\x8C\xDA\x33\x88\x92\x2E\x6D\x6A\x50\x9F\x5B\x7A" },
+        { KV5M_DATA, 37,
+          "\x68\xFB\x96\x79\x60\x1F\x45\xC7\x88\x57\xB2\xBF\x82\x0F\xD6\xE5"
+          "\x3E\xCA\x8D\x42\xFD\x4B\x1D\x70\x24\xA0\x92\x05\xAB\xB7\xCD\x2E"
+          "\xC2\x6C\x35\x5D\x2F" }
+    },
+    {
+        ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+        "13 bytes byte", 3,
+        { KV5M_DATA, 16,
+          "\x03\x3E\xE6\x50\x2C\x54\xFD\x23\xE2\x77\x91\xE9\x87\x98\x38\x27" },
+        { KV5M_DATA, 41,
+          "\xEC\x36\x6D\x03\x27\xA9\x33\xBF\x49\x33\x0E\x65\x0E\x49\xBC\x6B"
+          "\x97\x46\x37\xFE\x80\xBF\x53\x2F\xE5\x17\x95\xB4\x80\x97\x18\xE6"
+          "\x19\x47\x24\xDB\x94\x8D\x1F\xD6\x37" }
+    },
+    {
+        ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+        "30 bytes bytes bytes bytes byt", 4,
+        { KV5M_DATA, 16,
+          "\xDC\xEE\xB7\x0B\x3D\xE7\x65\x62\xE6\x89\x22\x6C\x76\x42\x91\x48" },
+        { KV5M_DATA, 58,
+          "\xC9\x60\x81\x03\x2D\x5D\x8E\xEB\x7E\x32\xB4\x08\x9F\x78\x9D\x0F"
+          "\xAA\x48\x1D\xEA\x74\xC0\xF9\x7C\xBF\x31\x46\xDD\xFC\xF8\xE8\x00"
+          "\x15\x6E\xCB\x53\x2F\xC2\x03\xE3\x0F\xF6\x00\xB6\x3B\x35\x09\x39"
+          "\xFE\xCE\x51\x0F\x02\xD7\xFF\x1E\x7B\xAC" }
+    },
+
+    {
+        ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+        "", 0,
+        { KV5M_DATA, 32,
+          "\x17\xF2\x75\xF2\x95\x4F\x2E\xD1\xF9\x0C\x37\x7B\xA7\xF4\xD6\xA3"
+          "\x69\xAA\x01\x36\xE0\xBF\x0C\x92\x7A\xD6\x13\x3C\x69\x37\x59\xA9" },
+        { KV5M_DATA, 28,
+          "\xE5\x09\x4C\x55\xEE\x7B\x38\x26\x2E\x2B\x04\x42\x80\xB0\x69\x37"
+          "\x9A\x95\xBF\x95\xBD\x83\x76\xFB\x32\x81\xB4\x35" }
+    },
+    {
+        ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+        "1", 1,
+        { KV5M_DATA, 32,
+          "\xB9\x47\x7E\x1F\xF0\x32\x9C\x00\x50\xE2\x0C\xE6\xC7\x2D\x2D\xFF"
+          "\x27\xE8\xFE\x54\x1A\xB0\x95\x44\x29\xA9\xCB\x5B\x4F\x7B\x1E\x2A" },
+        { KV5M_DATA, 29,
+          "\x40\x61\x50\xB9\x7A\xEB\x76\xD4\x3B\x36\xB6\x2C\xC1\xEC\xDF\xBE"
+          "\x6F\x40\xE9\x57\x55\xE0\xBE\xB5\xC2\x78\x25\xF3\xA4" }
+    },
+    {
+        ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+        "9 bytesss", 2,
+        { KV5M_DATA, 32,
+          "\xB1\xAE\x4C\xD8\x46\x2A\xFF\x16\x77\x05\x3C\xC9\x27\x9A\xAC\x30"
+          "\xB7\x96\xFB\x81\xCE\x21\x47\x4D\xD3\xDD\xBC\xFE\xA4\xEC\x76\xD7" },
+        { KV5M_DATA, 37,
+          "\x09\x95\x7A\xA2\x5F\xCA\xF8\x8F\x7B\x39\xE4\x40\x6E\x63\x30\x12"
+          "\xD5\xFE\xA2\x18\x53\xF6\x47\x8D\xA7\x06\x5C\xAE\xF4\x1F\xD4\x54"
+          "\xA4\x08\x24\xEE\xC5" }
+    },
+    {
+        ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+        "13 bytes byte", 3,
+        { KV5M_DATA, 32,
+          "\xE5\xA7\x2B\xE9\xB7\x92\x6C\x12\x25\xBA\xFE\xF9\xC1\x87\x2E\x7B"
+          "\xA4\xCD\xB2\xB1\x78\x93\xD8\x4A\xBD\x90\xAC\xDD\x87\x64\xD9\x66" },
+        { KV5M_DATA, 41,
+          "\xD8\xF1\xAA\xFE\xEC\x84\x58\x7C\xC3\xE7\x00\xA7\x74\xE5\x66\x51"
+          "\xA6\xD6\x93\xE1\x74\xEC\x44\x73\xB5\xE6\xD9\x6F\x80\x29\x7A\x65"
+          "\x3F\xB8\x18\xAD\x89\x3E\x71\x9F\x96" }
+    },
+    {
+        ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+        "30 bytes bytes bytes bytes byt", 4,
+        { KV5M_DATA, 32,
+          "\xF1\xC7\x95\xE9\x24\x8A\x09\x33\x8D\x82\xC3\xF8\xD5\xB5\x67\x04"
+          "\x0B\x01\x10\x73\x68\x45\x04\x13\x47\x23\x5B\x14\x04\x23\x13\x98" },
+        { KV5M_DATA, 58,
+          "\xD1\x13\x7A\x4D\x63\x4C\xFE\xCE\x92\x4D\xBC\x3B\xF6\x79\x06\x48"
+          "\xBD\x5C\xFF\x7D\xE0\xE7\xB9\x94\x60\x21\x1D\x0D\xAE\xF3\xD7\x9A"
+          "\x29\x5C\x68\x88\x58\xF3\xB3\x4B\x9C\xBD\x6E\xEB\xAE\x81\xDA\xF6"
+          "\xB7\x34\xD4\xD4\x98\xB6\x71\x4F\x1C\x1D" }
+    },
+
+#ifdef CAMELLIA
+    {
+        ENCTYPE_CAMELLIA128_CTS_CMAC,
+        "", 0,
+        { KV5M_DATA, 16,
+          "\x1D\xC4\x6A\x8D\x76\x3F\x4F\x93\x74\x2B\xCB\xA3\x38\x75\x76\xC3" },
+        { KV5M_DATA, 32,
+          "\xC4\x66\xF1\x87\x10\x69\x92\x1E\xDB\x7C\x6F\xDE\x24\x4A\x52\xDB"
+          "\x0B\xA1\x0E\xDC\x19\x7B\xDB\x80\x06\x65\x8C\xA3\xCC\xCE\x6E\xB8" }
+    },
+    {
+        ENCTYPE_CAMELLIA128_CTS_CMAC,
+        "1", 1,
+        { KV5M_DATA, 16,
+          "\x50\x27\xBC\x23\x1D\x0F\x3A\x9D\x23\x33\x3F\x1C\xA6\xFD\xBE\x7C" },
+        { KV5M_DATA, 33,
+          "\x84\x2D\x21\xFD\x95\x03\x11\xC0\xDD\x46\x4A\x3F\x4B\xE8\xD6\xDA"
+          "\x88\xA5\x6D\x55\x9C\x9B\x47\xD3\xF9\xA8\x50\x67\xAF\x66\x15\x59"
+          "\xB8" }
+    },
+    {
+        ENCTYPE_CAMELLIA128_CTS_CMAC,
+        "9 bytesss", 2,
+        { KV5M_DATA, 16,
+          "\xA1\xBB\x61\xE8\x05\xF9\xBA\x6D\xDE\x8F\xDB\xDD\xC0\x5C\xDE\xA0" },
+        { KV5M_DATA, 41,
+          "\x61\x9F\xF0\x72\xE3\x62\x86\xFF\x0A\x28\xDE\xB3\xA3\x52\xEC\x0D"
+          "\x0E\xDF\x5C\x51\x60\xD6\x63\xC9\x01\x75\x8C\xCF\x9D\x1E\xD3\x3D"
+          "\x71\xDB\x8F\x23\xAA\xBF\x83\x48\xA0" }
+    },
+    {
+        ENCTYPE_CAMELLIA128_CTS_CMAC,
+        "13 bytes byte", 3,
+        { KV5M_DATA, 16,
+          "\x2C\xA2\x7A\x5F\xAF\x55\x32\x24\x45\x06\x43\x4E\x1C\xEF\x66\x76" },
+        { KV5M_DATA, 45,
+          "\xB8\xEC\xA3\x16\x7A\xE6\x31\x55\x12\xE5\x9F\x98\xA7\xC5\x00\x20"
+          "\x5E\x5F\x63\xFF\x3B\xB3\x89\xAF\x1C\x41\xA2\x1D\x64\x0D\x86\x15"
+          "\xC9\xED\x3F\xBE\xB0\x5A\xB6\xAC\xB6\x76\x89\xB5\xEA" }
+    },
+    {
+        ENCTYPE_CAMELLIA128_CTS_CMAC,
+        "30 bytes bytes bytes bytes byt", 4,
+        { KV5M_DATA, 16,
+          "\x78\x24\xF8\xC1\x6F\x83\xFF\x35\x4C\x6B\xF7\x51\x5B\x97\x3F\x43" },
+        { KV5M_DATA, 62,
+          "\xA2\x6A\x39\x05\xA4\xFF\xD5\x81\x6B\x7B\x1E\x27\x38\x0D\x08\x09"
+          "\x0C\x8E\xC1\xF3\x04\x49\x6E\x1A\xBD\xCD\x2B\xDC\xD1\xDF\xFC\x66"
+          "\x09\x89\xE1\x17\xA7\x13\xDD\xBB\x57\xA4\x14\x6C\x15\x87\xCB\xA4"
+          "\x35\x66\x65\x59\x1D\x22\x40\x28\x2F\x58\x42\xB1\x05\xA5" }
+    },
+
+    {
+        ENCTYPE_CAMELLIA256_CTS_CMAC,
+        "", 0,
+        { KV5M_DATA, 32,
+          "\xB6\x1C\x86\xCC\x4E\x5D\x27\x57\x54\x5A\xD4\x23\x39\x9F\xB7\x03"
+          "\x1E\xCA\xB9\x13\xCB\xB9\x00\xBD\x7A\x3C\x6D\xD8\xBF\x92\x01\x5B" },
+        { KV5M_DATA, 32,
+          "\x03\x88\x6D\x03\x31\x0B\x47\xA6\xD8\xF0\x6D\x7B\x94\xD1\xDD\x83"
+          "\x7E\xCC\xE3\x15\xEF\x65\x2A\xFF\x62\x08\x59\xD9\x4A\x25\x92\x66" }
+    },
+    {
+        ENCTYPE_CAMELLIA256_CTS_CMAC,
+        "1", 1,
+        { KV5M_DATA, 32,
+          "\x1B\x97\xFE\x0A\x19\x0E\x20\x21\xEB\x30\x75\x3E\x1B\x6E\x1E\x77"
+          "\xB0\x75\x4B\x1D\x68\x46\x10\x35\x58\x64\x10\x49\x63\x46\x38\x33" },
+        { KV5M_DATA, 33,
+          "\x2C\x9C\x15\x70\x13\x3C\x99\xBF\x6A\x34\xBC\x1B\x02\x12\x00\x2F"
+          "\xD1\x94\x33\x87\x49\xDB\x41\x35\x49\x7A\x34\x7C\xFC\xD9\xD1\x8A"
+          "\x12" }
+    },
+    {
+        ENCTYPE_CAMELLIA256_CTS_CMAC,
+        "9 bytesss", 2,
+        { KV5M_DATA, 32,
+          "\x32\x16\x4C\x5B\x43\x4D\x1D\x15\x38\xE4\xCF\xD9\xBE\x80\x40\xFE"
+          "\x8C\x4A\xC7\xAC\xC4\xB9\x3D\x33\x14\xD2\x13\x36\x68\x14\x7A\x05" },
+        { KV5M_DATA, 41,
+          "\x9C\x6D\xE7\x5F\x81\x2D\xE7\xED\x0D\x28\xB2\x96\x35\x57\xA1\x15"
+          "\x64\x09\x98\x27\x5B\x0A\xF5\x15\x27\x09\x91\x3F\xF5\x2A\x2A\x9C"
+          "\x8E\x63\xB8\x72\xF9\x2E\x64\xC8\x39" }
+    },
+    {
+        ENCTYPE_CAMELLIA256_CTS_CMAC,
+        "13 bytes byte", 3,
+        { KV5M_DATA, 32,
+          "\xB0\x38\xB1\x32\xCD\x8E\x06\x61\x22\x67\xFA\xB7\x17\x00\x66\xD8"
+          "\x8A\xEC\xCB\xA0\xB7\x44\xBF\xC6\x0D\xC8\x9B\xCA\x18\x2D\x07\x15" },
+        { KV5M_DATA, 45,
+          "\xEE\xEC\x85\xA9\x81\x3C\xDC\x53\x67\x72\xAB\x9B\x42\xDE\xFC\x57"
+          "\x06\xF7\x26\xE9\x75\xDD\xE0\x5A\x87\xEB\x54\x06\xEA\x32\x4C\xA1"
+          "\x85\xC9\x98\x6B\x42\xAA\xBE\x79\x4B\x84\x82\x1B\xEE" }
+    },
+    {
+        ENCTYPE_CAMELLIA256_CTS_CMAC,
+        "30 bytes bytes bytes bytes byt", 4,
+        { KV5M_DATA, 32,
+          "\xCC\xFC\xD3\x49\xBF\x4C\x66\x77\xE8\x6E\x4B\x02\xB8\xEA\xB9\x24"
+          "\xA5\x46\xAC\x73\x1C\xF9\xBF\x69\x89\xB9\x96\xE7\xD6\xBF\xBB\xA7" },
+        { KV5M_DATA, 62,
+          "\x0E\x44\x68\x09\x85\x85\x5F\x2D\x1F\x18\x12\x52\x9C\xA8\x3B\xFD"
+          "\x8E\x34\x9D\xE6\xFD\x9A\xDA\x0B\xAA\xA0\x48\xD6\x8E\x26\x5F\xEB"
+          "\xF3\x4A\xD1\x25\x5A\x34\x49\x99\xAD\x37\x14\x68\x87\xA6\xC6\x84"
+          "\x57\x31\xAC\x7F\x46\x37\x6A\x05\x04\xCD\x06\x57\x14\x74" }
+    },
+#endif
+};
+
+static void
+printhex(const char *head, void *data, size_t len)
+{
+    size_t i;
+
+    printf("%s", head);
+    for (i = 0; i < len; i++) {
+#if 0                           /* For convenience when updating test cases. */
+        printf("\\x%02X", ((unsigned char*)data)[i]);
+#else
+        printf("%02X", ((unsigned char*)data)[i]);
+        if (i % 16 == 15 && i + 1 < len)
+            printf("\n%*s", (int)strlen(head), "");
+        else if (i + 1 < len)
+            printf(" ");
+#endif
+    }
+    printf("\n");
+}
+
+static krb5_enctype
+enctypes[] = {
+    ENCTYPE_DES_CBC_CRC,
+    ENCTYPE_DES_CBC_MD4,
+    ENCTYPE_DES_CBC_MD5,
+    ENCTYPE_DES3_CBC_SHA1,
+    ENCTYPE_ARCFOUR_HMAC,
+    ENCTYPE_ARCFOUR_HMAC_EXP,
+    ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+    ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+#ifdef CAMELLIA
+    ENCTYPE_CAMELLIA128_CTS_CMAC,
+    ENCTYPE_CAMELLIA256_CTS_CMAC
+#endif
+};
+
+static char *plaintexts[] = {
+    "",
+    "1",
+    "9 bytesss",
+    "13 bytes byte",
+    "30 bytes bytes bytes bytes byt"
+};
+
+static int
+generate(krb5_context context)
+{
+    size_t i, j;
+    krb5_keyblock kb;
+    krb5_data plain, seed = string2data("seed");
+    krb5_enc_data enc;
+    size_t enclen;
+    char buf[64];
+
+    assert(krb5_c_random_seed(context, &seed) == 0);
+    for (i = 0; i < sizeof(enctypes) / sizeof(*enctypes); i++) {
+        for (j = 0; j < sizeof(plaintexts) / sizeof(*plaintexts); j++) {
+            assert(krb5_c_make_random_key(context, enctypes[i], &kb) == 0);
+            plain = string2data(plaintexts[j]);
+            assert(krb5_c_encrypt_length(context, enctypes[i], plain.length,
+                                         &enclen) == 0);
+            assert(alloc_data(&enc.ciphertext, enclen) == 0);
+            assert(krb5_c_encrypt(context, &kb, j, NULL, &plain, &enc) == 0);
+            krb5_enctype_to_name(enctypes[i], FALSE, buf, sizeof(buf));
+            printf("\nEnctype: %s\n", buf);
+            printf("Plaintext: %s\n", plaintexts[j]);
+            printhex("Key: ", kb.contents, kb.length);
+            printhex("Ciphertext: ", enc.ciphertext.data,
+                     enc.ciphertext.length);
+            free(enc.ciphertext.data);
+        }
+    }
+    return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+    krb5_context context = NULL;
+    krb5_data plain;
+    size_t i;
+    struct test *test;
+    krb5_keyblock kb;
+    krb5_enc_data enc;
+
+    if (argc >= 2 && strcmp(argv[1], "-g") == 0)
+        return generate(context);
+
+    for (i = 0; i < sizeof(test_cases) / sizeof(*test_cases); i++) {
+        test = &test_cases[i];
+       kb.magic = KV5M_KEYBLOCK;
+       kb.enctype = test->enctype;
+       kb.length = test->keybits.length;
+       kb.contents = (unsigned char *)test->keybits.data;
+        assert(alloc_data(&plain, test->ciphertext.length) == 0);
+        enc.magic = KV5M_ENC_DATA;
+        enc.enctype = test->enctype;
+        enc.kvno = 0;
+        enc.ciphertext = test->ciphertext;
+        if (krb5_c_decrypt(context, &kb, test->usage, NULL, &enc,
+                           &plain) != 0) {
+            printf("decrypt test %d failed to decrypt\n", (int)i);
+            return 1;
+        }
+        assert(plain.length >= strlen(test->plaintext));
+        if (memcmp(plain.data, test->plaintext,
+                   strlen(test->plaintext)) != 0) {
+            printf("decrypt test %d produced wrong result\n", (int)i);
+            return 1;
+        }
+        free(plain.data);
+    }
+    return 0;
+}
diff --git a/src/lib/crypto/crypto_tests/t_derive.c b/src/lib/crypto/crypto_tests/t_derive.c
new file mode 100644 (file)
index 0000000..49b0bb5
--- /dev/null
@@ -0,0 +1,291 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/crypto_tests/t_derive.c - Test harness for key derivation */
+/*
+ * Copyright (C) 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.
+ */
+
+/*
+ * This harness detects changes in key derivation results using known values.
+ * With the -v flag, results for all tests are displayed.
+ */
+
+#include "k5-int.h"
+#include "../krb/dk/dk.h"
+#include "enc_provider/enc_provider.h"
+
+struct test {
+    krb5_enctype enctype;
+    krb5_data inkey;
+    krb5_data constant;
+    enum deriv_alg alg;
+    krb5_data expected_key;
+} test_cases[] = {
+    /* Kc, Ke, Kei for a DES3 key */
+    {
+       ENCTYPE_DES3_CBC_SHA1,
+        { KV5M_DATA, 24,
+          "\x85\x0B\xB5\x13\x58\x54\x8C\xD0\x5E\x86\x76\x8C\x31\x3E\x3B\xFE"
+         "\xF7\x51\x19\x37\xDC\xF7\x2C\x3E" },
+       { KV5M_DATA, 5, "\0\0\0\2\x99" },
+       DERIVE_RFC3961,
+        { KV5M_DATA, 24,
+         "\xF7\x8C\x49\x6D\x16\xE6\xC2\xDA\xE0\xE0\xB6\xC2\x40\x57\xA8\x4C"
+         "\x04\x26\xAE\xEF\x26\xFD\x6D\xCE" }
+    },
+    {
+       ENCTYPE_DES3_CBC_SHA1,
+        { KV5M_DATA, 24,
+          "\x85\x0B\xB5\x13\x58\x54\x8C\xD0\x5E\x86\x76\x8C\x31\x3E\x3B\xFE"
+         "\xF7\x51\x19\x37\xDC\xF7\x2C\x3E" },
+       { KV5M_DATA, 5, "\0\0\0\2\xAA" },
+       DERIVE_RFC3961,
+        { KV5M_DATA, 24,
+         "\x5B\x57\x23\xD0\xB6\x34\xCB\x68\x4C\x3E\xBA\x52\x64\xE9\xA7\x0D"
+         "\x52\xE6\x83\x23\x1A\xD3\xC4\xCE" }
+    },
+    {
+       ENCTYPE_DES3_CBC_SHA1,
+        { KV5M_DATA, 24,
+          "\x85\x0B\xB5\x13\x58\x54\x8C\xD0\x5E\x86\x76\x8C\x31\x3E\x3B\xFE"
+         "\xF7\x51\x19\x37\xDC\xF7\x2C\x3E" },
+       { KV5M_DATA, 5, "\0\0\0\2\x55" },
+       DERIVE_RFC3961,
+        { KV5M_DATA, 24,
+         "\xA7\x7C\x94\x98\x0E\x9B\x73\x45\xA8\x15\x25\xC4\x23\xA7\x37\xCE"
+         "\x67\xF4\xCD\x91\xB6\xB3\xDA\x45" }
+    },
+
+    /* Kc, Ke, Ki for an AES-128 key */
+    {
+       ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+        { KV5M_DATA, 16,
+          "\x42\x26\x3C\x6E\x89\xF4\xFC\x28\xB8\xDF\x68\xEE\x09\x79\x9F\x15" },
+       { KV5M_DATA, 5, "\0\0\0\2\x99" },
+       DERIVE_RFC3961,
+        { KV5M_DATA, 16,
+         "\x34\x28\x0A\x38\x2B\xC9\x27\x69\xB2\xDA\x2F\x9E\xF0\x66\x85\x4B" }
+    },
+    {
+       ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+        { KV5M_DATA, 16,
+          "\x42\x26\x3C\x6E\x89\xF4\xFC\x28\xB8\xDF\x68\xEE\x09\x79\x9F\x15" },
+       { KV5M_DATA, 5, "\0\0\0\2\xAA" },
+       DERIVE_RFC3961,
+        { KV5M_DATA, 16,
+         "\x5B\x14\xFC\x4E\x25\x0E\x14\xDD\xF9\xDC\xCF\x1A\xF6\x67\x4F\x53" }
+    },
+    {
+       ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+        { KV5M_DATA, 16,
+          "\x42\x26\x3C\x6E\x89\xF4\xFC\x28\xB8\xDF\x68\xEE\x09\x79\x9F\x15" },
+       { KV5M_DATA, 5, "\0\0\0\2\x55" },
+       DERIVE_RFC3961,
+        { KV5M_DATA, 16,
+         "\x4E\xD3\x10\x63\x62\x16\x84\xF0\x9A\xE8\xD8\x99\x91\xAF\x3E\x8F" }
+    },
+
+    /* Kc, Ke, Ki for an AES-256 key */
+    {
+       ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+        { KV5M_DATA, 32,
+          "\xFE\x69\x7B\x52\xBC\x0D\x3C\xE1\x44\x32\xBA\x03\x6A\x92\xE6\x5B"
+          "\xBB\x52\x28\x09\x90\xA2\xFA\x27\x88\x39\x98\xD7\x2A\xF3\x01\x61" },
+       { KV5M_DATA, 5, "\0\0\0\2\x99" },
+       DERIVE_RFC3961,
+        { KV5M_DATA, 32,
+         "\xBF\xAB\x38\x8B\xDC\xB2\x38\xE9\xF9\xC9\x8D\x6A\x87\x83\x04\xF0"
+         "\x4D\x30\xC8\x25\x56\x37\x5A\xC5\x07\xA7\xA8\x52\x79\x0F\x46\x74" }
+    },
+    {
+       ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+        { KV5M_DATA, 32,
+          "\xFE\x69\x7B\x52\xBC\x0D\x3C\xE1\x44\x32\xBA\x03\x6A\x92\xE6\x5B"
+          "\xBB\x52\x28\x09\x90\xA2\xFA\x27\x88\x39\x98\xD7\x2A\xF3\x01\x61" },
+       { KV5M_DATA, 5, "\0\0\0\2\xAA" },
+       DERIVE_RFC3961,
+        { KV5M_DATA, 32,
+         "\xC7\xCF\xD9\xCD\x75\xFE\x79\x3A\x58\x6A\x54\x2D\x87\xE0\xD1\x39"
+         "\x6F\x11\x34\xA1\x04\xBB\x1A\x91\x90\xB8\xC9\x0A\xDA\x3D\xDF\x37" }
+    },
+    {
+       ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+        { KV5M_DATA, 32,
+          "\xFE\x69\x7B\x52\xBC\x0D\x3C\xE1\x44\x32\xBA\x03\x6A\x92\xE6\x5B"
+          "\xBB\x52\x28\x09\x90\xA2\xFA\x27\x88\x39\x98\xD7\x2A\xF3\x01\x61" },
+       { KV5M_DATA, 5, "\0\0\0\2\x55" },
+       DERIVE_RFC3961,
+        { KV5M_DATA, 32,
+         "\x97\x15\x1B\x4C\x76\x94\x50\x63\xE2\xEB\x05\x29\xDC\x06\x7D\x97"
+         "\xD7\xBB\xA9\x07\x76\xD8\x12\x6D\x91\xF3\x4F\x31\x01\xAE\xA8\xBA" }
+    },
+
+#ifdef CAMELLIA
+    /* Kc, Ke, Ki for a Camellia-128 key */
+    {
+       ENCTYPE_CAMELLIA128_CTS_CMAC,
+        { KV5M_DATA, 16,
+          "\x57\xD0\x29\x72\x98\xFF\xD9\xD3\x5D\xE5\xA4\x7F\xB4\xBD\xE2\x4B" },
+       { KV5M_DATA, 5, "\0\0\0\2\x99" },
+       DERIVE_SP800_108_CMAC,
+        { KV5M_DATA, 16,
+         "\xD1\x55\x77\x5A\x20\x9D\x05\xF0\x2B\x38\xD4\x2A\x38\x9E\x5A\x56" }
+    },
+    {
+       ENCTYPE_CAMELLIA128_CTS_CMAC,
+        { KV5M_DATA, 16,
+          "\x57\xD0\x29\x72\x98\xFF\xD9\xD3\x5D\xE5\xA4\x7F\xB4\xBD\xE2\x4B" },
+       { KV5M_DATA, 5, "\0\0\0\2\xAA" },
+       DERIVE_SP800_108_CMAC,
+        { KV5M_DATA, 16,
+         "\x64\xDF\x83\xF8\x5A\x53\x2F\x17\x57\x7D\x8C\x37\x03\x57\x96\xAB" }
+    },
+    {
+       ENCTYPE_CAMELLIA128_CTS_CMAC,
+        { KV5M_DATA, 16,
+          "\x57\xD0\x29\x72\x98\xFF\xD9\xD3\x5D\xE5\xA4\x7F\xB4\xBD\xE2\x4B" },
+       { KV5M_DATA, 5, "\0\0\0\2\x55" },
+       DERIVE_SP800_108_CMAC,
+        { KV5M_DATA, 16,
+         "\x3E\x4F\xBD\xF3\x0F\xB8\x25\x9C\x42\x5C\xB6\xC9\x6F\x1F\x46\x35" }
+    },
+
+    /* Kc, Ke, Ki for a Camellia-256 key */
+    {
+       ENCTYPE_CAMELLIA256_CTS_CMAC,
+        { KV5M_DATA, 32,
+          "\xB9\xD6\x82\x8B\x20\x56\xB7\xBE\x65\x6D\x88\xA1\x23\xB1\xFA\xC6"
+          "\x82\x14\xAC\x2B\x72\x7E\xCF\x5F\x69\xAF\xE0\xC4\xDF\x2A\x6D\x2C" },
+       { KV5M_DATA, 5, "\0\0\0\2\x99" },
+       DERIVE_SP800_108_CMAC,
+        { KV5M_DATA, 32,
+         "\xE4\x67\xF9\xA9\x55\x2B\xC7\xD3\x15\x5A\x62\x20\xAF\x9C\x19\x22"
+         "\x0E\xEE\xD4\xFF\x78\xB0\xD1\xE6\xA1\x54\x49\x91\x46\x1A\x9E\x50" }
+    },
+    {
+       ENCTYPE_CAMELLIA256_CTS_CMAC,
+        { KV5M_DATA, 32,
+          "\xB9\xD6\x82\x8B\x20\x56\xB7\xBE\x65\x6D\x88\xA1\x23\xB1\xFA\xC6"
+          "\x82\x14\xAC\x2B\x72\x7E\xCF\x5F\x69\xAF\xE0\xC4\xDF\x2A\x6D\x2C" },
+       { KV5M_DATA, 5, "\0\0\0\2\xAA" },
+       DERIVE_SP800_108_CMAC,
+        { KV5M_DATA, 32,
+         "\x41\x2A\xEF\xC3\x62\xA7\x28\x5F\xC3\x96\x6C\x6A\x51\x81\xE7\x60"
+         "\x5A\xE6\x75\x23\x5B\x6D\x54\x9F\xBF\xC9\xAB\x66\x30\xA4\xC6\x04" }
+    },
+    {
+       ENCTYPE_CAMELLIA256_CTS_CMAC,
+        { KV5M_DATA, 32,
+          "\xB9\xD6\x82\x8B\x20\x56\xB7\xBE\x65\x6D\x88\xA1\x23\xB1\xFA\xC6"
+          "\x82\x14\xAC\x2B\x72\x7E\xCF\x5F\x69\xAF\xE0\xC4\xDF\x2A\x6D\x2C" },
+       { KV5M_DATA, 5, "\0\0\0\2\x55" },
+       DERIVE_SP800_108_CMAC,
+        { KV5M_DATA, 32,
+         "\xFA\x62\x4F\xA0\xE5\x23\x99\x3F\xA3\x88\xAE\xFD\xC6\x7E\x67\xEB"
+         "\xCD\x8C\x08\xE8\xA0\x24\x6B\x1D\x73\xB0\xD1\xDD\x9F\xC5\x82\xB0" }
+    },
+#endif
+};
+
+static void
+printhex(const char *head, void *data, size_t len)
+{
+    size_t i;
+
+    printf("%s", head);
+    for (i = 0; i < len; i++) {
+#if 0                           /* For convenience when updating test cases. */
+        printf("\\x%02X", ((unsigned char*)data)[i]);
+#else
+        printf("%02X", ((unsigned char*)data)[i]);
+        if (i % 16 == 15 && i + 1 < len)
+            printf("\n%*s", (int)strlen(head), "");
+        else if (i + 1 < len)
+            printf(" ");
+#endif
+    }
+    printf("\n");
+}
+
+static const struct krb5_enc_provider *
+get_enc_provider(krb5_enctype enctype)
+{
+    switch (enctype) {
+    case ENCTYPE_DES3_CBC_SHA1:           return &krb5int_enc_des3;
+    case ENCTYPE_AES128_CTS_HMAC_SHA1_96: return &krb5int_enc_aes128;
+    case ENCTYPE_AES256_CTS_HMAC_SHA1_96: return &krb5int_enc_aes256;
+#ifdef CAMELLIA
+    case ENCTYPE_CAMELLIA128_CTS_CMAC:    return &krb5int_enc_camellia128;
+    case ENCTYPE_CAMELLIA256_CTS_CMAC:    return &krb5int_enc_camellia256;
+#endif
+    }
+    abort();
+}
+
+int
+main(int argc, char **argv)
+{
+    krb5_context context = NULL;
+    size_t i;
+    struct test *test;
+    krb5_keyblock kb;
+    krb5_key inkey, outkey;
+    const struct krb5_enc_provider *enc;
+    krb5_boolean verbose = FALSE;
+    int status = 0;
+
+    if (argc >= 2 && strcmp(argv[1], "-v") == 0)
+        verbose = TRUE;
+    for (i = 0; i < sizeof(test_cases) / sizeof(*test_cases); i++) {
+        test = &test_cases[i];
+       kb.magic = KV5M_KEYBLOCK;
+       kb.enctype = test->enctype;
+       kb.length = test->inkey.length;
+       kb.contents = (unsigned char *)test->inkey.data;
+       assert(krb5_k_create_key(context, &kb, &inkey) == 0);
+       enc = get_enc_provider(test->enctype);
+       assert(krb5int_derive_key(enc, inkey, &outkey, &test->constant,
+                                 test->alg) == 0);
+       if (verbose) {
+            char buf[64];
+            krb5_enctype_to_name(test->enctype, FALSE, buf, sizeof(buf));
+            printf("\nTest %d:\n", (int)i);
+            printf("Enctype: %s\n", buf);
+           printhex("Input key: ", inkey->keyblock.contents,
+                    inkey->keyblock.length);
+           printhex("Constant: ", test->constant.data, test->constant.length);
+           printhex("Output key: ", outkey->keyblock.contents,
+                    outkey->keyblock.length);
+       }
+        assert(outkey->keyblock.length == test->expected_key.length);
+        if (memcmp(outkey->keyblock.contents, test->expected_key.data,
+                   outkey->keyblock.length) != 0) {
+            printf("derive test %d failed\n", (int)i);
+            status = 1;
+            if (!verbose)
+                break;
+        }
+       krb5_k_free_key(context, inkey);
+       krb5_k_free_key(context, outkey);
+    }
+    return status;
+}
index c2d2be86978c1d6895ef8f52be9bc4b8de9e48e7..5008ab015628017a1dae21cdae9257e667a89ace 100644 (file)
@@ -45,9 +45,9 @@ krb5_enctype interesting_enctypes[] = {
     ENCTYPE_ARCFOUR_HMAC_EXP,
     ENCTYPE_AES256_CTS_HMAC_SHA1_96,
     ENCTYPE_AES128_CTS_HMAC_SHA1_96,
-#ifdef CAMELLIA_CCM
-    ENCTYPE_CAMELLIA128_CCM_128,
-    ENCTYPE_CAMELLIA256_CCM_128,
+#ifdef CAMELLIA
+    ENCTYPE_CAMELLIA128_CTS_CMAC,
+    ENCTYPE_CAMELLIA256_CTS_CMAC,
 #endif
     0
 };
index 9b1b630fc9a0f00ad1398933d53ca3208bf36644..7f9f3ad679a6e4309e41948bcdb776882f0404d0 100644 (file)
@@ -41,9 +41,9 @@ krb5_enctype interesting_enctypes[] = {
     ENCTYPE_ARCFOUR_HMAC_EXP,
     ENCTYPE_AES256_CTS_HMAC_SHA1_96,
     ENCTYPE_AES128_CTS_HMAC_SHA1_96,
-#ifdef CAMELLIA_CCM
-    ENCTYPE_CAMELLIA128_CCM_128,
-    ENCTYPE_CAMELLIA256_CCM_128,
+#ifdef CAMELLIA
+    ENCTYPE_CAMELLIA128_CTS_CMAC,
+    ENCTYPE_CAMELLIA256_CTS_CMAC,
 #endif
     0
 };
index d441e66f325ee9d7e9e6f8547443ba929be340ed..076ef6088258c3384885886805e419f216365b82 100644 (file)
@@ -158,139 +158,146 @@ struct test {
           "\x57\x18\x48\xB7\x84\xA3\xD6\xBD\xC3\x46\x58\x9A\x3E\x39\x3F\x9E" }
     },
 
-#ifdef CAMELLIA_CCM
-    /* The same inputs applied to camellia-ccm enctypes. */
+#ifdef CAMELLIA
+    /* The same inputs applied to Camellia enctypes. */
     { 
-        ENCTYPE_CAMELLIA128_CCM_128,
+        ENCTYPE_CAMELLIA128_CTS_CMAC,
         "password",
         "ATHENA.MIT.EDUraeburn",
         { KV5M_DATA, 4, "\0\0\0\1" },
         { KV5M_DATA, 16,
-          "\xF0\x10\x02\xD2\xB1\xF9\xA1\xAD\xE2\x57\xEE\xF7\x52\x9C\x2A\x16" }
+          "\x57\xD0\x29\x72\x98\xFF\xD9\xD3\x5D\xE5\xA4\x7F\xB4\xBD\xE2\x4B" }
     },
     { 
-        ENCTYPE_CAMELLIA256_CCM_128,
+        ENCTYPE_CAMELLIA256_CTS_CMAC,
         "password",
         "ATHENA.MIT.EDUraeburn",
         { KV5M_DATA, 4, "\0\0\0\1" },
         { KV5M_DATA, 32,
-          "\xD7\xEF\x37\xE2\xD1\x05\x5E\xB7\xD7\x6B\x06\x39\x6E\xF7\x00\x52"
-          "\x3D\xA4\xB0\xB7\xA0\x53\xF5\xCC\x5F\xAE\x4A\x39\xCF\xC5\x75\x0F" }
+          "\xB9\xD6\x82\x8B\x20\x56\xB7\xBE\x65\x6D\x88\xA1\x23\xB1\xFA\xC6"
+          "\x82\x14\xAC\x2B\x72\x7E\xCF\x5F\x69\xAF\xE0\xC4\xDF\x2A\x6D\x2C" }
     },
     { 
-        ENCTYPE_CAMELLIA128_CCM_128,
+        ENCTYPE_CAMELLIA128_CTS_CMAC,
         "password",
         "ATHENA.MIT.EDUraeburn",
         { KV5M_DATA, 4, "\0\0\0\2" },
         { KV5M_DATA, 16,
-          "\xDD\x74\x90\xC0\x57\x4A\x44\x6B\x10\x3A\xB3\x1B\x6D\xE4\x77\x4F" }
+          "\x73\xF1\xB5\x3A\xA0\xF3\x10\xF9\x3B\x1D\xE8\xCC\xAA\x0C\xB1\x52" }
     },
     { 
-        ENCTYPE_CAMELLIA256_CCM_128,
+        ENCTYPE_CAMELLIA256_CTS_CMAC,
         "password",
         "ATHENA.MIT.EDUraeburn",
         { KV5M_DATA, 4, "\0\0\0\2" },
         { KV5M_DATA, 32,
-          "\x68\xC1\x64\x74\x09\x42\x8F\x59\x47\x9B\x26\xC3\x98\x6D\x5B\xB8"
-          "\x66\x1C\xDE\x3C\x66\x79\xA0\xF5\x2C\x89\x01\xBD\x78\xDC\xEB\xA2" }
+          "\x83\xFC\x58\x66\xE5\xF8\xF4\xC6\xF3\x86\x63\xC6\x5C\x87\x54\x9F"
+          "\x34\x2B\xC4\x7E\xD3\x94\xDC\x9D\x3C\xD4\xD1\x63\xAD\xE3\x75\xE3" }
     },
     { 
-        ENCTYPE_CAMELLIA128_CCM_128,
+        ENCTYPE_CAMELLIA128_CTS_CMAC,
         "password",
         "ATHENA.MIT.EDUraeburn",
         { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */
         { KV5M_DATA, 16,
-          "\x1A\xA9\x0A\xA6\x1E\x0B\x3C\xB8\x6A\xA5\xA7\x7E\xD8\x44\x9D\x3B" }
+          "\x8E\x57\x11\x45\x45\x28\x55\x57\x5F\xD9\x16\xE7\xB0\x44\x87\xAA" }
     },
     { 
-        ENCTYPE_CAMELLIA256_CCM_128,
+        ENCTYPE_CAMELLIA256_CTS_CMAC,
         "password",
         "ATHENA.MIT.EDUraeburn",
         { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */
         { KV5M_DATA, 32,
-          "\xF8\x29\xBC\xE4\xBB\xB1\xA2\x4B\x01\xA0\xE8\xB1\xA7\x09\x52\x0A"
-          "\x61\x38\xE9\xAF\xE5\x13\x84\x59\xB2\x0B\xAC\xCA\xB2\x4D\x5F\xAA" }
+          "\x77\xF4\x21\xA6\xF2\x5E\x13\x83\x95\xE8\x37\xE5\xD8\x5D\x38\x5B"
+          "\x4C\x1B\xFD\x77\x2E\x11\x2C\xD9\x20\x8C\xE7\x2A\x53\x0B\x15\xE6" }
     },
     { 
-        ENCTYPE_CAMELLIA128_CCM_128,
+        ENCTYPE_CAMELLIA128_CTS_CMAC,
         "password",
         "\x12\x34\x56\x78\x78\x56\x34\x12",
         { KV5M_DATA, 4, "\0\0\0\5" },
         { KV5M_DATA, 16,
-          "\x35\x70\xC6\x68\x0D\xC6\xE9\xB0\x2E\x01\x28\x8B\xD0\xD2\xB6\x9B" }
+          "\x00\x49\x8F\xD9\x16\xBF\xC1\xC2\xB1\x03\x1C\x17\x08\x01\xB3\x81" }
     },
     { 
-        ENCTYPE_CAMELLIA256_CCM_128,
+        ENCTYPE_CAMELLIA256_CTS_CMAC,
         "password",
         "\x12\x34\x56\x78\x78\x56\x34\x12",
         { KV5M_DATA, 4, "\0\0\0\5" },
         { KV5M_DATA, 32,
-          "\x40\xB3\xB7\xC8\xF9\xC3\xB8\x65\x18\x10\xDC\x28\x42\x2D\x5F\x6D"
-          "\x10\xA6\xB3\xE9\xE1\x2A\x71\xFF\xA6\x35\x41\x08\x4A\xFA\x2C\xA2" }
+          "\x11\x08\x3A\x00\xBD\xFE\x6A\x41\xB2\xF1\x97\x16\xD6\x20\x2F\x0A"
+          "\xFA\x94\x28\x9A\xFE\x8B\x27\xA0\x49\xBD\x28\xB1\xD7\x6C\x38\x9A" }
     },
     { 
-        ENCTYPE_CAMELLIA128_CCM_128,
+        ENCTYPE_CAMELLIA128_CTS_CMAC,
         "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         "pass phrase equals block size",
         { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */
         { KV5M_DATA, 16,
-          "\xFF\x99\x18\x52\x84\x8E\x67\x50\x4C\x09\x4F\x94\x68\xC9\xD6\x05" }
+          "\x8B\xF6\xC3\xEF\x70\x9B\x98\x1D\xBB\x58\x5D\x08\x68\x43\xBE\x05" }
     },
     { 
-        ENCTYPE_CAMELLIA256_CCM_128,
+        ENCTYPE_CAMELLIA256_CTS_CMAC,
         "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         "pass phrase equals block size",
         { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */
         { KV5M_DATA, 32,
-          "\x56\x5C\x0A\x29\xC0\x58\xCD\xDC\x3C\xD8\xA9\xF3\x0A\x92\xAA\xD7"
-          "\xFE\x30\xEA\xD4\x16\xC1\x51\xAA\x9B\x54\x75\x56\x62\xF0\x95\xDD" }
+          "\x11\x9F\xE2\xA1\xCB\x0B\x1B\xE0\x10\xB9\x06\x7A\x73\xDB\x63\xED"
+          "\x46\x65\xB4\xE5\x3A\x98\xD1\x78\x03\x5D\xCF\xE8\x43\xA6\xB9\xB0" }
     },
     { 
-        ENCTYPE_CAMELLIA128_CCM_128,
+        ENCTYPE_CAMELLIA128_CTS_CMAC,
         "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         "pass phrase exceeds block size",
         { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */
         { KV5M_DATA, 16,
-          "\xAC\x83\x28\x64\x10\xA2\x8C\x76\x64\x79\x60\xF6\xA0\x37\x88\x03" }
+          "\x57\x52\xAC\x8D\x6A\xD1\xCC\xFE\x84\x30\xB3\x12\x87\x1C\x2F\x74" }
     },
     { 
-        ENCTYPE_CAMELLIA256_CCM_128,
+        ENCTYPE_CAMELLIA256_CTS_CMAC,
         "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         "pass phrase exceeds block size",
         { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */
         { KV5M_DATA, 32,
-          "\xD3\x25\x4A\x5B\x45\x1F\x27\x9C\x1A\xD6\x29\x3E\x72\xF0\x69\x55"
-          "\xEB\xFF\x36\xB6\x47\xDF\x97\x48\x97\x18\xD7\x5C\xF0\x6C\x40\x7C" }
+          "\x61\x4D\x5D\xFC\x0B\xA6\xD3\x90\xB4\x12\xB8\x9A\xE4\xD5\xB0\x88"
+          "\xB6\x12\xB3\x16\x51\x09\x94\x67\x9D\xDB\x43\x83\xC7\x12\x6D\xDF" }
     },
     { 
-        ENCTYPE_CAMELLIA128_CCM_128,
+        ENCTYPE_CAMELLIA128_CTS_CMAC,
         "\xf0\x9d\x84\x9e",
         "EXAMPLE.COMpianist",
         { KV5M_DATA, 4, "\0\0\0\x32" }, /* 50 */
         { KV5M_DATA, 16,
-          "\x5D\xBD\x71\x57\x09\x38\x59\x81\xDA\xAB\xA2\x8A\x43\x10\xD7\x20" }
+          "\xCC\x75\xC7\xFD\x26\x0F\x1C\x16\x58\x01\x1F\xCC\x0D\x56\x06\x16" }
     },
     { 
-        ENCTYPE_CAMELLIA256_CCM_128,
+        ENCTYPE_CAMELLIA256_CTS_CMAC,
         "\xf0\x9d\x84\x9e",
         "EXAMPLE.COMpianist",
         { KV5M_DATA, 4, "\0\0\0\x32" }, /* 50 */
         { KV5M_DATA, 32,
-          "\x6A\x1F\x10\xE5\x74\x4E\x32\xDD\x33\x49\x03\xA8\xEB\xD1\x42\x7E"
-          "\x4C\x8D\x3D\x6D\xA5\x76\x77\x50\x4C\x38\x4C\x24\x33\x0B\x60\x3D" }
+          "\x16\x3B\x76\x8C\x6D\xB1\x48\xB4\xEE\xC7\x16\x3D\xF5\xAE\xD7\x0E"
+          "\x20\x6B\x68\xCE\xC0\x78\xBC\x06\x9E\xD6\x8A\x7E\xD3\x6B\x1E\xCC" }
     }
-#endif /* CAMELLIA_CCM */
+#endif /* CAMELLIA */
 };
 
 static void
-printkey(krb5_keyblock *keyblock)
+printhex(const char *head, void *data, size_t len)
 {
-    unsigned int i;
+    size_t i;
 
-    for (i = 0; i < keyblock->length; i++) {
-        printf("%02X", keyblock->contents[i]);
-        if (i + 1 < keyblock->length)
+    printf("%s", head);
+    for (i = 0; i < len; i++) {
+#if 0                           /* For convenience when updating test cases. */
+        printf("\\x%02X", ((unsigned char*)data)[i]);
+#else
+        printf("%02X", ((unsigned char*)data)[i]);
+        if (i % 16 == 15 && i + 1 < len)
+            printf("\n%*s", (int)strlen(head), "");
+        else if (i + 1 < len)
             printf(" ");
+#endif
     }
     printf("\n");
 }
@@ -305,6 +312,7 @@ main(int argc, char **argv)
     size_t i;
     struct test *test;
     krb5_boolean verbose = FALSE;
+    int status = 0;
 
     if (argc >= 2 && strcmp(argv[1], "-v") == 0)
         verbose = TRUE;
@@ -321,16 +329,24 @@ main(int argc, char **argv)
             exit(1);
         }
         if (verbose) {
-            printf("Test %02d: ", (int)i);
-            printkey(keyblock);
+            char buf[64];
+            krb5_enctype_to_name(test->enctype, FALSE, buf, sizeof(buf));
+            printf("\nTest %d:\n", (int)i);
+            printf("Enctype: %s\n", buf);
+            printf("String: %s\n", test->string);
+            printf("Salt: %s\n", test->salt);
+            printhex("Params: ", test->params.data, test->params.length);
+            printhex("Key: ", keyblock->contents, keyblock->length);
         }
         assert(keyblock->length == test->expected_key.length);
         if (memcmp(keyblock->contents, test->expected_key.data,
                    keyblock->length) != 0) {
             printf("str2key test %d failed\n", (int)i);
-            exit(1);
+            status = 1;
+            if (!verbose)
+                break;
         }
         krb5_free_keyblock(context, keyblock);
     }
-    return 0;
+    return status;
 }
index a0e249ffd683869e5433ee36201ccdb70e6a07c3..ec4d65ff66e9dda3b136f2046a7931d84b039c90 100644 (file)
@@ -45,7 +45,7 @@
 #include "etypes.h"
 #include "cksumtypes.h"
 
-#ifdef CAMELLIA_CCM
+#ifdef CAMELLIA
 
 #define BLOCK_SIZE 16
 
@@ -226,7 +226,7 @@ krb5int_cmac_checksum(const struct krb5_enc_provider *enc, krb5_key key,
     return 0;
 }
 
-#else /* CAMELLIA_CCM */
+#else /* CAMELLIA */
 
 /* This won't be used, but is still in the export table. */
 
@@ -238,4 +238,4 @@ krb5int_cmac_checksum(const struct krb5_enc_provider *enc, krb5_key key,
     return EINVAL;
 }
 
-#endif /* CAMELLIA_CCM */
+#endif /* CAMELLIA */
index 6744775bcb27b883181061201dab4c86985c23dc..bcd514011f9bcf4f6c072b51515b5db623ed5dac 100644 (file)
@@ -105,19 +105,19 @@ const struct krb5_cksumtypes krb5int_cksumtypes_list[] = {
       krb5int_hmacmd5_checksum, NULL,
       16, 16, 0 },
 
-#ifdef CAMELLIA_CCM
-    { CKSUMTYPE_CMAC_128_CAMELLIA128,
-      "cmac-128-camellia128", { 0 }, "CMAC Camellia128 key",
-      &krb5int_enc_camellia128_ctr, NULL,
+#ifdef CAMELLIA
+    { CKSUMTYPE_CMAC_CAMELLIA128,
+      "cmac-camellia128", { 0 }, "CMAC Camellia128 key",
+      &krb5int_enc_camellia128, NULL,
       krb5int_dk_cmac_checksum, NULL,
       16, 16, 0 },
 
-    { CKSUMTYPE_CMAC_128_CAMELLIA256,
-      "cmac-128-camellia256", { 0 }, "CMAC Camellia256 key",
-      &krb5int_enc_camellia256_ctr, NULL,
+    { CKSUMTYPE_CMAC_CAMELLIA256,
+      "cmac-camellia256", { 0 }, "CMAC Camellia256 key",
+      &krb5int_enc_camellia256, NULL,
       krb5int_dk_cmac_checksum, NULL,
       16, 16, 0 },
-#endif /* CAMELLIA_CCM */
+#endif /* CAMELLIA */
 };
 
 const size_t krb5int_cksumtypes_length =
index 09df6c38d5fa093af18ab4347ba247ec714bd2f4..cd804bc6d97822817b37cacd77c42b29377a254f 100644 (file)
@@ -14,7 +14,7 @@ STLIBOBJS=\
        checksum_hmac.o \
        checksum_cmac.o \
        dk_aead.o       \
-       dk_ccm.o        \
+       dk_cmac.o       \
        derive.o        \
        stringtokey.o
 
@@ -22,7 +22,7 @@ OBJS=\
        $(OUTPRE)checksum_hmac.$(OBJEXT)\
        $(OUTPRE)checksum_cmac.$(OBJEXT)\
        $(OUTPRE)dk_aead.$(OBJEXT)      \
-       $(OUTPRE)dk_ccm.$(OBJEXT)       \
+       $(OUTPRE)dk_cmac.$(OBJEXT)      \
        $(OUTPRE)derive.$(OBJEXT)       \
        $(OUTPRE)stringtokey.$(OBJEXT)
 
@@ -30,7 +30,7 @@ SRCS=\
        $(srcdir)/checksum_hmac.c       \
        $(srcdir)/checksum_cmac.c       \
        $(srcdir)/dk_aead.c     \
-       $(srcdir)/dk_ccm.c      \
+       $(srcdir)/dk_cmac.c     \
        $(srcdir)/derive.c      \
        $(srcdir)/stringtokey.c
 
index c2309b7cd5405471ee9f88990c95c7df3488ce5c..ac3e4e9985bc422b8e288bf5d101226af0e77f53 100644 (file)
@@ -32,7 +32,7 @@
 
 #define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
 
-#ifdef CAMELLIA_CCM
+#ifdef CAMELLIA
 
 krb5_error_code
 krb5int_dk_cmac_checksum(const struct krb5_cksumtypes *ctp,
@@ -63,4 +63,4 @@ krb5int_dk_cmac_checksum(const struct krb5_cksumtypes *ctp,
     return ret;
 }
 
-#endif /* CAMELLIA_CCM */
+#endif /* CAMELLIA */
index a7ad2e344596897cd11040903fff7bf40579b270..d309206f1e5b9019270ae96d4441c2edd2abc470 100644 (file)
@@ -129,7 +129,7 @@ cleanup:
     return ret;
 }
 
-#ifdef CAMELLIA_CCM
+#ifdef CAMELLIA
 
 /*
  * NIST SP800-108 KDF in feedback mode (section 5.2).
@@ -181,7 +181,7 @@ derive_random_sp800_108_cmac(const struct krb5_enc_provider *enc,
     /* [L]2: four-byte big-endian binary string giving the output length */
     iov[5].flags = KRB5_CRYPTO_TYPE_DATA;
     iov[5].data = make_data(Lbuf, sizeof(Lbuf));
-    store_32_be(outrnd->length, Lbuf);
+    store_32_be(outrnd->length * 8, Lbuf);
 
     for (i = 1, n = 0; n < keybytes; i++) {
         /* Update the block counter. */
@@ -206,7 +206,7 @@ cleanup:
     return ret;
 }
 
-#endif /* CAMELLIA_CCM */
+#endif /* CAMELLIA */
 
 krb5_error_code
 krb5int_derive_random(const struct krb5_enc_provider *enc,
@@ -216,7 +216,7 @@ krb5int_derive_random(const struct krb5_enc_provider *enc,
     switch (alg) {
     case DERIVE_RFC3961:
         return derive_random_rfc3961(enc, inkey, outrnd, in_constant);
-#ifdef CAMELLIA_CCM
+#ifdef CAMELLIA
     case DERIVE_SP800_108_CMAC:
         return derive_random_sp800_108_cmac(enc, inkey, outrnd, in_constant);
 #endif
index fb6df88fa81ff212cf45c311c80177adfa4c7093..079977847f88564a7a0646b77aff39332b4a6165 100644 (file)
@@ -37,6 +37,9 @@ unsigned int
 krb5int_aes_crypto_length(const struct krb5_keytypes *ktp,
                           krb5_cryptotype type);
 
+unsigned int
+krb5int_camellia_crypto_length(const struct krb5_keytypes *ktp,
+                               krb5_cryptotype type);
 krb5_error_code
 krb5int_dk_encrypt(const struct krb5_keytypes *ktp, krb5_key key,
                    krb5_keyusage usage, const krb5_data *ivec,
@@ -58,15 +61,15 @@ krb5int_aes_string_to_key(const struct krb5_keytypes *enc,
                           const krb5_data *params, krb5_keyblock *key);
 
 krb5_error_code
-krb5int_camellia_ccm_string_to_key(const struct krb5_keytypes *enc,
-                                   const krb5_data *string,
-                                   const krb5_data *salt,
-                                   const krb5_data *params,
-                                   krb5_keyblock *key);
+krb5int_camellia_string_to_key(const struct krb5_keytypes *enc,
+                               const krb5_data *string,
+                               const krb5_data *salt,
+                               const krb5_data *params,
+                               krb5_keyblock *key);
 
 enum deriv_alg {
     DERIVE_RFC3961,             /* RFC 3961 section 5.1 */
-#ifdef CAMELLIA_CCM
+#ifdef CAMELLIA
     DERIVE_SP800_108_CMAC       /* NIST SP 800-108 with CMAC as PRF */
 #endif
 };
@@ -92,36 +95,20 @@ krb5int_derive_random(const struct krb5_enc_provider *enc,
                       krb5_key inkey, krb5_data *outrnd,
                       const krb5_data *in_constant, enum deriv_alg alg);
 
-unsigned int
-krb5int_dk_ccm_crypto_length(const struct krb5_keytypes *ktp,
-                             krb5_cryptotype type);
-
 krb5_error_code
-krb5int_dk_ccm_encrypt(const struct krb5_keytypes *ktp,
-                       krb5_key key,
-                       krb5_keyusage usage,
-                       const krb5_data *ivec,
-                       krb5_crypto_iov *data,
-                       size_t num_data);
+krb5int_dk_cmac_encrypt(const struct krb5_keytypes *ktp,
+                        krb5_key key, krb5_keyusage usage,
+                        const krb5_data *ivec, krb5_crypto_iov *data,
+                        size_t num_data);
 
 krb5_error_code
-krb5int_dk_ccm_decrypt(const struct krb5_keytypes *ktp,
-                       krb5_key key,
-                       krb5_keyusage usage,
-                       const krb5_data *ivec,
-                       krb5_crypto_iov *data,
-                       size_t num_data);
+krb5int_dk_cmac_decrypt(const struct krb5_keytypes *ktp,
+                        krb5_key key, krb5_keyusage usage,
+                        const krb5_data *ivec, krb5_crypto_iov *data,
+                        size_t num_data);
 
 krb5_error_code
 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);
-
-krb5_error_code
-krb5int_dk_ccm_init_state(const struct krb5_keytypes *ktp,
-                          const krb5_keyblock *key, krb5_keyusage usage,
-                          krb5_data *out_state);
-
-void
-krb5int_dk_ccm_free_state(const struct krb5_keytypes *ktp, krb5_data *state);
diff --git a/src/lib/crypto/krb/dk/dk_ccm.c b/src/lib/crypto/krb/dk/dk_ccm.c
deleted file mode 100644 (file)
index 284e362..0000000
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * lib/crypto/krb/dk/dk_ccm.c
- *
- * Copyright 2008-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.
- */
-
-#include "k5-int.h"
-#include "dk.h"
-#include "aead.h"
-
-#ifdef CAMELLIA_CCM
-
-/*
- * Implement CCM-mode AEAD as described in section 5.3 and 5.4 of RFC 5116.
- * This is the CCM mode as described in NIST SP800-38C, with a 12 byte nonce
- * and 16 byte checksum.  Multiple buffers of the same type are logically
- * concatenated.  The underlying enc provider must have a 16-byte block size,
- * must have a counter-mode encrypt method, and must have a cbc_mac method.
- *
- * The IOV should be laid out as follows:
- *
- *    HEADER | SIGN_DATA | DATA | PADDING | TRAILER
- *
- * SIGN_DATA and PADDING may be absent.
- *
- * Upon decryption, one can pass in explicit buffers as for encryption, or one
- * can pass in STREAM, being the concatenation of HEADER | DATA | TRAILER.
- *
- *    STREAM | SIGN_DATA | DATA
- *
- * Upon output, DATA will contain a pointer into the STREAM buffer with the
- * decrypted payload. SIGN_DATA should be ordered relative to the output DATA
- * buffer as it was upon encryption.
- *
- * For compatibility with RFC 5116, a single key is used both for encryption
- * and checksumming. The key derivation function is as follows:
- *
- *    Kc = DK(base-key, usage | 0xCC)
- *
- * Again as required by the CCM specification, SIGN_DATA is processed before
- * DATA for the purpose of checksumming.
- */
-
-#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
-
-unsigned int
-krb5int_dk_ccm_crypto_length(const struct krb5_keytypes *ktp,
-                             krb5_cryptotype type)
-{
-    unsigned int length;
-
-    switch (type) {
-    case KRB5_CRYPTO_TYPE_HEADER:
-        length = 12; /* RFC 5116 5.3 */
-        break;
-    case KRB5_CRYPTO_TYPE_PADDING:
-        length = 0; /* CTR mode requires no padding */
-        break;
-    case KRB5_CRYPTO_TYPE_TRAILER:
-    case KRB5_CRYPTO_TYPE_CHECKSUM:
-        length = ktp->enc->block_size;
-        break;
-    default:
-        assert(0 && "invalid cryptotype passed to ccm_crypto_length");
-        length = ~0;
-        break;
-    }
-
-    return length;
-}
-
-/*
- * Encode the length of the additional data according to NIST SP800-38C section
- * A.2.2.  The size of the encoding will be 0, 2, 6, or 10 bytes depending on
- * the length value.
- */
-static krb5_error_code
-encode_a_len(krb5_data *a, krb5_ui_8 adata_len)
-{
-    size_t len;
-    unsigned char *p;
-
-    if (adata_len > (1LL << 32))
-        len = 10;
-    else if (adata_len > (1LL << 16) - (1LL << 8))
-        len = 6;
-    else if (adata_len)
-        len = 2;
-    else
-        len = 0;
-
-    if (a->length < len)
-        return KRB5_BAD_MSIZE;
-
-    p = (unsigned char *)a->data;
-
-    switch (len) {
-    case 2:
-       /* Two raw bytes; first byte will not be 0xFF. */
-        p[0] = (adata_len >> 8) & 0xFF;
-        p[1] = (adata_len     ) & 0xFF;
-        break;
-    case 6:
-       /* FF FE followed by four bytes. */
-        p[0] = 0xFF;
-        p[1] = 0xFE;
-        p[2] = (adata_len >> 24) & 0xFF;
-        p[3] = (adata_len >> 16) & 0xFF;
-        p[4] = (adata_len >> 8 ) & 0xFF;
-        p[5] = (adata_len      ) & 0xFF;
-        break;
-    case 10:
-       /* FF FF followed by eight bytes. */
-        p[0] = 0xFF;
-        p[1] = 0xFF;
-        p[2] = (adata_len >> 56) & 0xFF;
-        p[3] = (adata_len >> 48) & 0xFF;
-        p[4] = (adata_len >> 40) & 0xFF;
-        p[5] = (adata_len >> 32) & 0xFF;
-        p[6] = (adata_len >> 24) & 0xFF;
-        p[7] = (adata_len >> 16) & 0xFF;
-        p[8] = (adata_len >> 8 ) & 0xFF;
-        p[9] = (adata_len      ) & 0xFF;
-        break;
-    }
-
-    a->length = len;
-
-    return 0;
-}
-
-/*
- * Encode the first 16-byte block of CBC-MAC input according to NIST SP800-38C
- * section A.2.1.  n (the nonce length) is given by nonce->length.
- */
-static krb5_error_code
-format_B0(krb5_data *B0,            /* B0 */
-          krb5_data *nonce,         /* N */
-          size_t trailer_len,       /* t */
-          krb5_ui_8 adata_len,      /* a */
-          krb5_ui_8 payload_len)    /* Q */
-{
-    unsigned char flags;
-    unsigned char *p;
-    krb5_octet q, i = 0;
-
-    if (B0->length != 16)
-        return KRB5_BAD_MSIZE;
-
-    /* Section A.1: Length Requirements */
-
-    /* t is an element of {4, 6, 8, 10, 12, 14, 16}. */
-    if (trailer_len % 2 ||
-        (trailer_len < 4 || trailer_len > 16))
-        return KRB5_BAD_MSIZE;
-
-    /* n is an element of {7, 8, 9, 10, 11, 12, 13}. */
-    if (nonce->length < 7 || nonce->length > 13)
-        return KRB5_BAD_MSIZE;
-
-    q = 15 - nonce->length;
-
-    /* P consists of fewer than 2^(8q) octets. */
-    if (payload_len >= (1UL << (8 * q)))
-        return KRB5_BAD_MSIZE;
-
-    /* Encode the flags octet. */
-    flags = q - 1;
-    flags |= (((trailer_len - 2) / 2) << 3);
-    if (adata_len != 0)
-        flags |= (1 << 6);
-
-    p = (unsigned char *)B0->data;
-    p[i++] = flags;
-
-    /* Next comes the nonce (n bytes). */
-    memcpy(&p[i], nonce->data, nonce->length);
-    i += nonce->length;
-
-    /* The final q bytes are the payload length. */
-    for (; i < B0->length; i++) {
-        register krb5_octet s;
-
-        s = (q - (i - nonce->length)) * 8;
-
-        p[i] = (payload_len >> s) & 0xFF;
-    }
-
-    return 0;
-}
-
-/*
- * Encode the initial counter block according to NIST SP800-38C section A.3.
- * The counter value may be chained across krb5_k_encrypt invocations via the
- * cipher_state parameter; otherwise it begins at 0.
- */
-static krb5_error_code
-format_Ctr0(krb5_data *counter, const krb5_data *nonce, const krb5_data *state,
-            unsigned int n)
-{
-    krb5_octet q; /* counter length */
-
-    assert(n >= 7 && n <= 13);
-
-    /* First byte is q-1 in the lowest three bits. */
-    q = 15 - n;
-    counter->data[0] = q - 1;
-    /* Next comes the nonce (n bytes). */
-    memcpy(&counter->data[1], nonce->data, n);
-
-    /* Finally, the counter value. */
-    if (state != NULL)
-        memcpy(&counter->data[1 + n], state->data, q);
-    else
-        memset(&counter->data[1 + n], 0, q);
-
-    return 0;
-}
-
-/* Return true if the payload length is valid given the nonce length n. */
-static krb5_boolean
-valid_payload_length_p(const struct krb5_keytypes *ktp, unsigned int n,
-                       unsigned int payload_len)
-{
-    unsigned int block_size = ktp->enc->block_size;
-    unsigned int nblocks, maxblocks;
-    krb5_octet q;
-
-    assert(n >= 7 && n <= 13);
-
-    q = 15 - n;
-
-    maxblocks = (1U << (8 * q)) - 1 /* tag */;
-
-    nblocks = (payload_len + block_size - 1) / block_size;
-
-    return (nblocks <= maxblocks);
-}
-
-/* Encrypt and authenticate data according to NIST SP800-38C section 6.1. */
-static krb5_error_code
-ccm_encrypt(const struct krb5_keytypes *ktp, krb5_key kc,
-           const krb5_data *state, krb5_crypto_iov *data, size_t num_data)
-{
-    krb5_error_code ret;
-    krb5_crypto_iov *header, *trailer, *sign_data = NULL, cksum;
-    size_t i, num_sign_data = 0;
-    unsigned int header_len;
-    unsigned int trailer_len;
-    size_t payload_len = 0;
-    size_t adata_len = 0;
-    char adata_len_buf[6];
-    unsigned char B0[16], Ctr[16];
-    krb5_data counter = make_data(Ctr, sizeof(Ctr));
-
-    header_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_HEADER);
-
-    header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
-    if (header == NULL || header->data.length < header_len) {
-        ret = KRB5_BAD_MSIZE;
-        goto cleanup;
-    }
-
-    trailer_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER);
-
-    trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
-    if (trailer == NULL || trailer->data.length < trailer_len) {
-        ret = KRB5_BAD_MSIZE;
-        goto cleanup;
-    }
-
-    for (i = 0; i < num_data; i++) {
-        krb5_crypto_iov *iov = &data[i];
-
-        switch (iov->flags) {
-        case KRB5_CRYPTO_TYPE_DATA:
-            payload_len += iov->data.length;
-            break;
-        case KRB5_CRYPTO_TYPE_SIGN_ONLY:
-            adata_len += iov->data.length;
-            break;
-        case KRB5_CRYPTO_TYPE_PADDING:
-            iov->data.length = 0;
-            break;
-        default:
-            break;
-        }
-    }
-
-    if (!valid_payload_length_p(ktp, header_len, payload_len)) {
-        ret = KRB5_BAD_MSIZE;
-        goto cleanup;
-    }
-
-    header->data.length = header_len;
-    trailer->data.length = trailer_len;
-
-    /* Choose a random nonce. */
-    ret = krb5_c_random_make_octets(NULL, &header->data);
-    if (ret != 0)
-        goto cleanup;
-
-    /* Encode the first counter block. */
-    ret = format_Ctr0(&counter, &header->data, state, header_len);
-    if (ret != 0)
-        goto cleanup;
-
-    /* Create a list of CBC-MAC input blocks. */
-    sign_data = k5alloc((num_data + 1) * sizeof(krb5_crypto_iov), &ret);
-    if (sign_data == NULL)
-        goto cleanup;
-
-    /* Format the initial control/nonce block. */
-    sign_data[0].flags = KRB5_CRYPTO_TYPE_HEADER;
-    sign_data[0].data = make_data(B0, sizeof(B0));
-    ret = format_B0(&sign_data[0].data, &header->data, trailer_len,
-                    (krb5_ui_8)adata_len, (krb5_ui_8)payload_len);
-    if (ret != 0)
-        goto cleanup;
-
-    /* Format the length of associated data. */
-    sign_data[1].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
-    sign_data[1].data = make_data(adata_len_buf, sizeof(adata_len_buf));
-    ret = encode_a_len(&sign_data[1].data, (krb5_ui_8)adata_len);
-    if (ret != 0)
-        goto cleanup;
-    num_sign_data = 2;
-
-    /* Reorder input IOV so SIGN_ONLY data is before DATA. */
-    for (i = 0; i < num_data; i++) {
-        if (data[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY)
-            sign_data[num_sign_data++] = data[i];
-    }
-    for (i = 0; i < num_data; i++) {
-        if (data[i].flags == KRB5_CRYPTO_TYPE_DATA)
-            sign_data[num_sign_data++] = data[i];
-    }
-
-    assert(ktp->enc->encrypt != NULL);
-    assert(ktp->enc->cbc_mac != NULL);
-
-    /* Make checksum and place in trailer. */
-    ret = ktp->enc->cbc_mac(kc, sign_data, num_sign_data, NULL,
-                           &trailer->data);
-    if (ret != 0)
-        goto cleanup;
-
-    /* Encrypt checksum in trailer using the first counter block. */
-    cksum.flags = KRB5_CRYPTO_TYPE_DATA;
-    cksum.data = trailer->data;
-    ret = ktp->enc->encrypt(kc, &counter, &cksum, 1);
-    if (ret != 0)
-       goto cleanup;
-
-    /* Encrypt everything but B0 (header) in subsequent counter blocks. */
-    ret = ktp->enc->encrypt(kc, &counter, data, num_data);
-    if (ret != 0)
-        goto cleanup;
-
-    /* Store the counter value as cipher state.  Subsequent encryptions will
-     * generate a fresh nonce. */
-    if (state != NULL)
-        memcpy(state->data, counter.data + 1 + header_len, 15 - header_len);
-
-cleanup:
-    free(sign_data);
-    return ret;
-}
-
-/* Derive an encryption key based on usage and CCM-encrypt data. */
-krb5_error_code
-krb5int_dk_ccm_encrypt(const struct krb5_keytypes *ktp, krb5_key key,
-                       krb5_keyusage usage, const krb5_data *state,
-                       krb5_crypto_iov *data, size_t num_data)
-{
-    unsigned char constantdata[K5CLENGTH];
-    krb5_error_code ret;
-    krb5_key kc;
-    krb5_data d1;
-
-    d1.data = (char *)constantdata;
-    d1.length = K5CLENGTH;
-
-    d1.data[0] = (usage >> 24) & 0xFF;
-    d1.data[1] = (usage >> 16) & 0xFF;
-    d1.data[2] = (usage >> 8 ) & 0xFF;
-    d1.data[3] = (usage      ) & 0xFF;
-
-    d1.data[4] = 0xCC;
-
-    ret = krb5int_derive_key(ktp->enc, key, &kc, &d1, DERIVE_SP800_108_CMAC);
-    if (ret != 0)
-        return ret;
-
-    ret = ccm_encrypt(ktp, kc, state, data, num_data);
-
-    krb5_k_free_key(NULL, kc);
-
-    return ret;
-}
-
-/* Decrypt and verify data according to NIST SP800-38C section 6.2. */
-static krb5_error_code
-ccm_decrypt(const struct krb5_keytypes *ktp, krb5_key kc,
-           const krb5_data *state, krb5_crypto_iov *data, size_t num_data)
-{
-    krb5_error_code ret;
-    krb5_crypto_iov *header, *trailer, *sign_data = NULL, got_cksum;
-    size_t i, num_sign_data = 0;
-    unsigned int header_len;
-    unsigned int trailer_len;
-    size_t adata_len = 0;
-    size_t payload_len = 0;
-    char adata_len_buf[6];
-    unsigned char B0[16], Ctr[16];
-    krb5_data made_cksum = empty_data();
-    krb5_data counter = make_data(Ctr, sizeof(Ctr));
-
-    header_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_HEADER);
-
-    header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
-    if (header == NULL || header->data.length != header_len) {
-        ret = KRB5_BAD_MSIZE;
-        goto cleanup;
-    }
-
-    trailer_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER);
-
-    trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
-    if (trailer == NULL || trailer->data.length != trailer_len) {
-        ret = KRB5_BAD_MSIZE;
-        goto cleanup;
-    }
-
-    for (i = 0; i < num_data; i++) {
-        krb5_crypto_iov *iov = &data[i];
-
-        switch (iov->flags) {
-        case KRB5_CRYPTO_TYPE_DATA:
-            payload_len += iov->data.length;
-            break;
-        case KRB5_CRYPTO_TYPE_SIGN_ONLY:
-            adata_len += iov->data.length;
-            break;
-        case KRB5_CRYPTO_TYPE_PADDING:
-            if (iov->data.length != 0) {
-                ret = KRB5_BAD_MSIZE;
-                goto cleanup;
-            }
-            break;
-        default:
-            break;
-        }
-    }
-
-    if (!valid_payload_length_p(ktp, header_len, payload_len)) {
-        ret = KRB5_BAD_MSIZE;
-        goto cleanup;
-    }
-
-    /* Encode the first counter block. */
-    ret = format_Ctr0(&counter, &header->data, state, header_len);
-    if (ret != 0)
-        goto cleanup;
-
-    /* Create a list of CBC-MAC input blocks. */
-    sign_data = k5alloc((num_data + 1) * sizeof(krb5_crypto_iov), &ret);
-    if (sign_data == NULL)
-        goto cleanup;
-
-    /* Format the initial control/nonce block. */
-    sign_data[0].flags = KRB5_CRYPTO_TYPE_HEADER;
-    sign_data[0].data = make_data(B0, sizeof(B0));
-    ret = format_B0(&sign_data[0].data, &header->data, trailer_len,
-                    (krb5_ui_8)adata_len, (krb5_ui_8)payload_len);
-    if (ret != 0)
-        goto cleanup;
-
-    /* Format the length of associated data. */
-    sign_data[1].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
-    sign_data[1].data = make_data(adata_len_buf, sizeof(adata_len_buf));
-    ret = encode_a_len(&sign_data[1].data, (krb5_ui_8)adata_len);
-    if (ret != 0)
-        goto cleanup;
-    num_sign_data = 2;
-
-    assert(ktp->enc->decrypt != NULL);
-    assert(ktp->enc->cbc_mac != NULL);
-
-    made_cksum.data = k5alloc(trailer_len, &ret);
-    if (made_cksum.data == NULL)
-        goto cleanup;
-    made_cksum.length = trailer_len;
-
-    /* Decrypt checksum from trailer using the first counter block. */
-    got_cksum.flags = KRB5_CRYPTO_TYPE_DATA;
-    got_cksum.data = trailer->data;
-    ret = ktp->enc->decrypt(kc, &counter, &got_cksum, 1);
-    if (ret != 0)
-       goto cleanup;
-
-    /* Decrypt everything but B0 (header) in subsequent counter blocks. */
-    ret = ktp->enc->decrypt(kc, &counter, data, num_data);
-    if (ret != 0)
-        goto cleanup;
-
-    /* Reorder input IOV so SIGN_ONLY data is before DATA */
-    for (i = 0; i < num_data; i++) {
-        if (data[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY)
-            sign_data[num_sign_data++] = data[i];
-    }
-    for (i = 0; i < num_data; i++) {
-        if (data[i].flags == KRB5_CRYPTO_TYPE_DATA)
-            sign_data[num_sign_data++] = data[i];
-    }
-
-    /* Calculate CBC-MAC for comparison (including B0). */
-    ret = ktp->enc->cbc_mac(kc, sign_data, num_sign_data, NULL, &made_cksum);
-    if (ret != 0)
-        goto cleanup;
-
-    if (made_cksum.length != trailer->data.length ||
-        memcmp(made_cksum.data, trailer->data.data,
-              trailer->data.length) != 0) {
-        ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
-        goto cleanup;
-    }
-
-    /* Store the counter value as cipher state.  Subsequent encryptions will
-     * generate a fresh nonce. */
-    if (state != NULL)
-        memcpy(state->data, counter.data + 1 + header_len, 15 - header_len);
-
-cleanup:
-    free(made_cksum.data);
-    free(sign_data);
-
-    return ret;
-}
-
-/* Derive an encryption key based on usage and CCM-decrypt data. */
-krb5_error_code
-krb5int_dk_ccm_decrypt(const struct krb5_keytypes *ktp, krb5_key key,
-                       krb5_keyusage usage, const krb5_data *state,
-                       krb5_crypto_iov *data, size_t num_data)
-{
-    unsigned char constantdata[K5CLENGTH];
-    krb5_error_code ret;
-    krb5_key kc;
-    krb5_data d1;
-
-    d1.data = (char *)constantdata;
-    d1.length = K5CLENGTH;
-
-    d1.data[0] = (usage >> 24) & 0xFF;
-    d1.data[1] = (usage >> 16) & 0xFF;
-    d1.data[2] = (usage >> 8 ) & 0xFF;
-    d1.data[3] = (usage      ) & 0xFF;
-
-    d1.data[4] = 0xCC;
-
-    ret = krb5int_derive_key(ktp->enc, key, &kc, &d1, DERIVE_SP800_108_CMAC);
-    if (ret != 0)
-        return ret;
-
-    ret = ccm_decrypt(ktp, kc, state, data, num_data);
-
-    krb5_k_free_key(NULL, kc);
-
-    return ret;
-}
-
-krb5_error_code
-krb5int_dk_ccm_init_state(const struct krb5_keytypes *ktp,
-                          const krb5_keyblock *key, krb5_keyusage usage,
-                          krb5_data *out_state)
-{
-    unsigned int header_len;
-
-    /* The cipher state is the q-byte block counter value. */
-    header_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_HEADER);
-    return alloc_data(out_state, 15 - header_len);
-}
-
-void
-krb5int_dk_ccm_free_state(const struct krb5_keytypes *ktp,
-                          krb5_data *state)
-{
-    free(state->data);
-    state->data = NULL;
-    state->length = 0;
-}
-
-#endif /* CAMELLIA_CCM */
diff --git a/src/lib/crypto/krb/dk/dk_cmac.c b/src/lib/crypto/krb/dk/dk_cmac.c
new file mode 100644 (file)
index 0000000..9ac5bee
--- /dev/null
@@ -0,0 +1,188 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/dk/dk_cmac.c - Derived-key enctype functions using CMAC */
+/*
+ * Copyright 2008, 2009, 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.
+ */
+
+
+#include "k5-int.h"
+#include "dk.h"
+#include "aead.h"
+
+#ifdef CAMELLIA
+
+#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
+
+/* AEAD */
+
+unsigned int
+krb5int_camellia_crypto_length(const struct krb5_keytypes *ktp,
+                              krb5_cryptotype type)
+{
+    switch (type) {
+    case KRB5_CRYPTO_TYPE_HEADER:
+        return ktp->enc->block_size;
+    case KRB5_CRYPTO_TYPE_PADDING:
+        return 0;
+    case KRB5_CRYPTO_TYPE_TRAILER:
+    case KRB5_CRYPTO_TYPE_CHECKSUM:
+        return ktp->enc->block_size;
+    default:
+        assert(0 && "bad type passed to krb5int_camellia_crypto_length");
+        return 0;
+    }
+}
+
+/* Derive encryption and integrity keys for CMAC-using enctypes. */
+static krb5_error_code
+derive_keys(const struct krb5_enc_provider *enc, krb5_key key,
+           krb5_keyusage usage, krb5_key *ke_out, krb5_key *ki_out)
+{
+    krb5_error_code ret;
+    unsigned char buf[K5CLENGTH];
+    krb5_data constant = make_data(buf, K5CLENGTH);
+    krb5_key ke, ki;
+
+    *ke_out = *ki_out = NULL;
+
+    /* Derive the encryption key. */
+    store_32_be(usage, buf);
+    buf[4] = 0xAA;
+    ret = krb5int_derive_key(enc, key, &ke, &constant, DERIVE_SP800_108_CMAC);
+    if (ret != 0)
+       return ret;
+
+    /* Derive the integrity key. */
+    buf[4] = 0x55;
+    ret = krb5int_derive_key(enc, key, &ki, &constant, DERIVE_SP800_108_CMAC);
+    if (ret != 0) {
+       krb5_k_free_key(NULL, ke);
+       return ret;
+    }
+
+    *ke_out = ke;
+    *ki_out = ki;
+    return 0;
+}
+
+krb5_error_code
+krb5int_dk_cmac_encrypt(const struct krb5_keytypes *ktp, krb5_key key,
+                       krb5_keyusage usage, const krb5_data *ivec,
+                       krb5_crypto_iov *data, size_t num_data)
+{
+    const struct krb5_enc_provider *enc = ktp->enc;
+    krb5_error_code ret;
+    krb5_crypto_iov *header, *trailer, *padding;
+    krb5_data cksum = empty_data();
+    krb5_key ke = NULL, ki = NULL;
+
+    /* E(Confounder | Plaintext | Pad) | Checksum */
+
+    /* Validate header and trailer lengths, and zero out padding length. */
+    header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
+    if (header == NULL || header->data.length < enc->block_size)
+        return KRB5_BAD_MSIZE;
+    trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
+    if (trailer == NULL || trailer->data.length < enc->block_size)
+        return KRB5_BAD_MSIZE;
+    padding = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_PADDING);
+    if (padding != NULL)
+       padding->data.length = 0;
+
+    /* Derive the encryption and integrity keys. */
+    ret = derive_keys(enc, key, usage, &ke, &ki);
+    if (ret != 0)
+        goto cleanup;
+
+    /* Generate confounder. */
+    header->data.length = enc->block_size;
+    ret = krb5_c_random_make_octets(NULL, &header->data);
+    if (ret != 0)
+        goto cleanup;
+
+    /* Checksum the plaintext. */
+    ret = krb5int_cmac_checksum(enc, ki, data, num_data, &trailer->data);
+    if (ret != 0)
+        goto cleanup;
+
+    /* Encrypt the plaintext (header | data | padding) */
+    ret = enc->encrypt(ke, ivec, data, num_data);
+    if (ret != 0)
+        goto cleanup;
+
+cleanup:
+    krb5_k_free_key(NULL, ke);
+    krb5_k_free_key(NULL, ki);
+    zapfree(cksum.data, cksum.length);
+    return ret;
+}
+
+krb5_error_code
+krb5int_dk_cmac_decrypt(const struct krb5_keytypes *ktp, krb5_key key,
+                        krb5_keyusage usage, const krb5_data *ivec,
+                        krb5_crypto_iov *data, size_t num_data)
+{
+    const struct krb5_enc_provider *enc = ktp->enc;
+    krb5_error_code ret;
+    krb5_crypto_iov *header, *trailer;
+    krb5_data cksum;
+    krb5_key ke = NULL, ki = NULL;
+
+    /* E(Confounder | Plaintext | Pad) | Checksum */
+
+    /* Validate header and trailer lengths. */
+    header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
+    if (header == NULL || header->data.length != enc->block_size)
+        return KRB5_BAD_MSIZE;
+    trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
+    if (trailer == NULL || trailer->data.length != enc->block_size)
+        return KRB5_BAD_MSIZE;
+
+    /* Derive the encryption and integrity keys. */
+    ret = derive_keys(enc, key, usage, &ke, &ki);
+    if (ret != 0)
+        goto cleanup;
+
+    /* Decrypt the plaintext (header | data | padding). */
+    ret = enc->decrypt(ke, ivec, data, num_data);
+    if (ret != 0)
+        goto cleanup;
+
+    /* Verify the hash. */
+    ret = alloc_data(&cksum, enc->block_size);
+    if (ret != 0)
+        goto cleanup;
+    ret = krb5int_cmac_checksum(enc, ki, data, num_data, &cksum);
+    if (ret != 0)
+        goto cleanup;
+    if (!data_eq(cksum, trailer->data))
+        ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+
+cleanup:
+    krb5_k_free_key(NULL, ke);
+    krb5_k_free_key(NULL, ki);
+    zapfree(cksum.data, cksum.length);
+    return ret;
+}
+
+#endif /* CAMELLIA */
index 12ef67a01700796ac54454afc94f32403c78d24a..779f51bdf02259557178f35d4cdfbc064ae3c6c0 100644 (file)
@@ -101,14 +101,13 @@ cleanup:
 }
 
 
-#define DEFAULT_ITERATION_COUNT         4096 /* was 0xb000L in earlier drafts */
 #define MAX_ITERATION_COUNT             0x1000000L
 
 static krb5_error_code
 pbkdf2_string_to_key(const struct krb5_keytypes *ktp, const krb5_data *string,
                      const krb5_data *salt, const krb5_data *pepper,
                      const krb5_data *params, krb5_keyblock *key,
-                     enum deriv_alg deriv_alg)
+                     enum deriv_alg deriv_alg, unsigned long def_iter_count)
 {
     unsigned long iter_count;
     krb5_data out;
@@ -129,7 +128,7 @@ pbkdf2_string_to_key(const struct krb5_keytypes *ktp, const krb5_data *string,
                 return KRB5_ERR_BAD_S2K_PARAMS;
         }
     } else
-        iter_count = DEFAULT_ITERATION_COUNT;
+        iter_count = def_iter_count;
 
     /* This is not a protocol specification constraint; this is an
        implementation limit, which should eventually be controlled by
@@ -182,20 +181,20 @@ krb5int_aes_string_to_key(const struct krb5_keytypes *ktp,
                           krb5_keyblock *key)
 {
     return pbkdf2_string_to_key(ktp, string, salt, NULL, params, key,
-                                DERIVE_RFC3961);
+                                DERIVE_RFC3961, 4096);
 }
 
-#ifdef CAMELLIA_CCM
+#ifdef CAMELLIA
 krb5_error_code
-krb5int_camellia_ccm_string_to_key(const struct krb5_keytypes *ktp,
-                                   const krb5_data *string,
-                                   const krb5_data *salt,
-                                   const krb5_data *params,
-                                   krb5_keyblock *key)
+krb5int_camellia_string_to_key(const struct krb5_keytypes *ktp,
+                               const krb5_data *string,
+                               const krb5_data *salt,
+                               const krb5_data *params,
+                               krb5_keyblock *key)
 {
     krb5_data pepper = string2data(ktp->name);
 
     return pbkdf2_string_to_key(ktp, string, salt, &pepper, params, key,
-                                DERIVE_SP800_108_CMAC);
+                                DERIVE_SP800_108_CMAC, 32768);
 }
 #endif
index 7a8d6f198c079d8b5a70623f0204574fb05c2b36..9703a939bd08d9882da3bff2117213da9ed865fe 100644 (file)
@@ -164,30 +164,32 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
       krb5int_init_state_enc, krb5int_free_state_enc,
       CKSUMTYPE_HMAC_SHA1_96_AES256,
       0 /*flags*/ },
-#ifdef CAMELLIA_CCM
-    { ENCTYPE_CAMELLIA128_CCM_128,
-      "camellia128-ccm-128", { "camellia128-ccm" },
-      "Camellia-128 CCM mode with 128-bit MAC",
-      &krb5int_enc_camellia128_ctr, NULL,
+#ifdef CAMELLIA
+    { ENCTYPE_CAMELLIA128_CTS_CMAC,
+      "camellia128-cts-cmac", { "camellia128-cts" },
+      "Camellia-128 CTS mode with CMAC",
+      &krb5int_enc_camellia128, NULL,
       16,
-      krb5int_dk_ccm_crypto_length, krb5int_dk_ccm_encrypt, krb5int_dk_ccm_decrypt,
-      krb5int_camellia_ccm_string_to_key,
+      krb5int_camellia_crypto_length,
+      krb5int_dk_cmac_encrypt, krb5int_dk_cmac_decrypt,
+      krb5int_camellia_string_to_key,
       krb5int_dk_cmac_prf,
-      krb5int_dk_ccm_init_state, krb5int_dk_ccm_free_state,
-      CKSUMTYPE_CMAC_128_CAMELLIA128,
+      krb5int_init_state_enc, krb5int_free_state_enc,
+      CKSUMTYPE_CMAC_CAMELLIA128,
       0 /*flags*/ },
-    { ENCTYPE_CAMELLIA256_CCM_128,
-      "camellia256-ccm-128", { "camellia256-ccm" },
-      "Camellia-256 CCM mode with 128-bit MAC",
-      &krb5int_enc_camellia256_ctr, NULL,
+    { ENCTYPE_CAMELLIA256_CTS_CMAC,
+      "camellia256-cts-cmac", { "camellia256-cts" },
+      "Camellia-256 CTS mode with CMAC",
+      &krb5int_enc_camellia256, NULL,
       16,
-      krb5int_dk_ccm_crypto_length, krb5int_dk_ccm_encrypt, krb5int_dk_ccm_decrypt,
-      krb5int_camellia_ccm_string_to_key,
+      krb5int_camellia_crypto_length,
+      krb5int_dk_cmac_encrypt, krb5int_dk_cmac_decrypt,
+      krb5int_camellia_string_to_key,
       krb5int_dk_cmac_prf,
-      krb5int_dk_ccm_init_state, krb5int_dk_ccm_free_state,
-      CKSUMTYPE_CMAC_128_CAMELLIA256,
+      krb5int_init_state_enc, krb5int_free_state_enc,
+      CKSUMTYPE_CMAC_CAMELLIA256,
       0 /*flags */ },
-#endif /* CAMELLIA_CCM */
+#endif /* CAMELLIA */
 };
 
 const int krb5int_enctypes_length =
index a9ad09ab28e766da6b511cfbfcd45666b1b83a81..78d11641c1db1762f557a1140be8addb0f24dfe3 100644 (file)
@@ -33,7 +33,7 @@
 #include "prf_int.h"
 #include <dk.h>
 
-#ifdef CAMELLIA_CCM
+#ifdef CAMELLIA
 
 krb5_error_code
 krb5int_dk_cmac_prf(const struct krb5_keytypes *ktp, krb5_key key,
@@ -66,4 +66,4 @@ cleanup:
     return ret;
 }
 
-#endif /* CAMELLIA_CCM */
+#endif /* CAMELLIA */
index 114b6c988060041a7a8666550cbec30e680901b0..37db683a32001be5c07380c2ab02bc05eb0b9042 100644 (file)
@@ -97,4 +97,8 @@ krb5int_enc_des3
 krb5int_arcfour_gsscrypt
 krb5int_camellia_cbc_mac
 krb5int_cmac_checksum
-krb5int_enc_camellia128_ctr
+krb5int_enc_aes128
+krb5int_enc_aes256
+krb5int_enc_camellia128
+krb5int_enc_camellia256
+krb5int_derive_key
index 790320885b57014f643c87a2f2340feb3d6ca8a8..3a33d90ca14a90d717b52bd5f1a18e1015ecafa2 100644 (file)
 #include "aead.h"
 #include "nss_gen.h"
 
-#ifdef CAMELLIA_CCM
+#ifdef CAMELLIA
 
-/* XXX These won't work yet (they're just the AES functions, which aren't right
- * for CTR mode).  Will fix later. */
-
-krb5_error_code
+static krb5_error_code
 krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec,
                         krb5_crypto_iov *data, size_t num_data)
 {
@@ -57,7 +54,7 @@ krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec,
                               ivec, data, num_data);
 }
 
-krb5_error_code
+static krb5_error_code
 krb5int_camellia_decrypt(krb5_key key, const krb5_data *ivec,
                         krb5_crypto_iov *data, size_t num_data)
 {
@@ -70,6 +67,20 @@ krb5int_camellia_decrypt(krb5_key key, const krb5_data *ivec,
                               ivec, data, num_data);
 }
 
+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)
+{
+    krb5_error_code ret;
+
+    ret = k5_nss_gen_import(key, CKM_CAMELLIA_CBC, CKA_DECRYPT);
+    if (ret != 0)
+        return ret;
+    return k5_nss_gen_cbcmac_iov(key, CKM_CAMELLIA_CBC, ivec, data, num_data,
+                                 output);
+}
+
 /*
  * perhaps we should store the NSS context in the krb5_data state here?
  */
@@ -120,7 +131,10 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
     return EINVAL;
 }
 
-const struct krb5_enc_provider krb5int_enc_camellia128_ctr = {
+const struct krb5_enc_provider krb5int_enc_camellia128 = {
+};
+
+const struct krb5_enc_provider krb5int_enc_camellia256 = {
 };
 
 #endif
index 6bdf1d0f92ab6b9145d91159e552bdad8711e55f..2927af318009d518215f296d565d756f7e578387 100644 (file)
@@ -539,6 +539,76 @@ done:
     return ret;
 }
 
+krb5_error_code
+k5_nss_gen_cbcmac_iov(krb5_key krb_key, CK_MECHANISM_TYPE mech,
+                      const krb5_data *ivec, const krb5_crypto_iov *data,
+                      size_t num_data, krb5_data *output)
+{
+    krb5_error_code ret = 0;
+    PK11Context *ctx = NULL;
+    SECStatus rv;
+    SECItem *param = NULL;
+    struct iov_block_state input_pos, output_pos;
+    unsigned char storage[MAX_BLOCK_SIZE];
+    unsigned char iv0[MAX_BLOCK_SIZE];
+    unsigned char *ptr = NULL, *lastptr = NULL;
+    SECItem iv;
+    size_t blocksize;
+    int length = 0;
+    int currentblock;
+
+    IOV_BLOCK_STATE_INIT(&input_pos);
+    IOV_BLOCK_STATE_INIT(&output_pos);
+
+    blocksize = PK11_GetBlockSize(mech, NULL);
+    assert(blocksize <= sizeof(storage));
+    if (output->length < blocksize)
+        return KRB5_BAD_MSIZE;
+
+    if (ivec && ivec->data) {
+        iv.data = (unsigned char *)ivec->data;
+        iv.len = ivec->length;
+    } else {
+        memset(iv0, 0, sizeof(iv0));
+        iv.data = iv0;
+        iv.len = blocksize;
+    }
+    param = PK11_ParamFromIV(mech, &iv);
+
+    ctx = k5_nss_create_context(krb_key, mech, CKA_ENCRYPT, param);
+    if (ctx == NULL) {
+        ret = k5_nss_map_last_error();
+        goto done;
+    }
+
+    lastptr = iv.data;
+    for (currentblock = 0;;currentblock++) {
+        if (!krb5int_c_iov_get_block_nocopy(storage, blocksize, data, num_data,
+                                            &input_pos, &ptr))
+            break;
+
+        lastptr = NULL;
+
+        rv = PK11_CipherOp(ctx, ptr, &length, blocksize, ptr, blocksize);
+        if (rv != SECSuccess) {
+            ret = k5_nss_map_last_error();
+            goto done;
+        }
+
+        lastptr = ptr;
+    }
+    memcpy(output->data, lastptr, blocksize);
+
+done:
+    if (ctx) {
+        PK11_Finalize(ctx);
+        PK11_DestroyContext(ctx, PR_TRUE);
+    }
+    if (param)
+        SECITEM_FreeItem(param, PR_TRUE);
+    return ret;
+}
+
 void
 k5_nss_gen_cleanup(krb5_key krb_key)
 {
index 8144b6533e3351bed5b54d1226fd6ee21a65d621..4365255ab4ee7994aa6c7e24518a84564eb665af 100644 (file)
@@ -34,3 +34,7 @@ extern const struct krb5_enc_provider krb5int_enc_aes128;
 extern const struct krb5_enc_provider krb5int_enc_aes256;
 extern const struct krb5_enc_provider krb5int_enc_aes128_ctr;
 extern const struct krb5_enc_provider krb5int_enc_aes256_ctr;
+#ifdef CAMELLIA
+extern const struct krb5_enc_provider krb5int_enc_camellia128;
+extern const struct krb5_enc_provider krb5int_enc_camellia256;
+#endif
index 4eb8f2f744bcbba6a09ce616b1b719591bb2b31a..73f77348adb610178d09e3a2376f098d931dbae8 100644 (file)
@@ -90,6 +90,12 @@ k5_nss_gen_cts_iov(krb5_key key, CK_MECHANISM_TYPE mech,
                    CK_ATTRIBUTE_TYPE operation, const krb5_data *ivec,
                    krb5_crypto_iov *data, size_t num_data);
 
+/* Compute a CBC-MAC. */
+krb5_error_code
+k5_nss_gen_cbcmac_iov(krb5_key key, CK_MECHANISM_TYPE mech,
+                      const krb5_data *ivec, const krb5_crypto_iov *data,
+                      size_t num_data, krb5_data *output);
+
 /* Stream state management calls. */
 krb5_error_code k5_nss_stream_init_state(krb5_data *new_state);
 krb5_error_code k5_nss_stream_free_state(krb5_data *state);
index d9c1cdc3c17ab251804eeb7acdf6b17b22f67fca..e974da406ff8da02d96d14273782e154733800bc 100644 (file)
@@ -21,7 +21,7 @@ STLIBOBJS= \
        des3.o  \
        rc4.o   \
        aes.o   \
-       camellia_ctr.o
+       camellia.o
 
 OBJS= \
        $(OUTPRE)des.$(OBJEXT)  \
@@ -29,7 +29,6 @@ OBJS= \
        $(OUTPRE)aes.$(OBJEXT)  \
        $(OUTPRE)aes_ctr.$(OBJEXT)      \
        $(OUTPRE)camellia.$(OBJEXT)     \
-       $(OUTPRE)camellia_ctr.$(OBJEXT)         \
        $(OUTPRE)rc4.$(OBJEXT)
 
 SRCS= \
@@ -38,7 +37,6 @@ SRCS= \
        $(srcdir)/aes.c         \
        $(srcdir)/aes_ctr.c     \
        $(srcdir)/camellia.c    \
-       $(srcdir)/camellia_ctr.c\
        $(srcdir)/rc4.c
 
 ##DOS##LIBOBJS = $(OBJS)
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
new file mode 100644 (file)
index 0000000..6c0dafa
--- /dev/null
@@ -0,0 +1,413 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/openssl/enc_provider/camellia.c
+ *
+ * Copyright (C) 2003, 2007, 2008, 2009, 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.
+ */
+
+#include "k5-int.h"
+#include "enc_provider.h"
+#include "rand2key.h"
+#include "aead.h"
+#include "hash_provider/hash_provider.h"
+#include <openssl/evp.h>
+#include <openssl/camellia.h>
+#include <openssl/modes.h>
+
+#ifdef CAMELLIA
+
+static krb5_error_code
+cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+        size_t num_data);
+static krb5_error_code
+cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+         size_t num_data);
+static krb5_error_code
+cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+         size_t num_data, size_t dlen);
+static krb5_error_code
+cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+         size_t num_data, size_t dlen);
+
+#define BLOCK_SIZE 16
+#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)
+{
+    if (len==16)
+        return EVP_camellia_128_cbc();
+    if (len==32)
+        return EVP_camellia_256_cbc();
+    else
+        return NULL;
+}
+
+/* Encrypt one block using CBC. */
+static krb5_error_code
+cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+        size_t num_data)
+{
+    int             ret, olen = BLOCK_SIZE;
+    unsigned char   iblock[BLOCK_SIZE], oblock[BLOCK_SIZE];
+    EVP_CIPHER_CTX  ciph_ctx;
+    struct iov_block_state input_pos, output_pos;
+
+    EVP_CIPHER_CTX_init(&ciph_ctx);
+    ret = EVP_EncryptInit_ex(&ciph_ctx, map_mode(key->keyblock.length),
+                             NULL, key->keyblock.contents, (ivec) ? (unsigned char*)ivec->data : NULL);
+    if (ret == 0)
+        return KRB5_CRYPTO_INTERNAL;
+
+    IOV_BLOCK_STATE_INIT(&input_pos);
+    IOV_BLOCK_STATE_INIT(&output_pos);
+    krb5int_c_iov_get_block(iblock, BLOCK_SIZE, data, num_data, &input_pos);
+    EVP_CIPHER_CTX_set_padding(&ciph_ctx,0);
+    ret = EVP_EncryptUpdate(&ciph_ctx, oblock, &olen, iblock, BLOCK_SIZE);
+    if (ret == 1) {
+        krb5int_c_iov_put_block(data, num_data, oblock, BLOCK_SIZE,
+                                &output_pos);
+    }
+    EVP_CIPHER_CTX_cleanup(&ciph_ctx);
+
+    zap(iblock, BLOCK_SIZE);
+    zap(oblock, BLOCK_SIZE);
+    return (ret == 1) ? 0 : KRB5_CRYPTO_INTERNAL;
+}
+
+/* Decrypt one block using CBC. */
+static krb5_error_code
+cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+         size_t num_data)
+{
+    int              ret = 0, olen = BLOCK_SIZE;
+    unsigned char    iblock[BLOCK_SIZE], oblock[BLOCK_SIZE];
+    EVP_CIPHER_CTX   ciph_ctx;
+    struct iov_block_state input_pos, output_pos;
+
+    EVP_CIPHER_CTX_init(&ciph_ctx);
+    ret = EVP_DecryptInit_ex(&ciph_ctx, map_mode(key->keyblock.length),
+                             NULL, key->keyblock.contents, (ivec) ? (unsigned char*)ivec->data : NULL);
+    if (ret == 0)
+        return KRB5_CRYPTO_INTERNAL;
+
+    IOV_BLOCK_STATE_INIT(&input_pos);
+    IOV_BLOCK_STATE_INIT(&output_pos);
+    krb5int_c_iov_get_block(iblock, BLOCK_SIZE, data, num_data, &input_pos);
+    EVP_CIPHER_CTX_set_padding(&ciph_ctx,0);
+    ret = EVP_DecryptUpdate(&ciph_ctx, oblock, &olen, iblock, BLOCK_SIZE);
+    if (ret == 1) {
+        krb5int_c_iov_put_block(data, num_data, oblock, BLOCK_SIZE,
+                                &output_pos);
+    }
+    EVP_CIPHER_CTX_cleanup(&ciph_ctx);
+
+    zap(iblock, BLOCK_SIZE);
+    zap(oblock, BLOCK_SIZE);
+    return (ret == 1) ? 0 : KRB5_CRYPTO_INTERNAL;
+}
+
+static krb5_error_code
+cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+         size_t num_data, size_t dlen)
+{
+    int                    ret = 0;
+    size_t                 size = 0;
+    unsigned char         *oblock = NULL, *dbuf = NULL;
+    unsigned char          iv_cts[IV_CTS_BUF_SIZE];
+    struct iov_block_state input_pos, output_pos;
+    CAMELLIA_KEY           enck;
+
+    memset(iv_cts,0,sizeof(iv_cts));
+    if (ivec && ivec->data){
+        if (ivec->length != sizeof(iv_cts))
+            return KRB5_CRYPTO_INTERNAL;
+        memcpy(iv_cts, ivec->data,ivec->length);
+    }
+
+    oblock = OPENSSL_malloc(dlen);
+    if (!oblock){
+        return ENOMEM;
+    }
+    dbuf = OPENSSL_malloc(dlen);
+    if (!dbuf){
+        OPENSSL_free(oblock);
+        return ENOMEM;
+    }
+
+    IOV_BLOCK_STATE_INIT(&input_pos);
+    IOV_BLOCK_STATE_INIT(&output_pos);
+
+    krb5int_c_iov_get_block(dbuf, dlen, data, num_data, &input_pos);
+
+    Camellia_set_key(key->keyblock.contents, NUM_BITS * key->keyblock.length,
+                    &enck);
+
+    size = CRYPTO_cts128_encrypt((unsigned char *)dbuf, oblock, dlen, &enck,
+                                 iv_cts, (cbc128_f)Camellia_cbc_encrypt);
+    if (size <= 0) {
+        ret = KRB5_CRYPTO_INTERNAL;
+    } else {
+        krb5int_c_iov_put_block(data, num_data,
+                                oblock, dlen, &output_pos);
+    }
+
+    if (!ret && ivec && ivec->data)
+        memcpy(ivec->data, iv_cts, sizeof(iv_cts));
+
+    zap(oblock, dlen);
+    zap(dbuf, dlen);
+    OPENSSL_free(oblock);
+    OPENSSL_free(dbuf);
+
+    return ret;
+}
+
+static krb5_error_code
+cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+         size_t num_data, size_t dlen)
+{
+    int                    ret = 0;
+    size_t                 size = 0;
+    unsigned char         *oblock = NULL;
+    unsigned char         *dbuf = NULL;
+    unsigned char          iv_cts[IV_CTS_BUF_SIZE];
+    struct iov_block_state input_pos, output_pos;
+    CAMELLIA_KEY           deck;
+
+    memset(iv_cts,0,sizeof(iv_cts));
+    if (ivec && ivec->data){
+        if (ivec->length != sizeof(iv_cts))
+            return KRB5_CRYPTO_INTERNAL;
+        memcpy(iv_cts, ivec->data,ivec->length);
+    }
+
+    IOV_BLOCK_STATE_INIT(&input_pos);
+    IOV_BLOCK_STATE_INIT(&output_pos);
+
+    oblock = OPENSSL_malloc(dlen);
+    if (!oblock)
+        return ENOMEM;
+    dbuf = OPENSSL_malloc(dlen);
+    if (!dbuf){
+        OPENSSL_free(oblock);
+        return ENOMEM;
+    }
+
+    Camellia_set_key(key->keyblock.contents, NUM_BITS * key->keyblock.length,
+                    &deck);
+
+    krb5int_c_iov_get_block(dbuf, dlen, data, num_data, &input_pos);
+
+    size = CRYPTO_cts128_decrypt((unsigned char *)dbuf, oblock,
+                                 dlen, &deck,
+                                 iv_cts, (cbc128_f)Camellia_cbc_encrypt);
+    if (size <= 0)
+        ret = KRB5_CRYPTO_INTERNAL;
+    else {
+        krb5int_c_iov_put_block(data, num_data, oblock, dlen, &output_pos);
+    }
+
+    if (!ret && ivec && ivec->data)
+        memcpy(ivec->data, iv_cts, sizeof(iv_cts));
+
+    zap(oblock, dlen);
+    zap(dbuf, dlen);
+    OPENSSL_free(oblock);
+    OPENSSL_free(dbuf);
+
+    return ret;
+}
+
+static krb5_error_code
+krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec,
+                        krb5_crypto_iov *data, size_t num_data)
+{
+    int    ret = 0;
+    int    nblocks = 0;
+    size_t input_length, i;
+
+    for (i = 0, input_length = 0; i < num_data; i++){
+        krb5_crypto_iov *iov = &data[i];
+
+        if (ENCRYPT_IOV(iov))
+            input_length += iov->data.length;
+    }
+
+    nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
+    if (nblocks == 1) {
+        if (input_length != BLOCK_SIZE)
+            return KRB5_BAD_MSIZE;
+        ret = cbc_enc(key, ivec, data, num_data);
+    } else if (nblocks > 1) {
+        ret = cts_encr(key, ivec, data, num_data, input_length);
+    }
+
+    return ret;
+}
+
+static krb5_error_code
+krb5int_camellia_decrypt(krb5_key key, const krb5_data *ivec,
+                        krb5_crypto_iov *data, size_t num_data)
+{
+    int    ret = 0;
+    int    nblocks = 0;
+    size_t input_length, i;
+
+    for (i = 0, input_length = 0; i < num_data; i++) {
+        krb5_crypto_iov *iov = &data[i];
+
+        if (ENCRYPT_IOV(iov))
+            input_length += iov->data.length;
+    }
+
+    nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
+    if (nblocks == 1) {
+        if (input_length != BLOCK_SIZE)
+            return KRB5_BAD_MSIZE;
+        ret = cbc_decr(key, ivec, data, num_data);
+    } else if (nblocks > 1) {
+        ret = cts_decr(key, ivec, data, num_data, input_length);
+    }
+
+    return ret;
+}
+
+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)
+{
+    CAMELLIA_KEY enck;
+    unsigned char blockY[CAMELLIA_BLOCK_SIZE];
+    struct iov_block_state iov_state;
+
+    if (output->length < CAMELLIA_BLOCK_SIZE)
+        return KRB5_BAD_MSIZE;
+
+    Camellia_set_key(key->keyblock.contents,
+                     NUM_BITS * key->keyblock.length, &enck);
+
+    if (iv != NULL)
+        memcpy(blockY, iv->data, CAMELLIA_BLOCK_SIZE);
+    else
+        memset(blockY, 0, CAMELLIA_BLOCK_SIZE);
+
+    IOV_BLOCK_STATE_INIT(&iov_state);
+
+    for (;;) {
+        unsigned char blockB[CAMELLIA_BLOCK_SIZE];
+
+        if (!krb5int_c_iov_get_block(blockB, CAMELLIA_BLOCK_SIZE, data,
+                                    num_data, &iov_state))
+            break;
+
+        xorblock(blockB, blockY);
+
+        Camellia_ecb_encrypt(blockB, blockY, &enck, 1);
+    }
+
+    output->length = CAMELLIA_BLOCK_SIZE;
+    memcpy(output->data, blockY, CAMELLIA_BLOCK_SIZE);
+
+    return 0;
+}
+
+static krb5_error_code
+krb5int_camellia_init_state (const krb5_keyblock *key, krb5_keyusage usage,
+                            krb5_data *state)
+{
+    state->length = 16;
+    state->data = (void *) malloc(16);
+    if (state->data == NULL)
+        return ENOMEM;
+    memset(state->data, 0, state->length);
+    return 0;
+}
+const struct krb5_enc_provider krb5int_enc_camellia128 = {
+    16,
+    16, 16,
+    krb5int_camellia_encrypt,
+    krb5int_camellia_decrypt,
+    krb5int_camellia_cbc_mac,
+    krb5int_camellia_make_key,
+    krb5int_camellia_init_state,
+    krb5int_default_free_state
+};
+
+const struct krb5_enc_provider krb5int_enc_camellia256 = {
+    16,
+    32, 32,
+    krb5int_camellia_encrypt,
+    krb5int_camellia_decrypt,
+    krb5int_camellia_cbc_mac,
+    krb5int_camellia_make_key,
+    krb5int_camellia_init_state,
+    krb5int_default_free_state
+};
+
+#else /* CAMELLIA */
+
+/* These won't be used, but are still in the export table. */
+
+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)
+{
+    return EINVAL;
+}
+
+const struct krb5_enc_provider krb5int_enc_camellia128 = {
+};
+
+const struct krb5_enc_provider krb5int_enc_camellia256 = {
+};
+
+#endif /* CAMELLIA */
diff --git a/src/lib/crypto/openssl/enc_provider/camellia_ctr.c b/src/lib/crypto/openssl/enc_provider/camellia_ctr.c
deleted file mode 100644 (file)
index 0b6eee7..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * lib/crypto/openssl/enc_provider/camellia_ctr.c
- *
- * Copyright (C) 2003, 2007-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.
- */
-
-#include "k5-int.h"
-#include "enc_provider.h"
-#include "rand2key.h"
-#include "aead.h"
-#include "hash_provider/hash_provider.h"
-#include <openssl/evp.h>
-#include <openssl/camellia.h>
-#include <openssl/modes.h>
-
-#ifdef CAMELLIA_CCM
-#define NUM_BITS 8
-
-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);
-    }
-}
-
-/*
- * ivec must be a correctly formatted counter block per SP800-38C A.3
- */
-static krb5_error_code
-krb5int_camellia_encrypt_ctr(krb5_key key, const krb5_data *ivec,
-                             krb5_crypto_iov *data, size_t num_data)
-{
-    CAMELLIA_KEY enck;
-    unsigned char ctr[CAMELLIA_BLOCK_SIZE];
-    krb5_ui_8 blockno;
-    struct iov_block_state input_pos, output_pos;
-
-    Camellia_set_key(key->keyblock.contents,
-                     NUM_BITS * key->keyblock.length, &enck);
-
-    IOV_BLOCK_STATE_INIT(&input_pos);
-    IOV_BLOCK_STATE_INIT(&output_pos);
-
-    /* Don't encrypt the header (B0), and use zero instead of IOV padding */
-    input_pos.ignore_header = output_pos.ignore_header = 1;
-    input_pos.pad_to_boundary = output_pos.pad_to_boundary = 1;
-
-    assert(ivec != NULL);
-
-    if (ivec->length != CAMELLIA_BLOCK_SIZE)
-        return KRB5_BAD_MSIZE;
-
-    memcpy(ctr, ivec->data, CAMELLIA_BLOCK_SIZE);
-
-    for (blockno = 0; ; blockno++) {
-        unsigned char storage[CAMELLIA_BLOCK_SIZE], *block;
-        unsigned char ectr[CAMELLIA_BLOCK_SIZE];
-        unsigned int num = 0;
-
-        if (!krb5int_c_iov_get_block_nocopy(storage, CAMELLIA_BLOCK_SIZE,
-                                            data, num_data, &input_pos,
-                                           &block))
-            break;
-
-        /* We should not need to initialise ectr because we're on a block
-        * boundary. */
-        Camellia_ctr128_encrypt(block, block, CAMELLIA_BLOCK_SIZE, &enck, ctr,
-                               ectr, &num);
-        assert(num == 0);
-        krb5int_c_iov_put_block_nocopy(data, num_data, storage,
-                                      CAMELLIA_BLOCK_SIZE, &output_pos,
-                                      block);
-    }
-
-    if (ivec != NULL)
-        memcpy(ivec->data, ctr, sizeof(ctr));
-
-    return 0;
-}
-
-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)
-{
-    CAMELLIA_KEY enck;
-    unsigned char blockY[CAMELLIA_BLOCK_SIZE];
-    struct iov_block_state iov_state;
-
-    if (output->length < CAMELLIA_BLOCK_SIZE)
-        return KRB5_BAD_MSIZE;
-
-    Camellia_set_key(key->keyblock.contents,
-                     NUM_BITS * key->keyblock.length, &enck);
-
-    if (iv != NULL)
-        memcpy(blockY, iv->data, CAMELLIA_BLOCK_SIZE);
-    else
-        memset(blockY, 0, CAMELLIA_BLOCK_SIZE);
-
-    IOV_BLOCK_STATE_INIT(&iov_state);
-
-    /*
-     * The CCM header may not fit in a block, because it includes a variable
-     * length encoding of the associated data length. This encoding plus the
-     * associated data itself is padded to the block size.
-     */
-    iov_state.include_sign_only = 1;
-    iov_state.pad_to_boundary = 1;
-
-    for (;;) {
-        unsigned char blockB[CAMELLIA_BLOCK_SIZE];
-
-        if (!krb5int_c_iov_get_block(blockB, CAMELLIA_BLOCK_SIZE, data,
-                                    num_data, &iov_state))
-            break;
-
-        xorblock(blockB, blockY);
-
-        Camellia_ecb_encrypt(blockB, blockY, &enck, 1);
-    }
-
-    output->length = CAMELLIA_BLOCK_SIZE;
-    memcpy(output->data, blockY, CAMELLIA_BLOCK_SIZE);
-
-    return 0;
-}
-
-static krb5_error_code
-krb5int_camellia_init_state_ctr (const krb5_keyblock *key, krb5_keyusage usage,
-                                 krb5_data *state)
-{
-    return alloc_data(state, 16);
-}
-
-const struct krb5_enc_provider krb5int_enc_camellia128_ctr = {
-    16,
-    16, 16,
-    krb5int_camellia_encrypt_ctr,
-    krb5int_camellia_encrypt_ctr,
-    krb5int_camellia_cbc_mac,
-    krb5int_camellia_make_key,
-    krb5int_camellia_init_state_ctr,
-    krb5int_default_free_state,
-    NULL
-};
-
-const struct krb5_enc_provider krb5int_enc_camellia256_ctr = {
-    16,
-    32, 32,
-    krb5int_camellia_encrypt_ctr,
-    krb5int_camellia_encrypt_ctr,
-    krb5int_camellia_cbc_mac,
-    krb5int_camellia_make_key,
-    krb5int_camellia_init_state_ctr,
-    krb5int_default_free_state,
-    NULL
-};
-
-#else /* CAMELLIA_CCM */
-
-/* These won't be used, but is still in the export table. */
-
-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)
-{
-    return EINVAL;
-}
-
-const struct krb5_enc_provider krb5int_enc_camellia128_ctr = {
-};
-
-#endif /* CAMELLIA_CCM */
index e8b552e4116b13ef32a1404ee43200ad43e86219..4365255ab4ee7994aa6c7e24518a84564eb665af 100644 (file)
@@ -34,8 +34,7 @@ extern const struct krb5_enc_provider krb5int_enc_aes128;
 extern const struct krb5_enc_provider krb5int_enc_aes256;
 extern const struct krb5_enc_provider krb5int_enc_aes128_ctr;
 extern const struct krb5_enc_provider krb5int_enc_aes256_ctr;
-#ifdef CAMELLIA_CCM
-extern const struct krb5_enc_provider krb5int_enc_camellia128_ctr;
-extern const struct krb5_enc_provider krb5int_enc_camellia256_ctr;
+#ifdef CAMELLIA
+extern const struct krb5_enc_provider krb5int_enc_camellia128;
+extern const struct krb5_enc_provider krb5int_enc_camellia256;
 #endif
-
index 49671d026b588d879dad580f526cf2f1bc8800a7..67810adcbe679d79bf03a49a45480bda9ad68631 100644 (file)
@@ -442,10 +442,10 @@ krb5int_parse_enctype_list(krb5_context context, char *profstr,
             mod_list(ENCTYPE_AES128_CTS_HMAC_SHA1_96, sel, weak, &list);
         } else if (strcasecmp(token, "rc4") == 0) {
             mod_list(ENCTYPE_ARCFOUR_HMAC, sel, weak, &list);
-#ifdef CAMELLIA_CCM
+#ifdef CAMELLIA
         } else if (strcasecmp(token, "camellia") == 0) {
-            mod_list(ENCTYPE_CAMELLIA256_CCM_128, sel, weak, &list);
-            mod_list(ENCTYPE_CAMELLIA128_CCM_128, sel, weak, &list);
+            mod_list(ENCTYPE_CAMELLIA256_CTS_CMAC, sel, weak, &list);
+            mod_list(ENCTYPE_CAMELLIA128_CTS_CMAC, sel, weak, &list);
 #endif
         } else if (krb5_string_to_enctype(token, &etype) == 0) {
             /* Set a specific enctype. */
index 5d4ae0e3d95473968220c25d41b80970547deb9d..b27f7bdfe3d434543b7f173524da2da86ef91816 100644 (file)
@@ -98,12 +98,12 @@ static struct {
         ENCTYPE_DES3_CBC_SHA1, 0 },
       0, 0
     },
-#ifdef CAMELLIA_CCM
+#ifdef CAMELLIA
     /* Family with enctype removed */
-    { "camellia -camellia256-ccm-128",
+    { "camellia -camellia256-cts-cmac",
       { 0 },
-      { ENCTYPE_CAMELLIA128_CCM_128, 0 },
-      { ENCTYPE_CAMELLIA128_CCM_128, 0 }
+      { ENCTYPE_CAMELLIA128_CTS_CMAC, 0 },
+      { ENCTYPE_CAMELLIA128_CTS_CMAC, 0 }
     },
 #endif
     /* Enctype followed by two families */
index 1ae02ea10f5d6dcb35506fa13f9ad7b81267f63e..ac9c82ae2339b2c664e0f71f226986dd4ac8c110 100644 (file)
@@ -263,29 +263,29 @@ set passes {
     }
 }
 
-# Add to above when Camellia-CCM support becomes unconditional.
+# Add to above when Camellia support becomes unconditional.
 #    {
 #      camellia-only
 #      mode=udp
 #      des3_krbtgt=0
-#      {supported_enctypes=camellia256-ccm:normal}
-#      {permitted_enctypes(kdc)=camellia256-ccm}
-#      {permitted_enctypes(slave)=camellia256-ccm}
-#      {permitted_enctypes(client)=camellia256-ccm}
-#      {permitted_enctypes(server)=camellia256-ccm}
-#      {default_tgs_enctypes(kdc)=camellia256-ccm}
-#      {default_tgs_enctypes(slave)=camellia256-ccm}
-#      {default_tgs_enctypes(client)=camellia256-ccm}
-#      {default_tgs_enctypes(server)=camellia256-ccm}
-#      {default_tkt_enctypes(kdc)=camellia256-ccm}
-#      {default_tkt_enctypes(slave)=camellia256-ccm}
-#      {default_tkt_enctypes(client)=camellia256-ccm}
-#      {default_tkt_enctypes(server)=camellia256-ccm}
+#      {supported_enctypes=camellia256-cts:normal}
+#      {permitted_enctypes(kdc)=camellia256-cts}
+#      {permitted_enctypes(slave)=camellia256-cts}
+#      {permitted_enctypes(client)=camellia256-cts}
+#      {permitted_enctypes(server)=camellia256-cts}
+#      {default_tgs_enctypes(kdc)=camellia256-cts}
+#      {default_tgs_enctypes(slave)=camellia256-cts}
+#      {default_tgs_enctypes(client)=camellia256-cts}
+#      {default_tgs_enctypes(server)=camellia256-cts}
+#      {default_tkt_enctypes(kdc)=camellia256-cts}
+#      {default_tkt_enctypes(slave)=camellia256-cts}
+#      {default_tkt_enctypes(client)=camellia256-cts}
+#      {default_tkt_enctypes(server)=camellia256-cts}
 #      {allow_weak_crypto(kdc)=false}
 #      {allow_weak_crypto(slave)=false}
 #      {allow_weak_crypto(client)=false}
 #      {allow_weak_crypto(server)=false}
-#      {master_key_type=camellia256-ccm}
+#      {master_key_type=camellia256-cts}
 #      {dummy=[verbose -log "Camellia-256 enctype"]}
 #    }
 
index 90f79d6511bf00b766d82b2d984fd5fcadbaf5cc..a710eee3aeee812c2233f0e798ca8f30547122a3 100644 (file)
@@ -1014,16 +1014,16 @@ _passes = [
                         'supported_enctypes' : 'aes128-cts:normal',
                         'master_key_type' : 'aes128-cts'}}}}),
 
-    # Exercise the camellia256-ccm enctype.
-# Enable when Camellia-CCM support becomes unconditional.
+    # Exercise the camellia256-cts enctype.
+# Enable when Camellia support becomes unconditional.
 #    ('camellia256', None,
 #      {'all' : {'libdefaults' : {
-#                    'default_tgs_enctypes' : 'camellia256-ccm',
-#                    'default_tkt_enctypes' : 'camellia256-ccm',
-#                    'permitted_enctypes' : 'camellia256-ccm'}}},
+#                    'default_tgs_enctypes' : 'camellia256-cts',
+#                    'default_tkt_enctypes' : 'camellia256-cts',
+#                    'permitted_enctypes' : 'camellia256-cts'}}},
 #      {'master' : {'realms' : {'$realm' : {
-#                        'supported_enctypes' : 'camellia256-ccm:normal',
-#                        'master_key_type' : 'camellia256-ccm'}}}}),
+#                        'supported_enctypes' : 'camellia256-cts:normal',
+#                        'master_key_type' : 'camellia256-cts'}}}}),
 
     # Test a setup with modern principal keys but an old TGT key.
     ('aes256.destgt', 'des-cbc-crc:normal',
index f260eceeab57e546eea4481cfdac63f4abc6f8cb..c4247aa67d263f5c728a444ee166e27e671d1ff5 100644 (file)
@@ -93,12 +93,12 @@ enctype_toString(const void * data, khm_size cbdata,
         resid = IDS_ETYPE_AES256_CTS_HMAC_SHA1_96;
         break;
 
-    case ENCTYPE_CAMELLIA128_CCM_128:
-        resid = IDS_ETYPE_CAMELLIA128_CCM_128;
+    case ENCTYPE_CAMELLIA128_CTS_CMAC:
+        resid = IDS_ETYPE_CAMELLIA128_CTS_CMAC;
         break;
 
-    case ENCTYPE_CAMELLIA256_CCM_128:
-        resid = IDS_ETYPE_CAMELLIA256_CCM_128;
+    case ENCTYPE_CAMELLIA256_CTS_CMAC:
+        resid = IDS_ETYPE_CAMELLIA256_CTS_CMAC;
         break;
 
     case ENCTYPE_ARCFOUR_HMAC:
index a98064e43aedb54f65700ac7abb76fc9aa2a32d2..9d110f5affc15147b3d826a273e36ce23c4f4a6d 100644 (file)
@@ -364,8 +364,8 @@ BEGIN
     IDS_ETYPE_DES3_CBC_SHA1 "DES3-CBC-SHA1"
     IDS_ETYPE_AES128_CTS_HMAC_SHA1_96 "AES128_CTS-HMAC-SHA1_96"
     IDS_ETYPE_AES256_CTS_HMAC_SHA1_96 "AES256_CTS-HMAC-SHA1_96"
-    IDS_ETYPE_CAMELLIA128_CCM_128 "CAMELLIA128_CCM-128"
-    IDS_ETYPE_CAMELLIA256_CCM_128 "CAMELLIA256_CCM-128"
+    IDS_ETYPE_CAMELLIA128_CTS_CMAC "CAMELLIA128_CTS-CMAC"
+    IDS_ETYPE_CAMELLIA256_CTS_CMAC "CAMELLIA256_CTS-CMAC"
     IDS_ETYPE_ARCFOUR_HMAC  "RC4-HMAC-NT"
     IDS_ETYPE_ARCFOUR_HMAC_EXP "RC4-HMAC-NT-EXP"
     IDS_ETYPE_UNKNOWN       "(Unknown)"