]> bbs.cooldavid.org Git - net-next-2.6.git/blame - crypto/crc32c.c
Net: rxrpc: Makefile: Remove deprecated kbuild goal definitions
[net-next-2.6.git] / crypto / crc32c.c
CommitLineData
db83aabf 1/*
1da177e4
LT
2 * Cryptographic API.
3 *
4 * CRC32C chksum
5 *
69c35efc
HX
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.
1da177e4 20 *
69c35efc
HX
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.
5773a3e6
HX
29 * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
30 *
1da177e4
LT
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
db83aabf 33 * Software Foundation; either version 2 of the License, or (at your option)
1da177e4
LT
34 * any later version.
35 *
36 */
5773a3e6
HX
37
38#include <crypto/internal/hash.h>
1da177e4
LT
39#include <linux/init.h>
40#include <linux/module.h>
41#include <linux/string.h>
25cdbcd9 42#include <linux/kernel.h>
1da177e4 43
5773a3e6 44#define CHKSUM_BLOCK_SIZE 1
1da177e4
LT
45#define CHKSUM_DIGEST_SIZE 4
46
47struct chksum_ctx {
25cdbcd9 48 u32 key;
1da177e4
LT
49};
50
faccc4bb
HX
51struct chksum_desc_ctx {
52 u32 crc;
53};
54
69c35efc
HX
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
1da177e4 144/*
db83aabf 145 * Steps through buffer one byte at at time, calculates reflected
1da177e4
LT
146 * crc using table.
147 */
148
faccc4bb 149static int chksum_init(struct shash_desc *desc)
1da177e4 150{
faccc4bb
HX
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;
1da177e4 155
faccc4bb 156 return 0;
1da177e4
LT
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 */
faccc4bb 164static int chksum_setkey(struct crypto_shash *tfm, const u8 *key,
560c06ae 165 unsigned int keylen)
1da177e4 166{
faccc4bb 167 struct chksum_ctx *mctx = crypto_shash_ctx(tfm);
1da177e4 168
faccc4bb
HX
169 if (keylen != sizeof(mctx->key)) {
170 crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
1da177e4
LT
171 return -EINVAL;
172 }
25cdbcd9 173 mctx->key = le32_to_cpu(*(__le32 *)key);
1da177e4
LT
174 return 0;
175}
176
faccc4bb
HX
177static int chksum_update(struct shash_desc *desc, const u8 *data,
178 unsigned int length)
1da177e4 179{
faccc4bb 180 struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
1da177e4 181
faccc4bb 182 ctx->crc = crc32c(ctx->crc, data, length);
25cdbcd9 183 return 0;
1da177e4
LT
184}
185
faccc4bb 186static int chksum_final(struct shash_desc *desc, u8 *out)
5773a3e6 187{
faccc4bb 188 struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
5773a3e6 189
faccc4bb 190 *(__le32 *)out = ~cpu_to_le32p(&ctx->crc);
5773a3e6
HX
191 return 0;
192}
193
faccc4bb 194static int __chksum_finup(u32 *crcp, const u8 *data, unsigned int len, u8 *out)
5773a3e6 195{
faccc4bb 196 *(__le32 *)out = ~cpu_to_le32(crc32c(*crcp, data, len));
5773a3e6
HX
197 return 0;
198}
199
faccc4bb
HX
200static int chksum_finup(struct shash_desc *desc, const u8 *data,
201 unsigned int len, u8 *out)
5773a3e6 202{
faccc4bb 203 struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
5773a3e6 204
faccc4bb 205 return __chksum_finup(&ctx->crc, data, len, out);
5773a3e6
HX
206}
207
faccc4bb
HX
208static int chksum_digest(struct shash_desc *desc, const u8 *data,
209 unsigned int length, u8 *out)
5773a3e6 210{
faccc4bb 211 struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
5773a3e6 212
faccc4bb 213 return __chksum_finup(&mctx->key, data, length, out);
5773a3e6
HX
214}
215
216static int crc32c_cra_init(struct crypto_tfm *tfm)
217{
faccc4bb 218 struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
5773a3e6 219
faccc4bb 220 mctx->key = ~0;
5773a3e6
HX
221 return 0;
222}
223
faccc4bb
HX
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,
5773a3e6
HX
242 }
243};
244
3af5b90b 245static int __init crc32c_mod_init(void)
1da177e4 246{
faccc4bb 247 return crypto_register_shash(&alg);
1da177e4
LT
248}
249
3af5b90b 250static void __exit crc32c_mod_fini(void)
1da177e4 251{
faccc4bb 252 crypto_unregister_shash(&alg);
1da177e4
LT
253}
254
3af5b90b
KB
255module_init(crc32c_mod_init);
256module_exit(crc32c_mod_fini);
1da177e4
LT
257
258MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
259MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
260MODULE_LICENSE("GPL");