diff options
author | Jeff Garzik <jeff@garzik.org> | 2016-06-17 01:00:35 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2016-06-20 07:25:01 -0400 |
commit | 53964b9ee63b7075931b8df85307c449da564b50 (patch) | |
tree | 5650ca6328973c090a3bf2ea8fdcf8ae58837061 | |
parent | 6999d504d4be3ddacd7a01ae961886a66b6a53d9 (diff) |
crypto: sha3 - Add SHA-3 hash algorithm
This patch adds the implementation of SHA3 algorithm
in software and it's based on original implementation
pushed in patch https://lwn.net/Articles/518415/ with
additional changes to match the padding rules specified
in SHA-3 specification.
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: Raveendra Padasalagi <raveendra.padasalagi@broadcom.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | crypto/Kconfig | 10 | ||||
-rw-r--r-- | crypto/Makefile | 1 | ||||
-rw-r--r-- | crypto/sha3_generic.c | 300 | ||||
-rw-r--r-- | include/crypto/sha3.h | 29 |
4 files changed, 340 insertions, 0 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig index c903f1832f2c..6881d1a5f859 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig | |||
@@ -750,6 +750,16 @@ config CRYPTO_SHA512_SPARC64 | |||
750 | SHA-512 secure hash standard (DFIPS 180-2) implemented | 750 | SHA-512 secure hash standard (DFIPS 180-2) implemented |
751 | using sparc64 crypto instructions, when available. | 751 | using sparc64 crypto instructions, when available. |
752 | 752 | ||
753 | config CRYPTO_SHA3 | ||
754 | tristate "SHA3 digest algorithm" | ||
755 | select CRYPTO_HASH | ||
756 | help | ||
757 | SHA-3 secure hash standard (DFIPS 202). It's based on | ||
758 | cryptographic sponge function family called Keccak. | ||
759 | |||
760 | References: | ||
761 | http://keccak.noekeon.org/ | ||
762 | |||
753 | config CRYPTO_TGR192 | 763 | config CRYPTO_TGR192 |
754 | tristate "Tiger digest algorithms" | 764 | tristate "Tiger digest algorithms" |
755 | select CRYPTO_HASH | 765 | select CRYPTO_HASH |
diff --git a/crypto/Makefile b/crypto/Makefile index 4f4ef7eaae3f..0b82c4753743 100644 --- a/crypto/Makefile +++ b/crypto/Makefile | |||
@@ -61,6 +61,7 @@ obj-$(CONFIG_CRYPTO_RMD320) += rmd320.o | |||
61 | obj-$(CONFIG_CRYPTO_SHA1) += sha1_generic.o | 61 | obj-$(CONFIG_CRYPTO_SHA1) += sha1_generic.o |
62 | obj-$(CONFIG_CRYPTO_SHA256) += sha256_generic.o | 62 | obj-$(CONFIG_CRYPTO_SHA256) += sha256_generic.o |
63 | obj-$(CONFIG_CRYPTO_SHA512) += sha512_generic.o | 63 | obj-$(CONFIG_CRYPTO_SHA512) += sha512_generic.o |
64 | obj-$(CONFIG_CRYPTO_SHA3) += sha3_generic.o | ||
64 | obj-$(CONFIG_CRYPTO_WP512) += wp512.o | 65 | obj-$(CONFIG_CRYPTO_WP512) += wp512.o |
65 | obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o | 66 | obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o |
66 | obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o | 67 | obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o |
diff --git a/crypto/sha3_generic.c b/crypto/sha3_generic.c new file mode 100644 index 000000000000..62264397a2d2 --- /dev/null +++ b/crypto/sha3_generic.c | |||
@@ -0,0 +1,300 @@ | |||
1 | /* | ||
2 | * Cryptographic API. | ||
3 | * | ||
4 | * SHA-3, as specified in | ||
5 | * http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf | ||
6 | * | ||
7 | * SHA-3 code by Jeff Garzik <jeff@garzik.org> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the Free | ||
11 | * Software Foundation; either version 2 of the License, or (at your option)• | ||
12 | * any later version. | ||
13 | * | ||
14 | */ | ||
15 | #include <crypto/internal/hash.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/types.h> | ||
19 | #include <crypto/sha3.h> | ||
20 | #include <asm/byteorder.h> | ||
21 | |||
22 | #define KECCAK_ROUNDS 24 | ||
23 | |||
24 | #define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) | ||
25 | |||
26 | static const u64 keccakf_rndc[24] = { | ||
27 | 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, | ||
28 | 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, | ||
29 | 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, | ||
30 | 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, | ||
31 | 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, | ||
32 | 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, | ||
33 | 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, | ||
34 | 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 | ||
35 | }; | ||
36 | |||
37 | static const int keccakf_rotc[24] = { | ||
38 | 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, | ||
39 | 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 | ||
40 | }; | ||
41 | |||
42 | static const int keccakf_piln[24] = { | ||
43 | 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, | ||
44 | 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 | ||
45 | }; | ||
46 | |||
47 | /* update the state with given number of rounds */ | ||
48 | |||
49 | static void keccakf(u64 st[25]) | ||
50 | { | ||
51 | int i, j, round; | ||
52 | u64 t, bc[5]; | ||
53 | |||
54 | for (round = 0; round < KECCAK_ROUNDS; round++) { | ||
55 | |||
56 | /* Theta */ | ||
57 | for (i = 0; i < 5; i++) | ||
58 | bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] | ||
59 | ^ st[i + 20]; | ||
60 | |||
61 | for (i = 0; i < 5; i++) { | ||
62 | t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); | ||
63 | for (j = 0; j < 25; j += 5) | ||
64 | st[j + i] ^= t; | ||
65 | } | ||
66 | |||
67 | /* Rho Pi */ | ||
68 | t = st[1]; | ||
69 | for (i = 0; i < 24; i++) { | ||
70 | j = keccakf_piln[i]; | ||
71 | bc[0] = st[j]; | ||
72 | st[j] = ROTL64(t, keccakf_rotc[i]); | ||
73 | t = bc[0]; | ||
74 | } | ||
75 | |||
76 | /* Chi */ | ||
77 | for (j = 0; j < 25; j += 5) { | ||
78 | for (i = 0; i < 5; i++) | ||
79 | bc[i] = st[j + i]; | ||
80 | for (i = 0; i < 5; i++) | ||
81 | st[j + i] ^= (~bc[(i + 1) % 5]) & | ||
82 | bc[(i + 2) % 5]; | ||
83 | } | ||
84 | |||
85 | /* Iota */ | ||
86 | st[0] ^= keccakf_rndc[round]; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | static void sha3_init(struct sha3_state *sctx, unsigned int digest_sz) | ||
91 | { | ||
92 | memset(sctx, 0, sizeof(*sctx)); | ||
93 | sctx->md_len = digest_sz; | ||
94 | sctx->rsiz = 200 - 2 * digest_sz; | ||
95 | sctx->rsizw = sctx->rsiz / 8; | ||
96 | } | ||
97 | |||
98 | static int sha3_224_init(struct shash_desc *desc) | ||
99 | { | ||
100 | struct sha3_state *sctx = shash_desc_ctx(desc); | ||
101 | |||
102 | sha3_init(sctx, SHA3_224_DIGEST_SIZE); | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static int sha3_256_init(struct shash_desc *desc) | ||
107 | { | ||
108 | struct sha3_state *sctx = shash_desc_ctx(desc); | ||
109 | |||
110 | sha3_init(sctx, SHA3_256_DIGEST_SIZE); | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int sha3_384_init(struct shash_desc *desc) | ||
115 | { | ||
116 | struct sha3_state *sctx = shash_desc_ctx(desc); | ||
117 | |||
118 | sha3_init(sctx, SHA3_384_DIGEST_SIZE); | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | static int sha3_512_init(struct shash_desc *desc) | ||
123 | { | ||
124 | struct sha3_state *sctx = shash_desc_ctx(desc); | ||
125 | |||
126 | sha3_init(sctx, SHA3_512_DIGEST_SIZE); | ||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static int sha3_update(struct shash_desc *desc, const u8 *data, | ||
131 | unsigned int len) | ||
132 | { | ||
133 | struct sha3_state *sctx = shash_desc_ctx(desc); | ||
134 | unsigned int done; | ||
135 | const u8 *src; | ||
136 | |||
137 | done = 0; | ||
138 | src = data; | ||
139 | |||
140 | if ((sctx->partial + len) > (sctx->rsiz - 1)) { | ||
141 | if (sctx->partial) { | ||
142 | done = -sctx->partial; | ||
143 | memcpy(sctx->buf + sctx->partial, data, | ||
144 | done + sctx->rsiz); | ||
145 | src = sctx->buf; | ||
146 | } | ||
147 | |||
148 | do { | ||
149 | unsigned int i; | ||
150 | |||
151 | for (i = 0; i < sctx->rsizw; i++) | ||
152 | sctx->st[i] ^= ((u64 *) src)[i]; | ||
153 | keccakf(sctx->st); | ||
154 | |||
155 | done += sctx->rsiz; | ||
156 | src = data + done; | ||
157 | } while (done + (sctx->rsiz - 1) < len); | ||
158 | |||
159 | sctx->partial = 0; | ||
160 | } | ||
161 | memcpy(sctx->buf + sctx->partial, src, len - done); | ||
162 | sctx->partial += (len - done); | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | static int sha3_final(struct shash_desc *desc, u8 *out) | ||
168 | { | ||
169 | struct sha3_state *sctx = shash_desc_ctx(desc); | ||
170 | unsigned int i, inlen = sctx->partial; | ||
171 | |||
172 | sctx->buf[inlen++] = 0x06; | ||
173 | memset(sctx->buf + inlen, 0, sctx->rsiz - inlen); | ||
174 | sctx->buf[sctx->rsiz - 1] |= 0x80; | ||
175 | |||
176 | for (i = 0; i < sctx->rsizw; i++) | ||
177 | sctx->st[i] ^= ((u64 *) sctx->buf)[i]; | ||
178 | |||
179 | keccakf(sctx->st); | ||
180 | |||
181 | for (i = 0; i < sctx->rsizw; i++) | ||
182 | sctx->st[i] = cpu_to_le64(sctx->st[i]); | ||
183 | |||
184 | memcpy(out, sctx->st, sctx->md_len); | ||
185 | |||
186 | memset(sctx, 0, sizeof(*sctx)); | ||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | static struct shash_alg sha3_224 = { | ||
191 | .digestsize = SHA3_224_DIGEST_SIZE, | ||
192 | .init = sha3_224_init, | ||
193 | .update = sha3_update, | ||
194 | .final = sha3_final, | ||
195 | .descsize = sizeof(struct sha3_state), | ||
196 | .base = { | ||
197 | .cra_name = "sha3-224", | ||
198 | .cra_driver_name = "sha3-224-generic", | ||
199 | .cra_flags = CRYPTO_ALG_TYPE_SHASH, | ||
200 | .cra_blocksize = SHA3_224_BLOCK_SIZE, | ||
201 | .cra_module = THIS_MODULE, | ||
202 | } | ||
203 | }; | ||
204 | |||
205 | static struct shash_alg sha3_256 = { | ||
206 | .digestsize = SHA3_256_DIGEST_SIZE, | ||
207 | .init = sha3_256_init, | ||
208 | .update = sha3_update, | ||
209 | .final = sha3_final, | ||
210 | .descsize = sizeof(struct sha3_state), | ||
211 | .base = { | ||
212 | .cra_name = "sha3-256", | ||
213 | .cra_driver_name = "sha3-256-generic", | ||
214 | .cra_flags = CRYPTO_ALG_TYPE_SHASH, | ||
215 | .cra_blocksize = SHA3_256_BLOCK_SIZE, | ||
216 | .cra_module = THIS_MODULE, | ||
217 | } | ||
218 | }; | ||
219 | |||
220 | static struct shash_alg sha3_384 = { | ||
221 | .digestsize = SHA3_384_DIGEST_SIZE, | ||
222 | .init = sha3_384_init, | ||
223 | .update = sha3_update, | ||
224 | .final = sha3_final, | ||
225 | .descsize = sizeof(struct sha3_state), | ||
226 | .base = { | ||
227 | .cra_name = "sha3-384", | ||
228 | .cra_driver_name = "sha3-384-generic", | ||
229 | .cra_flags = CRYPTO_ALG_TYPE_SHASH, | ||
230 | .cra_blocksize = SHA3_384_BLOCK_SIZE, | ||
231 | .cra_module = THIS_MODULE, | ||
232 | } | ||
233 | }; | ||
234 | |||
235 | static struct shash_alg sha3_512 = { | ||
236 | .digestsize = SHA3_512_DIGEST_SIZE, | ||
237 | .init = sha3_512_init, | ||
238 | .update = sha3_update, | ||
239 | .final = sha3_final, | ||
240 | .descsize = sizeof(struct sha3_state), | ||
241 | .base = { | ||
242 | .cra_name = "sha3-512", | ||
243 | .cra_driver_name = "sha3-512-generic", | ||
244 | .cra_flags = CRYPTO_ALG_TYPE_SHASH, | ||
245 | .cra_blocksize = SHA3_512_BLOCK_SIZE, | ||
246 | .cra_module = THIS_MODULE, | ||
247 | } | ||
248 | }; | ||
249 | |||
250 | static int __init sha3_generic_mod_init(void) | ||
251 | { | ||
252 | int ret; | ||
253 | |||
254 | ret = crypto_register_shash(&sha3_224); | ||
255 | if (ret < 0) | ||
256 | goto err_out; | ||
257 | ret = crypto_register_shash(&sha3_256); | ||
258 | if (ret < 0) | ||
259 | goto err_out_224; | ||
260 | ret = crypto_register_shash(&sha3_384); | ||
261 | if (ret < 0) | ||
262 | goto err_out_256; | ||
263 | ret = crypto_register_shash(&sha3_512); | ||
264 | if (ret < 0) | ||
265 | goto err_out_384; | ||
266 | |||
267 | return 0; | ||
268 | |||
269 | err_out_384: | ||
270 | crypto_unregister_shash(&sha3_384); | ||
271 | err_out_256: | ||
272 | crypto_unregister_shash(&sha3_256); | ||
273 | err_out_224: | ||
274 | crypto_unregister_shash(&sha3_224); | ||
275 | err_out: | ||
276 | return ret; | ||
277 | } | ||
278 | |||
279 | static void __exit sha3_generic_mod_fini(void) | ||
280 | { | ||
281 | crypto_unregister_shash(&sha3_224); | ||
282 | crypto_unregister_shash(&sha3_256); | ||
283 | crypto_unregister_shash(&sha3_384); | ||
284 | crypto_unregister_shash(&sha3_512); | ||
285 | } | ||
286 | |||
287 | module_init(sha3_generic_mod_init); | ||
288 | module_exit(sha3_generic_mod_fini); | ||
289 | |||
290 | MODULE_LICENSE("GPL"); | ||
291 | MODULE_DESCRIPTION("SHA-3 Secure Hash Algorithm"); | ||
292 | |||
293 | MODULE_ALIAS_CRYPTO("sha3-224"); | ||
294 | MODULE_ALIAS_CRYPTO("sha3-224-generic"); | ||
295 | MODULE_ALIAS_CRYPTO("sha3-256"); | ||
296 | MODULE_ALIAS_CRYPTO("sha3-256-generic"); | ||
297 | MODULE_ALIAS_CRYPTO("sha3-384"); | ||
298 | MODULE_ALIAS_CRYPTO("sha3-384-generic"); | ||
299 | MODULE_ALIAS_CRYPTO("sha3-512"); | ||
300 | MODULE_ALIAS_CRYPTO("sha3-512-generic"); | ||
diff --git a/include/crypto/sha3.h b/include/crypto/sha3.h new file mode 100644 index 000000000000..f4c9f68f5ffe --- /dev/null +++ b/include/crypto/sha3.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Common values for SHA-3 algorithms | ||
3 | */ | ||
4 | #ifndef __CRYPTO_SHA3_H__ | ||
5 | #define __CRYPTO_SHA3_H__ | ||
6 | |||
7 | #define SHA3_224_DIGEST_SIZE (224 / 8) | ||
8 | #define SHA3_224_BLOCK_SIZE (200 - 2 * SHA3_224_DIGEST_SIZE) | ||
9 | |||
10 | #define SHA3_256_DIGEST_SIZE (256 / 8) | ||
11 | #define SHA3_256_BLOCK_SIZE (200 - 2 * SHA3_256_DIGEST_SIZE) | ||
12 | |||
13 | #define SHA3_384_DIGEST_SIZE (384 / 8) | ||
14 | #define SHA3_384_BLOCK_SIZE (200 - 2 * SHA3_384_DIGEST_SIZE) | ||
15 | |||
16 | #define SHA3_512_DIGEST_SIZE (512 / 8) | ||
17 | #define SHA3_512_BLOCK_SIZE (200 - 2 * SHA3_512_DIGEST_SIZE) | ||
18 | |||
19 | struct sha3_state { | ||
20 | u64 st[25]; | ||
21 | unsigned int md_len; | ||
22 | unsigned int rsiz; | ||
23 | unsigned int rsizw; | ||
24 | |||
25 | unsigned int partial; | ||
26 | u8 buf[SHA3_224_BLOCK_SIZE]; | ||
27 | }; | ||
28 | |||
29 | #endif | ||