374330e2 |
1 | /* |
2 | * The following code was taken directly from drivers/char/random.c |
3 | * in the Linux kernel. |
4 | */ |
5 | |
6 | #include "ssh.h" |
7 | |
8 | /* |
9 | * SHA transform algorithm, taken from code written by Peter Gutman, |
10 | * and apparently in the public domain. |
11 | */ |
12 | |
13 | /* The SHA f()-functions. */ |
14 | |
15 | #define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */ |
16 | #define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */ |
17 | #define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */ |
18 | #define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */ |
19 | |
20 | /* The SHA Mysterious Constants */ |
21 | |
22 | #define K1 0x5A827999L /* Rounds 0-19 */ |
23 | #define K2 0x6ED9EBA1L /* Rounds 20-39 */ |
24 | #define K3 0x8F1BBCDCL /* Rounds 40-59 */ |
25 | #define K4 0xCA62C1D6L /* Rounds 60-79 */ |
26 | |
27 | #define ROTL(n,X) ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) ) |
28 | |
29 | #define expand(W,i) ( W[ i & 15 ] = \ |
30 | ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \ |
31 | W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) ) |
32 | |
33 | #define subRound(a, b, c, d, e, f, k, data) \ |
34 | ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) ) |
35 | |
36 | |
37 | void SHATransform(word32 *digest, word32 *data) |
38 | { |
39 | word32 A, B, C, D, E; /* Local vars */ |
40 | word32 eData[ 16 ]; /* Expanded data */ |
41 | |
42 | /* Set up first buffer and local data buffer */ |
43 | A = digest[ 0 ]; |
44 | B = digest[ 1 ]; |
45 | C = digest[ 2 ]; |
46 | D = digest[ 3 ]; |
47 | E = digest[ 4 ]; |
48 | memcpy( eData, data, 16*sizeof(word32)); |
49 | |
50 | /* Heavy mangling, in 4 sub-rounds of 20 iterations each. */ |
51 | subRound( A, B, C, D, E, f1, K1, eData[ 0 ] ); |
52 | subRound( E, A, B, C, D, f1, K1, eData[ 1 ] ); |
53 | subRound( D, E, A, B, C, f1, K1, eData[ 2 ] ); |
54 | subRound( C, D, E, A, B, f1, K1, eData[ 3 ] ); |
55 | subRound( B, C, D, E, A, f1, K1, eData[ 4 ] ); |
56 | subRound( A, B, C, D, E, f1, K1, eData[ 5 ] ); |
57 | subRound( E, A, B, C, D, f1, K1, eData[ 6 ] ); |
58 | subRound( D, E, A, B, C, f1, K1, eData[ 7 ] ); |
59 | subRound( C, D, E, A, B, f1, K1, eData[ 8 ] ); |
60 | subRound( B, C, D, E, A, f1, K1, eData[ 9 ] ); |
61 | subRound( A, B, C, D, E, f1, K1, eData[ 10 ] ); |
62 | subRound( E, A, B, C, D, f1, K1, eData[ 11 ] ); |
63 | subRound( D, E, A, B, C, f1, K1, eData[ 12 ] ); |
64 | subRound( C, D, E, A, B, f1, K1, eData[ 13 ] ); |
65 | subRound( B, C, D, E, A, f1, K1, eData[ 14 ] ); |
66 | subRound( A, B, C, D, E, f1, K1, eData[ 15 ] ); |
67 | subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) ); |
68 | subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) ); |
69 | subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) ); |
70 | subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) ); |
71 | |
72 | subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) ); |
73 | subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) ); |
74 | subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) ); |
75 | subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) ); |
76 | subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) ); |
77 | subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) ); |
78 | subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) ); |
79 | subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) ); |
80 | subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) ); |
81 | subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) ); |
82 | subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) ); |
83 | subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) ); |
84 | subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) ); |
85 | subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) ); |
86 | subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) ); |
87 | subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) ); |
88 | subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) ); |
89 | subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) ); |
90 | subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) ); |
91 | subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) ); |
92 | |
93 | subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) ); |
94 | subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) ); |
95 | subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) ); |
96 | subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) ); |
97 | subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) ); |
98 | subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) ); |
99 | subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) ); |
100 | subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) ); |
101 | subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) ); |
102 | subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) ); |
103 | subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) ); |
104 | subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) ); |
105 | subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) ); |
106 | subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) ); |
107 | subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) ); |
108 | subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) ); |
109 | subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) ); |
110 | subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) ); |
111 | subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) ); |
112 | subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) ); |
113 | |
114 | subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) ); |
115 | subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) ); |
116 | subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) ); |
117 | subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) ); |
118 | subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) ); |
119 | subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) ); |
120 | subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) ); |
121 | subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) ); |
122 | subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) ); |
123 | subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) ); |
124 | subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) ); |
125 | subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) ); |
126 | subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) ); |
127 | subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) ); |
128 | subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) ); |
129 | subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) ); |
130 | subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) ); |
131 | subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) ); |
132 | subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) ); |
133 | subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) ); |
134 | |
135 | /* Build message digest */ |
136 | digest[ 0 ] += A; |
137 | digest[ 1 ] += B; |
138 | digest[ 2 ] += C; |
139 | digest[ 3 ] += D; |
140 | digest[ 4 ] += E; |
141 | } |