0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <linux/export.h>
0011 #include <linux/module.h>
0012 #include <linux/bitops.h>
0013 #include <linux/string.h>
0014 #include <crypto/sha1.h>
0015 #include <asm/unaligned.h>
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #ifdef CONFIG_X86
0040 #define setW(x, val) (*(volatile __u32 *)&W(x) = (val))
0041 #elif defined(CONFIG_ARM)
0042 #define setW(x, val) do { W(x) = (val); __asm__("":::"memory"); } while (0)
0043 #else
0044 #define setW(x, val) (W(x) = (val))
0045 #endif
0046
0047
0048 #define W(x) (array[(x)&15])
0049
0050
0051
0052
0053
0054 #define SHA_SRC(t) get_unaligned_be32((__u32 *)data + t)
0055 #define SHA_MIX(t) rol32(W(t+13) ^ W(t+8) ^ W(t+2) ^ W(t), 1)
0056
0057 #define SHA_ROUND(t, input, fn, constant, A, B, C, D, E) do { \
0058 __u32 TEMP = input(t); setW(t, TEMP); \
0059 E += TEMP + rol32(A,5) + (fn) + (constant); \
0060 B = ror32(B, 2); \
0061 TEMP = E; E = D; D = C; C = B; B = A; A = TEMP; } while (0)
0062
0063 #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 )
0064 #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 )
0065 #define T_20_39(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0x6ed9eba1, A, B, C, D, E )
0066 #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 )
0067 #define T_60_79(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0xca62c1d6, A, B, C, D, E )
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 void sha1_transform(__u32 *digest, const char *data, __u32 *array)
0088 {
0089 __u32 A, B, C, D, E;
0090 unsigned int i = 0;
0091
0092 A = digest[0];
0093 B = digest[1];
0094 C = digest[2];
0095 D = digest[3];
0096 E = digest[4];
0097
0098
0099 for (; i < 16; ++i)
0100 T_0_15(i, A, B, C, D, E);
0101
0102
0103 for (; i < 20; ++i)
0104 T_16_19(i, A, B, C, D, E);
0105
0106
0107 for (; i < 40; ++i)
0108 T_20_39(i, A, B, C, D, E);
0109
0110
0111 for (; i < 60; ++i)
0112 T_40_59(i, A, B, C, D, E);
0113
0114
0115 for (; i < 80; ++i)
0116 T_60_79(i, A, B, C, D, E);
0117
0118 digest[0] += A;
0119 digest[1] += B;
0120 digest[2] += C;
0121 digest[3] += D;
0122 digest[4] += E;
0123 }
0124 EXPORT_SYMBOL(sha1_transform);
0125
0126
0127
0128
0129
0130 void sha1_init(__u32 *buf)
0131 {
0132 buf[0] = 0x67452301;
0133 buf[1] = 0xefcdab89;
0134 buf[2] = 0x98badcfe;
0135 buf[3] = 0x10325476;
0136 buf[4] = 0xc3d2e1f0;
0137 }
0138 EXPORT_SYMBOL(sha1_init);
0139
0140 MODULE_LICENSE("GPL");