Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

+19 -10
+15 -10
crypto/crc32c.c
··· 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 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 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 ··· 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); 73 + } 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; 77 81 } 78 82 79 83 static struct crypto_alg alg = { ··· 87 83 .cra_ctxsize = sizeof(struct chksum_ctx), 88 84 .cra_module = THIS_MODULE, 89 85 .cra_list = LIST_HEAD_INIT(alg.cra_list), 86 + .cra_init = crc32c_cra_init, 90 87 .cra_u = { 91 88 .digest = { 92 89 .dia_digestsize= CHKSUM_DIGEST_SIZE,
+4
crypto/tcrypt.c
··· 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"); ··· 822 821 for (i = 0; i < NUMVEC; i++) { 823 822 seed = ~(u32)0; 824 823 (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); 824 + crypto_digest_init(tfm); 825 825 crypto_digest_update(tfm, &sg[i], 1); 826 826 crypto_digest_final(tfm, (u8*)&crc); 827 827 if (crc == vec_results[i]) { ··· 838 836 for (i = 0; i < NUMVEC; i++) { 839 837 seed = (crc ^ ~(u32)0); 840 838 (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); 839 + crypto_digest_init(tfm); 841 840 crypto_digest_update(tfm, &sg[i], 1); 842 841 crypto_digest_final(tfm, (u8*)&crc); 843 842 } ··· 852 849 printk("\ntesting crc32c using digest:\n"); 853 850 seed = ~(u32)0; 854 851 (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); 852 + crypto_digest_init(tfm); 855 853 crypto_digest_digest(tfm, sg, NUMVEC, (u8*)&crc); 856 854 if (crc == tot_vec_results) { 857 855 printk(" %08x:OK", crc);