Blame view

crypto/crc32c_generic.c 4.1 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
db83aabfe   Richard Hartmann   crypto: crc32 - F...
2
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3
4
5
6
   * Cryptographic API.
   *
   * CRC32C chksum
   *
69c35efcf   Herbert Xu   libcrc32c: Move i...
7
8
9
10
11
12
13
14
15
16
17
   *@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},
   *}
743b91507   Randy Dunlap   crypto: crc32c_ge...
18
   * Used by the iSCSI driver, possibly others, and derived from
69c35efcf   Herbert Xu   libcrc32c: Move i...
19
20
   * the iscsi-crc.c module of the linux-iscsi driver at
   * http://linux-iscsi.sourceforge.net.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
   *
69c35efcf   Herbert Xu   libcrc32c: Move i...
22
23
24
25
26
27
28
29
   * 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 - ...
30
   * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
   */
5773a3e6e   Herbert Xu   crypto: crc32c - ...
32

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

5773a3e6e   Herbert Xu   crypto: crc32c - ...
41
  #define CHKSUM_BLOCK_SIZE	1
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42
43
44
  #define CHKSUM_DIGEST_SIZE	4
  
  struct chksum_ctx {
25cdbcd9e   Herbert Xu   [CRYPTO] crc32c: ...
45
  	u32 key;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  };
faccc4bba   Herbert Xu   crypto: crc32c - ...
47
48
49
  struct chksum_desc_ctx {
  	u32 crc;
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
  /*
743b91507   Randy Dunlap   crypto: crc32c_ge...
51
   * Steps through buffer one byte at a time, calculates reflected
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52
53
   * crc using table.
   */
faccc4bba   Herbert Xu   crypto: crc32c - ...
54
  static int chksum_init(struct shash_desc *desc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
56
57
58
59
  	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
60

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

674f368a9   Eric Biggers   crypto: remove CR...
74
  	if (keylen != sizeof(mctx->key))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
  		return -EINVAL;
7bcfb1363   Eric Biggers   crypto: crc32c-ge...
76
  	mctx->key = get_unaligned_le32(key);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
  	return 0;
  }
faccc4bba   Herbert Xu   crypto: crc32c - ...
79
80
  static int chksum_update(struct shash_desc *desc, const u8 *data,
  			 unsigned int length)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
82
  	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83

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

7bcfb1363   Eric Biggers   crypto: crc32c-ge...
91
  	put_unaligned_le32(~ctx->crc, out);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
92
93
  	return 0;
  }
faccc4bba   Herbert Xu   crypto: crc32c - ...
94
  static int __chksum_finup(u32 *crcp, const u8 *data, unsigned int len, u8 *out)
5773a3e6e   Herbert Xu   crypto: crc32c - ...
95
  {
7bcfb1363   Eric Biggers   crypto: crc32c-ge...
96
  	put_unaligned_le32(~__crc32c_le(*crcp, data, len), out);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
97
98
  	return 0;
  }
faccc4bba   Herbert Xu   crypto: crc32c - ...
99
100
  static int chksum_finup(struct shash_desc *desc, const u8 *data,
  			unsigned int len, u8 *out)
5773a3e6e   Herbert Xu   crypto: crc32c - ...
101
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
102
  	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
103

faccc4bba   Herbert Xu   crypto: crc32c - ...
104
  	return __chksum_finup(&ctx->crc, data, len, out);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
105
  }
faccc4bba   Herbert Xu   crypto: crc32c - ...
106
107
  static int chksum_digest(struct shash_desc *desc, const u8 *data,
  			 unsigned int length, u8 *out)
5773a3e6e   Herbert Xu   crypto: crc32c - ...
108
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
109
  	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
110

faccc4bba   Herbert Xu   crypto: crc32c - ...
111
  	return __chksum_finup(&mctx->key, data, length, out);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
112
113
114
115
  }
  
  static int crc32c_cra_init(struct crypto_tfm *tfm)
  {
faccc4bba   Herbert Xu   crypto: crc32c - ...
116
  	struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
5773a3e6e   Herbert Xu   crypto: crc32c - ...
117

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