+ */ +static inline void crypto_chksum_setseedstruct crypto_tfm *tfm, + const u32 seed +{ +BUG_ONcrypto_tfm_alg_typetfm != CRYPTO_ALG_TYPE_CHKSUM; +tfm->crt_chksum.cht_setseedtfm, seed;
Trang 1+for (j = 0; j < VECSIZE; j++)
+test_vec[i][j] = ++b;
+sg[i].page = virt_to_page(test_vec[i]);
+sg[i].offset = offset_in_page(test_vec[i]);
+sg[i].length = VECSIZE;
+}
+
+crypto_chksum_setseed(tfm, SEEDTESTVAL);
+crypto_chksum_final(tfm, &crc);
+printk("testing crc32c setseed returns %08x : %s\n", crc, (crc == (SEEDTESTVAL ^ ~(u32)0)) ?
+ "pass" : "ERROR");
+
+printk("testing crc32c using update/final:\n");
+
+pass = 1; /* assume all is well */
+
+for (i = 0; i < NUMVEC; i++) {
+crypto_chksum_setseed(tfm, ~(u32)0);
+crypto_chksum_update(tfm, &sg[i], 1);
+crypto_chksum_final(tfm, &crc);
+if (crc == vec_results[i]) {
+printk(" %08x:OK", crc);
+} else {
+printk(" %08x:BAD, wanted %08x\n", crc, vec_results[i]); +pass = 0;
+}
+}
+
+printk("\ntesting crc32c using incremental accumulator:\n"); +crc = 0;
+for (i = 0; i < NUMVEC; i++) {
+crypto_chksum_setseed(tfm, (crc ^ ~(u32)0));
+crypto_chksum_update(tfm, &sg[i], 1);
+crypto_chksum_final(tfm, &crc);
+}
+if (crc == tot_vec_results) {
+printk(" %08x:OK", crc);
+} else {
Trang 2+printk(" %08x:BAD, wanted %08x\n", crc, tot_vec_results);
+pass = 0;
+}
+
+printk("\ntesting crc32c using digest:\n");
+crypto_chksum_setseed(tfm, ~(u32)0);
+crypto_chksum_digest(tfm, sg, NUMVEC, &crc);
+if (crc == tot_vec_results) {
+printk(" %08x:OK", crc);
+} else {
+printk(" %08x:BAD, wanted %08x\n", crc, tot_vec_results);
+pass = 0;
+}
+
+printk("\n%s\n", pass ? "pass" : "ERROR");
+
+crypto_free_tfm(tfm);
+printk("crc32c test complete\n");
+}
+
+static void
test_available(void)
{
char **name = check;
@@ -558,7 +654,8 @@
test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
-test_deflate();
+test_deflate();
+test_crc32c();
#ifdef CONFIG_CRYPTO_HMAC
test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS);
@@ -638,6 +735,10 @@
test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template,
CAST6_DEC_TEST_VECTORS);
break;
Trang 3
+case 16:
+test_crc32c();
+break;
+
#ifdef CONFIG_CRYPTO_HMAC
case 100:
test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); diff -urN exclude '*.ko' exclude '*.mod.*' exclude '*~' exclude '*.o*' exclude '.*' exclude '*.cmd' exclude drivers
linux-2.6.1.orig/include/linux/crypto.h linux/include/linux/crypto.h
- linux-2.6.1.orig/include/linux/crypto.hFri Jan 9 00:59:19 2004
+++ linux/include/linux/crypto.hWed Jan 14 11:26:39 2004
@@ -30,7 +30,7 @@
#define CRYPTO_ALG_TYPE_CIPHER0x00000001
#define CRYPTO_ALG_TYPE_DIGEST0x00000002
#define CRYPTO_ALG_TYPE_COMPRESS0x00000004
-
+#define CRYPTO_ALG_TYPE_CHKSUM0x00000008
/*
* Transform masks and values (for crt_flags)
*/
@@ -87,9 +87,18 @@
u8 *dst, unsigned int *dlen);
};
+struct chksum_alg {
+unsigned int cha_digestsize;
+void (*cha_init)(void *ctx);
+void (*cha_setseed)(void *ctx, const u32 seed);
+void (*cha_update)(void *ctx, const u8 *data, unsigned int len);
+void (*cha_final)(void *ctx, u32 *out);
+};
+
#define cra_ciphercra_u.cipher
#define cra_digestcra_u.digest
#define cra_compresscra_u.compress
+#define cra_chksum cra_u.chksum
struct crypto_alg {
Trang 4struct list_head cra_list;
@@ -102,6 +111,7 @@
struct cipher_alg cipher;
struct digest_alg digest;
struct compress_alg compress;
+struct chksum_alg chksum;
} cra_u;
struct module *cra_module;
@@ -171,9 +181,23 @@
u8 *dst, unsigned int *dlen);
};
+/*
+ * Setting the seed allows arbitrary accumulators and flexible XOR policy + */
+struct chksum_tfm {
+void (*cht_init)(struct crypto_tfm *tfm); /* inits to ~0 */
+void (*cht_setseed)(struct crypto_tfm *tfm, const u32 seed);
+void (*cht_update)(struct crypto_tfm *tfm,
+ struct scatterlist *sg, unsigned int nsg);
+void (*cht_final)(struct crypto_tfm *tfm, u32 *out);
+void (*cht_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
+ unsigned int nsg, u32 *out);
+};
+
#define crt_ciphercrt_u.cipher
#define crt_digestcrt_u.digest
#define crt_compresscrt_u.compress
+#define crt_chksum crt_u.chksum
struct crypto_tfm {
@@ -183,6 +207,7 @@
struct cipher_tfm cipher;
struct digest_tfm digest;
struct compress_tfm compress;
+struct chksum_tfm chksum;
} crt_u;
Trang 5
struct crypto_alg * crt_alg;
@@ -357,6 +382,49 @@
return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen);
}
+static inline void crypto_chksum_init(struct crypto_tfm *tfm)
+{
+BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CHKSUM); +tfm->crt_chksum.cht_init(tfm);
+}
+
+/*
+ * If your algorithm normally inits with ~0, then you
+ * must XOR your seed with ~0 before calling setseed()
+ */
+static inline void crypto_chksum_setseed(struct crypto_tfm *tfm,
+ const u32 seed)
+{
+BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CHKSUM); +tfm->crt_chksum.cht_setseed(tfm, seed);
+}
+
+static inline void crypto_chksum_update(struct crypto_tfm *tfm,
+struct scatterlist *sg,
+unsigned int nsg)
+{
+BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CHKSUM); +tfm->crt_chksum.cht_update(tfm, sg, nsg);
+}
+
+/*
+ * This function will XOR the results with ~0, so take that into
+ * account
+ */
+static inline void crypto_chksum_final(struct crypto_tfm *tfm, u32 *out) +{
+BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CHKSUM); +tfm->crt_chksum.cht_final(tfm, out);