svn rev #23462: trunk/src/ include/ lib/crypto/ lib/crypto/builtin/des/ lib/crypto/builtin/enc_provider/ ...

ghudson@MIT.EDU ghudson at MIT.EDU
Thu Dec 10 12:10:10 EST 2009


http://src.mit.edu/fisheye/changelog/krb5/?cs=23462
Commit By: ghudson
Log Message:
Restructure the crypto checksum implementation to minimize
dependencies on the internals of modules.

* Keyhash providers are gone.
* The cksumtypes table contains checksum and verify functions,
  similar to the etypes encrypt and decrypt functions.  New checksum
  functions parallel the old keyhash providers, and there are also
  functions for unkeyed and derived-key HMAC checksums.
* The flags field is now used to indicate whether a checksum is
  unkeyed, but not whether it is a derived-key HMAC checksum.
* The descbc checksum is handled through a new enc_provider function
  which calculates a CBC MAC.

The OpenSSL module does not implement the CBC MAC function (it didn't
implement descbc before).  builtin/des could probably get rid of
f_cksum.c (the old DES CBC routine) with some alterations to
string2key.c.



Changed Files:
U   trunk/src/configure.in
U   trunk/src/include/k5-int.h
U   trunk/src/lib/crypto/Makefile.in
U   trunk/src/lib/crypto/builtin/des/des_int.h
U   trunk/src/lib/crypto/builtin/des/f_aead.c
U   trunk/src/lib/crypto/builtin/enc_provider/aes.c
U   trunk/src/lib/crypto/builtin/enc_provider/des.c
U   trunk/src/lib/crypto/builtin/enc_provider/des3.c
U   trunk/src/lib/crypto/builtin/enc_provider/rc4.c
U   trunk/src/lib/crypto/crypto_tests/t_cksum.c
U   trunk/src/lib/crypto/krb/Makefile.in
U   trunk/src/lib/crypto/krb/aead.c
U   trunk/src/lib/crypto/krb/aead.h
A   trunk/src/lib/crypto/krb/checksum/
A   trunk/src/lib/crypto/krb/checksum/Makefile.in
A   trunk/src/lib/crypto/krb/checksum/cbc.c
A   trunk/src/lib/crypto/krb/checksum/confounder.c
A   trunk/src/lib/crypto/krb/checksum/deps
A   trunk/src/lib/crypto/krb/checksum/hmac_md5.c
A   trunk/src/lib/crypto/krb/checksum/unkeyed.c
U   trunk/src/lib/crypto/krb/checksum_length.c
U   trunk/src/lib/crypto/krb/cksumtype_to_string.c
U   trunk/src/lib/crypto/krb/cksumtypes.c
U   trunk/src/lib/crypto/krb/cksumtypes.h
U   trunk/src/lib/crypto/krb/coll_proof_cksum.c
U   trunk/src/lib/crypto/krb/deps
U   trunk/src/lib/crypto/krb/dk/checksum.c
U   trunk/src/lib/crypto/krb/dk/deps
U   trunk/src/lib/crypto/krb/dk/dk.h
U   trunk/src/lib/crypto/krb/keyed_checksum_types.c
U   trunk/src/lib/crypto/krb/keyed_cksum.c
D   trunk/src/lib/crypto/krb/keyhash_provider/
U   trunk/src/lib/crypto/krb/make_checksum.c
U   trunk/src/lib/crypto/krb/make_checksum_iov.c
U   trunk/src/lib/crypto/krb/valid_cksumtype.c
U   trunk/src/lib/crypto/krb/verify_checksum.c
U   trunk/src/lib/crypto/krb/verify_checksum_iov.c
U   trunk/src/lib/crypto/libk5crypto.exports
U   trunk/src/lib/crypto/openssl/enc_provider/aes.c
U   trunk/src/lib/crypto/openssl/enc_provider/des.c
U   trunk/src/lib/crypto/openssl/enc_provider/des3.c
U   trunk/src/lib/crypto/openssl/enc_provider/rc4.c
Modified: trunk/src/configure.in
===================================================================
--- trunk/src/configure.in	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/configure.in	2009-12-10 17:10:10 UTC (rev 23462)
@@ -1060,7 +1060,7 @@
 
 	lib/crypto lib/crypto/krb lib/crypto/krb/crc32 lib/crypto/$CRYPTO_IMPL/des
 	lib/crypto/krb/dk lib/crypto/$CRYPTO_IMPL/enc_provider
-	lib/crypto/$CRYPTO_IMPL/hash_provider lib/crypto/krb/keyhash_provider
+	lib/crypto/$CRYPTO_IMPL/hash_provider lib/crypto/krb/checksum
 	lib/crypto/krb/prf lib/crypto/krb/rand2key
 	lib/crypto/$CRYPTO_IMPL lib/crypto/$CRYPTO_IMPL/md4 lib/crypto/$CRYPTO_IMPL/md5
 	lib/crypto/krb/old lib/crypto/krb/raw lib/crypto/$CRYPTO_IMPL/sha1

Modified: trunk/src/include/k5-int.h
===================================================================
--- trunk/src/include/k5-int.h	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/include/k5-int.h	2009-12-10 17:10:10 UTC (rev 23462)
@@ -653,6 +653,11 @@
     krb5_error_code (*decrypt)(krb5_key key, const krb5_data *cipher_state,
                                krb5_crypto_iov *data, size_t num_data);
 
+    /* May be NULL if the cipher is not used for a cbc-mac checksum. */
+    krb5_error_code (*cbc_mac)(krb5_key key, const krb5_crypto_iov *data,
+                               size_t num_data, const krb5_data *ivec,
+                               krb5_data *output);
+
     krb5_error_code (*make_key)(const krb5_data *randombits,
                                 krb5_keyblock *key);
 
@@ -671,26 +676,6 @@
                             krb5_data *output);
 };
 
-struct krb5_keyhash_provider {
-    size_t hashsize;
-
-    krb5_error_code (*hash)(krb5_key key, krb5_keyusage keyusage,
-                            const krb5_data *input, krb5_data *output);
-
-    krb5_error_code (*verify)(krb5_key key, krb5_keyusage keyusage,
-                              const krb5_data *input, const krb5_data *hash,
-                              krb5_boolean *valid);
-
-    krb5_error_code (*hash_iov)(krb5_key key, krb5_keyusage keyusage,
-                                const krb5_crypto_iov *data, size_t num_data,
-                                krb5_data *output);
-
-    krb5_error_code (*verify_iov)(krb5_key key, krb5_keyusage keyusage,
-                                  const krb5_crypto_iov *data,
-                                  size_t num_data, const krb5_data *hash,
-                                  krb5_boolean *valid);
-};
-
 /*
  * in here to deal with stuff from lib/crypto
  */

Modified: trunk/src/lib/crypto/Makefile.in
===================================================================
--- trunk/src/lib/crypto/Makefile.in	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/Makefile.in	2009-12-10 17:10:10 UTC (rev 23462)
@@ -19,7 +19,7 @@
 RELDIR=crypto
 
 STOBJLISTS=krb/crc32/OBJS.ST krb/dk/OBJS.ST @CRYPTO_IMPL@/enc_provider/OBJS.ST	\
-	@CRYPTO_IMPL@/hash_provider/OBJS.ST krb/keyhash_provider/OBJS.ST  		\
+	@CRYPTO_IMPL@/hash_provider/OBJS.ST krb/checksum/OBJS.ST  		\
 	krb/prf/OBJS.ST krb/rand2key/OBJS.ST 		 			\
 	krb/old/OBJS.ST krb/raw/OBJS.ST krb/yarrow/OBJS.ST 			\
 	@CRYPTO_IMPL@/md4/OBJS.ST @CRYPTO_IMPL@/md5/OBJS.ST @CRYPTO_IMPL@/sha1/OBJS.ST 		\
@@ -27,7 +27,7 @@
 	krb/OBJS.ST  @CRYPTO_IMPL@/OBJS.ST
 
 SUBDIROBJLISTS=krb/crc32/OBJS.ST krb/dk/OBJS.ST @CRYPTO_IMPL@/enc_provider/OBJS.ST 	\
-	@CRYPTO_IMPL@/hash_provider/OBJS.ST krb/keyhash_provider/OBJS.ST 		\
+	@CRYPTO_IMPL@/hash_provider/OBJS.ST krb/checksum/OBJS.ST 		\
 	krb/prf/OBJS.ST krb/rand2key/OBJS.ST 		 			\
 	krb/old/OBJS.ST krb/raw/OBJS.ST  krb/yarrow/OBJS.ST 			\
 	@CRYPTO_IMPL@/md4/OBJS.ST @CRYPTO_IMPL@/md5/OBJS.ST	@CRYPTO_IMPL@/sha1/OBJS.ST 		\

Modified: trunk/src/lib/crypto/builtin/des/des_int.h
===================================================================
--- trunk/src/lib/crypto/builtin/des/des_int.h	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/builtin/des/des_int.h	2009-12-10 17:10:10 UTC (rev 23462)
@@ -263,6 +263,11 @@
                         const mit_des_key_schedule schedule,
                         mit_des_cblock ivec);
 
+void
+krb5int_des_cbc_mac(const krb5_crypto_iov *data, unsigned long num_data,
+                    const mit_des_key_schedule schedule, mit_des_cblock ivec,
+                    mit_des_cblock out);
+
 /* d3_procky.c */
 krb5_error_code mit_des3_process_key(krb5_encrypt_block *eblock,
                                      const krb5_keyblock *keyblock);

Modified: trunk/src/lib/crypto/builtin/des/f_aead.c
===================================================================
--- trunk/src/lib/crypto/builtin/des/f_aead.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/builtin/des/f_aead.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -152,6 +152,54 @@
     }
 }
 
+void
+krb5int_des_cbc_mac(const krb5_crypto_iov *data, unsigned long num_data,
+                    const mit_des_key_schedule schedule, mit_des_cblock ivec,
+                    mit_des_cblock out)
+{
+    unsigned DES_INT32 left, right;
+    const unsigned DES_INT32 *kp;
+    const unsigned char *ip;
+    struct iov_block_state input_pos;
+    unsigned char storage[MIT_DES_BLOCK_LENGTH], *block = NULL, *ptr;
+
+    IOV_BLOCK_STATE_INIT(&input_pos);
+    input_pos.include_sign_only = 1;
+
+    /* Get key pointer here.  This won't need to be reinitialized. */
+    kp = (const unsigned DES_INT32 *)schedule;
+
+    /* Initialize left and right with the contents of the initial vector. */
+    ip = (ivec != NULL) ? ivec : mit_des_zeroblock;
+    GET_HALF_BLOCK(left, ip);
+    GET_HALF_BLOCK(right, ip);
+
+    /* Work the length down 8 bytes at a time. */
+    for (;;) {
+        unsigned DES_INT32 temp;
+
+        ptr = iov_next_block(storage, MIT_DES_BLOCK_LENGTH, data, num_data,
+                             &input_pos);
+        if (ptr == NULL)
+            break;
+        block = ptr;
+
+        /* Decompose this block and xor it with the previous ciphertext. */
+        GET_HALF_BLOCK(temp, ptr);
+        left  ^= temp;
+        GET_HALF_BLOCK(temp, ptr);
+        right ^= temp;
+
+        /* Encrypt what we have. */
+        DES_DO_ENCRYPT(left, right, kp);
+    }
+
+    /* Output the final ciphertext block. */
+    ptr = out;
+    PUT_HALF_BLOCK(left, ptr);
+    PUT_HALF_BLOCK(right, ptr);
+}
+
 #if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO)
 void krb5int_des_do_encrypt_2 (unsigned DES_INT32 *left,
                                unsigned DES_INT32 *right,

Modified: trunk/src/lib/crypto/builtin/enc_provider/aes.c
===================================================================
--- trunk/src/lib/crypto/builtin/enc_provider/aes.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/builtin/enc_provider/aes.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -267,6 +267,7 @@
     16, 16,
     krb5int_aes_encrypt,
     krb5int_aes_decrypt,
+    NULL,
     krb5int_aes_make_key,
     aes_init_state,
     krb5int_default_free_state,
@@ -277,6 +278,7 @@
     32, 32,
     krb5int_aes_encrypt,
     krb5int_aes_decrypt,
+    NULL,
     krb5int_aes_make_key,
     aes_init_state,
     krb5int_default_free_state

Modified: trunk/src/lib/crypto/builtin/enc_provider/des.c
===================================================================
--- trunk/src/lib/crypto/builtin/enc_provider/des.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/builtin/enc_provider/des.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -31,32 +31,24 @@
 #include <aead.h>
 #include <rand2key.h>
 
-
 static krb5_error_code
-k5_des_docrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
-               size_t num_data, int enc)
+validate_and_schedule(krb5_key key, const krb5_data *ivec,
+                      const krb5_crypto_iov *data, size_t num_data,
+                      mit_des_key_schedule schedule)
 {
-    mit_des_key_schedule schedule;
-    size_t input_length = 0;
-    unsigned int i;
-    unsigned char *ivecbytes;
+    size_t i, input_length;
 
-    /* key->keyblock.enctype was checked by the caller */
-
-    if (key->keyblock.length != 8)
-        return(KRB5_BAD_KEYSIZE);
-
-    for (i = 0; i < num_data; i++) {
+    for (i = 0, input_length = 0; i < num_data; i++) {
         const krb5_crypto_iov *iov = &data[i];
 
         if (ENCRYPT_IOV(iov))
             input_length += iov->data.length;
     }
 
-    if ((input_length % 8) != 0)
-        return(KRB5_BAD_MSIZE);
-    if (ivec && (ivec->length != 8))
-        return(KRB5_BAD_MSIZE);
+    if (key->keyblock.length != 8)
+        return KRB5_BAD_KEYSIZE;
+    if (input_length % 8 != 0 || (ivec != NULL && ivec->length != 8))
+        return KRB5_BAD_MSIZE;
 
     switch (mit_des_key_sched(key->keyblock.contents, schedule)) {
     case -1:
@@ -64,38 +56,75 @@
     case -2:
         return(KRB5DES_WEAK_KEY);
     }
+    return 0;
+}
 
-    /* this has a return value, but the code always returns zero */
-    ivecbytes = ivec ? (unsigned char *) ivec->data : NULL;
-    if (enc)
-        krb5int_des_cbc_encrypt(data, num_data, schedule, ivecbytes);
-    else
-        krb5int_des_cbc_decrypt(data, num_data, schedule, ivecbytes);
+static krb5_error_code
+des_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+            size_t num_data)
+{
+    mit_des_key_schedule schedule;
+    krb5_error_code err;
 
-    memset(schedule, 0, sizeof(schedule));
+    err = validate_and_schedule(key, ivec, data, num_data, schedule);
+    if (err)
+        return err;
 
-    return(0);
+    krb5int_des_cbc_encrypt(data, num_data, schedule,
+                            ivec != NULL ? (unsigned char *) ivec->data :
+                            NULL);
+
+    zap(schedule, sizeof(schedule));
+    return 0;
 }
 
 static krb5_error_code
-k5_des_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
-               size_t num_data)
+des_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+            size_t num_data)
 {
-    return k5_des_docrypt(key, ivec, data, num_data, 1);
+    mit_des_key_schedule schedule;
+    krb5_error_code err;
+
+    err = validate_and_schedule(key, ivec, data, num_data, schedule);
+    if (err)
+        return err;
+
+    krb5int_des_cbc_decrypt(data, num_data, schedule,
+                            ivec != NULL ? (unsigned char *) ivec->data :
+                            NULL);
+
+    zap(schedule, sizeof(schedule));
+    return 0;
 }
 
 static krb5_error_code
-k5_des_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
-               size_t num_data)
+des_cbc_mac(krb5_key key, const krb5_crypto_iov *data, size_t num_data,
+            const krb5_data *ivec, krb5_data *output)
 {
-    return k5_des_docrypt(key, ivec, data, num_data, 0);
+    mit_des_key_schedule schedule;
+    krb5_error_code err;
+
+    err = validate_and_schedule(key, ivec, data, num_data, schedule);
+    if (err)
+        return err;
+
+    if (output->length != 8)
+        return KRB5_CRYPTO_INTERNAL;
+
+    krb5int_des_cbc_mac(data, num_data, schedule,
+                        ivec != NULL ? (unsigned char *) ivec->data : NULL,
+                        (unsigned char *) output->data);
+
+    zap(schedule, sizeof(schedule));
+    return 0;
 }
 
 const struct krb5_enc_provider krb5int_enc_des = {
     8,
     7, 8,
-    k5_des_encrypt,
-    k5_des_decrypt,
+    des_encrypt,
+    des_decrypt,
+    des_cbc_mac,
     krb5int_des_make_key,
     krb5int_des_init_state,
     krb5int_default_free_state

Modified: trunk/src/lib/crypto/builtin/enc_provider/des3.c
===================================================================
--- trunk/src/lib/crypto/builtin/enc_provider/des3.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/builtin/enc_provider/des3.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -110,6 +110,7 @@
     21, 24,
     k5_des3_encrypt,
     k5_des3_decrypt,
+    NULL,
     krb5int_des3_make_key,
     krb5int_des_init_state,
     krb5int_default_free_state

Modified: trunk/src/lib/crypto/builtin/enc_provider/rc4.c
===================================================================
--- trunk/src/lib/crypto/builtin/enc_provider/rc4.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/builtin/enc_provider/rc4.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -206,6 +206,7 @@
     16, 16,
     k5_arcfour_docrypt,
     k5_arcfour_docrypt,
+    NULL,
     krb5int_arcfour_make_key,
     k5_arcfour_init_state, /*xxx not implemented yet*/
     krb5int_default_free_state

Modified: trunk/src/lib/crypto/crypto_tests/t_cksum.c
===================================================================
--- trunk/src/lib/crypto/crypto_tests/t_cksum.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/crypto_tests/t_cksum.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -35,33 +35,27 @@
 #define MD5_K5BETA_COMPAT
 #define MD4_K5BETA_COMPAT
 
-#if     MD == 4
-extern struct krb5_keyhash_provider krb5int_keyhash_md4des;
-#define khp krb5int_keyhash_md4des
+#if MD == 4
+#define CKTYPE CKSUMTYPE_RSA_MD4_DES
 #endif
 
-#if     MD == 5
-extern struct krb5_keyhash_provider krb5int_keyhash_md5des;
-#define khp krb5int_keyhash_md5des
+#if MD == 5
+#define CKTYPE CKSUMTYPE_RSA_MD5_DES
 #endif
 
 static void
-print_checksum(text, number, message, checksum)
-    char       *text;
-    int        number;
-    char       *message;
-    krb5_data  *checksum;
+print_checksum(char *text, int number, char *message, krb5_checksum *checksum)
 {
-    int i;
+    unsigned int i;
 
     printf("%s MD%d checksum(\"%s\") = ", text, number, message);
     for (i=0; i<checksum->length; i++)
-        printf("%02x", (unsigned char) checksum->data[i]);
+        printf("%02x", (unsigned char) checksum->contents[i]);
     printf("\n");
 }
 
 static void
-parse_hexstring(const char *s, krb5_data *dat)
+parse_hexstring(const char *s, krb5_checksum *cksum)
 {
     size_t i, len;
     unsigned int byte;
@@ -69,16 +63,18 @@
 
     len = strlen(s);
     cp = malloc(len / 2);
-    dat->data = (char *)cp;
+    cksum->contents = cp;
     if (cp == NULL) {
-        dat->length = 0;
+        cksum->length = 0;
         return;
     }
-    dat->length = len / 2;
+    cksum->length = len / 2;
     for (i = 0; i + 1 < len; i += 2) {
         sscanf(&s[i], "%2x", &byte);
         *cp++ = byte;
     }
+    cksum->checksum_type = CKTYPE;
+    cksum->magic = KV5M_CHECKSUM;
 }
 
 /*
@@ -95,11 +91,11 @@
 {
     int                   msgindex;
     krb5_boolean          valid;
-    size_t                length;
     krb5_keyblock         keyblock;
     krb5_key              key;
     krb5_error_code       kret=0;
-    krb5_data             plaintext, newstyle_checksum, knowncksum_dat;
+    krb5_data             plaintext;
+    krb5_checksum         checksum, knowncksum;
 
     /* this is a terrible seed, but that's ok for the test. */
 
@@ -114,27 +110,23 @@
 
     krb5_k_create_key(NULL, &keyblock, &key);
 
-    length = khp.hashsize;
-
-    newstyle_checksum.length = length;
-
-    if (!(newstyle_checksum.data = (char *)
-          malloc((unsigned) newstyle_checksum.length))) {
-        printf("cannot get memory for new style checksum\n");
-        return(ENOMEM);
-    }
     for (msgindex = 1; msgindex + 1 < argc; msgindex += 2) {
         plaintext.length = strlen(argv[msgindex]);
         plaintext.data = argv[msgindex];
 
-        if ((kret = (*(khp.hash))(key, 0, &plaintext, &newstyle_checksum))) {
+        /* Create a checksum. */
+        kret = krb5_k_make_checksum(NULL, CKTYPE, key, 0, &plaintext,
+                                    &checksum);
+        if (kret != 0) {
             printf("krb5_calculate_checksum choked with %d\n", kret);
             break;
         }
-        print_checksum("correct", MD, argv[msgindex], &newstyle_checksum);
+        print_checksum("correct", MD, argv[msgindex], &checksum);
 
-        if ((kret = (*(khp.verify))(key, 0, &plaintext, &newstyle_checksum,
-                                    &valid))) {
+        /* Verify it. */
+        kret = krb5_k_verify_checksum(NULL, key, 0, &plaintext, &checksum,
+                                      &valid);
+        if (kret != 0) {
             printf("verify on new checksum choked with %d\n", kret);
             break;
         }
@@ -145,9 +137,11 @@
         }
         printf("Verify succeeded for \"%s\"\n", argv[msgindex]);
 
-        newstyle_checksum.data[0]++;
-        if ((kret = (*(khp.verify))(key, 0, &plaintext, &newstyle_checksum,
-                                    &valid))) {
+        /* Corrupt the checksum and see if it still verifies. */
+        checksum.contents[0]++;
+        kret = krb5_k_verify_checksum(NULL, key, 0, &plaintext, &checksum,
+                                      &valid);
+        if (kret != 0) {
             printf("verify on new checksum choked with %d\n", kret);
             break;
         }
@@ -157,14 +151,18 @@
             break;
         }
         printf("Verify of bad checksum OK for \"%s\"\n", argv[msgindex]);
-        parse_hexstring(argv[msgindex+1], &knowncksum_dat);
-        if (knowncksum_dat.data == NULL) {
+        free(checksum.contents);
+
+        /* Verify a known-good checksum for this plaintext. */
+        parse_hexstring(argv[msgindex+1], &knowncksum);
+        if (knowncksum.contents == NULL) {
             printf("parse_hexstring failed\n");
             kret = 1;
             break;
         }
-        if ((kret = (*(khp.verify))(key, 0, &plaintext, &knowncksum_dat,
-                                    &valid))) {
+        kret = krb5_k_verify_checksum(NULL, key, 0, &plaintext, &knowncksum,
+                                      &valid);
+        if (kret != 0) {
             printf("verify on known checksum choked with %d\n", kret);
             break;
         }
@@ -174,9 +172,8 @@
             break;
         }
         printf("Verify on known checksum succeeded\n");
-        kret = 0;
+        free(knowncksum.contents);
     }
-    free(newstyle_checksum.data);
     if (!kret)
         printf("%d tests passed successfully for MD%d checksum\n", (argc-1)/2, MD);
 

Modified: trunk/src/lib/crypto/krb/Makefile.in
===================================================================
--- trunk/src/lib/crypto/krb/Makefile.in	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/Makefile.in	2009-12-10 17:10:10 UTC (rev 23462)
@@ -1,9 +1,9 @@
 mydir=lib/crypto/krb
 BUILDTOP=$(REL)..$(S)..$(S)..
-SUBDIRS= arcfour crc32 dk keyhash_provider \
+SUBDIRS= arcfour checksum crc32 dk \
 	prf rand2key old raw yarrow 
 LOCALINCLUDES = -I$(srcdir) -I$(srcdir)/../@CRYPTO_IMPL@/enc_provider -I$(srcdir)/dk	\
-		-I$(srcdir)/../@CRYPTO_IMPL@/hash_provider -I$(srcdir)/keyhash_provider	\
+		-I$(srcdir)/../@CRYPTO_IMPL@/hash_provider				\
 		-I$(srcdir)/prf -I$(srcdir)/rand2key		 			\
 		-I$(srcdir)/old -I$(srcdir)/raw -I$(srcdir)/yarrow 			\
 		-I$(srcdir)/../@CRYPTO_IMPL@/ -I$(srcdir)/../@CRYPTO_IMPL@/des		\
@@ -16,8 +16,8 @@
 ##DOSBUILDTOP = ..\..\..
 ##DOSLIBNAME=$(OUTPRE)crypto.lib
 ##DOSOBJFILE=$(OUTPRE)crypto.lst
-##DOSOBJFILELIST=@$(OUTPRE)crypto.lst @$(OUTPRE)des.lst @$(OUTPRE)md4.lst @$(OUTPRE)md5.lst @$(OUTPRE)sha1.lst @$(OUTPRE)arcfour.lst @$(OUTPRE)crc32.lst @$(OUTPRE)dk.lst @$(OUTPRE)old.lst @$(OUTPRE)raw.lst @$(OUTPRE)enc_prov.lst @$(OUTPRE)hash_pro.lst @$(OUTPRE)kh_pro.lst @$(OUTPRE)yarrow.lst @$(OUTPRE)aes.lst
-##DOSOBJFILEDEP =$(OUTPRE)crypto.lst $(OUTPRE)des.lst $(OUTPRE)md4.lst $(OUTPRE)md5.lst $(OUTPRE)sha1.lst $(OUTPRE)arcfour.lst $(OUTPRE)crc32.lst $(OUTPRE)dk.lst $(OUTPRE)old.lst $(OUTPRE)raw.lst $(OUTPRE)enc_prov.lst $(OUTPRE)hash_pro.lst $(OUTPRE)kh_pro.lst $(OUTPRE)aes.lst
+##DOSOBJFILELIST=@$(OUTPRE)crypto.lst @$(OUTPRE)des.lst @$(OUTPRE)md4.lst @$(OUTPRE)md5.lst @$(OUTPRE)sha1.lst @$(OUTPRE)arcfour.lst @$(OUTPRE)crc32.lst @$(OUTPRE)dk.lst @$(OUTPRE)old.lst @$(OUTPRE)raw.lst @$(OUTPRE)enc_prov.lst @$(OUTPRE)hash_pro.lst @$(OUTPRE)cksum.lst @$(OUTPRE)yarrow.lst @$(OUTPRE)aes.lst
+##DOSOBJFILEDEP =$(OUTPRE)crypto.lst $(OUTPRE)des.lst $(OUTPRE)md4.lst $(OUTPRE)md5.lst $(OUTPRE)sha1.lst $(OUTPRE)arcfour.lst $(OUTPRE)crc32.lst $(OUTPRE)dk.lst $(OUTPRE)old.lst $(OUTPRE)raw.lst $(OUTPRE)enc_prov.lst $(OUTPRE)hash_pro.lst $(OUTPRE)cksum.lst $(OUTPRE)aes.lst
 
 PROG_LIBPATH=-L$(TOPLIBD)
 PROG_RPATH=$(KRB5_LIBDIR)
@@ -151,14 +151,12 @@
 	$(srcdir)/verify_checksum.c	\
 	$(srcdir)/verify_checksum_iov.c
 
-STOBJLISTS=arcfour/OBJS.ST crc32/OBJS.ST dk/OBJS.ST		\
-	keyhash_provider/OBJS.ST 			 	\
-	prf/OBJS.ST rand2key/OBJS.ST 			 	\
+STOBJLISTS=arcfour/OBJS.ST checksum/OBJS.ST crc32/OBJS.ST	\
+	dk/OBJS.ST prf/OBJS.ST rand2key/OBJS.ST			\
 	old/OBJS.ST raw/OBJS.ST  yarrow/OBJS.ST  OBJS.ST
 
-SUBDIROBJLISTS=arcfour/OBJS.ST crc32/OBJS.ST dk/OBJS.ST		\
-	keyhash_provider/OBJS.ST 			 	\
-	prf/OBJS.ST rand2key/OBJS.ST 			 	\
+SUBDIROBJLISTS=arcfour/OBJS.ST checksum/OBJS.ST crc32/OBJS.ST	\
+	dk/OBJS.ST prf/OBJS.ST rand2key/OBJS.ST			\
 	old/OBJS.ST raw/OBJS.ST  yarrow/OBJS.ST 
 
 ##DOS##LIBOBJS = $(OBJS)
@@ -177,12 +175,12 @@
 	cd ..\crc32
 	@echo Making in crypto\crc32
 	$(MAKE) -$(MFLAGS)
+	cd ..\checksum
+	@echo Making in crypto\checksum
+	$(MAKE) -$(MFLAGS)
 	cd ..\dk
 	@echo Making in crypto\dk
 	$(MAKE) -$(MFLAGS)
-	cd ..\keyhash_provider
-	@echo Making in crypto\keyhash_provider
-	$(MAKE) -$(MFLAGS)
 	cd ..\prf
 	@echo Making in crypto\prf
 	$(MAKE) -$(MFLAGS)
@@ -207,12 +205,12 @@
 	cd ..\crc32
 	@echo Making in clean crypto\crc32
 	$(MAKE) -$(MFLAGS) clean
+	cd ..\checksum
+	@echo Making clean in crypto\checksum
+	$(MAKE) -$(MFLAGS) clean
 	cd ..\dk
 	@echo Making clean in crypto\dk
 	$(MAKE) -$(MFLAGS) clean
-	cd ..\keyhash_provider
-	@echo Making clean in crypto\keyhash_provider
-	$(MAKE) -$(MFLAGS) clean
 	cd ..\prf
 	@echo Making clean in crypto\prf
 	$(MAKE) -$(MFLAGS) clean
@@ -237,12 +235,12 @@
 	cd ..\crc32
 	@echo Making in check crypto\crc32
 	$(MAKE) -$(MFLAGS) check
+	cd ..\checksum
+	@echo Making check in crypto\checksum
+	$(MAKE) -$(MFLAGS) check
 	cd ..\dk
 	@echo Making check in crypto\dk
 	$(MAKE) -$(MFLAGS) check
-	cd ..\keyhash_provider
-	@echo Making check in crypto\keyhash_provider
-	$(MAKE) -$(MFLAGS) check
 	cd ..\prf
 	@echo Making check in crypto\prf
 	$(MAKE) -$(MFLAGS) check

Modified: trunk/src/lib/crypto/krb/aead.c
===================================================================
--- trunk/src/lib/crypto/krb/aead.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/aead.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -53,71 +53,6 @@
     return iov;
 }
 
-krb5_error_code
-krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum_type,
-                            krb5_key key,
-                            krb5_keyusage usage,
-                            const krb5_crypto_iov *data,
-                            size_t num_data,
-                            krb5_data *cksum_data)
-{
-    const struct krb5_keytypes *e1, *e2;
-    krb5_error_code ret;
-
-    if (cksum_type->keyhash != NULL) {
-        /* Check if key is compatible. */
-
-        if (cksum_type->keyed_etype) {
-            e1 = find_enctype(cksum_type->keyed_etype);
-            e2 = find_enctype(key->keyblock.enctype);
-            if (e1 == NULL || e2 == NULL || e1->enc != e2->enc) {
-                ret = KRB5_BAD_ENCTYPE;
-                goto cleanup;
-            }
-        }
-
-        if (cksum_type->keyhash->hash_iov == NULL)
-            return KRB5_BAD_ENCTYPE;
-
-        ret = cksum_type->keyhash->hash_iov(key, usage, data, num_data,
-                                            cksum_data);
-    } else if (cksum_type->flags & KRB5_CKSUMFLAG_DERIVE) {
-        ret = krb5int_dk_make_checksum(cksum_type->hash, key, usage, data,
-                                       num_data, cksum_data);
-    } else {
-        ret = cksum_type->hash->hash(data, num_data, cksum_data);
-    }
-
-    if (ret == 0) {
-        if (cksum_type->trunc_size) {
-            cksum_data->length = cksum_type->trunc_size;
-        }
-    }
-
-cleanup:
-    if (ret != 0) {
-        memset(cksum_data->data, 0, cksum_data->length);
-    }
-
-    return ret;
-}
-
-const struct krb5_cksumtypes *
-krb5int_c_find_checksum_type(krb5_cksumtype cksumtype)
-{
-    size_t i;
-
-    for (i = 0; i < krb5int_cksumtypes_length; i++) {
-        if (krb5int_cksumtypes_list[i].ctype == cksumtype)
-            break;
-    }
-
-    if (i == krb5int_cksumtypes_length)
-        return NULL;
-
-    return &krb5int_cksumtypes_list[i];
-}
-
 #ifdef DEBUG_IOV
 static void
 dump_block(const char *tag,

Modified: trunk/src/lib/crypto/krb/aead.h
===================================================================
--- trunk/src/lib/crypto/krb/aead.h	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/aead.h	2009-12-10 17:10:10 UTC (rev 23462)
@@ -36,17 +36,6 @@
                      size_t num_data,
                      krb5_cryptotype type);
 
-krb5_error_code
-krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum,
-                            krb5_key key,
-                            krb5_keyusage usage,
-                            const krb5_crypto_iov *data,
-                            size_t num_data,
-                            krb5_data *cksum_data);
-
-const struct krb5_cksumtypes *
-krb5int_c_find_checksum_type(krb5_cksumtype cksumtype);
-
 #define ENCRYPT_CONF_IOV(_iov)  ((_iov)->flags == KRB5_CRYPTO_TYPE_HEADER)
 
 #define ENCRYPT_DATA_IOV(_iov)  ((_iov)->flags == KRB5_CRYPTO_TYPE_DATA || \

Added: trunk/src/lib/crypto/krb/checksum/Makefile.in
===================================================================
--- trunk/src/lib/crypto/krb/checksum/Makefile.in	                        (rev 0)
+++ trunk/src/lib/crypto/krb/checksum/Makefile.in	2009-12-10 17:10:10 UTC (rev 23462)
@@ -0,0 +1,32 @@
+mydir=lib/crypto/krb/checksum
+BUILDTOP=$(REL)..$(S)..$(S)..$(S)..
+LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir)/../arcfour
+DEFS=
+
+##DOS##BUILDTOP = ..\..\..\..
+##DOS##PREFIXDIR=checksum
+##DOS##OBJFILE=..\$(OUTPRE)cksum.lst
+
+PROG_LIBPATH=-L$(TOPLIBD)
+PROG_RPATH=$(KRB5_LIBDIR)
+
+STLIBOBJS= cbc.o confounder.o hmac_md5.o unkeyed.o
+
+OBJS=	$(OUTPRE)cbc.$(OBJEXT) $(OUTPRE)confounder.$(OBJEXT) \
+	$(OUTPRE)hmac_md5.$(OBJEXT) $(OUTPRE)unkeyed.$(OBJEXT)
+
+SRCS=	$(srcdir)/cbc.c $(srcdir)/confounder.c $(srcdir)/hmac_md5.c \
+	$(srcdir)/unkeyed.c
+
+##DOS##LIBOBJS = $(OBJS)
+
+all-unix:: all-libobjs
+
+includes:: depend
+
+depend:: $(SRCS)
+
+clean-unix:: clean-libobjs
+
+ at libobj_frag@
+

Added: trunk/src/lib/crypto/krb/checksum/cbc.c
===================================================================
--- trunk/src/lib/crypto/krb/checksum/cbc.c	                        (rev 0)
+++ trunk/src/lib/crypto/krb/checksum/cbc.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -0,0 +1,43 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/krb/checksum/cbc.c
+ *
+ * Copyright (C) 2009 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.
+ *
+ * CBC checksum, which computes the ivec resulting from CBC encryption of the
+ * input.
+ */
+
+#include "k5-int.h"
+#include "cksumtypes.h"
+
+krb5_error_code
+krb5int_cbc_checksum(const struct krb5_cksumtypes *ctp,
+                     krb5_key key, krb5_keyusage usage,
+                     const krb5_crypto_iov *data, size_t num_data,
+                     krb5_data *output)
+{
+    if (ctp->enc->cbc_mac == NULL)
+        return KRB5_CRYPTO_INTERNAL;
+    return ctp->enc->cbc_mac(key, data, num_data, NULL, output);
+}

Added: trunk/src/lib/crypto/krb/checksum/confounder.c
===================================================================
--- trunk/src/lib/crypto/krb/checksum/confounder.c	                        (rev 0)
+++ trunk/src/lib/crypto/krb/checksum/confounder.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -0,0 +1,159 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/krb/checksum/confounder.c
+ *
+ * Copyright (C) 2009 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.
+ *
+ * Confounder checksum implementation, using tokens of the form:
+ *   enc(xorkey, confounder | hash(confounder | data))
+ * where xorkey is the key XOR'd with 0xf0 bytes.
+ */
+
+#include "k5-int.h"
+#include "cksumtypes.h"
+
+/* Derive a key by XOR with 0xF0 bytes. */
+static krb5_error_code
+mk_xorkey(krb5_key origkey, krb5_key *xorkey)
+{
+    krb5_error_code retval = 0;
+    unsigned char *xorbytes;
+    krb5_keyblock xorkeyblock;
+    size_t i = 0;
+
+    xorbytes = malloc(origkey->keyblock.length);
+    if (xorbytes == NULL)
+	return ENOMEM;
+    memcpy(xorbytes, origkey->keyblock.contents, origkey->keyblock.length);
+    for (i = 0; i < sizeof(xorbytes); i++)
+        xorbytes[i] ^= 0xf0;
+
+    /* Do a shallow copy here. */
+    xorkeyblock = origkey->keyblock;
+    xorkeyblock.contents = xorbytes;
+
+    retval = krb5_k_create_key(0, &xorkeyblock, xorkey);
+    zapfree(xorbytes, sizeof(xorbytes));
+    return retval;
+}
+
+krb5_error_code
+krb5int_confounder_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 ret;
+    krb5_data conf, hashval;
+    krb5_key xorkey = NULL;
+    krb5_crypto_iov *hash_iov, iov;
+    size_t blocksize = ctp->enc->block_size, hashsize = ctp->hash->hashsize;
+
+    conf = make_data(output->data, blocksize);
+    hashval = make_data(output->data + blocksize, hashsize);
+
+    /* Create the confounder. */
+    ret = krb5_c_random_make_octets(NULL, &conf);
+    if (ret != 0)
+        return ret;
+
+    ret = mk_xorkey(key, &xorkey);
+    if (ret)
+        return ret;
+
+    /* Hash the confounder, then the input data. */
+    hash_iov = k5alloc((num_data + 1) * sizeof(krb5_crypto_iov), &ret);
+    if (hash_iov == NULL)
+	goto cleanup;
+    hash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+    hash_iov[0].data = conf;
+    memcpy(hash_iov + 1, data, num_data * sizeof(krb5_crypto_iov));
+    ret = ctp->hash->hash(hash_iov, num_data + 1, &hashval);
+    if (ret != 0)
+	goto cleanup;
+
+    /* Encrypt the confounder and hash value. */
+    iov.flags = KRB5_CRYPTO_TYPE_DATA;
+    iov.data = *output;
+    ret = ctp->enc->encrypt(xorkey, NULL, &iov, 1);
+
+cleanup:
+    free(hash_iov);
+    krb5_k_free_key(NULL, xorkey);
+    return ret;
+}
+
+krb5_error_code krb5int_confounder_verify(const struct krb5_cksumtypes *ctp,
+                                          krb5_key key, krb5_keyusage usage,
+                                          const krb5_crypto_iov *data,
+                                          size_t num_data,
+                                          const krb5_data *input,
+                                          krb5_boolean *valid)
+{
+    krb5_error_code ret;
+    unsigned char *plaintext = NULL;
+    krb5_key xorkey = NULL;
+    krb5_data computed = empty_data();
+    krb5_crypto_iov *hash_iov, iov;
+    size_t blocksize = ctp->enc->block_size, hashsize = ctp->hash->hashsize;
+
+    plaintext = k5alloc(input->length, &ret);
+    if (plaintext == NULL)
+	return ret;
+
+    ret = mk_xorkey(key, &xorkey);
+    if (ret != 0)
+	goto cleanup;
+
+    /* Decrypt the input checksum. */
+    iov.flags = KRB5_CRYPTO_TYPE_DATA;
+    iov.data = make_data(plaintext, input->length);
+    memcpy(plaintext, input->data, input->length);
+    ret = ctp->enc->decrypt(xorkey, NULL, &iov, 1);
+    if (ret != 0)
+        goto cleanup;
+
+    /* Hash the confounder, then the input data. */
+    hash_iov = k5alloc((num_data + 1) * sizeof(krb5_crypto_iov), &ret);
+    if (hash_iov == NULL)
+	goto cleanup;
+    hash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+    hash_iov[0].data = make_data(plaintext, blocksize);
+    memcpy(hash_iov + 1, data, num_data * sizeof(krb5_crypto_iov));
+    ret = alloc_data(&computed, hashsize);
+    if (ret != 0)
+	goto cleanup;
+    ret = ctp->hash->hash(hash_iov, num_data + 1, &computed);
+    if (ret != 0)
+	goto cleanup;
+
+    /* Compare the decrypted hash to the computed one. */
+    *valid = (memcmp(plaintext + blocksize, computed.data, hashsize) == 0);
+
+cleanup:
+    zapfree(plaintext, input->length);
+    zapfree(computed.data, hashsize);
+    free(hash_iov);
+    krb5_k_free_key(NULL, xorkey);
+    return ret;
+}

Added: trunk/src/lib/crypto/krb/checksum/deps
===================================================================
--- trunk/src/lib/crypto/krb/checksum/deps	                        (rev 0)
+++ trunk/src/lib/crypto/krb/checksum/deps	2009-12-10 17:10:10 UTC (rev 23462)
@@ -0,0 +1,49 @@
+# 
+# Generated makefile dependencies follow.
+#
+cbc.so cbc.po $(OUTPRE)cbc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../cksumtypes.h \
+  $(srcdir)/../etypes.h $(top_srcdir)/include/k5-buf.h \
+  $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \
+  $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \
+  $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \
+  $(top_srcdir)/include/socket-utils.h cbc.c
+confounder.so confounder.po $(OUTPRE)confounder.$(OBJEXT): \
+  $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+  $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+  $(COM_ERR_DEPS) $(srcdir)/../cksumtypes.h $(srcdir)/../etypes.h \
+  $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+  $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+  $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+  $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+  $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
+  $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+  confounder.c
+hmac_md5.so hmac_md5.po $(OUTPRE)hmac_md5.$(OBJEXT): \
+  $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+  $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+  $(COM_ERR_DEPS) $(srcdir)/../arcfour/arcfour.h $(srcdir)/../cksumtypes.h \
+  $(srcdir)/../etypes.h $(top_srcdir)/include/k5-buf.h \
+  $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \
+  $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \
+  $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \
+  $(top_srcdir)/include/socket-utils.h hmac_md5.c
+unkeyed.so unkeyed.po $(OUTPRE)unkeyed.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../cksumtypes.h \
+  $(srcdir)/../etypes.h $(top_srcdir)/include/k5-buf.h \
+  $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \
+  $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \
+  $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \
+  $(top_srcdir)/include/socket-utils.h unkeyed.c

Added: trunk/src/lib/crypto/krb/checksum/hmac_md5.c
===================================================================
--- trunk/src/lib/crypto/krb/checksum/hmac_md5.c	                        (rev 0)
+++ trunk/src/lib/crypto/krb/checksum/hmac_md5.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -0,0 +1,94 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/krb/checksum/hmac_md5.c
+ *
+ * Copyright (C) 2009 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.
+ *
+ * Microsoft HMAC-MD5 and MD5-HMAC checksums (see RFC 4757):
+ *   HMAC(KS, hash(msusage || input))
+ * KS is HMAC(key, "signaturekey\0") for HMAC-MD5, or just the key for
+ * MD5-HMAC.
+ */
+
+#include "k5-int.h"
+#include "cksumtypes.h"
+#include "arcfour.h"
+#include "arcfour-int.h"
+
+krb5_error_code krb5int_hmacmd5_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_keyusage ms_usage;
+    krb5_error_code ret;
+    krb5_keyblock ks, *keyblock;
+    krb5_crypto_iov *hash_iov = NULL, iov;
+    krb5_data ds = empty_data(), hashval = empty_data();
+    char t[4];
+
+    if (ctp->ctype == CKSUMTYPE_HMAC_MD5_ARCFOUR) {
+	/* Compute HMAC(key, "signaturekey\0") to get the signing key ks. */
+	ret = alloc_data(&ds, key->keyblock.length);
+	if (ret != 0)
+	    goto cleanup;
+
+	iov.flags = KRB5_CRYPTO_TYPE_DATA;
+	iov.data = make_data("signaturekey", 13);
+	ret = krb5int_hmac(ctp->hash, key, &iov, 1, &ds);
+	if (ret)
+	    goto cleanup;
+	ks.length = key->keyblock.length;
+	ks.contents = (krb5_octet *) ds.data;
+	keyblock = &ks;
+    } else  /* For md5-hmac, just use the key. */
+	keyblock = &key->keyblock;
+
+    /* Compute the MD5 value of the input. */
+    ms_usage = krb5int_arcfour_translate_usage(usage);
+    store_32_le(ms_usage, t);
+    hash_iov = k5alloc((num_data + 1) * sizeof(krb5_crypto_iov), &ret);
+    if (hash_iov == NULL)
+	goto cleanup;
+    hash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+    hash_iov[0].data = make_data(t, 4);
+    memcpy(hash_iov + 1, data, num_data * sizeof(krb5_crypto_iov));
+    ret = alloc_data(&hashval, ctp->hash->hashsize);
+    if (ret != 0)
+	goto cleanup;
+    ret = ctp->hash->hash(hash_iov, num_data + 1, &hashval);
+    if (ret != 0)
+	goto cleanup;
+
+    /* Compute HMAC(ks, md5value). */
+    iov.flags = KRB5_CRYPTO_TYPE_DATA;
+    iov.data = hashval;
+    ret = krb5int_hmac_keyblock(ctp->hash, keyblock, &iov, 1, output);
+
+cleanup:
+    zapfree(ds.data, ds.length);
+    zapfree(hashval.data, hashval.length);
+    free(hash_iov);
+    return ret;
+}

Added: trunk/src/lib/crypto/krb/checksum/unkeyed.c
===================================================================
--- trunk/src/lib/crypto/krb/checksum/unkeyed.c	                        (rev 0)
+++ trunk/src/lib/crypto/krb/checksum/unkeyed.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -0,0 +1,40 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/krb/checksum/unkeyed.c
+ *
+ * Copyright (C) 2009 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.
+ *
+ * Unkeyed hash checksum implementation.
+ */
+
+#include "k5-int.h"
+#include "cksumtypes.h"
+
+krb5_error_code
+krb5int_unkeyed_checksum(const struct krb5_cksumtypes *ctp,
+                         krb5_key key, krb5_keyusage usage,
+                         const krb5_crypto_iov *data, size_t num_data,
+                         krb5_data *output)
+{
+    return ctp->hash->hash(data, num_data, output);
+}

Modified: trunk/src/lib/crypto/krb/checksum_length.c
===================================================================
--- trunk/src/lib/crypto/krb/checksum_length.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/checksum_length.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -32,22 +32,12 @@
 krb5_c_checksum_length(krb5_context context, krb5_cksumtype cksumtype,
                        size_t *length)
 {
-    unsigned int i;
+    const struct krb5_cksumtypes *ctp;
 
-    for (i=0; i<krb5int_cksumtypes_length; i++) {
-        if (krb5int_cksumtypes_list[i].ctype == cksumtype)
-            break;
-    }
-
-    if (i == krb5int_cksumtypes_length)
+    ctp = find_cksumtype(cksumtype);
+    if (ctp == NULL)
         return KRB5_BAD_ENCTYPE;
 
-    if (krb5int_cksumtypes_list[i].keyhash)
-        *length = krb5int_cksumtypes_list[i].keyhash->hashsize;
-    else if (krb5int_cksumtypes_list[i].trunc_size)
-        *length = krb5int_cksumtypes_list[i].trunc_size;
-    else
-        *length = krb5int_cksumtypes_list[i].hash->hashsize;
-
+    *length = ctp->output_size;
     return 0;
 }

Modified: trunk/src/lib/crypto/krb/cksumtype_to_string.c
===================================================================
--- trunk/src/lib/crypto/krb/cksumtype_to_string.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/cksumtype_to_string.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -31,16 +31,13 @@
 krb5_error_code KRB5_CALLCONV
 krb5_cksumtype_to_string(krb5_cksumtype cksumtype, char *buffer, size_t buflen)
 {
-    unsigned int i;
+    const struct krb5_cksumtypes *ctp;
 
-    for (i = 0; i < krb5int_cksumtypes_length; i++) {
-        if (krb5int_cksumtypes_list[i].ctype == cksumtype) {
-            if (strlcpy(buffer, krb5int_cksumtypes_list[i].out_string,
-                        buflen) >= buflen)
-                return ENOMEM;
-            return 0;
-        }
-    }
+    ctp = find_cksumtype(cksumtype);
+    if (ctp == NULL)
+        return KRB5_BAD_ENCTYPE;
 
-    return EINVAL;
+    if (strlcpy(buffer, ctp->out_string, buflen) >= buflen)
+        return ENOMEM;
+    return 0;
 }

Modified: trunk/src/lib/crypto/krb/cksumtypes.c
===================================================================
--- trunk/src/lib/crypto/krb/cksumtypes.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/cksumtypes.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -26,67 +26,85 @@
  */
 
 #include "k5-int.h"
+#include "enc_provider.h"
 #include "hash_provider.h"
-#include "keyhash_provider.h"
+#include "dk.h"
 #include "cksumtypes.h"
 
 const struct krb5_cksumtypes krb5int_cksumtypes_list[] = {
-    { CKSUMTYPE_CRC32, KRB5_CKSUMFLAG_NOT_COLL_PROOF,
+    { CKSUMTYPE_CRC32,
       "crc32", { 0 }, "CRC-32",
-      0, NULL,
-      &krb5int_hash_crc32 },
+      NULL, &krb5int_hash_crc32,
+      krb5int_unkeyed_checksum, NULL,
+      4, 4, CKSUM_UNKEYED | CKSUM_NOT_COLL_PROOF },
 
-    { CKSUMTYPE_RSA_MD4, 0,
+    { CKSUMTYPE_RSA_MD4,
       "md4", { 0 }, "RSA-MD4",
-      0, NULL,
-      &krb5int_hash_md4 },
-    { CKSUMTYPE_RSA_MD4_DES, 0,
+      NULL, &krb5int_hash_md4,
+      krb5int_unkeyed_checksum, NULL,
+      16, 16, CKSUM_UNKEYED },
+
+    { CKSUMTYPE_RSA_MD4_DES,
       "md4-des", { 0 }, "RSA-MD4 with DES cbc mode",
-      ENCTYPE_DES_CBC_CRC, &krb5int_keyhash_md4des,
-      NULL },
+      &krb5int_enc_des, &krb5int_hash_md4,
+      krb5int_confounder_checksum, krb5int_confounder_verify,
+      24, 24, 0 },
 
-    { CKSUMTYPE_DESCBC, 0,
+    { CKSUMTYPE_DESCBC,
       "des-cbc", { 0 }, "DES cbc mode",
-      ENCTYPE_DES_CBC_CRC, &krb5int_keyhash_descbc,
-      NULL },
+      &krb5int_enc_des, NULL,
+      krb5int_cbc_checksum, NULL,
+      8, 8, 0 },
 
-    { CKSUMTYPE_RSA_MD5, 0,
+    { CKSUMTYPE_RSA_MD5,
       "md5", { 0 }, "RSA-MD5",
-      0, NULL,
-      &krb5int_hash_md5 },
-    { CKSUMTYPE_RSA_MD5_DES, 0,
+      NULL, &krb5int_hash_md5,
+      krb5int_unkeyed_checksum, NULL,
+      16, 16, CKSUM_UNKEYED },
+
+    { CKSUMTYPE_RSA_MD5_DES,
       "md5-des", { 0 }, "RSA-MD5 with DES cbc mode",
-      ENCTYPE_DES_CBC_CRC, &krb5int_keyhash_md5des,
-      NULL },
+      &krb5int_enc_des, &krb5int_hash_md5,
+      krb5int_confounder_checksum, krb5int_confounder_verify,
+      24, 24, 0 },
 
-    { CKSUMTYPE_NIST_SHA, 0,
+    { CKSUMTYPE_NIST_SHA,
       "sha", { 0 }, "NIST-SHA",
-      0, NULL,
-      &krb5int_hash_sha1 },
+      NULL, &krb5int_hash_sha1,
+      krb5int_unkeyed_checksum, NULL,
+      20, 20, CKSUM_UNKEYED },
 
-    { CKSUMTYPE_HMAC_SHA1_DES3, KRB5_CKSUMFLAG_DERIVE,
+    { CKSUMTYPE_HMAC_SHA1_DES3,
       "hmac-sha1-des3", { "hmac-sha1-des3-kd" }, "HMAC-SHA1 DES3 key",
-      0, NULL,
-      &krb5int_hash_sha1 },
-    { CKSUMTYPE_HMAC_MD5_ARCFOUR, 0,
+      NULL, &krb5int_hash_sha1,
+      krb5int_dk_checksum, NULL,
+      20, 20, 0 },
+
+    { CKSUMTYPE_HMAC_MD5_ARCFOUR,
       "hmac-md5-rc4", { "hmac-md5-enc", "hmac-md5-earcfour" },
       "Microsoft HMAC MD5 (RC4 key)",
-      ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_hmac_md5,
-      NULL },
+      &krb5int_enc_arcfour, &krb5int_hash_md5,
+      krb5int_hmacmd5_checksum, NULL,
+      16, 16, 0 },
 
-    { CKSUMTYPE_HMAC_SHA1_96_AES128, KRB5_CKSUMFLAG_DERIVE,
+    { CKSUMTYPE_HMAC_SHA1_96_AES128,
       "hmac-sha1-96-aes128", { 0 }, "HMAC-SHA1 AES128 key",
-      0, NULL,
-      &krb5int_hash_sha1, 12 },
-    { CKSUMTYPE_HMAC_SHA1_96_AES256, KRB5_CKSUMFLAG_DERIVE,
+      NULL, &krb5int_hash_sha1,
+      krb5int_dk_checksum, NULL,
+      20, 12, 0 },
+
+    { CKSUMTYPE_HMAC_SHA1_96_AES256,
       "hmac-sha1-96-aes256", { 0 }, "HMAC-SHA1 AES256 key",
-      0, NULL,
-      &krb5int_hash_sha1, 12 },
-    { CKSUMTYPE_MD5_HMAC_ARCFOUR, 0,
+      NULL, &krb5int_hash_sha1,
+      krb5int_dk_checksum, NULL,
+      20, 12, 0 },
+
+    { CKSUMTYPE_MD5_HMAC_ARCFOUR,
       "md5-hmac-rc4", { 0 }, "Microsoft MD5 HMAC (RC4 key)",
-      ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_md5_hmac,
-      NULL }
+      &krb5int_enc_arcfour, &krb5int_hash_md5,
+      krb5int_hmacmd5_checksum, NULL,
+      16, 16, 0 },
 };
 
-const unsigned int krb5int_cksumtypes_length =
+const size_t krb5int_cksumtypes_length =
     sizeof(krb5int_cksumtypes_list) / sizeof(struct krb5_cksumtypes);

Modified: trunk/src/lib/crypto/krb/cksumtypes.h
===================================================================
--- trunk/src/lib/crypto/krb/cksumtypes.h	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/cksumtypes.h	2009-12-10 17:10:10 UTC (rev 23462)
@@ -28,42 +28,114 @@
 #ifndef CKSUMTYPES_H
 #define CKSUMTYPES_H
 #include "k5-int.h"
+#include "etypes.h"
 
+struct krb5_cksumtypes;
+
+/*
+ * Compute a checksum over the header, data, padding, and sign-only fields of
+ * the iov array data (of size num_data).  The output buffer will already be
+ * allocated with ctp->compute_size bytes available; the handler just needs to
+ * fill in the contents.  If ctp->enc is not NULL, the handler can assume that
+ * key is a valid-length key of an enctype which uses that enc provider.
+ */
+typedef krb5_error_code (*checksum_func)(const struct krb5_cksumtypes *ctp,
+                                         krb5_key key, krb5_keyusage usage,
+                                         const krb5_crypto_iov *data,
+                                         size_t num_data,
+                                         krb5_data *output);
+
+/*
+ * Verify a checksum over the header, data, padding, and sign-only fields of
+ * the iov array data (of size num_data), and store the boolean result in
+ * *valid.  The handler can assume that hash has length ctp->output_size.  If
+ * ctp->enc is not NULL, the handler can assume that key a valid-length key of
+ * an enctype which uses that enc provider.
+ */
+typedef krb5_error_code (*verify_func)(const struct krb5_cksumtypes *ctp,
+                                       krb5_key key, krb5_keyusage usage,
+                                       const krb5_crypto_iov *data,
+                                       size_t num_data,
+                                       const krb5_data *input,
+                                       krb5_boolean *valid);
+
 struct krb5_cksumtypes {
     krb5_cksumtype ctype;
-    unsigned int flags;
     char *name;
     char *aliases[2];
     char *out_string;
-    /*
-     * If the hash is keyed, this is the etype it is keyed with.
-     * Actually, it can be keyed by any etype which has the same
-     * enc_provider as the specified etype.  DERIVE checksums can
-     * be keyed with any valid etype.
-     */
-    krb5_enctype keyed_etype;
-    /*
-     * I can't statically initialize a union, so I'm just going to use
-     * two pointers here.  The keyhash is used if non-NULL.  If NULL,
-     * then HMAC/hash with derived keys is used if the relevant flag
-     * is set.  Otherwise, a non-keyed hash is computed.  This is all
-     * kind of messy, but so is the krb5 api.
-     */
-    const struct krb5_keyhash_provider *keyhash;
+    const struct krb5_enc_provider *enc;
     const struct krb5_hash_provider *hash;
-    /*
-     * This just gets uglier and uglier.  In the key derivation case,
-     * we produce an hmac.  To make the hmac code work, we can't hack
-     * the output size indicated by the hash provider, but we may want
-     * a truncated hmac.  If we want truncation, this is the number of
-     * bytes we truncate to; it should be 0 otherwise.
-     */
-    unsigned int trunc_size;
+    checksum_func checksum;
+    verify_func verify;         /* NULL means recompute checksum and compare */
+    unsigned int compute_size;  /* Allocation size for checksum computation */
+    unsigned int output_size;   /* Possibly truncated output size */
+    krb5_flags flags;
 };
 
-#define KRB5_CKSUMFLAG_DERIVE           0x0001
-#define KRB5_CKSUMFLAG_NOT_COLL_PROOF   0x0002
+#define CKSUM_UNKEYED          0x0001
+#define CKSUM_NOT_COLL_PROOF   0x0002
 
 extern const struct krb5_cksumtypes krb5int_cksumtypes_list[];
-extern const unsigned int krb5int_cksumtypes_length;
+extern const size_t krb5int_cksumtypes_length;
+
+krb5_error_code krb5int_unkeyed_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_cbc_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_hmacmd5_checksum(const struct krb5_cksumtypes *ctp,
+                                         krb5_key key, krb5_keyusage usage,
+                                         const krb5_crypto_iov *data,
+                                         size_t num_data,
+                                         krb5_data *output);
+
+krb5_error_code krb5int_confounder_checksum(const struct krb5_cksumtypes *ctp,
+                                            krb5_key key, krb5_keyusage usage,
+                                            const krb5_crypto_iov *data,
+                                            size_t num_data,
+                                            krb5_data *output);
+
+krb5_error_code krb5int_confounder_verify(const struct krb5_cksumtypes *ctp,
+                                          krb5_key key, krb5_keyusage usage,
+                                          const krb5_crypto_iov *data,
+                                          size_t num_data,
+                                          const krb5_data *input,
+                                          krb5_boolean *valid);
+
+static inline const struct krb5_cksumtypes *
+find_cksumtype(krb5_cksumtype ctype)
+{
+    size_t i;
+
+    for (i = 0; i < krb5int_cksumtypes_length; i++) {
+        if (krb5int_cksumtypes_list[i].ctype == ctype)
+            break;
+    }
+
+    if (i == krb5int_cksumtypes_length)
+        return NULL;
+    return &krb5int_cksumtypes_list[i];
+}
+
+static inline krb5_error_code
+verify_key(const struct krb5_cksumtypes *ctp, krb5_key key)
+{
+    const struct krb5_keytypes *ktp;
+
+    ktp = key ? find_enctype(key->keyblock.enctype) : NULL;
+    if (ctp->enc != NULL && (!ktp || ktp->enc != ctp->enc))
+        return KRB5_BAD_ENCTYPE;
+    if (key && (!ktp || key->keyblock.length != ktp->enc->keylength))
+        return KRB5_BAD_KEYSIZE;
+    return 0;
+}
+
 #endif

Modified: trunk/src/lib/crypto/krb/coll_proof_cksum.c
===================================================================
--- trunk/src/lib/crypto/krb/coll_proof_cksum.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/coll_proof_cksum.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -31,15 +31,8 @@
 krb5_boolean KRB5_CALLCONV
 krb5_c_is_coll_proof_cksum(krb5_cksumtype ctype)
 {
-    unsigned int i;
+    const struct krb5_cksumtypes *ctp;
 
-    for (i = 0; i < krb5int_cksumtypes_length; i++) {
-        if (krb5int_cksumtypes_list[i].ctype == ctype)
-            return((krb5int_cksumtypes_list[i].flags &
-                    KRB5_CKSUMFLAG_NOT_COLL_PROOF) ? FALSE : TRUE);
-    }
-
-    /* ick, but it's better than coredumping, which is what the
-       old code would have done */
-    return FALSE;
+    ctp = find_cksumtype(ctype);
+    return (ctp != NULL && !(ctp->flags & CKSUM_NOT_COLL_PROOF));
 }

Modified: trunk/src/lib/crypto/krb/deps
===================================================================
--- trunk/src/lib/crypto/krb/deps	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/deps	2009-12-10 17:10:10 UTC (rev 23462)
@@ -33,7 +33,7 @@
   $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
   $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
   $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
-  checksum_length.c cksumtypes.h
+  checksum_length.c cksumtypes.h etypes.h
 cksumtype_to_string.so cksumtype_to_string.po $(OUTPRE)cksumtype_to_string.$(OBJEXT): \
   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
   $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
@@ -44,19 +44,20 @@
   $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
   $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
   $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
-  cksumtype_to_string.c cksumtypes.h
+  cksumtype_to_string.c cksumtypes.h etypes.h
 cksumtypes.so cksumtypes.po $(OUTPRE)cksumtypes.$(OBJEXT): \
   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
   $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
-  $(COM_ERR_DEPS) $(srcdir)/../builtin/hash_provider/hash_provider.h \
-  $(srcdir)/keyhash_provider/keyhash_provider.h $(top_srcdir)/include/k5-buf.h \
-  $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
-  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
-  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
-  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \
-  $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \
-  $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \
-  $(top_srcdir)/include/socket-utils.h cksumtypes.c cksumtypes.h
+  $(COM_ERR_DEPS) $(srcdir)/../builtin/enc_provider/enc_provider.h \
+  $(srcdir)/../builtin/hash_provider/hash_provider.h \
+  $(srcdir)/dk/dk.h $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+  $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+  $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+  $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+  $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
+  $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+  cksumtypes.c cksumtypes.h etypes.h
 coll_proof_cksum.so coll_proof_cksum.po $(OUTPRE)coll_proof_cksum.$(OBJEXT): \
   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
   $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
@@ -67,7 +68,7 @@
   $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
   $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
   $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
-  cksumtypes.h coll_proof_cksum.c
+  cksumtypes.h coll_proof_cksum.c etypes.h
 combine_keys.so combine_keys.po $(OUTPRE)combine_keys.$(OBJEXT): \
   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
   $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
@@ -234,7 +235,7 @@
   $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
   $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
   $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
-  cksumtypes.h keyed_cksum.c
+  cksumtypes.h etypes.h keyed_cksum.c
 keyed_checksum_types.so keyed_checksum_types.po $(OUTPRE)keyed_checksum_types.$(OBJEXT): \
   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
   $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
@@ -387,7 +388,7 @@
   $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
   $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
   $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
-  cksumtypes.h string_to_cksumtype.c
+  cksumtypes.h etypes.h string_to_cksumtype.c
 string_to_enctype.so string_to_enctype.po $(OUTPRE)string_to_enctype.$(OBJEXT): \
   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
   $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
@@ -420,7 +421,7 @@
   $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
   $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
   $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
-  cksumtypes.h valid_cksumtype.c
+  cksumtypes.h etypes.h valid_cksumtype.c
 valid_enctype.so valid_enctype.po $(OUTPRE)valid_enctype.$(OBJEXT): \
   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
   $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
@@ -442,7 +443,7 @@
   $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
   $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
   $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
-  cksumtypes.h verify_checksum.c
+  cksumtypes.h etypes.h verify_checksum.c
 verify_checksum_iov.so verify_checksum_iov.po $(OUTPRE)verify_checksum_iov.$(OBJEXT): \
   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
   $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \

Modified: trunk/src/lib/crypto/krb/dk/checksum.c
===================================================================
--- trunk/src/lib/crypto/krb/dk/checksum.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/dk/checksum.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -28,15 +28,15 @@
 #include "k5-int.h"
 #include "etypes.h"
 #include "dk.h"
-#include "aead.h"
+#include "cksumtypes.h"
 
 #define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
 
 krb5_error_code
-krb5int_dk_make_checksum(const struct krb5_hash_provider *hash,
-                         krb5_key key, krb5_keyusage usage,
-                         const krb5_crypto_iov *data, size_t num_data,
-                         krb5_data *output)
+krb5int_dk_checksum(const struct krb5_cksumtypes *ctp,
+                    krb5_key key, krb5_keyusage usage,
+                    const krb5_crypto_iov *data, size_t num_data,
+                    krb5_data *output)
 {
     const struct krb5_keytypes *ktp;
     const struct krb5_enc_provider *enc;
@@ -45,32 +45,24 @@
     krb5_data datain;
     krb5_key kc;
 
+    /* Use the key's enctype (more flexible than setting an enctype in ctp). */
     ktp = find_enctype(key->keyblock.enctype);
     if (ktp == NULL)
         return KRB5_BAD_ENCTYPE;
     enc = ktp->enc;
+    if (key->keyblock.length != enc->keylength)
+        return KRB5_BAD_KEYSIZE;
 
-    /*
-     * key->length will be tested in enc->encrypt.
-     * output->length will be tested in krb5int_hmac.
-     */
-
     /* Derive the key. */
-
-    datain.data = (char *) constantdata;
-    datain.length = K5CLENGTH;
-
+    datain = make_data(constantdata, K5CLENGTH);
     store_32_be(usage, constantdata);
-
-    datain.data[4] = (char) 0x99;
-
+    constantdata[4] = (char) 0x99;
     ret = krb5int_derive_key(enc, key, &kc, &datain);
     if (ret)
         return ret;
 
     /* Hash the data. */
-
-    ret = krb5int_hmac(hash, kc, data, num_data, output);
+    ret = krb5int_hmac(ctp->hash, kc, data, num_data, output);
     if (ret)
         memset(output->data, 0, output->length);
 

Modified: trunk/src/lib/crypto/krb/dk/deps
===================================================================
--- trunk/src/lib/crypto/krb/dk/deps	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/dk/deps	2009-12-10 17:10:10 UTC (rev 23462)
@@ -4,15 +4,15 @@
 checksum.so checksum.po $(OUTPRE)checksum.$(OBJEXT): \
   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
   $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
-  $(COM_ERR_DEPS) $(srcdir)/../aead.h $(srcdir)/../cksumtypes.h \
-  $(srcdir)/../etypes.h $(top_srcdir)/include/k5-buf.h \
-  $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
-  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
-  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
-  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \
-  $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \
-  $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \
-  $(top_srcdir)/include/socket-utils.h checksum.c dk.h
+  $(COM_ERR_DEPS) $(srcdir)/../cksumtypes.h $(srcdir)/../etypes.h \
+  $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+  $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+  $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+  $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+  $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
+  $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+  checksum.c dk.h
 dk_aead.so dk_aead.po $(OUTPRE)dk_aead.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
   $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
   $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../aead.h \

Modified: trunk/src/lib/crypto/krb/dk/dk.h
===================================================================
--- trunk/src/lib/crypto/krb/dk/dk.h	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/dk/dk.h	2009-12-10 17:10:10 UTC (rev 23462)
@@ -27,6 +27,7 @@
 
 #include "k5-int.h"
 #include "etypes.h"
+#include "cksumtypes.h"
 
 unsigned int
 krb5int_dk_crypto_length(const struct krb5_keytypes *ktp,
@@ -69,10 +70,10 @@
                    const krb5_data *in_constant);
 
 krb5_error_code
-krb5int_dk_make_checksum(const struct krb5_hash_provider *hash,
-                         krb5_key key, krb5_keyusage usage,
-                         const krb5_crypto_iov *data, size_t num_data,
-                         krb5_data *output);
+krb5int_dk_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_derive_random(const struct krb5_enc_provider *enc,

Modified: trunk/src/lib/crypto/krb/keyed_checksum_types.c
===================================================================
--- trunk/src/lib/crypto/krb/keyed_checksum_types.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/keyed_checksum_types.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -30,13 +30,12 @@
 #include "cksumtypes.h"
 
 static krb5_boolean
-etype_match(krb5_enctype e1, krb5_enctype e2)
+is_keyed_for(const struct krb5_cksumtypes *ctp,
+             const struct krb5_keytypes *ktp)
 {
-    const struct krb5_keytypes *ktp1, *ktp2;
-
-    ktp1 = find_enctype(e1);
-    ktp2 = find_enctype(e2);
-    return (ktp1 != NULL && ktp2 != NULL && ktp1->enc == ktp2->enc);
+    if (ctp->flags & CKSUM_UNKEYED)
+        return FALSE;
+    return (!ctp->enc || ktp->enc == ctp->enc);
 }
 
 krb5_error_code KRB5_CALLCONV
@@ -45,16 +44,20 @@
 {
     unsigned int i, c, nctypes;
     krb5_cksumtype *ctypes;
-    const struct krb5_cksumtypes *ct;
+    const struct krb5_cksumtypes *ctp;
+    const struct krb5_keytypes *ktp;
 
     *count = 0;
     *cksumtypes = NULL;
 
+    ktp = find_enctype(enctype);
+    if (ktp == NULL)
+        return KRB5_BAD_ENCTYPE;
+
     nctypes = 0;
     for (i = 0; i < krb5int_cksumtypes_length; i++) {
-        ct = &krb5int_cksumtypes_list[i];
-        if ((ct->keyhash && etype_match(ct->keyed_etype, enctype)) ||
-            (ct->flags & KRB5_CKSUMFLAG_DERIVE))
+        ctp = &krb5int_cksumtypes_list[i];
+        if (is_keyed_for(ctp, ktp))
             nctypes++;
     }
 
@@ -64,10 +67,9 @@
 
     c = 0;
     for (i = 0; i < krb5int_cksumtypes_length; i++) {
-        ct = &krb5int_cksumtypes_list[i];
-        if ((ct->keyhash && etype_match(ct->keyed_etype, enctype)) ||
-            (ct->flags & KRB5_CKSUMFLAG_DERIVE))
-            ctypes[c++] = krb5int_cksumtypes_list[i].ctype;
+        ctp = &krb5int_cksumtypes_list[i];
+        if (is_keyed_for(ctp, ktp))
+            ctypes[c++] = ctp->ctype;
     }
 
     *count = nctypes;

Modified: trunk/src/lib/crypto/krb/keyed_cksum.c
===================================================================
--- trunk/src/lib/crypto/krb/keyed_cksum.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/keyed_cksum.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -31,17 +31,10 @@
 krb5_boolean KRB5_CALLCONV
 krb5_c_is_keyed_cksum(krb5_cksumtype ctype)
 {
-    unsigned int i;
     const struct krb5_cksumtypes *ctp;
 
-    for (i = 0; i < krb5int_cksumtypes_length; i++) {
-        ctp = &krb5int_cksumtypes_list[i];
-        if (ctp->ctype == ctype) {
-            return (ctp->keyhash != NULL ||
-                    (ctp->flags & KRB5_CKSUMFLAG_DERIVE));
-        }
-    }
-
-    /* Invalid ctype.  This is misleading, but better than dumping core. */
-    return FALSE;
+    ctp = find_cksumtype(ctype);
+    if (ctp == NULL)
+        return FALSE;
+    return !(ctp->flags & CKSUM_UNKEYED);
 }

Modified: trunk/src/lib/crypto/krb/make_checksum.c
===================================================================
--- trunk/src/lib/crypto/krb/make_checksum.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/make_checksum.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -35,81 +35,43 @@
                      krb5_key key, krb5_keyusage usage,
                      const krb5_data *input, krb5_checksum *cksum)
 {
-    unsigned int i;
     const struct krb5_cksumtypes *ctp;
-    const struct krb5_keytypes *ktp1, *ktp2;
-    const struct krb5_keyhash_provider *keyhash;
     krb5_crypto_iov iov;
-    krb5_data data;
+    krb5_data cksum_data;
     krb5_octet *trunc;
     krb5_error_code ret;
-    size_t cksumlen;
 
-    iov.flags = KRB5_CRYPTO_TYPE_DATA;
-    iov.data = *input;
-
-    for (i = 0; i < krb5int_cksumtypes_length; i++) {
-        if (krb5int_cksumtypes_list[i].ctype == cksumtype)
-            break;
-    }
-    if (i == krb5int_cksumtypes_length)
+    ctp = find_cksumtype(cksumtype);
+    if (ctp == NULL)
         return KRB5_BAD_ENCTYPE;
-    ctp = &krb5int_cksumtypes_list[i];
 
-    if (ctp->keyhash != NULL)
-        cksumlen = ctp->keyhash->hashsize;
-    else
-        cksumlen = ctp->hash->hashsize;
+    ret = verify_key(ctp, key);
+    if (ret != 0)
+        return ret;
 
-    cksum->length = cksumlen;
-    cksum->contents = malloc(cksum->length);
-    if (cksum->contents == NULL)
-        return ENOMEM;
+    ret = alloc_data(&cksum_data, ctp->compute_size);
+    if (ret != 0)
+        return ret;
 
-    data = make_data(cksum->contents, cksum->length);
+    iov.flags = KRB5_CRYPTO_TYPE_DATA;
+    iov.data = *input;
+    ret = ctp->checksum(ctp, key, usage, &iov, 1, &cksum_data);
+    if (ret != 0)
+        goto cleanup;
 
-    if (ctp->keyhash) {
-        /* check if key is compatible */
-        if (ctp->keyed_etype) {
-            ktp1 = find_enctype(ctp->keyed_etype);
-            ktp2 = key ? find_enctype(key->keyblock.enctype) : NULL;
-            if (ktp1 == NULL || ktp2 == NULL || ktp1->enc != ktp2->enc) {
-                ret = KRB5_BAD_ENCTYPE;
-                goto cleanup;
-            }
-        }
-
-        keyhash = ctp->keyhash;
-        if (keyhash->hash == NULL) {
-            assert(keyhash->hash_iov != NULL);
-            ret = (*keyhash->hash_iov)(key, usage, &iov, 1, &data);
-        } else {
-            ret = (*keyhash->hash)(key, usage, input, &data);
-        }
-    } else if (ctp->flags & KRB5_CKSUMFLAG_DERIVE) {
-        ret = krb5int_dk_make_checksum(ctp->hash, key, usage, &iov, 1, &data);
-    } else {
-        /* No key is used. */
-        ret = ctp->hash->hash(&iov, 1, &data);
+    cksum->magic = KV5M_CHECKSUM;
+    cksum->checksum_type = cksumtype;
+    cksum->length = ctp->output_size;
+    cksum->contents = (krb5_octet *) cksum_data.data;
+    cksum_data.data = NULL;
+    if (ctp->output_size < ctp->compute_size) {
+        trunc = realloc(cksum->contents, ctp->output_size);
+        if (trunc != NULL)
+            cksum->contents = trunc;
     }
 
-    if (!ret) {
-        cksum->magic = KV5M_CHECKSUM;
-        cksum->checksum_type = cksumtype;
-        if (ctp->trunc_size) {
-            cksum->length = ctp->trunc_size;
-            trunc = realloc(cksum->contents, cksum->length);
-            if (trunc)
-                cksum->contents = trunc;
-        }
-    }
-
 cleanup:
-    if (ret) {
-        zapfree(cksum->contents, cksum->length);
-        cksum->contents = NULL;
-    }
-
+    zapfree(cksum_data.data, ctp->compute_size);
     return ret;
 }
 

Modified: trunk/src/lib/crypto/krb/make_checksum_iov.c
===================================================================
--- trunk/src/lib/crypto/krb/make_checksum_iov.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/make_checksum_iov.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -37,50 +37,37 @@
                          krb5_crypto_iov *data,
                          size_t num_data)
 {
-    unsigned int i;
-    size_t cksumlen;
     krb5_error_code ret;
     krb5_data cksum_data;
     krb5_crypto_iov *checksum;
     const struct krb5_cksumtypes *ctp;
 
-    for (i = 0; i < krb5int_cksumtypes_length; i++) {
-        if (krb5int_cksumtypes_list[i].ctype == cksumtype)
-            break;
-    }
-    if (i == krb5int_cksumtypes_length)
+    ctp = find_cksumtype(cksumtype);
+    if (ctp == NULL)
         return KRB5_BAD_ENCTYPE;
-    ctp = &krb5int_cksumtypes_list[i];
 
-    if (ctp->keyhash != NULL)
-        cksum_data.length = ctp->keyhash->hashsize;
-    else
-        cksum_data.length = ctp->hash->hashsize;
+    ret = verify_key(ctp, key);
+    if (ret != 0)
+        return ret;
 
-    if (ctp->trunc_size != 0)
-        cksumlen = ctp->trunc_size;
-    else
-        cksumlen = cksum_data.length;
-
     checksum = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_CHECKSUM);
-    if (checksum == NULL || checksum->data.length < cksumlen)
+    if (checksum == NULL || checksum->data.length < ctp->output_size)
         return(KRB5_BAD_MSIZE);
 
-    cksum_data.data = malloc(cksum_data.length);
-    if (cksum_data.data == NULL)
-        return(ENOMEM);
+    ret = alloc_data(&cksum_data, ctp->compute_size);
+    if (ret != 0)
+        return ret;
 
-    ret = krb5int_c_make_checksum_iov(&krb5int_cksumtypes_list[i],
-                                      key, usage, data, num_data,
-                                      &cksum_data);
-    if (ret == 0) {
-        memcpy(checksum->data.data, cksum_data.data, cksumlen);
-        checksum->data.length = cksumlen;
-    }
+    ret = ctp->checksum(ctp, key, usage, data, num_data, &cksum_data);
+    if (ret != 0)
+        goto cleanup;
 
-    free(cksum_data.data);
+    memcpy(checksum->data.data, cksum_data.data, ctp->output_size);
+    checksum->data.length = ctp->output_size;
 
-    return(ret);
+cleanup:
+    zapfree(cksum_data.data, ctp->compute_size);
+    return ret;
 }
 
 krb5_error_code KRB5_CALLCONV

Modified: trunk/src/lib/crypto/krb/valid_cksumtype.c
===================================================================
--- trunk/src/lib/crypto/krb/valid_cksumtype.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/valid_cksumtype.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -31,12 +31,10 @@
 krb5_boolean KRB5_CALLCONV
 krb5_c_valid_cksumtype(krb5_cksumtype ctype)
 {
-    unsigned int i;
+    const struct krb5_cksumtypes *ctp;
 
-    for (i = 0; i < krb5int_cksumtypes_length; i++) {
-        if (krb5int_cksumtypes_list[i].ctype == ctype)
-            return TRUE;
-    }
-
-    return FALSE;
+    ctp = find_cksumtype(ctype);
+    if (ctp == NULL)
+        return FALSE;
+    return TRUE;
 }

Modified: trunk/src/lib/crypto/krb/verify_checksum.c
===================================================================
--- trunk/src/lib/crypto/krb/verify_checksum.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/verify_checksum.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -33,58 +33,39 @@
                        krb5_keyusage usage, const krb5_data *data,
                        const krb5_checksum *cksum, krb5_boolean *valid)
 {
-    unsigned int i;
     const struct krb5_cksumtypes *ctp;
-    const struct krb5_keyhash_provider *keyhash;
-    size_t hashsize;
+    krb5_crypto_iov iov;
     krb5_error_code ret;
-    krb5_data indata;
+    krb5_data cksum_data;
     krb5_checksum computed;
 
-    for (i=0; i<krb5int_cksumtypes_length; i++) {
-        if (krb5int_cksumtypes_list[i].ctype == cksum->checksum_type)
-            break;
-    }
-    if (i == krb5int_cksumtypes_length)
+    iov.flags = KRB5_CRYPTO_TYPE_DATA;
+    iov.data = *data;
+
+    ctp = find_cksumtype(cksum->checksum_type);
+    if (ctp == NULL)
         return KRB5_BAD_ENCTYPE;
-    ctp = &krb5int_cksumtypes_list[i];
 
-    indata.length = cksum->length;
-    indata.data = (char *) cksum->contents;
+    ret = verify_key(ctp, key);
+    if (ret != 0)
+        return ret;
 
     /* If there's actually a verify function, call it. */
-    if (ctp->keyhash) {
-        keyhash = ctp->keyhash;
+    cksum_data = make_data(cksum->contents, cksum->length);
+    if (ctp->verify != NULL)
+        return ctp->verify(ctp, key, usage, &iov, 1, &cksum_data, valid);
 
-        if (keyhash->verify == NULL && keyhash->verify_iov != NULL) {
-            krb5_crypto_iov iov[1];
-
-            iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
-            iov[0].data.data = data->data;
-            iov[0].data.length = data->length;
-
-            return (*keyhash->verify_iov)(key, usage, iov, 1, &indata, valid);
-        } else if (keyhash->verify != NULL) {
-            return (*keyhash->verify)(key, usage, data, &indata, valid);
-        }
-    }
-
     /* Otherwise, make the checksum again, and compare. */
-    ret = krb5_c_checksum_length(context, cksum->checksum_type, &hashsize);
-    if (ret)
-        return ret;
-
-    if (cksum->length != hashsize)
+    if (cksum->length != ctp->output_size)
         return KRB5_BAD_MSIZE;
 
-    computed.length = hashsize;
-
     ret = krb5_k_make_checksum(context, cksum->checksum_type, key, usage,
                                data, &computed);
     if (ret)
         return ret;
 
-    *valid = (memcmp(computed.contents, cksum->contents, hashsize) == 0);
+    *valid = (memcmp(computed.contents, cksum->contents,
+                     ctp->output_size) == 0);
 
     free(computed.contents);
     return 0;

Modified: trunk/src/lib/crypto/krb/verify_checksum_iov.c
===================================================================
--- trunk/src/lib/crypto/krb/verify_checksum_iov.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/krb/verify_checksum_iov.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -38,62 +38,42 @@
                            size_t num_data,
                            krb5_boolean *valid)
 {
-    unsigned int i;
     const struct krb5_cksumtypes *ctp;
-    size_t cksumlen;
     krb5_error_code ret;
     krb5_data computed;
     krb5_crypto_iov *checksum;
 
-    for (i = 0; i < krb5int_cksumtypes_length; i++) {
-        if (krb5int_cksumtypes_list[i].ctype == checksum_type)
-            break;
-    }
-    if (i == krb5int_cksumtypes_length)
+    ctp = find_cksumtype(checksum_type);
+    if (ctp == NULL)
         return KRB5_BAD_ENCTYPE;
-    ctp = &krb5int_cksumtypes_list[i];
 
+    ret = verify_key(ctp, key);
+    if (ret != 0)
+        return ret;
+
     checksum = krb5int_c_locate_iov((krb5_crypto_iov *)data, num_data,
                                     KRB5_CRYPTO_TYPE_CHECKSUM);
-    if (checksum == NULL)
-        return(KRB5_BAD_MSIZE);
+    if (checksum == NULL || checksum->data.length != ctp->output_size)
+        return KRB5_BAD_MSIZE;
 
     /* If there's actually a verify function, call it. */
-    if (ctp->keyhash && ctp->keyhash->verify_iov) {
-        return (*ctp->keyhash->verify_iov)(key, usage, data, num_data,
-                                           &checksum->data, valid);
+    if (ctp->verify != NULL) {
+        return ctp->verify(ctp, key, usage, data, num_data, &checksum->data,
+                           valid);
     }
 
-    /* Otherwise, make the checksum again, and compare. */
-    if (ctp->keyhash != NULL)
-        computed.length = ctp->keyhash->hashsize;
-    else
-        computed.length = ctp->hash->hashsize;
-
-    if (ctp->trunc_size != 0)
-        cksumlen = ctp->trunc_size;
-    else
-        cksumlen = computed.length;
-
-    if (checksum->data.length != cksumlen)
-        return KRB5_BAD_MSIZE;
-
-    computed.data = malloc(computed.length);
-    if (computed.data == NULL)
-        return ENOMEM;
-
-    ret = krb5int_c_make_checksum_iov(&krb5int_cksumtypes_list[i], key, usage,
-                                      data, num_data, &computed);
-    if (ret) {
-        free(computed.data);
+    ret = alloc_data(&computed, ctp->compute_size);
+    if (ret != 0)
         return ret;
+
+    ret = ctp->checksum(ctp, key, usage, data, num_data, &computed);
+    if (ret == 0) {
+        *valid = (memcmp(computed.data, checksum->data.data,
+                         ctp->output_size) == 0);
     }
 
-    *valid = (computed.length == cksumlen) &&
-        (memcmp(computed.data, checksum->data.data, cksumlen) == 0);
-
-    free(computed.data);
-    return 0;
+    zapfree(computed.data, ctp->compute_size);
+    return ret;
 }
 
 krb5_error_code KRB5_CALLCONV

Modified: trunk/src/lib/crypto/libk5crypto.exports
===================================================================
--- trunk/src/lib/crypto/libk5crypto.exports	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/libk5crypto.exports	2009-12-10 17:10:10 UTC (rev 23462)
@@ -83,8 +83,6 @@
 krb5_k_reference_key
 krb5_k_verify_checksum
 krb5_k_verify_checksum_iov
-krb5int_keyhash_md4des
-krb5int_keyhash_md5des
 mit_crc32
 krb5int_aes_encrypt
 krb5int_MD4Init

Modified: trunk/src/lib/crypto/openssl/enc_provider/aes.c
===================================================================
--- trunk/src/lib/crypto/openssl/enc_provider/aes.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/openssl/enc_provider/aes.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -285,7 +285,7 @@
     if (nblocks == 1) {
         if (input_length != BLOCK_SIZE)
             return KRB5_BAD_MSIZE;
-        ret = cbc_enc(key, ivec, data, num_data);
+        ret = cbc_decr(key, ivec, data, num_data);
     } else if (nblocks > 1) {
         ret = cts_decr(key, ivec, data, num_data, input_length);
     }
@@ -309,6 +309,7 @@
     16, 16,
     krb5int_aes_encrypt,
     krb5int_aes_decrypt,
+    NULL,
     krb5int_aes_make_key,
     krb5int_aes_init_state,
     krb5int_default_free_state
@@ -319,6 +320,7 @@
     32, 32,
     krb5int_aes_encrypt,
     krb5int_aes_decrypt,
+    NULL,
     krb5int_aes_make_key,
     krb5int_aes_init_state,
     krb5int_default_free_state

Modified: trunk/src/lib/crypto/openssl/enc_provider/des.c
===================================================================
--- trunk/src/lib/crypto/openssl/enc_provider/des.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/openssl/enc_provider/des.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -187,6 +187,7 @@
     DES_KEY_BYTES, KRB5_MIT_DES_KEYSIZE,
     k5_des_encrypt,
     k5_des_decrypt,
+    NULL,
     krb5int_des_make_key,
     krb5int_des_init_state,
     krb5int_default_free_state

Modified: trunk/src/lib/crypto/openssl/enc_provider/des3.c
===================================================================
--- trunk/src/lib/crypto/openssl/enc_provider/des3.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/openssl/enc_provider/des3.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -193,6 +193,7 @@
     KRB5_MIT_DES3_KEY_BYTES, KRB5_MIT_DES3_KEYSIZE,
     k5_des3_encrypt,
     k5_des3_decrypt,
+    NULL,
     krb5int_des3_make_key,
     krb5int_des_init_state,
     krb5int_default_free_state

Modified: trunk/src/lib/crypto/openssl/enc_provider/rc4.c
===================================================================
--- trunk/src/lib/crypto/openssl/enc_provider/rc4.c	2009-12-09 17:54:07 UTC (rev 23461)
+++ trunk/src/lib/crypto/openssl/enc_provider/rc4.c	2009-12-10 17:10:10 UTC (rev 23462)
@@ -145,6 +145,7 @@
     RC4_KEY_SIZE, RC4_KEY_SIZE,
     k5_arcfour_docrypt,
     k5_arcfour_docrypt,
+    NULL,
     krb5int_arcfour_make_key,
     k5_arcfour_init_state, /*xxx not implemented */
     k5_arcfour_free_state  /*xxx not implemented */




More information about the cvs-krb5 mailing list