linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Add CRC32C chksums to crypto routines
@ 2004-01-14 21:31 Clay Haapala
  2004-01-14 21:45 ` James Morris
                   ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Clay Haapala @ 2004-01-14 21:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-scsi

[-- Attachment #1: Type: text/plain, Size: 768 bytes --]

This patch against 2.6.1 adds CRC32C checksumming capabilities to the
crypto routines.  The structure of it is based wholly on the existing
digest (md5) routines, the main difference being that chksums are
often used in an "accumulator" fashion, effectively requiring one to
set the seed, and the digest algorithms don't do that.

CRC32C is a 32-bit CRC variant used by the iSCSI protocol and in other
drivers.  iSCSI uses scatterlists, so it was strongly suggested by the
SCSI maintainers during reviews of Version 4 of the linux-iscsi driver
that the code be added to the crypto routines, which operate on
scatterlists.

Test routines have been added to tcrypt.c.

The linux-iscsi project can be found on SourceForge:
  http://sourceforge.net/projects/linux-iscsi/


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Adds CRC32C chksums to crypto routines --]
[-- Type: text/x-patch, Size: 20483 bytes --]

diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/Kconfig linux/crypto/Kconfig
--- linux-2.6.1.orig/crypto/Kconfig	Fri Jan  9 01:00:03 2004
+++ linux/crypto/Kconfig	Mon Jan 12 10:33:59 2004
@@ -22,6 +22,14 @@
 	help
 	  These are 'Null' algorithms, used by IPsec, which do nothing.
 
+config CRYPTO_CRC32C
+	tristate "CRC32c CRC algorithm"
+	depends on CRYPTO
+	help
+	  Castagnoli, et al Cyclic Redundancy-Check Algorithm.  Used
+	  by iSCSI for header and data digests and by others.
+	  See Castagnoli93.
+
 config CRYPTO_MD4
 	tristate "MD4 digest algorithm"
 	depends on CRYPTO
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/Makefile linux/crypto/Makefile
--- linux-2.6.1.orig/crypto/Makefile	Fri Jan  9 01:00:04 2004
+++ linux/crypto/Makefile	Mon Jan 12 10:33:59 2004
@@ -4,11 +4,12 @@
 
 proc-crypto-$(CONFIG_PROC_FS) = proc.o
 
-obj-$(CONFIG_CRYPTO) += api.o cipher.o digest.o compress.o \
+obj-$(CONFIG_CRYPTO) += api.o cipher.o digest.o compress.o chksum.o \
 			$(proc-crypto-y)
 
 obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
 obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
+obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
 obj-$(CONFIG_CRYPTO_MD4) += md4.o
 obj-$(CONFIG_CRYPTO_MD5) += md5.o
 obj-$(CONFIG_CRYPTO_SHA1) += sha1.o
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/api.c linux/crypto/api.c
--- linux-2.6.1.orig/crypto/api.c	Fri Jan  9 01:00:04 2004
+++ linux/crypto/api.c	Mon Jan 12 10:33:59 2004
@@ -68,6 +68,9 @@
 	case CRYPTO_ALG_TYPE_COMPRESS:
 		return crypto_init_compress_flags(tfm, flags);
 	
+	case CRYPTO_ALG_TYPE_CHKSUM:
+		return crypto_init_chksum_flags(tfm, flags);
+		
 	default:
 		break;
 	}
@@ -88,6 +91,9 @@
 	case CRYPTO_ALG_TYPE_COMPRESS:
 		return crypto_init_compress_ops(tfm);
 	
+	case CRYPTO_ALG_TYPE_CHKSUM:
+		return crypto_init_chksum_ops(tfm);
+		
 	default:
 		break;
 	}
@@ -111,6 +117,10 @@
 		crypto_exit_compress_ops(tfm);
 		break;
 	
+	case CRYPTO_ALG_TYPE_CHKSUM:
+		crypto_exit_chksum_ops(tfm);
+		break;
+		
 	default:
 		BUG();
 		
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/chksum.c linux/crypto/chksum.c
--- linux-2.6.1.orig/crypto/chksum.c	Wed Dec 31 18:00:00 1969
+++ linux/crypto/chksum.c	Mon Jan 12 10:33:59 2004
@@ -0,0 +1,89 @@
+/*
+ * Cryptographic API.
+ *
+ * Chksum/CRC operations.
+ *
+ * Copyright (c) 2003 Clay Haapala (clay@haapi.mn.org)
+ *   cribbed from digest code by James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/crypto.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/highmem.h>
+#include <asm/scatterlist.h>
+#include "internal.h"
+
+static void init(struct crypto_tfm *tfm)
+{
+	tfm->__crt_alg->cra_chksum.cha_init(crypto_tfm_ctx(tfm));
+}
+
+static void setseed(struct crypto_tfm *tfm, const u32 seed)
+{
+	tfm->__crt_alg->cra_chksum.cha_setseed(crypto_tfm_ctx(tfm), seed);
+}
+
+static void update(struct crypto_tfm *tfm,
+                   struct scatterlist *sg, unsigned int nsg)
+{
+	unsigned int i;
+	
+	for (i = 0; i < nsg; i++) {
+		char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
+		tfm->__crt_alg->cra_chksum.cha_update(crypto_tfm_ctx(tfm),
+		                                      p, sg[i].length);
+		crypto_kunmap(p, 0);
+		crypto_yield(tfm);
+	}
+}
+
+static void final(struct crypto_tfm *tfm, u32 *out)
+{
+	tfm->__crt_alg->cra_chksum.cha_final(crypto_tfm_ctx(tfm), out);
+}
+
+static void digest(struct crypto_tfm *tfm,
+                   struct scatterlist *sg, unsigned int nsg, u32 *out)
+{
+	unsigned int i;
+
+	tfm->crt_chksum.cht_init(tfm);
+		
+	for (i = 0; i < nsg; i++) {
+		char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
+		tfm->__crt_alg->cra_chksum.cha_update(crypto_tfm_ctx(tfm),
+		                                      p, sg[i].length);
+		crypto_kunmap(p, 0);
+		crypto_yield(tfm);
+	}
+	crypto_chksum_final(tfm, out);
+}
+
+int crypto_init_chksum_flags(struct crypto_tfm *tfm, u32 flags)
+{
+	return flags ? -EINVAL : 0;
+}
+
+int crypto_init_chksum_ops(struct crypto_tfm *tfm)
+{
+	struct chksum_tfm *ops = &tfm->crt_chksum;
+	
+	ops->cht_init	= init;
+	ops->cht_setseed = setseed;
+	ops->cht_update	= update;
+	ops->cht_final	= final;
+	ops->cht_digest	= digest;
+
+	return 0;
+}
+
+void crypto_exit_chksum_ops(struct crypto_tfm *tfm)
+{
+	return;
+}
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/crc32c.c linux/crypto/crc32c.c
--- linux-2.6.1.orig/crypto/crc32c.c	Wed Dec 31 18:00:00 1969
+++ linux/crypto/crc32c.c	Wed Jan 14 11:40:25 2004
@@ -0,0 +1,203 @@
+/* 
+ * Cryptographic API.
+ *
+ * CRC32C
+ *
+ *@Article{castagnoli-crc,
+ * author =       { Guy Castagnoli and Stefan Braeuer and Martin Herrman},
+ * title =        {{Optimization of Cyclic Redundancy-Check Codes with 24
+ *                 and 32 Parity Bits}},
+ * journal =      IEEE Transactions on Communication,
+ * year =         {1993},
+ * volume =       {41},
+ * number =       {6},
+ * pages =        {},
+ * month =        {June},
+ *}
+ * Used by the iSCSI driver, possibly others, and derived from the
+ * the iscsi-crc.c module of the linux-iscsi driver at
+ * http://linux-iscsi.sourceforge.net.
+ *
+ * Following the example of lib/crc32, this function is intended to be
+ * flexible and useful for all users.  Modules that currently have their
+ * own crc32c, but hopefully may be able to use this one are:
+ *  <ul>
+ *  <li>net/sctp (please add all your doco to here if you change to
+ *            use these routines)
+ *  </li>
+ *  </ul>
+ *
+ * Copyright (c) 2003 Cisco Systems, Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <asm/byteorder.h>
+
+#define CHKSUM_BLOCK_SIZE	32
+#define CHKSUM_DIGEST_SIZE	32
+
+struct chksum_ctx {
+	u32 crc;
+};
+
+/*
+ * This is the CRC-32C table
+ * Generated with:
+ * width = 32 bits
+ * poly = 0x1EDC6F41
+ * reflect input bytes = true
+ * reflect output bytes = true
+ */
+
+static u32 crc32c_table[256] = {
+	0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
+	0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
+	0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
+	0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
+	0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
+	0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
+	0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
+	0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
+	0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
+	0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
+	0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
+	0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
+	0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
+	0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
+	0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
+	0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
+	0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
+	0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
+	0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
+	0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
+	0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
+	0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
+	0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
+	0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
+	0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
+	0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
+	0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
+	0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
+	0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
+	0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
+	0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
+	0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
+	0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
+	0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
+	0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
+	0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
+	0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
+	0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
+	0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
+	0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
+	0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
+	0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
+	0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
+	0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
+	0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
+	0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
+	0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
+	0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
+	0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
+	0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
+	0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
+	0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
+	0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
+	0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
+	0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
+	0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
+	0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
+	0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
+	0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
+	0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
+	0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
+	0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
+	0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
+	0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
+};
+
+/*
+ * Steps through buffer one byte at at time, calculates reflected 
+ * crc using table.
+ */
+
+static void chksum_init(void *ctx)
+{
+	struct chksum_ctx *mctx = ctx;
+
+	mctx->crc = ~(u32)0;			/* common usage */
+}
+
+/*
+ * Setting the seed allows arbitrary accumulators and flexible XOR policy
+ * If your algorithm starts with ~0, then XOR with ~0 before you set
+ * the seed.
+ */
+static void chksum_setseed(void *ctx, const u32 seed)
+{
+	struct chksum_ctx *mctx = ctx;
+
+	mctx->crc = __cpu_to_le32(seed);
+}
+
+static void chksum_update(void *ctx, u8 const *data, size_t length)
+{
+	struct chksum_ctx *mctx = ctx;
+	u32 mcrc = mctx->crc;
+
+	while (length--)
+		mcrc = crc32c_table[(mcrc ^ *data++) & 0xFFL] ^ (mcrc >> 8);
+
+	mctx->crc = mcrc;
+}
+
+static void chksum_final(void *ctx, u32 *out)
+{
+	struct chksum_ctx *mctx = ctx;
+	u32 mcrc = (mctx->crc ^ ~(u32)0);
+	
+	*out = __le32_to_cpu(mcrc);
+}
+
+static struct crypto_alg alg = {
+	.cra_name	=	"crc32c",
+	.cra_flags	=	CRYPTO_ALG_TYPE_CHKSUM,
+	.cra_blocksize	=	CHKSUM_BLOCK_SIZE,
+	.cra_ctxsize	=	sizeof(struct chksum_ctx),
+	.cra_module	=	THIS_MODULE,
+	.cra_list	=	LIST_HEAD_INIT(alg.cra_list),
+	.cra_u		=	{
+		.chksum = {
+			 .cha_digestsize=	CHKSUM_DIGEST_SIZE,
+			 .cha_init   	= 	chksum_init,
+			 .cha_setseed	=	chksum_setseed,
+			 .cha_update 	=	chksum_update,
+			 .cha_final  	=	chksum_final
+		 }
+	}
+};
+
+static int __init init(void)
+{
+	return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
+MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations");
+MODULE_LICENSE("GPL and additional rights");
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/internal.h linux/crypto/internal.h
--- linux-2.6.1.orig/crypto/internal.h	Fri Jan  9 00:59:04 2004
+++ linux/crypto/internal.h	Mon Jan 12 10:33:59 2004
@@ -79,14 +79,17 @@
 int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
 int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
 int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
+int crypto_init_chksum_flags(struct crypto_tfm *tfm, u32 flags);
 
 int crypto_init_digest_ops(struct crypto_tfm *tfm);
 int crypto_init_cipher_ops(struct crypto_tfm *tfm);
 int crypto_init_compress_ops(struct crypto_tfm *tfm);
+int crypto_init_chksum_ops(struct crypto_tfm *tfm);
 
 void crypto_exit_digest_ops(struct crypto_tfm *tfm);
 void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
 void crypto_exit_compress_ops(struct crypto_tfm *tfm);
+void crypto_exit_chksum_ops(struct crypto_tfm *tfm);
 
 #endif	/* _CRYPTO_INTERNAL_H */
 
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/tcrypt.c linux/crypto/tcrypt.c
--- linux-2.6.1.orig/crypto/tcrypt.c	Fri Jan  9 00:59:56 2004
+++ linux/crypto/tcrypt.c	Wed Jan 14 11:43:12 2004
@@ -61,7 +61,7 @@
 static char *check[] = {
 	"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
 	"twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", 
-	"deflate", NULL
+	"deflate", "crc32c", NULL
 };
 
 static void
@@ -492,6 +492,102 @@
 }
 
 static void
+test_crc32c(void)
+{
+#define NUMVEC 6
+#define VECSIZE 40
+
+	int i, j, pass;
+	u32 crc;
+	u8 b, test_vec[NUMVEC][VECSIZE];
+	static u32 vec_results[NUMVEC] = {
+		0x0e2c157f, 0xe980ebf6, 0xde74bded,
+		0xd579c862, 0xba979ad0, 0x2b29d913
+	};
+	static u32 tot_vec_results = 0x24c5d375;
+	
+	struct scatterlist sg[NUMVEC];
+	struct crypto_tfm *tfm;
+	char *fmtdata = "testing crc32c initted to %08x: %s\n";
+#define SEEDTESTVAL 0xedcba987
+
+	printk("\ntesting crc32c\n");
+
+	tfm = crypto_alloc_tfm("crc32c", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for crc32c\n");
+		return;
+	}
+	
+	crypto_chksum_init(tfm);
+	crypto_chksum_final(tfm, &crc);
+	printk(fmtdata, crc, (crc == 0) ? "pass" : "ERROR");
+	
+	/*
+	 * stuff test_vec with known values, simple incrementing
+	 * byte values.
+	 */
+	b = 0;
+	for (i = 0; i < NUMVEC; i++) {
+		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 {
+		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;
 
+	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.h	Fri Jan  9 00:59:19 2004
+++ linux/include/linux/crypto.h	Wed Jan 14 11:26:39 2004
@@ -30,7 +30,7 @@
 #define CRYPTO_ALG_TYPE_CIPHER		0x00000001
 #define CRYPTO_ALG_TYPE_DIGEST		0x00000002
 #define CRYPTO_ALG_TYPE_COMPRESS	0x00000004
-
+#define CRYPTO_ALG_TYPE_CHKSUM		0x00000008
 /*
  * 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_cipher	cra_u.cipher
 #define cra_digest	cra_u.digest
 #define cra_compress	cra_u.compress
+#define cra_chksum    cra_u.chksum
 
 struct crypto_alg {
 	struct 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_cipher	crt_u.cipher
 #define crt_digest	crt_u.digest
 #define crt_compress	crt_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;
 	
 	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);
+}
+
+static inline void crypto_chksum_digest(struct crypto_tfm *tfm,
+					struct scatterlist *sg,
+					unsigned int nsg, u32 *out)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CHKSUM);
+	tfm->crt_chksum.cht_digest(tfm, sg, nsg, out);
+}
+
 /*
  * HMAC support.
  */

[-- Attachment #3: Type: text/plain, Size: 194 bytes --]

-- 
Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056
   6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD
	 Funny, I didn't think Haliburton was into aerospace.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH] Add CRC32C chksums to crypto routines
  2004-01-14 21:31 [PATCH] Add CRC32C chksums to crypto routines Clay Haapala
@ 2004-01-14 21:45 ` James Morris
  2004-01-14 22:12   ` Clay Haapala
  2004-01-16  1:40 ` Matt Mackall
  2004-01-19 20:13 ` James Morris
  2 siblings, 1 reply; 26+ messages in thread
From: James Morris @ 2004-01-14 21:45 UTC (permalink / raw)
  To: Clay Haapala; +Cc: linux-kernel, linux-scsi, David S. Miller

On Wed, 14 Jan 2004, Clay Haapala wrote:

> This patch against 2.6.1 adds CRC32C checksumming capabilities to the
> crypto routines.  The structure of it is based wholly on the existing
> digest (md5) routines, the main difference being that chksums are
> often used in an "accumulator" fashion, effectively requiring one to
> set the seed, and the digest algorithms don't do that.

This looks interesting; do you know of any other chksum algorithms which
might need to be implemented in the kernel?


- james
-- 
James Morris
<jmorris@redhat.com>



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH] Add CRC32C chksums to crypto routines
  2004-01-14 21:45 ` James Morris
@ 2004-01-14 22:12   ` Clay Haapala
  0 siblings, 0 replies; 26+ messages in thread
From: Clay Haapala @ 2004-01-14 22:12 UTC (permalink / raw)
  To: James Morris; +Cc: linux-kernel, linux-scsi, David S. Miller

On Wed, 14 Jan 2004, James Morris stated:
> On Wed, 14 Jan 2004, Clay Haapala wrote:
> 
>> This patch against 2.6.1 adds CRC32C checksumming capabilities to
>> the crypto routines.  The structure of it is based wholly on the
>> existing digest (md5) routines, the main difference being that
>> chksums are often used in an "accumulator" fashion, effectively
>> requiring one to set the seed, and the digest algorithms don't do
>> that.
> 
> This looks interesting; do you know of any other chksum algorithms
> which might need to be implemented in the kernel?
> 
I reference the one other user of CRC32C in my code, that would be the
sctp network driver, at this time.

Of course, there is library/crc32, which I did make an attempt to
implement companion code to it, but we really need the "work over
scatterlists" feature of the crypto routines.

I took the design goals the of the library/crc32 routines (flexible
XOR policy, flexible initial values) and tried to allow that in the
crypto chksum routines.  CRC32 could be moved into it, but the uses of
CRC32 are often quick accumulation over packet fragments, rather than
computing digests over scatterlists describing would can be many K of
data.
-- 
Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056
   6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD
	 Funny, I didn't think Haliburton was into aerospace.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH] Add CRC32C chksums to crypto routines
  2004-01-14 21:31 [PATCH] Add CRC32C chksums to crypto routines Clay Haapala
  2004-01-14 21:45 ` James Morris
@ 2004-01-16  1:40 ` Matt Mackall
  2004-01-19 20:13 ` James Morris
  2 siblings, 0 replies; 26+ messages in thread
From: Matt Mackall @ 2004-01-16  1:40 UTC (permalink / raw)
  To: Clay Haapala; +Cc: linux-kernel, linux-scsi

On Wed, Jan 14, 2004 at 03:31:10PM -0600, Clay Haapala wrote:
> This patch against 2.6.1 adds CRC32C checksumming capabilities to the
> crypto routines.  The structure of it is based wholly on the existing
> digest (md5) routines, the main difference being that chksums are
> often used in an "accumulator" fashion, effectively requiring one to
> set the seed, and the digest algorithms don't do that.
> 
> CRC32C is a 32-bit CRC variant used by the iSCSI protocol and in other
> drivers.  iSCSI uses scatterlists, so it was strongly suggested by the
> SCSI maintainers during reviews of Version 4 of the linux-iscsi driver
> that the code be added to the crypto routines, which operate on
> scatterlists.
> 
> Test routines have been added to tcrypt.c.
> 
> The linux-iscsi project can be found on SourceForge:
>   http://sourceforge.net/projects/linux-iscsi/

Clay!

The cryptoapi stuff seems sensible, but we've already got at least one
copy of the core crc32c code in the kernel at net/sctp/crc32c.c. It'd
be better to work with the sctp folks to push this into lib/crc32.c.
Handling multiple polynomials shouldn't be too painful there.

-- 
Matt Mackall : http://www.selenic.com : Linux development and consulting

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH] Add CRC32C chksums to crypto routines
  2004-01-14 21:31 [PATCH] Add CRC32C chksums to crypto routines Clay Haapala
  2004-01-14 21:45 ` James Morris
  2004-01-16  1:40 ` Matt Mackall
@ 2004-01-19 20:13 ` James Morris
  2004-01-19 21:15   ` Clay Haapala
  2 siblings, 1 reply; 26+ messages in thread
From: James Morris @ 2004-01-19 20:13 UTC (permalink / raw)
  To: Clay Haapala; +Cc: linux-kernel, linux-scsi, David S. Miller

On Wed, 14 Jan 2004, Clay Haapala wrote:

> This patch against 2.6.1 adds CRC32C checksumming capabilities to the
> crypto routines.  The structure of it is based wholly on the existing
> digest (md5) routines, the main difference being that chksums are
> often used in an "accumulator" fashion, effectively requiring one to
> set the seed, and the digest algorithms don't do that.

Looks good to me.


- James
-- 
James Morris
<jmorris@redhat.com>



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH] Add CRC32C chksums to crypto routines
  2004-01-19 20:13 ` James Morris
@ 2004-01-19 21:15   ` Clay Haapala
  2004-01-19 21:33     ` James Morris
  0 siblings, 1 reply; 26+ messages in thread
From: Clay Haapala @ 2004-01-19 21:15 UTC (permalink / raw)
  To: James Morris; +Cc: linux-kernel, linux-scsi, David S. Miller

On Mon, 19 Jan 2004, James Morris stated:
> On Wed, 14 Jan 2004, Clay Haapala wrote:
> 
>> This patch against 2.6.1 adds CRC32C checksumming capabilities to
>> the crypto routines.  The structure of it is based wholly on the
>> existing digest (md5) routines, the main difference being that
>> chksums are often used in an "accumulator" fashion, effectively
>> requiring one to set the seed, and the digest algorithms don't do
>> that.
> 
> Looks good to me.
> 
In other email, Matt Mackall suggested a slightly different
integration with the kernel that would allow more general usage of the
CRC32C.  His suggestion was to put the implementation under /lib, next
to the crc32 routines, and make the crypto routine a wrapper that calls
it.  Selecting the CRYPTO_CRC32C module would SELECT the lib CRC32C
module, in other words.

The benefit of this would be to allow easy usage by other routines
(with no premption side-affects, a concern Matt has) while still being
there for routines that process scatterlist.  And the table/code is
still in one place.

Patch to follow in a day or two, after I can test it.  Implementation
was simple.
-- 
Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056
   6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD
	 Funny, I didn't think Haliburton was into aerospace.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH] Add CRC32C chksums to crypto routines
  2004-01-19 21:15   ` Clay Haapala
@ 2004-01-19 21:33     ` James Morris
  2004-02-03 16:58       ` [PATCH 2.6.1] Add CRC32C chksums to crypto and lib routines Clay Haapala
  0 siblings, 1 reply; 26+ messages in thread
From: James Morris @ 2004-01-19 21:33 UTC (permalink / raw)
  To: Clay Haapala; +Cc: linux-kernel, linux-scsi, David S. Miller

On Mon, 19 Jan 2004, Clay Haapala wrote:

> In other email, Matt Mackall suggested a slightly different
> integration with the kernel that would allow more general usage of the
> CRC32C.  His suggestion was to put the implementation under /lib, next
> to the crc32 routines, and make the crypto routine a wrapper that calls
> it.  Selecting the CRYPTO_CRC32C module would SELECT the lib CRC32C
> module, in other words.
> 
> The benefit of this would be to allow easy usage by other routines
> (with no premption side-affects, a concern Matt has) while still being
> there for routines that process scatterlist.  And the table/code is
> still in one place.
> 
> Patch to follow in a day or two, after I can test it.  Implementation
> was simple.

Sounds good -- the inflate/deflate algorithms do this as well.


- James
-- 
James Morris
<jmorris@redhat.com>



^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 2.6.1] Add CRC32C chksums to crypto and lib routines
  2004-01-19 21:33     ` James Morris
@ 2004-02-03 16:58       ` Clay Haapala
  2004-02-03 17:09         ` James Morris
  2004-02-03 17:13         ` James Morris
  0 siblings, 2 replies; 26+ messages in thread
From: Clay Haapala @ 2004-02-03 16:58 UTC (permalink / raw)
  To: James Morris; +Cc: linux-kernel, linux-scsi, David S. Miller, mpm

[-- Attachment #1: Type: text/plain, Size: 1912 bytes --]

On Mon, 19 Jan 2004, James Morris verbalised:
> On Mon, 19 Jan 2004, Clay Haapala wrote:
> 
>> In other email, Matt Mackall suggested a slightly different
>> integration with the kernel that would allow more general usage of
>> the CRC32C.  His suggestion was to put the implementation under
>> /lib, next to the crc32 routines, and make the crypto routine a
>> wrapper that calls it.  Selecting the CRYPTO_CRC32C module would
>> SELECT the lib CRC32C module, in other words.
>> 
>> The benefit of this would be to allow easy usage by other routines
>> (with no premption side-affects, a concern Matt has) while still
>> being there for routines that process scatterlist.  And the
>> table/code is still in one place.
>> 
>> Patch to follow in a day or two, after I can test it.
>> Implementation was simple.
> 
> Sounds good -- the inflate/deflate algorithms do this as well.
> 
> 
> - James

A long "day or two", but here's a patch that implements the CRC32C
under lib, and has the crypto implementation as a wrapper for it.  The
crypto module is "crc32c.ko", and the lib module is "libcrc32c.ko".

While further work could meld the lib/crc32 and lib/crc32c routines to
vary by only the polynomial, this patch keeps them entirely separate.
I added an optional bit-wise routine, though, which doesn't require
the table, though (set CRC32C_LE_BITS = 1). The bit-wise is slower on
x86, but I agree, Matt, that on some architectures it may rock.

If this patch looks good, I'd like it accepted so we can submit code
iSCSI driver code that makes use of it.  This may be a good time,
since the crypto SHA code is getting a little scrutiny right now.

Regards,
-- 
Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056
   6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD
             Minnesota, a quite agreeable state.  Lately,
             Celsius and Fahrenheit have tended to agree.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Patch adds CRC32C lib and crypto modules for generic use --]
[-- Type: text/x-patch, Size: 24863 bytes --]

diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/Kconfig linux/crypto/Kconfig
--- linux-2.6.1.orig/crypto/Kconfig	Fri Jan  9 01:00:03 2004
+++ linux/crypto/Kconfig	Fri Jan 30 10:45:42 2004
@@ -22,6 +22,16 @@
 	help
 	  These are 'Null' algorithms, used by IPsec, which do nothing.
 
+config CRYPTO_CRC32C
+	tristate "CRC32c CRC algorithm"
+	depends on CRYPTO
+	select LIBCRC32C
+	help
+	  Castagnoli, et al Cyclic Redundancy-Check Algorithm.  Used
+	  by iSCSI for header and data digests and by others.
+	  See Castagnoli93.  This implementation uses lib/crc32c.
+          Module will be crc32c.
+
 config CRYPTO_MD4
 	tristate "MD4 digest algorithm"
 	depends on CRYPTO
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/Makefile linux/crypto/Makefile
--- linux-2.6.1.orig/crypto/Makefile	Fri Jan  9 01:00:04 2004
+++ linux/crypto/Makefile	Fri Jan 30 10:46:03 2004
@@ -4,11 +4,12 @@
 
 proc-crypto-$(CONFIG_PROC_FS) = proc.o
 
-obj-$(CONFIG_CRYPTO) += api.o cipher.o digest.o compress.o \
+obj-$(CONFIG_CRYPTO) += api.o cipher.o digest.o compress.o chksum.o \
 			$(proc-crypto-y)
 
 obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
 obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
+obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
 obj-$(CONFIG_CRYPTO_MD4) += md4.o
 obj-$(CONFIG_CRYPTO_MD5) += md5.o
 obj-$(CONFIG_CRYPTO_SHA1) += sha1.o
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/api.c linux/crypto/api.c
--- linux-2.6.1.orig/crypto/api.c	Fri Jan  9 01:00:04 2004
+++ linux/crypto/api.c	Mon Jan 12 10:33:59 2004
@@ -68,6 +68,9 @@
 	case CRYPTO_ALG_TYPE_COMPRESS:
 		return crypto_init_compress_flags(tfm, flags);
 	
+	case CRYPTO_ALG_TYPE_CHKSUM:
+		return crypto_init_chksum_flags(tfm, flags);
+		
 	default:
 		break;
 	}
@@ -88,6 +91,9 @@
 	case CRYPTO_ALG_TYPE_COMPRESS:
 		return crypto_init_compress_ops(tfm);
 	
+	case CRYPTO_ALG_TYPE_CHKSUM:
+		return crypto_init_chksum_ops(tfm);
+		
 	default:
 		break;
 	}
@@ -111,6 +117,10 @@
 		crypto_exit_compress_ops(tfm);
 		break;
 	
+	case CRYPTO_ALG_TYPE_CHKSUM:
+		crypto_exit_chksum_ops(tfm);
+		break;
+		
 	default:
 		BUG();
 		
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/chksum.c linux/crypto/chksum.c
--- linux-2.6.1.orig/crypto/chksum.c	Wed Dec 31 18:00:00 1969
+++ linux/crypto/chksum.c	Mon Jan 12 10:33:59 2004
@@ -0,0 +1,89 @@
+/*
+ * Cryptographic API.
+ *
+ * Chksum/CRC operations.
+ *
+ * Copyright (c) 2003 Clay Haapala (chaapala@cisco.com)
+ *   cribbed from digest code (c) by James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/crypto.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/highmem.h>
+#include <asm/scatterlist.h>
+#include "internal.h"
+
+static void init(struct crypto_tfm *tfm)
+{
+	tfm->__crt_alg->cra_chksum.cha_init(crypto_tfm_ctx(tfm));
+}
+
+static void setseed(struct crypto_tfm *tfm, const u32 seed)
+{
+	tfm->__crt_alg->cra_chksum.cha_setseed(crypto_tfm_ctx(tfm), seed);
+}
+
+static void update(struct crypto_tfm *tfm,
+                   struct scatterlist *sg, unsigned int nsg)
+{
+	unsigned int i;
+	
+	for (i = 0; i < nsg; i++) {
+		char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
+		tfm->__crt_alg->cra_chksum.cha_update(crypto_tfm_ctx(tfm),
+		                                      p, sg[i].length);
+		crypto_kunmap(p, 0);
+		crypto_yield(tfm);
+	}
+}
+
+static void final(struct crypto_tfm *tfm, u32 *out)
+{
+	tfm->__crt_alg->cra_chksum.cha_final(crypto_tfm_ctx(tfm), out);
+}
+
+static void digest(struct crypto_tfm *tfm,
+                   struct scatterlist *sg, unsigned int nsg, u32 *out)
+{
+	unsigned int i;
+
+	tfm->crt_chksum.cht_init(tfm);
+		
+	for (i = 0; i < nsg; i++) {
+		char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
+		tfm->__crt_alg->cra_chksum.cha_update(crypto_tfm_ctx(tfm),
+		                                      p, sg[i].length);
+		crypto_kunmap(p, 0);
+		crypto_yield(tfm);
+	}
+	crypto_chksum_final(tfm, out);
+}
+
+int crypto_init_chksum_flags(struct crypto_tfm *tfm, u32 flags)
+{
+	return flags ? -EINVAL : 0;
+}
+
+int crypto_init_chksum_ops(struct crypto_tfm *tfm)
+{
+	struct chksum_tfm *ops = &tfm->crt_chksum;
+	
+	ops->cht_init	= init;
+	ops->cht_setseed = setseed;
+	ops->cht_update	= update;
+	ops->cht_final	= final;
+	ops->cht_digest	= digest;
+
+	return 0;
+}
+
+void crypto_exit_chksum_ops(struct crypto_tfm *tfm)
+{
+	return;
+}
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/crc32c.c linux/crypto/crc32c.c
--- linux-2.6.1.orig/crypto/crc32c.c	Wed Dec 31 18:00:00 1969
+++ linux/crypto/crc32c.c	Fri Jan 16 14:27:35 2004
@@ -0,0 +1,103 @@
+/* 
+ * Cryptographic API.
+ *
+ * CRC32C chksum
+ *
+ * This file is a wrapper to invoke the lib/crc32c routines.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/crc32c.h>
+#include <asm/byteorder.h>
+
+#define CHKSUM_BLOCK_SIZE	32
+#define CHKSUM_DIGEST_SIZE	32
+
+struct chksum_ctx {
+	u32 crc;
+};
+
+/*
+ * Steps through buffer one byte at at time, calculates reflected 
+ * crc using table.
+ */
+
+static void chksum_init(void *ctx)
+{
+	struct chksum_ctx *mctx = ctx;
+
+	mctx->crc = ~(u32)0;			/* common usage */
+}
+
+/*
+ * Setting the seed allows arbitrary accumulators and flexible XOR policy
+ * If your algorithm starts with ~0, then XOR with ~0 before you set
+ * the seed.
+ */
+static void chksum_setseed(void *ctx, const u32 seed)
+{
+	struct chksum_ctx *mctx = ctx;
+
+	mctx->crc = __cpu_to_le32(seed);
+}
+
+static void chksum_update(void *ctx, u8 const *data, size_t length)
+{
+	struct chksum_ctx *mctx = ctx;
+	u32 mcrc;
+
+	mcrc = crc32c(mctx->crc, data, length);
+
+	mctx->crc = mcrc;
+}
+
+static void chksum_final(void *ctx, u32 *out)
+{
+	struct chksum_ctx *mctx = ctx;
+	u32 mcrc = (mctx->crc ^ ~(u32)0);
+	
+	*out = __le32_to_cpu(mcrc);
+}
+
+static struct crypto_alg alg = {
+	.cra_name	=	"crc32c",
+	.cra_flags	=	CRYPTO_ALG_TYPE_CHKSUM,
+	.cra_blocksize	=	CHKSUM_BLOCK_SIZE,
+	.cra_ctxsize	=	sizeof(struct chksum_ctx),
+	.cra_module	=	THIS_MODULE,
+	.cra_list	=	LIST_HEAD_INIT(alg.cra_list),
+	.cra_u		=	{
+		.chksum = {
+			 .cha_digestsize=	CHKSUM_DIGEST_SIZE,
+			 .cha_init   	= 	chksum_init,
+			 .cha_setseed	=	chksum_setseed,
+			 .cha_update 	=	chksum_update,
+			 .cha_final  	=	chksum_final
+		 }
+	}
+};
+
+static int __init init(void)
+{
+	return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
+MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
+MODULE_LICENSE("GPL and additional rights");
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/internal.h linux/crypto/internal.h
--- linux-2.6.1.orig/crypto/internal.h	Fri Jan  9 00:59:04 2004
+++ linux/crypto/internal.h	Mon Jan 12 10:33:59 2004
@@ -79,14 +79,17 @@
 int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
 int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
 int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
+int crypto_init_chksum_flags(struct crypto_tfm *tfm, u32 flags);
 
 int crypto_init_digest_ops(struct crypto_tfm *tfm);
 int crypto_init_cipher_ops(struct crypto_tfm *tfm);
 int crypto_init_compress_ops(struct crypto_tfm *tfm);
+int crypto_init_chksum_ops(struct crypto_tfm *tfm);
 
 void crypto_exit_digest_ops(struct crypto_tfm *tfm);
 void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
 void crypto_exit_compress_ops(struct crypto_tfm *tfm);
+void crypto_exit_chksum_ops(struct crypto_tfm *tfm);
 
 #endif	/* _CRYPTO_INTERNAL_H */
 
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/tcrypt.c linux/crypto/tcrypt.c
--- linux-2.6.1.orig/crypto/tcrypt.c	Fri Jan  9 00:59:56 2004
+++ linux/crypto/tcrypt.c	Wed Jan 14 11:43:12 2004
@@ -61,7 +61,7 @@
 static char *check[] = {
 	"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
 	"twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", 
-	"deflate", NULL
+	"deflate", "crc32c", NULL
 };
 
 static void
@@ -492,6 +492,102 @@
 }
 
 static void
+test_crc32c(void)
+{
+#define NUMVEC 6
+#define VECSIZE 40
+
+	int i, j, pass;
+	u32 crc;
+	u8 b, test_vec[NUMVEC][VECSIZE];
+	static u32 vec_results[NUMVEC] = {
+		0x0e2c157f, 0xe980ebf6, 0xde74bded,
+		0xd579c862, 0xba979ad0, 0x2b29d913
+	};
+	static u32 tot_vec_results = 0x24c5d375;
+	
+	struct scatterlist sg[NUMVEC];
+	struct crypto_tfm *tfm;
+	char *fmtdata = "testing crc32c initted to %08x: %s\n";
+#define SEEDTESTVAL 0xedcba987
+
+	printk("\ntesting crc32c\n");
+
+	tfm = crypto_alloc_tfm("crc32c", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for crc32c\n");
+		return;
+	}
+	
+	crypto_chksum_init(tfm);
+	crypto_chksum_final(tfm, &crc);
+	printk(fmtdata, crc, (crc == 0) ? "pass" : "ERROR");
+	
+	/*
+	 * stuff test_vec with known values, simple incrementing
+	 * byte values.
+	 */
+	b = 0;
+	for (i = 0; i < NUMVEC; i++) {
+		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 {
+		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;
 
+	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/lib/Kconfig linux/lib/Kconfig
--- linux-2.6.1.orig/lib/Kconfig	Fri Jan  9 00:59:44 2004
+++ linux/lib/Kconfig	Fri Jan 30 10:46:38 2004
@@ -12,6 +12,14 @@
 	  kernel tree does. Such modules that use library CRC32 functions
 	  require M here.
 
+config LIBCRC32C
+	tristate "CRC32c (Castagnoli, et al) Cyclic Redundancy-Check"
+	help
+	  This option is provided for the case where no in-kernel-tree
+	  modules require CRC32c functions, but a module built outside the
+	  kernel tree does. Such modules that use library CRC32c functions
+	  require M here.  See Castagnoli93.
+
 #
 # compression support is select'ed if needed
 #
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/lib/Makefile linux/lib/Makefile
--- linux-2.6.1.orig/lib/Makefile	Fri Jan  9 00:59:06 2004
+++ linux/lib/Makefile	Fri Jan 30 10:46:58 2004
@@ -15,6 +15,7 @@
 endif
 
 obj-$(CONFIG_CRC32)	+= crc32.o
+obj-$(CONFIG_LIBCRC32C)	+= libcrc32c.o
 
 obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/
 obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/lib/libcrc32c.c linux/lib/libcrc32c.c
--- linux-2.6.1.orig/lib/libcrc32c.c	Wed Dec 31 18:00:00 1969
+++ linux/lib/libcrc32c.c	Mon Feb  2 17:00:07 2004
@@ -0,0 +1,205 @@
+/* 
+ * CRC32C
+ *@Article{castagnoli-crc,
+ * author =       { Guy Castagnoli and Stefan Braeuer and Martin Herrman},
+ * title =        {{Optimization of Cyclic Redundancy-Check Codes with 24
+ *                 and 32 Parity Bits}},
+ * journal =      IEEE Transactions on Communication,
+ * year =         {1993},
+ * volume =       {41},
+ * number =       {6},
+ * pages =        {},
+ * month =        {June},
+ *}
+ * Used by the iSCSI driver, possibly others, and derived from the
+ * the iscsi-crc.c module of the linux-iscsi driver at
+ * http://linux-iscsi.sourceforge.net.
+ *
+ * Following the example of lib/crc32, this function is intended to be
+ * flexible and useful for all users.  Modules that currently have their
+ * own crc32c, but hopefully may be able to use this one are:
+ *  net/sctp (please add all your doco to here if you change to
+ *            use this one!)
+ *  <endoflist>
+ *
+ * Copyright (c) 2003 Cisco Systems, Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/crc32c.h>
+#include <linux/module.h>
+#include <asm/byteorder.h>
+
+MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
+MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations");
+MODULE_LICENSE("GPL and additional rights");
+
+#if __GNUC__ >= 3	/* 2.x has "attribute", but only 3.0 has "pure */
+#define attribute(x) __attribute__(x)
+#else
+#define attribute(x)
+#endif
+
+#define CRC32C_POLY_BE 0x1EDC6F41
+#define CRC32C_POLY_LE 0x82F63B78
+
+#ifndef CRC_LE_BITS 
+# define CRC_LE_BITS 8
+#endif
+
+
+/*
+ * Haven't generated a big-endian table yet, but the bit-wise version
+ * should at least work.
+ */
+#ifdef CRC_BE_BITS
+#undef CRC_BE_BITS
+#endif
+#ifndef CRC_BE_BITS
+# define CRC_BE_BITS 1
+#endif
+
+EXPORT_SYMBOL(crc32c_le);
+
+#if CRC_LE_BITS == 1
+/*
+ * Compute things bit-wise, as done in crc32.c.  We could share the tight 
+ * loop below with crc32 and vary the POLY if we don't find value in terms
+ * of space and maintainability in keeping the two modules separate.
+ */
+u32 attribute((pure))
+crc32c_le(u32 crc, unsigned char const *p, size_t len)
+{
+	int i;
+	while (len--) {
+		crc ^= *p++;
+		for (i = 0; i < 8; i++)
+			crc = (crc >> 1) ^ ((crc & 1) ? CRC32C_POLY_LE : 0);
+	}
+	return crc;
+}
+#else
+
+/*
+ * This is the CRC-32C table
+ * Generated with:
+ * width = 32 bits
+ * poly = 0x1EDC6F41
+ * reflect input bytes = true
+ * reflect output bytes = true
+ */
+
+static u32 crc32c_table[256] = {
+	0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
+	0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
+	0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
+	0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
+	0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
+	0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
+	0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
+	0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
+	0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
+	0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
+	0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
+	0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
+	0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
+	0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
+	0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
+	0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
+	0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
+	0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
+	0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
+	0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
+	0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
+	0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
+	0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
+	0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
+	0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
+	0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
+	0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
+	0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
+	0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
+	0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
+	0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
+	0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
+	0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
+	0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
+	0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
+	0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
+	0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
+	0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
+	0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
+	0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
+	0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
+	0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
+	0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
+	0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
+	0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
+	0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
+	0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
+	0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
+	0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
+	0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
+	0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
+	0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
+	0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
+	0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
+	0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
+	0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
+	0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
+	0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
+	0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
+	0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
+	0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
+	0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
+	0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
+	0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
+};
+
+/*
+ * Steps through buffer one byte at at time, calculates reflected 
+ * crc using table.
+ */
+
+u32 attribute((pure))
+crc32c_le(u32 seed, unsigned char const *data, size_t length)
+{
+	u32 crc = __cpu_to_le32(seed);
+	
+	while (length--)
+		crc =
+		    crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
+
+	return __le32_to_cpu(crc);
+}
+
+#endif	/* CRC_LE_BITS == 8 */
+
+/*EXPORT_SYMBOL(crc32c_be);*/
+
+#if CRC_BE_BITS == 1
+u32 attribute((pure))
+crc32_be(u32 crc, unsigned char const *p, size_t len)
+{
+	int i;
+	while (len--) {
+		crc ^= *p++ << 24;
+		for (i = 0; i < 8; i++)
+			crc =
+			    (crc << 1) ^ ((crc & 0x80000000) ? CRC32C_POLY_BE :
+					  0);
+	}
+	return crc;
+}
+#endif
+
+/*
+ * Unit test
+ *
+ * A small unit test suite is implemented as part of the crypto suite.
+ * Select CRYPTO_CRC32C and use the tcrypt module to run the tests.
+ */
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/include/linux/crc32c.h linux/include/linux/crc32c.h
--- linux-2.6.1.orig/include/linux/crc32c.h	Wed Dec 31 18:00:00 1969
+++ linux/include/linux/crc32c.h	Mon Feb  2 16:33:20 2004
@@ -0,0 +1,11 @@
+#ifndef _LINUX_CRC32C_H
+#define _LINUX_CRC32C_H
+
+#include <linux/types.h>
+
+extern u32 crc32c_le(u32 crc, unsigned char const *address, size_t length);
+extern u32 crc32c_be(u32 crc, unsigned char const *address, size_t length);
+
+#define crc32c(seed, data, length)  crc32c_le(seed, (unsigned char const *)data, length)
+
+#endif	/* _LINUX_CRC32C_H */
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.h	Fri Jan  9 00:59:19 2004
+++ linux/include/linux/crypto.h	Wed Jan 14 11:26:39 2004
@@ -30,7 +30,7 @@
 #define CRYPTO_ALG_TYPE_CIPHER		0x00000001
 #define CRYPTO_ALG_TYPE_DIGEST		0x00000002
 #define CRYPTO_ALG_TYPE_COMPRESS	0x00000004
-
+#define CRYPTO_ALG_TYPE_CHKSUM		0x00000008
 /*
  * 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_cipher	cra_u.cipher
 #define cra_digest	cra_u.digest
 #define cra_compress	cra_u.compress
+#define cra_chksum    cra_u.chksum
 
 struct crypto_alg {
 	struct 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_cipher	crt_u.cipher
 #define crt_digest	crt_u.digest
 #define crt_compress	crt_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;
 	
 	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 c

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1] Add CRC32C chksums to crypto and lib routines
  2004-02-03 16:58       ` [PATCH 2.6.1] Add CRC32C chksums to crypto and lib routines Clay Haapala
@ 2004-02-03 17:09         ` James Morris
  2004-02-04 17:07           ` Clay Haapala
  2004-02-03 17:13         ` James Morris
  1 sibling, 1 reply; 26+ messages in thread
From: James Morris @ 2004-02-03 17:09 UTC (permalink / raw)
  To: Clay Haapala; +Cc: linux-kernel, linux-scsi, David S. Miller, mpm

On Tue, 3 Feb 2004, Clay Haapala wrote:

> If this patch looks good, I'd like it accepted so we can submit code
> iSCSI driver code that makes use of it.  This may be a good time,
> since the crypto SHA code is getting a little scrutiny right now.

This will need to wait until 2.6.2 is released, and will you also please 
submit the iSCSI change for review?

Thanks,


- James
-- 
James Morris
<jmorris@redhat.com>



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1] Add CRC32C chksums to crypto and lib routines
  2004-02-03 16:58       ` [PATCH 2.6.1] Add CRC32C chksums to crypto and lib routines Clay Haapala
  2004-02-03 17:09         ` James Morris
@ 2004-02-03 17:13         ` James Morris
  2004-02-03 17:50           ` [PATCH 2.6.1 -- take two] " Clay Haapala
  1 sibling, 1 reply; 26+ messages in thread
From: James Morris @ 2004-02-03 17:13 UTC (permalink / raw)
  To: Clay Haapala; +Cc: linux-kernel, linux-scsi, David S. Miller, mpm

On Tue, 3 Feb 2004, Clay Haapala wrote:

The patch looks malformed:

+/*
+ * This function will XOR the results with ~0, so take that into
+ * account.
+ */
+static inline void c



- James
-- 
James Morris
<jmorris@redhat.com>



^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 2.6.1 -- take two] Add CRC32C chksums to crypto and lib routines
  2004-02-03 17:13         ` James Morris
@ 2004-02-03 17:50           ` Clay Haapala
  2004-02-03 18:51             ` Matt Mackall
  0 siblings, 1 reply; 26+ messages in thread
From: Clay Haapala @ 2004-02-03 17:50 UTC (permalink / raw)
  To: James Morris; +Cc: Clay Haapala, linux-kernel, linux-scsi, David S. Miller, mpm

On Tue, Feb 03, 2004 at 12:13:34PM -0500, James Morris wrote:
> Date: Tue, 3 Feb 2004 12:13:34 -0500 (EST)
> From: James Morris <jmorris@redhat.com>
> To: Clay Haapala <chaapala@cisco.com>
> cc: linux-kernel@vger.kernel.org, <linux-scsi@vger.kernel.org>,
>         "David S. Miller" <davem@redhat.com>, <mpm@selenic.com>
> Subject: Re: [PATCH 2.6.1] Add CRC32C chksums to crypto and lib routines
> 
> On Tue, 3 Feb 2004, Clay Haapala wrote:
> 
> The patch looks malformed:
> 
> +/*
> + * This function will XOR the results with ~0, so take that into
> + * account.
> + */
> +static inline void c
> 
Very strange.  I saved the attachment (my apologies for it being an
attachment -- Gnus fooled me) and looked at the line above and it is
OK.  I am resending this patch from mutt, hopefully in-line this time.
--
Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056
   6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD
 The marketing flacks who thought the Super Bowl half-time show was the
 best way to reach 25-49-year-old males obviously surf a little too
 much Internet pr0n and read a bit much into the spam they receive.

diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/Kconfig linux/crypto/Kconfig
--- linux-2.6.1.orig/crypto/Kconfig	Fri Jan  9 01:00:03 2004
+++ linux/crypto/Kconfig	Fri Jan 30 10:45:42 2004
@@ -22,6 +22,16 @@
 	help
 	  These are 'Null' algorithms, used by IPsec, which do nothing.
 
+config CRYPTO_CRC32C
+	tristate "CRC32c CRC algorithm"
+	depends on CRYPTO
+	select LIBCRC32C
+	help
+	  Castagnoli, et al Cyclic Redundancy-Check Algorithm.  Used
+	  by iSCSI for header and data digests and by others.
+	  See Castagnoli93.  This implementation uses lib/crc32c.
+          Module will be crc32c.
+
 config CRYPTO_MD4
 	tristate "MD4 digest algorithm"
 	depends on CRYPTO
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/Makefile linux/crypto/Makefile
--- linux-2.6.1.orig/crypto/Makefile	Fri Jan  9 01:00:04 2004
+++ linux/crypto/Makefile	Fri Jan 30 10:46:03 2004
@@ -4,11 +4,12 @@
 
 proc-crypto-$(CONFIG_PROC_FS) = proc.o
 
-obj-$(CONFIG_CRYPTO) += api.o cipher.o digest.o compress.o \
+obj-$(CONFIG_CRYPTO) += api.o cipher.o digest.o compress.o chksum.o \
 			$(proc-crypto-y)
 
 obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
 obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
+obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
 obj-$(CONFIG_CRYPTO_MD4) += md4.o
 obj-$(CONFIG_CRYPTO_MD5) += md5.o
 obj-$(CONFIG_CRYPTO_SHA1) += sha1.o
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/api.c linux/crypto/api.c
--- linux-2.6.1.orig/crypto/api.c	Fri Jan  9 01:00:04 2004
+++ linux/crypto/api.c	Mon Jan 12 10:33:59 2004
@@ -68,6 +68,9 @@
 	case CRYPTO_ALG_TYPE_COMPRESS:
 		return crypto_init_compress_flags(tfm, flags);
 	
+	case CRYPTO_ALG_TYPE_CHKSUM:
+		return crypto_init_chksum_flags(tfm, flags);
+		
 	default:
 		break;
 	}
@@ -88,6 +91,9 @@
 	case CRYPTO_ALG_TYPE_COMPRESS:
 		return crypto_init_compress_ops(tfm);
 	
+	case CRYPTO_ALG_TYPE_CHKSUM:
+		return crypto_init_chksum_ops(tfm);
+		
 	default:
 		break;
 	}
@@ -111,6 +117,10 @@
 		crypto_exit_compress_ops(tfm);
 		break;
 	
+	case CRYPTO_ALG_TYPE_CHKSUM:
+		crypto_exit_chksum_ops(tfm);
+		break;
+		
 	default:
 		BUG();
 		
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/chksum.c linux/crypto/chksum.c
--- linux-2.6.1.orig/crypto/chksum.c	Wed Dec 31 18:00:00 1969
+++ linux/crypto/chksum.c	Mon Jan 12 10:33:59 2004
@@ -0,0 +1,89 @@
+/*
+ * Cryptographic API.
+ *
+ * Chksum/CRC operations.
+ *
+ * Copyright (c) 2003 Clay Haapala (chaapala@cisco.com)
+ *   cribbed from digest code (c) by James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/crypto.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/highmem.h>
+#include <asm/scatterlist.h>
+#include "internal.h"
+
+static void init(struct crypto_tfm *tfm)
+{
+	tfm->__crt_alg->cra_chksum.cha_init(crypto_tfm_ctx(tfm));
+}
+
+static void setseed(struct crypto_tfm *tfm, const u32 seed)
+{
+	tfm->__crt_alg->cra_chksum.cha_setseed(crypto_tfm_ctx(tfm), seed);
+}
+
+static void update(struct crypto_tfm *tfm,
+                   struct scatterlist *sg, unsigned int nsg)
+{
+	unsigned int i;
+	
+	for (i = 0; i < nsg; i++) {
+		char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
+		tfm->__crt_alg->cra_chksum.cha_update(crypto_tfm_ctx(tfm),
+		                                      p, sg[i].length);
+		crypto_kunmap(p, 0);
+		crypto_yield(tfm);
+	}
+}
+
+static void final(struct crypto_tfm *tfm, u32 *out)
+{
+	tfm->__crt_alg->cra_chksum.cha_final(crypto_tfm_ctx(tfm), out);
+}
+
+static void digest(struct crypto_tfm *tfm,
+                   struct scatterlist *sg, unsigned int nsg, u32 *out)
+{
+	unsigned int i;
+
+	tfm->crt_chksum.cht_init(tfm);
+		
+	for (i = 0; i < nsg; i++) {
+		char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
+		tfm->__crt_alg->cra_chksum.cha_update(crypto_tfm_ctx(tfm),
+		                                      p, sg[i].length);
+		crypto_kunmap(p, 0);
+		crypto_yield(tfm);
+	}
+	crypto_chksum_final(tfm, out);
+}
+
+int crypto_init_chksum_flags(struct crypto_tfm *tfm, u32 flags)
+{
+	return flags ? -EINVAL : 0;
+}
+
+int crypto_init_chksum_ops(struct crypto_tfm *tfm)
+{
+	struct chksum_tfm *ops = &tfm->crt_chksum;
+	
+	ops->cht_init	= init;
+	ops->cht_setseed = setseed;
+	ops->cht_update	= update;
+	ops->cht_final	= final;
+	ops->cht_digest	= digest;
+
+	return 0;
+}
+
+void crypto_exit_chksum_ops(struct crypto_tfm *tfm)
+{
+	return;
+}
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/crc32c.c linux/crypto/crc32c.c
--- linux-2.6.1.orig/crypto/crc32c.c	Wed Dec 31 18:00:00 1969
+++ linux/crypto/crc32c.c	Fri Jan 16 14:27:35 2004
@@ -0,0 +1,103 @@
+/* 
+ * Cryptographic API.
+ *
+ * CRC32C chksum
+ *
+ * This file is a wrapper to invoke the lib/crc32c routines.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/crc32c.h>
+#include <asm/byteorder.h>
+
+#define CHKSUM_BLOCK_SIZE	32
+#define CHKSUM_DIGEST_SIZE	32
+
+struct chksum_ctx {
+	u32 crc;
+};
+
+/*
+ * Steps through buffer one byte at at time, calculates reflected 
+ * crc using table.
+ */
+
+static void chksum_init(void *ctx)
+{
+	struct chksum_ctx *mctx = ctx;
+
+	mctx->crc = ~(u32)0;			/* common usage */
+}
+
+/*
+ * Setting the seed allows arbitrary accumulators and flexible XOR policy
+ * If your algorithm starts with ~0, then XOR with ~0 before you set
+ * the seed.
+ */
+static void chksum_setseed(void *ctx, const u32 seed)
+{
+	struct chksum_ctx *mctx = ctx;
+
+	mctx->crc = __cpu_to_le32(seed);
+}
+
+static void chksum_update(void *ctx, u8 const *data, size_t length)
+{
+	struct chksum_ctx *mctx = ctx;
+	u32 mcrc;
+
+	mcrc = crc32c(mctx->crc, data, length);
+
+	mctx->crc = mcrc;
+}
+
+static void chksum_final(void *ctx, u32 *out)
+{
+	struct chksum_ctx *mctx = ctx;
+	u32 mcrc = (mctx->crc ^ ~(u32)0);
+	
+	*out = __le32_to_cpu(mcrc);
+}
+
+static struct crypto_alg alg = {
+	.cra_name	=	"crc32c",
+	.cra_flags	=	CRYPTO_ALG_TYPE_CHKSUM,
+	.cra_blocksize	=	CHKSUM_BLOCK_SIZE,
+	.cra_ctxsize	=	sizeof(struct chksum_ctx),
+	.cra_module	=	THIS_MODULE,
+	.cra_list	=	LIST_HEAD_INIT(alg.cra_list),
+	.cra_u		=	{
+		.chksum = {
+			 .cha_digestsize=	CHKSUM_DIGEST_SIZE,
+			 .cha_init   	= 	chksum_init,
+			 .cha_setseed	=	chksum_setseed,
+			 .cha_update 	=	chksum_update,
+			 .cha_final  	=	chksum_final
+		 }
+	}
+};
+
+static int __init init(void)
+{
+	return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
+MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
+MODULE_LICENSE("GPL and additional rights");
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/internal.h linux/crypto/internal.h
--- linux-2.6.1.orig/crypto/internal.h	Fri Jan  9 00:59:04 2004
+++ linux/crypto/internal.h	Mon Jan 12 10:33:59 2004
@@ -79,14 +79,17 @@
 int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
 int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
 int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
+int crypto_init_chksum_flags(struct crypto_tfm *tfm, u32 flags);
 
 int crypto_init_digest_ops(struct crypto_tfm *tfm);
 int crypto_init_cipher_ops(struct crypto_tfm *tfm);
 int crypto_init_compress_ops(struct crypto_tfm *tfm);
+int crypto_init_chksum_ops(struct crypto_tfm *tfm);
 
 void crypto_exit_digest_ops(struct crypto_tfm *tfm);
 void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
 void crypto_exit_compress_ops(struct crypto_tfm *tfm);
+void crypto_exit_chksum_ops(struct crypto_tfm *tfm);
 
 #endif	/* _CRYPTO_INTERNAL_H */
 
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/crypto/tcrypt.c linux/crypto/tcrypt.c
--- linux-2.6.1.orig/crypto/tcrypt.c	Fri Jan  9 00:59:56 2004
+++ linux/crypto/tcrypt.c	Wed Jan 14 11:43:12 2004
@@ -61,7 +61,7 @@
 static char *check[] = {
 	"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
 	"twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", 
-	"deflate", NULL
+	"deflate", "crc32c", NULL
 };
 
 static void
@@ -492,6 +492,102 @@
 }
 
 static void
+test_crc32c(void)
+{
+#define NUMVEC 6
+#define VECSIZE 40
+
+	int i, j, pass;
+	u32 crc;
+	u8 b, test_vec[NUMVEC][VECSIZE];
+	static u32 vec_results[NUMVEC] = {
+		0x0e2c157f, 0xe980ebf6, 0xde74bded,
+		0xd579c862, 0xba979ad0, 0x2b29d913
+	};
+	static u32 tot_vec_results = 0x24c5d375;
+	
+	struct scatterlist sg[NUMVEC];
+	struct crypto_tfm *tfm;
+	char *fmtdata = "testing crc32c initted to %08x: %s\n";
+#define SEEDTESTVAL 0xedcba987
+
+	printk("\ntesting crc32c\n");
+
+	tfm = crypto_alloc_tfm("crc32c", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for crc32c\n");
+		return;
+	}
+	
+	crypto_chksum_init(tfm);
+	crypto_chksum_final(tfm, &crc);
+	printk(fmtdata, crc, (crc == 0) ? "pass" : "ERROR");
+	
+	/*
+	 * stuff test_vec with known values, simple incrementing
+	 * byte values.
+	 */
+	b = 0;
+	for (i = 0; i < NUMVEC; i++) {
+		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 {
+		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;
 
+	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/lib/Kconfig linux/lib/Kconfig
--- linux-2.6.1.orig/lib/Kconfig	Fri Jan  9 00:59:44 2004
+++ linux/lib/Kconfig	Fri Jan 30 10:46:38 2004
@@ -12,6 +12,14 @@
 	  kernel tree does. Such modules that use library CRC32 functions
 	  require M here.
 
+config LIBCRC32C
+	tristate "CRC32c (Castagnoli, et al) Cyclic Redundancy-Check"
+	help
+	  This option is provided for the case where no in-kernel-tree
+	  modules require CRC32c functions, but a module built outside the
+	  kernel tree does. Such modules that use library CRC32c functions
+	  require M here.  See Castagnoli93.
+
 #
 # compression support is select'ed if needed
 #
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/lib/Makefile linux/lib/Makefile
--- linux-2.6.1.orig/lib/Makefile	Fri Jan  9 00:59:06 2004
+++ linux/lib/Makefile	Fri Jan 30 10:46:58 2004
@@ -15,6 +15,7 @@
 endif
 
 obj-$(CONFIG_CRC32)	+= crc32.o
+obj-$(CONFIG_LIBCRC32C)	+= libcrc32c.o
 
 obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/
 obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/lib/libcrc32c.c linux/lib/libcrc32c.c
--- linux-2.6.1.orig/lib/libcrc32c.c	Wed Dec 31 18:00:00 1969
+++ linux/lib/libcrc32c.c	Mon Feb  2 17:00:07 2004
@@ -0,0 +1,205 @@
+/* 
+ * CRC32C
+ *@Article{castagnoli-crc,
+ * author =       { Guy Castagnoli and Stefan Braeuer and Martin Herrman},
+ * title =        {{Optimization of Cyclic Redundancy-Check Codes with 24
+ *                 and 32 Parity Bits}},
+ * journal =      IEEE Transactions on Communication,
+ * year =         {1993},
+ * volume =       {41},
+ * number =       {6},
+ * pages =        {},
+ * month =        {June},
+ *}
+ * Used by the iSCSI driver, possibly others, and derived from the
+ * the iscsi-crc.c module of the linux-iscsi driver at
+ * http://linux-iscsi.sourceforge.net.
+ *
+ * Following the example of lib/crc32, this function is intended to be
+ * flexible and useful for all users.  Modules that currently have their
+ * own crc32c, but hopefully may be able to use this one are:
+ *  net/sctp (please add all your doco to here if you change to
+ *            use this one!)
+ *  <endoflist>
+ *
+ * Copyright (c) 2003 Cisco Systems, Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/crc32c.h>
+#include <linux/module.h>
+#include <asm/byteorder.h>
+
+MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
+MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations");
+MODULE_LICENSE("GPL and additional rights");
+
+#if __GNUC__ >= 3	/* 2.x has "attribute", but only 3.0 has "pure */
+#define attribute(x) __attribute__(x)
+#else
+#define attribute(x)
+#endif
+
+#define CRC32C_POLY_BE 0x1EDC6F41
+#define CRC32C_POLY_LE 0x82F63B78
+
+#ifndef CRC_LE_BITS 
+# define CRC_LE_BITS 8
+#endif
+
+
+/*
+ * Haven't generated a big-endian table yet, but the bit-wise version
+ * should at least work.
+ */
+#ifdef CRC_BE_BITS
+#undef CRC_BE_BITS
+#endif
+#ifndef CRC_BE_BITS
+# define CRC_BE_BITS 1
+#endif
+
+EXPORT_SYMBOL(crc32c_le);
+
+#if CRC_LE_BITS == 1
+/*
+ * Compute things bit-wise, as done in crc32.c.  We could share the tight 
+ * loop below with crc32 and vary the POLY if we don't find value in terms
+ * of space and maintainability in keeping the two modules separate.
+ */
+u32 attribute((pure))
+crc32c_le(u32 crc, unsigned char const *p, size_t len)
+{
+	int i;
+	while (len--) {
+		crc ^= *p++;
+		for (i = 0; i < 8; i++)
+			crc = (crc >> 1) ^ ((crc & 1) ? CRC32C_POLY_LE : 0);
+	}
+	return crc;
+}
+#else
+
+/*
+ * This is the CRC-32C table
+ * Generated with:
+ * width = 32 bits
+ * poly = 0x1EDC6F41
+ * reflect input bytes = true
+ * reflect output bytes = true
+ */
+
+static u32 crc32c_table[256] = {
+	0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
+	0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
+	0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
+	0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
+	0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
+	0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
+	0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
+	0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
+	0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
+	0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
+	0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
+	0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
+	0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
+	0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
+	0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
+	0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
+	0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
+	0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
+	0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
+	0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
+	0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
+	0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
+	0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
+	0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
+	0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
+	0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
+	0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
+	0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
+	0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
+	0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
+	0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
+	0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
+	0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
+	0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
+	0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
+	0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
+	0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
+	0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
+	0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
+	0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
+	0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
+	0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
+	0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
+	0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
+	0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
+	0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
+	0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
+	0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
+	0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
+	0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
+	0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
+	0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
+	0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
+	0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
+	0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
+	0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
+	0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
+	0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
+	0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
+	0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
+	0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
+	0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
+	0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
+	0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
+};
+
+/*
+ * Steps through buffer one byte at at time, calculates reflected 
+ * crc using table.
+ */
+
+u32 attribute((pure))
+crc32c_le(u32 seed, unsigned char const *data, size_t length)
+{
+	u32 crc = __cpu_to_le32(seed);
+	
+	while (length--)
+		crc =
+		    crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
+
+	return __le32_to_cpu(crc);
+}
+
+#endif	/* CRC_LE_BITS == 8 */
+
+/*EXPORT_SYMBOL(crc32c_be);*/
+
+#if CRC_BE_BITS == 1
+u32 attribute((pure))
+crc32_be(u32 crc, unsigned char const *p, size_t len)
+{
+	int i;
+	while (len--) {
+		crc ^= *p++ << 24;
+		for (i = 0; i < 8; i++)
+			crc =
+			    (crc << 1) ^ ((crc & 0x80000000) ? CRC32C_POLY_BE :
+					  0);
+	}
+	return crc;
+}
+#endif
+
+/*
+ * Unit test
+ *
+ * A small unit test suite is implemented as part of the crypto suite.
+ * Select CRYPTO_CRC32C and use the tcrypt module to run the tests.
+ */
diff -urN --exclude '*.ko' --exclude '*.mod.*' --exclude '*~' --exclude '*.o*' --exclude '.*' --exclude '*.cmd' --exclude drivers linux-2.6.1.orig/include/linux/crc32c.h linux/include/linux/crc32c.h
--- linux-2.6.1.orig/include/linux/crc32c.h	Wed Dec 31 18:00:00 1969
+++ linux/include/linux/crc32c.h	Mon Feb  2 16:33:20 2004
@@ -0,0 +1,11 @@
+#ifndef _LINUX_CRC32C_H
+#define _LINUX_CRC32C_H
+
+#include <linux/types.h>
+
+extern u32 crc32c_le(u32 crc, unsigned char const *address, size_t length);
+extern u32 crc32c_be(u32 crc, unsigned char const *address, size_t length);
+
+#define crc32c(seed, data, length)  crc32c_le(seed, (unsigned char const *)data, length)
+
+#endif	/* _LINUX_CRC32C_H */
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.h	Fri Jan  9 00:59:19 2004
+++ linux/include/linux/crypto.h	Wed Jan 14 11:26:39 2004
@@ -30,7 +30,7 @@
 #define CRYPTO_ALG_TYPE_CIPHER		0x00000001
 #define CRYPTO_ALG_TYPE_DIGEST		0x00000002
 #define CRYPTO_ALG_TYPE_COMPRESS	0x00000004
-
+#define CRYPTO_ALG_TYPE_CHKSUM		0x00000008
 /*
  * 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_cipher	cra_u.cipher
 #define cra_digest	cra_u.digest
 #define cra_compress	cra_u.compress
+#define cra_chksum    cra_u.chksum
 
 struct crypto_alg {
 	struct 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_cipher	crt_u.cipher
 #define crt_digest	crt_u.digest
 #define crt_compress	crt_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;
 	
 	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);
+}
+
+static inline void crypto_chksum_digest(struct crypto_tfm *tfm,
+					struct scatterlist *sg,
+					unsigned int nsg, u32 *out)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CHKSUM);
+	tfm->crt_chksum.cht_digest(tfm, sg, nsg, out);
+}
+
 /*
  * HMAC support.
  */

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1 -- take two] Add CRC32C chksums to crypto and lib routines
  2004-02-03 17:50           ` [PATCH 2.6.1 -- take two] " Clay Haapala
@ 2004-02-03 18:51             ` Matt Mackall
  2004-02-03 19:13               ` Clay Haapala
  0 siblings, 1 reply; 26+ messages in thread
From: Matt Mackall @ 2004-02-03 18:51 UTC (permalink / raw)
  To: Clay Haapala; +Cc: James Morris, linux-kernel, linux-scsi, David S. Miller

On Tue, Feb 03, 2004 at 11:50:06AM -0600, Clay Haapala wrote:

> +void crypto_exit_chksum_ops(struct crypto_tfm *tfm)
> +{
> +	return;
> +}

It'd be nice to come up with a way to avoid null funcs just for the
sake of satisfying function pointers, there's quite a few of them
around.

> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the Free
> + * Software Foundation; either version 2 of the License, or (at your option) 
> + * any later version.
...
> +MODULE_LICENSE("GPL and additional rights");

"additional rights?"

> +#if __GNUC__ >= 3	/* 2.x has "attribute", but only 3.0 has "pure */
> +#define attribute(x) __attribute__(x)
> +#else
> +#define attribute(x)
> +#endif

This sort of thing ought to be added to linux/compiler.h if it's not
there already.

> +/*
> + * Haven't generated a big-endian table yet, but the bit-wise version
> + * should at least work.
> + */

Big-endian in this context means, of course, the order of the bits in
the byte rather than bytes in a word, and as this CRC polynomial was
chosen especially for its robustness on noise bursts in little-endian
transmission (aka standard serial and network *bit* transmission
ordering), I think we should intentionally omit BE support and make
note of it.

> +static inline void crypto_chksum_final(struct crypto_tfm *tfm, u32 *out)
> +{
> +	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CHKSUM);

A lot of these BUG_ONs seem to be overkill. You're not going to get
here by someone accidentally misusing the interface. You can only get
here by some very willful abuse of the interface or by extremely
unlikely fandango on core, neither of which is worth trying to defend
against.

-- 
Matt Mackall : http://www.selenic.com : Linux development and consulting

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1 -- take two] Add CRC32C chksums to crypto and lib routines
  2004-02-03 18:51             ` Matt Mackall
@ 2004-02-03 19:13               ` Clay Haapala
  2004-02-03 19:27                 ` Matt Mackall
  2004-02-03 23:25                 ` Matt Domsch
  0 siblings, 2 replies; 26+ messages in thread
From: Clay Haapala @ 2004-02-03 19:13 UTC (permalink / raw)
  To: Matt Mackall; +Cc: James Morris, linux-kernel, linux-scsi, David S. Miller

On Tue, 3 Feb 2004, Matt Mackall uttered the following:

> On Tue, Feb 03, 2004 at 11:50:06AM -0600, Clay Haapala wrote:
> 
>> + * This program is free software; you can redistribute it and/or
>> + modify it * under the terms of the GNU General Public License as
>> + published by the Free * Software Foundation; either version 2 of
>> + the License, or (at your option) * any later version.
> ...
>> +MODULE_LICENSE("GPL and additional rights");
> 
> "additional rights?"
> 
Take it up with Matt_Domsch@dell.com -- it's his code that I
cribbed, so that's the license line I used.

>> +#if __GNUC__ >= 3 /* 2.x has "attribute", but only 3.0 has "pure
>> +*/ #define attribute(x) __attribute__(x) #else #define
>> +attribute(x) #endif
> 
> This sort of thing ought to be added to linux/compiler.h if it's not
> there already.
> 
+/*
+ * Haven't generated a big-endian table yet, but the bit-wise version
+ * should at least work.
+ */
> 
> Big-endian in this context means, of course, the order of the bits in
> the byte rather than bytes in a word, and as this CRC polynomial was
> chosen especially for its robustness on noise bursts in little-endian
> transmission (aka standard serial and network *bit* transmission
> ordering), I think we should intentionally omit BE support and make
> note of it.
> 
Yes, it is about transmission bit-order.  Is the crc32 BE code also
not necessary?  Does it deal with how various networking hardware
and architecture combos present this data?

>> +static inline void crypto_chksum_final(struct crypto_tfm *tfm, u32 *out)
>> +{
>> +	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CHKSUM);
> 
> A lot of these BUG_ONs seem to be overkill. You're not going to get
> here by someone accidentally misusing the interface. You can only get
> here by some very willful abuse of the interface or by extremely
> unlikely fandango on core, neither of which is worth trying to defend
> against.

That would be a worth changing in a clean-up pass over all of
crypto, then.
-- 
Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056
   6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD
 The marketing flacks who thought the Super Bowl half-time show was the
 best way to reach 25-49-year-old males

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1 -- take two] Add CRC32C chksums to crypto and lib routines
  2004-02-03 19:13               ` Clay Haapala
@ 2004-02-03 19:27                 ` Matt Mackall
  2004-02-03 20:17                   ` James Morris
  2004-02-03 23:25                 ` Matt Domsch
  1 sibling, 1 reply; 26+ messages in thread
From: Matt Mackall @ 2004-02-03 19:27 UTC (permalink / raw)
  To: Clay Haapala; +Cc: James Morris, linux-kernel, linux-scsi, David S. Miller

On Tue, Feb 03, 2004 at 01:13:48PM -0600, Clay Haapala wrote:
> On Tue, 3 Feb 2004, Matt Mackall uttered the following:
> 
> +/*
> + * Haven't generated a big-endian table yet, but the bit-wise version
> + * should at least work.
> + */
> > 
> > Big-endian in this context means, of course, the order of the bits in
> > the byte rather than bytes in a word, and as this CRC polynomial was
> > chosen especially for its robustness on noise bursts in little-endian
> > transmission (aka standard serial and network *bit* transmission
> > ordering), I think we should intentionally omit BE support and make
> > note of it.
> > 
> Yes, it is about transmission bit-order.  Is the crc32 BE code also
> not necessary?  Does it deal with how various networking hardware
> and architecture combos present this data?

The crc32_be stuff is used by at least Bluetooth, some of the digital
video stuff, and a couple other random things. I suspect it's mostly
historical accident.

> >> +static inline void crypto_chksum_final(struct crypto_tfm *tfm, u32 *out)
> >> +{
> >> +	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CHKSUM);
> > 
> > A lot of these BUG_ONs seem to be overkill. You're not going to get
> > here by someone accidentally misusing the interface. You can only get
> > here by some very willful abuse of the interface or by extremely
> > unlikely fandango on core, neither of which is worth trying to defend
> > against.
> 
> That would be a worth changing in a clean-up pass over all of
> crypto, then.

I'll do them if James has no objections. I've got a couple other
crypto bits queued.

-- 
Matt Mackall : http://www.selenic.com : Linux development and consulting

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1 -- take two] Add CRC32C chksums to crypto and lib routines
  2004-02-03 19:27                 ` Matt Mackall
@ 2004-02-03 20:17                   ` James Morris
  0 siblings, 0 replies; 26+ messages in thread
From: James Morris @ 2004-02-03 20:17 UTC (permalink / raw)
  To: Matt Mackall; +Cc: Clay Haapala, linux-kernel, linux-scsi, David S. Miller

On Tue, 3 Feb 2004, Matt Mackall wrote:

> > >> +static inline void crypto_chksum_final(struct crypto_tfm *tfm, u32 *out)
> > >> +{
> > >> +	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CHKSUM);
> > > 
> > > A lot of these BUG_ONs seem to be overkill. You're not going to get
> > > here by someone accidentally misusing the interface. You can only get
> > > here by some very willful abuse of the interface or by extremely
> > > unlikely fandango on core, neither of which is worth trying to defend
> > > against.
> > 
> > That would be a worth changing in a clean-up pass over all of
> > crypto, then.
> 
> I'll do them if James has no objections. I've got a couple other
> crypto bits queued.

The problem is that someone could make a programming mistake, not see any 
errors, and get bad crypto.


- James
-- 
James Morris
<jmorris@redhat.com>



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1 -- take two] Add CRC32C chksums to crypto and lib routines
  2004-02-03 19:13               ` Clay Haapala
  2004-02-03 19:27                 ` Matt Mackall
@ 2004-02-03 23:25                 ` Matt Domsch
  2004-02-03 23:37                   ` Matt Mackall
                                     ` (2 more replies)
  1 sibling, 3 replies; 26+ messages in thread
From: Matt Domsch @ 2004-02-03 23:25 UTC (permalink / raw)
  To: Clay Haapala
  Cc: Matt Mackall, James Morris, linux-kernel, linux-scsi, David S. Miller

> >> +MODULE_LICENSE("GPL and additional rights");
> > 
> > "additional rights?"
> > 
> Take it up with Matt_Domsch@dell.com -- it's his code that I
> cribbed, so that's the license line I used.

The crc32 code came from linux@horizon.com with the following
copyright abandonment disclaimer, which is still in lib/crc32.c:

/*
 * This code is in the public domain; copyright abandoned.
 * Liability for non-performance of this code is limited to the amount
 * you paid for it.  Since it is distributed for free, your refund will
 * be very very small.  If it breaks, you get to keep both pieces.
 */

Thus GPL plus additional rights is appropriate.

Thanks,
Matt

-- 
Matt Domsch
Sr. Software Engineer, Lead Engineer
Dell Linux Solutions linux.dell.com & www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1 -- take two] Add CRC32C chksums to crypto and lib routines
  2004-02-03 23:25                 ` Matt Domsch
@ 2004-02-03 23:37                   ` Matt Mackall
  2004-02-04 16:14                     ` Clay Haapala
  2004-02-04  2:18                   ` James Morris
  2004-02-04  3:11                   ` Valdis.Kletnieks
  2 siblings, 1 reply; 26+ messages in thread
From: Matt Mackall @ 2004-02-03 23:37 UTC (permalink / raw)
  To: Matt Domsch
  Cc: Clay Haapala, James Morris, linux-kernel, linux-scsi, David S. Miller

On Tue, Feb 03, 2004 at 05:25:08PM -0600, Matt Domsch wrote:
> > >> +MODULE_LICENSE("GPL and additional rights");
> > > 
> > > "additional rights?"
> > > 
> > Take it up with Matt_Domsch@dell.com -- it's his code that I
> > cribbed, so that's the license line I used.
> 
> The crc32 code came from linux@horizon.com with the following
> copyright abandonment disclaimer, which is still in lib/crc32.c:
> 
> /*
>  * This code is in the public domain; copyright abandoned.
>  * Liability for non-performance of this code is limited to the amount
>  * you paid for it.  Since it is distributed for free, your refund will
>  * be very very small.  If it breaks, you get to keep both pieces.
>  */
> 
> Thus GPL plus additional rights is appropriate.

Ok, makes sense for CRC32 stuff which can be easily lifted from the
kernel or 50 other places, but not for stuff that's depends on
cryptoapi.

-- 
Matt Mackall : http://www.selenic.com : Linux development and consulting

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1 -- take two] Add CRC32C chksums to crypto and lib routines
  2004-02-03 23:25                 ` Matt Domsch
  2004-02-03 23:37                   ` Matt Mackall
@ 2004-02-04  2:18                   ` James Morris
  2004-02-04  3:11                   ` Valdis.Kletnieks
  2 siblings, 0 replies; 26+ messages in thread
From: James Morris @ 2004-02-04  2:18 UTC (permalink / raw)
  To: Matt Domsch
  Cc: Clay Haapala, Matt Mackall, linux-kernel, linux-scsi, David S. Miller

On Tue, 3 Feb 2004, Matt Domsch wrote:

> > >> +MODULE_LICENSE("GPL and additional rights");
> > > 
> > > "additional rights?"
> > > 
> > Take it up with Matt_Domsch@dell.com -- it's his code that I
> > cribbed, so that's the license line I used.
> 
> The crc32 code came from linux@horizon.com with the following
> copyright abandonment disclaimer, which is still in lib/crc32.c:
> 
> /*
>  * This code is in the public domain; copyright abandoned.
>  * Liability for non-performance of this code is limited to the amount
>  * you paid for it.  Since it is distributed for free, your refund will
>  * be very very small.  If it breaks, you get to keep both pieces.
>  */
> 
> Thus GPL plus additional rights is appropriate.
> 

Placing the code in the public domain then adding additional rights seems 
to be inherently conflicted.

People will pay for distribution of the code, so these additional rights 
would not be acceptable anyway.

(IMHO).


- James
-- 
James Morris
<jmorris@redhat.com>



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1 -- take two] Add CRC32C chksums to crypto and lib routines
  2004-02-03 23:25                 ` Matt Domsch
  2004-02-03 23:37                   ` Matt Mackall
  2004-02-04  2:18                   ` James Morris
@ 2004-02-04  3:11                   ` Valdis.Kletnieks
  2 siblings, 0 replies; 26+ messages in thread
From: Valdis.Kletnieks @ 2004-02-04  3:11 UTC (permalink / raw)
  To: Matt Domsch
  Cc: Clay Haapala, Matt Mackall, James Morris, linux-kernel,
	linux-scsi, David S. Miller

[-- Attachment #1: Type: text/plain, Size: 904 bytes --]

On Tue, 03 Feb 2004 17:25:08 CST, Matt Domsch said:

> /*
>  * This code is in the public domain; copyright abandoned.
>  * Liability for non-performance of this code is limited to the amount
>  * you paid for it.  Since it is distributed for free, your refund will
>  * be very very small.  If it breaks, you get to keep both pieces.
>  */

Hmm.. I could have *sworn* that abandoning something to the public
domain prohibited any disclaimer-of-liability clauses - the original
reason for the MIT X copyright was because they couldn't disclaim
liability if they let it into the public domain.  It's the same basic
"by copying, you agree to our terms" copyright that essentially all
open-source depends on.

And if it's in the public domain, they don't have to agree to your terms,
and thus you can't enforce that liability disclaimer..

Smells fishy, needs to be looked at by an actual copyright expert.

[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1 -- take two] Add CRC32C chksums to crypto and lib routines
  2004-02-03 23:37                   ` Matt Mackall
@ 2004-02-04 16:14                     ` Clay Haapala
  2004-02-04 17:21                       ` Matt Mackall
  2004-02-06 23:54                       ` Jamie Lokier
  0 siblings, 2 replies; 26+ messages in thread
From: Clay Haapala @ 2004-02-04 16:14 UTC (permalink / raw)
  To: Matt Mackall
  Cc: Matt Domsch, James Morris, linux-kernel, linux-scsi, David S. Miller

On Tue, 3 Feb 2004, Matt Mackall said:
> On Tue, Feb 03, 2004 at 05:25:08PM -0600, Matt Domsch wrote:
>> > >> +MODULE_LICENSE("GPL and additional rights");
>> > > 
>> > > "additional rights?"
>> > > 
>> > Take it up with Matt_Domsch@dell.com -- it's his code that I
>> > cribbed, so that's the license line I used.
>> 
>> The crc32 code came from linux@horizon.com with the following
>> copyright abandonment disclaimer, which is still in lib/crc32.c:
>> 
>> /*
>>  * This code is in the public domain; copyright abandoned.
>>  * Liability for non-performance of this code is limited to the
>>  * amount you paid for it.  Since it is distributed for free, your
>>  * refund will be very very small.  If it breaks, you get to keep
>>  * both pieces.  */
>> 
>> Thus GPL plus additional rights is appropriate.
> 
> Ok, makes sense for CRC32 stuff which can be easily lifted from the
> kernel or 50 other places, but not for stuff that's depends on
> cryptoapi.

Matt is correct about crypto/crc32c.c -- that should be simply "GPL".

As for the derived-from-public-domain-CRC32 stuff, should one even
claim "GPL" on it?  That would be, in effect, licensing public-domain
code and placing restrictions on it, something only a copyright holder
should be able to do, and not the intent of the author, in this case.
-- 
Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056
   6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD
 The marketing flacks who thought the Super Bowl half-time show was the
 best way to reach 25-49-year-old males obviously surf a little too
 much Internet pr0n and read a bit much into the spam they receive.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1] Add CRC32C chksums to crypto and lib routines
  2004-02-03 17:09         ` James Morris
@ 2004-02-04 17:07           ` Clay Haapala
  0 siblings, 0 replies; 26+ messages in thread
From: Clay Haapala @ 2004-02-04 17:07 UTC (permalink / raw)
  To: James Morris; +Cc: linux-kernel, linux-scsi, David S. Miller, mpm

On Tue, 3 Feb 2004, James Morris told this:
> On Tue, 3 Feb 2004, Clay Haapala wrote:
> 
>> If this patch looks good, I'd like it accepted so we can submit
>> code iSCSI driver code that makes use of it.  This may be a good
>> time, since the crypto SHA code is getting a little scrutiny right
>> now.
> 
> This will need to wait until 2.6.2 is released, and will you also
> please submit the iSCSI change for review?
> 
Thanks, Dave, for setting me straight on not posting mondo patches to
lkml. :-)

The 4.0.0.4 version of the driver, with the crypto CRC calls omitted,
has been submitted for review by the scsi maintainers.  Here is link
to a "preview" patch with the calls to the crypto CRC32C module back
in, but without any of their latest comments incorporated:

  http://home.mn.rr.com/haapi/iSCSI/iscsi-4.0.0.4-with-crypto.patch.bz2

iscsi-crc.{c,h} are just wrappers for code using the previous private
implementation.  iscsi-recv-pdu.c and iscsi-xmit-pdu.c have the code
which processes scatterlists and make calls to the crypto CRC32C
routines in the other patch.

This code has been tested successfully on 2.6.1 with udev-0.15 and late-model
sysfs, hotplug, and klibc.  The patch also contains the iscsi utilities
code, if you want to go the whole nine yards.
-- 
Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056
   6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD
    Minnesota is a very agreeable state.  Lately even Celsius and
                   Fahrenheit have tended to agree.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1 -- take two] Add CRC32C chksums to crypto and lib routines
  2004-02-04 16:14                     ` Clay Haapala
@ 2004-02-04 17:21                       ` Matt Mackall
  2004-02-07 15:20                         ` Matt Domsch
  2004-02-18 21:24                         ` Matt Domsch
  2004-02-06 23:54                       ` Jamie Lokier
  1 sibling, 2 replies; 26+ messages in thread
From: Matt Mackall @ 2004-02-04 17:21 UTC (permalink / raw)
  To: Clay Haapala; +Cc: Matt Domsch, linux-kernel

On Wed, Feb 04, 2004 at 10:14:13AM -0600, Clay Haapala wrote:
> On Tue, 3 Feb 2004, Matt Mackall said:
> > On Tue, Feb 03, 2004 at 05:25:08PM -0600, Matt Domsch wrote:
> >> > >> +MODULE_LICENSE("GPL and additional rights");
> >> > > 
> >> > > "additional rights?"
> >> > > 
> >> > Take it up with Matt_Domsch@dell.com -- it's his code that I
> >> > cribbed, so that's the license line I used.
> >> 
> >> The crc32 code came from linux@horizon.com with the following
> >> copyright abandonment disclaimer, which is still in lib/crc32.c:
> >> 
> >> /*
> >>  * This code is in the public domain; copyright abandoned.
> >>  * Liability for non-performance of this code is limited to the
> >>  * amount you paid for it.  Since it is distributed for free, your
> >>  * refund will be very very small.  If it breaks, you get to keep
> >>  * both pieces.  */
> >> 
> >> Thus GPL plus additional rights is appropriate.
> > 
> > Ok, makes sense for CRC32 stuff which can be easily lifted from the
> > kernel or 50 other places, but not for stuff that's depends on
> > cryptoapi.
> 
> Matt is correct about crypto/crc32c.c -- that should be simply "GPL".
> 
> As for the derived-from-public-domain-CRC32 stuff, should one even
> claim "GPL" on it?  That would be, in effect, licensing public-domain
> code and placing restrictions on it, something only a copyright holder
> should be able to do, and not the intent of the author, in this case.

Hard to guess what the author's intent was as he left no license, but
perhaps you're right. However, public domain works are routinely
relicensed by publishers when they make a trivially derived work, see
any reprint of Shakespeare or Bach. 

As has been pointed out, _not_ putting some sort of license on it
potentially opens people who ship it up to liability. Arguably, by
compiling it into the kernel, you're accepting the GPL liability terms
for that use. But that doesn't stop someone from taking crc32.c,
incorporating it into something else, having it blow up disastrously,
and then suing whoever sold them the kernel tarball. Sounds
outlandish, but crazier things have happened.

As "dual GPL/public domain license" is an oxymoron, the best thing to
do is probably to slap a dual GPL/2-clause BSD license on it to
disclaim liability while minimally limiting all other rights. Matt,
since you're the last one to touch this, I'll let you make the call,
but here's what I would suggest (still needs an actual copyright
notice):

 tiny-mpm/lib/crc32.c |   39 +++++++++++++++++++++++++++++----------
 2 files changed, 29 insertions(+), 10 deletions(-)

diff -puN lib/crc32.c~crc-license lib/crc32.c
--- tiny/lib/crc32.c~crc-license	2004-02-04 10:54:57.000000000 -0600
+++ tiny-mpm/lib/crc32.c	2004-02-04 10:58:23.000000000 -0600
@@ -1,4 +1,4 @@
-/* 
+/*
  * Oct 15, 2000 Matt Domsch <Matt_Domsch@dell.com>
  * Nicer crc32 functions/docs submitted by linux@horizon.com.  Thanks!
  *
@@ -12,7 +12,33 @@
  *   drivers/net/smc9194.c uses seed ~0, doesn't xor with ~0.
  *   fs/jffs2 uses seed 0, doesn't xor with ~0.
  *   fs/partitions/efi.c uses seed ~0, xor's with ~0.
- * 
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, and the entire permission notice in its entirety,
+ *    including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU General Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
  */
 
 #include <linux/crc32.h>
@@ -40,16 +66,9 @@
 #define attribute(x)
 #endif
 
-/*
- * This code is in the public domain; copyright abandoned.
- * Liability for non-performance of this code is limited to the amount
- * you paid for it.  Since it is distributed for free, your refund will
- * be very very small.  If it breaks, you get to keep both pieces.
- */
-
 MODULE_AUTHOR("Matt Domsch <Matt_Domsch@dell.com>");
 MODULE_DESCRIPTION("Ethernet CRC32 calculations");
-MODULE_LICENSE("GPL and additional rights");
+MODULE_LICENSE("Dual BSD/GPL");
 
 #if CRC_LE_BITS == 1
 /*

-- 
Matt Mackall : http://www.selenic.com : Linux development and consulting

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1 -- take two] Add CRC32C chksums to crypto and lib routines
  2004-02-04 16:14                     ` Clay Haapala
  2004-02-04 17:21                       ` Matt Mackall
@ 2004-02-06 23:54                       ` Jamie Lokier
  1 sibling, 0 replies; 26+ messages in thread
From: Jamie Lokier @ 2004-02-06 23:54 UTC (permalink / raw)
  To: Clay Haapala
  Cc: Matt Mackall, Matt Domsch, James Morris, linux-kernel,
	linux-scsi, David S. Miller

Clay Haapala wrote:
> licensing public-domain code and placing restrictions on it,
> something only a copyright holder should be able to do,

Public domain means it doesn't have a copyright holder.

> and not the intent of the author, in this case.

But I agree, the intent of the author is important (not legally, but
morally).

-- Jamie

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1 -- take two] Add CRC32C chksums to crypto and lib routines
  2004-02-04 17:21                       ` Matt Mackall
@ 2004-02-07 15:20                         ` Matt Domsch
  2004-02-18 21:24                         ` Matt Domsch
  1 sibling, 0 replies; 26+ messages in thread
From: Matt Domsch @ 2004-02-07 15:20 UTC (permalink / raw)
  To: Matt Mackall; +Cc: Clay Haapala, linux-kernel

On Wed, Feb 04, 2004 at 11:21:16AM -0600, Matt Mackall wrote:
> As has been pointed out, _not_ putting some sort of license on it
> potentially opens people who ship it up to liability. Arguably, by
> compiling it into the kernel, you're accepting the GPL liability terms
> for that use. But that doesn't stop someone from taking crc32.c,
> incorporating it into something else, having it blow up disastrously,
> and then suing whoever sold them the kernel tarball. Sounds
> outlandish, but crazier things have happened.
> 
> As "dual GPL/public domain license" is an oxymoron, the best thing to
> do is probably to slap a dual GPL/2-clause BSD license on it to
> disclaim liability while minimally limiting all other rights. Matt,
> since you're the last one to touch this, I'll let you make the call,
> but here's what I would suggest (still needs an actual copyright
> notice):

Thanks for the dual-license BSD/GPL patch Matt.
Before proceeding with accepting your patch, I'm asking our Dell IP
legal team for advice, just to be safe.  IANAL, most of us aren't,
they are.  I'll send a follow-up soon as I hear back, probably early
next week.

Thanks,
Matt

-- 
Matt Domsch
Sr. Software Engineer, Lead Engineer
Dell Linux Solutions linux.dell.com & www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1 -- take two] Add CRC32C chksums to crypto and lib routines
  2004-02-04 17:21                       ` Matt Mackall
  2004-02-07 15:20                         ` Matt Domsch
@ 2004-02-18 21:24                         ` Matt Domsch
  2004-02-18 23:18                           ` Matt Domsch
  1 sibling, 1 reply; 26+ messages in thread
From: Matt Domsch @ 2004-02-18 21:24 UTC (permalink / raw)
  To: Matt Mackall; +Cc: Clay Haapala, linux-kernel

On Wed, Feb 04, 2004 at 11:21:16AM -0600, Matt Mackall wrote:
> On Wed, Feb 04, 2004 at 10:14:13AM -0600, Clay Haapala wrote:
> > On Tue, 3 Feb 2004, Matt Mackall said:
> > > On Tue, Feb 03, 2004 at 05:25:08PM -0600, Matt Domsch wrote:
> > >> > >> +MODULE_LICENSE("GPL and additional rights");
> > >> > > 
> > >> > > "additional rights?"
> > >> > > 
> > >> > Take it up with Matt_Domsch@dell.com -- it's his code that I
> > >> > cribbed, so that's the license line I used.
> > >> 
> > >> The crc32 code came from linux@horizon.com with the following
> > >> copyright abandonment disclaimer, which is still in lib/crc32.c:
> > >> 
> > >> /*
> > >>  * This code is in the public domain; copyright abandoned.
> > >>  * Liability for non-performance of this code is limited to the
> > >>  * amount you paid for it.  Since it is distributed for free, your
> > >>  * refund will be very very small.  If it breaks, you get to keep
> > >>  * both pieces.  */
> > >> 
> > >> Thus GPL plus additional rights is appropriate.
> > > 
> > > Ok, makes sense for CRC32 stuff which can be easily lifted from the
> > > kernel or 50 other places, but not for stuff that's depends on
> > > cryptoapi.
> > 
> > Matt is correct about crypto/crc32c.c -- that should be simply "GPL".
> > 
> > As for the derived-from-public-domain-CRC32 stuff, should one even
> > claim "GPL" on it?  That would be, in effect, licensing public-domain
> > code and placing restrictions on it, something only a copyright holder
> > should be able to do, and not the intent of the author, in this case.
> 
> Hard to guess what the author's intent was as he left no license, but
> perhaps you're right. However, public domain works are routinely
> relicensed by publishers when they make a trivially derived work, see
> any reprint of Shakespeare or Bach. 
> 
> As has been pointed out, _not_ putting some sort of license on it
> potentially opens people who ship it up to liability. Arguably, by
> compiling it into the kernel, you're accepting the GPL liability terms
> for that use. But that doesn't stop someone from taking crc32.c,
> incorporating it into something else, having it blow up disastrously,
> and then suing whoever sold them the kernel tarball. Sounds
> outlandish, but crazier things have happened.
> 
> As "dual GPL/public domain license" is an oxymoron, the best thing to
> do is probably to slap a dual GPL/2-clause BSD license on it to
> disclaim liability while minimally limiting all other rights. Matt,
> since you're the last one to touch this, I'll let you make the call,
> but here's what I would suggest (still needs an actual copyright
> notice):

After seeking advice from Dell's lawyers, they recommend simply adding
the GPL license text to the top of the file and be done with it.
It's public domain, we're free to include (and relicense) it as we
wish.  If someone else wants to use it in a non-GPL fashion, they'll
need to start from the original public domain submission, not this one
which clearly has been modified somewhat since we first received it,
with faster algorithms, creation of the table at compile time, etc.

Thanks,
Matt

-- 
Matt Domsch
Sr. Software Engineer, Lead Engineer
Dell Linux Solutions linux.dell.com & www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2.6.1 -- take two] Add CRC32C chksums to crypto and lib routines
  2004-02-18 21:24                         ` Matt Domsch
@ 2004-02-18 23:18                           ` Matt Domsch
  0 siblings, 0 replies; 26+ messages in thread
From: Matt Domsch @ 2004-02-18 23:18 UTC (permalink / raw)
  To: Matt Mackall, akpm, marcelo.tosatti; +Cc: Clay Haapala, linux-kernel

> After seeking advice from Dell's lawyers, they recommend simply adding
> the GPL license text to the top of the file and be done with it.
> It's public domain, we're free to include (and relicense) it as we
> wish.  If someone else wants to use it in a non-GPL fashion, they'll
> need to start from the original public domain submission, not this one
> which clearly has been modified somewhat since we first received it,
> with faster algorithms, creation of the table at compile time, etc.

Patch below applies to both 2.4.25 and 2.6.3, and replaces the public
domain statement and non-warranty with the GPL, as is permitted by the
code being in the public domain, and is done with legal advice.

Thanks,
Matt

-- 
Matt Domsch
Sr. Software Engineer, Lead Engineer
Dell Linux Solutions linux.dell.com & www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com


===== lib/crc32.c 1.11 vs edited =====
--- 1.11/lib/crc32.c	Tue Feb  3 23:29:15 2004
+++ edited/lib/crc32.c	Wed Feb 18 17:00:27 2004
@@ -1,6 +1,9 @@
-/* 
+/*
  * Oct 15, 2000 Matt Domsch <Matt_Domsch@dell.com>
  * Nicer crc32 functions/docs submitted by linux@horizon.com.  Thanks!
+ * Code was from the public domain, copyright abandoned.  Code was
+ * subsequently included in the kernel, thus was re-licensed under the
+ * GNU GPL v2.
  *
  * Oct 12, 2000 Matt Domsch <Matt_Domsch@dell.com>
  * Same crc32 function was used in 5 other places in the kernel.
@@ -12,7 +15,9 @@
  *   drivers/net/smc9194.c uses seed ~0, doesn't xor with ~0.
  *   fs/jffs2 uses seed 0, doesn't xor with ~0.
  *   fs/partitions/efi.c uses seed ~0, xor's with ~0.
- * 
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
  */
 
 #include <linux/crc32.h>
@@ -38,16 +43,10 @@
 #define attribute(x)
 #endif
 
-/*
- * This code is in the public domain; copyright abandoned.
- * Liability for non-performance of this code is limited to the amount
- * you paid for it.  Since it is distributed for free, your refund will
- * be very very small.  If it breaks, you get to keep both pieces.
- */
 
 MODULE_AUTHOR("Matt Domsch <Matt_Domsch@dell.com>");
 MODULE_DESCRIPTION("Ethernet CRC32 calculations");
-MODULE_LICENSE("GPL and additional rights");
+MODULE_LICENSE("GPL");
 
 #if CRC_LE_BITS == 1
 /*

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2004-02-18 23:21 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-01-14 21:31 [PATCH] Add CRC32C chksums to crypto routines Clay Haapala
2004-01-14 21:45 ` James Morris
2004-01-14 22:12   ` Clay Haapala
2004-01-16  1:40 ` Matt Mackall
2004-01-19 20:13 ` James Morris
2004-01-19 21:15   ` Clay Haapala
2004-01-19 21:33     ` James Morris
2004-02-03 16:58       ` [PATCH 2.6.1] Add CRC32C chksums to crypto and lib routines Clay Haapala
2004-02-03 17:09         ` James Morris
2004-02-04 17:07           ` Clay Haapala
2004-02-03 17:13         ` James Morris
2004-02-03 17:50           ` [PATCH 2.6.1 -- take two] " Clay Haapala
2004-02-03 18:51             ` Matt Mackall
2004-02-03 19:13               ` Clay Haapala
2004-02-03 19:27                 ` Matt Mackall
2004-02-03 20:17                   ` James Morris
2004-02-03 23:25                 ` Matt Domsch
2004-02-03 23:37                   ` Matt Mackall
2004-02-04 16:14                     ` Clay Haapala
2004-02-04 17:21                       ` Matt Mackall
2004-02-07 15:20                         ` Matt Domsch
2004-02-18 21:24                         ` Matt Domsch
2004-02-18 23:18                           ` Matt Domsch
2004-02-06 23:54                       ` Jamie Lokier
2004-02-04  2:18                   ` James Morris
2004-02-04  3:11                   ` Valdis.Kletnieks

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).