]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - crypto/crc32c.c
eCryptfs: Allocate a variable number of pages for file headers
[karo-tx-linux.git] / crypto / crc32c.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
44 #define CHKSUM_BLOCK_SIZE       1
45 #define CHKSUM_DIGEST_SIZE      4
46
47 struct chksum_ctx {
48         u32 key;
49 };
50
51 struct chksum_desc_ctx {
52         u32 crc;
53 };
54
55 /*
56  * This is the CRC-32C table
57  * Generated with:
58  * width = 32 bits
59  * poly = 0x1EDC6F41
60  * reflect input bytes = true
61  * reflect output bytes = true
62  */
63
64 static const u32 crc32c_table[256] = {
65         0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
66         0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
67         0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
68         0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
69         0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
70         0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
71         0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
72         0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
73         0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
74         0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
75         0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
76         0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
77         0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
78         0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
79         0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
80         0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
81         0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
82         0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
83         0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
84         0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
85         0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
86         0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
87         0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
88         0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
89         0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
90         0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
91         0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
92         0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
93         0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
94         0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
95         0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
96         0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
97         0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
98         0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
99         0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
100         0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
101         0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
102         0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
103         0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
104         0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
105         0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
106         0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
107         0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
108         0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
109         0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
110         0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
111         0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
112         0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
113         0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
114         0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
115         0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
116         0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
117         0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
118         0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
119         0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
120         0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
121         0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
122         0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
123         0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
124         0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
125         0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
126         0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
127         0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
128         0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
129 };
130
131 /*
132  * Steps through buffer one byte at at time, calculates reflected
133  * crc using table.
134  */
135
136 static u32 crc32c(u32 crc, const u8 *data, unsigned int length)
137 {
138         while (length--)
139                 crc = crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
140
141         return crc;
142 }
143
144 /*
145  * Steps through buffer one byte at at time, calculates reflected 
146  * crc using table.
147  */
148
149 static int chksum_init(struct shash_desc *desc)
150 {
151         struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
152         struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
153
154         ctx->crc = mctx->key;
155
156         return 0;
157 }
158
159 /*
160  * Setting the seed allows arbitrary accumulators and flexible XOR policy
161  * If your algorithm starts with ~0, then XOR with ~0 before you set
162  * the seed.
163  */
164 static int chksum_setkey(struct crypto_shash *tfm, const u8 *key,
165                          unsigned int keylen)
166 {
167         struct chksum_ctx *mctx = crypto_shash_ctx(tfm);
168
169         if (keylen != sizeof(mctx->key)) {
170                 crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
171                 return -EINVAL;
172         }
173         mctx->key = le32_to_cpu(*(__le32 *)key);
174         return 0;
175 }
176
177 static int chksum_update(struct shash_desc *desc, const u8 *data,
178                          unsigned int length)
179 {
180         struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
181
182         ctx->crc = crc32c(ctx->crc, data, length);
183         return 0;
184 }
185
186 static int chksum_final(struct shash_desc *desc, u8 *out)
187 {
188         struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
189
190         *(__le32 *)out = ~cpu_to_le32p(&ctx->crc);
191         return 0;
192 }
193
194 static int __chksum_finup(u32 *crcp, const u8 *data, unsigned int len, u8 *out)
195 {
196         *(__le32 *)out = ~cpu_to_le32(crc32c(*crcp, data, len));
197         return 0;
198 }
199
200 static int chksum_finup(struct shash_desc *desc, const u8 *data,
201                         unsigned int len, u8 *out)
202 {
203         struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
204
205         return __chksum_finup(&ctx->crc, data, len, out);
206 }
207
208 static int chksum_digest(struct shash_desc *desc, const u8 *data,
209                          unsigned int length, u8 *out)
210 {
211         struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
212
213         return __chksum_finup(&mctx->key, data, length, out);
214 }
215
216 static int crc32c_cra_init(struct crypto_tfm *tfm)
217 {
218         struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
219
220         mctx->key = ~0;
221         return 0;
222 }
223
224 static struct shash_alg alg = {
225         .digestsize             =       CHKSUM_DIGEST_SIZE,
226         .setkey                 =       chksum_setkey,
227         .init                   =       chksum_init,
228         .update                 =       chksum_update,
229         .final                  =       chksum_final,
230         .finup                  =       chksum_finup,
231         .digest                 =       chksum_digest,
232         .descsize               =       sizeof(struct chksum_desc_ctx),
233         .base                   =       {
234                 .cra_name               =       "crc32c",
235                 .cra_driver_name        =       "crc32c-generic",
236                 .cra_priority           =       100,
237                 .cra_blocksize          =       CHKSUM_BLOCK_SIZE,
238                 .cra_alignmask          =       3,
239                 .cra_ctxsize            =       sizeof(struct chksum_ctx),
240                 .cra_module             =       THIS_MODULE,
241                 .cra_init               =       crc32c_cra_init,
242         }
243 };
244
245 static int __init crc32c_mod_init(void)
246 {
247         return crypto_register_shash(&alg);
248 }
249
250 static void __exit crc32c_mod_fini(void)
251 {
252         crypto_unregister_shash(&alg);
253 }
254
255 module_init(crc32c_mod_init);
256 module_exit(crc32c_mod_fini);
257
258 MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
259 MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
260 MODULE_LICENSE("GPL");