gvariant test: Remove unused variable
[platform/upstream/glib.git] / glib / gchecksum.c
1 /* gchecksum.h - data hashing functions
2  *
3  * Copyright (C) 2007  Emmanuele Bassi  <ebassi@gnome.org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "glibconfig.h"
26 #include "gchecksum.h"
27 #include "glib.h"
28 #include "glibintl.h"
29
30 #include "galias.h"
31
32 /**
33  * SECTION: checksum
34  * @title: Data Checksums
35  * @short_description: Computes the checksum for data
36  *
37  * GLib provides a generic API for computing checksums (or "digests")
38  * for a sequence of arbitrary bytes, using various hashing algorithms
39  * like MD5, SHA-1 and SHA-256. Checksums are commonly used in various
40  * environments and specifications.
41  *
42  * GLib supports incremental checksums using the GChecksum data
43  * structure, by calling g_checksum_update() as long as there's data
44  * available and then using g_checksum_get_string() or
45  * g_checksum_get_digest() to compute the checksum and return it either
46  * as a string in hexadecimal form, or as a raw sequence of bytes. To
47  * compute the checksum for binary blobs and NUL-terminated strings in
48  * one go, use the convenience functions g_compute_checksum_for_data()
49  * and g_compute_checksum_for_string(), respectively.
50  *
51  * Support for checksums has been added in GLib 2.16
52  **/
53
54 #define IS_VALID_TYPE(type)     ((type) >= G_CHECKSUM_MD5 && (type) <= G_CHECKSUM_SHA256)
55
56 /* The fact that these are lower case characters is part of the ABI */
57 static const gchar hex_digits[] = "0123456789abcdef";
58
59 #define MD5_DATASIZE    64
60 #define MD5_DIGEST_LEN  16
61
62 typedef struct
63 {
64   guint32 buf[4];
65   guint32 bits[2];
66   
67   guchar data[MD5_DATASIZE];
68
69   guchar digest[MD5_DIGEST_LEN];
70 } Md5sum;
71
72 #define SHA1_DATASIZE   64
73 #define SHA1_DIGEST_LEN 20
74
75 typedef struct
76 {
77   guint32 buf[5];
78   guint32 bits[2];
79
80   /* we pack 64 unsigned chars into 16 32-bit unsigned integers */
81   guint32 data[16];
82
83   guchar digest[SHA1_DIGEST_LEN];
84 } Sha1sum;
85
86 #define SHA256_DATASIZE         64
87 #define SHA256_DIGEST_LEN       32
88
89 typedef struct
90 {
91   guint32 buf[8];
92   guint32 bits[2];
93
94   guint8 data[SHA256_DATASIZE];
95
96   guchar digest[SHA256_DIGEST_LEN];
97 } Sha256sum;
98
99 struct _GChecksum
100 {
101   GChecksumType type;
102
103   gchar *digest_str;
104
105   union {
106     Md5sum md5;
107     Sha1sum sha1;
108     Sha256sum sha256;
109   } sum;
110 };
111
112 /* we need different byte swapping functions because MD5 expects buffers
113  * to be little-endian, while SHA1 and SHA256 expect them in big-endian
114  * form.
115  */
116
117 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
118 #define md5_byte_reverse(buffer,length)
119 #else
120 /* assume that the passed buffer is integer aligned */
121 static inline void
122 md5_byte_reverse (guchar *buffer,
123                   gulong  length)
124 {
125   guint32 bit;
126
127   do
128     {
129       bit = (guint32) ((unsigned) buffer[3] << 8 | buffer[2]) << 16 |
130                       ((unsigned) buffer[1] << 8 | buffer[0]);
131       * (guint32 *) buffer = bit;
132       buffer += 4;
133     }
134   while (--length);
135 }
136 #endif /* G_BYTE_ORDER == G_LITTLE_ENDIAN */
137
138 #if G_BYTE_ORDER == G_BIG_ENDIAN
139 #define sha_byte_reverse(buffer,length)
140 #else
141 static inline void
142 sha_byte_reverse (guint32 *buffer,
143                   gint     length)
144 {
145   length /= sizeof (guint32);
146   while (length--)
147     {
148       *buffer = GUINT32_SWAP_LE_BE (*buffer);
149       ++buffer;
150     }
151 }
152 #endif /* G_BYTE_ORDER == G_BIG_ENDIAN */
153
154 static gchar *
155 digest_to_string (guint8 *digest,
156                   gsize   digest_len)
157 {
158   gint len = digest_len * 2;
159   gint i;
160   gchar *retval;
161
162   retval = g_new (gchar, len + 1);
163
164   for (i = 0; i < digest_len; i++)
165     {
166       guint8 byte = digest[i];
167
168       retval[2 * i] = hex_digits[byte >> 4];
169       retval[2 * i + 1] = hex_digits[byte & 0xf];
170     }
171
172   retval[len] = 0;
173
174   return retval;
175 }
176
177 /*
178  * MD5 Checksum
179  */
180
181 /* This MD5 digest computation is based on the equivalent code
182  * written by Colin Plumb. It came with this notice:
183  *
184  * This code implements the MD5 message-digest algorithm.
185  * The algorithm is due to Ron Rivest.  This code was
186  * written by Colin Plumb in 1993, no copyright is claimed.
187  * This code is in the public domain; do with it what you wish.
188  *
189  * Equivalent code is available from RSA Data Security, Inc.
190  * This code has been tested against that, and is equivalent,
191  * except that you don't need to include two pages of legalese
192  * with every copy.
193  */
194
195 static void
196 md5_sum_init (Md5sum *md5)
197 {
198   /* arbitrary constants */
199   md5->buf[0] = 0x67452301;
200   md5->buf[1] = 0xefcdab89;
201   md5->buf[2] = 0x98badcfe;
202   md5->buf[3] = 0x10325476;
203
204   md5->bits[0] = md5->bits[1] = 0;
205 }
206
207 /*
208  * The core of the MD5 algorithm, this alters an existing MD5 hash to
209  * reflect the addition of 16 longwords of new data.  md5_sum_update()
210  * blocks the data and converts bytes into longwords for this routine.
211  */
212 static void 
213 md5_transform (guint32       buf[4],
214                guint32 const in[16])
215 {
216   register guint32 a, b, c, d;
217
218 /* The four core functions - F1 is optimized somewhat */
219 #define F1(x, y, z)     (z ^ (x & (y ^ z)))
220 #define F2(x, y, z)     F1 (z, x, y)
221 #define F3(x, y, z)     (x ^ y ^ z)
222 #define F4(x, y, z)     (y ^ (x | ~z))
223
224 /* This is the central step in the MD5 algorithm. */
225 #define md5_step(f, w, x, y, z, data, s) \
226         ( w += f (x, y, z) + data,  w = w << s | w >> (32 - s),  w += x )
227
228   a = buf[0];
229   b = buf[1];
230   c = buf[2];
231   d = buf[3];
232
233   md5_step (F1, a, b, c, d, in[0]  + 0xd76aa478,  7);
234   md5_step (F1, d, a, b, c, in[1]  + 0xe8c7b756, 12);
235   md5_step (F1, c, d, a, b, in[2]  + 0x242070db, 17);
236   md5_step (F1, b, c, d, a, in[3]  + 0xc1bdceee, 22);
237   md5_step (F1, a, b, c, d, in[4]  + 0xf57c0faf,  7);
238   md5_step (F1, d, a, b, c, in[5]  + 0x4787c62a, 12);
239   md5_step (F1, c, d, a, b, in[6]  + 0xa8304613, 17);
240   md5_step (F1, b, c, d, a, in[7]  + 0xfd469501, 22);
241   md5_step (F1, a, b, c, d, in[8]  + 0x698098d8,  7);
242   md5_step (F1, d, a, b, c, in[9]  + 0x8b44f7af, 12);
243   md5_step (F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
244   md5_step (F1, b, c, d, a, in[11] + 0x895cd7be, 22);
245   md5_step (F1, a, b, c, d, in[12] + 0x6b901122,  7);
246   md5_step (F1, d, a, b, c, in[13] + 0xfd987193, 12);
247   md5_step (F1, c, d, a, b, in[14] + 0xa679438e, 17);
248   md5_step (F1, b, c, d, a, in[15] + 0x49b40821, 22);
249         
250   md5_step (F2, a, b, c, d, in[1]  + 0xf61e2562,  5);
251   md5_step (F2, d, a, b, c, in[6]  + 0xc040b340,  9);
252   md5_step (F2, c, d, a, b, in[11] + 0x265e5a51, 14);
253   md5_step (F2, b, c, d, a, in[0]  + 0xe9b6c7aa, 20);
254   md5_step (F2, a, b, c, d, in[5]  + 0xd62f105d,  5);
255   md5_step (F2, d, a, b, c, in[10] + 0x02441453,  9);
256   md5_step (F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
257   md5_step (F2, b, c, d, a, in[4]  + 0xe7d3fbc8, 20);
258   md5_step (F2, a, b, c, d, in[9]  + 0x21e1cde6,  5);
259   md5_step (F2, d, a, b, c, in[14] + 0xc33707d6,  9);
260   md5_step (F2, c, d, a, b, in[3]  + 0xf4d50d87, 14);
261   md5_step (F2, b, c, d, a, in[8]  + 0x455a14ed, 20);
262   md5_step (F2, a, b, c, d, in[13] + 0xa9e3e905,  5);
263   md5_step (F2, d, a, b, c, in[2]  + 0xfcefa3f8,  9);
264   md5_step (F2, c, d, a, b, in[7]  + 0x676f02d9, 14);
265   md5_step (F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
266
267   md5_step (F3, a, b, c, d, in[5]  + 0xfffa3942,  4);
268   md5_step (F3, d, a, b, c, in[8]  + 0x8771f681, 11);
269   md5_step (F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
270   md5_step (F3, b, c, d, a, in[14] + 0xfde5380c, 23);
271   md5_step (F3, a, b, c, d, in[1]  + 0xa4beea44,  4);
272   md5_step (F3, d, a, b, c, in[4]  + 0x4bdecfa9, 11);
273   md5_step (F3, c, d, a, b, in[7]  + 0xf6bb4b60, 16);
274   md5_step (F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
275   md5_step (F3, a, b, c, d, in[13] + 0x289b7ec6,  4);
276   md5_step (F3, d, a, b, c, in[0]  + 0xeaa127fa, 11);
277   md5_step (F3, c, d, a, b, in[3]  + 0xd4ef3085, 16);
278   md5_step (F3, b, c, d, a, in[6]  + 0x04881d05, 23);
279   md5_step (F3, a, b, c, d, in[9]  + 0xd9d4d039,  4);
280   md5_step (F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
281   md5_step (F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
282   md5_step (F3, b, c, d, a, in[2]  + 0xc4ac5665, 23);
283
284   md5_step (F4, a, b, c, d, in[0]  + 0xf4292244,  6);
285   md5_step (F4, d, a, b, c, in[7]  + 0x432aff97, 10);
286   md5_step (F4, c, d, a, b, in[14] + 0xab9423a7, 15);
287   md5_step (F4, b, c, d, a, in[5]  + 0xfc93a039, 21);
288   md5_step (F4, a, b, c, d, in[12] + 0x655b59c3,  6);
289   md5_step (F4, d, a, b, c, in[3]  + 0x8f0ccc92, 10);
290   md5_step (F4, c, d, a, b, in[10] + 0xffeff47d, 15);
291   md5_step (F4, b, c, d, a, in[1]  + 0x85845dd1, 21);
292   md5_step (F4, a, b, c, d, in[8]  + 0x6fa87e4f,  6);
293   md5_step (F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
294   md5_step (F4, c, d, a, b, in[6]  + 0xa3014314, 15);
295   md5_step (F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
296   md5_step (F4, a, b, c, d, in[4]  + 0xf7537e82,  6);
297   md5_step (F4, d, a, b, c, in[11] + 0xbd3af235, 10);
298   md5_step (F4, c, d, a, b, in[2]  + 0x2ad7d2bb, 15);
299   md5_step (F4, b, c, d, a, in[9]  + 0xeb86d391, 21);
300
301   buf[0] += a;
302   buf[1] += b;
303   buf[2] += c;
304   buf[3] += d;
305
306 #undef F1
307 #undef F2
308 #undef F3
309 #undef F4
310 #undef md5_step
311 }
312
313 static void
314 md5_sum_update (Md5sum       *md5,
315                 const guchar *data,
316                 gsize         length)
317 {
318   guint32 bit;
319
320   bit = md5->bits[0];
321   md5->bits[0] = bit + ((guint32) length << 3);
322
323   /* carry from low to high */
324   if (md5->bits[0] < bit)
325     md5->bits[1] += 1;
326
327   md5->bits[1] += length >> 29;
328
329   /* bytes already in Md5sum->data */
330   bit = (bit >> 3) & 0x3f;
331
332   /* handle any leading odd-sized chunks */
333   if (bit)
334     {
335       guchar *p = (guchar *) md5->data + bit;
336
337       bit = MD5_DATASIZE - bit;
338       if (length < bit)
339         {
340           memcpy (p, data, length);
341           return;
342         }
343
344       memcpy (p, data, bit);
345       
346       md5_byte_reverse (md5->data, 16);
347       md5_transform (md5->buf, (guint32 *) md5->data);
348
349       data += bit;
350       length -= bit;
351     }
352
353   /* process data in 64-byte chunks */
354   while (length >= MD5_DATASIZE)
355     {
356       memcpy (md5->data, data, MD5_DATASIZE);
357       
358       md5_byte_reverse (md5->data, 16);
359       md5_transform (md5->buf, (guint32 *) md5->data);
360
361       data += MD5_DATASIZE;
362       length -= MD5_DATASIZE;
363     }
364
365   /* handle any remaining bytes of data */
366   memcpy (md5->data, data, length);
367 }
368
369 /* closes a checksum */
370 static void
371 md5_sum_close (Md5sum *md5)
372 {
373   guint count;
374   guchar *p;
375
376   /* Compute number of bytes mod 64 */
377   count = (md5->bits[0] >> 3) & 0x3F;
378
379   /* Set the first char of padding to 0x80.
380    * This is safe since there is always at least one byte free
381    */
382   p = md5->data + count;
383   *p++ = 0x80;
384
385   /* Bytes of padding needed to make 64 bytes */
386   count = MD5_DATASIZE - 1 - count;
387
388   /* Pad out to 56 mod 64 */
389   if (count < 8)
390     {
391       /* Two lots of padding:  Pad the first block to 64 bytes */
392       memset (p, 0, count);
393       
394       md5_byte_reverse (md5->data, 16);
395       md5_transform (md5->buf, (guint32 *) md5->data);
396
397       /* Now fill the next block with 56 bytes */
398       memset (md5->data, 0, MD5_DATASIZE - 8);
399     }
400   else
401     {
402       /* Pad block to 56 bytes */
403       memset (p, 0, count - 8);
404     }
405
406   md5_byte_reverse (md5->data, 14);
407
408   /* Append length in bits and transform */
409   ((guint32 *) md5->data)[14] = md5->bits[0];
410   ((guint32 *) md5->data)[15] = md5->bits[1];
411
412   md5_transform (md5->buf, (guint32 *) md5->data);
413   md5_byte_reverse ((guchar *) md5->buf, 4);
414   
415   memcpy (md5->digest, md5->buf, 16);
416
417   /* Reset buffers in case they contain sensitive data */
418   memset (md5->buf, 0, sizeof (md5->buf));
419   memset (md5->data, 0, sizeof (md5->data));
420 }
421
422 static gchar *
423 md5_sum_to_string (Md5sum *md5)
424 {
425   return digest_to_string (md5->digest, MD5_DIGEST_LEN);
426 }
427
428 static void
429 md5_sum_digest (Md5sum *md5,
430                 guint8 *digest)
431 {
432   gint i;
433
434   for (i = 0; i < MD5_DIGEST_LEN; i++)
435     digest[i] = md5->digest[i];
436 }
437
438 /*
439  * SHA-1 Checksum
440  */
441
442 /* The following implementation comes from D-Bus dbus-sha.c. I've changed
443  * it to use GLib types and to work more like the MD5 implementation above.
444  * I left the comments to have an history of this code.
445  *      -- Emmanuele Bassi, ebassi@gnome.org
446  */
447
448 /* The following comments have the history of where this code
449  * comes from. I actually copied it from GNet in GNOME CVS.
450  * - hp@redhat.com
451  */
452
453 /*
454  *  sha.h : Implementation of the Secure Hash Algorithm
455  *
456  * Part of the Python Cryptography Toolkit, version 1.0.0
457  *
458  * Copyright (C) 1995, A.M. Kuchling
459  *
460  * Distribute and use freely; there are no restrictions on further
461  * dissemination and usage except those imposed by the laws of your
462  * country of residence.
463  *
464  */
465
466 /* SHA: NIST's Secure Hash Algorithm */
467
468 /* Based on SHA code originally posted to sci.crypt by Peter Gutmann
469    in message <30ajo5$oe8@ccu2.auckland.ac.nz>.
470    Modified to test for endianness on creation of SHA objects by AMK.
471    Also, the original specification of SHA was found to have a weakness
472    by NSA/NIST.  This code implements the fixed version of SHA.
473 */
474
475 /* Here's the first paragraph of Peter Gutmann's posting:
476
477 The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
478 SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
479 what's changed in the new version.  The fix is a simple change which involves
480 adding a single rotate in the initial expansion function.  It is unknown
481 whether this is an optimal solution to the problem which was discovered in the
482 SHA or whether it's simply a bandaid which fixes the problem with a minimum of
483 effort (for example the reengineering of a great many Capstone chips).
484 */
485
486 static void
487 sha1_sum_init (Sha1sum *sha1)
488 {
489   /* initialize constants */
490   sha1->buf[0] = 0x67452301L;
491   sha1->buf[1] = 0xEFCDAB89L;
492   sha1->buf[2] = 0x98BADCFEL;
493   sha1->buf[3] = 0x10325476L;
494   sha1->buf[4] = 0xC3D2E1F0L;
495
496   /* initialize bits */
497   sha1->bits[0] = sha1->bits[1] = 0;
498 }
499
500 /* The SHA f()-functions. */
501
502 #define f1(x,y,z)       (z ^ (x & (y ^ z)))             /* Rounds  0-19 */
503 #define f2(x,y,z)       (x ^ y ^ z)                     /* Rounds 20-39 */
504 #define f3(x,y,z)       (( x & y) | (z & (x | y)))      /* Rounds 40-59 */
505 #define f4(x,y,z)       (x ^ y ^ z)                     /* Rounds 60-79 */
506
507 /* The SHA Mysterious Constants */
508 #define K1  0x5A827999L                                 /* Rounds  0-19 */
509 #define K2  0x6ED9EBA1L                                 /* Rounds 20-39 */
510 #define K3  0x8F1BBCDCL                                 /* Rounds 40-59 */
511 #define K4  0xCA62C1D6L                                 /* Rounds 60-79 */
512
513 /* 32-bit rotate left - kludged with shifts */
514 #define ROTL(n,X) (((X) << n ) | ((X) >> (32 - n)))
515
516 /* The initial expanding function.  The hash function is defined over an
517    80-word expanded input array W, where the first 16 are copies of the input
518    data, and the remaining 64 are defined by
519
520         W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
521
522    This implementation generates these values on the fly in a circular
523    buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
524    optimization.
525
526    The updated SHA changes the expanding function by adding a rotate of 1
527    bit.  Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
528    for this information */
529
530 #define expand(W,i) (W[ i & 15 ] = ROTL (1, (W[ i       & 15] ^ \
531                                              W[(i - 14) & 15] ^ \
532                                              W[(i -  8) & 15] ^ \
533                                              W[(i -  3) & 15])))
534
535
536 /* The prototype SHA sub-round.  The fundamental sub-round is:
537
538         a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
539         b' = a;
540         c' = ROTL( 30, b );
541         d' = c;
542         e' = d;
543
544    but this is implemented by unrolling the loop 5 times and renaming the
545    variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
546    This code is then replicated 20 times for each of the 4 functions, using
547    the next 20 values from the W[] array each time */
548
549 #define subRound(a, b, c, d, e, f, k, data) \
550    (e += ROTL (5, a) + f(b, c, d) + k + data, b = ROTL (30, b))
551
552 static void
553 sha1_transform (guint32  buf[5],
554                 guint32  in[16])
555 {
556   guint32 A, B, C, D, E;
557
558   A = buf[0];
559   B = buf[1];
560   C = buf[2];
561   D = buf[3];
562   E = buf[4];
563
564   /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
565   subRound (A, B, C, D, E, f1, K1, in[0]);
566   subRound (E, A, B, C, D, f1, K1, in[1]);
567   subRound (D, E, A, B, C, f1, K1, in[2]);
568   subRound (C, D, E, A, B, f1, K1, in[3]);
569   subRound (B, C, D, E, A, f1, K1, in[4]);
570   subRound (A, B, C, D, E, f1, K1, in[5]);
571   subRound (E, A, B, C, D, f1, K1, in[6]);
572   subRound (D, E, A, B, C, f1, K1, in[7]);
573   subRound (C, D, E, A, B, f1, K1, in[8]);
574   subRound (B, C, D, E, A, f1, K1, in[9]);
575   subRound (A, B, C, D, E, f1, K1, in[10]);
576   subRound (E, A, B, C, D, f1, K1, in[11]);
577   subRound (D, E, A, B, C, f1, K1, in[12]);
578   subRound (C, D, E, A, B, f1, K1, in[13]);
579   subRound (B, C, D, E, A, f1, K1, in[14]);
580   subRound (A, B, C, D, E, f1, K1, in[15]);
581   subRound (E, A, B, C, D, f1, K1, expand (in, 16));
582   subRound (D, E, A, B, C, f1, K1, expand (in, 17));
583   subRound (C, D, E, A, B, f1, K1, expand (in, 18));
584   subRound (B, C, D, E, A, f1, K1, expand (in, 19));
585
586   subRound (A, B, C, D, E, f2, K2, expand (in, 20));
587   subRound (E, A, B, C, D, f2, K2, expand (in, 21));
588   subRound (D, E, A, B, C, f2, K2, expand (in, 22));
589   subRound (C, D, E, A, B, f2, K2, expand (in, 23));
590   subRound (B, C, D, E, A, f2, K2, expand (in, 24));
591   subRound (A, B, C, D, E, f2, K2, expand (in, 25));
592   subRound (E, A, B, C, D, f2, K2, expand (in, 26));
593   subRound (D, E, A, B, C, f2, K2, expand (in, 27));
594   subRound (C, D, E, A, B, f2, K2, expand (in, 28));
595   subRound (B, C, D, E, A, f2, K2, expand (in, 29));
596   subRound (A, B, C, D, E, f2, K2, expand (in, 30));
597   subRound (E, A, B, C, D, f2, K2, expand (in, 31));
598   subRound (D, E, A, B, C, f2, K2, expand (in, 32));
599   subRound (C, D, E, A, B, f2, K2, expand (in, 33));
600   subRound (B, C, D, E, A, f2, K2, expand (in, 34));
601   subRound (A, B, C, D, E, f2, K2, expand (in, 35));
602   subRound (E, A, B, C, D, f2, K2, expand (in, 36));
603   subRound (D, E, A, B, C, f2, K2, expand (in, 37));
604   subRound (C, D, E, A, B, f2, K2, expand (in, 38));
605   subRound (B, C, D, E, A, f2, K2, expand (in, 39));
606   
607   subRound (A, B, C, D, E, f3, K3, expand (in, 40));
608   subRound (E, A, B, C, D, f3, K3, expand (in, 41));
609   subRound (D, E, A, B, C, f3, K3, expand (in, 42));
610   subRound (C, D, E, A, B, f3, K3, expand (in, 43));
611   subRound (B, C, D, E, A, f3, K3, expand (in, 44));
612   subRound (A, B, C, D, E, f3, K3, expand (in, 45));
613   subRound (E, A, B, C, D, f3, K3, expand (in, 46));
614   subRound (D, E, A, B, C, f3, K3, expand (in, 47));
615   subRound (C, D, E, A, B, f3, K3, expand (in, 48));
616   subRound (B, C, D, E, A, f3, K3, expand (in, 49));
617   subRound (A, B, C, D, E, f3, K3, expand (in, 50));
618   subRound (E, A, B, C, D, f3, K3, expand (in, 51));
619   subRound (D, E, A, B, C, f3, K3, expand (in, 52));
620   subRound (C, D, E, A, B, f3, K3, expand (in, 53));
621   subRound (B, C, D, E, A, f3, K3, expand (in, 54));
622   subRound (A, B, C, D, E, f3, K3, expand (in, 55));
623   subRound (E, A, B, C, D, f3, K3, expand (in, 56));
624   subRound (D, E, A, B, C, f3, K3, expand (in, 57));
625   subRound (C, D, E, A, B, f3, K3, expand (in, 58));
626   subRound (B, C, D, E, A, f3, K3, expand (in, 59));
627
628   subRound (A, B, C, D, E, f4, K4, expand (in, 60));
629   subRound (E, A, B, C, D, f4, K4, expand (in, 61));
630   subRound (D, E, A, B, C, f4, K4, expand (in, 62));
631   subRound (C, D, E, A, B, f4, K4, expand (in, 63));
632   subRound (B, C, D, E, A, f4, K4, expand (in, 64));
633   subRound (A, B, C, D, E, f4, K4, expand (in, 65));
634   subRound (E, A, B, C, D, f4, K4, expand (in, 66));
635   subRound (D, E, A, B, C, f4, K4, expand (in, 67));
636   subRound (C, D, E, A, B, f4, K4, expand (in, 68));
637   subRound (B, C, D, E, A, f4, K4, expand (in, 69));
638   subRound (A, B, C, D, E, f4, K4, expand (in, 70));
639   subRound (E, A, B, C, D, f4, K4, expand (in, 71));
640   subRound (D, E, A, B, C, f4, K4, expand (in, 72));
641   subRound (C, D, E, A, B, f4, K4, expand (in, 73));
642   subRound (B, C, D, E, A, f4, K4, expand (in, 74));
643   subRound (A, B, C, D, E, f4, K4, expand (in, 75));
644   subRound (E, A, B, C, D, f4, K4, expand (in, 76));
645   subRound (D, E, A, B, C, f4, K4, expand (in, 77));
646   subRound (C, D, E, A, B, f4, K4, expand (in, 78));
647   subRound (B, C, D, E, A, f4, K4, expand (in, 79));
648
649   /* Build message digest */
650   buf[0] += A;
651   buf[1] += B;
652   buf[2] += C;
653   buf[3] += D;
654   buf[4] += E;
655 }
656
657 #undef K1
658 #undef K2
659 #undef K3
660 #undef K4
661 #undef f1
662 #undef f2
663 #undef f3
664 #undef f4
665 #undef ROTL
666 #undef expand
667 #undef subRound
668
669 static void
670 sha1_sum_update (Sha1sum      *sha1,
671                  const guchar *buffer,
672                  gsize         count)
673 {
674   guint32 tmp;
675   guint dataCount;
676
677   /* Update bitcount */
678   tmp = sha1->bits[0];
679   if ((sha1->bits[0] = tmp + ((guint32) count << 3) ) < tmp)
680     sha1->bits[1] += 1;             /* Carry from low to high */
681   sha1->bits[1] += count >> 29;
682
683   /* Get count of bytes already in data */
684   dataCount = (guint) (tmp >> 3) & 0x3F;
685
686   /* Handle any leading odd-sized chunks */
687   if (dataCount)
688     {
689       guchar *p = (guchar *) sha1->data + dataCount;
690
691       dataCount = SHA1_DATASIZE - dataCount;
692       if (count < dataCount)
693         {
694           memcpy (p, buffer, count);
695           return;
696         }
697       
698       memcpy (p, buffer, dataCount);
699
700       sha_byte_reverse (sha1->data, SHA1_DATASIZE);
701       sha1_transform (sha1->buf, sha1->data);
702
703       buffer += dataCount;
704       count -= dataCount;
705     }
706
707   /* Process data in SHA1_DATASIZE chunks */
708   while (count >= SHA1_DATASIZE)
709     {
710       memcpy (sha1->data, buffer, SHA1_DATASIZE);
711       
712       sha_byte_reverse (sha1->data, SHA1_DATASIZE);
713       sha1_transform (sha1->buf, sha1->data);
714
715       buffer += SHA1_DATASIZE;
716       count -= SHA1_DATASIZE;
717     }
718
719   /* Handle any remaining bytes of data. */
720   memcpy (sha1->data, buffer, count);
721 }
722
723 /* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern
724    1 0* (64-bit count of bits processed, MSB-first) */
725 static void
726 sha1_sum_close (Sha1sum *sha1)
727 {
728   gint count;
729   guchar *data_p;
730
731   /* Compute number of bytes mod 64 */
732   count = (gint) ((sha1->bits[0] >> 3) & 0x3f);
733
734   /* Set the first char of padding to 0x80.  This is safe since there is
735      always at least one byte free */
736   data_p = (guchar *) sha1->data + count;
737   *data_p++ = 0x80;
738
739   /* Bytes of padding needed to make 64 bytes */
740   count = SHA1_DATASIZE - 1 - count;
741
742   /* Pad out to 56 mod 64 */
743   if (count < 8)
744     {
745       /* Two lots of padding:  Pad the first block to 64 bytes */
746       memset (data_p, 0, count);
747
748       sha_byte_reverse (sha1->data, SHA1_DATASIZE);
749       sha1_transform (sha1->buf, sha1->data);
750
751       /* Now fill the next block with 56 bytes */
752       memset (sha1->data, 0, SHA1_DATASIZE - 8);
753     }
754   else
755     {
756       /* Pad block to 56 bytes */
757       memset (data_p, 0, count - 8);
758     }
759
760   /* Append length in bits and transform */
761   sha1->data[14] = sha1->bits[1];
762   sha1->data[15] = sha1->bits[0];
763
764   sha_byte_reverse (sha1->data, SHA1_DATASIZE - 8);
765   sha1_transform (sha1->buf, sha1->data);
766   sha_byte_reverse (sha1->buf, SHA1_DIGEST_LEN);
767
768   memcpy (sha1->digest, sha1->buf, SHA1_DIGEST_LEN);
769
770   /* Reset buffers in case they contain sensitive data */
771   memset (sha1->buf, 0, sizeof (sha1->buf));
772   memset (sha1->data, 0, sizeof (sha1->data));
773 }
774
775 static gchar *
776 sha1_sum_to_string (Sha1sum *sha1)
777 {
778   return digest_to_string (sha1->digest, SHA1_DIGEST_LEN);
779 }
780
781 static void
782 sha1_sum_digest (Sha1sum *sha1,
783                  guint8  *digest)
784 {
785   gint i;
786
787   for (i = 0; i < SHA1_DIGEST_LEN; i++)
788     digest[i] = sha1->digest[i];
789 }
790
791 /*
792  * SHA-256 Checksum
793  */
794
795 /* adapted from the SHA256 implementation in gsk/src/hash/gskhash.c.
796  *
797  * Copyright (C) 2006 Dave Benson
798  * Released under the terms of the GNU Lesser General Public License
799  */
800
801 static void
802 sha256_sum_init (Sha256sum *sha256)
803 {
804   sha256->buf[0] = 0x6a09e667;
805   sha256->buf[1] = 0xbb67ae85;
806   sha256->buf[2] = 0x3c6ef372;
807   sha256->buf[3] = 0xa54ff53a;
808   sha256->buf[4] = 0x510e527f;
809   sha256->buf[5] = 0x9b05688c;
810   sha256->buf[6] = 0x1f83d9ab;
811   sha256->buf[7] = 0x5be0cd19;
812
813   sha256->bits[0] = sha256->bits[1] = 0;
814 }
815
816 #define GET_UINT32(n,b,i)               G_STMT_START{   \
817     (n) = ((guint32) (b)[(i)    ] << 24)                \
818         | ((guint32) (b)[(i) + 1] << 16)                \
819         | ((guint32) (b)[(i) + 2] <<  8)                \
820         | ((guint32) (b)[(i) + 3]      ); } G_STMT_END
821
822 #define PUT_UINT32(n,b,i)               G_STMT_START{   \
823     (b)[(i)    ] = (guint8) ((n) >> 24);                \
824     (b)[(i) + 1] = (guint8) ((n) >> 16);                \
825     (b)[(i) + 2] = (guint8) ((n) >>  8);                \
826     (b)[(i) + 3] = (guint8) ((n)      ); } G_STMT_END
827
828 static void
829 sha256_transform (guint32      buf[8],
830                   guint8 const data[64])
831 {
832   guint32 temp1, temp2, W[64];
833   guint32 A, B, C, D, E, F, G, H;
834
835   GET_UINT32 (W[0],  data,  0);
836   GET_UINT32 (W[1],  data,  4);
837   GET_UINT32 (W[2],  data,  8);
838   GET_UINT32 (W[3],  data, 12);
839   GET_UINT32 (W[4],  data, 16);
840   GET_UINT32 (W[5],  data, 20);
841   GET_UINT32 (W[6],  data, 24);
842   GET_UINT32 (W[7],  data, 28);
843   GET_UINT32 (W[8],  data, 32);
844   GET_UINT32 (W[9],  data, 36);
845   GET_UINT32 (W[10], data, 40);
846   GET_UINT32 (W[11], data, 44);
847   GET_UINT32 (W[12], data, 48);
848   GET_UINT32 (W[13], data, 52);
849   GET_UINT32 (W[14], data, 56);
850   GET_UINT32 (W[15], data, 60);
851
852 #define SHR(x,n)        ((x & 0xFFFFFFFF) >> n)
853 #define ROTR(x,n)       (SHR (x,n) | (x << (32 - n)))
854
855 #define S0(x) (ROTR (x, 7) ^ ROTR (x,18) ^  SHR (x, 3))
856 #define S1(x) (ROTR (x,17) ^ ROTR (x,19) ^  SHR (x,10))
857 #define S2(x) (ROTR (x, 2) ^ ROTR (x,13) ^ ROTR (x,22))
858 #define S3(x) (ROTR (x, 6) ^ ROTR (x,11) ^ ROTR (x,25))
859
860 #define F0(x,y,z) ((x & y) | (z & (x | y)))
861 #define F1(x,y,z) (z ^ (x & (y ^ z)))
862
863 #define R(t)    (W[t] = S1(W[t -  2]) + W[t -  7] + \
864                         S0(W[t - 15]) + W[t - 16])
865
866 #define P(a,b,c,d,e,f,g,h,x,K)          G_STMT_START {  \
867         temp1 = h + S3(e) + F1(e,f,g) + K + x;          \
868         temp2 = S2(a) + F0(a,b,c);                      \
869         d += temp1; h = temp1 + temp2; } G_STMT_END
870
871   A = buf[0];
872   B = buf[1];
873   C = buf[2];
874   D = buf[3];
875   E = buf[4];
876   F = buf[5];
877   G = buf[6];
878   H = buf[7];
879
880   P (A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98);
881   P (H, A, B, C, D, E, F, G, W[ 1], 0x71374491);
882   P (G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF);
883   P (F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5);
884   P (E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B);
885   P (D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1);
886   P (C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4);
887   P (B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5);
888   P (A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98);
889   P (H, A, B, C, D, E, F, G, W[ 9], 0x12835B01);
890   P (G, H, A, B, C, D, E, F, W[10], 0x243185BE);
891   P (F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
892   P (E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
893   P (D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
894   P (C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
895   P (B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
896   P (A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
897   P (H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
898   P (G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
899   P (F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
900   P (E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
901   P (D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
902   P (C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
903   P (B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
904   P (A, B, C, D, E, F, G, H, R(24), 0x983E5152);
905   P (H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
906   P (G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
907   P (F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
908   P (E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
909   P (D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
910   P (C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
911   P (B, C, D, E, F, G, H, A, R(31), 0x14292967);
912   P (A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
913   P (H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
914   P (G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
915   P (F, G, H, A, B, C, D, E, R(35), 0x53380D13);
916   P (E, F, G, H, A, B, C, D, R(36), 0x650A7354);
917   P (D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
918   P (C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
919   P (B, C, D, E, F, G, H, A, R(39), 0x92722C85);
920   P (A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
921   P (H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
922   P (G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
923   P (F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
924   P (E, F, G, H, A, B, C, D, R(44), 0xD192E819);
925   P (D, E, F, G, H, A, B, C, R(45), 0xD6990624);
926   P (C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
927   P (B, C, D, E, F, G, H, A, R(47), 0x106AA070);
928   P (A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
929   P (H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
930   P (G, H, A, B, C, D, E, F, R(50), 0x2748774C);
931   P (F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
932   P (E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
933   P (D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
934   P (C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
935   P (B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
936   P (A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
937   P (H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
938   P (G, H, A, B, C, D, E, F, R(58), 0x84C87814);
939   P (F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
940   P (E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
941   P (D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
942   P (C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
943   P (B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
944
945 #undef SHR
946 #undef ROTR
947 #undef S0
948 #undef S1
949 #undef S2
950 #undef S3
951 #undef F0
952 #undef F1
953 #undef R
954 #undef P
955
956   buf[0] += A;
957   buf[1] += B;
958   buf[2] += C;
959   buf[3] += D;
960   buf[4] += E;
961   buf[5] += F;
962   buf[6] += G;
963   buf[7] += H;
964 }
965
966 static void
967 sha256_sum_update (Sha256sum    *sha256,
968                    const guchar *buffer,
969                    gsize         length)
970 {
971   guint32 left, fill;
972   const guint8 *input = buffer;
973
974   if (length == 0)
975     return;
976
977   left = sha256->bits[0] & 0x3F;
978   fill = 64 - left;
979
980   sha256->bits[0] += length;
981   sha256->bits[0] &= 0xFFFFFFFF;
982
983   if (sha256->bits[0] < length)
984       sha256->bits[1]++;
985
986   if (left > 0 && length >= fill)
987     {
988       memcpy ((sha256->data + left), input, fill);
989
990       sha256_transform (sha256->buf, sha256->data);
991       length -= fill;
992       input += fill;
993
994       left = 0;
995     }
996
997   while (length >= SHA256_DATASIZE)
998     {
999       sha256_transform (sha256->buf, input);
1000
1001       length -= 64;
1002       input += 64;
1003     }
1004
1005   if (length)
1006     memcpy (sha256->data + left, input, length);
1007 }
1008
1009 static guint8 sha256_padding[64] =
1010 {
1011  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1012     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1013     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1014     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1015 };
1016
1017 static void
1018 sha256_sum_close (Sha256sum *sha256)
1019 {
1020   guint32 last, padn;
1021   guint32 high, low;
1022   guint8 msglen[8];
1023
1024   high = (sha256->bits[0] >> 29)
1025        | (sha256->bits[1] <<  3);
1026   low  = (sha256->bits[0] <<  3);
1027
1028   PUT_UINT32 (high, msglen, 0);
1029   PUT_UINT32 (low, msglen, 4);
1030
1031   last = sha256->bits[0] & 0x3F;
1032   padn = (last < 56) ? (56 - last) : (120 - last);
1033
1034   sha256_sum_update (sha256, sha256_padding, padn);
1035   sha256_sum_update (sha256, msglen, 8);
1036
1037   PUT_UINT32 (sha256->buf[0], sha256->digest,  0);
1038   PUT_UINT32 (sha256->buf[1], sha256->digest,  4);
1039   PUT_UINT32 (sha256->buf[2], sha256->digest,  8);
1040   PUT_UINT32 (sha256->buf[3], sha256->digest, 12);
1041   PUT_UINT32 (sha256->buf[4], sha256->digest, 16);
1042   PUT_UINT32 (sha256->buf[5], sha256->digest, 20);
1043   PUT_UINT32 (sha256->buf[6], sha256->digest, 24);
1044   PUT_UINT32 (sha256->buf[7], sha256->digest, 28);
1045 }
1046
1047 #undef PUT_UINT32
1048 #undef GET_UINT32
1049
1050 static gchar *
1051 sha256_sum_to_string (Sha256sum *sha256)
1052 {
1053   return digest_to_string (sha256->digest, SHA256_DIGEST_LEN);
1054 }
1055
1056 static void
1057 sha256_sum_digest (Sha256sum *sha256,
1058                    guint8    *digest)
1059 {
1060   gint i;
1061
1062   for (i = 0; i < SHA256_DIGEST_LEN; i++)
1063     digest[i] = sha256->digest[i];
1064 }
1065
1066
1067 /*
1068  * Public API
1069  */
1070
1071 /**
1072  * g_checksum_type_get_length:
1073  * @checksum_type: a #GChecksumType
1074  *
1075  * Gets the length in bytes of digests of type @checksum_type
1076  *
1077  * Return value: the checksum length, or -1 if @checksum_type is
1078  * not supported.
1079  * 
1080  * Since: 2.16
1081  */
1082 gssize
1083 g_checksum_type_get_length (GChecksumType checksum_type)
1084 {
1085   gssize len = -1;
1086
1087   switch (checksum_type)
1088     {
1089     case G_CHECKSUM_MD5:
1090       len = MD5_DIGEST_LEN;
1091       break;
1092     case G_CHECKSUM_SHA1:
1093       len = SHA1_DIGEST_LEN;
1094       break;
1095     case G_CHECKSUM_SHA256:
1096       len = SHA256_DIGEST_LEN;
1097       break;
1098     default:
1099       len = -1;
1100       break;
1101     }
1102
1103   return len;
1104 }
1105
1106 /**
1107  * g_checksum_new:
1108  * @checksum_type: the desired type of checksum
1109  *
1110  * Creates a new #GChecksum, using the checksum algorithm @checksum_type. 
1111  * If the @checksum_type is not known, %NULL is returned.
1112  * A #GChecksum can be used to compute the checksum, or digest, of an
1113  * arbitrary binary blob, using different hashing algorithms.
1114  *
1115  * A #GChecksum works by feeding a binary blob through g_checksum_update()
1116  * until there is data to be checked; the digest can then be extracted
1117  * using g_checksum_get_string(), which will return the checksum as a
1118  * hexadecimal string; or g_checksum_get_digest(), which will return a
1119  * vector of raw bytes. Once either g_checksum_get_string() or
1120  * g_checksum_get_digest() have been called on a #GChecksum, the checksum
1121  * will be closed and it won't be possible to call g_checksum_update()
1122  * on it anymore.
1123  *
1124  * Return value: the newly created #GChecksum, or %NULL. 
1125  *   Use g_checksum_free() to free the memory allocated by it.
1126  *
1127  * Since: 2.16
1128  */
1129 GChecksum *
1130 g_checksum_new (GChecksumType checksum_type)
1131 {
1132   GChecksum *checksum;
1133
1134   if (! IS_VALID_TYPE (checksum_type))
1135     return NULL;
1136
1137   checksum = g_slice_new0 (GChecksum);
1138   checksum->type = checksum_type;
1139
1140   g_checksum_reset (checksum);
1141
1142   return checksum;
1143 }
1144
1145 /**
1146  * g_checksum_reset:
1147  * @checksum: the #GChecksum to reset
1148  *
1149  * Resets the state of the @checksum back to its initial state.
1150  *
1151  * Since: 2.18
1152  **/
1153 void
1154 g_checksum_reset (GChecksum *checksum)
1155 {
1156   g_return_if_fail (checksum != NULL);
1157
1158   g_free (checksum->digest_str);
1159   checksum->digest_str = NULL;
1160
1161   switch (checksum->type)
1162     {
1163     case G_CHECKSUM_MD5:
1164       md5_sum_init (&(checksum->sum.md5));
1165       break;
1166     case G_CHECKSUM_SHA1:
1167       sha1_sum_init (&(checksum->sum.sha1));
1168       break;
1169     case G_CHECKSUM_SHA256:
1170       sha256_sum_init (&(checksum->sum.sha256));
1171       break;
1172     default:
1173       g_assert_not_reached ();
1174       break;
1175     }
1176 }
1177
1178 /**
1179  * g_checksum_copy:
1180  * @checksum: the #GChecksum to copy
1181  *
1182  * Copies a #GChecksum. If @checksum has been closed, by calling
1183  * g_checksum_get_string() or g_checksum_get_digest(), the copied
1184  * checksum will be closed as well.
1185  *
1186  * Return value: the copy of the passed #GChecksum. Use g_checksum_free()
1187  *   when finished using it.
1188  *
1189  * Since: 2.16
1190  */
1191 GChecksum *
1192 g_checksum_copy (const GChecksum *checksum)
1193 {
1194   GChecksum *copy;
1195
1196   g_return_val_if_fail (checksum != NULL, NULL);
1197
1198   copy = g_slice_new (GChecksum);
1199   *copy = *checksum;
1200
1201   copy->digest_str = g_strdup (checksum->digest_str);
1202
1203   return copy;
1204 }
1205
1206 /**
1207  * g_checksum_free:
1208  * @checksum: a #GChecksum
1209  *
1210  * Frees the memory allocated for @checksum.
1211  *
1212  * Since: 2.16
1213  */
1214 void
1215 g_checksum_free (GChecksum *checksum)
1216 {
1217   if (G_LIKELY (checksum))
1218     {
1219       g_free (checksum->digest_str);
1220
1221       g_slice_free (GChecksum, checksum);
1222     }
1223 }
1224
1225 /**
1226  * g_checksum_update:
1227  * @checksum: a #GChecksum
1228  * @data: buffer used to compute the checksum
1229  * @length: size of the buffer, or -1 if it is a null-terminated string.
1230  *
1231  * Feeds @data into an existing #GChecksum. The checksum must still be
1232  * open, that is g_checksum_get_string() or g_checksum_get_digest() must
1233  * not have been called on @checksum.
1234  *
1235  * Since: 2.16
1236  */
1237 void
1238 g_checksum_update (GChecksum    *checksum,
1239                    const guchar *data,
1240                    gssize        length)
1241 {
1242   g_return_if_fail (checksum != NULL);
1243   g_return_if_fail (data != NULL);
1244
1245   if (length < 0)
1246     length = strlen ((const gchar *) data);
1247
1248   if (checksum->digest_str)
1249     {
1250       g_warning ("The checksum `%s' has been closed and cannot be updated "
1251                  "anymore.",
1252                  checksum->digest_str);
1253       return;
1254     }
1255
1256   switch (checksum->type)
1257     {
1258     case G_CHECKSUM_MD5:
1259       md5_sum_update (&(checksum->sum.md5), data, length);
1260       break;
1261     case G_CHECKSUM_SHA1:
1262       sha1_sum_update (&(checksum->sum.sha1), data, length);
1263       break;
1264     case G_CHECKSUM_SHA256:
1265       sha256_sum_update (&(checksum->sum.sha256), data, length);
1266       break;
1267     default:
1268       g_assert_not_reached ();
1269       break;
1270     }
1271 }
1272
1273 /**
1274  * g_checksum_get_string:
1275  * @checksum: a #GChecksum
1276  *
1277  * Gets the digest as an hexadecimal string.
1278  *
1279  * Once this function has been called the #GChecksum can no longer be
1280  * updated with g_checksum_update().
1281  * 
1282  * The hexadecimal characters will be lower case. 
1283  *
1284  * Return value: the hexadecimal representation of the checksum. The
1285  *   returned string is owned by the checksum and should not be modified
1286  *   or freed.
1287  * 
1288  * Since: 2.16
1289  */
1290 G_CONST_RETURN gchar *
1291 g_checksum_get_string (GChecksum *checksum)
1292 {
1293   gchar *str = NULL;
1294
1295   g_return_val_if_fail (checksum != NULL, NULL);
1296   
1297   if (checksum->digest_str)
1298     return checksum->digest_str;
1299
1300   switch (checksum->type)
1301     {
1302     case G_CHECKSUM_MD5:
1303       md5_sum_close (&(checksum->sum.md5));
1304       str = md5_sum_to_string (&(checksum->sum.md5));
1305       break;
1306     case G_CHECKSUM_SHA1:
1307       sha1_sum_close (&(checksum->sum.sha1));
1308       str = sha1_sum_to_string (&(checksum->sum.sha1));
1309       break;
1310     case G_CHECKSUM_SHA256:
1311       sha256_sum_close (&(checksum->sum.sha256));
1312       str = sha256_sum_to_string (&(checksum->sum.sha256));
1313       break;
1314     default:
1315       g_assert_not_reached ();
1316       break;
1317     }
1318
1319   checksum->digest_str = str;
1320
1321   return checksum->digest_str;
1322 }
1323
1324 /**
1325  * g_checksum_get_digest:
1326  * @checksum: a #GChecksum
1327  * @buffer: output buffer
1328  * @digest_len: an inout parameter. The caller initializes it to the size of @buffer.
1329  *   After the call it contains the length of the digest.
1330  *
1331  * Gets the digest from @checksum as a raw binary vector and places it
1332  * into @buffer. The size of the digest depends on the type of checksum.
1333  *
1334  * Once this function has been called, the #GChecksum is closed and can
1335  * no longer be updated with g_checksum_update().
1336  *
1337  * Since: 2.16
1338  */
1339 void
1340 g_checksum_get_digest (GChecksum  *checksum,
1341                        guint8     *buffer,
1342                        gsize      *digest_len)
1343 {
1344   gboolean checksum_open = FALSE;
1345   gchar *str = NULL;
1346   gsize len;
1347
1348   g_return_if_fail (checksum != NULL);
1349
1350   len = g_checksum_type_get_length (checksum->type);
1351   g_return_if_fail (*digest_len >= len);
1352
1353   checksum_open = !!(checksum->digest_str == NULL);
1354
1355   switch (checksum->type)
1356     {
1357     case G_CHECKSUM_MD5:
1358       if (checksum_open)
1359         {
1360           md5_sum_close (&(checksum->sum.md5));
1361           str = md5_sum_to_string (&(checksum->sum.md5));
1362         }
1363       md5_sum_digest (&(checksum->sum.md5), buffer);
1364       break;
1365     case G_CHECKSUM_SHA1:
1366       if (checksum_open)
1367         {
1368           sha1_sum_close (&(checksum->sum.sha1));
1369           str = sha1_sum_to_string (&(checksum->sum.sha1));
1370         }
1371       sha1_sum_digest (&(checksum->sum.sha1), buffer);
1372       break;
1373     case G_CHECKSUM_SHA256:
1374       if (checksum_open)
1375         {
1376           sha256_sum_close (&(checksum->sum.sha256));
1377           str = sha256_sum_to_string (&(checksum->sum.sha256));
1378         }
1379       sha256_sum_digest (&(checksum->sum.sha256), buffer);
1380       break;
1381     default:
1382       g_assert_not_reached ();
1383       break;
1384     }
1385
1386   if (str)
1387     checksum->digest_str = str;
1388
1389   *digest_len = len;
1390 }
1391
1392 /**
1393  * g_compute_checksum_for_data:
1394  * @checksum_type: a #GChecksumType
1395  * @data: binary blob to compute the digest of
1396  * @length: length of @data
1397  *
1398  * Computes the checksum for a binary @data of @length. This is a
1399  * convenience wrapper for g_checksum_new(), g_checksum_get_string()
1400  * and g_checksum_free().
1401  * 
1402  * The hexadecimal string returned will be in lower case.
1403  *
1404  * Return value: the digest of the binary data as a string in hexadecimal.
1405  *   The returned string should be freed with g_free() when done using it.
1406  *
1407  * Since: 2.16
1408  */
1409 gchar *
1410 g_compute_checksum_for_data (GChecksumType  checksum_type,
1411                              const guchar  *data,
1412                              gsize          length)
1413 {
1414   GChecksum *checksum;
1415   gchar *retval;
1416
1417   g_return_val_if_fail (IS_VALID_TYPE (checksum_type), NULL);
1418   g_return_val_if_fail (data != NULL, NULL);
1419
1420   checksum = g_checksum_new (checksum_type);
1421   if (!checksum)
1422     return NULL;
1423
1424   g_checksum_update (checksum, data, length);
1425   retval = g_strdup (g_checksum_get_string (checksum));
1426   g_checksum_free (checksum);
1427
1428   return retval;
1429 }
1430
1431 /**
1432  * g_compute_checksum_for_string:
1433  * @checksum_type: a #GChecksumType
1434  * @str: the string to compute the checksum of
1435  * @length: the length of the string, or -1 if the string is null-terminated.
1436  *
1437  * Computes the checksum of a string.
1438  * 
1439  * The hexadecimal string returned will be in lower case.
1440  *
1441  * Return value: the checksum as a hexadecimal string. The returned string
1442  *   should be freed with g_free() when done using it.
1443  *
1444  * Since: 2.16
1445  */
1446 gchar *
1447 g_compute_checksum_for_string (GChecksumType  checksum_type,
1448                                const gchar   *str,
1449                                gssize         length)
1450 {
1451   g_return_val_if_fail (IS_VALID_TYPE (checksum_type), NULL);
1452   g_return_val_if_fail (str != NULL, NULL);
1453
1454   if (length < 0)
1455     length = strlen (str);
1456
1457   return g_compute_checksum_for_data (checksum_type, (const guchar *) str, length);
1458 }
1459
1460 #define __G_CHECKSUM_C__
1461 #include "galiasdef.c"