brintos

brintos / linux-shallow public Read only

0
0
Text · 4.5 KiB · ebb6051 Raw
142 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * SHA1 routine optimized to do word accesses rather than byte accesses,4 * and to avoid unnecessary copies into the context array.5 *6 * This was based on the git SHA1 implementation.7 */8 9#include <linux/kernel.h>10#include <linux/export.h>11#include <linux/module.h>12#include <linux/bitops.h>13#include <linux/string.h>14#include <crypto/sha1.h>15#include <linux/unaligned.h>16 17/*18 * If you have 32 registers or more, the compiler can (and should)19 * try to change the array[] accesses into registers. However, on20 * machines with less than ~25 registers, that won't really work,21 * and at least gcc will make an unholy mess of it.22 *23 * So to avoid that mess which just slows things down, we force24 * the stores to memory to actually happen (we might be better off25 * with a 'W(t)=(val);asm("":"+m" (W(t))' there instead, as26 * suggested by Artur Skawina - that will also make gcc unable to27 * try to do the silly "optimize away loads" part because it won't28 * see what the value will be).29 *30 * Ben Herrenschmidt reports that on PPC, the C version comes close31 * to the optimized asm with this (ie on PPC you don't want that32 * 'volatile', since there are lots of registers).33 *34 * On ARM we get the best code generation by forcing a full memory barrier35 * between each SHA_ROUND, otherwise gcc happily get wild with spilling and36 * the stack frame size simply explode and performance goes down the drain.37 */38 39#ifdef CONFIG_X8640  #define setW(x, val) (*(volatile __u32 *)&W(x) = (val))41#elif defined(CONFIG_ARM)42  #define setW(x, val) do { W(x) = (val); __asm__("":::"memory"); } while (0)43#else44  #define setW(x, val) (W(x) = (val))45#endif46 47/* This "rolls" over the 512-bit array */48#define W(x) (array[(x)&15])49 50/*51 * Where do we get the source from? The first 16 iterations get it from52 * the input data, the next mix it from the 512-bit array.53 */54#define SHA_SRC(t) get_unaligned_be32((__u32 *)data + t)55#define SHA_MIX(t) rol32(W(t+13) ^ W(t+8) ^ W(t+2) ^ W(t), 1)56 57#define SHA_ROUND(t, input, fn, constant, A, B, C, D, E) do { \58	__u32 TEMP = input(t); setW(t, TEMP); \59	E += TEMP + rol32(A,5) + (fn) + (constant); \60	B = ror32(B, 2); \61	TEMP = E; E = D; D = C; C = B; B = A; A = TEMP; } while (0)62 63#define T_0_15(t, A, B, C, D, E)  SHA_ROUND(t, SHA_SRC, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )64#define T_16_19(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )65#define T_20_39(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0x6ed9eba1, A, B, C, D, E )66#define T_40_59(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, ((B&C)+(D&(B^C))) , 0x8f1bbcdc, A, B, C, D, E )67#define T_60_79(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) ,  0xca62c1d6, A, B, C, D, E )68 69/**70 * sha1_transform - single block SHA1 transform (deprecated)71 *72 * @digest: 160 bit digest to update73 * @data:   512 bits of data to hash74 * @array:  16 words of workspace (see note)75 *76 * This function executes SHA-1's internal compression function.  It updates the77 * 160-bit internal state (@digest) with a single 512-bit data block (@data).78 *79 * Don't use this function.  SHA-1 is no longer considered secure.  And even if80 * you do have to use SHA-1, this isn't the correct way to hash something with81 * SHA-1 as this doesn't handle padding and finalization.82 *83 * Note: If the hash is security sensitive, the caller should be sure84 * to clear the workspace. This is left to the caller to avoid85 * unnecessary clears between chained hashing operations.86 */87void sha1_transform(__u32 *digest, const char *data, __u32 *array)88{89	__u32 A, B, C, D, E;90	unsigned int i = 0;91 92	A = digest[0];93	B = digest[1];94	C = digest[2];95	D = digest[3];96	E = digest[4];97 98	/* Round 1 - iterations 0-16 take their input from 'data' */99	for (; i < 16; ++i)100		T_0_15(i, A, B, C, D, E);101 102	/* Round 1 - tail. Input from 512-bit mixing array */103	for (; i < 20; ++i)104		T_16_19(i, A, B, C, D, E);105 106	/* Round 2 */107	for (; i < 40; ++i)108		T_20_39(i, A, B, C, D, E);109 110	/* Round 3 */111	for (; i < 60; ++i)112		T_40_59(i, A, B, C, D, E);113 114	/* Round 4 */115	for (; i < 80; ++i)116		T_60_79(i, A, B, C, D, E);117 118	digest[0] += A;119	digest[1] += B;120	digest[2] += C;121	digest[3] += D;122	digest[4] += E;123}124EXPORT_SYMBOL(sha1_transform);125 126/**127 * sha1_init - initialize the vectors for a SHA1 digest128 * @buf: vector to initialize129 */130void sha1_init(__u32 *buf)131{132	buf[0] = 0x67452301;133	buf[1] = 0xefcdab89;134	buf[2] = 0x98badcfe;135	buf[3] = 0x10325476;136	buf[4] = 0xc3d2e1f0;137}138EXPORT_SYMBOL(sha1_init);139 140MODULE_DESCRIPTION("SHA-1 Algorithm");141MODULE_LICENSE("GPL");142