Make the crc32 hash provider correctly chain multiple input buffers,
authorGreg Hudson <ghudson@mit.edu>
Mon, 30 Nov 2009 16:12:36 +0000 (16:12 +0000)
committerGreg Hudson <ghudson@mit.edu>
Mon, 30 Nov 2009 16:12:36 +0000 (16:12 +0000)
so that it returns the same result if you pass it one big buffer or
many small buffers containing the same data.  To do this, change the
contract of mit_crc32 so that the cksum parameter is in-out.

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

src/lib/crypto/builtin/hash_provider/hash_crc32.c
src/lib/crypto/crypto_tests/t_crc.c
src/lib/crypto/krb/crc32/crc-32.h
src/lib/crypto/krb/crc32/crc32.c
src/lib/crypto/openssl/hash_provider/hash_crc32.c

index e748c98cfe9ab98fef7b16c4e3dd620ec3f12938..58efffe4f3422ac212f61623a5d1680e68e75c44 100644 (file)
@@ -33,17 +33,15 @@ static krb5_error_code
 k5_crc32_hash(unsigned int icount, const krb5_data *input,
               krb5_data *output)
 {
-    unsigned long c, cn;
+    unsigned long c;
     unsigned int i;
 
     if (output->length != CRC32_CKSUM_LENGTH)
         return(KRB5_CRYPTO_INTERNAL);
 
     c = 0;
-    for (i=0; i<icount; i++) {
-        mit_crc32(input[i].data, input[i].length, &cn);
-        c ^= cn;
-    }
+    for (i=0; i<icount; i++)
+        mit_crc32(input[i].data, input[i].length, &c);
 
     store_32_le(c, output->data);
     return(0);
index 6d06334dd7f74a133e92fd70ea18937c7bde33f5..69a6468053dda30e3a283ac56953a5a9db62ec33 100644 (file)
@@ -121,6 +121,7 @@ timetest(unsigned int nblk, unsigned int blksiz)
         block[i] = i % 256;
     times(&before);
     for (i = 0; i < nblk; i++) {
+        cksum = 0;
         mit_crc32(block + i * blksiz, blksiz, &cksum);
     }
 
@@ -136,6 +137,7 @@ timetest(unsigned int nblk, unsigned int blksiz)
 #ifdef CRC32_SHIFT4
     times(&before);
     for (i = 0; i < nblk; i++) {
+        cksum = 0;
         mit_crc32_shift4(block + i * blksiz, blksiz, &cksum);
     }
     times(&after);
@@ -185,11 +187,13 @@ verify(void)
         case STR:
             len = strlen(trial.data);
             typestr = "STR";
+            cksum = 0;
             mit_crc32(trial.data, len, &cksum);
             break;
         case HEX:
             typestr = "HEX";
             gethexstr(trial.data, &len, buf, 4);
+            cksum = 0;
             mit_crc32(buf, len, &cksum);
             break;
         default:
index 95001f59d3108d44a3114de48cc6952d6ee72434..5c28b8b790288e4fe2a43c11233b365adc10bba1 100644 (file)
@@ -60,6 +60,7 @@
 
 #define CRC32_CKSUM_LENGTH      4
 
+/* c is in-out to allow chaining; initialize to 0. */
 void
 mit_crc32 (krb5_pointer in, size_t in_length, unsigned long *c);
 
index 490979803143995a4d629bd19145df9dbba6ebab..ef364f3ed9bbcf33874ba9d240d55b5a1b2d3ccf 100644 (file)
@@ -151,7 +151,7 @@ void
 mit_crc32(krb5_pointer in, size_t in_length, unsigned long *cksum)
 {
     register u_char *data;
-    register u_long c = 0;
+    register u_long c = *cksum;
     register int idx;
     size_t i;
 
@@ -178,7 +178,7 @@ void
 mit_crc32_shift4(krb5_pointer in, size_t in_length, unsigned long *cksum)
 {
     register unsigned char *data, b;
-    register unsigned long c = 0;
+    register unsigned long c = *cksum;
     size_t i;
 
     data = (u_char *)in;
index e748c98cfe9ab98fef7b16c4e3dd620ec3f12938..58efffe4f3422ac212f61623a5d1680e68e75c44 100644 (file)
@@ -33,17 +33,15 @@ static krb5_error_code
 k5_crc32_hash(unsigned int icount, const krb5_data *input,
               krb5_data *output)
 {
-    unsigned long c, cn;
+    unsigned long c;
     unsigned int i;
 
     if (output->length != CRC32_CKSUM_LENGTH)
         return(KRB5_CRYPTO_INTERNAL);
 
     c = 0;
-    for (i=0; i<icount; i++) {
-        mit_crc32(input[i].data, input[i].length, &cn);
-        c ^= cn;
-    }
+    for (i=0; i<icount; i++)
+        mit_crc32(input[i].data, input[i].length, &c);
 
     store_32_le(c, output->data);
     return(0);