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