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

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

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ 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-512 and SHA-384 Secure Hash Algorithm.
  6  *
  7  * Adapted for OCTEON by Aaro Koskinen <aaro.koskinen@iki.fi>.
  8  *
  9  * Based on crypto/sha512_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) 2003 Kyle McMartin <kyle@debian.org>
 14  */
 15 
 16 #include <linux/mm.h>
 17 #include <crypto/sha2.h>
 18 #include <crypto/sha512_base.h>
 19 #include <linux/init.h>
 20 #include <linux/types.h>
 21 #include <linux/module.h>
 22 #include <asm/byteorder.h>
 23 #include <asm/octeon/octeon.h>
 24 #include <crypto/internal/hash.h>
 25 
 26 #include "octeon-crypto.h"
 27 
 28 /*
 29  * We pass everything as 64-bit. OCTEON can handle misaligned data.
 30  */
 31 
 32 static void octeon_sha512_store_hash(struct sha512_state *sctx)
 33 {
 34         write_octeon_64bit_hash_sha512(sctx->state[0], 0);
 35         write_octeon_64bit_hash_sha512(sctx->state[1], 1);
 36         write_octeon_64bit_hash_sha512(sctx->state[2], 2);
 37         write_octeon_64bit_hash_sha512(sctx->state[3], 3);
 38         write_octeon_64bit_hash_sha512(sctx->state[4], 4);
 39         write_octeon_64bit_hash_sha512(sctx->state[5], 5);
 40         write_octeon_64bit_hash_sha512(sctx->state[6], 6);
 41         write_octeon_64bit_hash_sha512(sctx->state[7], 7);
 42 }
 43 
 44 static void octeon_sha512_read_hash(struct sha512_state *sctx)
 45 {
 46         sctx->state[0] = read_octeon_64bit_hash_sha512(0);
 47         sctx->state[1] = read_octeon_64bit_hash_sha512(1);
 48         sctx->state[2] = read_octeon_64bit_hash_sha512(2);
 49         sctx->state[3] = read_octeon_64bit_hash_sha512(3);
 50         sctx->state[4] = read_octeon_64bit_hash_sha512(4);
 51         sctx->state[5] = read_octeon_64bit_hash_sha512(5);
 52         sctx->state[6] = read_octeon_64bit_hash_sha512(6);
 53         sctx->state[7] = read_octeon_64bit_hash_sha512(7);
 54 }
 55 
 56 static void octeon_sha512_transform(const void *_block)
 57 {
 58         const u64 *block = _block;
 59 
 60         write_octeon_64bit_block_sha512(block[0], 0);
 61         write_octeon_64bit_block_sha512(block[1], 1);
 62         write_octeon_64bit_block_sha512(block[2], 2);
 63         write_octeon_64bit_block_sha512(block[3], 3);
 64         write_octeon_64bit_block_sha512(block[4], 4);
 65         write_octeon_64bit_block_sha512(block[5], 5);
 66         write_octeon_64bit_block_sha512(block[6], 6);
 67         write_octeon_64bit_block_sha512(block[7], 7);
 68         write_octeon_64bit_block_sha512(block[8], 8);
 69         write_octeon_64bit_block_sha512(block[9], 9);
 70         write_octeon_64bit_block_sha512(block[10], 10);
 71         write_octeon_64bit_block_sha512(block[11], 11);
 72         write_octeon_64bit_block_sha512(block[12], 12);
 73         write_octeon_64bit_block_sha512(block[13], 13);
 74         write_octeon_64bit_block_sha512(block[14], 14);
 75         octeon_sha512_start(block[15]);
 76 }
 77 
 78 static void __octeon_sha512_update(struct sha512_state *sctx, const u8 *data,
 79                                    unsigned int len)
 80 {
 81         unsigned int part_len;
 82         unsigned int index;
 83         unsigned int i;
 84 
 85         /* Compute number of bytes mod 128. */
 86         index = sctx->count[0] % SHA512_BLOCK_SIZE;
 87 
 88         /* Update number of bytes. */
 89         if ((sctx->count[0] += len) < len)
 90                 sctx->count[1]++;
 91 
 92         part_len = SHA512_BLOCK_SIZE - index;
 93 
 94         /* Transform as many times as possible. */
 95         if (len >= part_len) {
 96                 memcpy(&sctx->buf[index], data, part_len);
 97                 octeon_sha512_transform(sctx->buf);
 98 
 99                 for (i = part_len; i + SHA512_BLOCK_SIZE <= len;
100                         i += SHA512_BLOCK_SIZE)
101                         octeon_sha512_transform(&data[i]);
102 
103                 index = 0;
104         } else {
105                 i = 0;
106         }
107 
108         /* Buffer remaining input. */
109         memcpy(&sctx->buf[index], &data[i], len - i);
110 }
111 
112 static int octeon_sha512_update(struct shash_desc *desc, const u8 *data,
113                                 unsigned int len)
114 {
115         struct sha512_state *sctx = shash_desc_ctx(desc);
116         struct octeon_cop2_state state;
117         unsigned long flags;
118 
119         /*
120          * Small updates never reach the crypto engine, so the generic sha512 is
121          * faster because of the heavyweight octeon_crypto_enable() /
122          * octeon_crypto_disable().
123          */
124         if ((sctx->count[0] % SHA512_BLOCK_SIZE) + len < SHA512_BLOCK_SIZE)
125                 return crypto_sha512_update(desc, data, len);
126 
127         flags = octeon_crypto_enable(&state);
128         octeon_sha512_store_hash(sctx);
129 
130         __octeon_sha512_update(sctx, data, len);
131 
132         octeon_sha512_read_hash(sctx);
133         octeon_crypto_disable(&state, flags);
134 
135         return 0;
136 }
137 
138 static int octeon_sha512_final(struct shash_desc *desc, u8 *hash)
139 {
140         struct sha512_state *sctx = shash_desc_ctx(desc);
141         static u8 padding[128] = { 0x80, };
142         struct octeon_cop2_state state;
143         __be64 *dst = (__be64 *)hash;
144         unsigned int pad_len;
145         unsigned long flags;
146         unsigned int index;
147         __be64 bits[2];
148         int i;
149 
150         /* Save number of bits. */
151         bits[1] = cpu_to_be64(sctx->count[0] << 3);
152         bits[0] = cpu_to_be64(sctx->count[1] << 3 | sctx->count[0] >> 61);
153 
154         /* Pad out to 112 mod 128. */
155         index = sctx->count[0] & 0x7f;
156         pad_len = (index < 112) ? (112 - index) : ((128+112) - index);
157 
158         flags = octeon_crypto_enable(&state);
159         octeon_sha512_store_hash(sctx);
160 
161         __octeon_sha512_update(sctx, padding, pad_len);
162 
163         /* Append length (before padding). */
164         __octeon_sha512_update(sctx, (const u8 *)bits, sizeof(bits));
165 
166         octeon_sha512_read_hash(sctx);
167         octeon_crypto_disable(&state, flags);
168 
169         /* Store state in digest. */
170         for (i = 0; i < 8; i++)
171                 dst[i] = cpu_to_be64(sctx->state[i]);
172 
173         /* Zeroize sensitive information. */
174         memset(sctx, 0, sizeof(struct sha512_state));
175 
176         return 0;
177 }
178 
179 static int octeon_sha384_final(struct shash_desc *desc, u8 *hash)
180 {
181         u8 D[64];
182 
183         octeon_sha512_final(desc, D);
184 
185         memcpy(hash, D, 48);
186         memzero_explicit(D, 64);
187 
188         return 0;
189 }
190 
191 static struct shash_alg octeon_sha512_algs[2] = { {
192         .digestsize     =       SHA512_DIGEST_SIZE,
193         .init           =       sha512_base_init,
194         .update         =       octeon_sha512_update,
195         .final          =       octeon_sha512_final,
196         .descsize       =       sizeof(struct sha512_state),
197         .base           =       {
198                 .cra_name       =       "sha512",
199                 .cra_driver_name=       "octeon-sha512",
200                 .cra_priority   =       OCTEON_CR_OPCODE_PRIORITY,
201                 .cra_blocksize  =       SHA512_BLOCK_SIZE,
202                 .cra_module     =       THIS_MODULE,
203         }
204 }, {
205         .digestsize     =       SHA384_DIGEST_SIZE,
206         .init           =       sha384_base_init,
207         .update         =       octeon_sha512_update,
208         .final          =       octeon_sha384_final,
209         .descsize       =       sizeof(struct sha512_state),
210         .base           =       {
211                 .cra_name       =       "sha384",
212                 .cra_driver_name=       "octeon-sha384",
213                 .cra_priority   =       OCTEON_CR_OPCODE_PRIORITY,
214                 .cra_blocksize  =       SHA384_BLOCK_SIZE,
215                 .cra_module     =       THIS_MODULE,
216         }
217 } };
218 
219 static int __init octeon_sha512_mod_init(void)
220 {
221         if (!octeon_has_crypto())
222                 return -ENOTSUPP;
223         return crypto_register_shashes(octeon_sha512_algs,
224                                        ARRAY_SIZE(octeon_sha512_algs));
225 }
226 
227 static void __exit octeon_sha512_mod_fini(void)
228 {
229         crypto_unregister_shashes(octeon_sha512_algs,
230                                   ARRAY_SIZE(octeon_sha512_algs));
231 }
232 
233 module_init(octeon_sha512_mod_init);
234 module_exit(octeon_sha512_mod_fini);
235 
236 MODULE_LICENSE("GPL");
237 MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms (OCTEON)");
238 MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>");
239 

~ [ 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