blob: a965b9d8055983af4353ae39fe676b7789c8f93f [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>
Ard Biesheuvel83dee2c2018-01-19 12:04:34 +00008 * Ard Biesheuvel <ard.biesheuvel@linaro.org>
Jeff Garzik53964b92016-06-17 10:30:35 +05309 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)•
13 * any later version.
14 *
15 */
16#include <crypto/internal/hash.h>
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/types.h>
20#include <crypto/sha3.h>
Ard Biesheuvelc013cee2018-01-19 12:04:33 +000021#include <asm/unaligned.h>
Jeff Garzik53964b92016-06-17 10:30:35 +053022
23#define KECCAK_ROUNDS 24
24
Jeff Garzik53964b92016-06-17 10:30:35 +053025static const u64 keccakf_rndc[24] = {
Geert Uytterhoevenf743e702016-08-03 19:37:03 +020026 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL,
27 0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL,
28 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL,
29 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL,
30 0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL,
31 0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL,
32 0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL,
33 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL
Jeff Garzik53964b92016-06-17 10:30:35 +053034};
35
Jeff Garzik53964b92016-06-17 10:30:35 +053036/* update the state with given number of rounds */
37
Ard Biesheuvel83dee2c2018-01-19 12:04:34 +000038static void __attribute__((__optimize__("O3"))) keccakf(u64 st[25])
Jeff Garzik53964b92016-06-17 10:30:35 +053039{
Ard Biesheuvel83dee2c2018-01-19 12:04:34 +000040 u64 t[5], tt, bc[5];
41 int round;
Jeff Garzik53964b92016-06-17 10:30:35 +053042
43 for (round = 0; round < KECCAK_ROUNDS; round++) {
44
45 /* Theta */
Ard Biesheuvel83dee2c2018-01-19 12:04:34 +000046 bc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20];
47 bc[1] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21];
48 bc[2] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22];
49 bc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23];
50 bc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24];
Jeff Garzik53964b92016-06-17 10:30:35 +053051
Ard Biesheuvel83dee2c2018-01-19 12:04:34 +000052 t[0] = bc[4] ^ rol64(bc[1], 1);
53 t[1] = bc[0] ^ rol64(bc[2], 1);
54 t[2] = bc[1] ^ rol64(bc[3], 1);
55 t[3] = bc[2] ^ rol64(bc[4], 1);
56 t[4] = bc[3] ^ rol64(bc[0], 1);
57
58 st[0] ^= t[0];
Jeff Garzik53964b92016-06-17 10:30:35 +053059
60 /* Rho Pi */
Ard Biesheuvel83dee2c2018-01-19 12:04:34 +000061 tt = st[1];
62 st[ 1] = rol64(st[ 6] ^ t[1], 44);
63 st[ 6] = rol64(st[ 9] ^ t[4], 20);
64 st[ 9] = rol64(st[22] ^ t[2], 61);
65 st[22] = rol64(st[14] ^ t[4], 39);
66 st[14] = rol64(st[20] ^ t[0], 18);
67 st[20] = rol64(st[ 2] ^ t[2], 62);
68 st[ 2] = rol64(st[12] ^ t[2], 43);
69 st[12] = rol64(st[13] ^ t[3], 25);
70 st[13] = rol64(st[19] ^ t[4], 8);
71 st[19] = rol64(st[23] ^ t[3], 56);
72 st[23] = rol64(st[15] ^ t[0], 41);
73 st[15] = rol64(st[ 4] ^ t[4], 27);
74 st[ 4] = rol64(st[24] ^ t[4], 14);
75 st[24] = rol64(st[21] ^ t[1], 2);
76 st[21] = rol64(st[ 8] ^ t[3], 55);
77 st[ 8] = rol64(st[16] ^ t[1], 45);
78 st[16] = rol64(st[ 5] ^ t[0], 36);
79 st[ 5] = rol64(st[ 3] ^ t[3], 28);
80 st[ 3] = rol64(st[18] ^ t[3], 21);
81 st[18] = rol64(st[17] ^ t[2], 15);
82 st[17] = rol64(st[11] ^ t[1], 10);
83 st[11] = rol64(st[ 7] ^ t[2], 6);
84 st[ 7] = rol64(st[10] ^ t[0], 3);
85 st[10] = rol64( tt ^ t[1], 1);
Jeff Garzik53964b92016-06-17 10:30:35 +053086
87 /* Chi */
Ard Biesheuvel83dee2c2018-01-19 12:04:34 +000088 bc[ 0] = ~st[ 1] & st[ 2];
89 bc[ 1] = ~st[ 2] & st[ 3];
90 bc[ 2] = ~st[ 3] & st[ 4];
91 bc[ 3] = ~st[ 4] & st[ 0];
92 bc[ 4] = ~st[ 0] & st[ 1];
93 st[ 0] ^= bc[ 0];
94 st[ 1] ^= bc[ 1];
95 st[ 2] ^= bc[ 2];
96 st[ 3] ^= bc[ 3];
97 st[ 4] ^= bc[ 4];
98
99 bc[ 0] = ~st[ 6] & st[ 7];
100 bc[ 1] = ~st[ 7] & st[ 8];
101 bc[ 2] = ~st[ 8] & st[ 9];
102 bc[ 3] = ~st[ 9] & st[ 5];
103 bc[ 4] = ~st[ 5] & st[ 6];
104 st[ 5] ^= bc[ 0];
105 st[ 6] ^= bc[ 1];
106 st[ 7] ^= bc[ 2];
107 st[ 8] ^= bc[ 3];
108 st[ 9] ^= bc[ 4];
109
110 bc[ 0] = ~st[11] & st[12];
111 bc[ 1] = ~st[12] & st[13];
112 bc[ 2] = ~st[13] & st[14];
113 bc[ 3] = ~st[14] & st[10];
114 bc[ 4] = ~st[10] & st[11];
115 st[10] ^= bc[ 0];
116 st[11] ^= bc[ 1];
117 st[12] ^= bc[ 2];
118 st[13] ^= bc[ 3];
119 st[14] ^= bc[ 4];
120
121 bc[ 0] = ~st[16] & st[17];
122 bc[ 1] = ~st[17] & st[18];
123 bc[ 2] = ~st[18] & st[19];
124 bc[ 3] = ~st[19] & st[15];
125 bc[ 4] = ~st[15] & st[16];
126 st[15] ^= bc[ 0];
127 st[16] ^= bc[ 1];
128 st[17] ^= bc[ 2];
129 st[18] ^= bc[ 3];
130 st[19] ^= bc[ 4];
131
132 bc[ 0] = ~st[21] & st[22];
133 bc[ 1] = ~st[22] & st[23];
134 bc[ 2] = ~st[23] & st[24];
135 bc[ 3] = ~st[24] & st[20];
136 bc[ 4] = ~st[20] & st[21];
137 st[20] ^= bc[ 0];
138 st[21] ^= bc[ 1];
139 st[22] ^= bc[ 2];
140 st[23] ^= bc[ 3];
141 st[24] ^= bc[ 4];
Jeff Garzik53964b92016-06-17 10:30:35 +0530142
143 /* Iota */
144 st[0] ^= keccakf_rndc[round];
145 }
146}
147
Ard Biesheuvel66576742018-01-19 12:04:36 +0000148int crypto_sha3_init(struct shash_desc *desc)
Jeff Garzik53964b92016-06-17 10:30:35 +0530149{
Ard Biesheuvelbeeb5042018-01-19 12:04:35 +0000150 struct sha3_state *sctx = shash_desc_ctx(desc);
151 unsigned int digest_size = crypto_shash_digestsize(desc->tfm);
152
153 sctx->rsiz = 200 - 2 * digest_size;
Jeff Garzik53964b92016-06-17 10:30:35 +0530154 sctx->rsizw = sctx->rsiz / 8;
Ard Biesheuvelbeeb5042018-01-19 12:04:35 +0000155 sctx->partial = 0;
Jeff Garzik53964b92016-06-17 10:30:35 +0530156
Ard Biesheuvelbeeb5042018-01-19 12:04:35 +0000157 memset(sctx->st, 0, sizeof(sctx->st));
Jeff Garzik53964b92016-06-17 10:30:35 +0530158 return 0;
159}
Ard Biesheuvel66576742018-01-19 12:04:36 +0000160EXPORT_SYMBOL(crypto_sha3_init);
Jeff Garzik53964b92016-06-17 10:30:35 +0530161
Ard Biesheuvel66576742018-01-19 12:04:36 +0000162int crypto_sha3_update(struct shash_desc *desc, const u8 *data,
Jeff Garzik53964b92016-06-17 10:30:35 +0530163 unsigned int len)
164{
165 struct sha3_state *sctx = shash_desc_ctx(desc);
166 unsigned int done;
167 const u8 *src;
168
169 done = 0;
170 src = data;
171
172 if ((sctx->partial + len) > (sctx->rsiz - 1)) {
173 if (sctx->partial) {
174 done = -sctx->partial;
175 memcpy(sctx->buf + sctx->partial, data,
176 done + sctx->rsiz);
177 src = sctx->buf;
178 }
179
180 do {
181 unsigned int i;
182
183 for (i = 0; i < sctx->rsizw; i++)
Ard Biesheuvelc013cee2018-01-19 12:04:33 +0000184 sctx->st[i] ^= get_unaligned_le64(src + 8 * i);
Jeff Garzik53964b92016-06-17 10:30:35 +0530185 keccakf(sctx->st);
186
187 done += sctx->rsiz;
188 src = data + done;
189 } while (done + (sctx->rsiz - 1) < len);
190
191 sctx->partial = 0;
192 }
193 memcpy(sctx->buf + sctx->partial, src, len - done);
194 sctx->partial += (len - done);
195
196 return 0;
197}
Ard Biesheuvel66576742018-01-19 12:04:36 +0000198EXPORT_SYMBOL(crypto_sha3_update);
Jeff Garzik53964b92016-06-17 10:30:35 +0530199
Ard Biesheuvel66576742018-01-19 12:04:36 +0000200int crypto_sha3_final(struct shash_desc *desc, u8 *out)
Jeff Garzik53964b92016-06-17 10:30:35 +0530201{
202 struct sha3_state *sctx = shash_desc_ctx(desc);
203 unsigned int i, inlen = sctx->partial;
Ard Biesheuvelbeeb5042018-01-19 12:04:35 +0000204 unsigned int digest_size = crypto_shash_digestsize(desc->tfm);
205 __le64 *digest = (__le64 *)out;
Jeff Garzik53964b92016-06-17 10:30:35 +0530206
207 sctx->buf[inlen++] = 0x06;
208 memset(sctx->buf + inlen, 0, sctx->rsiz - inlen);
209 sctx->buf[sctx->rsiz - 1] |= 0x80;
210
211 for (i = 0; i < sctx->rsizw; i++)
Ard Biesheuvelc013cee2018-01-19 12:04:33 +0000212 sctx->st[i] ^= get_unaligned_le64(sctx->buf + 8 * i);
Jeff Garzik53964b92016-06-17 10:30:35 +0530213
214 keccakf(sctx->st);
215
Ard Biesheuvelbeeb5042018-01-19 12:04:35 +0000216 for (i = 0; i < digest_size / 8; i++)
217 put_unaligned_le64(sctx->st[i], digest++);
Jeff Garzik53964b92016-06-17 10:30:35 +0530218
Ard Biesheuvelbeeb5042018-01-19 12:04:35 +0000219 if (digest_size & 4)
220 put_unaligned_le32(sctx->st[i], (__le32 *)digest);
Jeff Garzik53964b92016-06-17 10:30:35 +0530221
222 memset(sctx, 0, sizeof(*sctx));
223 return 0;
224}
Ard Biesheuvel66576742018-01-19 12:04:36 +0000225EXPORT_SYMBOL(crypto_sha3_final);
Jeff Garzik53964b92016-06-17 10:30:35 +0530226
Ard Biesheuvelbeeb5042018-01-19 12:04:35 +0000227static struct shash_alg algs[] = { {
228 .digestsize = SHA3_224_DIGEST_SIZE,
Ard Biesheuvel66576742018-01-19 12:04:36 +0000229 .init = crypto_sha3_init,
230 .update = crypto_sha3_update,
231 .final = crypto_sha3_final,
Ard Biesheuvelbeeb5042018-01-19 12:04:35 +0000232 .descsize = sizeof(struct sha3_state),
233 .base.cra_name = "sha3-224",
234 .base.cra_driver_name = "sha3-224-generic",
235 .base.cra_flags = CRYPTO_ALG_TYPE_SHASH,
236 .base.cra_blocksize = SHA3_224_BLOCK_SIZE,
237 .base.cra_module = THIS_MODULE,
238}, {
239 .digestsize = SHA3_256_DIGEST_SIZE,
Ard Biesheuvel66576742018-01-19 12:04:36 +0000240 .init = crypto_sha3_init,
241 .update = crypto_sha3_update,
242 .final = crypto_sha3_final,
Ard Biesheuvelbeeb5042018-01-19 12:04:35 +0000243 .descsize = sizeof(struct sha3_state),
244 .base.cra_name = "sha3-256",
245 .base.cra_driver_name = "sha3-256-generic",
246 .base.cra_flags = CRYPTO_ALG_TYPE_SHASH,
247 .base.cra_blocksize = SHA3_256_BLOCK_SIZE,
248 .base.cra_module = THIS_MODULE,
249}, {
250 .digestsize = SHA3_384_DIGEST_SIZE,
Ard Biesheuvel66576742018-01-19 12:04:36 +0000251 .init = crypto_sha3_init,
252 .update = crypto_sha3_update,
253 .final = crypto_sha3_final,
Ard Biesheuvelbeeb5042018-01-19 12:04:35 +0000254 .descsize = sizeof(struct sha3_state),
255 .base.cra_name = "sha3-384",
256 .base.cra_driver_name = "sha3-384-generic",
257 .base.cra_flags = CRYPTO_ALG_TYPE_SHASH,
258 .base.cra_blocksize = SHA3_384_BLOCK_SIZE,
259 .base.cra_module = THIS_MODULE,
260}, {
261 .digestsize = SHA3_512_DIGEST_SIZE,
Ard Biesheuvel66576742018-01-19 12:04:36 +0000262 .init = crypto_sha3_init,
263 .update = crypto_sha3_update,
264 .final = crypto_sha3_final,
Ard Biesheuvelbeeb5042018-01-19 12:04:35 +0000265 .descsize = sizeof(struct sha3_state),
266 .base.cra_name = "sha3-512",
267 .base.cra_driver_name = "sha3-512-generic",
268 .base.cra_flags = CRYPTO_ALG_TYPE_SHASH,
269 .base.cra_blocksize = SHA3_512_BLOCK_SIZE,
270 .base.cra_module = THIS_MODULE,
271} };
Jeff Garzik53964b92016-06-17 10:30:35 +0530272
273static int __init sha3_generic_mod_init(void)
274{
Ard Biesheuvelbeeb5042018-01-19 12:04:35 +0000275 return crypto_register_shashes(algs, ARRAY_SIZE(algs));
Jeff Garzik53964b92016-06-17 10:30:35 +0530276}
277
278static void __exit sha3_generic_mod_fini(void)
279{
Ard Biesheuvelbeeb5042018-01-19 12:04:35 +0000280 crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
Jeff Garzik53964b92016-06-17 10:30:35 +0530281}
282
283module_init(sha3_generic_mod_init);
284module_exit(sha3_generic_mod_fini);
285
286MODULE_LICENSE("GPL");
287MODULE_DESCRIPTION("SHA-3 Secure Hash Algorithm");
288
289MODULE_ALIAS_CRYPTO("sha3-224");
290MODULE_ALIAS_CRYPTO("sha3-224-generic");
291MODULE_ALIAS_CRYPTO("sha3-256");
292MODULE_ALIAS_CRYPTO("sha3-256-generic");
293MODULE_ALIAS_CRYPTO("sha3-384");
294MODULE_ALIAS_CRYPTO("sha3-384-generic");
295MODULE_ALIAS_CRYPTO("sha3-512");
296MODULE_ALIAS_CRYPTO("sha3-512-generic");