~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/cavium-octeon/crypto/octeon-sha256.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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>");
242 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php