Commit 25cdbcd9e5d20e431f829cafce48a418830011f4

Authored by Herbert Xu
1 parent 58ec415289

[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 <herbert@gondor.apana.org.au>

Showing 2 changed files with 19 additions and 10 deletions Side-by-side Diff

... ... @@ -16,14 +16,14 @@
16 16 #include <linux/string.h>
17 17 #include <linux/crypto.h>
18 18 #include <linux/crc32c.h>
19   -#include <linux/types.h>
20   -#include <asm/byteorder.h>
  19 +#include <linux/kernel.h>
21 20  
22 21 #define CHKSUM_BLOCK_SIZE 32
23 22 #define CHKSUM_DIGEST_SIZE 4
24 23  
25 24 struct chksum_ctx {
26 25 u32 crc;
  26 + u32 key;
27 27 };
28 28  
29 29 /*
... ... @@ -35,7 +35,7 @@
35 35 {
36 36 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
37 37  
38   - mctx->crc = ~(u32)0; /* common usage */
  38 + mctx->crc = mctx->key;
39 39 }
40 40  
41 41 /*
... ... @@ -53,7 +53,7 @@
53 53 *flags = CRYPTO_TFM_RES_BAD_KEY_LEN;
54 54 return -EINVAL;
55 55 }
56   - mctx->crc = __cpu_to_le32(*(u32 *)key);
  56 + mctx->key = le32_to_cpu(*(__le32 *)key);
57 57 return 0;
58 58 }
59 59  
60 60  
61 61  
62 62  
63 63  
... ... @@ -61,21 +61,25 @@
61 61 unsigned int length)
62 62 {
63 63 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
64   - u32 mcrc;
65 64  
66   - mcrc = crc32c(mctx->crc, data, (size_t)length);
67   -
68   - mctx->crc = mcrc;
  65 + mctx->crc = crc32c(mctx->crc, data, length);
69 66 }
70 67  
71 68 static void chksum_final(struct crypto_tfm *tfm, u8 *out)
72 69 {
73 70 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
74   - u32 mcrc = (mctx->crc ^ ~(u32)0);
75 71  
76   - *(u32 *)out = __le32_to_cpu(mcrc);
  72 + *(__le32 *)out = ~cpu_to_le32(mctx->crc);
77 73 }
78 74  
  75 +static int crc32c_cra_init(struct crypto_tfm *tfm)
  76 +{
  77 + struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
  78 +
  79 + mctx->key = ~0;
  80 + return 0;
  81 +}
  82 +
79 83 static struct crypto_alg alg = {
80 84 .cra_name = "crc32c",
81 85 .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
... ... @@ -83,6 +87,7 @@
83 87 .cra_ctxsize = sizeof(struct chksum_ctx),
84 88 .cra_module = THIS_MODULE,
85 89 .cra_list = LIST_HEAD_INIT(alg.cra_list),
  90 + .cra_init = crc32c_cra_init,
86 91 .cra_u = {
87 92 .digest = {
88 93 .dia_digestsize= CHKSUM_DIGEST_SIZE,
... ... @@ -810,6 +810,7 @@
810 810  
811 811 seed = SEEDTESTVAL;
812 812 (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
  813 + crypto_digest_init(tfm);
813 814 crypto_digest_final(tfm, (u8*)&crc);
814 815 printk("testing crc32c setkey returns %08x : %s\n", crc, (crc == (SEEDTESTVAL ^ ~(u32)0)) ?
815 816 "pass" : "ERROR");
... ... @@ -821,6 +822,7 @@
821 822 for (i = 0; i < NUMVEC; i++) {
822 823 seed = ~(u32)0;
823 824 (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
  825 + crypto_digest_init(tfm);
824 826 crypto_digest_update(tfm, &sg[i], 1);
825 827 crypto_digest_final(tfm, (u8*)&crc);
826 828 if (crc == vec_results[i]) {
... ... @@ -836,6 +838,7 @@
836 838 for (i = 0; i < NUMVEC; i++) {
837 839 seed = (crc ^ ~(u32)0);
838 840 (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
  841 + crypto_digest_init(tfm);
839 842 crypto_digest_update(tfm, &sg[i], 1);
840 843 crypto_digest_final(tfm, (u8*)&crc);
841 844 }
... ... @@ -849,6 +852,7 @@
849 852 printk("\ntesting crc32c using digest:\n");
850 853 seed = ~(u32)0;
851 854 (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
  855 + crypto_digest_init(tfm);
852 856 crypto_digest_digest(tfm, sg, NUMVEC, (u8*)&crc);
853 857 if (crc == tot_vec_results) {
854 858 printk(" %08x:OK", crc);