arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / arch / mips / cavium-octeon / crypto / octeon-sha256.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Cryptographic API.
4  *
5  * SHA-224 and SHA-256 Secure Hash Algorithm.
6  *
7  * Adapted for OCTEON by Aaro Koskinen <aaro.koskinen@iki.fi>.
8  *
9  * Based on crypto/sha256_generic.c, which is:
10  *
11  * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
12  * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
13  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
14  * SHA224 Support Copyright 2007 Intel Corporation <jonathan.lynch@intel.com>
15  */
16
17 #include <linux/mm.h>
18 #include <crypto/sha2.h>
19 #include <crypto/sha256_base.h>
20 #include <linux/init.h>
21 #include <linux/types.h>
22 #include <linux/module.h>
23 #include <asm/byteorder.h>
24 #include <asm/octeon/octeon.h>
25 #include <crypto/internal/hash.h>
26
27 #include "octeon-crypto.h"
28
29 /*
30  * We pass everything as 64-bit. OCTEON can handle misaligned data.
31  */
32
33 static void octeon_sha256_store_hash(struct sha256_state *sctx)
34 {
35         u64 *hash = (u64 *)sctx->state;
36
37         write_octeon_64bit_hash_dword(hash[0], 0);
38         write_octeon_64bit_hash_dword(hash[1], 1);
39         write_octeon_64bit_hash_dword(hash[2], 2);
40         write_octeon_64bit_hash_dword(hash[3], 3);
41 }
42
43 static void octeon_sha256_read_hash(struct sha256_state *sctx)
44 {
45         u64 *hash = (u64 *)sctx->state;
46
47         hash[0] = read_octeon_64bit_hash_dword(0);
48         hash[1] = read_octeon_64bit_hash_dword(1);
49         hash[2] = read_octeon_64bit_hash_dword(2);
50         hash[3] = read_octeon_64bit_hash_dword(3);
51 }
52
53 static void octeon_sha256_transform(const void *_block)
54 {
55         const u64 *block = _block;
56
57         write_octeon_64bit_block_dword(block[0], 0);
58         write_octeon_64bit_block_dword(block[1], 1);
59         write_octeon_64bit_block_dword(block[2], 2);
60         write_octeon_64bit_block_dword(block[3], 3);
61         write_octeon_64bit_block_dword(block[4], 4);
62         write_octeon_64bit_block_dword(block[5], 5);
63         write_octeon_64bit_block_dword(block[6], 6);
64         octeon_sha256_start(block[7]);
65 }
66
67 static void __octeon_sha256_update(struct sha256_state *sctx, const u8 *data,
68                                    unsigned int len)
69 {
70         unsigned int partial;
71         unsigned int done;
72         const u8 *src;
73
74         partial = sctx->count % SHA256_BLOCK_SIZE;
75         sctx->count += len;
76         done = 0;
77         src = data;
78
79         if ((partial + len) >= SHA256_BLOCK_SIZE) {
80                 if (partial) {
81                         done = -partial;
82                         memcpy(sctx->buf + partial, data,
83                                done + SHA256_BLOCK_SIZE);
84                         src = sctx->buf;
85                 }
86
87                 do {
88                         octeon_sha256_transform(src);
89                         done += SHA256_BLOCK_SIZE;
90                         src = data + done;
91                 } while (done + SHA256_BLOCK_SIZE <= len);
92
93                 partial = 0;
94         }
95         memcpy(sctx->buf + partial, src, len - done);
96 }
97
98 static int octeon_sha256_update(struct shash_desc *desc, const u8 *data,
99                                 unsigned int len)
100 {
101         struct sha256_state *sctx = shash_desc_ctx(desc);
102         struct octeon_cop2_state state;
103         unsigned long flags;
104
105         /*
106          * Small updates never reach the crypto engine, so the generic sha256 is
107          * faster because of the heavyweight octeon_crypto_enable() /
108          * octeon_crypto_disable().
109          */
110         if ((sctx->count % SHA256_BLOCK_SIZE) + len < SHA256_BLOCK_SIZE)
111                 return crypto_sha256_update(desc, data, len);
112
113         flags = octeon_crypto_enable(&state);
114         octeon_sha256_store_hash(sctx);
115
116         __octeon_sha256_update(sctx, data, len);
117
118         octeon_sha256_read_hash(sctx);
119         octeon_crypto_disable(&state, flags);
120
121         return 0;
122 }
123
124 static int octeon_sha256_final(struct shash_desc *desc, u8 *out)
125 {
126         struct sha256_state *sctx = shash_desc_ctx(desc);
127         static const u8 padding[64] = { 0x80, };
128         struct octeon_cop2_state state;
129         __be32 *dst = (__be32 *)out;
130         unsigned int pad_len;
131         unsigned long flags;
132         unsigned int index;
133         __be64 bits;
134         int i;
135
136         /* Save number of bits. */
137         bits = cpu_to_be64(sctx->count << 3);
138
139         /* Pad out to 56 mod 64. */
140         index = sctx->count & 0x3f;
141         pad_len = (index < 56) ? (56 - index) : ((64+56) - index);
142
143         flags = octeon_crypto_enable(&state);
144         octeon_sha256_store_hash(sctx);
145
146         __octeon_sha256_update(sctx, padding, pad_len);
147
148         /* Append length (before padding). */
149         __octeon_sha256_update(sctx, (const u8 *)&bits, sizeof(bits));
150
151         octeon_sha256_read_hash(sctx);
152         octeon_crypto_disable(&state, flags);
153
154         /* Store state in digest */
155         for (i = 0; i < 8; i++)
156                 dst[i] = cpu_to_be32(sctx->state[i]);
157
158         /* Zeroize sensitive information. */
159         memset(sctx, 0, sizeof(*sctx));
160
161         return 0;
162 }
163
164 static int octeon_sha224_final(struct shash_desc *desc, u8 *hash)
165 {
166         u8 D[SHA256_DIGEST_SIZE];
167
168         octeon_sha256_final(desc, D);
169
170         memcpy(hash, D, SHA224_DIGEST_SIZE);
171         memzero_explicit(D, SHA256_DIGEST_SIZE);
172
173         return 0;
174 }
175
176 static int octeon_sha256_export(struct shash_desc *desc, void *out)
177 {
178         struct sha256_state *sctx = shash_desc_ctx(desc);
179
180         memcpy(out, sctx, sizeof(*sctx));
181         return 0;
182 }
183
184 static int octeon_sha256_import(struct shash_desc *desc, const void *in)
185 {
186         struct sha256_state *sctx = shash_desc_ctx(desc);
187
188         memcpy(sctx, in, sizeof(*sctx));
189         return 0;
190 }
191
192 static struct shash_alg octeon_sha256_algs[2] = { {
193         .digestsize     =       SHA256_DIGEST_SIZE,
194         .init           =       sha256_base_init,
195         .update         =       octeon_sha256_update,
196         .final          =       octeon_sha256_final,
197         .export         =       octeon_sha256_export,
198         .import         =       octeon_sha256_import,
199         .descsize       =       sizeof(struct sha256_state),
200         .statesize      =       sizeof(struct sha256_state),
201         .base           =       {
202                 .cra_name       =       "sha256",
203                 .cra_driver_name=       "octeon-sha256",
204                 .cra_priority   =       OCTEON_CR_OPCODE_PRIORITY,
205                 .cra_blocksize  =       SHA256_BLOCK_SIZE,
206                 .cra_module     =       THIS_MODULE,
207         }
208 }, {
209         .digestsize     =       SHA224_DIGEST_SIZE,
210         .init           =       sha224_base_init,
211         .update         =       octeon_sha256_update,
212         .final          =       octeon_sha224_final,
213         .descsize       =       sizeof(struct sha256_state),
214         .base           =       {
215                 .cra_name       =       "sha224",
216                 .cra_driver_name=       "octeon-sha224",
217                 .cra_blocksize  =       SHA224_BLOCK_SIZE,
218                 .cra_module     =       THIS_MODULE,
219         }
220 } };
221
222 static int __init octeon_sha256_mod_init(void)
223 {
224         if (!octeon_has_crypto())
225                 return -ENOTSUPP;
226         return crypto_register_shashes(octeon_sha256_algs,
227                                        ARRAY_SIZE(octeon_sha256_algs));
228 }
229
230 static void __exit octeon_sha256_mod_fini(void)
231 {
232         crypto_unregister_shashes(octeon_sha256_algs,
233                                   ARRAY_SIZE(octeon_sha256_algs));
234 }
235
236 module_init(octeon_sha256_mod_init);
237 module_exit(octeon_sha256_mod_fini);
238
239 MODULE_LICENSE("GPL");
240 MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm (OCTEON)");
241 MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>");