Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[sfrench/cifs-2.6.git] / arch / mips / cavium-octeon / crypto / octeon-sha1.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Cryptographic API.
4  *
5  * SHA1 Secure Hash Algorithm.
6  *
7  * Adapted for OCTEON by Aaro Koskinen <aaro.koskinen@iki.fi>.
8  *
9  * Based on crypto/sha1_generic.c, which is:
10  *
11  * Copyright (c) Alan Smithee.
12  * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
13  * Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
14  */
15
16 #include <linux/mm.h>
17 #include <crypto/sha.h>
18 #include <linux/init.h>
19 #include <linux/types.h>
20 #include <linux/module.h>
21 #include <asm/byteorder.h>
22 #include <asm/octeon/octeon.h>
23 #include <crypto/internal/hash.h>
24
25 #include "octeon-crypto.h"
26
27 /*
28  * We pass everything as 64-bit. OCTEON can handle misaligned data.
29  */
30
31 static void octeon_sha1_store_hash(struct sha1_state *sctx)
32 {
33         u64 *hash = (u64 *)sctx->state;
34         union {
35                 u32 word[2];
36                 u64 dword;
37         } hash_tail = { { sctx->state[4], } };
38
39         write_octeon_64bit_hash_dword(hash[0], 0);
40         write_octeon_64bit_hash_dword(hash[1], 1);
41         write_octeon_64bit_hash_dword(hash_tail.dword, 2);
42         memzero_explicit(&hash_tail.word[0], sizeof(hash_tail.word[0]));
43 }
44
45 static void octeon_sha1_read_hash(struct sha1_state *sctx)
46 {
47         u64 *hash = (u64 *)sctx->state;
48         union {
49                 u32 word[2];
50                 u64 dword;
51         } hash_tail;
52
53         hash[0]         = read_octeon_64bit_hash_dword(0);
54         hash[1]         = read_octeon_64bit_hash_dword(1);
55         hash_tail.dword = read_octeon_64bit_hash_dword(2);
56         sctx->state[4]  = hash_tail.word[0];
57         memzero_explicit(&hash_tail.dword, sizeof(hash_tail.dword));
58 }
59
60 static void octeon_sha1_transform(const void *_block)
61 {
62         const u64 *block = _block;
63
64         write_octeon_64bit_block_dword(block[0], 0);
65         write_octeon_64bit_block_dword(block[1], 1);
66         write_octeon_64bit_block_dword(block[2], 2);
67         write_octeon_64bit_block_dword(block[3], 3);
68         write_octeon_64bit_block_dword(block[4], 4);
69         write_octeon_64bit_block_dword(block[5], 5);
70         write_octeon_64bit_block_dword(block[6], 6);
71         octeon_sha1_start(block[7]);
72 }
73
74 static int octeon_sha1_init(struct shash_desc *desc)
75 {
76         struct sha1_state *sctx = shash_desc_ctx(desc);
77
78         sctx->state[0] = SHA1_H0;
79         sctx->state[1] = SHA1_H1;
80         sctx->state[2] = SHA1_H2;
81         sctx->state[3] = SHA1_H3;
82         sctx->state[4] = SHA1_H4;
83         sctx->count = 0;
84
85         return 0;
86 }
87
88 static void __octeon_sha1_update(struct sha1_state *sctx, const u8 *data,
89                                  unsigned int len)
90 {
91         unsigned int partial;
92         unsigned int done;
93         const u8 *src;
94
95         partial = sctx->count % SHA1_BLOCK_SIZE;
96         sctx->count += len;
97         done = 0;
98         src = data;
99
100         if ((partial + len) >= SHA1_BLOCK_SIZE) {
101                 if (partial) {
102                         done = -partial;
103                         memcpy(sctx->buffer + partial, data,
104                                done + SHA1_BLOCK_SIZE);
105                         src = sctx->buffer;
106                 }
107
108                 do {
109                         octeon_sha1_transform(src);
110                         done += SHA1_BLOCK_SIZE;
111                         src = data + done;
112                 } while (done + SHA1_BLOCK_SIZE <= len);
113
114                 partial = 0;
115         }
116         memcpy(sctx->buffer + partial, src, len - done);
117 }
118
119 static int octeon_sha1_update(struct shash_desc *desc, const u8 *data,
120                         unsigned int len)
121 {
122         struct sha1_state *sctx = shash_desc_ctx(desc);
123         struct octeon_cop2_state state;
124         unsigned long flags;
125
126         /*
127          * Small updates never reach the crypto engine, so the generic sha1 is
128          * faster because of the heavyweight octeon_crypto_enable() /
129          * octeon_crypto_disable().
130          */
131         if ((sctx->count % SHA1_BLOCK_SIZE) + len < SHA1_BLOCK_SIZE)
132                 return crypto_sha1_update(desc, data, len);
133
134         flags = octeon_crypto_enable(&state);
135         octeon_sha1_store_hash(sctx);
136
137         __octeon_sha1_update(sctx, data, len);
138
139         octeon_sha1_read_hash(sctx);
140         octeon_crypto_disable(&state, flags);
141
142         return 0;
143 }
144
145 static int octeon_sha1_final(struct shash_desc *desc, u8 *out)
146 {
147         struct sha1_state *sctx = shash_desc_ctx(desc);
148         static const u8 padding[64] = { 0x80, };
149         struct octeon_cop2_state state;
150         __be32 *dst = (__be32 *)out;
151         unsigned int pad_len;
152         unsigned long flags;
153         unsigned int index;
154         __be64 bits;
155         int i;
156
157         /* Save number of bits. */
158         bits = cpu_to_be64(sctx->count << 3);
159
160         /* Pad out to 56 mod 64. */
161         index = sctx->count & 0x3f;
162         pad_len = (index < 56) ? (56 - index) : ((64+56) - index);
163
164         flags = octeon_crypto_enable(&state);
165         octeon_sha1_store_hash(sctx);
166
167         __octeon_sha1_update(sctx, padding, pad_len);
168
169         /* Append length (before padding). */
170         __octeon_sha1_update(sctx, (const u8 *)&bits, sizeof(bits));
171
172         octeon_sha1_read_hash(sctx);
173         octeon_crypto_disable(&state, flags);
174
175         /* Store state in digest */
176         for (i = 0; i < 5; i++)
177                 dst[i] = cpu_to_be32(sctx->state[i]);
178
179         /* Zeroize sensitive information. */
180         memset(sctx, 0, sizeof(*sctx));
181
182         return 0;
183 }
184
185 static int octeon_sha1_export(struct shash_desc *desc, void *out)
186 {
187         struct sha1_state *sctx = shash_desc_ctx(desc);
188
189         memcpy(out, sctx, sizeof(*sctx));
190         return 0;
191 }
192
193 static int octeon_sha1_import(struct shash_desc *desc, const void *in)
194 {
195         struct sha1_state *sctx = shash_desc_ctx(desc);
196
197         memcpy(sctx, in, sizeof(*sctx));
198         return 0;
199 }
200
201 static struct shash_alg octeon_sha1_alg = {
202         .digestsize     =       SHA1_DIGEST_SIZE,
203         .init           =       octeon_sha1_init,
204         .update         =       octeon_sha1_update,
205         .final          =       octeon_sha1_final,
206         .export         =       octeon_sha1_export,
207         .import         =       octeon_sha1_import,
208         .descsize       =       sizeof(struct sha1_state),
209         .statesize      =       sizeof(struct sha1_state),
210         .base           =       {
211                 .cra_name       =       "sha1",
212                 .cra_driver_name=       "octeon-sha1",
213                 .cra_priority   =       OCTEON_CR_OPCODE_PRIORITY,
214                 .cra_blocksize  =       SHA1_BLOCK_SIZE,
215                 .cra_module     =       THIS_MODULE,
216         }
217 };
218
219 static int __init octeon_sha1_mod_init(void)
220 {
221         if (!octeon_has_crypto())
222                 return -ENOTSUPP;
223         return crypto_register_shash(&octeon_sha1_alg);
224 }
225
226 static void __exit octeon_sha1_mod_fini(void)
227 {
228         crypto_unregister_shash(&octeon_sha1_alg);
229 }
230
231 module_init(octeon_sha1_mod_init);
232 module_exit(octeon_sha1_mod_fini);
233
234 MODULE_LICENSE("GPL");
235 MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm (OCTEON)");
236 MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>");