1 /*
2
3 GNet API added by David Helder <dhelder@umich.edu> 2000-6-11. All
4 additions and changes placed in the public domain.
5
6 Files originally from: http://www.gxsnmp.org/CVS/gxsnmp/
7
8 */
9 /*
10 * sha.h : Implementation of the Secure Hash Algorithm
11 *
12 * Part of the Python Cryptography Toolkit, version 1.0.0
13 *
14 * Copyright (C) 1995, A.M. Kuchling
15 *
16 * Distribute and use freely; there are no restrictions on further
17 * dissemination and usage except those imposed by the laws of your
18 * country of residence.
19 *
20 */
21
22 /* SHA: NIST's Secure Hash Algorithm */
23
24 /* Based on SHA code originally posted to sci.crypt by Peter Gutmann
25 in message <30ajo5$oe8@ccu2.auckland.ac.nz>.
26 Modified to test for endianness on creation of SHA objects by AMK.
27 Also, the original specification of SHA was found to have a weakness
28 by NSA/NIST. This code implements the fixed version of SHA.
29 */
30
31 /* Here's the first paragraph of Peter Gutmann's posting:
32
33 The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
34 SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
35 what's changed in the new version. The fix is a simple change which involves
36 adding a single rotate in the initial expansion function. It is unknown
37 whether this is an optimal solution to the problem which was discovered in the
38 SHA or whether it's simply a bandaid which fixes the problem with a minimum of
39 effort (for example the reengineering of a great many Capstone chips).
40 */
41
42 #include <glib.h>
43 #include "sha.h"
44
45 #include <sys/types.h>
46 #include <sys/stat.h>
47 #include <fcntl.h>
48
49 #include "config.h" /* needed to define GNET_WIN32 */
50 #ifndef GNET_WIN32
51 #include <unistd.h>
52 #endif
53
54 /* The SHA block size and message digest sizes, in bytes */
55
56 #define SHA_DATASIZE 64
57 #define SHA_DIGESTSIZE 20
58
59 /* The structure for storing SHA info */
60
61 typedef struct {
62 guint32 digest[ 5 ]; /* Message digest */
63 guint32 countLo, countHi; /* 64-bit bit count */
64 guint32 data[ 16 ]; /* SHA data buffer */
65 int Endianness;
66 } SHA_CTX;
67
68 /* Message digest functions */
69
70 static void SHAInit(SHA_CTX* shaInfo);
71 static void SHAUpdate(SHA_CTX* shaInfo, guint8 const* buffer, guint count);
72 static void SHAFinal(char *key, SHA_CTX *shaInfo);
73 static void SHATransform(guint32 *digest, guint32 *data );
74
75 /*
76 * sha.c : Implementation of the Secure Hash Algorithm
77 *
78 * Part of the Python Cryptography Toolkit, version 1.0.0
79 *
80 * Copyright (C) 1995, A.M. Kuchling
81 *
82 * Distribute and use freely; there are no restrictions on further
83 * dissemination and usage except those imposed by the laws of your
84 * country of residence.
85 *
86 */
87
88 /* SHA: NIST's Secure Hash Algorithm */
89
90 /* Based on SHA code originally posted to sci.crypt by Peter Gutmann
91 in message <30ajo5$oe8@ccu2.auckland.ac.nz>.
92 Modified to test for endianness on creation of SHA objects by AMK.
93 Also, the original specification of SHA was found to have a weakness
94 by NSA/NIST. This code implements the fixed version of SHA.
95 */
96
97 /* Here's the first paragraph of Peter Gutmann's posting:
98
99 The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
100 SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
101 what's changed in the new version. The fix is a simple change which involves
102 adding a single rotate in the initial expansion function. It is unknown
103 whether this is an optimal solution to the problem which was discovered in the
104 SHA or whether it's simply a bandaid which fixes the problem with a minimum of
105 effort (for example the reengineering of a great many Capstone chips).
106 */
107
108
109 #include <string.h>
110
111 /* The SHA f()-functions. The f1 and f3 functions can be optimized to
112 save one boolean operation each - thanks to Rich Schroeppel,
113 rcs@cs.arizona.edu for discovering this */
114
115 /*#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) // Rounds 0-19 */
116 #define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */
117 #define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
118 /*#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) // Rounds 40-59 */
119 #define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */
120 #define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
121
122 /* The SHA Mysterious Constants */
123
124 #define K1 0x5A827999L /* Rounds 0-19 */
125 #define K2 0x6ED9EBA1L /* Rounds 20-39 */
126 #define K3 0x8F1BBCDCL /* Rounds 40-59 */
127 #define K4 0xCA62C1D6L /* Rounds 60-79 */
128
129 /* SHA initial values */
130
131 #define h0init 0x67452301L
132 #define h1init 0xEFCDAB89L
133 #define h2init 0x98BADCFEL
134 #define h3init 0x10325476L
135 #define h4init 0xC3D2E1F0L
136
137 /* Note that it may be necessary to add parentheses to these macros if they
138 are to be called with expressions as arguments */
139 /* 32-bit rotate left - kludged with shifts */
140
141 #define ROTL(n,X) ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
142
143 /* The initial expanding function. The hash function is defined over an
144 80-word expanded input array W, where the first 16 are copies of the input
145 data, and the remaining 64 are defined by
146
147 W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
148
149 This implementation generates these values on the fly in a circular
150 buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
151 optimization.
152
153 The updated SHA changes the expanding function by adding a rotate of 1
154 bit. Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
155 for this information */
156
157 #define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
158 W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
159
160
161 /* The prototype SHA sub-round. The fundamental sub-round is:
162
163 a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
164 b' = a;
165 c' = ROTL( 30, b );
166 d' = c;
167 e' = d;
168
169 but this is implemented by unrolling the loop 5 times and renaming the
170 variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
171 This code is then replicated 20 times for each of the 4 functions, using
172 the next 20 values from the W[] array each time */
173
174 #define subRound(a, b, c, d, e, f, k, data) \
175 ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
176
177 /* Initialize the SHA values */
178
179 void
SHAInit(SHA_CTX * shaInfo)180 SHAInit(SHA_CTX * shaInfo )
181 {
182 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
183 shaInfo->Endianness = 1;
184 #else
185 shaInfo->Endianness = 0;
186 #endif
187
188 /* Set the h-vars to their initial values */
189 shaInfo->digest[ 0 ] = h0init;
190 shaInfo->digest[ 1 ] = h1init;
191 shaInfo->digest[ 2 ] = h2init;
192 shaInfo->digest[ 3 ] = h3init;
193 shaInfo->digest[ 4 ] = h4init;
194
195 /* Initialise bit count */
196 shaInfo->countLo = shaInfo->countHi = 0;
197 }
198
199
200 /* Perform the SHA transformation. Note that this code, like MD5, seems to
201 break some optimizing compilers due to the complexity of the expressions
202 and the size of the basic block. It may be necessary to split it into
203 sections, e.g. based on the four subrounds
204
205 Note that this corrupts the shaInfo->data area */
206
207 void
SHATransform(guint32 * digest,guint32 * data)208 SHATransform(guint32 *digest, guint32 *data )
209 {
210 guint32 A, B, C, D, E; /* Local vars */
211 guint32 eData[ 16 ]; /* Expanded data */
212
213 /* Set up first buffer and local data buffer */
214 A = digest[ 0 ];
215 B = digest[ 1 ];
216 C = digest[ 2 ];
217 D = digest[ 3 ];
218 E = digest[ 4 ];
219 g_memmove( eData, data, SHA_DATASIZE );
220
221 /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
222 subRound( A, B, C, D, E, f1, K1, eData[ 0 ] );
223 subRound( E, A, B, C, D, f1, K1, eData[ 1 ] );
224 subRound( D, E, A, B, C, f1, K1, eData[ 2 ] );
225 subRound( C, D, E, A, B, f1, K1, eData[ 3 ] );
226 subRound( B, C, D, E, A, f1, K1, eData[ 4 ] );
227 subRound( A, B, C, D, E, f1, K1, eData[ 5 ] );
228 subRound( E, A, B, C, D, f1, K1, eData[ 6 ] );
229 subRound( D, E, A, B, C, f1, K1, eData[ 7 ] );
230 subRound( C, D, E, A, B, f1, K1, eData[ 8 ] );
231 subRound( B, C, D, E, A, f1, K1, eData[ 9 ] );
232 subRound( A, B, C, D, E, f1, K1, eData[ 10 ] );
233 subRound( E, A, B, C, D, f1, K1, eData[ 11 ] );
234 subRound( D, E, A, B, C, f1, K1, eData[ 12 ] );
235 subRound( C, D, E, A, B, f1, K1, eData[ 13 ] );
236 subRound( B, C, D, E, A, f1, K1, eData[ 14 ] );
237 subRound( A, B, C, D, E, f1, K1, eData[ 15 ] );
238 subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) );
239 subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) );
240 subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) );
241 subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) );
242
243 subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) );
244 subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) );
245 subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) );
246 subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) );
247 subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) );
248 subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) );
249 subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) );
250 subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) );
251 subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) );
252 subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) );
253 subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) );
254 subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) );
255 subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) );
256 subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) );
257 subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) );
258 subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) );
259 subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) );
260 subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) );
261 subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) );
262 subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) );
263
264 subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) );
265 subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) );
266 subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) );
267 subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) );
268 subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) );
269 subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) );
270 subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) );
271 subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) );
272 subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) );
273 subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) );
274 subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) );
275 subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) );
276 subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) );
277 subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) );
278 subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) );
279 subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) );
280 subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) );
281 subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) );
282 subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) );
283 subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) );
284
285 subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) );
286 subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) );
287 subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) );
288 subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) );
289 subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) );
290 subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) );
291 subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) );
292 subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) );
293 subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) );
294 subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) );
295 subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) );
296 subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) );
297 subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) );
298 subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) );
299 subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) );
300 subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) );
301 subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) );
302 subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) );
303 subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) );
304 subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) );
305
306 /* Build message digest */
307 digest[ 0 ] += A;
308 digest[ 1 ] += B;
309 digest[ 2 ] += C;
310 digest[ 3 ] += D;
311 digest[ 4 ] += E;
312 }
313
314 /* When run on a little-endian CPU we need to perform byte reversal on an
315 array of longwords. */
316
317 static void
longReverse(guint32 * buffer,int byteCount,int Endianness)318 longReverse(guint32 *buffer, int byteCount, int Endianness )
319 {
320 guint32 value;
321
322 if (Endianness==1) return;
323 byteCount /= sizeof( guint32 );
324 while( byteCount-- )
325 {
326 value = *buffer;
327 value = ( ( value & 0xFF00FF00L ) >> 8 ) | \
328 ( ( value & 0x00FF00FFL ) << 8 );
329 *buffer++ = ( value << 16 ) | ( value >> 16 );
330 }
331 }
332
333 /* Update SHA for a block of data */
334
335 void
SHAUpdate(SHA_CTX * shaInfo,guint8 const * buffer,guint count)336 SHAUpdate( SHA_CTX *shaInfo, guint8 const *buffer, guint count )
337 {
338 guint32 tmp;
339 unsigned int dataCount;
340
341 /* Update bitcount */
342 tmp = shaInfo->countLo;
343 if ( ( shaInfo->countLo = tmp + ( ( guint32 ) count << 3 ) ) < tmp )
344 shaInfo->countHi++; /* Carry from low to high */
345 shaInfo->countHi += count >> 29;
346
347 /* Get count of bytes already in data */
348 dataCount = ( int ) ( tmp >> 3 ) & 0x3F;
349
350 /* Handle any leading odd-sized chunks */
351 if( dataCount )
352 {
353 guint8 *p = ( guint8 * ) shaInfo->data + dataCount;
354
355 dataCount = SHA_DATASIZE - dataCount;
356 if( count < dataCount )
357 {
358 g_memmove( p, buffer, count );
359 return;
360 }
361 g_memmove( p, buffer, dataCount );
362 longReverse( shaInfo->data, SHA_DATASIZE, shaInfo->Endianness);
363 SHATransform( shaInfo->digest, shaInfo->data );
364 buffer += dataCount;
365 count -= dataCount;
366 }
367
368 /* Process data in SHA_DATASIZE chunks */
369 while( count >= SHA_DATASIZE )
370 {
371 g_memmove( shaInfo->data, buffer, SHA_DATASIZE );
372 longReverse( shaInfo->data, SHA_DATASIZE, shaInfo->Endianness );
373 SHATransform( shaInfo->digest, shaInfo->data );
374 buffer += SHA_DATASIZE;
375 count -= SHA_DATASIZE;
376 }
377
378 /* Handle any remaining bytes of data. */
379 g_memmove( shaInfo->data, buffer, count );
380 }
381
382 /* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern
383 1 0* (64-bit count of bits processed, MSB-first) */
384
385 void
SHAFinal(char * key,SHA_CTX * shaInfo)386 SHAFinal( char *key, SHA_CTX *shaInfo )
387 {
388 int count;
389 guint8 *dataPtr;
390
391 /* Compute number of bytes mod 64 */
392 count = ( int ) shaInfo->countLo;
393 count = ( count >> 3 ) & 0x3F;
394
395 /* Set the first char of padding to 0x80. This is safe since there is
396 always at least one byte free */
397 dataPtr = ( guchar * ) shaInfo->data + count;
398 *dataPtr++ = 0x80;
399
400 /* Bytes of padding needed to make 64 bytes */
401 count = SHA_DATASIZE - 1 - count;
402
403 /* Pad out to 56 mod 64 */
404 if( count < 8 )
405 {
406 /* Two lots of padding: Pad the first block to 64 bytes */
407 memset( dataPtr, 0, count );
408 longReverse( shaInfo->data, SHA_DATASIZE, shaInfo->Endianness );
409 SHATransform( shaInfo->digest, shaInfo->data );
410
411 /* Now fill the next block with 56 bytes */
412 memset( shaInfo->data, 0, SHA_DATASIZE - 8 );
413 }
414 else
415 /* Pad block to 56 bytes */
416 memset( dataPtr, 0, count - 8 );
417
418 /* Append length in bits and transform */
419 shaInfo->data[ 14 ] = shaInfo->countHi;
420 shaInfo->data[ 15 ] = shaInfo->countLo;
421
422 longReverse( shaInfo->data, SHA_DATASIZE - 8, shaInfo->Endianness );
423 SHATransform( shaInfo->digest, shaInfo->data );
424 longReverse(shaInfo->digest, SHA_DIGESTSIZE, shaInfo->Endianness );
425 g_memmove(key, shaInfo->digest, SHA_DIGESTSIZE);
426 }
427
428
429
430 /* ************************************************************ */
431 /* Code below is David Helder's API for GNet */
432
433 struct _GSHA
434 {
435 SHA_CTX ctx;
436 guint8 digest[GNET_SHA_HASH_LENGTH];
437 };
438
439
440 /**
441 * gnet_sha_new:
442 * @buffer: buffer to hash
443 * @length: length of @buffer
444 *
445 * Creates a #GSHA from @buffer.
446 *
447 * Returns: a new #GSHA.
448 *
449 **/
450 GSHA*
gnet_sha_new(const gchar * buffer,guint length)451 gnet_sha_new (const gchar* buffer, guint length)
452 {
453 GSHA* sha;
454
455 sha = g_new0 (GSHA, 1);
456 SHAInit (&sha->ctx);
457 SHAUpdate (&sha->ctx, (const guchar*) buffer, length);
458 SHAFinal ((gpointer) &sha->digest, &sha->ctx);
459
460 return sha;
461 }
462
463
464
465 /**
466 * gnet_sha_new_string:
467 * @str: hexidecimal string
468 *
469 * Createss a #GSHA from @str. @str is a hexidecimal string
470 * representing the digest.
471 *
472 * Returns: a new #GSHA.
473 *
474 **/
475 GSHA*
gnet_sha_new_string(const gchar * str)476 gnet_sha_new_string (const gchar* str)
477 {
478 GSHA* sha;
479 guint i;
480
481 g_return_val_if_fail (str, NULL);
482 g_return_val_if_fail (strlen(str) == (GNET_SHA_HASH_LENGTH * 2), NULL);
483
484 sha = g_new0 (GSHA, 1);
485
486 for (i = 0; i < (GNET_SHA_HASH_LENGTH * 2); ++i)
487 {
488 guint val = 0;
489
490 switch (str[i])
491 {
492 case '0': val = 0; break;
493 case '1': val = 1; break;
494 case '2': val = 2; break;
495 case '3': val = 3; break;
496 case '4': val = 4; break;
497 case '5': val = 5; break;
498 case '6': val = 6; break;
499 case '7': val = 7; break;
500 case '8': val = 8; break;
501 case '9': val = 9; break;
502 case 'A':
503 case 'a': val = 10; break;
504 case 'B':
505 case 'b': val = 11; break;
506 case 'C':
507 case 'c': val = 12; break;
508 case 'D':
509 case 'd': val = 13; break;
510 case 'E':
511 case 'e': val = 14; break;
512 case 'F':
513 case 'f': val = 15; break;
514 default:
515 g_return_val_if_fail (FALSE, NULL);
516 }
517
518 if (i % 2)
519 sha->digest[i / 2] |= val;
520 else
521 sha->digest[i / 2] = val << 4;
522 }
523
524 return sha;
525 }
526
527
528
529 /**
530 * gnet_sha_clone
531 * @sha: a #GSHA
532 *
533 * Copies a #GSHA.
534 *
535 * Returns: a copy of @sha.
536 *
537 **/
538 GSHA*
gnet_sha_clone(const GSHA * sha)539 gnet_sha_clone (const GSHA* sha)
540 {
541 GSHA* sha2;
542
543 g_return_val_if_fail (sha, NULL);
544
545 sha2 = g_new0 (GSHA, 1);
546 sha2->ctx = sha->ctx;
547 memcpy (sha2->digest, sha->digest, sizeof(sha->digest));
548
549 return sha2;
550 }
551
552
553
554 /**
555 * gnet_sha_delete
556 * @sha: a #GSHA
557 *
558 * Deletes a #GSHA.
559 *
560 **/
561 void
gnet_sha_delete(GSHA * sha)562 gnet_sha_delete (GSHA* sha)
563 {
564 g_free (sha);
565 }
566
567
568
569
570
571 /**
572 * gnet_sha_new_incremental
573 *
574 * Creates a #GSHA incrementally. After creating a #GSHA, call
575 * gnet_sha_update() one or more times to hash data. Finally, call
576 * gnet_sha_final() to compute the final hash value.
577 *
578 * Returns: a new #GSHA.
579 *
580 **/
581 GSHA*
gnet_sha_new_incremental(void)582 gnet_sha_new_incremental (void)
583 {
584 GSHA* sha;
585
586 sha = g_new0 (GSHA, 1);
587 SHAInit (&sha->ctx);
588 return sha;
589 }
590
591
592 /**
593 * gnet_sha_update
594 * @sha: a #GSHA
595 * @buffer: buffer to add
596 * @length: length of @buffer
597 *
598 * Updates the hash with @buffer. This may be called several times
599 * on a hash created by gnet_sha_new_incremental() before being
600 * finalized by calling gnet_sha_final().
601 *
602 **/
603 void
gnet_sha_update(GSHA * sha,const gchar * buffer,guint length)604 gnet_sha_update (GSHA* sha, const gchar* buffer, guint length)
605 {
606 g_return_if_fail (sha);
607
608 SHAUpdate (&sha->ctx, (const guchar*) buffer, length);
609 }
610
611
612 /**
613 * gnet_sha_final
614 * @sha: a #GSHA
615 *
616 * Calcuates the final hash value of a #GSHA. This should only be
617 * called on a #GSHA created by gnet_sha_new_incremental().
618 *
619 **/
620 void
gnet_sha_final(GSHA * sha)621 gnet_sha_final (GSHA* sha)
622 {
623 g_return_if_fail (sha);
624
625 SHAFinal ((gpointer) &sha->digest, &sha->ctx);
626 }
627
628
629
630 /* **************************************** */
631
632 /**
633 * gnet_sha_get_digest
634 * @sha: a #GSHA
635 *
636 * Gets the raw SHA digest.
637 *
638 * Returns: a callee-owned buffer containing the SHA hash digest.
639 * The buffer is %GNET_SHA_HASH_LENGTH bytes long.
640 *
641 **/
642 gchar*
gnet_sha_get_digest(const GSHA * sha)643 gnet_sha_get_digest (const GSHA* sha)
644 {
645 g_return_val_if_fail (sha, NULL);
646
647 return (gchar*) sha->digest;
648 }
649
650
651 static const gchar bits2hex[] = "0123456789abcdef";
652
653 /**
654 * gnet_sha_get_string
655 * @sha: a #GSHA
656 *
657 * Get the digest represented a human-readable string.
658 *
659 * Returns: a hexadecimal string representing the digest. The string
660 * is 2 * %GNET_SHA_HASH_LENGTH bytes long and NULL terminated. The
661 * string is caller owned.
662 *
663 **/
664 gchar*
gnet_sha_get_string(const GSHA * sha)665 gnet_sha_get_string (const GSHA* sha)
666 {
667 gchar* str;
668
669 g_return_val_if_fail (sha, NULL);
670
671 str = g_new (gchar, GNET_SHA_HASH_LENGTH * 2 + 1);
672
673 gnet_sha_copy_string (sha, str);
674 str[GNET_SHA_HASH_LENGTH * 2] = '\0';
675
676 return str;
677 }
678
679
680
681
682 /**
683 * gnet_sha_copy_string
684 * @sha: a #GSHA
685 * @buffer: buffer at least 2 * %GNET_SHA_HASH_LENGTH bytes long
686 *
687 * Copies the digest, represented as a string, into @buffer. The
688 * string is not NULL terminated.
689 *
690 **/
691 void
gnet_sha_copy_string(const GSHA * sha,gchar * buffer)692 gnet_sha_copy_string (const GSHA* sha, gchar* buffer)
693 {
694 guint i;
695
696 g_return_if_fail (sha);
697 g_return_if_fail (buffer);
698
699 for (i = 0; i < GNET_SHA_HASH_LENGTH; ++i)
700 {
701 buffer[i * 2] = bits2hex[(sha->digest[i] & 0xF0) >> 4];
702 buffer[(i * 2) + 1] = bits2hex[(sha->digest[i] & 0x0F) ];
703 }
704 }
705
706
707 /**
708 * gnet_sha_equal
709 * @p1: a #GSHA.
710 * @p2: another #GSHA.
711 *
712 * Compares two #GSHA's for equality.
713 *
714 * Returns: TRUE if they are equal; FALSE otherwise.
715 *
716 **/
717 gboolean
gnet_sha_equal(gconstpointer p1,gconstpointer p2)718 gnet_sha_equal (gconstpointer p1, gconstpointer p2)
719 {
720 GSHA* shaa = (GSHA*) p1;
721 GSHA* shab = (GSHA*) p2;
722 guint i;
723
724 for (i = 0; i < GNET_SHA_HASH_LENGTH; ++i)
725 if (shaa->digest[i] != shab->digest[i])
726 return FALSE;
727
728 return TRUE;
729 }
730
731
732 /**
733 * gnet_sha_hash
734 * @p: a #GSHA
735 *
736 * Creates a hash code for a #GMD5 for use with GHashTable. This
737 * hash value is not the same as the MD5 digest.
738 *
739 * Returns: the hash code for @p.
740 *
741 **/
742 guint
gnet_sha_hash(gconstpointer p)743 gnet_sha_hash (gconstpointer p)
744 {
745 const GSHA* sha = (const GSHA*) p;
746 const guint* q;
747
748 g_return_val_if_fail (sha, 0);
749
750 q = (const guint*) sha->digest;
751
752 return (q[0] ^ q[1] ^ q[2] ^ q[3] ^ q[4]);
753 }
754