Blame view

crypto/crc32c_generic.c 4.34 KB
db83aabfe   Richard Hartmann   crypto: crc32 - F...
1
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
   * Cryptographic API.
   *
   * CRC32C chksum
   *
69c35efcf   Herbert Xu   libcrc32c: Move i...
6
7
8
9
10
11
12
13
14
15
16
17
18
19
   *@Article{castagnoli-crc,
   * author =       { Guy Castagnoli and Stefan Braeuer and Martin Herrman},
   * title =        {{Optimization of Cyclic Redundancy-Check Codes with 24
   *                 and 32 Parity Bits}},
   * journal =      IEEE Transactions on Communication,
   * year =         {1993},
   * volume =       {41},
   * number =       {6},
   * pages =        {},
   * month =        {June},
   *}
   * Used by the iSCSI driver, possibly others, and derived from the
   * the iscsi-crc.c module of the linux-iscsi driver at
   * http://linux-iscsi.sourceforge.net.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
   *
69c35efcf   Herbert Xu   libcrc32c: Move i...
21
22
23
24
25
26
27
28
   * Following the example of lib/crc32, this function is intended to be
   * flexible and useful for all users.  Modules that currently have their
   * own crc32c, but hopefully may be able to use this one are:
   *  net/sctp (please add all your doco to here if you change to
   *            use this one!)
   *  <endoflist>
   *
   * Copyright (c) 2004 Cisco Systems, Inc.
5773a3e6e   Herbert Xu   crypto: crc32c - ...
29
30
   * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License as published by the Free
db83aabfe   Richard Hartmann   crypto: crc32 - F...
33
   * Software Foundation; either version 2 of the License, or (at your option)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
36
   * any later version.
   *
   */
5773a3e6e   Herbert Xu   crypto: crc32c - ...
37
38
  
  #include <crypto/internal/hash.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
40
41
  #include <linux/init.h>
  #include <linux/module.h>
  #include <linux/string.h>
25cdbcd9e   Herbert Xu   [CRYPTO] crc32c: ...
42
  #include <linux/kernel.h>
6a0962b22   Darrick J. Wong   crypto: crc32c sh...
43
  #include <linux/crc32.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44

5773a3e6e   Herbert Xu   crypto: crc32c - ...
45
  #define CHKSUM_BLOCK_SIZE	1
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
47
48
  #define CHKSUM_DIGEST_SIZE	4
  
  struct chksum_ctx {
25cdbcd9e   Herbert Xu   [CRYPTO] crc32c: ...
49
  	u32 key;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
  };
faccc4bba   Herbert Xu   crypto: crc32c - ...
51
52
53
  struct chksum_desc_ctx {
  	u32 crc;
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
  /*
db83aabfe   Richard Hartmann   crypto: crc32 - F...
55
   * Steps through buffer one byte at at time, calculates reflected
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
57
   * crc using table.
   */
faccc4bba   Herbert Xu   crypto: crc32c - ...
58
  static int chksum_init(struct shash_desc *desc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
60
61
62
63
  	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
  	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
  
  	ctx->crc = mctx->key;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64

faccc4bba   Herbert Xu   crypto: crc32c - ...
65
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
67
68
69
70
71
72
  }
  
  /*
   * Setting the seed allows arbitrary accumulators and flexible XOR policy
   * If your algorithm starts with ~0, then XOR with ~0 before you set
   * the seed.
   */
faccc4bba   Herbert Xu   crypto: crc32c - ...
73
  static int chksum_setkey(struct crypto_shash *tfm, const u8 *key,
560c06ae1   Herbert Xu   [CRYPTO] api: Get...
74
  			 unsigned int keylen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
76
  	struct chksum_ctx *mctx = crypto_shash_ctx(tfm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77

faccc4bba   Herbert Xu   crypto: crc32c - ...
78
79
  	if (keylen != sizeof(mctx->key)) {
  		crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
81
  		return -EINVAL;
  	}
25cdbcd9e   Herbert Xu   [CRYPTO] crc32c: ...
82
  	mctx->key = le32_to_cpu(*(__le32 *)key);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83
84
  	return 0;
  }
faccc4bba   Herbert Xu   crypto: crc32c - ...
85
86
  static int chksum_update(struct shash_desc *desc, const u8 *data,
  			 unsigned int length)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
88
  	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89

6a0962b22   Darrick J. Wong   crypto: crc32c sh...
90
  	ctx->crc = __crc32c_le(ctx->crc, data, length);
25cdbcd9e   Herbert Xu   [CRYPTO] crc32c: ...
91
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
  }
faccc4bba   Herbert Xu   crypto: crc32c - ...
93
  static int chksum_final(struct shash_desc *desc, u8 *out)
5773a3e6e   Herbert Xu   crypto: crc32c - ...
94
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
95
  	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
96

faccc4bba   Herbert Xu   crypto: crc32c - ...
97
  	*(__le32 *)out = ~cpu_to_le32p(&ctx->crc);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
98
99
  	return 0;
  }
faccc4bba   Herbert Xu   crypto: crc32c - ...
100
  static int __chksum_finup(u32 *crcp, const u8 *data, unsigned int len, u8 *out)
5773a3e6e   Herbert Xu   crypto: crc32c - ...
101
  {
6a0962b22   Darrick J. Wong   crypto: crc32c sh...
102
  	*(__le32 *)out = ~cpu_to_le32(__crc32c_le(*crcp, data, len));
5773a3e6e   Herbert Xu   crypto: crc32c - ...
103
104
  	return 0;
  }
faccc4bba   Herbert Xu   crypto: crc32c - ...
105
106
  static int chksum_finup(struct shash_desc *desc, const u8 *data,
  			unsigned int len, u8 *out)
5773a3e6e   Herbert Xu   crypto: crc32c - ...
107
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
108
  	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
109

faccc4bba   Herbert Xu   crypto: crc32c - ...
110
  	return __chksum_finup(&ctx->crc, data, len, out);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
111
  }
faccc4bba   Herbert Xu   crypto: crc32c - ...
112
113
  static int chksum_digest(struct shash_desc *desc, const u8 *data,
  			 unsigned int length, u8 *out)
5773a3e6e   Herbert Xu   crypto: crc32c - ...
114
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
115
  	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
116

faccc4bba   Herbert Xu   crypto: crc32c - ...
117
  	return __chksum_finup(&mctx->key, data, length, out);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
118
119
120
121
  }
  
  static int crc32c_cra_init(struct crypto_tfm *tfm)
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
122
  	struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
123

faccc4bba   Herbert Xu   crypto: crc32c - ...
124
  	mctx->key = ~0;
5773a3e6e   Herbert Xu   crypto: crc32c - ...
125
126
  	return 0;
  }
faccc4bba   Herbert Xu   crypto: crc32c - ...
127
128
129
  static struct shash_alg alg = {
  	.digestsize		=	CHKSUM_DIGEST_SIZE,
  	.setkey			=	chksum_setkey,
fae366401   Mati Vait   crypto: crc32c - ...
130
131
132
133
134
  	.init		=	chksum_init,
  	.update		=	chksum_update,
  	.final		=	chksum_final,
  	.finup		=	chksum_finup,
  	.digest		=	chksum_digest,
faccc4bba   Herbert Xu   crypto: crc32c - ...
135
136
137
138
139
140
141
142
143
144
  	.descsize		=	sizeof(struct chksum_desc_ctx),
  	.base			=	{
  		.cra_name		=	"crc32c",
  		.cra_driver_name	=	"crc32c-generic",
  		.cra_priority		=	100,
  		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
  		.cra_alignmask		=	3,
  		.cra_ctxsize		=	sizeof(struct chksum_ctx),
  		.cra_module		=	THIS_MODULE,
  		.cra_init		=	crc32c_cra_init,
5773a3e6e   Herbert Xu   crypto: crc32c - ...
145
146
  	}
  };
3af5b90bd   Kamalesh Babulal   [CRYPTO] all: Cle...
147
  static int __init crc32c_mod_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
149
  	return crypto_register_shash(&alg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
150
  }
3af5b90bd   Kamalesh Babulal   [CRYPTO] all: Cle...
151
  static void __exit crc32c_mod_fini(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
153
  	crypto_unregister_shash(&alg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
  }
3af5b90bd   Kamalesh Babulal   [CRYPTO] all: Cle...
155
156
  module_init(crc32c_mod_init);
  module_exit(crc32c_mod_fini);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
158
159
160
  
  MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
  MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
  MODULE_LICENSE("GPL");
5d26a105b   Kees Cook   crypto: prefix mo...
161
  MODULE_ALIAS_CRYPTO("crc32c");
3e14dcf7c   Mathias Krause   crypto: add missi...
162
  MODULE_ALIAS_CRYPTO("crc32c-generic");