Branch data Line data Source code
1 : : /*
2 : : *****************************************************************************
3 : : *
4 : : * File: sha1.c
5 : : *
6 : : * Purpose: Implementation of the SHA1 message-digest algorithm for
7 : : * libfwknop.
8 : : *
9 : : * NIST Secure Hash Algorithm
10 : : * Heavily modified by Uwe Hollerbach <uh@alumni.caltech edu>
11 : : * from Peter C. Gutmann's implementation as found in
12 : : * Applied Cryptography by Bruce Schneier
13 : : * Further modifications to include the "UNRAVEL" stuff, below
14 : : *
15 : : * This code is in the public domain
16 : : *
17 : : *****************************************************************************
18 : : */
19 : : #include "sha1.h"
20 : : #include "fko_common.h"
21 : :
22 : : /* SHA f()-functions */
23 : : #define f1(x,y,z) ((x & y) | (~x & z))
24 : : #define f2(x,y,z) (x ^ y ^ z)
25 : : #define f3(x,y,z) ((x & y) | (x & z) | (y & z))
26 : : #define f4(x,y,z) (x ^ y ^ z)
27 : :
28 : : /* SHA constants */
29 : : #define CONST1 0x5a827999L
30 : : #define CONST2 0x6ed9eba1L
31 : : #define CONST3 0x8f1bbcdcL
32 : : #define CONST4 0xca62c1d6L
33 : :
34 : : /* truncate to 32 bits -- should be a null op on 32-bit machines */
35 : : #define T32(x) ((x) & 0xffffffffL)
36 : :
37 : : /* 32-bit rotate */
38 : : #define R32(x,n) T32(((x << n) | (x >> (32 - n))))
39 : :
40 : : /* the generic case, for when the overall rotation is not unraveled */
41 : : #define FG(n) \
42 : : T = T32(R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n); \
43 : : E = D; D = C; C = R32(B,30); B = A; A = T
44 : :
45 : : /* specific cases, for when the overall rotation is unraveled */
46 : : #define FA(n) \
47 : : T = T32(R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n); B = R32(B,30)
48 : :
49 : : #define FB(n) \
50 : : E = T32(R32(T,5) + f##n(A,B,C) + D + *WP++ + CONST##n); A = R32(A,30)
51 : :
52 : : #define FC(n) \
53 : : D = T32(R32(E,5) + f##n(T,A,B) + C + *WP++ + CONST##n); T = R32(T,30)
54 : :
55 : : #define FD(n) \
56 : : C = T32(R32(D,5) + f##n(E,T,A) + B + *WP++ + CONST##n); E = R32(E,30)
57 : :
58 : : #define FE(n) \
59 : : B = T32(R32(C,5) + f##n(D,E,T) + A + *WP++ + CONST##n); D = R32(D,30)
60 : :
61 : : #define FT(n) \
62 : : A = T32(R32(B,5) + f##n(C,D,E) + T + *WP++ + CONST##n); C = R32(C,30)
63 : :
64 : :
65 : : void
66 : 2602686 : sha1_transform(SHA1_INFO *sha1_info)
67 : : {
68 : : int i;
69 : : uint8_t *dp;
70 : : uint32_t T, A, B, C, D, E, W[80], *WP;
71 : :
72 : 2602686 : dp = sha1_info->data;
73 : :
74 : : #undef SWAP_DONE
75 : :
76 : : #if BYTEORDER == 1234
77 : : #define SWAP_DONE
78 [ + + ]: 44245662 : for (i = 0; i < 16; ++i) {
79 : 41642976 : T = *((uint32_t *) dp);
80 : 41642976 : dp += 4;
81 : 41642976 : W[i] =
82 : 83285952 : ((T << 24) & 0xff000000) |
83 : 83285952 : ((T << 8) & 0x00ff0000) |
84 : 83285952 : ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
85 : : }
86 : : #endif
87 : :
88 : : #if BYTEORDER == 4321
89 : : #define SWAP_DONE
90 : : for (i = 0; i < 16; ++i) {
91 : : T = *((uint32_t *) dp);
92 : : dp += 4;
93 : : W[i] = TRUNC32(T);
94 : : }
95 : : #endif
96 : :
97 : : #if BYTEORDER == 12345678
98 : : #define SWAP_DONE
99 : : for (i = 0; i < 16; i += 2) {
100 : : T = *((uint32_t *) dp);
101 : : dp += 8;
102 : : W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
103 : : ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
104 : : T >>= 32;
105 : : W[i+1] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
106 : : ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
107 : : }
108 : : #endif
109 : :
110 : : #if BYTEORDER == 87654321
111 : : #define SWAP_DONE
112 : : for (i = 0; i < 16; i += 2) {
113 : : T = *((uint32_t *) dp);
114 : : dp += 8;
115 : : W[i] = TRUNC32(T >> 32);
116 : : W[i+1] = TRUNC32(T);
117 : : }
118 : : #endif
119 : :
120 : : #ifndef SWAP_DONE
121 : : #define SWAP_DONE
122 : : for (i = 0; i < 16; ++i) {
123 : : T = *((uint32_t *) dp);
124 : : dp += 4;
125 : : W[i] = TRUNC32(T);
126 : : }
127 : : #ifndef WIN32
128 : : #warning Undetermined or unsupported Byte Order... We will try LITTLE_ENDIAN
129 : : #endif
130 : : #endif /* SWAP_DONE */
131 : :
132 [ + + ]: 169174590 : for (i = 16; i < 80; ++i) {
133 : 166571904 : W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
134 : 166571904 : W[i] = R32(W[i], 1);
135 : : }
136 : 2602686 : A = sha1_info->digest[0];
137 : 2602686 : B = sha1_info->digest[1];
138 : 2602686 : C = sha1_info->digest[2];
139 : 2602686 : D = sha1_info->digest[3];
140 : 2602686 : E = sha1_info->digest[4];
141 : 2602686 : WP = W;
142 : : #ifdef UNRAVEL
143 : : FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1);
144 : : FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1);
145 : : FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(2); FT(2);
146 : : FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2);
147 : : FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(3); FB(3);
148 : : FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3);
149 : : FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4);
150 : : FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4);
151 : : sha1_info->digest[0] = T32(sha1_info->digest[0] + E);
152 : : sha1_info->digest[1] = T32(sha1_info->digest[1] + T);
153 : : sha1_info->digest[2] = T32(sha1_info->digest[2] + A);
154 : : sha1_info->digest[3] = T32(sha1_info->digest[3] + B);
155 : : sha1_info->digest[4] = T32(sha1_info->digest[4] + C);
156 : : #else /* !UNRAVEL */
157 : : #ifdef UNROLL_LOOPS
158 : : FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
159 : : FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
160 : : FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
161 : : FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
162 : : FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
163 : : FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
164 : : FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
165 : : FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
166 : : #else /* !UNROLL_LOOPS */
167 [ + + ]: 54656406 : for (i = 0; i < 20; ++i) { FG(1); }
168 [ + + ]: 54656406 : for (i = 20; i < 40; ++i) { FG(2); }
169 [ + + ]: 54656406 : for (i = 40; i < 60; ++i) { FG(3); }
170 [ + + ]: 54656406 : for (i = 60; i < 80; ++i) { FG(4); }
171 : : #endif /* !UNROLL_LOOPS */
172 : 2602686 : sha1_info->digest[0] = T32(sha1_info->digest[0] + A);
173 : 2602686 : sha1_info->digest[1] = T32(sha1_info->digest[1] + B);
174 : 2602686 : sha1_info->digest[2] = T32(sha1_info->digest[2] + C);
175 : 2602686 : sha1_info->digest[3] = T32(sha1_info->digest[3] + D);
176 : 2602686 : sha1_info->digest[4] = T32(sha1_info->digest[4] + E);
177 : : #endif /* !UNRAVEL */
178 : 2602686 : }
179 : :
180 : : /* initialize the SHA digest */
181 : :
182 : : void
183 : 1023262 : sha1_init(SHA1_INFO *sha1_info)
184 : : {
185 : 1023262 : sha1_info->digest[0] = 0x67452301L;
186 : 1023262 : sha1_info->digest[1] = 0xefcdab89L;
187 : 1023262 : sha1_info->digest[2] = 0x98badcfeL;
188 : 1023262 : sha1_info->digest[3] = 0x10325476L;
189 : 1023262 : sha1_info->digest[4] = 0xc3d2e1f0L;
190 : 1023262 : sha1_info->count_lo = 0L;
191 : 1023262 : sha1_info->count_hi = 0L;
192 : 1023262 : sha1_info->local = 0;
193 : 1023262 : }
194 : :
195 : : /* update the SHA digest */
196 : :
197 : : void
198 : 1411964 : sha1_update(SHA1_INFO *sha1_info, uint8_t *buffer, int count)
199 : : {
200 : : int i;
201 : : uint32_t clo;
202 : :
203 : 1411964 : clo = T32(sha1_info->count_lo + ((uint32_t) count << 3));
204 [ - + ]: 1411964 : if (clo < sha1_info->count_lo) {
205 : 0 : ++sha1_info->count_hi;
206 : : }
207 : 1411964 : sha1_info->count_lo = clo;
208 : 1411964 : sha1_info->count_hi += (uint32_t) count >> 29;
209 [ - + ]: 1411964 : if (sha1_info->local) {
210 : 0 : i = SHA1_BLOCKSIZE - sha1_info->local;
211 [ # # ]: 0 : if (i > count) {
212 : 0 : i = count;
213 : : }
214 : 0 : memcpy(((uint8_t *) sha1_info->data) + sha1_info->local, buffer, i);
215 : 0 : count -= i;
216 : 0 : buffer += i;
217 : 0 : sha1_info->local += i;
218 [ # # ]: 0 : if (sha1_info->local == SHA1_BLOCKSIZE) {
219 : 1411964 : sha1_transform(sha1_info);
220 : : } else {
221 : 1411964 : return;
222 : : }
223 : : }
224 [ + + ]: 2877507 : while (count >= SHA1_BLOCKSIZE) {
225 : 1465543 : memcpy(sha1_info->data, buffer, SHA1_BLOCKSIZE);
226 : 1465543 : buffer += SHA1_BLOCKSIZE;
227 : 1465543 : count -= SHA1_BLOCKSIZE;
228 : 1465543 : sha1_transform(sha1_info);
229 : : }
230 : 1411964 : memcpy(sha1_info->data, buffer, count);
231 : 1411964 : sha1_info->local = count;
232 : : }
233 : :
234 : :
235 : : void
236 : 1023262 : sha1_transform_and_copy(unsigned char digest[20], SHA1_INFO *sha1_info)
237 : : {
238 : 1023262 : sha1_transform(sha1_info);
239 : 1023262 : digest[ 0] = (unsigned char) ((sha1_info->digest[0] >> 24) & 0xff);
240 : 1023262 : digest[ 1] = (unsigned char) ((sha1_info->digest[0] >> 16) & 0xff);
241 : 1023262 : digest[ 2] = (unsigned char) ((sha1_info->digest[0] >> 8) & 0xff);
242 : 1023262 : digest[ 3] = (unsigned char) ((sha1_info->digest[0] ) & 0xff);
243 : 1023262 : digest[ 4] = (unsigned char) ((sha1_info->digest[1] >> 24) & 0xff);
244 : 1023262 : digest[ 5] = (unsigned char) ((sha1_info->digest[1] >> 16) & 0xff);
245 : 1023262 : digest[ 6] = (unsigned char) ((sha1_info->digest[1] >> 8) & 0xff);
246 : 1023262 : digest[ 7] = (unsigned char) ((sha1_info->digest[1] ) & 0xff);
247 : 1023262 : digest[ 8] = (unsigned char) ((sha1_info->digest[2] >> 24) & 0xff);
248 : 1023262 : digest[ 9] = (unsigned char) ((sha1_info->digest[2] >> 16) & 0xff);
249 : 1023262 : digest[10] = (unsigned char) ((sha1_info->digest[2] >> 8) & 0xff);
250 : 1023262 : digest[11] = (unsigned char) ((sha1_info->digest[2] ) & 0xff);
251 : 1023262 : digest[12] = (unsigned char) ((sha1_info->digest[3] >> 24) & 0xff);
252 : 1023262 : digest[13] = (unsigned char) ((sha1_info->digest[3] >> 16) & 0xff);
253 : 1023262 : digest[14] = (unsigned char) ((sha1_info->digest[3] >> 8) & 0xff);
254 : 1023262 : digest[15] = (unsigned char) ((sha1_info->digest[3] ) & 0xff);
255 : 1023262 : digest[16] = (unsigned char) ((sha1_info->digest[4] >> 24) & 0xff);
256 : 1023262 : digest[17] = (unsigned char) ((sha1_info->digest[4] >> 16) & 0xff);
257 : 1023262 : digest[18] = (unsigned char) ((sha1_info->digest[4] >> 8) & 0xff);
258 : 1023262 : digest[19] = (unsigned char) ((sha1_info->digest[4] ) & 0xff);
259 : 1023262 : }
260 : :
261 : : /* finish computing the SHA digest */
262 : : void
263 : 1023262 : sha1_final(uint8_t digest[20], SHA1_INFO *sha1_info)
264 : : {
265 : : int count;
266 : : uint32_t lo_bit_count, hi_bit_count;
267 : :
268 : 1023262 : lo_bit_count = sha1_info->count_lo;
269 : 1023262 : hi_bit_count = sha1_info->count_hi;
270 : 1023262 : count = (int) ((lo_bit_count >> 3) & 0x3f);
271 : 1023262 : ((uint8_t *) sha1_info->data)[count++] = 0x80;
272 [ + + ]: 1023262 : if (count > SHA1_BLOCKSIZE - 8) {
273 : 113881 : memset(((uint8_t *) sha1_info->data) + count, 0, SHA1_BLOCKSIZE - count);
274 : 113881 : sha1_transform(sha1_info);
275 : 113881 : memset((uint8_t *) sha1_info->data, 0, SHA1_BLOCKSIZE - 8);
276 : : } else {
277 : 909381 : memset(((uint8_t *) sha1_info->data) + count, 0,
278 : 909381 : SHA1_BLOCKSIZE - 8 - count);
279 : : }
280 : 1023262 : sha1_info->data[56] = (uint8_t)((hi_bit_count >> 24) & 0xff);
281 : 1023262 : sha1_info->data[57] = (uint8_t)((hi_bit_count >> 16) & 0xff);
282 : 1023262 : sha1_info->data[58] = (uint8_t)((hi_bit_count >> 8) & 0xff);
283 : 1023262 : sha1_info->data[59] = (uint8_t)((hi_bit_count >> 0) & 0xff);
284 : 1023262 : sha1_info->data[60] = (uint8_t)((lo_bit_count >> 24) & 0xff);
285 : 1023262 : sha1_info->data[61] = (uint8_t)((lo_bit_count >> 16) & 0xff);
286 : 1023262 : sha1_info->data[62] = (uint8_t)((lo_bit_count >> 8) & 0xff);
287 : 1023262 : sha1_info->data[63] = (uint8_t)((lo_bit_count >> 0) & 0xff);
288 : 1023262 : sha1_transform_and_copy(digest, sha1_info);
289 : 1023262 : }
290 : :
291 : : /***EOF***/
|