blob: a68be626017c2b7eb9785e02b6806f8ed665f7ae [file] [log] [blame]
Jeff Garzik53964b92016-06-17 10:30:35 +05301/*
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>
Ard Biesheuvel1ce8e522018-01-19 12:04:33 +000021#include <asm/unaligned.h>
Jeff Garzik53964b92016-06-17 10:30:35 +053022
23#define KECCAK_ROUNDS 24
24
25#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y))))
26
27static const u64 keccakf_rndc[24] = {
Geert Uytterhoevenf743e702016-08-03 19:37:03 +020028 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL,
29 0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL,
30 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL,
31 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL,
32 0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL,
33 0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL,
34 0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL,
35 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL
Jeff Garzik53964b92016-06-17 10:30:35 +053036};
37
38static const int keccakf_rotc[24] = {
39 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
40 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44
41};
42
43static const int keccakf_piln[24] = {
44 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
45 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1
46};
47
48/* update the state with given number of rounds */
49
50static void keccakf(u64 st[25])
51{
52 int i, j, round;
53 u64 t, bc[5];
54
55 for (round = 0; round < KECCAK_ROUNDS; round++) {
56
57 /* Theta */
58 for (i = 0; i < 5; i++)
59 bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15]
60 ^ st[i + 20];
61
62 for (i = 0; i < 5; i++) {
63 t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1);
64 for (j = 0; j < 25; j += 5)
65 st[j + i] ^= t;
66 }
67
68 /* Rho Pi */
69 t = st[1];
70 for (i = 0; i < 24; i++) {
71 j = keccakf_piln[i];
72 bc[0] = st[j];
73 st[j] = ROTL64(t, keccakf_rotc[i]);
74 t = bc[0];
75 }
76
77 /* Chi */
78 for (j = 0; j < 25; j += 5) {
79 for (i = 0; i < 5; i++)
80 bc[i] = st[j + i];
81 for (i = 0; i < 5; i++)
82 st[j + i] ^= (~bc[(i + 1) % 5]) &
83 bc[(i + 2) % 5];
84 }
85
86 /* Iota */
87 st[0] ^= keccakf_rndc[round];
88 }
89}
90
91static void sha3_init(struct sha3_state *sctx, unsigned int digest_sz)
92{
93 memset(sctx, 0, sizeof(*sctx));
94 sctx->md_len = digest_sz;
95 sctx->rsiz = 200 - 2 * digest_sz;
96 sctx->rsizw = sctx->rsiz / 8;
97}
98
99static int sha3_224_init(struct shash_desc *desc)
100{
101 struct sha3_state *sctx = shash_desc_ctx(desc);
102
103 sha3_init(sctx, SHA3_224_DIGEST_SIZE);
104 return 0;
105}
106
107static int sha3_256_init(struct shash_desc *desc)
108{
109 struct sha3_state *sctx = shash_desc_ctx(desc);
110
111 sha3_init(sctx, SHA3_256_DIGEST_SIZE);
112 return 0;
113}
114
115static int sha3_384_init(struct shash_desc *desc)
116{
117 struct sha3_state *sctx = shash_desc_ctx(desc);
118
119 sha3_init(sctx, SHA3_384_DIGEST_SIZE);
120 return 0;
121}
122
123static int sha3_512_init(struct shash_desc *desc)
124{
125 struct sha3_state *sctx = shash_desc_ctx(desc);
126
127 sha3_init(sctx, SHA3_512_DIGEST_SIZE);
128 return 0;
129}
130
131static int sha3_update(struct shash_desc *desc, const u8 *data,
132 unsigned int len)
133{
134 struct sha3_state *sctx = shash_desc_ctx(desc);
135 unsigned int done;
136 const u8 *src;
137
138 done = 0;
139 src = data;
140
141 if ((sctx->partial + len) > (sctx->rsiz - 1)) {
142 if (sctx->partial) {
143 done = -sctx->partial;
144 memcpy(sctx->buf + sctx->partial, data,
145 done + sctx->rsiz);
146 src = sctx->buf;
147 }
148
149 do {
150 unsigned int i;
151
152 for (i = 0; i < sctx->rsizw; i++)
Ard Biesheuvel1ce8e522018-01-19 12:04:33 +0000153 sctx->st[i] ^= get_unaligned_le64(src + 8 * i);
Jeff Garzik53964b92016-06-17 10:30:35 +0530154 keccakf(sctx->st);
155
156 done += sctx->rsiz;
157 src = data + done;
158 } while (done + (sctx->rsiz - 1) < len);
159
160 sctx->partial = 0;
161 }
162 memcpy(sctx->buf + sctx->partial, src, len - done);
163 sctx->partial += (len - done);
164
165 return 0;
166}
167
168static int sha3_final(struct shash_desc *desc, u8 *out)
169{
170 struct sha3_state *sctx = shash_desc_ctx(desc);
171 unsigned int i, inlen = sctx->partial;
172
173 sctx->buf[inlen++] = 0x06;
174 memset(sctx->buf + inlen, 0, sctx->rsiz - inlen);
175 sctx->buf[sctx->rsiz - 1] |= 0x80;
176
177 for (i = 0; i < sctx->rsizw; i++)
Ard Biesheuvel1ce8e522018-01-19 12:04:33 +0000178 sctx->st[i] ^= get_unaligned_le64(sctx->buf + 8 * i);
Jeff Garzik53964b92016-06-17 10:30:35 +0530179
180 keccakf(sctx->st);
181
182 for (i = 0; i < sctx->rsizw; i++)
183 sctx->st[i] = cpu_to_le64(sctx->st[i]);
184
185 memcpy(out, sctx->st, sctx->md_len);
186
187 memset(sctx, 0, sizeof(*sctx));
188 return 0;
189}
190
191static struct shash_alg sha3_224 = {
192 .digestsize = SHA3_224_DIGEST_SIZE,
193 .init = sha3_224_init,
194 .update = sha3_update,
195 .final = sha3_final,
196 .descsize = sizeof(struct sha3_state),
197 .base = {
198 .cra_name = "sha3-224",
199 .cra_driver_name = "sha3-224-generic",
200 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
201 .cra_blocksize = SHA3_224_BLOCK_SIZE,
202 .cra_module = THIS_MODULE,
203 }
204};
205
206static struct shash_alg sha3_256 = {
207 .digestsize = SHA3_256_DIGEST_SIZE,
208 .init = sha3_256_init,
209 .update = sha3_update,
210 .final = sha3_final,
211 .descsize = sizeof(struct sha3_state),
212 .base = {
213 .cra_name = "sha3-256",
214 .cra_driver_name = "sha3-256-generic",
215 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
216 .cra_blocksize = SHA3_256_BLOCK_SIZE,
217 .cra_module = THIS_MODULE,
218 }
219};
220
221static struct shash_alg sha3_384 = {
222 .digestsize = SHA3_384_DIGEST_SIZE,
223 .init = sha3_384_init,
224 .update = sha3_update,
225 .final = sha3_final,
226 .descsize = sizeof(struct sha3_state),
227 .base = {
228 .cra_name = "sha3-384",
229 .cra_driver_name = "sha3-384-generic",
230 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
231 .cra_blocksize = SHA3_384_BLOCK_SIZE,
232 .cra_module = THIS_MODULE,
233 }
234};
235
236static struct shash_alg sha3_512 = {
237 .digestsize = SHA3_512_DIGEST_SIZE,
238 .init = sha3_512_init,
239 .update = sha3_update,
240 .final = sha3_final,
241 .descsize = sizeof(struct sha3_state),
242 .base = {
243 .cra_name = "sha3-512",
244 .cra_driver_name = "sha3-512-generic",
245 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
246 .cra_blocksize = SHA3_512_BLOCK_SIZE,
247 .cra_module = THIS_MODULE,
248 }
249};
250
251static int __init sha3_generic_mod_init(void)
252{
253 int ret;
254
255 ret = crypto_register_shash(&sha3_224);
256 if (ret < 0)
257 goto err_out;
258 ret = crypto_register_shash(&sha3_256);
259 if (ret < 0)
260 goto err_out_224;
261 ret = crypto_register_shash(&sha3_384);
262 if (ret < 0)
263 goto err_out_256;
264 ret = crypto_register_shash(&sha3_512);
265 if (ret < 0)
266 goto err_out_384;
267
268 return 0;
269
270err_out_384:
271 crypto_unregister_shash(&sha3_384);
272err_out_256:
273 crypto_unregister_shash(&sha3_256);
274err_out_224:
275 crypto_unregister_shash(&sha3_224);
276err_out:
277 return ret;
278}
279
280static void __exit sha3_generic_mod_fini(void)
281{
282 crypto_unregister_shash(&sha3_224);
283 crypto_unregister_shash(&sha3_256);
284 crypto_unregister_shash(&sha3_384);
285 crypto_unregister_shash(&sha3_512);
286}
287
288module_init(sha3_generic_mod_init);
289module_exit(sha3_generic_mod_fini);
290
291MODULE_LICENSE("GPL");
292MODULE_DESCRIPTION("SHA-3 Secure Hash Algorithm");
293
294MODULE_ALIAS_CRYPTO("sha3-224");
295MODULE_ALIAS_CRYPTO("sha3-224-generic");
296MODULE_ALIAS_CRYPTO("sha3-256");
297MODULE_ALIAS_CRYPTO("sha3-256-generic");
298MODULE_ALIAS_CRYPTO("sha3-384");
299MODULE_ALIAS_CRYPTO("sha3-384-generic");
300MODULE_ALIAS_CRYPTO("sha3-512");
301MODULE_ALIAS_CRYPTO("sha3-512-generic");