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