Skip to content

Commit

Permalink
[CRYPTO] crc32c: Fix unconventional setkey usage
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
herbertx committed Sep 21, 2006
1 parent 58ec415 commit 25cdbcd
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 10 deletions.
25 changes: 15 additions & 10 deletions crypto/crc32c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

/*
Expand All @@ -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;
}

/*
Expand All @@ -53,27 +53,31 @@ 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;
}

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 = {
Expand All @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions crypto/tcrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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]) {
Expand All @@ -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);
}
Expand All @@ -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);
Expand Down

0 comments on commit 25cdbcd

Please sign in to comment.