Crypto API and keyed non-HMAC digest algorithms / Michael MIC
Subsystems (2)
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.
Documentation/crypto/api-intro.txt +1 -0
@@ -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
crypto/Kconfig +9 -0
@@ -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
crypto/Makefile +1 -0
@@ -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
crypto/digest.c +10 -0
@@ -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); }
crypto/tcrypt.c +10 -0
@@ -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 );
crypto/tcrypt.h +52 -0
62 lines not on this page · raw message
include/linux/crypto.h +13 -0
@@ -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) {
crypto/michael_mic.c +193 -0
193 lines not on this page · raw message
Signature · 1 line
Jouni Malinen PGP id EFC895FA
Quoted 6 lines · Jouni Malinen
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.
Quoted 7 lines
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.
Quoted 5 lines
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
Signature · 2 lines
James Morris <[email protected]>
Quoted 8 lines · James Morris
Quoted 6 lines · Jouni Malinen
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.
Quoted 5 lines
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. Thekmac_update()andkmac_final()methods are just wrappers around the digest methods, and we alsokmac_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.
Quoted 3 lines
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
Quoted 1 line
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.
Signature · 1 line
Jouni Malinen PGP id EFC895FA
Quoted 4 lines · Jouni Malinen
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.
Quoted 5 lines
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?
Quoted 10 lines
If you prefer, I can make a new type crypto alg type (
CRYPTO_ALG_TYPE_KEYED_DIGEST) and make it a clone of theCRYPTO_ALG_TYPE_DIGESTwith the only change of adding a new callback, setkey, in the way I added in the patch forCRYPTO_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 thedia_setkeyfunction 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 structcrypto_algdue to thecra_uunion already being a bit larger than the current structdigest_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.
Quoted 3 lines
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
Signature · 2 lines
James Morris <[email protected]>
On Tue, 9 Mar 2004, James Morris uttered the following:
Quoted 13 lines · Jouni Malinen
Quoted 11 lines
If you prefer, I can make a new type crypto alg type (
CRYPTO_ALG_TYPE_KEYED_DIGEST) and make it a clone of theCRYPTO_ALG_TYPE_DIGESTwith the only change of adding a new callback, setkey, in the way I added in the patch forCRYPTO_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 thedia_setkeyfunction 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 structcrypto_algdue to thecra_uunion already being a bit larger than the current structdigest_alg.
Quoted 3 lines
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?
Signature · 3 lines
Clay Haapala ([email protected]) 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?
Quoted 10 lines · Clay Haapala
On Tue, 9 Mar 2004, James Morris uttered the following:
Quoted 3 lines
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.
Quoted 3 lines
So, we could modify digests now, or perhaps Jouni and I could combine our code into a new
KEYED_DIGESTtype and leave digests 'pure'. What's best?
I think that adding a setkey method for digests is the simplest approach.
- James
Signature · 2 lines
James Morris <[email protected]>
Quoted 6 lines · Clay Haapala
Quoted 5 lines
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.
Quoted 1 line · James Morris
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.
===================================================================
[email protected], 2004-03-09 18:54:50-08:00, [email protected]
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(+)
crypto/digest.c +10 -0
@@ -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); }
crypto/tcrypt.c +4 -0
@@ -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);
crypto/tcrypt.h +2 -0
@@ -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 {
include/linux/crypto.h +13 -0
@@ -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
Signature · 1 line
Jouni Malinen PGP id EFC895FA
PATCH 1/1 Crypto API and Michael MIC
Quoted 5 lines · Jouni Malinen
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.
===================================================================
[email protected], 2004-03-09 19:17:59-08:00, [email protected]
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(-)
Documentation/crypto/api-intro.txt +1 -0
@@ -187,6 +187,7 @@ Brian Gladman (AES) Kartikey Mahendra Bhatt (CAST6) Jon Oberheide (ARC4) + Jouni Malinen (Michael MIC) SHA1 algorithm contributors: Jean-Francois Dive
crypto/Kconfig +9 -0
@@ -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
crypto/Makefile +1 -0
@@ -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
crypto/michael_mic.c new file +193 -0
193 lines not on this page · raw message
crypto/tcrypt.c +7 -1
@@ -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
crypto/tcrypt.h +50 -0
54 lines not on this page · raw message
===================================================================
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 !
Signature · 1 line
Jouni Malinen PGP id EFC895FA
crypto/digest.c line 49
Quoted 5 lines · Jouni Malinen
crypto/digest.c +5
-0+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
Signature · 2 lines
James Morris <[email protected]>
Quoted 2 lines · James Morris
In both patches, these 'return -1' statements should be
-EINVAL, or whatever is appropriate (probably-ENOSYSfor 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.
===================================================================
[email protected], 2004-03-09 21:12:44-08:00, [email protected]
Fixed the error return value for Michael MIC.
[email protected], 2004-03-09 21:08:17-08:00, [email protected]
Fixed error codes in return values of the digest setkey handler.
[email protected], 2004-03-09 19:17:59-08:00, [email protected]
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.
[email protected], 2004-03-09 18:54:50-08:00, [email protected]
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(-)
Documentation/crypto/api-intro.txt +1 -0
@@ -187,6 +187,7 @@ Brian Gladman (AES) Kartikey Mahendra Bhatt (CAST6) Jon Oberheide (ARC4) + Jouni Malinen (Michael MIC) SHA1 algorithm contributors: Jean-Francois Dive
crypto/Kconfig +9 -0
@@ -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
crypto/Makefile +1 -0
@@ -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
crypto/digest.c +10 -0
@@ -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); }
crypto/michael_mic.c new file +193 -0
193 lines not on this page · raw message
crypto/tcrypt.c +11 -1
@@ -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
crypto/tcrypt.h +52 -0
62 lines not on this page · raw message
include/linux/crypto.h +13 -0
@@ -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^ [email protected]]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:[email protected]+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
Signature · 1 line
Jouni Malinen PGP id EFC895FA
Quoted 8 lines · Jouni Malinen
Quoted 2 lines · James Morris
In both patches, these 'return -1' statements should be
-EINVAL, or whatever is appropriate (probably-ENOSYSfor 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
Signature · 2 lines
James Morris <[email protected]>
Quoted 8 lines · James Morris
Quoted 3 lines · Jouni Malinen
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.
Signature · 1 line
Jouni Malinen PGP id EFC895FA
Quoted 9 lines · Jouni Malinen
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
Signature · 2 lines
James Morris <[email protected]>
Quoted 4 lines · James Morris
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).
crypto/digest.c +10 -0
@@ -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); }
crypto/tcrypt.c +4 -0
@@ -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);
crypto/tcrypt.h +2 -0
@@ -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 {
include/linux/crypto.h +13 -0
@@ -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,
Signature · 1 line
Jouni Malinen PGP id EFC895FA
On Wed, 10 Mar 2004, Jouni Malinen outgrape:
Quoted 16 lines · James Morris
Quoted 5 lines
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.
Quoted 7 lines
Added support for using keyed digest with an optional
dit_setkeyhandler. 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?
Signature · 3 lines
Clay Haapala ([email protected]) 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?
Quoted 2 lines · Clay Haapala
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.
Quoted 3 lines
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
Signature · 2 lines
James Morris <[email protected]>
On Thu, 11 Mar 2004, James Morris outgrape:
Quoted 7 lines · Clay Haapala
Quoted 3 lines
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.
Quoted 8 lines
Quoted 3 lines
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,
Signature · 545 lines
Clay Haapala ([email protected]) 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 <[email protected]>"); +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 <[email protected]>"); +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/
Quoted 11 lines · Clay Haapala
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 newCRYPTO_ALGtype.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
Signature · 2 lines
James Morris <[email protected]>
PATCH 1/1 lib/libcrc32c implementation
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.
Signature · 260 lines
Clay Haapala ([email protected]) 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 <[email protected]>"); +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/
Re: [PATCH] lib/libcrc32c implementation
Quoted 6 lines · Clay Haapala
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
Re: [PATCH] lib/libcrc32c implementation
On Mon, 22 Mar 2004, Jeff Garzik spake thusly:
Quoted 8 lines
Quoted 5 lines · Clay Haapala
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.
Quoted 5 lines
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. :-)
Signature · 5 lines
Clay Haapala ([email protected]) 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!)
Re: [PATCH] lib/libcrc32c implementation
Quoted 11 lines · Clay Haapala
On Mon, 22 Mar 2004, Jeff Garzik spake thusly:
Quoted 9 lines
Quoted 5 lines · Clay Haapala
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.
Quoted 8 lines
Quoted 5 lines
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
Re: [PATCH] lib/libcrc32c implementation
In reply to Clay HaapalaQuoted 3 lines · Clay Haapala
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
Signature · 2 lines
James Morris <[email protected]>
Re: [PATCH] lib/libcrc32c implementation
On Fri, 26 Mar 2004, James Morris verbalised:
Quoted 11 lines · Clay Haapala
Quoted 4 lines
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!
Signature · 3 lines
Clay Haapala ([email protected]) Cisco Systems SRBU +1 763-398-1056 6450 Wedgwood Rd, Suite 130 Maple Grove MN 55311 PGP: C89240AD "Microsoft bans gnus on these premises."
Re: [PATCH] lib/libcrc32c implementation
Quoted 2 lines · Clay Haapala
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
Signature · 2 lines
James Morris <[email protected]>
PATCH 1/1 lib/libcrc32c
In reply to James MorrisOn Fri, 26 Mar 2004, James Morris outgrape:
Quoted 7 lines
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).
Signature · 259 lines
Clay Haapala ([email protected]) 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 <[email protected]>"); +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/
Re: [PATCH] lib/libcrc32c
Hi,
Quoted 9 lines · Clay Haapala
On Fri, 26 Mar 2004, James Morris outgrape:
Quoted 7 lines
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
Quoted 8 lines
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
Re: [PATCH] lib/libcrc32c
On Tue, 30 Mar 2004, Bartlomiej Zolnierkiewicz outgrape:
Quoted 9 lines
(quoted diff) +2
-0+ +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?
Quoted 11 lines
(quoted diff) +10
-0+/*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
Quoted 5 lines
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.
Signature · 4 lines
Clay Haapala ([email protected]) 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"
Re: [PATCH] lib/libcrc32c
Quoted 2 lines · Clay Haapala
Quoted 2 lines
+#if
CRC_BE_BITS== 1
u32 attribute((pure)) crc32_be(u32 crc,
Shouldn't this be crc32c_bc() instead?
Signature · 4 lines
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
Re: [PATCH] lib/libcrc32c
On Tue, 30 Mar 2004, Matt Domsch told this:
Quoted 5 lines · Clay Haapala
Quoted 2 lines
Quoted 2 lines
+#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.
Signature · 4 lines
Clay Haapala ([email protected]) 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"
PATCH 1/1 lib/libcrc32c, revised 040331
In reply to Matt DomschOn Tue, 30 Mar 2004, Matt Domsch verbalised:
Quoted 5 lines · Clay Haapala
Quoted 2 lines
Quoted 2 lines
+#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.
Signature · 255 lines
Clay Haapala ([email protected]) 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 <[email protected]>"); +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/
PATCH 1/1 lib/libcrc32c, revised 040419
On Wed, 31 Mar 2004, Clay Haapala spake thusly:
Quoted 10 lines
On Tue, 30 Mar 2004, Matt Domsch verbalised:
Quoted 5 lines · Clay Haapala
Quoted 2 lines
Quoted 2 lines
+#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.
Signature · 260 lines
Clay Haapala ([email protected]) 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 <[email protected]>"); +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 */
Re: [PATCH] lib/libcrc32c, revised 040419
Review
Quoted 5 lines · On Mon, 19 Apr 2004 16:37:01 -0500 Clay Haapala <[email protected]> wrote:
(quoted diff) +5
-0+#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.
PATCH 1/1 lib/libcrc32c, revised 040427
On Fri, 23 Apr 2004, David S. Miller outgrape:
Quoted 12 lines
Review
Quoted 3 lines · On Mon, 19 Apr 2004 16:37:01 -0500 Clay Haapala <[email protected]> wrote:
(quoted diff) +3
-0+#if __GNUC__ >= 3 /* 2.x has "attribute", but only 3.0 has "pure +*/ #define attribute(x) __attribute__(x) #else #define +attribute(x) #endifI was about to apply your two patches, but then I noticed this thing. WHatever you may need this for exists in
linux/compiler.hand if it doesn't you should add the necessary macro interfaces there.
Quoted 1 line
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!
Signature · 253 lines
Clay Haapala ([email protected]) 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 <[email protected]>"); +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 */
Re: [PATCH] lib/libcrc32c, revised 040427
Quoted 4 lines · On Tue, 27 Apr 2004 14:46:35 -0500 Clay Haapala <[email protected]> wrote:
Attribute(pure) was used, so I changed the patch to use the define in
compiler.h, as you suggest. I will also changecrc32.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.
Re: [PATCH] lib/libcrc32c, revised 040427
On Tue, 27 Apr 2004, David S. Miller spake thusly:
Quoted 9 lines
Quoted 5 lines · On Tue, 27 Apr 2004 14:46:35 -0500 Clay Haapala <[email protected]> wrote:
Attribute(pure) was used, so I changed the patch to use the define in
compiler.h, as you suggest. I will also changecrc32.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.
Quoted 6 lines
Please include
linux/compiler.hif 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, socompiler.h must be included by something else. Do you wish an explicit include of compiler.h anyways? If so, no problem, let me know.
Signature · 4 lines
Clay Haapala ([email protected]) 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."
Re: [PATCH] lib/libcrc32c, revised 040427
On Tue, 27 Apr 2004, Clay Haapala stated:
Quoted 15 lines
On Tue, 27 Apr 2004, David S. Miller spake thusly:
Quoted 14 lines
Quoted 5 lines · On Tue, 27 Apr 2004 14:46:35 -0500 Clay Haapala <[email protected]> wrote:
Attribute(pure) was used, so I changed the patch to use the define in
compiler.h, as you suggest. I will also changecrc32.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.hif 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.
Quoted 7 lines
Quoted 1 line
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.hmust be included by something else. Do you wish an explicit include ofcompiler.hanyways? 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?
Signature · 4 lines
Clay Haapala ([email protected]) 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."
Re: [PATCH] lib/libcrc32c, revised 040427
Quoted 1 line · On Tue, 27 Apr 2004 16:49:53 -0500 Clay Haapala <[email protected]> wrote:
Is it accepted form to add the include line even so?
Yes, it only works today because those other headers include it.
PATCH 1/1 lib/libcrc32c, revised 040428, with compiler.h included
On Tue, 27 Apr 2004, David S. Miller stated:
Quoted 6 lines
Quoted 1 line · On Tue, 27 Apr 2004 16:49:53 -0500 Clay Haapala <[email protected]> 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.
Signature · 254 lines
Clay Haapala ([email protected]) 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 <[email protected]>"); +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 */
Re: [PATCH] lib/libcrc32c, revised 040428, with compiler.h included
Quoted 9 lines · On Wed, 28 Apr 2004 10:14:32 -0500 Clay Haapala <[email protected]> wrote:
On Tue, 27 Apr 2004, David S. Miller stated:
Quoted 6 lines
Quoted 1 line · On Tue, 27 Apr 2004 16:49:53 -0500 Clay Haapala <[email protected]> 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.hincluded.
Looks great, patch applied.
Thanks.
PATCH 1/1 lib/crc32.c: to use compiler.h defines
In reply to David S. MillerOn Fri, 23 Apr 2004, David S. Miller told this:
Quoted 12 lines
Review
Quoted 3 lines · On Mon, 19 Apr 2004 16:37:01 -0500 Clay Haapala <[email protected]> wrote:
(quoted diff) +3
-0+#if __GNUC__ >= 3 /* 2.x has "attribute", but only 3.0 has "pure +*/ #define attribute(x) __attribute__(x) #else #define +attribute(x) #endifI was about to apply your two patches, but then I noticed this thing. WHatever you may need this for exists in
linux/compiler.hand if it doesn't you should add the necessary macro interfaces there.
Quoted 1 line
Thanks.
Below is a patch to lib/crc32.c to use the compiler.h define for attribute((pure)).
Signature · 50 lines
Clay Haapala ([email protected]) 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 <[email protected]>"); 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 -
PATCH 1/1 lib/crc32.c: uses (and includes) compiler.h
Here is the crc32.c patch to remove attribute((pure)), with compiler.h included.
Signature · 65 lines
Clay Haapala ([email protected]) 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 <[email protected]>"); 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;
David S. Miller
AppliedRe: [PATCH] lib/crc32.c: uses (and includes) compiler.h
Quoted 2 lines · On Wed, 28 Apr 2004 10:19:02 -0500 Clay Haapala <[email protected]> wrote:
Here is the
crc32.cpatch to remove attribute((pure)), withcompiler.hincluded.
Applied, thanks!
Re: [PATCH] lib/libcrc32c
In reply to Clay HaapalaQuoted 8 lines · Clay Haapala
On Tue, 30 Mar 2004, Bartlomiej Zolnierkiewicz outgrape:
Quoted 7 lines
(quoted diff) +2
-0+ +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.
Quoted 5 lines
Quoted 1 line
[ 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
Re: [PATCH] lib/libcrc32c
On Tue, 30 Mar 2004, Bartlomiej Zolnierkiewicz told this:
Quoted 24 lines · Clay Haapala
Quoted 8 lines
On Tue, 30 Mar 2004, Bartlomiej Zolnierkiewicz outgrape:
Quoted 7 lines
(quoted diff) +2
-0+ +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.Quoted 5 lines
Quoted 1 line
[ 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.handlib/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# defineCRC_LE_BITS8 #endif #ifndefCRC_BE_BITS# defineCRC_BE_BITS8 #endif
Quoted 9 lines
lib/gen_crc32table.c:#define
LE_TABLE_SIZE(1 <<CRC_LE_BITS)
#defineBE_TABLE_SIZE(1 <<CRC_BE_BITS)static
u_int32_tcrc32table_le[LE_TABLE_SIZE];
staticu_int32_tcrc32table_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. :-)
Signature · 4 lines
Clay Haapala ([email protected]) 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"
PATCH 1/1 crypto/crc32c implementation
In reply to James MorrisThis 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.
Signature · 290 lines
Clay Haapala ([email protected]) 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 <[email protected]>"); +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);
PATCH 1/1 crypto/crc32c implementation, updated 040419
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.
Signature · 291 lines
Clay Haapala ([email protected]) 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 <[email protected]>"); +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);
Re: [PATCH] crypto/crc32c implementation, updated 040419
Quoted 4 lines · On Mon, 19 Apr 2004 16:31:55 -0500 Clay Haapala <[email protected]> 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?
Re: [PATCH] crypto/crc32c implementation, updated 040419
Quoted 10 lines · David S. Miller
Quoted 4 lines · On Mon, 19 Apr 2004 16:31:55 -0500 Clay Haapala <[email protected]> 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
Signature · 2 lines
James Morris <[email protected]>
PATCH 1/1 crypto/crc32c support
In reply to James MorrisThis 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 <[email protected]>, 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.
Signature · 291 lines
Clay Haapala ([email protected]) 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 <[email protected]>"); +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);
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.
Documentation/crypto/api-intro.txt +1 -0
@@ -187,6 +187,7 @@ Brian Gladman (AES) Kartikey Mahendra Bhatt (CAST6) Jon Oberheide (ARC4) + Jouni Malinen (Michael MIC) SHA1 algorithm contributors: Jean-Francois Dive
crypto/Kconfig +9 -0
@@ -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
crypto/Makefile +1 -0
@@ -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
crypto/michael_mic.c new file +193 -0
193 lines not on this page · raw message
crypto/tcrypt.c +7 -1
@@ -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
crypto/tcrypt.h +50 -0
54 lines not on this page · raw message
Signature · 1 line
Jouni Malinen PGP id EFC895FA
On Tue, 9 Mar 2004, Jouni Malinen outgrape:
Quoted 12 lines
Quoted 6 lines · Clay Haapala
Quoted 5 lines
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.
Quoted 2 lines · James Morris
I think that adding a setkey method for digests is the simplest approach.
Quoted 9 lines
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?
Quoted 8 lines
(quoted diff) +7
-0+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); +} +
Signature · 3 lines
Clay Haapala ([email protected]) 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?