summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-08-06 15:03:08 +0200
committerHerbert Xu <herbert@gondor.apana.org.au>2006-09-21 03:41:01 +0200
commit25cdbcd9e5d20e431f829cafce48a418830011f4 (patch)
tree0dff8422d2b0b1da1d3505b0ad0e840f6f0fd66d
parent[CRYPTO] padlock-sha: TFMs don't need to be static (diff)
downloadlinux-25cdbcd9e5d20e431f829cafce48a418830011f4.tar.xz
linux-25cdbcd9e5d20e431f829cafce48a418830011f4.zip
[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>
-rw-r--r--crypto/crc32c.c25
-rw-r--r--crypto/tcrypt.c4
2 files changed, 19 insertions, 10 deletions
diff --git a/crypto/crc32c.c b/crypto/crc32c.c
index f2660123aeb4..91ecd895e957 100644
--- 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;
+ u32 key;
};
/*
@@ -35,7 +35,7 @@ static void chksum_init(struct crypto_tfm *tfm)
{
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_tfm *tfm, const u8 *key,
*flags = CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
}
- mctx->crc = __cpu_to_le32(*(u32 *)key);
+ mctx->key = le32_to_cpu(*(__le32 *)key);
return 0;
}
@@ -61,19 +61,23 @@ static void chksum_update(struct crypto_tfm *tfm, const u8 *data,
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 = crc32c(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);
+ *(__le32 *)out = ~cpu_to_le32(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
index e52f56c5bd5e..bed225e83231 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -810,6 +810,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");
@@ -821,6 +822,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]) {
@@ -836,6 +838,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);
}
@@ -849,6 +852,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);