Version:  2.0.40 2.2.26 2.4.37 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10

Linux/crypto/crc32c_generic.c

  1 /*
  2  * Cryptographic API.
  3  *
  4  * CRC32C chksum
  5  *
  6  *@Article{castagnoli-crc,
  7  * author =       { Guy Castagnoli and Stefan Braeuer and Martin Herrman},
  8  * title =        {{Optimization of Cyclic Redundancy-Check Codes with 24
  9  *                 and 32 Parity Bits}},
 10  * journal =      IEEE Transactions on Communication,
 11  * year =         {1993},
 12  * volume =       {41},
 13  * number =       {6},
 14  * pages =        {},
 15  * month =        {June},
 16  *}
 17  * Used by the iSCSI driver, possibly others, and derived from the
 18  * the iscsi-crc.c module of the linux-iscsi driver at
 19  * http://linux-iscsi.sourceforge.net.
 20  *
 21  * Following the example of lib/crc32, this function is intended to be
 22  * flexible and useful for all users.  Modules that currently have their
 23  * own crc32c, but hopefully may be able to use this one are:
 24  *  net/sctp (please add all your doco to here if you change to
 25  *            use this one!)
 26  *  <endoflist>
 27  *
 28  * Copyright (c) 2004 Cisco Systems, Inc.
 29  * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
 30  *
 31  * This program is free software; you can redistribute it and/or modify it
 32  * under the terms of the GNU General Public License as published by the Free
 33  * Software Foundation; either version 2 of the License, or (at your option)
 34  * any later version.
 35  *
 36  */
 37 
 38 #include <crypto/internal/hash.h>
 39 #include <linux/init.h>
 40 #include <linux/module.h>
 41 #include <linux/string.h>
 42 #include <linux/kernel.h>
 43 #include <linux/crc32.h>
 44 
 45 #define CHKSUM_BLOCK_SIZE       1
 46 #define CHKSUM_DIGEST_SIZE      4
 47 
 48 struct chksum_ctx {
 49         u32 key;
 50 };
 51 
 52 struct chksum_desc_ctx {
 53         u32 crc;
 54 };
 55 
 56 /*
 57  * Steps through buffer one byte at at time, calculates reflected
 58  * crc using table.
 59  */
 60 
 61 static int chksum_init(struct shash_desc *desc)
 62 {
 63         struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
 64         struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
 65 
 66         ctx->crc = mctx->key;
 67 
 68         return 0;
 69 }
 70 
 71 /*
 72  * Setting the seed allows arbitrary accumulators and flexible XOR policy
 73  * If your algorithm starts with ~0, then XOR with ~0 before you set
 74  * the seed.
 75  */
 76 static int chksum_setkey(struct crypto_shash *tfm, const u8 *key,
 77                          unsigned int keylen)
 78 {
 79         struct chksum_ctx *mctx = crypto_shash_ctx(tfm);
 80 
 81         if (keylen != sizeof(mctx->key)) {
 82                 crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
 83                 return -EINVAL;
 84         }
 85         mctx->key = le32_to_cpu(*(__le32 *)key);
 86         return 0;
 87 }
 88 
 89 static int chksum_update(struct shash_desc *desc, const u8 *data,
 90                          unsigned int length)
 91 {
 92         struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
 93 
 94         ctx->crc = __crc32c_le(ctx->crc, data, length);
 95         return 0;
 96 }
 97 
 98 static int chksum_final(struct shash_desc *desc, u8 *out)
 99 {
100         struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
101 
102         *(__le32 *)out = ~cpu_to_le32p(&ctx->crc);
103         return 0;
104 }
105 
106 static int __chksum_finup(u32 *crcp, const u8 *data, unsigned int len, u8 *out)
107 {
108         *(__le32 *)out = ~cpu_to_le32(__crc32c_le(*crcp, data, len));
109         return 0;
110 }
111 
112 static int chksum_finup(struct shash_desc *desc, const u8 *data,
113                         unsigned int len, u8 *out)
114 {
115         struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
116 
117         return __chksum_finup(&ctx->crc, data, len, out);
118 }
119 
120 static int chksum_digest(struct shash_desc *desc, const u8 *data,
121                          unsigned int length, u8 *out)
122 {
123         struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
124 
125         return __chksum_finup(&mctx->key, data, length, out);
126 }
127 
128 static int crc32c_cra_init(struct crypto_tfm *tfm)
129 {
130         struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
131 
132         mctx->key = ~0;
133         return 0;
134 }
135 
136 static struct shash_alg alg = {
137         .digestsize             =       CHKSUM_DIGEST_SIZE,
138         .setkey                 =       chksum_setkey,
139         .init           =       chksum_init,
140         .update         =       chksum_update,
141         .final          =       chksum_final,
142         .finup          =       chksum_finup,
143         .digest         =       chksum_digest,
144         .descsize               =       sizeof(struct chksum_desc_ctx),
145         .base                   =       {
146                 .cra_name               =       "crc32c",
147                 .cra_driver_name        =       "crc32c-generic",
148                 .cra_priority           =       100,
149                 .cra_blocksize          =       CHKSUM_BLOCK_SIZE,
150                 .cra_alignmask          =       3,
151                 .cra_ctxsize            =       sizeof(struct chksum_ctx),
152                 .cra_module             =       THIS_MODULE,
153                 .cra_init               =       crc32c_cra_init,
154         }
155 };
156 
157 static int __init crc32c_mod_init(void)
158 {
159         return crypto_register_shash(&alg);
160 }
161 
162 static void __exit crc32c_mod_fini(void)
163 {
164         crypto_unregister_shash(&alg);
165 }
166 
167 module_init(crc32c_mod_init);
168 module_exit(crc32c_mod_fini);
169 
170 MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
171 MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
172 MODULE_LICENSE("GPL");
173 MODULE_ALIAS_CRYPTO("crc32c");
174 MODULE_ALIAS_CRYPTO("crc32c-generic");
175 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us