Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
crc32c.c
Go to the documentation of this file.
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 <[email protected]>
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 {
50 };
51 
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 {
165 }
166 
167 module_init(crc32c_mod_init);
168 module_exit(crc32c_mod_fini);
169 
170 MODULE_AUTHOR("Clay Haapala <[email protected]>");
171 MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
172 MODULE_LICENSE("GPL");