Root/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
47struct chksum_ctx {
48    u32 key;
49};
50
51struct 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
64static 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
136static 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
149static 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 */
164static 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
177static 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
186static 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
194static 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
200static 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
208static 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
216static 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
224static 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
245static int __init crc32c_mod_init(void)
246{
247    return crypto_register_shash(&alg);
248}
249
250static void __exit crc32c_mod_fini(void)
251{
252    crypto_unregister_shash(&alg);
253}
254
255module_init(crc32c_mod_init);
256module_exit(crc32c_mod_fini);
257
258MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
259MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
260MODULE_LICENSE("GPL");
261

Archive Download this file



interactive