Blame view

crypto/crc32c_generic.c 4.37 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

7bcfb1363   Eric Biggers   crypto: crc32c-ge...
38
  #include <asm/unaligned.h>
5773a3e6e   Herbert Xu   crypto: crc32c - ...
39
  #include <crypto/internal/hash.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
41
42
  #include <linux/init.h>
  #include <linux/module.h>
  #include <linux/string.h>
25cdbcd9e   Herbert Xu   [CRYPTO] crc32c: ...
43
  #include <linux/kernel.h>
6a0962b22   Darrick J. Wong   crypto: crc32c sh...
44
  #include <linux/crc32.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45

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

faccc4bba   Herbert Xu   crypto: crc32c - ...
66
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
68
69
70
71
72
73
  }
  
  /*
   * 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 - ...
74
  static int chksum_setkey(struct crypto_shash *tfm, const u8 *key,
560c06ae1   Herbert Xu   [CRYPTO] api: Get...
75
  			 unsigned int keylen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
77
  	struct chksum_ctx *mctx = crypto_shash_ctx(tfm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
78

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

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

7bcfb1363   Eric Biggers   crypto: crc32c-ge...
98
  	put_unaligned_le32(~ctx->crc, out);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
99
100
  	return 0;
  }
faccc4bba   Herbert Xu   crypto: crc32c - ...
101
  static int __chksum_finup(u32 *crcp, const u8 *data, unsigned int len, u8 *out)
5773a3e6e   Herbert Xu   crypto: crc32c - ...
102
  {
7bcfb1363   Eric Biggers   crypto: crc32c-ge...
103
  	put_unaligned_le32(~__crc32c_le(*crcp, data, len), out);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
104
105
  	return 0;
  }
faccc4bba   Herbert Xu   crypto: crc32c - ...
106
107
  static int chksum_finup(struct shash_desc *desc, const u8 *data,
  			unsigned int len, u8 *out)
5773a3e6e   Herbert Xu   crypto: crc32c - ...
108
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
109
  	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
110

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

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

faccc4bba   Herbert Xu   crypto: crc32c - ...
125
  	mctx->key = ~0;
5773a3e6e   Herbert Xu   crypto: crc32c - ...
126
127
  	return 0;
  }
faccc4bba   Herbert Xu   crypto: crc32c - ...
128
129
130
  static struct shash_alg alg = {
  	.digestsize		=	CHKSUM_DIGEST_SIZE,
  	.setkey			=	chksum_setkey,
fae366401   Mati Vait   crypto: crc32c - ...
131
132
133
134
135
  	.init		=	chksum_init,
  	.update		=	chksum_update,
  	.final		=	chksum_final,
  	.finup		=	chksum_finup,
  	.digest		=	chksum_digest,
faccc4bba   Herbert Xu   crypto: crc32c - ...
136
137
138
139
140
  	.descsize		=	sizeof(struct chksum_desc_ctx),
  	.base			=	{
  		.cra_name		=	"crc32c",
  		.cra_driver_name	=	"crc32c-generic",
  		.cra_priority		=	100,
a208fa8f3   Eric Biggers   crypto: hash - an...
141
  		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
faccc4bba   Herbert Xu   crypto: crc32c - ...
142
  		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
faccc4bba   Herbert Xu   crypto: crc32c - ...
143
144
145
  		.cra_ctxsize		=	sizeof(struct chksum_ctx),
  		.cra_module		=	THIS_MODULE,
  		.cra_init		=	crc32c_cra_init,
5773a3e6e   Herbert Xu   crypto: crc32c - ...
146
147
  	}
  };
3af5b90bd   Kamalesh Babulal   [CRYPTO] all: Cle...
148
  static int __init crc32c_mod_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
150
  	return crypto_register_shash(&alg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
  }
3af5b90bd   Kamalesh Babulal   [CRYPTO] all: Cle...
152
  static void __exit crc32c_mod_fini(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
153
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
154
  	crypto_unregister_shash(&alg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155
  }
3af5b90bd   Kamalesh Babulal   [CRYPTO] all: Cle...
156
157
  module_init(crc32c_mod_init);
  module_exit(crc32c_mod_fini);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
159
160
161
  
  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...
162
  MODULE_ALIAS_CRYPTO("crc32c");
3e14dcf7c   Mathias Krause   crypto: add missi...
163
  MODULE_ALIAS_CRYPTO("crc32c-generic");