* Crypto API and keyed non-HMAC digest algorithms / Michael MIC @ 2004-03-06 18:46 Jouni Malinen 2004-03-08 14:45 ` James Morris 0 siblings, 1 reply; 52+ messages in thread From: Jouni Malinen @ 2004-03-06 18:46 UTC (permalink / raw) To: James Morris, David S. Miller; +Cc: linux-kernel Current Linux crypto API does not seem to have generic mechanism for adding keyed digest algorithms that are not using HMAC construction. IEEE 802.11i/WPA uses such an algorithm in TKIP and getting this to crypto API would be useful in order to be able to share more code of TKIP implementation. One straightforward way of adding support for Michael MIC is to add an optional setkey operation for digest algorithms. The included patch (against Linux 2.6.4-rc2) does exactly this and also includes an implementation of Michael MIC. Another option would be to add a new algorithm type for keyed hash algorithms, but that seemed unnecessary for this purpose. Is the modification of digest type acceptable way of adding support for a keyed digest algorithm that does not use HMAC? The patch includes test vectors for Michael MIC and I have tested this with the Host AP driver and TKIP. Getting this into crypto API is one of the first steps in replacing the internal crypto algorithm implementation in the Host AP driver code and I would appreciate it if this would be applied to Linux 2.6 tree. diff -upr linux-2.6.4-rc2.orig/Documentation/crypto/api-intro.txt linux-2.6.4-rc2/Documentation/crypto/api-intro.txt --- linux-2.6.4-rc2.orig/Documentation/crypto/api-intro.txt 2004-03-05 21:55:12.000000000 -0800 +++ linux-2.6.4-rc2/Documentation/crypto/api-intro.txt 2004-03-05 22:28:38.090693088 -0800 @@ -186,6 +186,7 @@ Original developers of the crypto algori Dag Arne Osvik (Serpent) Brian Gladman (AES) Kartikey Mahendra Bhatt (CAST6) + Jouni Malinen (Michael MIC) SHA1 algorithm contributors: Jean-Francois Dive diff -upr linux-2.6.4-rc2.orig/crypto/Kconfig linux-2.6.4-rc2/crypto/Kconfig --- linux-2.6.4-rc2.orig/crypto/Kconfig 2004-03-05 22:12:13.347396824 -0800 +++ linux-2.6.4-rc2/crypto/Kconfig 2004-03-05 22:11:00.152524136 -0800 @@ -151,6 +151,15 @@ config CRYPTO_DEFLATE You will most probably want this if using IPSec. +config CRYPTO_MICHAEL_MIC + tristate "Michael MIC keyed digest algorithm" + depends on CRYPTO + help + Michael MIC is used for message integrity protection in TKIP + (IEEE 802.11i). This algorithm is required for TKIP, but it + should not be used for other purposes because of the weakness + of the algorithm. + config CRYPTO_TEST tristate "Testing module" depends on CRYPTO diff -upr linux-2.6.4-rc2.orig/crypto/Makefile linux-2.6.4-rc2/crypto/Makefile --- linux-2.6.4-rc2.orig/crypto/Makefile 2004-03-05 22:13:30.891608312 -0800 +++ linux-2.6.4-rc2/crypto/Makefile 2004-03-05 22:07:55.211639424 -0800 @@ -22,5 +22,6 @@ obj-$(CONFIG_CRYPTO_AES) += aes.o obj-$(CONFIG_CRYPTO_CAST5) += cast5.o obj-$(CONFIG_CRYPTO_CAST6) += cast6.o obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o +obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o diff -upr linux-2.6.4-rc2.orig/crypto/digest.c linux-2.6.4-rc2/crypto/digest.c --- linux-2.6.4-rc2.orig/crypto/digest.c 2004-02-17 19:57:12.000000000 -0800 +++ linux-2.6.4-rc2/crypto/digest.c 2004-03-05 22:18:14.429504000 -0800 @@ -42,6 +42,15 @@ static void final(struct crypto_tfm *tfm tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out); } +static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) +{ + u32 flags; + if (tfm->__crt_alg->cra_digest.dia_setkey == NULL) + return -1; + return tfm->__crt_alg->cra_digest.dia_setkey(crypto_tfm_ctx(tfm), + key, keylen, &flags); +} + static void digest(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg, u8 *out) { @@ -72,6 +81,7 @@ int crypto_init_digest_ops(struct crypto ops->dit_update = update; ops->dit_final = final; ops->dit_digest = digest; + ops->dit_setkey = setkey; return crypto_alloc_hmac_block(tfm); } diff -upr linux-2.6.4-rc2.orig/crypto/tcrypt.c linux-2.6.4-rc2/crypto/tcrypt.c --- linux-2.6.4-rc2.orig/crypto/tcrypt.c 2004-02-17 19:59:11.000000000 -0800 +++ linux-2.6.4-rc2/crypto/tcrypt.c 2004-03-05 22:53:14.400259920 -0800 @@ -112,6 +112,10 @@ test_hash (char * algo, struct hash_test sg[0].length = hash_tv[i].psize; crypto_digest_init (tfm); + if (tfm->crt_u.digest.dit_setkey) { + crypto_digest_setkey (tfm, hash_tv[i].key, + hash_tv[i].ksize); + } crypto_digest_update (tfm, sg, 1); crypto_digest_final (tfm, result); @@ -564,6 +568,8 @@ do_test(void) test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS); test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS); #endif + + test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); break; case 1: @@ -638,6 +644,10 @@ do_test(void) test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS); break; + case 16: + test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); + break; + #ifdef CONFIG_CRYPTO_HMAC case 100: test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); diff -upr linux-2.6.4-rc2.orig/crypto/tcrypt.h linux-2.6.4-rc2/crypto/tcrypt.h --- linux-2.6.4-rc2.orig/crypto/tcrypt.h 2004-02-17 19:59:27.000000000 -0800 +++ linux-2.6.4-rc2/crypto/tcrypt.h 2004-03-05 22:53:36.807853448 -0800 @@ -30,6 +30,8 @@ struct hash_testvec { char digest[MAX_DIGEST_SIZE]; unsigned char np; unsigned char tap[MAX_TAP]; + char key[128]; /* only used with keyed hash algorithms */ + unsigned char ksize; }; struct hmac_testvec { @@ -1578,4 +1580,54 @@ struct comp_testvec deflate_decomp_tv_te }, }; +/* + * Michael MIC test vectors from IEEE 802.11i + */ +#define MICHAEL_MIC_TEST_VECTORS 6 + +struct hash_testvec michael_mic_tv_template[] = +{ + { + .key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .ksize = 8, + .plaintext = { }, + .psize = 0, + .digest = { 0x82, 0x92, 0x5c, 0x1c, 0xa1, 0xd1, 0x30, 0xb8 } + }, + { + .key = { 0x82, 0x92, 0x5c, 0x1c, 0xa1, 0xd1, 0x30, 0xb8 }, + .ksize = 8, + .plaintext = { 'M' }, + .psize = 1, + .digest = { 0x43, 0x47, 0x21, 0xca, 0x40, 0x63, 0x9b, 0x3f } + }, + { + .key = { 0x43, 0x47, 0x21, 0xca, 0x40, 0x63, 0x9b, 0x3f }, + .ksize = 8, + .plaintext = { 'M', 'i' }, + .psize = 2, + .digest = { 0xe8, 0xf9, 0xbe, 0xca, 0xe9, 0x7e, 0x5d, 0x29 } + }, + { + .key = { 0xe8, 0xf9, 0xbe, 0xca, 0xe9, 0x7e, 0x5d, 0x29 }, + .ksize = 8, + .plaintext = { 'M', 'i', 'c' }, + .psize = 3, + .digest = { 0x90, 0x03, 0x8f, 0xc6, 0xcf, 0x13, 0xc1, 0xdb } + }, + { + .key = { 0x90, 0x03, 0x8f, 0xc6, 0xcf, 0x13, 0xc1, 0xdb }, + .ksize = 8, + .plaintext = { 'M', 'i', 'c', 'h' }, + .psize = 4, + .digest = { 0xd5, 0x5e, 0x10, 0x05, 0x10, 0x12, 0x89, 0x86 } + }, + { + .key = { 0xd5, 0x5e, 0x10, 0x05, 0x10, 0x12, 0x89, 0x86 }, + .ksize = 8, + .plaintext = { 'M', 'i', 'c', 'h', 'a', 'e', 'l' }, + .psize = 7, + .digest = { 0x0a, 0x94, 0x2b, 0x12, 0x4e, 0xca, 0xa5, 0x46 }, + } +}; #endif /* _CRYPTO_TCRYPT_H */ diff -upr linux-2.6.4-rc2.orig/include/linux/crypto.h linux-2.6.4-rc2/include/linux/crypto.h --- linux-2.6.4-rc2.orig/include/linux/crypto.h 2004-02-17 19:57:21.000000000 -0800 +++ linux-2.6.4-rc2/include/linux/crypto.h 2004-03-05 22:15:16.142607728 -0800 @@ -76,6 +76,8 @@ struct digest_alg { void (*dia_init)(void *ctx); void (*dia_update)(void *ctx, const u8 *data, unsigned int len); void (*dia_final)(void *ctx, u8 *out); + int (*dia_setkey)(void *ctx, const u8 *key, + unsigned int keylen, u32 *flags); }; struct compress_alg { @@ -157,6 +159,8 @@ struct digest_tfm { void (*dit_final)(struct crypto_tfm *tfm, u8 *out); void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg, u8 *out); + int (*dit_setkey)(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen); #ifdef CONFIG_CRYPTO_HMAC void *dit_hmac_block; #endif @@ -282,6 +286,15 @@ static inline void crypto_digest_digest( tfm->crt_digest.dit_digest(tfm, sg, nsg, out); } +static inline int crypto_digest_setkey(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + if (tfm->crt_digest.dit_setkey == NULL) + return -1; + return tfm->crt_digest.dit_setkey(tfm, key, keylen); +} + static inline int crypto_cipher_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) { --- linux-2.6.4-rc2.orig/crypto/michael_mic.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.4-rc2/crypto/michael_mic.c 2004-03-05 22:07:06.956975248 -0800 @@ -0,0 +1,193 @@ +/* + * Cryptographic API + * + * Michael MIC (IEEE 802.11i/TKIP) keyed digest + * + * Copyright (c) 2004 Jouni Malinen <jkmaline@cc.hut.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/crypto.h> + + +struct michael_mic_ctx { + u8 pending[4]; + size_t pending_len; + + u32 l, r; +}; + + +static inline u32 rotl(u32 val, int bits) +{ + return (val << bits) | (val >> (32 - bits)); +} + + +static inline u32 rotr(u32 val, int bits) +{ + return (val >> bits) | (val << (32 - bits)); +} + + +static inline u32 xswap(u32 val) +{ + return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8); +} + + +#define michael_block(l, r) \ +do { \ + r ^= rotl(l, 17); \ + l += r; \ + r ^= xswap(l); \ + l += r; \ + r ^= rotl(l, 3); \ + l += r; \ + r ^= rotr(l, 2); \ + l += r; \ +} while (0) + + +static inline u32 get_le32(const u8 *p) +{ + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +} + + +static inline void put_le32(u8 *p, u32 v) +{ + p[0] = v; + p[1] = v >> 8; + p[2] = v >> 16; + p[3] = v >> 24; +} + + +static void michael_init(void *ctx) +{ + struct michael_mic_ctx *mctx = ctx; + mctx->pending_len = 0; +} + + +static void michael_update(void *ctx, const u8 *data, unsigned int len) +{ + struct michael_mic_ctx *mctx = ctx; + + if (mctx->pending_len) { + int flen = 4 - mctx->pending_len; + if (flen > len) + flen = len; + memcpy(&mctx->pending[mctx->pending_len], data, flen); + mctx->pending_len += flen; + data += flen; + len -= flen; + + if (mctx->pending_len < 4) + return; + + mctx->l ^= get_le32(mctx->pending); + michael_block(mctx->l, mctx->r); + mctx->pending_len = 0; + } + + while (len >= 4) { + mctx->l ^= get_le32(data); + michael_block(mctx->l, mctx->r); + data += 4; + len -= 4; + } + + if (len > 0) { + mctx->pending_len = len; + memcpy(mctx->pending, data, len); + } +} + + +static void michael_final(void *ctx, u8 *out) +{ + struct michael_mic_ctx *mctx = ctx; + u8 *data = mctx->pending; + + /* Last block and padding (0x5a, 4..7 x 0) */ + switch (mctx->pending_len) { + case 0: + mctx->l ^= 0x5a; + break; + case 1: + mctx->l ^= data[0] | 0x5a00; + break; + case 2: + mctx->l ^= data[0] | (data[1] << 8) | 0x5a0000; + break; + case 3: + mctx->l ^= data[0] | (data[1] << 8) | (data[2] << 16) | + 0x5a000000; + break; + } + michael_block(mctx->l, mctx->r); + /* l ^= 0; */ + michael_block(mctx->l, mctx->r); + + put_le32(out, mctx->l); + put_le32(out + 4, mctx->r); +} + + +static int michael_setkey(void *ctx, const u8 *key, unsigned int keylen, + u32 *flags) +{ + struct michael_mic_ctx *mctx = ctx; + if (keylen != 8) { + if (flags) + *flags = CRYPTO_TFM_RES_BAD_KEY_LEN; + return -1; + } + mctx->l = get_le32(key); + mctx->r = get_le32(key + 4); + return 0; +} + + +static struct crypto_alg michael_mic_alg = { + .cra_name = "michael_mic", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .cra_blocksize = 8, + .cra_ctxsize = sizeof(struct michael_mic_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(michael_mic_alg.cra_list), + .cra_u = { .digest = { + .dia_digestsize = 8, + .dia_init = michael_init, + .dia_update = michael_update, + .dia_final = michael_final, + .dia_setkey = michael_setkey } } +}; + + +static int __init michael_mic_init(void) +{ + return crypto_register_alg(&michael_mic_alg); +} + + +static void __exit michael_mic_exit(void) +{ + crypto_unregister_alg(&michael_mic_alg); +} + + +module_init(michael_mic_init); +module_exit(michael_mic_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Michael MIC"); +MODULE_AUTHOR("Jouni Malinen <jkmaline@cc.hut.fi>"); -- Jouni Malinen PGP id EFC895FA ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-06 18:46 Crypto API and keyed non-HMAC digest algorithms / Michael MIC Jouni Malinen @ 2004-03-08 14:45 ` James Morris 2004-03-09 3:37 ` Jouni Malinen 0 siblings, 1 reply; 52+ messages in thread From: James Morris @ 2004-03-08 14:45 UTC (permalink / raw) To: Jouni Malinen; +Cc: David S. Miller, linux-kernel On Sat, 6 Mar 2004, Jouni Malinen wrote: > Current Linux crypto API does not seem to have generic mechanism for > adding keyed digest algorithms that are not using HMAC construction. > IEEE 802.11i/WPA uses such an algorithm in TKIP and getting this to > crypto API would be useful in order to be able to share more code of > TKIP implementation. > > One straightforward way of adding support for Michael MIC is to add an > optional setkey operation for digest algorithms. The included patch > (against Linux 2.6.4-rc2) does exactly this and also includes an > implementation of Michael MIC. Another option would be to add a new > algorithm type for keyed hash algorithms, but that seemed unnecessary > for this purpose. Is the modification of digest type acceptable way of > adding support for a keyed digest algorithm that does not use HMAC? I think it would be better to do the latter, add another mode for simple keyed digest processing (KMAC?), where a function called something like kmac_init() takes the tfm/key/kelen paramters. The kmac_update() and kmac_final() methods are just wrappers around the digest methods, and we also kmac_kmac() similar to the HMAC method. This would be a config option. > The patch includes test vectors for Michael MIC and I have tested this > with the Host AP driver and TKIP. Getting this into crypto API is one of > the first steps in replacing the internal crypto algorithm > implementation in the Host AP driver code and I would appreciate it if > this would be applied to Linux 2.6 tree. Is there an 802.11i spec available? It seems like there are only drafts available which require payment. I'd like to see the Micheal MIC algorithm description & know of any potential IP rights issues. Also, is there any mainline kernel code which would use this feature? - James -- James Morris <jmorris@redhat.com> ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-08 14:45 ` James Morris @ 2004-03-09 3:37 ` Jouni Malinen 2004-03-09 5:55 ` James Morris 0 siblings, 1 reply; 52+ messages in thread From: Jouni Malinen @ 2004-03-09 3:37 UTC (permalink / raw) To: James Morris; +Cc: David S. Miller, linux-kernel On Mon, Mar 08, 2004 at 09:45:39AM -0500, James Morris wrote: > On Sat, 6 Mar 2004, Jouni Malinen wrote: > > One straightforward way of adding support for Michael MIC is to add an > > optional setkey operation for digest algorithms. The included patch > > (against Linux 2.6.4-rc2) does exactly this and also includes an > > implementation of Michael MIC. Another option would be to add a new > > algorithm type for keyed hash algorithms, but that seemed unnecessary > > for this purpose. > I think it would be better to do the latter, add another mode for > simple keyed digest processing (KMAC?), where a function called something > like kmac_init() takes the tfm/key/kelen paramters. The kmac_update() and > kmac_final() methods are just wrappers around the digest methods, and we > also kmac_kmac() similar to the HMAC method. Hmm.. HMAC can do this easily, since that construction uses plain digest functions and just hashes the key with them. Michael MIC initializes some of the internal state (L and R in the implementation) with the key. This would mean that the kmac_init() would need to know something about the used digest algorithm or we would need to have setkey handler for the digests (which is actually the way I implemented Michael MIC in the original patch). crypto_kmac() can be implemented, if that is considered useful wrapper for Michael MIC. However, I'm not sure whether the other part of this would work very well with Michael MIC. In addition, I'm not sure whether there would be another algorithm using this new keyed has method. HMAC and CBC-MAC (which, btw, is also on my list of crypto API things to do for IEEE 802.11i) are using more generic mechanism and can be used with multiple algorithms and are probably prefered for anything that requires real security. If you prefer, I can make a new type crypto alg type (CRYPTO_ALG_TYPE_KEYED_DIGEST) and make it a clone of the CRYPTO_ALG_TYPE_DIGEST with the only change of adding a new callback, setkey, in the way I added in the patch for CRYPTO_ALG_TYPE_DIGEST. This would leave the digest type unmodified, but would result in copying most of the digest code. I do not see much benefit of this because the dia_setkey function pointer does not seem to change the old digest functionality at all since it is optional and since this function pointer does not even enlarge struct crypto_alg due to the cra_u union already being a bit larger than the current struct digest_alg. > Is there an 802.11i spec available? It seems like there are only drafts > available which require payment. I'd like to see the Micheal MIC > algorithm description & know of any potential IP rights issues. IEEE 802.11i draft is not freely available. The finalized standard is likely to become freely available six month after its publications (I would guess this would be about early 2005 or so). However, the proposal for Michael MIC is available from http://grouper.ieee.org/groups/802/11/Documents/DocumentHolder/2-020.zip. This includes full description of the algorithm, analysis of it and reasoning for the compromises needed for TKIP. I haven't verified, but I would assume that this matches with the algorithm as defined in the current IEEE 802.11i draft. As far as IP rights (I would assume you mean patents, in this case) are concerned, IEEE has a policy* of requiring a statement about potential patent application on the algorithms used in the standards. I do not remember seeing such a statement about Michael MIC (of course this does not mean that there is not one, but at least I haven't seen one) and could not find such a statement in the IEEE 802.11 patent statements**. In addition, the author of Michael MIC proposal has put the reference implementation code in the public domain. *) http://standards.ieee.org/guides/bylaws/sect6-7.html#6 **) http://standards.ieee.org/db/patents/pat802_11.html > Also, is there any mainline kernel code which would use this feature? Well, the main goal for me here is to get Host AP driver in shape for mainline inclusion.. ;-) The only use for Michael MIC seems to be in implementing TKIP since it is not very secure (due to compromises needed to support old legacy wlan hardware). This is needed for wireless LAN cards that cannot or at least do not implement TKIP in hardware/firmware. It may also be useful, if the hardware implementation does not support all needed modes (e.g., AP) or is considered too slow. Some of the current IEEE 802.11b drivers in the mainline kernel would be likely canditates for using this when WPA/IEEE 802.11i support is added. -- Jouni Malinen PGP id EFC895FA ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-09 3:37 ` Jouni Malinen @ 2004-03-09 5:55 ` James Morris 2004-03-09 17:30 ` Clay Haapala 0 siblings, 1 reply; 52+ messages in thread From: James Morris @ 2004-03-09 5:55 UTC (permalink / raw) To: Jouni Malinen; +Cc: David S. Miller, linux-kernel On Mon, 8 Mar 2004, Jouni Malinen wrote: > This would mean that the kmac_init() would need to know something about > the used digest algorithm or we would need to have setkey handler for > the digests (which is actually the way I implemented Michael MIC in the > original patch). You're correct. > In addition, I'm not sure whether there would be another algorithm using > this new keyed has method. HMAC and CBC-MAC (which, btw, is also on my > list of crypto API things to do for IEEE 802.11i) are using more generic > mechanism and can be used with multiple algorithms and are probably > prefered for anything that requires real security. There are several potential MAC processing modes to be added, XCBC-MAC, OMAC, RMAC etc. Do you know if any are likely to benefit from a setkey method for digests? > If you prefer, I can make a new type crypto alg type > (CRYPTO_ALG_TYPE_KEYED_DIGEST) and make it a clone of the > CRYPTO_ALG_TYPE_DIGEST with the only change of adding a new callback, > setkey, in the way I added in the patch for CRYPTO_ALG_TYPE_DIGEST. This > would leave the digest type unmodified, but would result in copying most > of the digest code. I do not see much benefit of this because the > dia_setkey function pointer does not seem to change the old digest > functionality at all since it is optional and since this function > pointer does not even enlarge struct crypto_alg due to the cra_u union > already being a bit larger than the current struct digest_alg. Agreed. I really wanted to keep digests 'pure', and not implement a setkey method, but it seems like the simplest way at this stage. > would guess this would be about early 2005 or so). However, the proposal > for Michael MIC is available from > http://grouper.ieee.org/groups/802/11/Documents/DocumentHolder/2-020.zip. Thanks for the pointer. - James -- James Morris <jmorris@redhat.com> ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-09 5:55 ` James Morris @ 2004-03-09 17:30 ` Clay Haapala 2004-03-09 20:32 ` James Morris 0 siblings, 1 reply; 52+ messages in thread From: Clay Haapala @ 2004-03-09 17:30 UTC (permalink / raw) To: James Morris; +Cc: Jouni Malinen, David S. Miller, linux-kernel On Tue, 9 Mar 2004, James Morris uttered the following: > On Mon, 8 Mar 2004, Jouni Malinen wrote: >> If you prefer, I can make a new type crypto alg type >> (CRYPTO_ALG_TYPE_KEYED_DIGEST) and make it a clone of the >> CRYPTO_ALG_TYPE_DIGEST with the only change of adding a new >> callback, setkey, in the way I added in the patch for >> CRYPTO_ALG_TYPE_DIGEST. This would leave the digest type >> unmodified, but would result in copying most of the digest code. I >> do not see much benefit of this because the dia_setkey function >> pointer does not seem to change the old digest functionality at all >> since it is optional and since this function pointer does not even >> enlarge struct crypto_alg due to the cra_u union already being a >> bit larger than the current struct digest_alg. > > Agreed. I really wanted to keep digests 'pure', and not implement a > setkey method, but it seems like the simplest way at this stage. > I had the same thought in my attempt at adding CRC32C to the crypto routines, that what was needed was "digests + setkey". But I didn't want to add the key baggage to digests, and so created a new alg type (CHKSUM), with pretty much identical code to digest, but with a modified init and a new setkey interface. So, we could modify digests now, or perhaps Jouni and I could combine our code into a new KEYED_DIGEST type and leave digests 'pure'. What's best? -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD Windows XP 'Reloaded'? *Reloaded?* Have they no sense of irony? ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-09 17:30 ` Clay Haapala @ 2004-03-09 20:32 ` James Morris 2004-03-10 3:40 ` Jouni Malinen 0 siblings, 1 reply; 52+ messages in thread From: James Morris @ 2004-03-09 20:32 UTC (permalink / raw) To: Clay Haapala; +Cc: Jouni Malinen, David S. Miller, linux-kernel On Tue, 9 Mar 2004, Clay Haapala wrote: > On Tue, 9 Mar 2004, James Morris uttered the following: > > Agreed. I really wanted to keep digests 'pure', and not implement a > > setkey method, but it seems like the simplest way at this stage. > > > I had the same thought in my attempt at adding CRC32C to the crypto > routines, that what was needed was "digests + setkey". But I didn't > want to add the key baggage to digests, and so created a new alg type > (CHKSUM), with pretty much identical code to digest, but with a > modified init and a new setkey interface. > > So, we could modify digests now, or perhaps Jouni and I could combine > our code into a new KEYED_DIGEST type and leave digests 'pure'. > What's best? I think that adding a setkey method for digests is the simplest approach. - James -- James Morris <jmorris@redhat.com> ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-09 20:32 ` James Morris @ 2004-03-10 3:40 ` Jouni Malinen 2004-03-10 4:02 ` [PATCH] Crypto API and " Jouni Malinen ` (2 more replies) 0 siblings, 3 replies; 52+ messages in thread From: Jouni Malinen @ 2004-03-10 3:40 UTC (permalink / raw) To: James Morris; +Cc: Clay Haapala, David S. Miller, linux-kernel > On Tue, 9 Mar 2004, Clay Haapala wrote: > > I had the same thought in my attempt at adding CRC32C to the crypto > > routines, that what was needed was "digests + setkey". But I didn't > > want to add the key baggage to digests, and so created a new alg type > > (CHKSUM), with pretty much identical code to digest, but with a > > modified init and a new setkey interface. On Tue, Mar 09, 2004 at 03:32:58PM -0500, James Morris wrote: > I think that adding a setkey method for digests is the simplest approach. I took a quick look at the CRC32C patch and it looked like the only needed change for the digest type was the new handler for setting a 32-bit seed. I used setkey handler that takes an arbitrary key data and length (Michael MIC uses 64-bit key/seed). As far as I could tell, this setkey function should be enough for CRC32C needs, too. Clay, please let me know if I missed something here. James, please consider merging this into Linux 2.6 tree if there are no issues with CRC32C. The patch below includes only the setkey addition from my previous patch. This is against current linus-2.5 BK tree. I will re-diff and send Michael MIC portion of the patch separately. Re-diffing was needed anyway, since ARC4 addition had a small conflict with the Michael MIC patch. You can import this changeset into BK by piping this whole message to: '| bk receive [path to repository]' or apply the patch as usual. =================================================================== ChangeSet@1.1689, 2004-03-09 18:54:50-08:00, jkmaline@cc.hut.fi Added support for using keyed digest with an optional dit_setkey handler. This does not change the behavior of the existing digest algorithms, but allows new ones to add setkey handler that can be used to initialize the algorithm with a key or seed. setkey is to be called after init, but before any of the update call(s). crypto/digest.c | 10 ++++++++++ crypto/tcrypt.c | 4 ++++ crypto/tcrypt.h | 2 ++ include/linux/crypto.h | 13 +++++++++++++ 4 files changed, 29 insertions(+) diff -Nru a/crypto/digest.c b/crypto/digest.c --- a/crypto/digest.c Tue Mar 9 18:58:22 2004 +++ b/crypto/digest.c Tue Mar 9 18:58:22 2004 @@ -42,6 +42,15 @@ tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out); } +static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) +{ + u32 flags; + if (tfm->__crt_alg->cra_digest.dia_setkey == NULL) + return -1; + return tfm->__crt_alg->cra_digest.dia_setkey(crypto_tfm_ctx(tfm), + key, keylen, &flags); +} + static void digest(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg, u8 *out) { @@ -72,6 +81,7 @@ ops->dit_update = update; ops->dit_final = final; ops->dit_digest = digest; + ops->dit_setkey = setkey; return crypto_alloc_hmac_block(tfm); } diff -Nru a/crypto/tcrypt.c b/crypto/tcrypt.c --- a/crypto/tcrypt.c Tue Mar 9 18:58:22 2004 +++ b/crypto/tcrypt.c Tue Mar 9 18:58:22 2004 @@ -112,6 +112,10 @@ sg[0].length = hash_tv[i].psize; crypto_digest_init (tfm); + if (tfm->crt_u.digest.dit_setkey) { + crypto_digest_setkey (tfm, hash_tv[i].key, + hash_tv[i].ksize); + } crypto_digest_update (tfm, sg, 1); crypto_digest_final (tfm, result); diff -Nru a/crypto/tcrypt.h b/crypto/tcrypt.h --- a/crypto/tcrypt.h Tue Mar 9 18:58:22 2004 +++ b/crypto/tcrypt.h Tue Mar 9 18:58:22 2004 @@ -30,6 +30,8 @@ char digest[MAX_DIGEST_SIZE]; unsigned char np; unsigned char tap[MAX_TAP]; + char key[128]; /* only used with keyed hash algorithms */ + unsigned char ksize; }; struct hmac_testvec { diff -Nru a/include/linux/crypto.h b/include/linux/crypto.h --- a/include/linux/crypto.h Tue Mar 9 18:58:22 2004 +++ b/include/linux/crypto.h Tue Mar 9 18:58:22 2004 @@ -76,6 +76,8 @@ void (*dia_init)(void *ctx); void (*dia_update)(void *ctx, const u8 *data, unsigned int len); void (*dia_final)(void *ctx, u8 *out); + int (*dia_setkey)(void *ctx, const u8 *key, + unsigned int keylen, u32 *flags); }; struct compress_alg { @@ -157,6 +159,8 @@ void (*dit_final)(struct crypto_tfm *tfm, u8 *out); void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg, u8 *out); + int (*dit_setkey)(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen); #ifdef CONFIG_CRYPTO_HMAC void *dit_hmac_block; #endif @@ -280,6 +284,15 @@ { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); tfm->crt_digest.dit_digest(tfm, sg, nsg, out); +} + +static inline int crypto_digest_setkey(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + if (tfm->crt_digest.dit_setkey == NULL) + return -1; + return tfm->crt_digest.dit_setkey(tfm, key, keylen); } static inline int crypto_cipher_setkey(struct crypto_tfm *tfm, =================================================================== This BitKeeper patch contains the following changesets: 1.1689 ## Wrapped with gzip_uu ## M'XL( $Z$3D ]586T_C.!1^CG^%5R.MVBY-[<1IDR(0<T$L&C0@!AY&LZ/( M==PFT,;=V(%AI_/?]^324B!<=QX6ETOK.-_Y?/R=2_H&GVJ9#:VS\QF?)JE$ M;_"?2INA)80=Y\8>)S!SK!3,]/[NG<UZH_.>3OE<Q\IT'=M#</F(&Q'C"YGI MH45M=S5CKN9R:!WO[IT>O#U&:&L+OX]Y.I&?I<%;6\BH[()/([W#33Q5J6TR MGNJ9--P6:K98+5TXA#CP\NC )5Y_0?N$#1:"1I1R1F5$'.;WV37:?"Z" ;&5 MCJ:VRB8W@1AQ*2&4N)ZWH)X[<-$'3&W:]P-,6(^X/1)@Z@\]-O1(E_A#0O#2 M,SLKC^ _&.X2] [_VAV\1P*_C2(989W/YRHS>*PRG.LDG>!S>07S43*1VN#+ MQ,28IUC-3:)2/H5Y$VII8!$&F]%49C9@G<2)QI&2&J?*8%&RP2:6>"1C?I$ MMAJ7G^7W1)O"2HW/IQ.5@8V9WL"CW 4GT[5)>#(2ZQ2 #0*\PAXWK )6!SL M +&1!-K %Y8E:6(2\-\_I>D2J@:OMU%L#0,7+65D+Q&3T@3 "+ ,0'QL +_ M*AG!%7!-B99>+7>1SR-NJCM:NFVCCYBR@3- 1]>J0]UG#H0()V@;1_Q"SG;2 MW&@[3=)S;J=PJB*[FAO5,^5_.RY/F<)94CAC%BR<XMW"8](+N.SW)1UY;M D MIR:@2J<."URV8(/ "^XCD:1BFD>R!Y#Y]UZ%=(L+*,YA ]=;^"0@A 14B&@D M/"&;N-R/MT[)<3S7?<0OE9AL<<<OQ'/I(G $%1!VCO <'OG. WY9!UHGT:>> M\QB)VJ=W25 WH LN!9R*&(]&Q.4C-G[\<.Z0 #_X3IG;;K$M,MRO<P\ZFZDL M2_1.DD(D"!7)(L78/&^"<XGK!)32ON<OW $E09WD;J0X%@Q=]D"*H^3_G^,^ MXDH#A[B;7=8_$.^W7/*"J-]G# =(&VX2 6G'U'FII4V6"U,;",UXACOP9P,+ ME0+GW,<=6+6!\U0GDQ0V4]P*,U.9MM$/9.6N@\=3/M&;R$K&N 7W=K?#4&0F MA+38W189#VO64<*7VP5M?3H].&@CR\JDR;,4=RD U.^?A-&Z9AP*\[TPW-X MO&+@8I2T*Z8;^/>28WL3_41_H?T!PQ19:JZ[V]=G8&W5+ME<U_XR2![3_O.B M$IVI=&>L(+''JCA/D%US4,*O3QES%PQBTB]%#PY_CNA?05W_B*N4TZSYI4=> MHGE*&68@BI4R"TWE]DI,2RYM_*.03BVIZO*29JL,AYCK.#077Y-O=B$L=*VS M&Y<T= 6@,LOZV2"B^(DB>F+=?51$\1T108X?5)DS>):(G-<@HJJI>%!$\4M$ M! 'G( N:S:R@]94Z_K=-W.M VSB]JIK"DF!%N1##6K>).SW(D<O<66$4&JER M3'-G<J]*_DMCA&97._-")KD!+VM;RP?@7-"+3ZM'"O#JH$X\Y'G5UGT-HJG: MOENB:?;,2[0S\ OM%#6SU;FN7>W6A4HBW(&Z=;O0HCJIK(^&V@L%&63965:U M?>H%ZX96>>V^\MYDY@D5'RPYT-@&91E=]1+%R9>KFO+GO0SN$F@<3^Q#WIWN MA8>?UIL"",*P>%PO.P/\&SRI'W\Y.CD,WQ[LA2=?CG;##_M[NY]/VNN-2U$> I[A2'IW0KC3=6E6.M#P%;JV\21"S%N<YG6R/6'Y$Q<=&_I7&6K[@0 -- Jouni Malinen PGP id EFC895FA ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH] Crypto API and Michael MIC 2004-03-10 3:40 ` Jouni Malinen @ 2004-03-10 4:02 ` Jouni Malinen 2004-03-10 4:21 ` Crypto API and keyed non-HMAC digest algorithms / " James Morris 2004-03-10 16:04 ` Clay Haapala 2 siblings, 0 replies; 52+ messages in thread From: Jouni Malinen @ 2004-03-10 4:02 UTC (permalink / raw) To: James Morris; +Cc: David S. Miller, linux-kernel On Tue, Mar 09, 2004 at 07:40:14PM -0800, Jouni Malinen wrote: > The patch below includes only the setkey addition from my previous > patch. This is against current linus-2.5 BK tree. I will re-diff and > send Michael MIC portion of the patch separately. Re-diffing was needed > anyway, since ARC4 addition had a small conflict with the Michael MIC > patch. And here's the re-diffed patch for adding Michael MIC. This requires the setkey patch for digest type that I just sent. I tested this new patch of Michael MIC with Linux 2.6.4-rc3 and Host AP driver. The patch is against linus-2.5 BK tree. Please consider merging into Linux 2.6. You can import this changeset into BK by piping this whole message to: '| bk receive [path to repository]' or apply the patch as usual. =================================================================== ChangeSet@1.1690, 2004-03-09 19:17:59-08:00, jkmaline@cc.hut.fi Added Michael MIC keyed digest for TKIP (IEEE 802.11i/WPA). This algorithm is quite weak due to the requirements for compatibility with old legacy wireless LAN hardware that does not have much CPU power. Consequently, this should not really be used with anything else than TKIP. Michael MIC is calculated over the payload of the IEEE 802.11 header which makes it easier to add TKIP support for old wireless LAN cards. An additional authenticated data area is used (but not send separately) to authenticate source and destination addresses. Documentation/crypto/api-intro.txt | 1 crypto/Kconfig | 9 + crypto/Makefile | 1 crypto/michael_mic.c | 193 +++++++++++++++++++++++++++++++++++++ crypto/tcrypt.c | 8 + crypto/tcrypt.h | 50 +++++++++ 6 files changed, 261 insertions(+), 1 deletion(-) diff -Nru a/Documentation/crypto/api-intro.txt b/Documentation/crypto/api-intro.txt --- a/Documentation/crypto/api-intro.txt Tue Mar 9 19:20:04 2004 +++ b/Documentation/crypto/api-intro.txt Tue Mar 9 19:20:04 2004 @@ -187,6 +187,7 @@ Brian Gladman (AES) Kartikey Mahendra Bhatt (CAST6) Jon Oberheide (ARC4) + Jouni Malinen (Michael MIC) SHA1 algorithm contributors: Jean-Francois Dive diff -Nru a/crypto/Kconfig b/crypto/Kconfig --- a/crypto/Kconfig Tue Mar 9 19:20:04 2004 +++ b/crypto/Kconfig Tue Mar 9 19:20:04 2004 @@ -161,6 +161,15 @@ You will most probably want this if using IPSec. +config CRYPTO_MICHAEL_MIC + tristate "Michael MIC keyed digest algorithm" + depends on CRYPTO + help + Michael MIC is used for message integrity protection in TKIP + (IEEE 802.11i). This algorithm is required for TKIP, but it + should not be used for other purposes because of the weakness + of the algorithm. + config CRYPTO_TEST tristate "Testing module" depends on CRYPTO diff -Nru a/crypto/Makefile b/crypto/Makefile --- a/crypto/Makefile Tue Mar 9 19:20:04 2004 +++ b/crypto/Makefile Tue Mar 9 19:20:04 2004 @@ -23,5 +23,6 @@ obj-$(CONFIG_CRYPTO_CAST6) += cast6.o obj-$(CONFIG_CRYPTO_ARC4) += arc4.o obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o +obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o diff -Nru a/crypto/michael_mic.c b/crypto/michael_mic.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/crypto/michael_mic.c Tue Mar 9 19:20:04 2004 @@ -0,0 +1,193 @@ +/* + * Cryptographic API + * + * Michael MIC (IEEE 802.11i/TKIP) keyed digest + * + * Copyright (c) 2004 Jouni Malinen <jkmaline@cc.hut.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/crypto.h> + + +struct michael_mic_ctx { + u8 pending[4]; + size_t pending_len; + + u32 l, r; +}; + + +static inline u32 rotl(u32 val, int bits) +{ + return (val << bits) | (val >> (32 - bits)); +} + + +static inline u32 rotr(u32 val, int bits) +{ + return (val >> bits) | (val << (32 - bits)); +} + + +static inline u32 xswap(u32 val) +{ + return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8); +} + + +#define michael_block(l, r) \ +do { \ + r ^= rotl(l, 17); \ + l += r; \ + r ^= xswap(l); \ + l += r; \ + r ^= rotl(l, 3); \ + l += r; \ + r ^= rotr(l, 2); \ + l += r; \ +} while (0) + + +static inline u32 get_le32(const u8 *p) +{ + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +} + + +static inline void put_le32(u8 *p, u32 v) +{ + p[0] = v; + p[1] = v >> 8; + p[2] = v >> 16; + p[3] = v >> 24; +} + + +static void michael_init(void *ctx) +{ + struct michael_mic_ctx *mctx = ctx; + mctx->pending_len = 0; +} + + +static void michael_update(void *ctx, const u8 *data, unsigned int len) +{ + struct michael_mic_ctx *mctx = ctx; + + if (mctx->pending_len) { + int flen = 4 - mctx->pending_len; + if (flen > len) + flen = len; + memcpy(&mctx->pending[mctx->pending_len], data, flen); + mctx->pending_len += flen; + data += flen; + len -= flen; + + if (mctx->pending_len < 4) + return; + + mctx->l ^= get_le32(mctx->pending); + michael_block(mctx->l, mctx->r); + mctx->pending_len = 0; + } + + while (len >= 4) { + mctx->l ^= get_le32(data); + michael_block(mctx->l, mctx->r); + data += 4; + len -= 4; + } + + if (len > 0) { + mctx->pending_len = len; + memcpy(mctx->pending, data, len); + } +} + + +static void michael_final(void *ctx, u8 *out) +{ + struct michael_mic_ctx *mctx = ctx; + u8 *data = mctx->pending; + + /* Last block and padding (0x5a, 4..7 x 0) */ + switch (mctx->pending_len) { + case 0: + mctx->l ^= 0x5a; + break; + case 1: + mctx->l ^= data[0] | 0x5a00; + break; + case 2: + mctx->l ^= data[0] | (data[1] << 8) | 0x5a0000; + break; + case 3: + mctx->l ^= data[0] | (data[1] << 8) | (data[2] << 16) | + 0x5a000000; + break; + } + michael_block(mctx->l, mctx->r); + /* l ^= 0; */ + michael_block(mctx->l, mctx->r); + + put_le32(out, mctx->l); + put_le32(out + 4, mctx->r); +} + + +static int michael_setkey(void *ctx, const u8 *key, unsigned int keylen, + u32 *flags) +{ + struct michael_mic_ctx *mctx = ctx; + if (keylen != 8) { + if (flags) + *flags = CRYPTO_TFM_RES_BAD_KEY_LEN; + return -1; + } + mctx->l = get_le32(key); + mctx->r = get_le32(key + 4); + return 0; +} + + +static struct crypto_alg michael_mic_alg = { + .cra_name = "michael_mic", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .cra_blocksize = 8, + .cra_ctxsize = sizeof(struct michael_mic_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(michael_mic_alg.cra_list), + .cra_u = { .digest = { + .dia_digestsize = 8, + .dia_init = michael_init, + .dia_update = michael_update, + .dia_final = michael_final, + .dia_setkey = michael_setkey } } +}; + + +static int __init michael_mic_init(void) +{ + return crypto_register_alg(&michael_mic_alg); +} + + +static void __exit michael_mic_exit(void) +{ + crypto_unregister_alg(&michael_mic_alg); +} + + +module_init(michael_mic_init); +module_exit(michael_mic_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Michael MIC"); +MODULE_AUTHOR("Jouni Malinen <jkmaline@cc.hut.fi>"); diff -Nru a/crypto/tcrypt.c b/crypto/tcrypt.c --- a/crypto/tcrypt.c Tue Mar 9 19:20:04 2004 +++ b/crypto/tcrypt.c Tue Mar 9 19:20:04 2004 @@ -61,7 +61,7 @@ static char *check[] = { "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", - "arc4", "deflate", NULL + "arc4", "michael_mic", "deflate", NULL }; static void @@ -572,6 +572,8 @@ test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS); test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS); #endif + + test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); break; case 1: @@ -649,6 +651,10 @@ case 16: test_cipher ("arc4", MODE_ECB, ENCRYPT, arc4_enc_tv_template, ARC4_ENC_TEST_VECTORS); test_cipher ("arc4", MODE_ECB, DECRYPT, arc4_dec_tv_template, ARC4_DEC_TEST_VECTORS); + break; + + case 17: + test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); break; #ifdef CONFIG_CRYPTO_HMAC diff -Nru a/crypto/tcrypt.h b/crypto/tcrypt.h --- a/crypto/tcrypt.h Tue Mar 9 19:20:04 2004 +++ b/crypto/tcrypt.h Tue Mar 9 19:20:04 2004 @@ -1721,4 +1721,54 @@ }, }; +/* + * Michael MIC test vectors from IEEE 802.11i + */ +#define MICHAEL_MIC_TEST_VECTORS 6 + +struct hash_testvec michael_mic_tv_template[] = +{ + { + .key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .ksize = 8, + .plaintext = { }, + .psize = 0, + .digest = { 0x82, 0x92, 0x5c, 0x1c, 0xa1, 0xd1, 0x30, 0xb8 } + }, + { + .key = { 0x82, 0x92, 0x5c, 0x1c, 0xa1, 0xd1, 0x30, 0xb8 }, + .ksize = 8, + .plaintext = { 'M' }, + .psize = 1, + .digest = { 0x43, 0x47, 0x21, 0xca, 0x40, 0x63, 0x9b, 0x3f } + }, + { + .key = { 0x43, 0x47, 0x21, 0xca, 0x40, 0x63, 0x9b, 0x3f }, + .ksize = 8, + .plaintext = { 'M', 'i' }, + .psize = 2, + .digest = { 0xe8, 0xf9, 0xbe, 0xca, 0xe9, 0x7e, 0x5d, 0x29 } + }, + { + .key = { 0xe8, 0xf9, 0xbe, 0xca, 0xe9, 0x7e, 0x5d, 0x29 }, + .ksize = 8, + .plaintext = { 'M', 'i', 'c' }, + .psize = 3, + .digest = { 0x90, 0x03, 0x8f, 0xc6, 0xcf, 0x13, 0xc1, 0xdb } + }, + { + .key = { 0x90, 0x03, 0x8f, 0xc6, 0xcf, 0x13, 0xc1, 0xdb }, + .ksize = 8, + .plaintext = { 'M', 'i', 'c', 'h' }, + .psize = 4, + .digest = { 0xd5, 0x5e, 0x10, 0x05, 0x10, 0x12, 0x89, 0x86 } + }, + { + .key = { 0xd5, 0x5e, 0x10, 0x05, 0x10, 0x12, 0x89, 0x86 }, + .ksize = 8, + .plaintext = { 'M', 'i', 'c', 'h', 'a', 'e', 'l' }, + .psize = 7, + .digest = { 0x0a, 0x94, 0x2b, 0x12, 0x4e, 0xca, 0xa5, 0x46 }, + } +}; #endif /* _CRYPTO_TCRYPT_H */ =================================================================== This BitKeeper patch contains the following changesets: 1.1690 ## Wrapped with gzip_uu ## M'XL( &2)3D ]U:>5/;2!;_V_H4;\G6C,U@6Z</"%08<(@W7 5F=J=(UM66 M6K:"+&ET )Z8[[[OM61;OL!0DZJIY9#=U^^=_?IUJ]_!3<3#W<*WNR%S'8]+ M[^"3'\6[!=.L#)*X8CM8<^7[6%/]H_IM6.W=52./!=' C\MJQ9"P^9+%Y@#N M>1CM%I2*-JV)1P'?+5RU3FY.#Z\D:7\?C@;,Z_-K'L/^OA3[X3USK>@#BP>N M[U7BD'G1D,>L8OK#\;3K6)5E%7\-I:[)1FVLU&2]/C852U&8KG!+5O5&39<F M GR8,CX/H<N:@D"&;LAC1:^K=>D8E(I2:\H@ZU59J\I-4)J[2GW7:);EQJXL MPS(D_%*#LBS]"G\M[T>2"8>6Q2TX<\P!XRZ<M8_@CH^PQG+Z/(K!]D/H?&Y? M0K'=:K6@(:L517&J_[X\+%6@,W B8&[?#YUX,$0P+/Z1.#&'!\[NP$HX,@SQ M@$/(L3[D0^[%D<!$=@,6.SW'=>(1/.!X\%T+7-YGY@B1'K"WRZ,(3@_/8<!" MZX&%B#9@,5@^C\#S8ZR^YS!,T.)'ES<0^ \\K,"1[T5(# FYHQT<X$2(AEZ3 M(#H-"CESW1'T."01BBDH,V^$';T^<#<21#PA<P5'XE]>-RB@R5PS<5F,@WWT M/2%>P$:NS[#"%L6<JF# F86]'@:(@F!#=H?<.S%P%CDTV@=F6:F*HR0(_##5 M.2EC3@<FZB"JP*%'_9W8\3WF(AY+D* 7.Z9@R&(Q U04(T:%?,5>$@NY(^Y9 M^ A8B#W=44E0S@TF+?E):'+4!@*A[1V/$1FB%R(7/*I(GT&M*:HF7<YFE%1^ MY8\DR4R6#E9X^=@,1T'L5X>IPKOX63%G<TA3ZC2'ZGJS-M;LAF9:6MVL:0U+ M,^IO0U/&JMJ4:\B,A:XT_. E<53Q'.^.53R<1!E +#XK S&I%)PZ"DXIO8EC M\=O8T+G19+Q6XTK/T)JK9N\JH+Q(LJ(H&C+QIQ,$W/V @Y/'\K#6N*OX8?]V M,N6_3F ^F[YG._V,'0VQ-%5KC)6&WFR,C5I-J<N&H=E*LZY;VC/LY'#FN-%T M57M!)6?HQ;;C\D65* W-4,<-;O;JNEHS=,O06>,9%O(X>1YJNEY;R\.Q;R84 M2(1W5C,D%CAEQXM#OQ(_QA.VFHJ"]E709QI*<VSWM)Y=MPQ5MU7-UE>QM1ET MGE.CB:%],P<REQQ(T9K*F'$3/<>T>SU98SW=?MF!EN:$K)$7TT+WL@"T OY( MM4K??.^#[6.4'.!Z+I:EC;6*_PU%US7TXD9=3A?*YM(R*3^S3"I_PV42HV;J M)1=0#A^R/PRA+ZOE#;&UK31041+ O_S$<^!,:,B#8H[SDO"4A1FXUBW>,N-7 M^,#J"3\U>$VNR:G!5>W_P>!I %LP^((.WF)=U4#C^KUOY7\6CR[./[9/ND=7 MOU]V+KK(X*?#UBE]EN"7?<BO>G[>X),8\I+!7Q>T5J7!:X.6JC<U?6QH6D,5 M)M=>9_(ZE)6_H<E%#%YM\8D*WF#QXYJ.%F^+9V&+A::^M0-;.>M2T>(V):3X M]?SF]%1J&W4=5.F+5"C$R'AWP*)!<6%,KM2-[[LQ'P8$L0,Y1^IV6M>=[F^M MH\[%U75I#[DP%- 1M8<9YMT>$3 9)LQHL+^:U++##C9TV W3M)<==K#HL'J] M:333&+6\=WO.80WY1P6IO*^2_G$S;"(5W&*%_C"_#7'(0T6:^:R'#MZTXM0Q M9ANR5-V68/L5+&'OJO0.?1?5M=87H(9N%L5A8M)^+QIT"1,AUWG5[5?8E[Y+ M!?PK5'#ZPCY\!_E1EG<V?L+3CA@<.7_BL@@-44)P7)8YY4\(F/8(LAZR*&51 M(J774 FK*9Z&24]%/)E"3TL\-4&OUX GJ4" "RR_#N)%EG\^^WF!;669;5TC M/+U.3U50,)FH$71JHK79$Y3M-6R_#F(3MG?@9V>1=W69=]X@4+LI-,)GA+FH MJ8L:PQ)L-=?P_CJ(C7G'A[DH@+8L0#/U/Z&AABVHU\13?%=$O9D:O[=&@-=! MO$X ? P6I="7I; ,H26A*R5EQYA]5X0[-X0^&[4U4KP.X@U2X(/1@]/#712J MOBR4+-R@J0O3]V9<Z#DG88)'/>7H27J:6\3F#B%H)3OG#T!)X.[*'I(-'%?: MW_#_F87J#><D8OEZW>KU0Q8O$WYUXL^<!SP4:H"5A[S5E;K!A8QDFRU>\\U7 ML"3T?T0X5=ZPN/T [2NOV]\TM1^3/'S$A/(SI.=?LYR@7%ZGUC<D!C(*J&5I MP9' [(<L&#B8:5^VL7(Q79C/JRG5+LUEX-F0(S\8A4Y_$$/1+ $I?F&S^WY9 MD0?96'%B'83$R)#.2.V0<XA\.Z;CY3T8^0F8S(.06PXF'4XOB3D=UC+/JF+V M/_0MQQX1#M8EGI6=_L8\'$:3L]^3\QLXX1X/F0N72<]%:4\=DWN8)].;"CI0 M58%%!!)0<S1 ^7HC,?8C<7.=<0,?42A+' Y41*KT17KG>*:;6!S>BS/"JN,Y MF+,=+-4CGXG+5[604%Y_54MJ=&KY,LNX\DF6&3\"!NJD 0'W+$2YU;_N204* MFMUX4M=UN2<V!HFF@KL#X1X%PA0113'!\<@P0,VA'[M%^H)^O8,-,?2<."I1 M]A;R. D]*&(+O'^?UL,X+1\<0!$'E=-:W"L\K<</-\!'O#E\I+<9_F/TP(() M@3E8@?.32"9MF_Y+A-H0)*9M:8LLEXB#QI3.)"&>J+[G^N9=D519*GR1+!^^ M%_ '-1S"?_=3'6*C4B_M4:5+>_]P+]<CY=+%YM7M$P1M'8!0(W90ESL\T6L- M#-Y%N;1&1WT>HTMH:M'T/5Q-T7FV@[RJ@EOY*VDEN%6^SG04W*JBI-2RHB:* MJK[&&O>^8^%LRD@)(CN"_+V@)8CLP_T>?57$5Z%S45:G9:4F*K1IA:HOD!-T M)H:AR5<4-=LX-02A-;-F>TA/S 7B1Z1 A?)!;K[0#N(Y0DF 48#/2.W 3)GT MP@=%]2*G[V$<(2='Q(V907LZ-A276"K13"\0FITRJ.-\6.JU1WUPN.ASD!)& MO\B&9!V&?&@&H^)/<Z-OE["^[D J"XTNB8%+>D+'LS-4\:(K5Z;F\J3X)>-K M&>$]Z(+%U/O2GFDOEUQ]ZJUS(U-NYJ9C-F8GTTFXAF%AV )9MI!-%*$I5&>J MX%6D2;)-*4ZTH.=4H$\HD@92P\AY:O/\S1MIKL?$()D]GI[Q4 Q8S,T[*+FF MG\2;3XJ)+V/%'!/"1-5M.&7H\$(3XO5D0.] O3X&GD<#6=0KE3H\DIRX3!:B M!X=N :SQ:G%B)>_.:Y]@]F8'6]FQUD(GXB\-5]1=EI<&J&L'"*OF0UR*L )# MVQPCK<A%2O+L"? \-.ZS7G8G5'.JC#VAQA<'H&6F,1>-/6ER"2O? +_@/C$W M;B&"SUPCXC&F>ZL#'38LQ#FL09O27JT (MAOVR[K1YO['$V0% 3^L4\J_3Z- M9P('@5-(')&=LG<^GG6O6M?=7P^/NY];OW=/6^>DYFPQ*RN9JC/SY68UTBE- M8W^XT$(*HM8,9G$QR(1)$[0N<_MS<E%YGUBOF"'K>FS("_L+!\19FY"E,)7E M\/2DV_G]LM4];I^TKCN37L+<E-05TMVTJ$2VLRKZ\.WB:@67)OW3!!2[=SZU MK[MG%\<WIZU)&Z:\,;:<MJ\[W4\M5&3[O-TI+H@T[3F%3 H%VHOG]N42;=)9 M-ZW(<TRUM#H7]N<6ZTE3NI[F&M.*2;,(9KE649XTIBZ::TTKX F>EA+=&+J" M[IR6IEE#/@O*3!OR/DK,0U( +ICS&EF<.&*6=+O\<8$ 5<P(9,B)MQEV:K>4 MR46NL5/6+$@LTA0!(;5T][1]U#J_;A6W3BY/X5[=PK:LY;AU?735ONRT+\Z+ M6[F]7Z[+X4WGT\55<>OE/=W6_(N"[#X#G:[\B)L4ZU]JSE^DF+[3U-6:KJ7O M"]17[?F;?\]WFN)>R.JC@DP#;WI[4-.@*66F6WZ9*15PQTHNSV%K+>/3*VA; M4L'BM.+C=MS+T*3"@+N!A(O$PD4N<3^*9![R*&)]3E.6]T.ZCQ;@IH>;XO:3 MD]X%H_%S:EFZ_D:0V34W:ZK*':#[5TY,PW.7T":WS\1-+]SYA[A["0,_XA$V MF0S;)L<)=)'.0_X((*N:4JS@C)M>>C0''.-V,MRORS;7ZCU3^A\%*@6E8RD ! -- Jouni Malinen PGP id EFC895FA ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-10 3:40 ` Jouni Malinen 2004-03-10 4:02 ` [PATCH] Crypto API and " Jouni Malinen @ 2004-03-10 4:21 ` James Morris 2004-03-10 5:34 ` Jouni Malinen 2004-03-10 16:04 ` Clay Haapala 2 siblings, 1 reply; 52+ messages in thread From: James Morris @ 2004-03-10 4:21 UTC (permalink / raw) To: Jouni Malinen; +Cc: Clay Haapala, David S. Miller, linux-kernel On Tue, 9 Mar 2004, Jouni Malinen wrote: > +static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) > +{ > + u32 flags; > + if (tfm->__crt_alg->cra_digest.dia_setkey == NULL) > + return -1; In both patches, these 'return -1' statements should be -EINVAL, or whatever is appropriate (probably -ENOSYS for this one). - James -- James Morris <jmorris@redhat.com> ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-10 4:21 ` Crypto API and keyed non-HMAC digest algorithms / " James Morris @ 2004-03-10 5:34 ` Jouni Malinen 2004-03-10 15:45 ` James Morris 0 siblings, 1 reply; 52+ messages in thread From: Jouni Malinen @ 2004-03-10 5:34 UTC (permalink / raw) To: James Morris; +Cc: Clay Haapala, David S. Miller, linux-kernel On Tue, Mar 09, 2004 at 11:21:03PM -0500, James Morris wrote: > In both patches, these 'return -1' statements should be -EINVAL, or > whatever is appropriate (probably -ENOSYS for this one). Fixed. The included patch combines changesets for both the setkey addition and Michael MIC. Please let me know if you want to get these as separate patch files. You can import this changeset into BK by piping this whole message to: '| bk receive [path to repository]' or apply the patch as usual. =================================================================== ChangeSet@1.1692, 2004-03-09 21:12:44-08:00, jkmaline@cc.hut.fi Fixed the error return value for Michael MIC. ChangeSet@1.1691, 2004-03-09 21:08:17-08:00, jkmaline@cc.hut.fi Fixed error codes in return values of the digest setkey handler. ChangeSet@1.1690, 2004-03-09 19:17:59-08:00, jkmaline@cc.hut.fi Added Michael MIC keyed digest for TKIP (IEEE 802.11i/WPA). This algorithm is quite weak due to the requirements for compatibility with old legacy wireless LAN hardware that does not have much CPU power. Consequently, this should not really be used with anything else than TKIP. Michael MIC is calculated over the payload of the IEEE 802.11 header which makes it easier to add TKIP support for old wireless LAN cards. An additional authenticated data area is used (but not send separately) to authenticate source and destination addresses. ChangeSet@1.1689, 2004-03-09 18:54:50-08:00, jkmaline@cc.hut.fi Added support for using keyed digest with an optional dit_setkey handler. This does not change the behavior of the existing digest algorithms, but allows new ones to add setkey handler that can be used to initialize the algorithm with a key or seed. setkey is to be called after init, but before any of the update call(s). Documentation/crypto/api-intro.txt | 1 crypto/Kconfig | 9 + crypto/Makefile | 1 crypto/digest.c | 10 + crypto/michael_mic.c | 193 +++++++++++++++++++++++++++++++++++++ crypto/tcrypt.c | 12 ++ crypto/tcrypt.h | 52 +++++++++ include/linux/crypto.h | 13 ++ 8 files changed, 290 insertions(+), 1 deletion(-) diff -Nru a/Documentation/crypto/api-intro.txt b/Documentation/crypto/api-intro.txt --- a/Documentation/crypto/api-intro.txt Tue Mar 9 21:25:13 2004 +++ b/Documentation/crypto/api-intro.txt Tue Mar 9 21:25:13 2004 @@ -187,6 +187,7 @@ Brian Gladman (AES) Kartikey Mahendra Bhatt (CAST6) Jon Oberheide (ARC4) + Jouni Malinen (Michael MIC) SHA1 algorithm contributors: Jean-Francois Dive diff -Nru a/crypto/Kconfig b/crypto/Kconfig --- a/crypto/Kconfig Tue Mar 9 21:25:13 2004 +++ b/crypto/Kconfig Tue Mar 9 21:25:13 2004 @@ -161,6 +161,15 @@ You will most probably want this if using IPSec. +config CRYPTO_MICHAEL_MIC + tristate "Michael MIC keyed digest algorithm" + depends on CRYPTO + help + Michael MIC is used for message integrity protection in TKIP + (IEEE 802.11i). This algorithm is required for TKIP, but it + should not be used for other purposes because of the weakness + of the algorithm. + config CRYPTO_TEST tristate "Testing module" depends on CRYPTO diff -Nru a/crypto/Makefile b/crypto/Makefile --- a/crypto/Makefile Tue Mar 9 21:25:13 2004 +++ b/crypto/Makefile Tue Mar 9 21:25:13 2004 @@ -23,5 +23,6 @@ obj-$(CONFIG_CRYPTO_CAST6) += cast6.o obj-$(CONFIG_CRYPTO_ARC4) += arc4.o obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o +obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o diff -Nru a/crypto/digest.c b/crypto/digest.c --- a/crypto/digest.c Tue Mar 9 21:25:13 2004 +++ b/crypto/digest.c Tue Mar 9 21:25:13 2004 @@ -42,6 +42,15 @@ tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out); } +static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) +{ + u32 flags; + if (tfm->__crt_alg->cra_digest.dia_setkey == NULL) + return -ENOSYS; + return tfm->__crt_alg->cra_digest.dia_setkey(crypto_tfm_ctx(tfm), + key, keylen, &flags); +} + static void digest(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg, u8 *out) { @@ -72,6 +81,7 @@ ops->dit_update = update; ops->dit_final = final; ops->dit_digest = digest; + ops->dit_setkey = setkey; return crypto_alloc_hmac_block(tfm); } diff -Nru a/crypto/michael_mic.c b/crypto/michael_mic.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/crypto/michael_mic.c Tue Mar 9 21:25:13 2004 @@ -0,0 +1,193 @@ +/* + * Cryptographic API + * + * Michael MIC (IEEE 802.11i/TKIP) keyed digest + * + * Copyright (c) 2004 Jouni Malinen <jkmaline@cc.hut.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/crypto.h> + + +struct michael_mic_ctx { + u8 pending[4]; + size_t pending_len; + + u32 l, r; +}; + + +static inline u32 rotl(u32 val, int bits) +{ + return (val << bits) | (val >> (32 - bits)); +} + + +static inline u32 rotr(u32 val, int bits) +{ + return (val >> bits) | (val << (32 - bits)); +} + + +static inline u32 xswap(u32 val) +{ + return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8); +} + + +#define michael_block(l, r) \ +do { \ + r ^= rotl(l, 17); \ + l += r; \ + r ^= xswap(l); \ + l += r; \ + r ^= rotl(l, 3); \ + l += r; \ + r ^= rotr(l, 2); \ + l += r; \ +} while (0) + + +static inline u32 get_le32(const u8 *p) +{ + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +} + + +static inline void put_le32(u8 *p, u32 v) +{ + p[0] = v; + p[1] = v >> 8; + p[2] = v >> 16; + p[3] = v >> 24; +} + + +static void michael_init(void *ctx) +{ + struct michael_mic_ctx *mctx = ctx; + mctx->pending_len = 0; +} + + +static void michael_update(void *ctx, const u8 *data, unsigned int len) +{ + struct michael_mic_ctx *mctx = ctx; + + if (mctx->pending_len) { + int flen = 4 - mctx->pending_len; + if (flen > len) + flen = len; + memcpy(&mctx->pending[mctx->pending_len], data, flen); + mctx->pending_len += flen; + data += flen; + len -= flen; + + if (mctx->pending_len < 4) + return; + + mctx->l ^= get_le32(mctx->pending); + michael_block(mctx->l, mctx->r); + mctx->pending_len = 0; + } + + while (len >= 4) { + mctx->l ^= get_le32(data); + michael_block(mctx->l, mctx->r); + data += 4; + len -= 4; + } + + if (len > 0) { + mctx->pending_len = len; + memcpy(mctx->pending, data, len); + } +} + + +static void michael_final(void *ctx, u8 *out) +{ + struct michael_mic_ctx *mctx = ctx; + u8 *data = mctx->pending; + + /* Last block and padding (0x5a, 4..7 x 0) */ + switch (mctx->pending_len) { + case 0: + mctx->l ^= 0x5a; + break; + case 1: + mctx->l ^= data[0] | 0x5a00; + break; + case 2: + mctx->l ^= data[0] | (data[1] << 8) | 0x5a0000; + break; + case 3: + mctx->l ^= data[0] | (data[1] << 8) | (data[2] << 16) | + 0x5a000000; + break; + } + michael_block(mctx->l, mctx->r); + /* l ^= 0; */ + michael_block(mctx->l, mctx->r); + + put_le32(out, mctx->l); + put_le32(out + 4, mctx->r); +} + + +static int michael_setkey(void *ctx, const u8 *key, unsigned int keylen, + u32 *flags) +{ + struct michael_mic_ctx *mctx = ctx; + if (keylen != 8) { + if (flags) + *flags = CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + mctx->l = get_le32(key); + mctx->r = get_le32(key + 4); + return 0; +} + + +static struct crypto_alg michael_mic_alg = { + .cra_name = "michael_mic", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .cra_blocksize = 8, + .cra_ctxsize = sizeof(struct michael_mic_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(michael_mic_alg.cra_list), + .cra_u = { .digest = { + .dia_digestsize = 8, + .dia_init = michael_init, + .dia_update = michael_update, + .dia_final = michael_final, + .dia_setkey = michael_setkey } } +}; + + +static int __init michael_mic_init(void) +{ + return crypto_register_alg(&michael_mic_alg); +} + + +static void __exit michael_mic_exit(void) +{ + crypto_unregister_alg(&michael_mic_alg); +} + + +module_init(michael_mic_init); +module_exit(michael_mic_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Michael MIC"); +MODULE_AUTHOR("Jouni Malinen <jkmaline@cc.hut.fi>"); diff -Nru a/crypto/tcrypt.c b/crypto/tcrypt.c --- a/crypto/tcrypt.c Tue Mar 9 21:25:13 2004 +++ b/crypto/tcrypt.c Tue Mar 9 21:25:13 2004 @@ -61,7 +61,7 @@ static char *check[] = { "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", - "arc4", "deflate", NULL + "arc4", "michael_mic", "deflate", NULL }; static void @@ -112,6 +112,10 @@ sg[0].length = hash_tv[i].psize; crypto_digest_init (tfm); + if (tfm->crt_u.digest.dit_setkey) { + crypto_digest_setkey (tfm, hash_tv[i].key, + hash_tv[i].ksize); + } crypto_digest_update (tfm, sg, 1); crypto_digest_final (tfm, result); @@ -568,6 +572,8 @@ test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS); test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS); #endif + + test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); break; case 1: @@ -645,6 +651,10 @@ case 16: test_cipher ("arc4", MODE_ECB, ENCRYPT, arc4_enc_tv_template, ARC4_ENC_TEST_VECTORS); test_cipher ("arc4", MODE_ECB, DECRYPT, arc4_dec_tv_template, ARC4_DEC_TEST_VECTORS); + break; + + case 17: + test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); break; #ifdef CONFIG_CRYPTO_HMAC diff -Nru a/crypto/tcrypt.h b/crypto/tcrypt.h --- a/crypto/tcrypt.h Tue Mar 9 21:25:13 2004 +++ b/crypto/tcrypt.h Tue Mar 9 21:25:13 2004 @@ -30,6 +30,8 @@ char digest[MAX_DIGEST_SIZE]; unsigned char np; unsigned char tap[MAX_TAP]; + char key[128]; /* only used with keyed hash algorithms */ + unsigned char ksize; }; struct hmac_testvec { @@ -1719,4 +1721,54 @@ }, }; +/* + * Michael MIC test vectors from IEEE 802.11i + */ +#define MICHAEL_MIC_TEST_VECTORS 6 + +struct hash_testvec michael_mic_tv_template[] = +{ + { + .key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .ksize = 8, + .plaintext = { }, + .psize = 0, + .digest = { 0x82, 0x92, 0x5c, 0x1c, 0xa1, 0xd1, 0x30, 0xb8 } + }, + { + .key = { 0x82, 0x92, 0x5c, 0x1c, 0xa1, 0xd1, 0x30, 0xb8 }, + .ksize = 8, + .plaintext = { 'M' }, + .psize = 1, + .digest = { 0x43, 0x47, 0x21, 0xca, 0x40, 0x63, 0x9b, 0x3f } + }, + { + .key = { 0x43, 0x47, 0x21, 0xca, 0x40, 0x63, 0x9b, 0x3f }, + .ksize = 8, + .plaintext = { 'M', 'i' }, + .psize = 2, + .digest = { 0xe8, 0xf9, 0xbe, 0xca, 0xe9, 0x7e, 0x5d, 0x29 } + }, + { + .key = { 0xe8, 0xf9, 0xbe, 0xca, 0xe9, 0x7e, 0x5d, 0x29 }, + .ksize = 8, + .plaintext = { 'M', 'i', 'c' }, + .psize = 3, + .digest = { 0x90, 0x03, 0x8f, 0xc6, 0xcf, 0x13, 0xc1, 0xdb } + }, + { + .key = { 0x90, 0x03, 0x8f, 0xc6, 0xcf, 0x13, 0xc1, 0xdb }, + .ksize = 8, + .plaintext = { 'M', 'i', 'c', 'h' }, + .psize = 4, + .digest = { 0xd5, 0x5e, 0x10, 0x05, 0x10, 0x12, 0x89, 0x86 } + }, + { + .key = { 0xd5, 0x5e, 0x10, 0x05, 0x10, 0x12, 0x89, 0x86 }, + .ksize = 8, + .plaintext = { 'M', 'i', 'c', 'h', 'a', 'e', 'l' }, + .psize = 7, + .digest = { 0x0a, 0x94, 0x2b, 0x12, 0x4e, 0xca, 0xa5, 0x46 }, + } +}; #endif /* _CRYPTO_TCRYPT_H */ diff -Nru a/include/linux/crypto.h b/include/linux/crypto.h --- a/include/linux/crypto.h Tue Mar 9 21:25:13 2004 +++ b/include/linux/crypto.h Tue Mar 9 21:25:13 2004 @@ -76,6 +76,8 @@ void (*dia_init)(void *ctx); void (*dia_update)(void *ctx, const u8 *data, unsigned int len); void (*dia_final)(void *ctx, u8 *out); + int (*dia_setkey)(void *ctx, const u8 *key, + unsigned int keylen, u32 *flags); }; struct compress_alg { @@ -157,6 +159,8 @@ void (*dit_final)(struct crypto_tfm *tfm, u8 *out); void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg, u8 *out); + int (*dit_setkey)(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen); #ifdef CONFIG_CRYPTO_HMAC void *dit_hmac_block; #endif @@ -280,6 +284,15 @@ { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); tfm->crt_digest.dit_digest(tfm, sg, nsg, out); +} + +static inline int crypto_digest_setkey(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + if (tfm->crt_digest.dit_setkey == NULL) + return -ENOSYS; + return tfm->crt_digest.dit_setkey(tfm, key, keylen); } static inline int crypto_cipher_setkey(struct crypto_tfm *tfm, =================================================================== This BitKeeper patch contains the following changesets: 1.1688.. ## Wrapped with gzip_uu ## M'XL( +FF3D ]U<>5?C1A+_V_H4O61?8A.PU3IL"08>!)@9[W ]8+*;Q\SZ MR5+;UB!+B@[ B?GN6]4MV?*)36"S6;(C4!]5U575OZZN;NUWY'/,HIW2M[N^ MY;D^D[XC'X,XV2G9=K67)M6."R5700 EM5]KW_JU]ETM]JTP[@7)ME+5):B^ MM!*[1^Y9%.^4:%4=E22#D.V4KDX^?#X]O)*DO3URU+/\+KMF"=G;DY(@NK<\ M)SZPDIX7^-4DLORXSQ*K:@?]X:CI4)%E!?[3:4.5]?J0UF6M,;2I0ZFE4>;( MBF;4M3&U,+3-AEP-8L>K!E%WDI FJU26J:PJ!KRJT.^8T"JM&P:1M9JLUF23 MT,:.K.[H^K9L[,@R6428_"B3;5GZB;SN.(XDFYRQJ,M(^VZG5KMCD<^\:ONN M[29QU6=)S;'N6;\&?X'ZZ]#8]9. 3,FV4^L%?5;+):O=@Z5J8-[T47+)7727 M]JWH((VK;KL_*R3H2#855=%T?2@W#%6%/L&=&QW$:<RJ#IO?NJXK0UE7=$7Z M1*BN-E3I;*U>EV/GD+;7_)&D=<T/0Q-"9N8W"^8W=G1M1Y<S\^<3XV T(<B/ MVEL9_M!QF$/B- R#*"&=(")I[/I=<L<&4.ZX718GY,%->L3R21 F;N!;'I0G MK9@ET(@ 3\=C415HW?3<F#@!BXD?),3FTI"D!W[%>M:]"[2##G]GCVZ<()>, MON5U@PAX].,MTDX3(&5Y7O =-@#"7P@" YG.2#G!$^@90$?$*S-0&R0%YJY MOINXH+_?.&M.*B.>#0.'1D"6F#&GFE-T.0L@8P-G(&1U$J"/M+A$4 .JX=3\ M03Z*-'2L1/0HQY4J>J'64!I_T*]D2Y;V"9]R!WZ*,]#U[RR<AT,[&H1)4$OX M[VJ/6YF"+2G86#.'"OXUU#6FFQ:KUQEMZZHYSYWF$1)^JFBFJ@VUAJF;BX1P M?=M+'2;F=DU0FI(%/$[1&JH^-&13EF63VK;3MG6;S9-E,;VB2(JB RHLUXMP MIJH]HQ=95^G05&QJP[13;%VQ'$-9HI<BH:(0=:HKSPF1Z716"*J:=&@Q&ZQB M=]IM6;7:6N=YX\P( 7HP%$F:TW$.[BBZILM#X98"=\ AQKAC[L#*HYM+<*?^ MMKASY@)*,(^<-8\F$0>!Z.93\Y*4FR<G)\20E2JE;NV?EX>5JL"9T;3&!2DF MOZ8NS,4'9MT1)V4XF7&*1@S*(]9G?A)SFB!N:"5NV_7<9" (? <XK&N90^ MT@.T]E@<D]/#<X"9R'FP(B9P9@1L@&6,]%,(-XXN/Y,P> #T(T>!'P,S8.0- MMJ"#&P,U"%E2H(Z=(@8P,1@!58:H V@(,,B\F#/Q^9@12G%)+N@&!@@P8Z<> M (Y#@GN.?8R$UL ++"<'I(*J2(]9#K1ZZ $5(-:W[D!Z-R',BEWL+?"4J[@( M_JB,"1W8H(.X2@Y];.\*^$<83(&AG[@V%PAPT"*@* L%Y>,K(VCBN&/F(VR' M5@0MO4&%<RYT1BT%:038 )A.'(;K@H5LD%\$4K 8D56I4YAZKX&LBV=<7RB\ M!;^+TTZE#9Q##<VL#]6.H=J.VK#KJN&H>N-EU"C F2G7_SR8%T.2*:4(9[^Y M8<B\ P[ V_VZ<8=1S&T^Y;_F9#[9@=]QNYDX*M!2%=484D,SC:%>K].&K.MJ MAYH-S5&7B%.@,R&-JCT+KF?@Q1W78],JH88*49W!['9#@P!/<W3-,I:(4*13 ME*&N:?6%,AP'=HI PKTS6ZAJ5NAN0S@<!=7D,<G%,BD%^U+P&8.:PTY;;7<: MCJYH'47M://$6HUT45+=!&C_\Y:BW&3HQ2LN1=@%>/-YG"U%=+P4*70'%B': M6+(4*6^U%+UW'P&Q6!3Q]<%!G/0!KY,T\@FP2J$@ ]AL<9J.?#D\J6\8^/VW M8RY=-N0&@E1=__-B+B%$G9JZOJJ/01?:& IC9#ZF3/@8578T;8F/T;?U,;[W MX7Y6="^^\!96^WR]J_\_K'<ZS'=EJ*BJK/%\S/-0AXF:MP1@Z5O@'W0"B*=Z M 7H<6'1E_(5_!M4T%=8[HR$+'S-G NIE&_DW\[ _$%"#OXGUY()L1P_9_\#Y MGE?+"[RR20U0E$3(/X+4=\D9UY!/R@7)*]Q3IM;JA6[QDMA@C@_,#PU&!J_+ M=5D87%'_'PPN0ITI@T_IX"76570P;M#^MOWW\M'%^?OFA];1U2^7-Q<M$/#C MX<DI_JZ0'_=($2^"HL'SE> Y@Z^W]$C?^D$4N?$!^"Z+<)E'Q5>M=!XY5581 M0VA=-X9J@\IFMII,I.PT<T==NI:\6;+V]7)VX <\IS'?#W*5O,0/-(V84HS0 MP?/%6<Q4CI,HM9.,02OI],DF/+8@[O)!YM0@F]!JBZ1^['9]& QVA1*/^17I M=ZF4J@KI>%8WWI5*;H>4H>_V?JME1TG+\KK;^W9DM3*I'=?*APN^=?[Y]+0B ME4K9NKM-@4#V]THTRF.)6W;RB(PK6T /?PC^<+&%I%OD>RYC95=ZDKY(S88& M4Z(4A/'V_M@&I;U,);MS@YN5,E'<*1O30;2\+(@&-*+_JT&T"/5>W16/-5QO MFOPY=H"3\XOK7ZYWB\"3;W.> Y[U]E6+EYJI;=5HJ=%40S&X<55E+<3Y"QP2 M0*3!\Y?SK9QKY$5A!=6(!@8>P0).Z+0ZFLFY+!7R.\[;;#Z+ZES,,L>BGA7W M6LG]K?NUBK-:&D_RB:K8_8W!%"^5GI;-X.5I7&[D]>*)QEO-X#\63_!4P*M; M];B.V-GDS]*&%=G:QA;9*(0.^.JP#N9%X4]$>:FI ^ J +RE4H*V19N5I_H4 MWL"<K83U0R2Q10I12NOFY/JF]?/)T<W%U348NEG7*?>P=L2LNUUD8%LQP\/; MUV8U"TJ]%4%IQ6SALZ#4FP$E\-S&[(;G>5!ZL[3-:X*2./%:ZKZ]EX 2 +@" M;M*S(A3KEBK&UUU2VR2![PT*!P%"9/2>PE$HV:Q!P),'0H(&8L[2@&'YD1[? MOLP> "V#&_WMKAP4D 9G#[EG-G")22<*^L6S#)<?K6*N^O4-1!NPG=-EJ;8I MD<TU1)+0.M\!\H"Z%LYD4@>0R")>L7( 32"Y"!-NOY(]C')Q@:KRP)7\3N1' M6=Y:^4F>MGAG=!3H;O W((Z['DRM $'1(LQ:R/PMFRV"GZ$@+9,_=1N?E#\M MBD^'/U7.KVV0)ZF$!*=$7H_$LR+_</;#E-AT5FQ-17I: Y\*YV!;O(3SJ?-: ML\TY=Q:(O1Z)5<3>(C^XT[(KL[(S XEV3*X1-F;,>$F#E^@.%\M<(/MZ)%:6 M'1[V] #4V0&8PO^XAHP.YU[G3_XWY>6V,'Y[P0#6(['> .#1FQZ%-CL*1^=: MXKJB0AQ]_#?E[FQP?1KU!:-8C\0+1@$/"Q\,'][TH!JS@Y*Y&Y@:-WU[+(56 M<!*+RZ@)B9ZD)Q&"S#\F6!B)_)%3"JD_. @Q%$D36,GC:LR6D%,A)C&HN%,% M"ULCVRS)ZZ5GU+]"8"+NO4RM>_,U\Y+EKV%@?())EO+F.-E1*=\'KD,V[>1Q M.C,C91NAXL^<9,T6P4S-9IX&:5+=+#(:[<46Y8/FL5DA102<%$,A)L^[C))/ M:'G>:MZ>;Z$$LP+,_5DQ<?73YP^MB_-B%@D"O19>5^6I)/*W/9+E20]//[1N M?KD\:1TW/T L42EFNG!+.[.A726]-;>CV.T6$E>5^:'E.C>T^$2<.=?]RZ:D MQ!'H6TV_8\7DVUOQ:VEN:N)T#1'XG#T0S-'OS&TA=0B#O>K/\&_)9N$%!X#< MP.OM(-YD V&3G]SD$V,AB[@:R-RKXK6YNH'-!(YMO(&8K+XB,X/^%P]IZ4MN M";^^]NEZQT_F&ZUS[\%E^029R/ML;R]2Z_JZ:\HP0#7;FAUQFMW("GL ZH>7 M32B<WK)-9J8P65696'2S+D=!.(C<;@_6(KM"4/%39Y'O9A6YG_7E5P_#" 7I MXV6W3L08B8-.@O<$=\D@2/E]Y(@Y+BPL;CM-&-ZZ T2I 0KU \?M#) .E*6^ MDUWC2UC4'V'1A_//Y /S600QP67:]F"TIZ[-_)CQ[QWP9IQ"K!B)A%@=]V!\ M[0'O^QZEN<ZD(>]A4 X_NZWR[>H7Z;L,NL@[@5UXO[G:VY\I!SE3C\VKP4'Y MW7DU.0[N Y_1KK>XT85H E.OL%2&S'> RJWV%98I#%Q;25[6@F6(I]8P?O"V M2+2+P>B7F>4<JZ,@\<KX!_CU%E]P\8L%OMQF2%J&&O+NG2@G0_&^OT_*T&E; ME&:'- OH1RO0!WH3]('?:O0?XP<KS!E,D.5TON<;^DX'_U60JL%9C.I$C2Q7 M4 )CQ"=/2N2J;WN!?5=&559*7R0G(+]C.ALT')%_[PD=0B5M5':QT,.CV6BW MT$)(Z4'U_/J<@KJ( %<C-%!F&SSA_50 [[)<6:"C+DO )52E/(ZSPJ*JPEOY M*VHEO*5?QSH*;Q7^1NO9J\I?%6V!-7BX&Z89*\Y$1+#WG!=GLD?N=_%/RO_D M.N?ORNB=UGF!.BI0M"EVG$]N&)Q\XT";,UHP:S;[^(18('D$#OBRO5^8+YC% M6<9(?*<P/Z;'F[M346L>LJXBS!<1G,Z() Y9D%I'"*C!?)AIM9L=U_ V^X(Q M^$76)6O09WT[')2_G^A].T/KZQ818^F(0+8T1T_@>)V,*K^Q7'C'ZNW\]4LF MURR%=T3C(@KO$RU%*P]=?>2M$SV%-!/3,>NSE>DD6B P-VP)+5O*)@K7%*A3 M*'@>:QS9JAQS+6@%%6@Y1]2 ,(Q<Y#8IWZ21)EKD!LGL\;3$0P&P+*_HH.B: M09JL/BER7X:""2&XB6J;Y-0"A^>:X/?,0[S,#EORLORH@XA:M=H@CSA.S+G' ML#>W>XN\FI_YR#N3VD<RN^.CH>Q@:*H1RB?@"IO+\DP'96$';M4BQ D*<VBH MJ],0!06D1,_."4^2?I)6<"=0LU#&+E?CLQW ,B/,!6/G51[2*E:0'XE6[#>% MX&/7R+:U"Y,7<S,5$C_<+:0K5O8YG""""&[?C0SS.)YQ.D!8D"2CS?W-^[/6 MU<EUZZ?#X]:GDU]:IR?GNU/;]B=I9+["K,9DR0C[HZD:5%!EO..?7@PF,QR6 MUYT8%[[OH>A5O/CB6WU6VILZ8LWJ^%A*BQ(5>2MN;@SJ2B*CR0M![*P(?P6= M\GP%5_+V(@"%YC<?F]>MLXOCSZ<G>1V$O G4G#:O;UH?3T"1S?/F37EJ2*.6 M(Y)IJ83YT$)N5"KQ"SZBH"@QEN+J7-J;6*SS*K&>%BI%05[-P:Q0R]_SRM'E MGTF?)4_D:2;034B+\YW0TBAJ*$9!F6DCUH41LP@5 OFI$:F)PZ?):T6>YQB M@ 5C!AGEU%^-MK";$')::FB457,6TSPY( A+MTZ;1R?GUR?EC0^7I^1>V8"Z MK.;XY/KHJGEYT[PX+V\4]GZ%)H>?;SY>7)4WGM_3;2Q(>*W^!0\_4)V^8:XJ M?UZV:XT;YOQ*]MOLW(^IKF!B2_PJ)+::YS\?GDXDMK*O@3"E]1;?(2V^Z##Y M&=+XGH-2UT0:4U'62K28_YOW?/E75?.MG&G@1<?F=9684F:ZV0N^4BF)7,09 M1C86"CZZZ; AE1R&859, C^C)I5ZS OQ&&#J,TA^:0+'W&=Q;'5Y8I]U(_R: M,X2=)K/YMX.N^)(2^T^H9>;C4229?23JC%0I/OEV$^Q>^(0S_W:3?R<)$RV" M+6,4!C&+H<JVH"[/X>!GJ#[(AP2RHA''*L#<Z/^OPNXQ6"S3_AY5C$['T!WI )/Y!&5#P>0P -- Jouni Malinen PGP id EFC895FA ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-10 5:34 ` Jouni Malinen @ 2004-03-10 15:45 ` James Morris 2004-03-11 3:00 ` Jouni Malinen 0 siblings, 1 reply; 52+ messages in thread From: James Morris @ 2004-03-10 15:45 UTC (permalink / raw) To: Jouni Malinen; +Cc: Clay Haapala, David S. Miller, linux-kernel On Tue, 9 Mar 2004, Jouni Malinen wrote: > On Tue, Mar 09, 2004 at 11:21:03PM -0500, James Morris wrote: > > > In both patches, these 'return -1' statements should be -EINVAL, or > > whatever is appropriate (probably -ENOSYS for this one). > > Fixed. The included patch combines changesets for both the setkey > addition and Michael MIC. Please let me know if you want to get these as > separate patch files. This is oopsing on 'modprobe tcrypt'. Separate patches would be preferred. - James -- James Morris <jmorris@redhat.com> ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-10 15:45 ` James Morris @ 2004-03-11 3:00 ` Jouni Malinen 2004-03-11 4:06 ` James Morris 0 siblings, 1 reply; 52+ messages in thread From: Jouni Malinen @ 2004-03-11 3:00 UTC (permalink / raw) To: James Morris; +Cc: Clay Haapala, David S. Miller, linux-kernel On Wed, Mar 10, 2004 at 10:45:28AM -0500, James Morris wrote: > On Tue, 9 Mar 2004, Jouni Malinen wrote: > > Fixed. The included patch combines changesets for both the setkey > > addition and Michael MIC. Please let me know if you want to get these as > > separate patch files. > > This is oopsing on 'modprobe tcrypt'. > > Separate patches would be preferred. I was unable to reproduce the oops by loading tcrypt. All tests passed and the kernel was fine. I did this testing with Linux 2.6.4-rc3 and all crypto algs compiled as modules. I will try this again with the latest linus-2.5 BK tree just in case. Anyway, if you happen to have any more details from the oops like backtrace or any ideas of what might be causing the difference in our results, they would be very helpful. I will also send separate patches once I figure out what caused the oops with tcrypt. -- Jouni Malinen PGP id EFC895FA ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-11 3:00 ` Jouni Malinen @ 2004-03-11 4:06 ` James Morris 2004-03-11 6:08 ` Jouni Malinen 2004-03-11 6:11 ` Crypto API and keyed non-HMAC digest algorithms / Michael MIC Jouni Malinen 0 siblings, 2 replies; 52+ messages in thread From: James Morris @ 2004-03-11 4:06 UTC (permalink / raw) To: Jouni Malinen; +Cc: Clay Haapala, David S. Miller, linux-kernel On Wed, 10 Mar 2004, Jouni Malinen wrote: > On Wed, Mar 10, 2004 at 10:45:28AM -0500, James Morris wrote: > > I was unable to reproduce the oops by loading tcrypt. All tests passed > and the kernel was fine. I did this testing with Linux 2.6.4-rc3 and > all crypto algs compiled as modules. I will try this again with the > latest linus-2.5 BK tree just in case. Anyway, if you happen to have any > more details from the oops like backtrace or any ideas of what might be > causing the difference in our results, they would be very helpful. > I can't reproduce it now either (AFAICR, it oopsed in test_hash(). I suspect it may have been caused by loading tcrypt module which was out of sync with the digest setkey change. - James -- James Morris <jmorris@redhat.com> ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-11 4:06 ` James Morris @ 2004-03-11 6:08 ` Jouni Malinen 2004-03-11 16:34 ` Clay Haapala 2004-03-11 6:11 ` Crypto API and keyed non-HMAC digest algorithms / Michael MIC Jouni Malinen 1 sibling, 1 reply; 52+ messages in thread From: Jouni Malinen @ 2004-03-11 6:08 UTC (permalink / raw) To: James Morris; +Cc: Clay Haapala, David S. Miller, linux-kernel On Wed, Mar 10, 2004 at 11:06:37PM -0500, James Morris wrote: > I can't reproduce it now either (AFAICR, it oopsed in test_hash(). > > I suspect it may have been caused by loading tcrypt module which was out > of sync with the digest setkey change. That's possible. It didn't fail in my test with an updated version from the BK repository either, so I would assume this issue can be called resolved. Here's the digest setkey part of the previous combined patch; I'll send a patch for Michael MIC separately. Added support for using keyed digest with an optional dit_setkey handler. This does not change the behavior of the existing digest algorithms, but allows new ones to add setkey handler that can be used to initialize the algorithm with a key or seed. setkey is to be called after init, but before any of the update call(s). diff -Nru a/crypto/digest.c b/crypto/digest.c --- a/crypto/digest.c Tue Mar 9 21:25:13 2004 +++ b/crypto/digest.c Tue Mar 9 21:25:13 2004 @@ -42,6 +42,15 @@ tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out); } +static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) +{ + u32 flags; + if (tfm->__crt_alg->cra_digest.dia_setkey == NULL) + return -ENOSYS; + return tfm->__crt_alg->cra_digest.dia_setkey(crypto_tfm_ctx(tfm), + key, keylen, &flags); +} + static void digest(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg, u8 *out) { @@ -72,6 +81,7 @@ ops->dit_update = update; ops->dit_final = final; ops->dit_digest = digest; + ops->dit_setkey = setkey; return crypto_alloc_hmac_block(tfm); } diff -Nru a/crypto/tcrypt.c b/crypto/tcrypt.c --- a/crypto/tcrypt.c Tue Mar 9 21:25:13 2004 +++ b/crypto/tcrypt.c Tue Mar 9 21:25:13 2004 @@ -112,6 +112,10 @@ sg[0].length = hash_tv[i].psize; crypto_digest_init (tfm); + if (tfm->crt_u.digest.dit_setkey) { + crypto_digest_setkey (tfm, hash_tv[i].key, + hash_tv[i].ksize); + } crypto_digest_update (tfm, sg, 1); crypto_digest_final (tfm, result); diff -Nru a/crypto/tcrypt.h b/crypto/tcrypt.h --- a/crypto/tcrypt.h Tue Mar 9 21:25:13 2004 +++ b/crypto/tcrypt.h Tue Mar 9 21:25:13 2004 @@ -30,6 +30,8 @@ char digest[MAX_DIGEST_SIZE]; unsigned char np; unsigned char tap[MAX_TAP]; + char key[128]; /* only used with keyed hash algorithms */ + unsigned char ksize; }; struct hmac_testvec { diff -Nru a/include/linux/crypto.h b/include/linux/crypto.h --- a/include/linux/crypto.h Tue Mar 9 21:25:13 2004 +++ b/include/linux/crypto.h Tue Mar 9 21:25:13 2004 @@ -76,6 +76,8 @@ void (*dia_init)(void *ctx); void (*dia_update)(void *ctx, const u8 *data, unsigned int len); void (*dia_final)(void *ctx, u8 *out); + int (*dia_setkey)(void *ctx, const u8 *key, + unsigned int keylen, u32 *flags); }; struct compress_alg { @@ -157,6 +159,8 @@ void (*dit_final)(struct crypto_tfm *tfm, u8 *out); void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg, u8 *out); + int (*dit_setkey)(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen); #ifdef CONFIG_CRYPTO_HMAC void *dit_hmac_block; #endif @@ -280,6 +284,15 @@ { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); tfm->crt_digest.dit_digest(tfm, sg, nsg, out); +} + +static inline int crypto_digest_setkey(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + if (tfm->crt_digest.dit_setkey == NULL) + return -ENOSYS; + return tfm->crt_digest.dit_setkey(tfm, key, keylen); } static inline int crypto_cipher_setkey(struct crypto_tfm *tfm, -- Jouni Malinen PGP id EFC895FA ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-11 6:08 ` Jouni Malinen @ 2004-03-11 16:34 ` Clay Haapala 2004-03-11 20:14 ` James Morris 0 siblings, 1 reply; 52+ messages in thread From: Clay Haapala @ 2004-03-11 16:34 UTC (permalink / raw) To: Jouni Malinen; +Cc: James Morris, David S. Miller, linux-kernel On Wed, 10 Mar 2004, Jouni Malinen outgrape: > On Wed, Mar 10, 2004 at 11:06:37PM -0500, James Morris wrote: > >> I can't reproduce it now either (AFAICR, it oopsed in test_hash(). >> >> I suspect it may have been caused by loading tcrypt module which >> was out of sync with the digest setkey change. > > That's possible. It didn't fail in my test with an updated version > from the BK repository either, so I would assume this issue can be > called resolved. > > Here's the digest setkey part of the previous combined patch; I'll > send a patch for Michael MIC separately. > > > > Added support for using keyed digest with an optional dit_setkey > handler. This does not change the behavior of the existing digest > algorithms, but allows new ones to add setkey handler that can be > used to initialize the algorithm with a key or seed. setkey is to be > called after init, but before any of the update call(s). > > [ ... patch omitted ... ] OK, so I should recode CRC32C to be a variation of digest that employs a setkey() handler, right? Should be no problem. Can I get to a reasonable development environment by starting with 2.6.3, and adding the patch you just sent? Or, do I need the Michael MIC patch, as well? -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD Windows XP 'Reloaded'? *Reloaded?* Have they no sense of irony? ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-11 16:34 ` Clay Haapala @ 2004-03-11 20:14 ` James Morris 2004-03-18 23:05 ` Clay Haapala 0 siblings, 1 reply; 52+ messages in thread From: James Morris @ 2004-03-11 20:14 UTC (permalink / raw) To: Clay Haapala; +Cc: Jouni Malinen, David S. Miller, linux-kernel On Thu, 11 Mar 2004, Clay Haapala wrote: > OK, so I should recode CRC32C to be a variation of digest that employs > a setkey() handler, right? Should be no problem. Give it a try and see. > Can I get to a reasonable development environment by starting with > 2.6.3, and adding the patch you just sent? Or, do I need the Michael > MIC patch, as well? Yes, please apply the first two patches first. - James -- James Morris <jmorris@redhat.com> ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-11 20:14 ` James Morris @ 2004-03-18 23:05 ` Clay Haapala 2004-03-21 15:08 ` James Morris 0 siblings, 1 reply; 52+ messages in thread From: Clay Haapala @ 2004-03-18 23:05 UTC (permalink / raw) To: James Morris; +Cc: Jouni Malinen, David S. Miller, linux-kernel On Thu, 11 Mar 2004, James Morris outgrape: > On Thu, 11 Mar 2004, Clay Haapala wrote: > >> OK, so I should recode CRC32C to be a variation of digest that >> employs a setkey() handler, right? Should be no problem. > > Give it a try and see. > >> Can I get to a reasonable development environment by starting with >> 2.6.3, and adding the patch you just sent? Or, do I need the >> Michael MIC patch, as well? > > Yes, please apply the first two patches first. > > > - James I've redone the crypto crc32c implementation to make use of Jouni's setkey() digest api. So now crypto crc32c checksums are just another type of digest, rather than a new CRYPTO_ALG type. This implementation is still a wrapper for the actual computation routine in lib/libcrc32c, per previous requests. The patch below includes the code under lib and crypto. It requires Jouni's previous patches to be applied, and was tested on 2.6.4 kernel source. Let me know how it looks, especially if I should add further tests in tcrypt. Regards, -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD Of course the drugs advertised in all those emails are safe. Show me the dead spammers! (Please!) diff -urN linux-2.6.4.orig/crypto/crc32c.c linux/crypto/crc32c.c --- linux-2.6.4.orig/crypto/crc32c.c 1969-12-31 18:00:00.000000000 -0600 +++ linux/crypto/crc32c.c 2004-03-18 16:09:05.000000000 -0600 @@ -0,0 +1,110 @@ +/* + * Cryptographic API. + * + * CRC32C chksum + * + * This module 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 4 + +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 int chksum_setkey(void *ctx, const u8 *key, unsigned int keylen, + u32 *flags) +{ + struct chksum_ctx *mctx = ctx; + + if (keylen != sizeof(mctx->crc)) { + if (flags) + *flags = CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + mctx->crc = __cpu_to_le32(*(u32 *)key); + return 0; +} + +static void chksum_update(void *ctx, const u8 *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, u8 *out) +{ + struct chksum_ctx *mctx = ctx; + u32 mcrc = (mctx->crc ^ ~(u32)0); + + *(u32 *)out = __le32_to_cpu(mcrc); +} + +static struct crypto_alg alg = { + .cra_name = "crc32c", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .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 = { + .digest = { + .dia_digestsize= CHKSUM_DIGEST_SIZE, + .dia_setkey = chksum_setkey, + .dia_init = chksum_init, + .dia_update = chksum_update, + .dia_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"); diff -urN linux-2.6.4.orig/crypto/Kconfig linux/crypto/Kconfig --- linux-2.6.4.orig/crypto/Kconfig 2004-03-17 15:23:06.000000000 -0600 +++ linux/crypto/Kconfig 2004-03-18 15:24:57.000000000 -0600 @@ -170,6 +170,16 @@ should not be used for other purposes because of the weakness of the algorithm. +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_TEST tristate "Testing module" depends on CRYPTO diff -urN linux-2.6.4.orig/crypto/Makefile linux/crypto/Makefile --- linux-2.6.4.orig/crypto/Makefile 2004-03-17 15:23:06.000000000 -0600 +++ linux/crypto/Makefile 2004-03-18 15:44:54.000000000 -0600 @@ -24,5 +24,6 @@ obj-$(CONFIG_CRYPTO_ARC4) += arc4.o obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o +obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o diff -urN linux-2.6.4.orig/crypto/tcrypt.c linux/crypto/tcrypt.c --- linux-2.6.4.orig/crypto/tcrypt.c 2004-03-17 15:23:06.000000000 -0600 +++ linux/crypto/tcrypt.c 2004-03-18 16:36:41.000000000 -0600 @@ -61,7 +61,7 @@ static char *check[] = { "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", - "arc4", "michael_mic", "deflate", NULL + "arc4", "michael_mic", "deflate", "crc32c", NULL }; static void @@ -496,6 +496,107 @@ } 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 initialized to %08x: %s\n"; +#define SEEDTESTVAL 0xedcba987 + u32 seed; + + printk("\ntesting crc32c\n"); + + tfm = crypto_alloc_tfm("crc32c", 0); + if (tfm == NULL) { + printk("failed to load transform for crc32c\n"); + return; + } + + crypto_digest_init(tfm); + crypto_digest_final(tfm, (u8*)&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; + } + + seed = SEEDTESTVAL; + (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); + crypto_digest_final(tfm, (u8*)&crc); + printk("testing crc32c setkey 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++) { + seed = ~(u32)0; + (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); + crypto_digest_update(tfm, &sg[i], 1); + crypto_digest_final(tfm, (u8*)&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++) { + seed = (crc ^ ~(u32)0); + (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); + crypto_digest_update(tfm, &sg[i], 1); + crypto_digest_final(tfm, (u8*)&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"); + seed = ~(u32)0; + (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); + crypto_digest_digest(tfm, sg, NUMVEC, (u8*)&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; @@ -566,7 +667,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); @@ -657,6 +759,10 @@ test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); break; + case 18: + test_crc32c(); + break; + #ifdef CONFIG_CRYPTO_HMAC case 100: test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); diff -urN linux-2.6.4.orig/include/linux/crc32c.h linux/include/linux/crc32c.h --- linux-2.6.4.orig/include/linux/crc32c.h 1969-12-31 18:00:00.000000000 -0600 +++ linux/include/linux/crc32c.h 2004-03-18 15:34:18.000000000 -0600 @@ -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 linux-2.6.4.orig/lib/Kconfig linux/lib/Kconfig --- linux-2.6.4.orig/lib/Kconfig 2004-03-10 20:55:33.000000000 -0600 +++ linux/lib/Kconfig 2004-03-18 16:28:42.000000000 -0600 @@ -12,6 +12,15 @@ 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. + Module will be libcrc32c. + # # compression support is select'ed if needed # diff -urN linux-2.6.4.orig/lib/libcrc32c.c linux/lib/libcrc32c.c --- linux-2.6.4.orig/lib/libcrc32c.c 1969-12-31 18:00:00.000000000 -0600 +++ linux/lib/libcrc32c.c 2004-03-18 16:27:54.000000000 -0600 @@ -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"); + +#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. + */ +#if defined CRC_BE_BITS && CRC_BE_BITS != 1 +#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 linux-2.6.4.orig/lib/Makefile linux/lib/Makefile --- linux-2.6.4.orig/lib/Makefile 2004-03-10 20:55:21.000000000 -0600 +++ linux/lib/Makefile 2004-03-18 15:59:55.000000000 -0600 @@ -16,6 +16,7 @@ endif obj-$(CONFIG_CRC32) += crc32.o +obj-$(CONFIG_LIBCRC32C) += libcrc32c.o obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/ ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-18 23:05 ` Clay Haapala @ 2004-03-21 15:08 ` James Morris 2004-03-22 16:49 ` [PATCH] lib/libcrc32c implementation Clay Haapala 2004-03-22 16:56 ` [PATCH] crypto/crc32c support Clay Haapala 0 siblings, 2 replies; 52+ messages in thread From: James Morris @ 2004-03-21 15:08 UTC (permalink / raw) To: Clay Haapala; +Cc: Jouni Malinen, David S. Miller, linux-kernel On Thu, 18 Mar 2004, Clay Haapala wrote: > I've redone the crypto crc32c implementation to make use of Jouni's > setkey() digest api. So now crypto crc32c checksums are just another > type of digest, rather than a new CRYPTO_ALG type. > > This implementation is still a wrapper for the actual computation > routine in lib/libcrc32c, per previous requests. The patch below > includes the code under lib and crypto. It requires Jouni's previous > patches to be applied, and was tested on 2.6.4 kernel source. > > Let me know how it looks, especially if I should add further tests in > tcrypt. This looks fine, could you split it into two patches, one with the libcrc32c code and then one with the crypto algorithm? Also, in the configuration help, "This implementation uses lib/crc32c" should be ""This implementation uses lib/libcrc32c". - James -- James Morris <jmorris@redhat.com> ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH] lib/libcrc32c implementation 2004-03-21 15:08 ` James Morris @ 2004-03-22 16:49 ` Clay Haapala 2004-03-22 17:00 ` Jeff Garzik 2004-03-26 16:36 ` James Morris 2004-03-22 16:56 ` [PATCH] crypto/crc32c support Clay Haapala 1 sibling, 2 replies; 52+ messages in thread From: Clay Haapala @ 2004-03-22 16:49 UTC (permalink / raw) To: James Morris; +Cc: Jouni Malinen, David S. Miller, linux-kernel, Matt_Domsch This patch agains 2.6.4 kernel code implements the CRC32C algorithm. The routines are based on the same design as the existing CRC32 code. Licensing is intended to be identical (GPL). The immediate customer of this code is the wrapper code in crypto/crc32c, available in another patch. And the immediate customer of the crypto code is the linux-iscsi driver module, currently in review. See the linux-iscsi project on SourceForge for details. -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD Of course the drugs advertised in all those emails are safe. Show me the dead spammers! (Please!) diff -urN linux-2.6.4.orig/include/linux/crc32c.h linux/include/linux/crc32c.h --- linux-2.6.4.orig/include/linux/crc32c.h 1969-12-31 18:00:00.000000000 -0600 +++ linux/include/linux/crc32c.h 2004-03-18 15:34:18.000000000 -0600 @@ -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 linux-2.6.4.orig/lib/Kconfig linux/lib/Kconfig --- linux-2.6.4.orig/lib/Kconfig 2004-03-10 20:55:33.000000000 -0600 +++ linux/lib/Kconfig 2004-03-18 16:28:42.000000000 -0600 @@ -12,6 +12,15 @@ 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. + Module will be libcrc32c. + # # compression support is select'ed if needed # diff -urN linux-2.6.4.orig/lib/libcrc32c.c linux/lib/libcrc32c.c --- linux-2.6.4.orig/lib/libcrc32c.c 1969-12-31 18:00:00.000000000 -0600 +++ linux/lib/libcrc32c.c 2004-03-18 16:27:54.000000000 -0600 @@ -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"); + +#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. + */ +#if defined CRC_BE_BITS && CRC_BE_BITS != 1 +#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 linux-2.6.4.orig/lib/Makefile linux/lib/Makefile --- linux-2.6.4.orig/lib/Makefile 2004-03-10 20:55:21.000000000 -0600 +++ linux/lib/Makefile 2004-03-18 15:59:55.000000000 -0600 @@ -16,6 +16,7 @@ endif obj-$(CONFIG_CRC32) += crc32.o +obj-$(CONFIG_LIBCRC32C) += libcrc32c.o obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/ ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c implementation 2004-03-22 16:49 ` [PATCH] lib/libcrc32c implementation Clay Haapala @ 2004-03-22 17:00 ` Jeff Garzik 2004-03-22 17:27 ` Clay Haapala 2004-03-26 16:36 ` James Morris 1 sibling, 1 reply; 52+ messages in thread From: Jeff Garzik @ 2004-03-22 17:00 UTC (permalink / raw) To: Clay Haapala Cc: James Morris, Jouni Malinen, David S. Miller, linux-kernel, Matt_Domsch Clay Haapala wrote: > This patch agains 2.6.4 kernel code implements the CRC32C algorithm. > The routines are based on the same design as the existing CRC32 code. > Licensing is intended to be identical (GPL). > > The immediate customer of this code is the wrapper code in > crypto/crc32c, available in another patch. Why not call it 'crc32c' like its cousin crc32, rather than the less-similar 'libcrc32c'? Violates the Principle of Least Surprise ;-) Jeff ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c implementation 2004-03-22 17:00 ` Jeff Garzik @ 2004-03-22 17:27 ` Clay Haapala 2004-03-22 17:36 ` Jeff Garzik 0 siblings, 1 reply; 52+ messages in thread From: Clay Haapala @ 2004-03-22 17:27 UTC (permalink / raw) To: Jeff Garzik Cc: James Morris, Jouni Malinen, David S. Miller, linux-kernel, Matt_Domsch On Mon, 22 Mar 2004, Jeff Garzik spake thusly: > Clay Haapala wrote: >> This patch agains 2.6.4 kernel code implements the CRC32C >> algorithm. The routines are based on the same design as the >> existing CRC32 code. Licensing is intended to be identical (GPL). >> The immediate customer of this code is the wrapper code in >> crypto/crc32c, available in another patch. > > > Why not call it 'crc32c' like its cousin crc32, rather than the > less-similar 'libcrc32c'? Violates the Principle of Least Surprise > ;-) > > Jeff The module under crypto is call "crc32c", which would conflict, UIASM. I'd entertain any reasonable naming. For a bit, undercrypto, I was calling that module "crc32c_wrap", but that looked ugly, too, but probably is more PLS-compliant. :-) -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD Of course the drugs advertised in all those emails are safe. Show me the dead spammers! (Please!) ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c implementation 2004-03-22 17:27 ` Clay Haapala @ 2004-03-22 17:36 ` Jeff Garzik 0 siblings, 0 replies; 52+ messages in thread From: Jeff Garzik @ 2004-03-22 17:36 UTC (permalink / raw) To: Clay Haapala Cc: James Morris, Jouni Malinen, David S. Miller, linux-kernel, Matt_Domsch Clay Haapala wrote: > On Mon, 22 Mar 2004, Jeff Garzik spake thusly: > >>Clay Haapala wrote: >> >>>This patch agains 2.6.4 kernel code implements the CRC32C >>>algorithm. The routines are based on the same design as the >>>existing CRC32 code. Licensing is intended to be identical (GPL). >>>The immediate customer of this code is the wrapper code in >>>crypto/crc32c, available in another patch. >> >> >>Why not call it 'crc32c' like its cousin crc32, rather than the >>less-similar 'libcrc32c'? Violates the Principle of Least Surprise >>;-) >> >> Jeff > > > The module under crypto is call "crc32c", which would conflict, UIASM. Fair enough... Jeff ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c implementation 2004-03-22 16:49 ` [PATCH] lib/libcrc32c implementation Clay Haapala 2004-03-22 17:00 ` Jeff Garzik @ 2004-03-26 16:36 ` James Morris 2004-03-26 16:59 ` Clay Haapala ` (2 more replies) 1 sibling, 3 replies; 52+ messages in thread From: James Morris @ 2004-03-26 16:36 UTC (permalink / raw) To: Clay Haapala; +Cc: Jouni Malinen, David S. Miller, linux-kernel, Matt_Domsch On Mon, 22 Mar 2004, Clay Haapala wrote: > This patch agains 2.6.4 kernel code implements the CRC32C algorithm. > The routines are based on the same design as the existing CRC32 code. > Licensing is intended to be identical (GPL). These need to be rediffed against the latest Linus kernel. It may be better to wait until 2.6.5 comes out, so we don't have too much new stuff going into the -rc kernels. - James -- James Morris <jmorris@redhat.com> ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c implementation 2004-03-26 16:36 ` James Morris @ 2004-03-26 16:59 ` Clay Haapala 2004-03-26 18:16 ` James Morris 2004-03-30 17:32 ` [PATCH] lib/libcrc32c Clay Haapala 2004-03-30 17:40 ` [PATCH] crypto/crc32c implementation Clay Haapala 2 siblings, 1 reply; 52+ messages in thread From: Clay Haapala @ 2004-03-26 16:59 UTC (permalink / raw) To: James Morris; +Cc: Jouni Malinen, David S. Miller, linux-kernel, Matt_Domsch On Fri, 26 Mar 2004, James Morris verbalised: > On Mon, 22 Mar 2004, Clay Haapala wrote: > >> This patch agains 2.6.4 kernel code implements the CRC32C >> algorithm. The routines are based on the same design as the >> existing CRC32 code. Licensing is intended to be identical (GPL). > > These need to be rediffed against the latest Linus kernel. > > It may be better to wait until 2.6.5 comes out, so we don't have too > much new stuff going into the -rc kernels. > All right, I'll wait for the 2.6.5 announcement and submit a diff against that. I assume that the code looks OK. Thanks! -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD "Microsoft bans gnus on these premises." ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c implementation 2004-03-26 16:59 ` Clay Haapala @ 2004-03-26 18:16 ` James Morris 0 siblings, 0 replies; 52+ messages in thread From: James Morris @ 2004-03-26 18:16 UTC (permalink / raw) To: Clay Haapala; +Cc: Jouni Malinen, David S. Miller, linux-kernel, Matt_Domsch On Fri, 26 Mar 2004, Clay Haapala wrote: > All right, I'll wait for the 2.6.5 announcement and submit a diff > against that. I assume that the code looks OK. Yep, looks fine to me, glad we can finally get this resolved. - James -- James Morris <jmorris@redhat.com> ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH] lib/libcrc32c 2004-03-26 16:36 ` James Morris 2004-03-26 16:59 ` Clay Haapala @ 2004-03-30 17:32 ` Clay Haapala 2004-03-30 18:43 ` Bartlomiej Zolnierkiewicz 2004-03-30 17:40 ` [PATCH] crypto/crc32c implementation Clay Haapala 2 siblings, 1 reply; 52+ messages in thread From: Clay Haapala @ 2004-03-30 17:32 UTC (permalink / raw) To: James Morris; +Cc: David S. Miller, linux-kernel, Matt_Domsch On Fri, 26 Mar 2004, James Morris outgrape: > These need to be rediffed against the latest Linus kernel. > > It may be better to wait until 2.6.5 comes out, so we don't have too > much new stuff going into the -rc kernels. > > > - James Rediffed they are! I see that the digest setkey() api is already part of -rc3, so because this code is a simple "add" and I will be on vacation next week when 2.6.5 might be cut, I am providing the patch now. This patch agains 2.6.5-rc3 kernel code implements the CRC32C algorithm. The routines are based on the same design as the existing CRC32 code. Licensing is intended to be identical (GPL). -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD Dyslexia meets Concealed Carry laws: "Microsoft bans gnus on these premises" diff -uNr --exclude BitKeeper --exclude SCCS linus-2.6.5-rc3/include/linux/crc32c.h linux/include/linux/crc32c.h --- linus-2.6.5-rc3/include/linux/crc32c.h 1969-12-31 18:00:00.000000000 -0600 +++ linux/include/linux/crc32c.h 2004-03-29 16:36:24.000000000 -0600 @@ -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 -uNr --exclude BitKeeper --exclude SCCS linus-2.6.5-rc3/lib/Kconfig linux/lib/Kconfig --- linus-2.6.5-rc3/lib/Kconfig 2004-03-29 15:30:22.000000000 -0600 +++ linux/lib/Kconfig 2004-03-29 16:36:24.000000000 -0600 @@ -12,6 +12,15 @@ 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. + Module will be libcrc32c. + # # compression support is select'ed if needed # diff -uNr --exclude BitKeeper --exclude SCCS linus-2.6.5-rc3/lib/libcrc32c.c linux/lib/libcrc32c.c --- linus-2.6.5-rc3/lib/libcrc32c.c 1969-12-31 18:00:00.000000000 -0600 +++ linux/lib/libcrc32c.c 2004-03-29 16:36:24.000000000 -0600 @@ -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"); + +#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. + */ +#if defined CRC_BE_BITS && CRC_BE_BITS != 1 +#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 -uNr --exclude BitKeeper --exclude SCCS linus-2.6.5-rc3/lib/Makefile linux/lib/Makefile --- linus-2.6.5-rc3/lib/Makefile 2004-03-29 15:30:22.000000000 -0600 +++ linux/lib/Makefile 2004-03-29 16:36:24.000000000 -0600 @@ -19,6 +19,7 @@ endif obj-$(CONFIG_CRC32) += crc32.o +obj-$(CONFIG_LIBCRC32C) += libcrc32c.o obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/ ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c 2004-03-30 17:32 ` [PATCH] lib/libcrc32c Clay Haapala @ 2004-03-30 18:43 ` Bartlomiej Zolnierkiewicz 2004-03-30 19:11 ` Clay Haapala 0 siblings, 1 reply; 52+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2004-03-30 18:43 UTC (permalink / raw) To: Clay Haapala, James Morris; +Cc: David S. Miller, linux-kernel, Matt_Domsch Hi, On Tuesday 30 of March 2004 19:32, Clay Haapala wrote: > On Fri, 26 Mar 2004, James Morris outgrape: > > These need to be rediffed against the latest Linus kernel. > > > > It may be better to wait until 2.6.5 comes out, so we don't have too > > much new stuff going into the -rc kernels. > > > > > > - James > > Rediffed they are! I see that the digest setkey() api is already part > of -rc3, so because this code is a simple "add" and I will be > on vacation next week when 2.6.5 might be cut, I am providing the > patch now. > > This patch agains 2.6.5-rc3 kernel code implements the CRC32C > algorithm. The routines are based on the same design as the > existing CRC32 code. Licensing is intended to be identical (GPL). +/* + * 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] = { Tables are build time generated in case of CRC32 (lib/gen_crc32table.c) so you can trade some performance for smaller size of the table. [ However I don't know how useful is this. ] +/*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 Is there any reason in adding crc32_be() until it is finished (LE version) and/or needed? Regards, Bartlomiej ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c 2004-03-30 18:43 ` Bartlomiej Zolnierkiewicz @ 2004-03-30 19:11 ` Clay Haapala 2004-03-30 19:23 ` Matt Domsch 2004-03-30 19:49 ` [PATCH] lib/libcrc32c Bartlomiej Zolnierkiewicz 0 siblings, 2 replies; 52+ messages in thread From: Clay Haapala @ 2004-03-30 19:11 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: James Morris, David S. Miller, linux-kernel, Matt_Domsch On Tue, 30 Mar 2004, Bartlomiej Zolnierkiewicz outgrape: > + > +static u32 crc32c_table[256] = { > > Tables are build time generated in case of CRC32 > (lib/gen_crc32table.c) so you can trade some performance for smaller > size of the table. > > [ However I don't know how useful is this. ] > As the table was statically in code in sctp and in the iSCSI driver where it originally came from, I left it that way. Why would the table be of a different size? > +/*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 > > Is there any reason in adding crc32_be() until it is finished > (LE version) and/or needed? > > Regards, > Bartlomiej I judged the few lines of code needed to do the non-table version was worth the bloat to include for completeness. -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD Dyslexia meets Concealed Carry laws: "Microsoft bans gnus on these premises" ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c 2004-03-30 19:11 ` Clay Haapala @ 2004-03-30 19:23 ` Matt Domsch 2004-03-30 19:33 ` Clay Haapala 2004-03-31 21:03 ` [PATCH] lib/libcrc32c, revised 040331 Clay Haapala 2004-03-30 19:49 ` [PATCH] lib/libcrc32c Bartlomiej Zolnierkiewicz 1 sibling, 2 replies; 52+ messages in thread From: Matt Domsch @ 2004-03-30 19:23 UTC (permalink / raw) To: Clay Haapala Cc: Bartlomiej Zolnierkiewicz, James Morris, David S. Miller, linux-kernel On Tue, Mar 30, 2004 at 01:11:41PM -0600, Clay Haapala wrote: > > +#if CRC_BE_BITS == 1 > > u32 attribute((pure)) crc32_be(u32 crc, Shouldn't this be crc32c_bc() instead? -- 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] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c 2004-03-30 19:23 ` Matt Domsch @ 2004-03-30 19:33 ` Clay Haapala 2004-03-31 21:03 ` [PATCH] lib/libcrc32c, revised 040331 Clay Haapala 1 sibling, 0 replies; 52+ messages in thread From: Clay Haapala @ 2004-03-30 19:33 UTC (permalink / raw) To: Matt Domsch Cc: Bartlomiej Zolnierkiewicz, James Morris, David S. Miller, linux-kernel On Tue, 30 Mar 2004, Matt Domsch told this: > On Tue, Mar 30, 2004 at 01:11:41PM -0600, Clay Haapala wrote: >> > +#if CRC_BE_BITS == 1 >> > u32 attribute((pure)) crc32_be(u32 crc, > > Shouldn't this be crc32c_bc() instead? Good catch! But rather crc32c_be(), I think. Maybe I should just take the code out -- there are no current users. -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD Dyslexia meets Concealed Carry laws: "Microsoft bans gnus on these premises" ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH] lib/libcrc32c, revised 040331 2004-03-30 19:23 ` Matt Domsch 2004-03-30 19:33 ` Clay Haapala @ 2004-03-31 21:03 ` Clay Haapala 2004-04-19 21:37 ` [PATCH] lib/libcrc32c, revised 040419 Clay Haapala 1 sibling, 1 reply; 52+ messages in thread From: Clay Haapala @ 2004-03-31 21:03 UTC (permalink / raw) To: Matt Domsch Cc: Bartlomiej Zolnierkiewicz, James Morris, David S. Miller, linux-kernel On Tue, 30 Mar 2004, Matt Domsch verbalised: > On Tue, Mar 30, 2004 at 01:11:41PM -0600, Clay Haapala wrote: >> > +#if CRC_BE_BITS == 1 >> > u32 attribute((pure)) crc32_be(u32 crc, > > Shouldn't this be crc32c_bc() instead? Below is the corrected patch with crc32c_be() declared correctly. We can still debate whether it should be included, but at least that's right now. -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD Dyslexia meets Concealed Carry laws: "Microsoft bans gnus on these premises" --- linus-2.6.5-rc3/include/linux/crc32c.h 1969-12-31 18:00:00.000000000 -0600 +++ linux/include/linux/crc32c.h 2004-03-29 16:36:24.000000000 -0600 @@ -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 */ --- linus-2.6.5-rc3/lib/Kconfig 2004-03-29 15:30:22.000000000 -0600 +++ linux/lib/Kconfig 2004-03-29 16:36:24.000000000 -0600 @@ -12,6 +12,15 @@ 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. + Module will be libcrc32c. + # # compression support is select'ed if needed # --- linus-2.6.5-rc3/lib/libcrc32c.c 1969-12-31 18:00:00.000000000 -0600 +++ linux/lib/libcrc32c.c 2004-03-31 14:52:05.000000000 -0600 @@ -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) 2004 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"); + +#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. + */ +#if defined CRC_BE_BITS && CRC_BE_BITS != 1 +#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)) +crc32c_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. + */ --- linus-2.6.5-rc3/lib/Makefile 2004-03-29 15:30:22.000000000 -0600 +++ linux/lib/Makefile 2004-03-29 16:36:24.000000000 -0600 @@ -19,6 +19,7 @@ endif obj-$(CONFIG_CRC32) += crc32.o +obj-$(CONFIG_LIBCRC32C) += libcrc32c.o obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/ ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH] lib/libcrc32c, revised 040419 2004-03-31 21:03 ` [PATCH] lib/libcrc32c, revised 040331 Clay Haapala @ 2004-04-19 21:37 ` Clay Haapala 2004-04-23 23:42 ` David S. Miller 0 siblings, 1 reply; 52+ messages in thread From: Clay Haapala @ 2004-04-19 21:37 UTC (permalink / raw) To: James Morris Cc: Matt Domsch, Bartlomiej Zolnierkiewicz, David S. Miller, linux-kernel On Wed, 31 Mar 2004, Clay Haapala spake thusly: > On Tue, 30 Mar 2004, Matt Domsch verbalised: >> On Tue, Mar 30, 2004 at 01:11:41PM -0600, Clay Haapala wrote: >>> > +#if CRC_BE_BITS == 1 >>> > u32 attribute((pure)) crc32_be(u32 crc, >> >> Shouldn't this be crc32c_bc() instead? > > Below is the corrected patch with crc32c_be() declared correctly. > We can still debate whether it should be included, but at least > that's right now. I re-diffed the lib directory against 2.6.6-rc1 fresh out of the BK repo. There were no changes necessary, but here it is below. The crc32c is used by the wrappers under crypto, which will be used by the iscsi-sfnet driver presently. -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD If, for the sake of keeping Americans from dying, the liberties for which Americans have fought and died are infringed, who has won? diff -ruN --exclude=SCCS --exclude=BitKeeper linux-2.6.6-rc1-bk.orig/lib/Kconfig linux-2.6.6-rc1/lib/Kconfig --- linux-2.6.6-rc1-bk.orig/lib/Kconfig 2004-03-29 15:30:22.000000000 -0600 +++ linux-2.6.6-rc1/lib/Kconfig 2004-04-19 16:17:48.000000000 -0500 @@ -12,6 +12,15 @@ 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. + Module will be libcrc32c. + # # compression support is select'ed if needed # diff -ruN --exclude=SCCS --exclude=BitKeeper linux-2.6.6-rc1-bk.orig/lib/libcrc32c.c linux-2.6.6-rc1/lib/libcrc32c.c --- linux-2.6.6-rc1-bk.orig/lib/libcrc32c.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.6-rc1/lib/libcrc32c.c 2004-04-19 16:17:48.000000000 -0500 @@ -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) 2004 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"); + +#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. + */ +#if defined CRC_BE_BITS && CRC_BE_BITS != 1 +#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)) +crc32c_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 -ruN --exclude=SCCS --exclude=BitKeeper linux-2.6.6-rc1-bk.orig/lib/Makefile linux-2.6.6-rc1/lib/Makefile --- linux-2.6.6-rc1-bk.orig/lib/Makefile 2004-03-29 15:30:22.000000000 -0600 +++ linux-2.6.6-rc1/lib/Makefile 2004-04-19 16:17:48.000000000 -0500 @@ -19,6 +19,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 -ruN --exclude=SCCS --exclude=BitKeeper linux-2.6.6-rc1-bk.orig/include/linux/crc32c.h linux-2.6.6-rc1/include/linux/crc32c.h --- linux-2.6.6-rc1-bk.orig/include/linux/crc32c.h 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.6-rc1/include/linux/crc32c.h 2004-04-19 16:17:48.000000000 -0500 @@ -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 */ ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c, revised 040419 2004-04-19 21:37 ` [PATCH] lib/libcrc32c, revised 040419 Clay Haapala @ 2004-04-23 23:42 ` David S. Miller 2004-04-27 19:46 ` [PATCH] lib/libcrc32c, revised 040427 Clay Haapala 2004-04-27 19:55 ` [PATCH] lib/crc32.c: to use compiler.h defines Clay Haapala 0 siblings, 2 replies; 52+ messages in thread From: David S. Miller @ 2004-04-23 23:42 UTC (permalink / raw) To: Clay Haapala; +Cc: jmorris, Matt_Domsch, B.Zolnierkiewicz, linux-kernel On Mon, 19 Apr 2004 16:37:01 -0500 Clay Haapala <chaapala@cisco.com> wrote: > +#if __GNUC__ >= 3 /* 2.x has "attribute", but only 3.0 has "pure */ > +#define attribute(x) __attribute__(x) > +#else > +#define attribute(x) > +#endif I was about to apply your two patches, but then I noticed this thing. WHatever you may need this for exists in linux/compiler.h and if it doesn't you should add the necessary macro interfaces there. Thanks. ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH] lib/libcrc32c, revised 040427 2004-04-23 23:42 ` David S. Miller @ 2004-04-27 19:46 ` Clay Haapala 2004-04-27 19:49 ` David S. Miller 2004-04-27 19:55 ` [PATCH] lib/crc32.c: to use compiler.h defines Clay Haapala 1 sibling, 1 reply; 52+ messages in thread From: Clay Haapala @ 2004-04-27 19:46 UTC (permalink / raw) To: David S. Miller; +Cc: jmorris, Matt_Domsch, B.Zolnierkiewicz, linux-kernel On Fri, 23 Apr 2004, David S. Miller outgrape: > On Mon, 19 Apr 2004 16:37:01 -0500 > Clay Haapala <chaapala@cisco.com> wrote: > >> +#if __GNUC__ >= 3 /* 2.x has "attribute", but only 3.0 has "pure >> +*/ #define attribute(x) __attribute__(x) #else #define >> +attribute(x) #endif > > I was about to apply your two patches, but then I noticed this > thing. WHatever you may need this for exists in linux/compiler.h > and if it doesn't you should add the necessary macro interfaces > there. > > Thanks. Attribute(pure) was used, so I changed the patch to use the define in compiler.h, as you suggest. I will also change crc32.c, and submit in a second patch. This is a patch against 2.6.5 sources. I did not change the crypto patch, as this construct was not used there. Thanks! -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD "Oh, *that* Physics Prize. Well, I just substituted 'stupidity' for 'dark matter' in the equations, and it all came together." diff -ruN linux-2.6.5.orig/lib/Kconfig linux-2.6.5/lib/Kconfig --- linux-2.6.5.orig/lib/Kconfig Sat Apr 3 21:37:23 2004 +++ linux-2.6.5/lib/Kconfig Tue Apr 27 13:39:03 2004 @@ -12,6 +12,15 @@ 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. + Module will be libcrc32c. + # # compression support is select'ed if needed # diff -ruN linux-2.6.5.orig/lib/Makefile linux-2.6.5/lib/Makefile --- linux-2.6.5.orig/lib/Makefile Sat Apr 3 21:36:16 2004 +++ linux-2.6.5/lib/Makefile Tue Apr 27 13:39:03 2004 @@ -19,6 +19,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 -ruN linux-2.6.5.orig/lib/libcrc32c.c linux-2.6.5/lib/libcrc32c.c --- linux-2.6.5.orig/lib/libcrc32c.c Wed Dec 31 18:00:00 1969 +++ linux-2.6.5/lib/libcrc32c.c Tue Apr 27 14:34:10 2004 @@ -0,0 +1,199 @@ +/* + * 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) 2004 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"); + +#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. + */ +#if defined CRC_BE_BITS && CRC_BE_BITS != 1 +#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__ +crc32c_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 -ruN linux-2.6.5.orig/include/linux/crc32c.h linux-2.6.5/include/linux/crc32c.h --- linux-2.6.5.orig/include/linux/crc32c.h Wed Dec 31 18:00:00 1969 +++ linux-2.6.5/include/linux/crc32c.h Tue Apr 27 13:39:03 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 */ ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c, revised 040427 2004-04-27 19:46 ` [PATCH] lib/libcrc32c, revised 040427 Clay Haapala @ 2004-04-27 19:49 ` David S. Miller 2004-04-27 20:00 ` Clay Haapala 0 siblings, 1 reply; 52+ messages in thread From: David S. Miller @ 2004-04-27 19:49 UTC (permalink / raw) To: Clay Haapala; +Cc: jmorris, Matt_Domsch, B.Zolnierkiewicz, linux-kernel On Tue, 27 Apr 2004 14:46:35 -0500 Clay Haapala <chaapala@cisco.com> wrote: > Attribute(pure) was used, so I changed the patch to use the define in > compiler.h, as you suggest. I will also change crc32.c, and submit in > a second patch. This is a patch against 2.6.5 sources. I did not > change the crypto patch, as this construct was not used there. Please include linux/compiler.h if you're going to use it :-) Once you fix that, send it again and resend the crypto part to me as well and I'll apply everything for you. Thanks a lot for following up on this. ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c, revised 040427 2004-04-27 19:49 ` David S. Miller @ 2004-04-27 20:00 ` Clay Haapala 2004-04-27 21:49 ` Clay Haapala 0 siblings, 1 reply; 52+ messages in thread From: Clay Haapala @ 2004-04-27 20:00 UTC (permalink / raw) To: David S. Miller; +Cc: jmorris, Matt_Domsch, B.Zolnierkiewicz, linux-kernel On Tue, 27 Apr 2004, David S. Miller spake thusly: > On Tue, 27 Apr 2004 14:46:35 -0500 > Clay Haapala <chaapala@cisco.com> wrote: > >> Attribute(pure) was used, so I changed the patch to use the define >> in compiler.h, as you suggest. I will also change crc32.c, and >> submit in a second patch. This is a patch against 2.6.5 sources. >> I did not change the crypto patch, as this construct was not used >> there. > > Please include linux/compiler.h if you're going to use it :-) > > Once you fix that, send it again and resend the crypto part to > me as well and I'll apply everything for you. > > Thanks a lot for following up on this. Uh .. I was prepared to terminally embarrassed by forgetting the #include, but I *did* compile the files, with both GCC 3.3 and 2.96, so compiler.h must be included by something else. Do you wish an explicit include of compiler.h anyways? If so, no problem, let me know. -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD "Oh, *that* Physics Prize. Well, I just substituted 'stupidity' for 'dark matter' in the equations, and it all came together." ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c, revised 040427 2004-04-27 20:00 ` Clay Haapala @ 2004-04-27 21:49 ` Clay Haapala 2004-04-27 21:50 ` David S. Miller 0 siblings, 1 reply; 52+ messages in thread From: Clay Haapala @ 2004-04-27 21:49 UTC (permalink / raw) To: David S. Miller; +Cc: jmorris, Matt_Domsch, B.Zolnierkiewicz, linux-kernel On Tue, 27 Apr 2004, Clay Haapala stated: > On Tue, 27 Apr 2004, David S. Miller spake thusly: >> On Tue, 27 Apr 2004 14:46:35 -0500 >> Clay Haapala <chaapala@cisco.com> wrote: >> >>> Attribute(pure) was used, so I changed the patch to use the define >>> in compiler.h, as you suggest. I will also change crc32.c, and >>> submit in a second patch. This is a patch against 2.6.5 sources. >>> I did not change the crypto patch, as this construct was not used >>> there. >> >> Please include linux/compiler.h if you're going to use it :-) >> >> Once you fix that, send it again and resend the crypto part to >> me as well and I'll apply everything for you. >> >> Thanks a lot for following up on this. > > Uh .. I was prepared to terminally embarrassed by forgetting the > #include, but I *did* compile the files, with both GCC 3.3 and 2.96, > so compiler.h must be included by something else. Do you wish an > explicit include of compiler.h anyways? If so, no problem, let me > know. The 'something else' in question that includes compiler.h is: kernel.h:#include <linux/compiler.h> module.h:#include <linux/compiler.h> init.h:#include <linux/compiler.h> so that is why it compiles. Is it accepted form to add the include line even so? -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD "Oh, *that* Physics Prize. Well, I just substituted 'stupidity' for 'dark matter' in the equations, and it all came together." ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c, revised 040427 2004-04-27 21:49 ` Clay Haapala @ 2004-04-27 21:50 ` David S. Miller 2004-04-28 15:14 ` [PATCH] lib/libcrc32c, revised 040428, with compiler.h included Clay Haapala 0 siblings, 1 reply; 52+ messages in thread From: David S. Miller @ 2004-04-27 21:50 UTC (permalink / raw) To: Clay Haapala; +Cc: jmorris, Matt_Domsch, B.Zolnierkiewicz, linux-kernel On Tue, 27 Apr 2004 16:49:53 -0500 Clay Haapala <chaapala@cisco.com> wrote: > Is it accepted form to add the include line even so? Yes, it only works today because those other headers include it. ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH] lib/libcrc32c, revised 040428, with compiler.h included 2004-04-27 21:50 ` David S. Miller @ 2004-04-28 15:14 ` Clay Haapala 2004-04-28 19:29 ` David S. Miller 0 siblings, 1 reply; 52+ messages in thread From: Clay Haapala @ 2004-04-28 15:14 UTC (permalink / raw) To: David S. Miller; +Cc: jmorris, Matt_Domsch, B.Zolnierkiewicz, linux-kernel On Tue, 27 Apr 2004, David S. Miller stated: > On Tue, 27 Apr 2004 16:49:53 -0500 > Clay Haapala <chaapala@cisco.com> wrote: > >> Is it accepted form to add the include line even so? > > Yes, it only works today because those other headers include it. OK, below is the patch with compiler.h included. -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD "Oh, *that* Physics Prize. Well, I just substituted 'stupidity' for 'dark matter' in the equations, and it all came together." diff -ruN linux-2.6.5.orig/lib/Kconfig linux-2.6.5/lib/Kconfig --- linux-2.6.5.orig/lib/Kconfig Sat Apr 3 21:37:23 2004 +++ linux-2.6.5/lib/Kconfig Tue Apr 27 13:39:03 2004 @@ -12,6 +12,15 @@ 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. + Module will be libcrc32c. + # # compression support is select'ed if needed # diff -ruN linux-2.6.5.orig/lib/Makefile linux-2.6.5/lib/Makefile --- linux-2.6.5.orig/lib/Makefile Sat Apr 3 21:36:16 2004 +++ linux-2.6.5/lib/Makefile Tue Apr 27 13:39:03 2004 @@ -19,6 +19,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 -ruN linux-2.6.5.orig/lib/libcrc32c.c linux-2.6.5/lib/libcrc32c.c --- linux-2.6.5.orig/lib/libcrc32c.c Wed Dec 31 18:00:00 1969 +++ linux-2.6.5/lib/libcrc32c.c Wed Apr 28 10:06:15 2004 @@ -0,0 +1,200 @@ +/* + * 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) 2004 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/compiler.h> +#include <linux/module.h> +#include <asm/byteorder.h> + +MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>"); +MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations"); +MODULE_LICENSE("GPL"); + +#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. + */ +#if defined CRC_BE_BITS && CRC_BE_BITS != 1 +#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__ +crc32c_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 -ruN linux-2.6.5.orig/include/linux/crc32c.h linux-2.6.5/include/linux/crc32c.h --- linux-2.6.5.orig/include/linux/crc32c.h Wed Dec 31 18:00:00 1969 +++ linux-2.6.5/include/linux/crc32c.h Tue Apr 27 13:39:03 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 */ ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c, revised 040428, with compiler.h included 2004-04-28 15:14 ` [PATCH] lib/libcrc32c, revised 040428, with compiler.h included Clay Haapala @ 2004-04-28 19:29 ` David S. Miller 0 siblings, 0 replies; 52+ messages in thread From: David S. Miller @ 2004-04-28 19:29 UTC (permalink / raw) To: Clay Haapala; +Cc: jmorris, Matt_Domsch, B.Zolnierkiewicz, linux-kernel On Wed, 28 Apr 2004 10:14:32 -0500 Clay Haapala <chaapala@cisco.com> wrote: > On Tue, 27 Apr 2004, David S. Miller stated: > > On Tue, 27 Apr 2004 16:49:53 -0500 > > Clay Haapala <chaapala@cisco.com> wrote: > > > >> Is it accepted form to add the include line even so? > > > > Yes, it only works today because those other headers include it. > > OK, below is the patch with compiler.h included. Looks great, patch applied. Thanks. ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH] lib/crc32.c: to use compiler.h defines 2004-04-23 23:42 ` David S. Miller 2004-04-27 19:46 ` [PATCH] lib/libcrc32c, revised 040427 Clay Haapala @ 2004-04-27 19:55 ` Clay Haapala 2004-04-28 15:19 ` [PATCH] lib/crc32.c: uses (and includes) compiler.h Clay Haapala 1 sibling, 1 reply; 52+ messages in thread From: Clay Haapala @ 2004-04-27 19:55 UTC (permalink / raw) To: David S. Miller; +Cc: jmorris, Matt_Domsch, B.Zolnierkiewicz, linux-kernel On Fri, 23 Apr 2004, David S. Miller told this: > On Mon, 19 Apr 2004 16:37:01 -0500 > Clay Haapala <chaapala@cisco.com> wrote: > >> +#if __GNUC__ >= 3 /* 2.x has "attribute", but only 3.0 has "pure >> +*/ #define attribute(x) __attribute__(x) #else #define >> +attribute(x) #endif > > I was about to apply your two patches, but then I noticed this > thing. WHatever you may need this for exists in linux/compiler.h > and if it doesn't you should add the necessary macro interfaces > there. > > Thanks. Below is a patch to lib/crc32.c to use the compiler.h define for attribute((pure)). -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD "Oh, *that* Physics Prize. Well, I just substituted 'stupidity' for 'dark matter' in the equations, and it all came together." --- linux-2.6.5.orig/lib/crc32.c Sat Apr 3 21:36:14 2004 +++ linux-2.6.5/lib/crc32.c Tue Apr 27 14:48:03 2004 @@ -37,13 +37,6 @@ #endif #include "crc32table.h" -#if __GNUC__ >= 3 /* 2.x has "attribute", but only 3.0 has "pure */ -#define attribute(x) __attribute__(x) -#else -#define attribute(x) -#endif - - MODULE_AUTHOR("Matt Domsch <Matt_Domsch@dell.com>"); MODULE_DESCRIPTION("Ethernet CRC32 calculations"); MODULE_LICENSE("GPL"); @@ -62,7 +55,7 @@ * @len - length of buffer @p * */ -u32 attribute((pure)) crc32_le(u32 crc, unsigned char const *p, size_t len) +u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len) { int i; while (len--) { @@ -82,7 +75,7 @@ * @len - length of buffer @p * */ -u32 attribute((pure)) crc32_le(u32 crc, unsigned char const *p, size_t len) +u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len) { # if CRC_LE_BITS == 8 const u32 *b =(u32 *)p; @@ -165,7 +158,7 @@ * @len - length of buffer @p * */ -u32 attribute((pure)) crc32_be(u32 crc, unsigned char const *p, size_t len) +u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len) { int i; while (len--) { @@ -187,7 +180,7 @@ * @len - ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH] lib/crc32.c: uses (and includes) compiler.h 2004-04-27 19:55 ` [PATCH] lib/crc32.c: to use compiler.h defines Clay Haapala @ 2004-04-28 15:19 ` Clay Haapala 2004-04-28 19:30 ` David S. Miller 0 siblings, 1 reply; 52+ messages in thread From: Clay Haapala @ 2004-04-28 15:19 UTC (permalink / raw) To: David S. Miller; +Cc: jmorris, Matt_Domsch, B.Zolnierkiewicz, linux-kernel Here is the crc32.c patch to remove attribute((pure)), with compiler.h included. -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD "Oh, *that* Physics Prize. Well, I just substituted 'stupidity' for 'dark matter' in the equations, and it all came together." --- linux-2.6.5.orig/lib/crc32.c Sat Apr 3 21:36:14 2004 +++ linux-2.6.5/lib/crc32.c Wed Apr 28 10:07:20 2004 @@ -23,6 +23,7 @@ #include <linux/crc32.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/compiler.h> #include <linux/types.h> #include <linux/slab.h> #include <linux/init.h> @@ -37,13 +38,6 @@ #endif #include "crc32table.h" -#if __GNUC__ >= 3 /* 2.x has "attribute", but only 3.0 has "pure */ -#define attribute(x) __attribute__(x) -#else -#define attribute(x) -#endif - - MODULE_AUTHOR("Matt Domsch <Matt_Domsch@dell.com>"); MODULE_DESCRIPTION("Ethernet CRC32 calculations"); MODULE_LICENSE("GPL"); @@ -62,7 +56,7 @@ * @len - length of buffer @p * */ -u32 attribute((pure)) crc32_le(u32 crc, unsigned char const *p, size_t len) +u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len) { int i; while (len--) { @@ -82,7 +76,7 @@ * @len - length of buffer @p * */ -u32 attribute((pure)) crc32_le(u32 crc, unsigned char const *p, size_t len) +u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len) { # if CRC_LE_BITS == 8 const u32 *b =(u32 *)p; @@ -165,7 +159,7 @@ * @len - length of buffer @p * */ -u32 attribute((pure)) crc32_be(u32 crc, unsigned char const *p, size_t len) +u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len) { int i; while (len--) { @@ -187,7 +181,7 @@ * @len - length of buffer @p * */ -u32 attribute((pure)) crc32_be(u32 crc, unsigned char const *p, size_t len) +u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len) { # if CRC_BE_BITS == 8 const u32 *b =(u32 *)p; ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/crc32.c: uses (and includes) compiler.h 2004-04-28 15:19 ` [PATCH] lib/crc32.c: uses (and includes) compiler.h Clay Haapala @ 2004-04-28 19:30 ` David S. Miller 0 siblings, 0 replies; 52+ messages in thread From: David S. Miller @ 2004-04-28 19:30 UTC (permalink / raw) To: Clay Haapala; +Cc: jmorris, Matt_Domsch, B.Zolnierkiewicz, linux-kernel On Wed, 28 Apr 2004 10:19:02 -0500 Clay Haapala <chaapala@cisco.com> wrote: > Here is the crc32.c patch to remove attribute((pure)), with compiler.h > included. Applied, thanks! ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c 2004-03-30 19:11 ` Clay Haapala 2004-03-30 19:23 ` Matt Domsch @ 2004-03-30 19:49 ` Bartlomiej Zolnierkiewicz 2004-03-31 15:28 ` Clay Haapala 1 sibling, 1 reply; 52+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2004-03-30 19:49 UTC (permalink / raw) To: Clay Haapala; +Cc: James Morris, David S. Miller, linux-kernel, Matt_Domsch On Tuesday 30 of March 2004 21:11, Clay Haapala wrote: > On Tue, 30 Mar 2004, Bartlomiej Zolnierkiewicz outgrape: > > + > > +static u32 crc32c_table[256] = { > > > > Tables are build time generated in case of CRC32 > > (lib/gen_crc32table.c) so you can trade some performance for smaller > > size of the table. > > > > [ However I don't know how useful is this. ] > > As the table was statically in code in sctp and in the iSCSI driver > where it originally came from, I left it that way. Why would the > table be of a different size? See lib/crc32defs.h and lib/gen_crc32table.c. lib/crc32defs.h: /* How many bits at a time to use. Requires a table of 4<<CRC_xx_BITS bytes. */ /* For less performance-sensitive, use 4 */ #ifndef CRC_LE_BITS # define CRC_LE_BITS 8 #endif #ifndef CRC_BE_BITS # define CRC_BE_BITS 8 #endif lib/gen_crc32table.c: #define LE_TABLE_SIZE (1 << CRC_LE_BITS) #define BE_TABLE_SIZE (1 << CRC_BE_BITS) static u_int32_t crc32table_le[LE_TABLE_SIZE]; static u_int32_t crc32table_be[BE_TABLE_SIZE]; Regards, Bartlomiej ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] lib/libcrc32c 2004-03-30 19:49 ` [PATCH] lib/libcrc32c Bartlomiej Zolnierkiewicz @ 2004-03-31 15:28 ` Clay Haapala 0 siblings, 0 replies; 52+ messages in thread From: Clay Haapala @ 2004-03-31 15:28 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: James Morris, David S. Miller, linux-kernel, Matt_Domsch On Tue, 30 Mar 2004, Bartlomiej Zolnierkiewicz told this: > On Tuesday 30 of March 2004 21:11, Clay Haapala wrote: >> On Tue, 30 Mar 2004, Bartlomiej Zolnierkiewicz outgrape: >> > + >> > +static u32 crc32c_table[256] = { >> > >> > Tables are build time generated in case of CRC32 >> > (lib/gen_crc32table.c) so you can trade some performance for >> > smaller size of the table. >> > >> > [ However I don't know how useful is this. ] >> >> As the table was statically in code in sctp and in the iSCSI driver >> where it originally came from, I left it that way. Why would the >> table be of a different size? > > See lib/crc32defs.h and lib/gen_crc32table.c. > > lib/crc32defs.h: > > /* How many bits at a time to use. Requires a table of > 4<<CRC_xx_BITS bytes. */ /* For less performance-sensitive, use 4 */ > #ifndef CRC_LE_BITS # define CRC_LE_BITS 8 #endif #ifndef > CRC_BE_BITS # define CRC_BE_BITS 8 #endif > > lib/gen_crc32table.c: > > #define LE_TABLE_SIZE (1 << CRC_LE_BITS) > #define BE_TABLE_SIZE (1 << CRC_BE_BITS) > > static u_int32_t crc32table_le[LE_TABLE_SIZE]; > static u_int32_t crc32table_be[BE_TABLE_SIZE]; > > This is a legitimate question. The immediate user of this crc32c is the iscsi-sfnet driver, and my mind-set for that is always towards gigabit-ethernet wire-rate, so that bias may prevent me from making the right choice here. Regarding performance vs. size, we have the BITS == 8 table for "high" performance and bigger size, and BITS == 1 bit-wise computation, for the least size, albeit slower performance. Is that good enough? The last time I wrote CRC lookup code for nibble-sized tables, it was for an 8051 microcontroller. :-) -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD Dyslexia meets Concealed Carry laws: "Microsoft bans gnus on these premises" ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH] crypto/crc32c implementation 2004-03-26 16:36 ` James Morris 2004-03-26 16:59 ` Clay Haapala 2004-03-30 17:32 ` [PATCH] lib/libcrc32c Clay Haapala @ 2004-03-30 17:40 ` Clay Haapala 2004-04-19 21:31 ` [PATCH] crypto/crc32c implementation, updated 040419 Clay Haapala 2 siblings, 1 reply; 52+ messages in thread From: Clay Haapala @ 2004-03-30 17:40 UTC (permalink / raw) To: James Morris; +Cc: Jouni Malinen, David S. Miller, linux-kernel This patch agains 2.6.5-rc3 implements the CRC32C algorithm as a type of digest. It is implemented as a wrapper for libcrc32c, available in a separate patch. The crypto CRC32C module will be used by the iscsi-sfnet driver. As I may be on vacation when 2.6.5 is cut, and this code is an "add", I thought it best to provide the patch now. -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD Dyslexia meets Concealed Carry laws: "Microsoft bans gnus on these premises" diff -uNr --exclude BitKeeper --exclude SCCS linus-2.6.5-rc3/crypto/crc32c.c linux/crypto/crc32c.c --- linus-2.6.5-rc3/crypto/crc32c.c 1969-12-31 18:00:00.000000000 -0600 +++ linux/crypto/crc32c.c 2004-03-29 16:36:04.000000000 -0600 @@ -0,0 +1,110 @@ +/* + * Cryptographic API. + * + * CRC32C chksum + * + * This module 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 4 + +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 int chksum_setkey(void *ctx, const u8 *key, unsigned int keylen, + u32 *flags) +{ + struct chksum_ctx *mctx = ctx; + + if (keylen != sizeof(mctx->crc)) { + if (flags) + *flags = CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + mctx->crc = __cpu_to_le32(*(u32 *)key); + return 0; +} + +static void chksum_update(void *ctx, const u8 *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, u8 *out) +{ + struct chksum_ctx *mctx = ctx; + u32 mcrc = (mctx->crc ^ ~(u32)0); + + *(u32 *)out = __le32_to_cpu(mcrc); +} + +static struct crypto_alg alg = { + .cra_name = "crc32c", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .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 = { + .digest = { + .dia_digestsize= CHKSUM_DIGEST_SIZE, + .dia_setkey = chksum_setkey, + .dia_init = chksum_init, + .dia_update = chksum_update, + .dia_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"); diff -uNr --exclude BitKeeper --exclude SCCS linus-2.6.5-rc3/crypto/Kconfig linux/crypto/Kconfig --- linus-2.6.5-rc3/crypto/Kconfig 2004-03-29 15:29:29.000000000 -0600 +++ linux/crypto/Kconfig 2004-03-29 16:36:04.000000000 -0600 @@ -170,6 +170,16 @@ should not be used for other purposes because of the weakness of the algorithm. +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/libcrc32c. + Module will be crc32c. + config CRYPTO_TEST tristate "Testing module" depends on CRYPTO diff -uNr --exclude BitKeeper --exclude SCCS linus-2.6.5-rc3/crypto/Makefile linux/crypto/Makefile --- linus-2.6.5-rc3/crypto/Makefile 2004-03-29 15:29:29.000000000 -0600 +++ linux/crypto/Makefile 2004-03-29 16:36:04.000000000 -0600 @@ -24,5 +24,6 @@ obj-$(CONFIG_CRYPTO_ARC4) += arc4.o obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o +obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o diff -uNr --exclude BitKeeper --exclude SCCS linus-2.6.5-rc3/crypto/tcrypt.c linux/crypto/tcrypt.c --- linus-2.6.5-rc3/crypto/tcrypt.c 2004-03-29 15:29:30.000000000 -0600 +++ linux/crypto/tcrypt.c 2004-03-29 16:36:04.000000000 -0600 @@ -61,7 +61,7 @@ static char *check[] = { "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", - "arc4", "michael_mic", "deflate", NULL + "arc4", "michael_mic", "deflate", "crc32c", NULL }; static void @@ -496,6 +496,107 @@ } 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 initialized to %08x: %s\n"; +#define SEEDTESTVAL 0xedcba987 + u32 seed; + + printk("\ntesting crc32c\n"); + + tfm = crypto_alloc_tfm("crc32c", 0); + if (tfm == NULL) { + printk("failed to load transform for crc32c\n"); + return; + } + + crypto_digest_init(tfm); + crypto_digest_final(tfm, (u8*)&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; + } + + seed = SEEDTESTVAL; + (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); + crypto_digest_final(tfm, (u8*)&crc); + printk("testing crc32c setkey 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++) { + seed = ~(u32)0; + (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); + crypto_digest_update(tfm, &sg[i], 1); + crypto_digest_final(tfm, (u8*)&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++) { + seed = (crc ^ ~(u32)0); + (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); + crypto_digest_update(tfm, &sg[i], 1); + crypto_digest_final(tfm, (u8*)&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"); + seed = ~(u32)0; + (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); + crypto_digest_digest(tfm, sg, NUMVEC, (u8*)&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; @@ -566,7 +667,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); @@ -657,6 +759,10 @@ test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); break; + case 18: + test_crc32c(); + break; + #ifdef CONFIG_CRYPTO_HMAC case 100: test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH] crypto/crc32c implementation, updated 040419 2004-03-30 17:40 ` [PATCH] crypto/crc32c implementation Clay Haapala @ 2004-04-19 21:31 ` Clay Haapala 2004-04-19 23:36 ` David S. Miller 0 siblings, 1 reply; 52+ messages in thread From: Clay Haapala @ 2004-04-19 21:31 UTC (permalink / raw) To: James Morris; +Cc: David S. Miller, linux-kernel This patch agains 2.6.6-rc1-bk implements the CRC32C algorithm as a type of digest. It is implemented as a wrapper for libcrc32c, available in a separate patch. The crypto CRC32C module will be used by the iscsi-sfnet driver. -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD If, for the sake of keeping Americans from dying, the liberties for which Americans have fought and died are infringed, who has won? diff -ruN --exclude='*.orig' --exclude=SCCS --exclude=BitKeeper linux-2.6.6-rc1-bk.orig/crypto/crc32c.c linux-2.6.6-rc1/crypto/crc32c.c --- linux-2.6.6-rc1-bk.orig/crypto/crc32c.c 1969-12-31 18:00:00.000000000 -0600 +++ linux-2.6.6-rc1/crypto/crc32c.c 2004-04-19 16:17:57.000000000 -0500 @@ -0,0 +1,110 @@ +/* + * Cryptographic API. + * + * CRC32C chksum + * + * This module 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 4 + +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 int chksum_setkey(void *ctx, const u8 *key, unsigned int keylen, + u32 *flags) +{ + struct chksum_ctx *mctx = ctx; + + if (keylen != sizeof(mctx->crc)) { + if (flags) + *flags = CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + mctx->crc = __cpu_to_le32(*(u32 *)key); + return 0; +} + +static void chksum_update(void *ctx, const u8 *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, u8 *out) +{ + struct chksum_ctx *mctx = ctx; + u32 mcrc = (mctx->crc ^ ~(u32)0); + + *(u32 *)out = __le32_to_cpu(mcrc); +} + +static struct crypto_alg alg = { + .cra_name = "crc32c", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .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 = { + .digest = { + .dia_digestsize= CHKSUM_DIGEST_SIZE, + .dia_setkey = chksum_setkey, + .dia_init = chksum_init, + .dia_update = chksum_update, + .dia_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"); diff -ruN --exclude='*.orig' --exclude=SCCS --exclude=BitKeeper linux-2.6.6-rc1-bk.orig/crypto/Kconfig linux-2.6.6-rc1/crypto/Kconfig --- linux-2.6.6-rc1-bk.orig/crypto/Kconfig 2004-04-19 15:04:01.000000000 -0500 +++ linux-2.6.6-rc1/crypto/Kconfig 2004-04-19 16:17:57.000000000 -0500 @@ -171,6 +171,16 @@ should not be used for other purposes because of the weakness of the algorithm. +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/libcrc32c. + Module will be crc32c. + config CRYPTO_TEST tristate "Testing module" depends on CRYPTO diff -ruN --exclude='*.orig' --exclude=SCCS --exclude=BitKeeper linux-2.6.6-rc1-bk.orig/crypto/Makefile linux-2.6.6-rc1/crypto/Makefile --- linux-2.6.6-rc1-bk.orig/crypto/Makefile 2004-03-29 15:29:29.000000000 -0600 +++ linux-2.6.6-rc1/crypto/Makefile 2004-04-19 16:17:57.000000000 -0500 @@ -24,5 +24,6 @@ obj-$(CONFIG_CRYPTO_ARC4) += arc4.o obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o +obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o diff -ruN --exclude='*.orig' --exclude=SCCS --exclude=BitKeeper linux-2.6.6-rc1-bk.orig/crypto/tcrypt.c linux-2.6.6-rc1/crypto/tcrypt.c --- linux-2.6.6-rc1-bk.orig/crypto/tcrypt.c 2004-03-29 15:29:30.000000000 -0600 +++ linux-2.6.6-rc1/crypto/tcrypt.c 2004-04-19 16:17:57.000000000 -0500 @@ -61,7 +61,7 @@ static char *check[] = { "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", - "arc4", "michael_mic", "deflate", NULL + "arc4", "michael_mic", "deflate", "crc32c", NULL }; static void @@ -496,6 +496,107 @@ } 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 initialized to %08x: %s\n"; +#define SEEDTESTVAL 0xedcba987 + u32 seed; + + printk("\ntesting crc32c\n"); + + tfm = crypto_alloc_tfm("crc32c", 0); + if (tfm == NULL) { + printk("failed to load transform for crc32c\n"); + return; + } + + crypto_digest_init(tfm); + crypto_digest_final(tfm, (u8*)&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; + } + + seed = SEEDTESTVAL; + (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); + crypto_digest_final(tfm, (u8*)&crc); + printk("testing crc32c setkey 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++) { + seed = ~(u32)0; + (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); + crypto_digest_update(tfm, &sg[i], 1); + crypto_digest_final(tfm, (u8*)&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++) { + seed = (crc ^ ~(u32)0); + (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); + crypto_digest_update(tfm, &sg[i], 1); + crypto_digest_final(tfm, (u8*)&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"); + seed = ~(u32)0; + (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); + crypto_digest_digest(tfm, sg, NUMVEC, (u8*)&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; @@ -566,7 +667,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); @@ -657,6 +759,10 @@ test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); break; + case 18: + test_crc32c(); + break; + #ifdef CONFIG_CRYPTO_HMAC case 100: test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] crypto/crc32c implementation, updated 040419 2004-04-19 21:31 ` [PATCH] crypto/crc32c implementation, updated 040419 Clay Haapala @ 2004-04-19 23:36 ` David S. Miller 2004-04-20 13:20 ` James Morris 0 siblings, 1 reply; 52+ messages in thread From: David S. Miller @ 2004-04-19 23:36 UTC (permalink / raw) To: Clay Haapala; +Cc: jmorris, linux-kernel On Mon, 19 Apr 2004 16:31:55 -0500 Clay Haapala <chaapala@cisco.com> wrote: > This patch agains 2.6.6-rc1-bk implements the CRC32C algorithm as a > type of digest. It is implemented as a wrapper for libcrc32c, > available in a separate patch. The crypto CRC32C module will be > used by the iscsi-sfnet driver. James, you got these two bits? ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCH] crypto/crc32c implementation, updated 040419 2004-04-19 23:36 ` David S. Miller @ 2004-04-20 13:20 ` James Morris 0 siblings, 0 replies; 52+ messages in thread From: James Morris @ 2004-04-20 13:20 UTC (permalink / raw) To: David S. Miller; +Cc: Clay Haapala, linux-kernel On Mon, 19 Apr 2004, David S. Miller wrote: > On Mon, 19 Apr 2004 16:31:55 -0500 > Clay Haapala <chaapala@cisco.com> wrote: > > > This patch agains 2.6.6-rc1-bk implements the CRC32C algorithm as a > > type of digest. It is implemented as a wrapper for libcrc32c, > > available in a separate patch. The crypto CRC32C module will be > > used by the iscsi-sfnet driver. > > James, you got these two bits? > Yep, they look ok to me. - James -- James Morris <jmorris@redhat.com> ^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCH] crypto/crc32c support 2004-03-21 15:08 ` James Morris 2004-03-22 16:49 ` [PATCH] lib/libcrc32c implementation Clay Haapala @ 2004-03-22 16:56 ` Clay Haapala 1 sibling, 0 replies; 52+ messages in thread From: Clay Haapala @ 2004-03-22 16:56 UTC (permalink / raw) To: James Morris; +Cc: Jouni Malinen, David S. Miller, linux-kernel This patch agains 2.6.4 kernel code implements the CRC32C checksum/crc algorithm as an additional type of digest. The implementation is a wrapper for routines found under lib/libcrc32c, available in another patch. This crypto patch requires the digest setkey() interface implemented by Jouni Malinen <jkmaline@cc.hut.fi>, and supercedes an earlier patch that implemented chksum as an additional CRYPTO_ALG_TYPE. The immediate customer of these routines is the linux-iscsi driver, currently in review. Please see the linux-iscsi project on SourceForge for details. -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD Of course the drugs advertised in all those emails are safe. Show me the dead spammers! (Please!) diff -urN linux-2.6.4.orig/crypto/crc32c.c linux/crypto/crc32c.c --- linux-2.6.4.orig/crypto/crc32c.c 1969-12-31 18:00:00.000000000 -0600 +++ linux/crypto/crc32c.c 2004-03-18 16:09:05.000000000 -0600 @@ -0,0 +1,110 @@ +/* + * Cryptographic API. + * + * CRC32C chksum + * + * This module 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 4 + +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 int chksum_setkey(void *ctx, const u8 *key, unsigned int keylen, + u32 *flags) +{ + struct chksum_ctx *mctx = ctx; + + if (keylen != sizeof(mctx->crc)) { + if (flags) + *flags = CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + mctx->crc = __cpu_to_le32(*(u32 *)key); + return 0; +} + +static void chksum_update(void *ctx, const u8 *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, u8 *out) +{ + struct chksum_ctx *mctx = ctx; + u32 mcrc = (mctx->crc ^ ~(u32)0); + + *(u32 *)out = __le32_to_cpu(mcrc); +} + +static struct crypto_alg alg = { + .cra_name = "crc32c", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .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 = { + .digest = { + .dia_digestsize= CHKSUM_DIGEST_SIZE, + .dia_setkey = chksum_setkey, + .dia_init = chksum_init, + .dia_update = chksum_update, + .dia_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"); diff -urN linux-2.6.4.orig/crypto/Kconfig linux/crypto/Kconfig --- linux-2.6.4.orig/crypto/Kconfig 2004-03-17 15:23:06.000000000 -0600 +++ linux/crypto/Kconfig 2004-03-18 15:24:57.000000000 -0600 @@ -170,6 +170,16 @@ should not be used for other purposes because of the weakness of the algorithm. +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/libcrc32c. + Module will be crc32c. + config CRYPTO_TEST tristate "Testing module" depends on CRYPTO diff -urN linux-2.6.4.orig/crypto/Makefile linux/crypto/Makefile --- linux-2.6.4.orig/crypto/Makefile 2004-03-17 15:23:06.000000000 -0600 +++ linux/crypto/Makefile 2004-03-18 15:44:54.000000000 -0600 @@ -24,5 +24,6 @@ obj-$(CONFIG_CRYPTO_ARC4) += arc4.o obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o +obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o diff -urN linux-2.6.4.orig/crypto/tcrypt.c linux/crypto/tcrypt.c --- linux-2.6.4.orig/crypto/tcrypt.c 2004-03-17 15:23:06.000000000 -0600 +++ linux/crypto/tcrypt.c 2004-03-18 16:36:41.000000000 -0600 @@ -61,7 +61,7 @@ static char *check[] = { "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", - "arc4", "michael_mic", "deflate", NULL + "arc4", "michael_mic", "deflate", "crc32c", NULL }; static void @@ -496,6 +496,107 @@ } 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 initialized to %08x: %s\n"; +#define SEEDTESTVAL 0xedcba987 + u32 seed; + + printk("\ntesting crc32c\n"); + + tfm = crypto_alloc_tfm("crc32c", 0); + if (tfm == NULL) { + printk("failed to load transform for crc32c\n"); + return; + } + + crypto_digest_init(tfm); + crypto_digest_final(tfm, (u8*)&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; + } + + seed = SEEDTESTVAL; + (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); + crypto_digest_final(tfm, (u8*)&crc); + printk("testing crc32c setkey 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++) { + seed = ~(u32)0; + (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); + crypto_digest_update(tfm, &sg[i], 1); + crypto_digest_final(tfm, (u8*)&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++) { + seed = (crc ^ ~(u32)0); + (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); + crypto_digest_update(tfm, &sg[i], 1); + crypto_digest_final(tfm, (u8*)&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"); + seed = ~(u32)0; + (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32)); + crypto_digest_digest(tfm, sg, NUMVEC, (u8*)&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; @@ -566,7 +667,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); @@ -657,6 +759,10 @@ test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); break; + case 18: + test_crc32c(); + break; + #ifdef CONFIG_CRYPTO_HMAC case 100: test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-11 4:06 ` James Morris 2004-03-11 6:08 ` Jouni Malinen @ 2004-03-11 6:11 ` Jouni Malinen 1 sibling, 0 replies; 52+ messages in thread From: Jouni Malinen @ 2004-03-11 6:11 UTC (permalink / raw) To: James Morris; +Cc: David S. Miller, linux-kernel This is the Michael MIC part of the previous combined patch. This requires the digest setkey patch from my previous email. Added Michael MIC keyed digest for TKIP (IEEE 802.11i/WPA). This algorithm is quite weak due to the requirements for compatibility with old legacy wireless LAN hardware that does not have much CPU power. Consequently, this should not really be used with anything else than TKIP. Michael MIC is calculated over the payload of the IEEE 802.11 header which makes it easier to add TKIP support for old wireless LAN cards. An additional authenticated data area is used (but not send separately) to authenticate source and destination addresses. diff -Nru a/Documentation/crypto/api-intro.txt b/Documentation/crypto/api-intro.txt --- a/Documentation/crypto/api-intro.txt Tue Mar 9 21:25:13 2004 +++ b/Documentation/crypto/api-intro.txt Tue Mar 9 21:25:13 2004 @@ -187,6 +187,7 @@ Brian Gladman (AES) Kartikey Mahendra Bhatt (CAST6) Jon Oberheide (ARC4) + Jouni Malinen (Michael MIC) SHA1 algorithm contributors: Jean-Francois Dive diff -Nru a/crypto/Kconfig b/crypto/Kconfig --- a/crypto/Kconfig Tue Mar 9 21:25:13 2004 +++ b/crypto/Kconfig Tue Mar 9 21:25:13 2004 @@ -161,6 +161,15 @@ You will most probably want this if using IPSec. +config CRYPTO_MICHAEL_MIC + tristate "Michael MIC keyed digest algorithm" + depends on CRYPTO + help + Michael MIC is used for message integrity protection in TKIP + (IEEE 802.11i). This algorithm is required for TKIP, but it + should not be used for other purposes because of the weakness + of the algorithm. + config CRYPTO_TEST tristate "Testing module" depends on CRYPTO diff -Nru a/crypto/Makefile b/crypto/Makefile --- a/crypto/Makefile Tue Mar 9 21:25:13 2004 +++ b/crypto/Makefile Tue Mar 9 21:25:13 2004 @@ -23,5 +23,6 @@ obj-$(CONFIG_CRYPTO_CAST6) += cast6.o obj-$(CONFIG_CRYPTO_ARC4) += arc4.o obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o +obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o diff -Nru a/crypto/michael_mic.c b/crypto/michael_mic.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/crypto/michael_mic.c Tue Mar 9 21:25:13 2004 @@ -0,0 +1,193 @@ +/* + * Cryptographic API + * + * Michael MIC (IEEE 802.11i/TKIP) keyed digest + * + * Copyright (c) 2004 Jouni Malinen <jkmaline@cc.hut.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/crypto.h> + + +struct michael_mic_ctx { + u8 pending[4]; + size_t pending_len; + + u32 l, r; +}; + + +static inline u32 rotl(u32 val, int bits) +{ + return (val << bits) | (val >> (32 - bits)); +} + + +static inline u32 rotr(u32 val, int bits) +{ + return (val >> bits) | (val << (32 - bits)); +} + + +static inline u32 xswap(u32 val) +{ + return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8); +} + + +#define michael_block(l, r) \ +do { \ + r ^= rotl(l, 17); \ + l += r; \ + r ^= xswap(l); \ + l += r; \ + r ^= rotl(l, 3); \ + l += r; \ + r ^= rotr(l, 2); \ + l += r; \ +} while (0) + + +static inline u32 get_le32(const u8 *p) +{ + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +} + + +static inline void put_le32(u8 *p, u32 v) +{ + p[0] = v; + p[1] = v >> 8; + p[2] = v >> 16; + p[3] = v >> 24; +} + + +static void michael_init(void *ctx) +{ + struct michael_mic_ctx *mctx = ctx; + mctx->pending_len = 0; +} + + +static void michael_update(void *ctx, const u8 *data, unsigned int len) +{ + struct michael_mic_ctx *mctx = ctx; + + if (mctx->pending_len) { + int flen = 4 - mctx->pending_len; + if (flen > len) + flen = len; + memcpy(&mctx->pending[mctx->pending_len], data, flen); + mctx->pending_len += flen; + data += flen; + len -= flen; + + if (mctx->pending_len < 4) + return; + + mctx->l ^= get_le32(mctx->pending); + michael_block(mctx->l, mctx->r); + mctx->pending_len = 0; + } + + while (len >= 4) { + mctx->l ^= get_le32(data); + michael_block(mctx->l, mctx->r); + data += 4; + len -= 4; + } + + if (len > 0) { + mctx->pending_len = len; + memcpy(mctx->pending, data, len); + } +} + + +static void michael_final(void *ctx, u8 *out) +{ + struct michael_mic_ctx *mctx = ctx; + u8 *data = mctx->pending; + + /* Last block and padding (0x5a, 4..7 x 0) */ + switch (mctx->pending_len) { + case 0: + mctx->l ^= 0x5a; + break; + case 1: + mctx->l ^= data[0] | 0x5a00; + break; + case 2: + mctx->l ^= data[0] | (data[1] << 8) | 0x5a0000; + break; + case 3: + mctx->l ^= data[0] | (data[1] << 8) | (data[2] << 16) | + 0x5a000000; + break; + } + michael_block(mctx->l, mctx->r); + /* l ^= 0; */ + michael_block(mctx->l, mctx->r); + + put_le32(out, mctx->l); + put_le32(out + 4, mctx->r); +} + + +static int michael_setkey(void *ctx, const u8 *key, unsigned int keylen, + u32 *flags) +{ + struct michael_mic_ctx *mctx = ctx; + if (keylen != 8) { + if (flags) + *flags = CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + mctx->l = get_le32(key); + mctx->r = get_le32(key + 4); + return 0; +} + + +static struct crypto_alg michael_mic_alg = { + .cra_name = "michael_mic", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .cra_blocksize = 8, + .cra_ctxsize = sizeof(struct michael_mic_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(michael_mic_alg.cra_list), + .cra_u = { .digest = { + .dia_digestsize = 8, + .dia_init = michael_init, + .dia_update = michael_update, + .dia_final = michael_final, + .dia_setkey = michael_setkey } } +}; + + +static int __init michael_mic_init(void) +{ + return crypto_register_alg(&michael_mic_alg); +} + + +static void __exit michael_mic_exit(void) +{ + crypto_unregister_alg(&michael_mic_alg); +} + + +module_init(michael_mic_init); +module_exit(michael_mic_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Michael MIC"); +MODULE_AUTHOR("Jouni Malinen <jkmaline@cc.hut.fi>"); diff -Nru a/crypto/tcrypt.c b/crypto/tcrypt.c --- a/crypto/tcrypt.c Tue Mar 9 21:25:13 2004 +++ b/crypto/tcrypt.c Tue Mar 9 21:25:13 2004 @@ -61,7 +61,7 @@ static char *check[] = { "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", - "arc4", "deflate", NULL + "arc4", "michael_mic", "deflate", NULL }; static void @@ -572,6 +576,8 @@ test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS); test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS); #endif + + test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); break; case 1: @@ -649,6 +655,10 @@ case 16: test_cipher ("arc4", MODE_ECB, ENCRYPT, arc4_enc_tv_template, ARC4_ENC_TEST_VECTORS); test_cipher ("arc4", MODE_ECB, DECRYPT, arc4_dec_tv_template, ARC4_DEC_TEST_VECTORS); + break; + + case 17: + test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS); break; #ifdef CONFIG_CRYPTO_HMAC diff -Nru a/crypto/tcrypt.h b/crypto/tcrypt.h --- a/crypto/tcrypt.h Tue Mar 9 21:25:13 2004 +++ b/crypto/tcrypt.h Tue Mar 9 21:25:13 2004 @@ -1721,4 +1723,54 @@ }, }; +/* + * Michael MIC test vectors from IEEE 802.11i + */ +#define MICHAEL_MIC_TEST_VECTORS 6 + +struct hash_testvec michael_mic_tv_template[] = +{ + { + .key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .ksize = 8, + .plaintext = { }, + .psize = 0, + .digest = { 0x82, 0x92, 0x5c, 0x1c, 0xa1, 0xd1, 0x30, 0xb8 } + }, + { + .key = { 0x82, 0x92, 0x5c, 0x1c, 0xa1, 0xd1, 0x30, 0xb8 }, + .ksize = 8, + .plaintext = { 'M' }, + .psize = 1, + .digest = { 0x43, 0x47, 0x21, 0xca, 0x40, 0x63, 0x9b, 0x3f } + }, + { + .key = { 0x43, 0x47, 0x21, 0xca, 0x40, 0x63, 0x9b, 0x3f }, + .ksize = 8, + .plaintext = { 'M', 'i' }, + .psize = 2, + .digest = { 0xe8, 0xf9, 0xbe, 0xca, 0xe9, 0x7e, 0x5d, 0x29 } + }, + { + .key = { 0xe8, 0xf9, 0xbe, 0xca, 0xe9, 0x7e, 0x5d, 0x29 }, + .ksize = 8, + .plaintext = { 'M', 'i', 'c' }, + .psize = 3, + .digest = { 0x90, 0x03, 0x8f, 0xc6, 0xcf, 0x13, 0xc1, 0xdb } + }, + { + .key = { 0x90, 0x03, 0x8f, 0xc6, 0xcf, 0x13, 0xc1, 0xdb }, + .ksize = 8, + .plaintext = { 'M', 'i', 'c', 'h' }, + .psize = 4, + .digest = { 0xd5, 0x5e, 0x10, 0x05, 0x10, 0x12, 0x89, 0x86 } + }, + { + .key = { 0xd5, 0x5e, 0x10, 0x05, 0x10, 0x12, 0x89, 0x86 }, + .ksize = 8, + .plaintext = { 'M', 'i', 'c', 'h', 'a', 'e', 'l' }, + .psize = 7, + .digest = { 0x0a, 0x94, 0x2b, 0x12, 0x4e, 0xca, 0xa5, 0x46 }, + } +}; #endif /* _CRYPTO_TCRYPT_H */ -- Jouni Malinen PGP id EFC895FA ^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: Crypto API and keyed non-HMAC digest algorithms / Michael MIC 2004-03-10 3:40 ` Jouni Malinen 2004-03-10 4:02 ` [PATCH] Crypto API and " Jouni Malinen 2004-03-10 4:21 ` Crypto API and keyed non-HMAC digest algorithms / " James Morris @ 2004-03-10 16:04 ` Clay Haapala 2 siblings, 0 replies; 52+ messages in thread From: Clay Haapala @ 2004-03-10 16:04 UTC (permalink / raw) To: Jouni Malinen; +Cc: James Morris, David S. Miller, linux-kernel On Tue, 9 Mar 2004, Jouni Malinen outgrape: >> On Tue, 9 Mar 2004, Clay Haapala wrote: >> > I had the same thought in my attempt at adding CRC32C to the >> > crypto routines, that what was needed was "digests + setkey". >> > But I didn't want to add the key baggage to digests, and so >> > created a new alg type (CHKSUM), with pretty much identical code >> > to digest, but with a modified init and a new setkey interface. > > On Tue, Mar 09, 2004 at 03:32:58PM -0500, James Morris wrote: >> I think that adding a setkey method for digests is the simplest >> approach. > > > I took a quick look at the CRC32C patch and it looked like the only > needed change for the digest type was the new handler for setting a > 32-bit seed. I used setkey handler that takes an arbitrary key data > and length (Michael MIC uses 64-bit key/seed). As far as I could > tell, this setkey function should be enough for CRC32C needs, > too. Clay, please let me know if I missed something here. James, > please consider merging this into Linux 2.6 tree if there are no > issues with CRC32C. > I believe that is all that CRC32C requires. I had hesitated to add the setkey/setseed method because I mentally had it tied to "init", which is not necessary, as your patch shows. I also didn't know what to do with the "&flags" parameter, but I gather that passing it in and not using it is fine. Should "unsigned int keylen" be also "const" or does that matter? > > +static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned > +int keylen) { u32 flags; if (tfm->__crt_alg->cra_digest.dia_setkey > +== NULL) return -1; return > +tfm->__crt_alg->cra_digest.dia_setkey(crypto_tfm_ctx(tfm), key, > +keylen, &flags); > +} > + -- Clay Haapala (chaapala@cisco.com) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD Windows XP 'Reloaded'? *Reloaded?* Have they no sense of irony? ^ permalink raw reply [flat|nested] 52+ messages in thread
end of thread, other threads:[~2004-04-28 20:26 UTC | newest] Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2004-03-06 18:46 Crypto API and keyed non-HMAC digest algorithms / Michael MIC Jouni Malinen 2004-03-08 14:45 ` James Morris 2004-03-09 3:37 ` Jouni Malinen 2004-03-09 5:55 ` James Morris 2004-03-09 17:30 ` Clay Haapala 2004-03-09 20:32 ` James Morris 2004-03-10 3:40 ` Jouni Malinen 2004-03-10 4:02 ` [PATCH] Crypto API and " Jouni Malinen 2004-03-10 4:21 ` Crypto API and keyed non-HMAC digest algorithms / " James Morris 2004-03-10 5:34 ` Jouni Malinen 2004-03-10 15:45 ` James Morris 2004-03-11 3:00 ` Jouni Malinen 2004-03-11 4:06 ` James Morris 2004-03-11 6:08 ` Jouni Malinen 2004-03-11 16:34 ` Clay Haapala 2004-03-11 20:14 ` James Morris 2004-03-18 23:05 ` Clay Haapala 2004-03-21 15:08 ` James Morris 2004-03-22 16:49 ` [PATCH] lib/libcrc32c implementation Clay Haapala 2004-03-22 17:00 ` Jeff Garzik 2004-03-22 17:27 ` Clay Haapala 2004-03-22 17:36 ` Jeff Garzik 2004-03-26 16:36 ` James Morris 2004-03-26 16:59 ` Clay Haapala 2004-03-26 18:16 ` James Morris 2004-03-30 17:32 ` [PATCH] lib/libcrc32c Clay Haapala 2004-03-30 18:43 ` Bartlomiej Zolnierkiewicz 2004-03-30 19:11 ` Clay Haapala 2004-03-30 19:23 ` Matt Domsch 2004-03-30 19:33 ` Clay Haapala 2004-03-31 21:03 ` [PATCH] lib/libcrc32c, revised 040331 Clay Haapala 2004-04-19 21:37 ` [PATCH] lib/libcrc32c, revised 040419 Clay Haapala 2004-04-23 23:42 ` David S. Miller 2004-04-27 19:46 ` [PATCH] lib/libcrc32c, revised 040427 Clay Haapala 2004-04-27 19:49 ` David S. Miller 2004-04-27 20:00 ` Clay Haapala 2004-04-27 21:49 ` Clay Haapala 2004-04-27 21:50 ` David S. Miller 2004-04-28 15:14 ` [PATCH] lib/libcrc32c, revised 040428, with compiler.h included Clay Haapala 2004-04-28 19:29 ` David S. Miller 2004-04-27 19:55 ` [PATCH] lib/crc32.c: to use compiler.h defines Clay Haapala 2004-04-28 15:19 ` [PATCH] lib/crc32.c: uses (and includes) compiler.h Clay Haapala 2004-04-28 19:30 ` David S. Miller 2004-03-30 19:49 ` [PATCH] lib/libcrc32c Bartlomiej Zolnierkiewicz 2004-03-31 15:28 ` Clay Haapala 2004-03-30 17:40 ` [PATCH] crypto/crc32c implementation Clay Haapala 2004-04-19 21:31 ` [PATCH] crypto/crc32c implementation, updated 040419 Clay Haapala 2004-04-19 23:36 ` David S. Miller 2004-04-20 13:20 ` James Morris 2004-03-22 16:56 ` [PATCH] crypto/crc32c support Clay Haapala 2004-03-11 6:11 ` Crypto API and keyed non-HMAC digest algorithms / Michael MIC Jouni Malinen 2004-03-10 16:04 ` Clay Haapala
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).