/src/gpac/src/utils/sha1.c
Line | Count | Source |
1 | | |
2 | | #ifndef _CRT_SECURE_NO_DEPRECATE |
3 | | #define _CRT_SECURE_NO_DEPRECATE 1 |
4 | | #endif |
5 | | |
6 | | #include <gpac/tools.h> |
7 | | |
8 | | #ifndef PUT_UINT32_BE |
9 | 0 | #define PUT_UINT32_BE(n,b,i) \ |
10 | 0 | { \ |
11 | 0 | (b)[(i) ] = (u8) ( (n) >> 24 ); \ |
12 | 0 | (b)[(i) + 1] = (u8) ( (n) >> 16 ); \ |
13 | 0 | (b)[(i) + 2] = (u8) ( (n) >> 8 ); \ |
14 | 0 | (b)[(i) + 3] = (u8) ( (n) ); \ |
15 | 0 | } |
16 | | #endif |
17 | | |
18 | | #if 0 |
19 | | /* |
20 | | * FIPS-180-1 compliant SHA-1 implementation |
21 | | * |
22 | | * Copyright (C) 2003-2006 Christophe Devine |
23 | | * |
24 | | * This library is free software; you can redistribute it and/or |
25 | | * modify it under the terms of the GNU Lesser General Public |
26 | | * License, version 2.1 as published by the Free Software Foundation. |
27 | | * |
28 | | * This library is distributed in the hope that it will be useful, |
29 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
30 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
31 | | * Lesser General Public License for more details. |
32 | | * |
33 | | * You should have received a copy of the GNU Lesser General Public |
34 | | * License along with this library; if not, write to the Free Software |
35 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
36 | | * MA 02110-1301 USA |
37 | | */ |
38 | | /* |
39 | | * The SHA-1 standard was published by NIST in 1993. |
40 | | * |
41 | | * http://www.itl.nist.gov/fipspubs/fip180-1.htm |
42 | | */ |
43 | | |
44 | | |
45 | | struct __sha1_context |
46 | | { |
47 | | u32 total[2]; |
48 | | u32 state[5]; |
49 | | u8 buffer[64]; |
50 | | }; |
51 | | |
52 | | /* |
53 | | * 32-bit integer manipulation macros (big endian) |
54 | | */ |
55 | | #ifndef GET_UINT32_BE |
56 | | #define GET_UINT32_BE(n,b,i) \ |
57 | | { \ |
58 | | (n) = ( (u32) (b)[(i) ] << 24 ) \ |
59 | | | ( (u32) (b)[(i) + 1] << 16 ) \ |
60 | | | ( (u32) (b)[(i) + 2] << 8 ) \ |
61 | | | ( (u32) (b)[(i) + 3] ); \ |
62 | | } |
63 | | #endif |
64 | | |
65 | | /* |
66 | | * SHA-1 context setup |
67 | | */ |
68 | | GF_SHA1Context *gf_sha1_starts() |
69 | | { |
70 | | GF_SHA1Context *ctx; |
71 | | GF_SAFEALLOC(ctx, GF_SHA1Context); |
72 | | if (!ctx) return NULL; |
73 | | ctx->total[0] = 0; |
74 | | ctx->total[1] = 0; |
75 | | |
76 | | ctx->state[0] = 0x67452301; |
77 | | ctx->state[1] = 0xEFCDAB89; |
78 | | ctx->state[2] = 0x98BADCFE; |
79 | | ctx->state[3] = 0x10325476; |
80 | | ctx->state[4] = 0xC3D2E1F0; |
81 | | return ctx; |
82 | | } |
83 | | |
84 | | static void sha1_process(GF_SHA1Context *ctx, u8 data[64] ) |
85 | | { |
86 | | u32 temp, W[16], A, B, C, D, E; |
87 | | |
88 | | GET_UINT32_BE( W[0], data, 0 ); |
89 | | GET_UINT32_BE( W[1], data, 4 ); |
90 | | GET_UINT32_BE( W[2], data, 8 ); |
91 | | GET_UINT32_BE( W[3], data, 12 ); |
92 | | GET_UINT32_BE( W[4], data, 16 ); |
93 | | GET_UINT32_BE( W[5], data, 20 ); |
94 | | GET_UINT32_BE( W[6], data, 24 ); |
95 | | GET_UINT32_BE( W[7], data, 28 ); |
96 | | GET_UINT32_BE( W[8], data, 32 ); |
97 | | GET_UINT32_BE( W[9], data, 36 ); |
98 | | GET_UINT32_BE( W[10], data, 40 ); |
99 | | GET_UINT32_BE( W[11], data, 44 ); |
100 | | GET_UINT32_BE( W[12], data, 48 ); |
101 | | GET_UINT32_BE( W[13], data, 52 ); |
102 | | GET_UINT32_BE( W[14], data, 56 ); |
103 | | GET_UINT32_BE( W[15], data, 60 ); |
104 | | |
105 | | #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) |
106 | | |
107 | | #define R(t) \ |
108 | | ( \ |
109 | | temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ |
110 | | W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ |
111 | | ( W[t & 0x0F] = S(temp,1) ) \ |
112 | | ) |
113 | | |
114 | | #define P(a,b,c,d,e,x) \ |
115 | | { \ |
116 | | e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ |
117 | | } |
118 | | |
119 | | A = ctx->state[0]; |
120 | | B = ctx->state[1]; |
121 | | C = ctx->state[2]; |
122 | | D = ctx->state[3]; |
123 | | E = ctx->state[4]; |
124 | | |
125 | | #define F(x,y,z) (z ^ (x & (y ^ z))) |
126 | | #define K 0x5A827999 |
127 | | |
128 | | P( A, B, C, D, E, W[0] ); |
129 | | P( E, A, B, C, D, W[1] ); |
130 | | P( D, E, A, B, C, W[2] ); |
131 | | P( C, D, E, A, B, W[3] ); |
132 | | P( B, C, D, E, A, W[4] ); |
133 | | P( A, B, C, D, E, W[5] ); |
134 | | P( E, A, B, C, D, W[6] ); |
135 | | P( D, E, A, B, C, W[7] ); |
136 | | P( C, D, E, A, B, W[8] ); |
137 | | P( B, C, D, E, A, W[9] ); |
138 | | P( A, B, C, D, E, W[10] ); |
139 | | P( E, A, B, C, D, W[11] ); |
140 | | P( D, E, A, B, C, W[12] ); |
141 | | P( C, D, E, A, B, W[13] ); |
142 | | P( B, C, D, E, A, W[14] ); |
143 | | P( A, B, C, D, E, W[15] ); |
144 | | P( E, A, B, C, D, R(16) ); |
145 | | P( D, E, A, B, C, R(17) ); |
146 | | P( C, D, E, A, B, R(18) ); |
147 | | P( B, C, D, E, A, R(19) ); |
148 | | |
149 | | #undef K |
150 | | #undef F |
151 | | |
152 | | #define F(x,y,z) (x ^ y ^ z) |
153 | | #define K 0x6ED9EBA1 |
154 | | |
155 | | P( A, B, C, D, E, R(20) ); |
156 | | P( E, A, B, C, D, R(21) ); |
157 | | P( D, E, A, B, C, R(22) ); |
158 | | P( C, D, E, A, B, R(23) ); |
159 | | P( B, C, D, E, A, R(24) ); |
160 | | P( A, B, C, D, E, R(25) ); |
161 | | P( E, A, B, C, D, R(26) ); |
162 | | P( D, E, A, B, C, R(27) ); |
163 | | P( C, D, E, A, B, R(28) ); |
164 | | P( B, C, D, E, A, R(29) ); |
165 | | P( A, B, C, D, E, R(30) ); |
166 | | P( E, A, B, C, D, R(31) ); |
167 | | P( D, E, A, B, C, R(32) ); |
168 | | P( C, D, E, A, B, R(33) ); |
169 | | P( B, C, D, E, A, R(34) ); |
170 | | P( A, B, C, D, E, R(35) ); |
171 | | P( E, A, B, C, D, R(36) ); |
172 | | P( D, E, A, B, C, R(37) ); |
173 | | P( C, D, E, A, B, R(38) ); |
174 | | P( B, C, D, E, A, R(39) ); |
175 | | |
176 | | #undef K |
177 | | #undef F |
178 | | |
179 | | #define F(x,y,z) ((x & y) | (z & (x | y))) |
180 | | #define K 0x8F1BBCDC |
181 | | |
182 | | P( A, B, C, D, E, R(40) ); |
183 | | P( E, A, B, C, D, R(41) ); |
184 | | P( D, E, A, B, C, R(42) ); |
185 | | P( C, D, E, A, B, R(43) ); |
186 | | P( B, C, D, E, A, R(44) ); |
187 | | P( A, B, C, D, E, R(45) ); |
188 | | P( E, A, B, C, D, R(46) ); |
189 | | P( D, E, A, B, C, R(47) ); |
190 | | P( C, D, E, A, B, R(48) ); |
191 | | P( B, C, D, E, A, R(49) ); |
192 | | P( A, B, C, D, E, R(50) ); |
193 | | P( E, A, B, C, D, R(51) ); |
194 | | P( D, E, A, B, C, R(52) ); |
195 | | P( C, D, E, A, B, R(53) ); |
196 | | P( B, C, D, E, A, R(54) ); |
197 | | P( A, B, C, D, E, R(55) ); |
198 | | P( E, A, B, C, D, R(56) ); |
199 | | P( D, E, A, B, C, R(57) ); |
200 | | P( C, D, E, A, B, R(58) ); |
201 | | P( B, C, D, E, A, R(59) ); |
202 | | |
203 | | #undef K |
204 | | #undef F |
205 | | |
206 | | #define F(x,y,z) (x ^ y ^ z) |
207 | | #define K 0xCA62C1D6 |
208 | | |
209 | | P( A, B, C, D, E, R(60) ); |
210 | | P( E, A, B, C, D, R(61) ); |
211 | | P( D, E, A, B, C, R(62) ); |
212 | | P( C, D, E, A, B, R(63) ); |
213 | | P( B, C, D, E, A, R(64) ); |
214 | | P( A, B, C, D, E, R(65) ); |
215 | | P( E, A, B, C, D, R(66) ); |
216 | | P( D, E, A, B, C, R(67) ); |
217 | | P( C, D, E, A, B, R(68) ); |
218 | | P( B, C, D, E, A, R(69) ); |
219 | | P( A, B, C, D, E, R(70) ); |
220 | | P( E, A, B, C, D, R(71) ); |
221 | | P( D, E, A, B, C, R(72) ); |
222 | | P( C, D, E, A, B, R(73) ); |
223 | | P( B, C, D, E, A, R(74) ); |
224 | | P( A, B, C, D, E, R(75) ); |
225 | | P( E, A, B, C, D, R(76) ); |
226 | | P( D, E, A, B, C, R(77) ); |
227 | | P( C, D, E, A, B, R(78) ); |
228 | | P( B, C, D, E, A, R(79) ); |
229 | | |
230 | | #undef K |
231 | | #undef F |
232 | | |
233 | | ctx->state[0] += A; |
234 | | ctx->state[1] += B; |
235 | | ctx->state[2] += C; |
236 | | ctx->state[3] += D; |
237 | | ctx->state[4] += E; |
238 | | } |
239 | | |
240 | | /* |
241 | | * SHA-1 process buffer |
242 | | */ |
243 | | void gf_sha1_update(GF_SHA1Context *ctx, u8 *input, u32 ilen ) |
244 | | { |
245 | | s32 fill; |
246 | | u32 left; |
247 | | |
248 | | if( ilen <= 0 ) |
249 | | return; |
250 | | |
251 | | left = ctx->total[0] & 0x3F; |
252 | | fill = 64 - left; |
253 | | |
254 | | ctx->total[0] += ilen; |
255 | | ctx->total[0] &= 0xFFFFFFFF; |
256 | | |
257 | | if( ctx->total[0] < (u32) ilen ) |
258 | | ctx->total[1]++; |
259 | | |
260 | | if( left && (s32) ilen >= fill ) |
261 | | { |
262 | | memcpy( (void *) (ctx->buffer + left), |
263 | | (void *) input, fill ); |
264 | | sha1_process( ctx, ctx->buffer ); |
265 | | input += fill; |
266 | | ilen -= fill; |
267 | | left = 0; |
268 | | } |
269 | | |
270 | | while( ilen >= 64 ) |
271 | | { |
272 | | sha1_process( ctx, input ); |
273 | | input += 64; |
274 | | ilen -= 64; |
275 | | } |
276 | | |
277 | | if( ilen > 0 ) |
278 | | { |
279 | | memcpy( (void *) (ctx->buffer + left), |
280 | | (void *) input, ilen ); |
281 | | } |
282 | | } |
283 | | |
284 | | static const u8 sha1_padding[64] = |
285 | | { |
286 | | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
287 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
288 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
289 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
290 | | }; |
291 | | |
292 | | /* |
293 | | * SHA-1 final digest |
294 | | */ |
295 | | void gf_sha1_finish(GF_SHA1Context *ctx, u8 output[GF_SHA1_DIGEST_SIZE] ) |
296 | | { |
297 | | u32 last, padn; |
298 | | u32 high, low; |
299 | | u8 msglen[8]; |
300 | | |
301 | | high = ( ctx->total[0] >> 29 ) |
302 | | | ( ctx->total[1] << 3 ); |
303 | | low = ( ctx->total[0] << 3 ); |
304 | | |
305 | | PUT_UINT32_BE( high, msglen, 0 ); |
306 | | PUT_UINT32_BE( low, msglen, 4 ); |
307 | | |
308 | | last = ctx->total[0] & 0x3F; |
309 | | padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); |
310 | | |
311 | | gf_sha1_update( ctx, (u8 *) sha1_padding, padn ); |
312 | | gf_sha1_update( ctx, msglen, 8 ); |
313 | | |
314 | | PUT_UINT32_BE( ctx->state[0], output, 0 ); |
315 | | PUT_UINT32_BE( ctx->state[1], output, 4 ); |
316 | | PUT_UINT32_BE( ctx->state[2], output, 8 ); |
317 | | PUT_UINT32_BE( ctx->state[3], output, 12 ); |
318 | | PUT_UINT32_BE( ctx->state[4], output, 16 ); |
319 | | |
320 | | gf_free(ctx); |
321 | | } |
322 | | #else |
323 | | |
324 | | /* |
325 | | * sha1.c |
326 | | * |
327 | | * Copyright (C) 1998, 2009 |
328 | | * Paul E. Jones <paulej@packetizer.com> |
329 | | * All Rights Reserved |
330 | | * |
331 | | * Freeware Public License (FPL) |
332 | | * |
333 | | * This software is licensed as "freeware." Permission to distribute |
334 | | * this software in source and binary forms, including incorporation |
335 | | * into other products, is hereby granted without a fee. THIS SOFTWARE |
336 | | * IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR IMPLIED WARRANTIES, |
337 | | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY |
338 | | * AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHOR SHALL NOT BE HELD |
339 | | * LIABLE FOR ANY DAMAGES RESULTING FROM THE USE OF THIS SOFTWARE, EITHER |
340 | | * DIRECTLY OR INDIRECTLY, INCLUDING, BUT NOT LIMITED TO, LOSS OF DATA |
341 | | * OR DATA BEING RENDERED INACCURATE. |
342 | | * |
343 | | ***************************************************************************** |
344 | | * $Id: sha1.c 12 2009-06-22 19:34:25Z paulej $ |
345 | | ***************************************************************************** |
346 | | * |
347 | | * Description: |
348 | | * This file implements the Secure Hashing Standard as defined |
349 | | * in FIPS PUB 180-1 published April 17, 1995. |
350 | | * |
351 | | * The Secure Hashing Standard, which uses the Secure Hashing |
352 | | * Algorithm (SHA), produces a 160-bit message digest for a |
353 | | * given data stream. In theory, it is highly improbable that |
354 | | * two messages will produce the same message digest. Therefore, |
355 | | * this algorithm can serve as a means of providing a "fingerprint" |
356 | | * for a message. |
357 | | * |
358 | | * Portability Issues: |
359 | | * SHA-1 is defined in terms of 32-bit "words". This code was |
360 | | * written with the expectation that the processor has at least |
361 | | * a 32-bit machine word size. If the machine word size is larger, |
362 | | * the code should still function properly. One caveat to that |
363 | | * is that the input functions taking characters and character |
364 | | * arrays assume that only 8 bits of information are stored in each |
365 | | * character. |
366 | | * |
367 | | * Caveats: |
368 | | * SHA-1 is designed to work with messages less than 2^64 bits |
369 | | * long. Although SHA-1 allows a message digest to be generated for |
370 | | * messages of any number of bits less than 2^64, this |
371 | | * implementation only works with messages with a length that is a |
372 | | * multiple of the size of an 8-bit character. |
373 | | * |
374 | | */ |
375 | | |
376 | | /* |
377 | | * This structure will hold context information for the hashing |
378 | | * operation |
379 | | */ |
380 | | struct __sha1_context |
381 | | { |
382 | | unsigned Message_Digest[5]; /* Message Digest (output) */ |
383 | | |
384 | | unsigned Length_Low; /* Message length in bits */ |
385 | | unsigned Length_High; /* Message length in bits */ |
386 | | |
387 | | unsigned char Message_Block[64]; /* 512-bit message blocks */ |
388 | | int Message_Block_Index; /* Index into message block array */ |
389 | | |
390 | | int Computed; /* Is the digest computed? */ |
391 | | int Corrupted; /* Is the message digest corruped? */ |
392 | | }; |
393 | | |
394 | | /* |
395 | | * Define the circular shift macro |
396 | | */ |
397 | | #define SHA1CircularShift(bits,word) \ |
398 | 0 | ((((word) << (bits)) & 0xFFFFFFFF) | \ |
399 | 0 | ((word) >> (32-(bits)))) |
400 | | |
401 | | |
402 | | /* |
403 | | * SHA1ProcessMessageBlock |
404 | | * |
405 | | * Description: |
406 | | * This function will process the next 512 bits of the message |
407 | | * stored in the Message_Block array. |
408 | | * |
409 | | * Parameters: |
410 | | * None. |
411 | | * |
412 | | * Returns: |
413 | | * Nothing. |
414 | | * |
415 | | * Comments: |
416 | | * Many of the variable names in the SHAContext, especially the |
417 | | * single character names, were used because those were the names |
418 | | * used in the publication. |
419 | | * |
420 | | * |
421 | | */ |
422 | | void SHA1ProcessMessageBlock(GF_SHA1Context *context) |
423 | 0 | { |
424 | 0 | const unsigned K[] = /* Constants defined in SHA-1 */ |
425 | 0 | { |
426 | 0 | 0x5A827999, |
427 | 0 | 0x6ED9EBA1, |
428 | 0 | 0x8F1BBCDC, |
429 | 0 | 0xCA62C1D6 |
430 | 0 | }; |
431 | 0 | int t; /* Loop counter */ |
432 | 0 | unsigned temp; /* Temporary word value */ |
433 | 0 | unsigned W[80]; /* Word sequence */ |
434 | 0 | unsigned A, B, C, D, E; /* Word buffers */ |
435 | | |
436 | | /* |
437 | | * Initialize the first 16 words in the array W |
438 | | */ |
439 | 0 | for(t = 0; t < 16; t++) |
440 | 0 | { |
441 | 0 | W[t] = ((unsigned) context->Message_Block[t * 4]) << 24; |
442 | 0 | W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16; |
443 | 0 | W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8; |
444 | 0 | W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]); |
445 | 0 | } |
446 | |
|
447 | 0 | for(t = 16; t < 80; t++) |
448 | 0 | { |
449 | 0 | W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); |
450 | 0 | } |
451 | |
|
452 | 0 | A = context->Message_Digest[0]; |
453 | 0 | B = context->Message_Digest[1]; |
454 | 0 | C = context->Message_Digest[2]; |
455 | 0 | D = context->Message_Digest[3]; |
456 | 0 | E = context->Message_Digest[4]; |
457 | |
|
458 | 0 | for(t = 0; t < 20; t++) |
459 | 0 | { |
460 | 0 | temp = SHA1CircularShift(5,A) + |
461 | 0 | ((B & C) | ((~B) & D)) + E + W[t] + K[0]; |
462 | 0 | temp &= 0xFFFFFFFF; |
463 | 0 | E = D; |
464 | 0 | D = C; |
465 | 0 | C = SHA1CircularShift(30,B); |
466 | 0 | B = A; |
467 | 0 | A = temp; |
468 | 0 | } |
469 | |
|
470 | 0 | for(t = 20; t < 40; t++) |
471 | 0 | { |
472 | 0 | temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; |
473 | 0 | temp &= 0xFFFFFFFF; |
474 | 0 | E = D; |
475 | 0 | D = C; |
476 | 0 | C = SHA1CircularShift(30,B); |
477 | 0 | B = A; |
478 | 0 | A = temp; |
479 | 0 | } |
480 | |
|
481 | 0 | for(t = 40; t < 60; t++) |
482 | 0 | { |
483 | 0 | temp = SHA1CircularShift(5,A) + |
484 | 0 | ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; |
485 | 0 | temp &= 0xFFFFFFFF; |
486 | 0 | E = D; |
487 | 0 | D = C; |
488 | 0 | C = SHA1CircularShift(30,B); |
489 | 0 | B = A; |
490 | 0 | A = temp; |
491 | 0 | } |
492 | |
|
493 | 0 | for(t = 60; t < 80; t++) |
494 | 0 | { |
495 | 0 | temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; |
496 | 0 | temp &= 0xFFFFFFFF; |
497 | 0 | E = D; |
498 | 0 | D = C; |
499 | 0 | C = SHA1CircularShift(30,B); |
500 | 0 | B = A; |
501 | 0 | A = temp; |
502 | 0 | } |
503 | |
|
504 | 0 | context->Message_Digest[0] = |
505 | 0 | (context->Message_Digest[0] + A) & 0xFFFFFFFF; |
506 | 0 | context->Message_Digest[1] = |
507 | 0 | (context->Message_Digest[1] + B) & 0xFFFFFFFF; |
508 | 0 | context->Message_Digest[2] = |
509 | 0 | (context->Message_Digest[2] + C) & 0xFFFFFFFF; |
510 | 0 | context->Message_Digest[3] = |
511 | 0 | (context->Message_Digest[3] + D) & 0xFFFFFFFF; |
512 | 0 | context->Message_Digest[4] = |
513 | 0 | (context->Message_Digest[4] + E) & 0xFFFFFFFF; |
514 | |
|
515 | 0 | context->Message_Block_Index = 0; |
516 | 0 | } |
517 | | |
518 | | /* |
519 | | * SHA1PadMessage |
520 | | * |
521 | | * Description: |
522 | | * According to the standard, the message must be padded to an even |
523 | | * 512 bits. The first padding bit must be a '1'. The last 64 |
524 | | * bits represent the length of the original message. All bits in |
525 | | * between should be 0. This function will pad the message |
526 | | * according to those rules by filling the Message_Block array |
527 | | * accordingly. It will also call SHA1ProcessMessageBlock() |
528 | | * appropriately. When it returns, it can be assumed that the |
529 | | * message digest has been computed. |
530 | | * |
531 | | * Parameters: |
532 | | * context: [in/out] |
533 | | * The context to pad |
534 | | * |
535 | | * Returns: |
536 | | * Nothing. |
537 | | * |
538 | | * Comments: |
539 | | * |
540 | | */ |
541 | | static void SHA1PadMessage(GF_SHA1Context *context) |
542 | 0 | { |
543 | | /* |
544 | | * Check to see if the current message block is too small to hold |
545 | | * the initial padding bits and length. If so, we will pad the |
546 | | * block, process it, and then continue padding into a second |
547 | | * block. |
548 | | */ |
549 | 0 | if (context->Message_Block_Index > 55) |
550 | 0 | { |
551 | 0 | context->Message_Block[context->Message_Block_Index++] = 0x80; |
552 | 0 | while(context->Message_Block_Index < 64) |
553 | 0 | { |
554 | 0 | context->Message_Block[context->Message_Block_Index++] = 0; |
555 | 0 | } |
556 | |
|
557 | 0 | SHA1ProcessMessageBlock(context); |
558 | |
|
559 | 0 | while(context->Message_Block_Index < 56) |
560 | 0 | { |
561 | 0 | context->Message_Block[context->Message_Block_Index++] = 0; |
562 | 0 | } |
563 | 0 | } |
564 | 0 | else |
565 | 0 | { |
566 | 0 | context->Message_Block[context->Message_Block_Index++] = 0x80; |
567 | 0 | while(context->Message_Block_Index < 56) |
568 | 0 | { |
569 | 0 | context->Message_Block[context->Message_Block_Index++] = 0; |
570 | 0 | } |
571 | 0 | } |
572 | | |
573 | | /* |
574 | | * Store the message length as the last 8 octets |
575 | | */ |
576 | 0 | context->Message_Block[56] = (context->Length_High >> 24) & 0xFF; |
577 | 0 | context->Message_Block[57] = (context->Length_High >> 16) & 0xFF; |
578 | 0 | context->Message_Block[58] = (context->Length_High >> 8) & 0xFF; |
579 | 0 | context->Message_Block[59] = (context->Length_High) & 0xFF; |
580 | 0 | context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF; |
581 | 0 | context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF; |
582 | 0 | context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF; |
583 | 0 | context->Message_Block[63] = (context->Length_Low) & 0xFF; |
584 | |
|
585 | 0 | SHA1ProcessMessageBlock(context); |
586 | 0 | } |
587 | | /* |
588 | | * SHA1Reset |
589 | | * |
590 | | * Description: |
591 | | * This function will initialize the SHA1Context in preparation |
592 | | * for computing a new message digest. |
593 | | * |
594 | | * Parameters: |
595 | | * context: [in/out] |
596 | | * The context to reset. |
597 | | * |
598 | | * Returns: |
599 | | * Nothing. |
600 | | * |
601 | | * Comments: |
602 | | * |
603 | | */ |
604 | | GF_SHA1Context *gf_sha1_starts() |
605 | 0 | { |
606 | 0 | GF_SHA1Context *context; |
607 | 0 | GF_SAFEALLOC(context, GF_SHA1Context); |
608 | 0 | if (!context) return NULL; |
609 | 0 | context->Length_Low = 0; |
610 | 0 | context->Length_High = 0; |
611 | 0 | context->Message_Block_Index = 0; |
612 | |
|
613 | 0 | context->Message_Digest[0] = 0x67452301; |
614 | 0 | context->Message_Digest[1] = 0xEFCDAB89; |
615 | 0 | context->Message_Digest[2] = 0x98BADCFE; |
616 | 0 | context->Message_Digest[3] = 0x10325476; |
617 | 0 | context->Message_Digest[4] = 0xC3D2E1F0; |
618 | |
|
619 | 0 | context->Computed = 0; |
620 | 0 | context->Corrupted = 0; |
621 | 0 | return context; |
622 | 0 | } |
623 | | |
624 | | void gf_sha1_update(GF_SHA1Context *context, u8 *message_array, u32 length ) |
625 | 0 | { |
626 | 0 | if (!length) |
627 | 0 | { |
628 | 0 | return; |
629 | 0 | } |
630 | | |
631 | 0 | if (context->Computed || context->Corrupted) |
632 | 0 | { |
633 | 0 | context->Corrupted = 1; |
634 | 0 | return; |
635 | 0 | } |
636 | | |
637 | 0 | while(length-- && !context->Corrupted) |
638 | 0 | { |
639 | 0 | context->Message_Block[context->Message_Block_Index++] = |
640 | 0 | (*message_array & 0xFF); |
641 | |
|
642 | 0 | context->Length_Low += 8; |
643 | | /* Force it to 32 bits */ |
644 | 0 | context->Length_Low &= 0xFFFFFFFF; |
645 | 0 | if (context->Length_Low == 0) |
646 | 0 | { |
647 | 0 | context->Length_High++; |
648 | | /* Force it to 32 bits */ |
649 | 0 | context->Length_High &= 0xFFFFFFFF; |
650 | 0 | if (context->Length_High == 0) |
651 | 0 | { |
652 | | /* Message is too long */ |
653 | 0 | context->Corrupted = 1; |
654 | 0 | } |
655 | 0 | } |
656 | |
|
657 | 0 | if (context->Message_Block_Index == 64) |
658 | 0 | { |
659 | 0 | SHA1ProcessMessageBlock(context); |
660 | 0 | } |
661 | |
|
662 | 0 | message_array++; |
663 | 0 | } |
664 | 0 | } |
665 | | void gf_sha1_finish(GF_SHA1Context *context, u8 output[GF_SHA1_DIGEST_SIZE] ) |
666 | 0 | { |
667 | 0 | if (context->Corrupted) |
668 | 0 | { |
669 | 0 | return; |
670 | 0 | } |
671 | | |
672 | 0 | if (!context->Computed) |
673 | 0 | { |
674 | 0 | SHA1PadMessage(context); |
675 | 0 | context->Computed = 1; |
676 | 0 | } |
677 | 0 | PUT_UINT32_BE( context->Message_Digest[0], output, 0 ); |
678 | 0 | PUT_UINT32_BE( context->Message_Digest[1], output, 4 ); |
679 | 0 | PUT_UINT32_BE( context->Message_Digest[2], output, 8 ); |
680 | 0 | PUT_UINT32_BE( context->Message_Digest[3], output, 12 ); |
681 | 0 | PUT_UINT32_BE( context->Message_Digest[4], output, 16 ); |
682 | |
|
683 | 0 | gf_free(context); |
684 | 0 | } |
685 | | |
686 | | #endif |
687 | | |
688 | | /* |
689 | | * Output = SHA-1( file contents ) |
690 | | */ |
691 | | GF_EXPORT |
692 | | GF_Err gf_sha1_file_ptr(FILE *f, u8 output[GF_SHA1_DIGEST_SIZE] ) |
693 | 0 | { |
694 | 0 | u64 pos = gf_ftell(f); |
695 | 0 | size_t n; |
696 | 0 | GF_SHA1Context *ctx; |
697 | 0 | u8 buf[1024]; |
698 | |
|
699 | 0 | ctx = gf_sha1_starts(); |
700 | 0 | gf_fseek(f, 0, SEEK_SET); |
701 | |
|
702 | 0 | while( ( n = gf_fread( buf, sizeof( buf ), f ) ) > 0 ) |
703 | 0 | gf_sha1_update(ctx, buf, (s32) n ); |
704 | |
|
705 | 0 | gf_sha1_finish(ctx, output ); |
706 | |
|
707 | 0 | gf_fseek(f, pos, SEEK_SET); |
708 | 0 | return GF_OK; |
709 | 0 | } |
710 | | |
711 | | GF_EXPORT |
712 | | GF_Err gf_sha1_file( const char *path, u8 output[GF_SHA1_DIGEST_SIZE] ) |
713 | 0 | { |
714 | 0 | FILE *f; |
715 | 0 | GF_Err e; |
716 | |
|
717 | 0 | if (!strncmp(path, "gmem://", 7)) { |
718 | 0 | u32 size; |
719 | 0 | u8 *mem_address; |
720 | 0 | e = gf_blob_get(path, &mem_address, &size, NULL); |
721 | 0 | if (e) return e; |
722 | | |
723 | 0 | gf_sha1_csum(mem_address, size, output); |
724 | 0 | gf_blob_release(path); |
725 | 0 | return GF_OK; |
726 | 0 | } |
727 | | |
728 | 0 | if( ( f = gf_fopen( path, "rb" ) ) == NULL ) |
729 | 0 | return GF_URL_ERROR; |
730 | | |
731 | 0 | e = gf_sha1_file_ptr(f, output); |
732 | 0 | gf_fclose( f ); |
733 | 0 | return e; |
734 | 0 | } |
735 | | |
736 | | /* |
737 | | * Output = SHA-1( input buffer ) |
738 | | */ |
739 | | GF_EXPORT |
740 | | void gf_sha1_csum( u8 *input, u32 ilen, u8 output[GF_SHA1_DIGEST_SIZE] ) |
741 | 0 | { |
742 | 0 | GF_SHA1Context *ctx; |
743 | |
|
744 | 0 | memset(output, 0, sizeof(u8)*GF_SHA1_DIGEST_SIZE); |
745 | 0 | ctx = gf_sha1_starts(); |
746 | 0 | if (ctx) { |
747 | 0 | gf_sha1_update(ctx, input, ilen ); |
748 | 0 | gf_sha1_finish(ctx, output ); |
749 | 0 | } |
750 | 0 | } |
751 | | |
752 | | #if 0 //unused |
753 | | #define GF_SHA1_DIGEST_SIZE_HEXA 41 |
754 | | void gf_sha1_csum_hexa(u8 *buf, u32 buflen, u8 digest[GF_SHA1_DIGEST_SIZE_HEXA]) { |
755 | | u8 tmp[GF_SHA1_DIGEST_SIZE]; |
756 | | gf_sha1_csum (buf, buflen, tmp ); |
757 | | digest[0] = 0; |
758 | | { |
759 | | int i; |
760 | | for ( i=0; i<GF_SHA1_DIGEST_SIZE; i++ ) |
761 | | { |
762 | | char t[3]; |
763 | | t[2] = 0; |
764 | | sprintf ( t, "%02X", tmp[i] ); |
765 | | strcat ( (char*)digest, t ); |
766 | | } |
767 | | } |
768 | | } |
769 | | #endif |
770 | | |
771 | | |