Hi:

[CRYPTO] crc32c: Fix unconventional setkey usage

The convention for setkey is that once it is set it should not change,
in particular, init must not wipe out the key set by it.  In fact, init
should always be used after setkey before any digestion is performed.

The only user of crc32c that sets the key is tcrypt.  This patch adds
the necessary init calls there.

Signed-off-by: Herbert Xu <[EMAIL PROTECTED]>

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[EMAIL PROTECTED]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/crypto/crc32c.c b/crypto/crc32c.c
--- a/crypto/crc32c.c
+++ b/crypto/crc32c.c
@@ -16,14 +16,14 @@
 #include <linux/string.h>
 #include <linux/crypto.h>
 #include <linux/crc32c.h>
-#include <linux/types.h>
-#include <asm/byteorder.h>
+#include <linux/kernel.h>
 
 #define CHKSUM_BLOCK_SIZE      32
 #define CHKSUM_DIGEST_SIZE     4
 
 struct chksum_ctx {
-       u32 crc;
+       __le32 crc;
+       __le32 key;
 };
 
 /*
@@ -35,7 +35,7 @@ static void chksum_init(struct crypto_tf
 {
        struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
 
-       mctx->crc = ~(u32)0;                    /* common usage */
+       mctx->crc = mctx->key;
 }
 
 /*
@@ -53,7 +53,7 @@ static int chksum_setkey(struct crypto_t
                        *flags = CRYPTO_TFM_RES_BAD_KEY_LEN;
                return -EINVAL;
        }
-       mctx->crc = __cpu_to_le32(*(u32 *)key);
+       mctx->key = cpu_to_le32(*(u32 *)key);
        return 0;
 }
 
@@ -61,19 +61,23 @@ static void chksum_update(struct crypto_
                          unsigned int length)
 {
        struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
-       u32 mcrc;
 
-       mcrc = crc32c(mctx->crc, data, (size_t)length);
-
-       mctx->crc = mcrc;
+       mctx->crc = (__le32)crc32c((u32)mctx->crc, data, length);
 }
 
 static void chksum_final(struct crypto_tfm *tfm, u8 *out)
 {
        struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
-       u32 mcrc = (mctx->crc ^ ~(u32)0);
        
-       *(u32 *)out = __le32_to_cpu(mcrc);
+       *(u32 *)out = ~le32_to_cpu(mctx->crc);
+}
+
+static int crc32c_cra_init(struct crypto_tfm *tfm)
+{
+       struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
+
+       mctx->key = ~0;
+       return 0;
 }
 
 static struct crypto_alg alg = {
@@ -83,6 +87,7 @@ static struct crypto_alg alg = {
        .cra_ctxsize    =       sizeof(struct chksum_ctx),
        .cra_module     =       THIS_MODULE,
        .cra_list       =       LIST_HEAD_INIT(alg.cra_list),
+       .cra_init       =       crc32c_cra_init,
        .cra_u          =       {
                .digest = {
                         .dia_digestsize=       CHKSUM_DIGEST_SIZE,
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -724,6 +724,7 @@ static void test_crc32c(void)
 
        seed = SEEDTESTVAL;
        (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
+       crypto_digest_init(tfm);
        crypto_digest_final(tfm, (u8*)&crc);
        printk("testing crc32c setkey returns %08x : %s\n", crc, (crc == 
(SEEDTESTVAL ^ ~(u32)0)) ?
               "pass" : "ERROR");
@@ -735,6 +736,7 @@ static void test_crc32c(void)
        for (i = 0; i < NUMVEC; i++) {
                seed = ~(u32)0;
                (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
+               crypto_digest_init(tfm);
                crypto_digest_update(tfm, &sg[i], 1);
                crypto_digest_final(tfm, (u8*)&crc);
                if (crc == vec_results[i]) {
@@ -750,6 +752,7 @@ static void test_crc32c(void)
        for (i = 0; i < NUMVEC; i++) {
                seed = (crc ^ ~(u32)0);
                (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
+               crypto_digest_init(tfm);
                crypto_digest_update(tfm, &sg[i], 1);
                crypto_digest_final(tfm, (u8*)&crc);
        }
@@ -763,6 +766,7 @@ static void test_crc32c(void)
        printk("\ntesting crc32c using digest:\n");
        seed = ~(u32)0;
        (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
+       crypto_digest_init(tfm);
        crypto_digest_digest(tfm, sg, NUMVEC, (u8*)&crc);
        if (crc == tot_vec_results) {
                printk(" %08x:OK", crc);
-
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to