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