Coverage Report

Created: 2025-11-16 06:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/glib/glib/gchecksum.c
Line
Count
Source
1
/* gchecksum.h - data hashing functions
2
 *
3
 * Copyright (C) 2007  Emmanuele Bassi  <ebassi@gnome.org>
4
 *
5
 * SPDX-License-Identifier: LGPL-2.1-or-later
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public License
18
 * along with this library; if not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#include "config.h"
22
23
#include <string.h>
24
25
#include "gchecksum.h"
26
27
#include "gslice.h"
28
#include "gmem.h"
29
#include "gstrfuncs.h"
30
#include "gtestutils.h"
31
#include "gtypes.h"
32
#include "glibintl.h"
33
34
35
/**
36
 * GChecksum:
37
 *
38
 * GLib provides a generic API for computing checksums (or ‘digests’)
39
 * for a sequence of arbitrary bytes, using various hashing algorithms
40
 * like MD5, SHA-1 and SHA-256. Checksums are commonly used in various
41
 * environments and specifications.
42
 *
43
 * To create a new `GChecksum`, use [ctor@GLib.Checksum.new]. To free
44
 * a `GChecksum`, use [method@GLib.Checksum.free].
45
 *
46
 * GLib supports incremental checksums using the `GChecksum` data
47
 * structure, by calling [method@GLib.Checksum.update] as long as there’s data
48
 * available and then using [method@GLib.Checksum.get_string] or
49
 * [method@GLib.Checksum.get_digest] to compute the checksum and return it
50
 * either as a string in hexadecimal form, or as a raw sequence of bytes. To
51
 * compute the checksum for binary blobs and nul-terminated strings in
52
 * one go, use the convenience functions [func@GLib.compute_checksum_for_data]
53
 * and [func@GLib.compute_checksum_for_string], respectively.
54
 *
55
 * Since: 2.16
56
 **/
57
58
0
#define IS_VALID_TYPE(type)     ((type) >= G_CHECKSUM_MD5 && (type) <= G_CHECKSUM_SHA384)
59
60
/* The fact that these are lower case characters is part of the ABI */
61
static const gchar hex_digits[] = "0123456789abcdef";
62
63
0
#define MD5_DATASIZE    64
64
0
#define MD5_DIGEST_LEN  16
65
66
typedef struct
67
{
68
  guint32 buf[4];
69
  guint32 bits[2];
70
71
  union {
72
    guchar data[MD5_DATASIZE];
73
    guint32 data32[MD5_DATASIZE / 4];
74
  } u;
75
76
  guchar digest[MD5_DIGEST_LEN];
77
} Md5sum;
78
79
0
#define SHA1_DATASIZE   64
80
0
#define SHA1_DIGEST_LEN 20
81
82
typedef struct
83
{
84
  guint32 buf[5];
85
  guint32 bits[2];
86
87
  /* we pack 64 unsigned chars into 16 32-bit unsigned integers */
88
  guint32 data[16];
89
90
  guchar digest[SHA1_DIGEST_LEN];
91
} Sha1sum;
92
93
0
#define SHA256_DATASIZE         64
94
0
#define SHA256_DIGEST_LEN       32
95
96
typedef struct
97
{
98
  guint32 buf[8];
99
  guint32 bits[2];
100
101
  guint8 data[SHA256_DATASIZE];
102
103
  guchar digest[SHA256_DIGEST_LEN];
104
} Sha256sum;
105
106
/* SHA2 is common thing for SHA-384, SHA-512, SHA-512/224 and SHA-512/256 */
107
0
#define SHA2_BLOCK_LEN         128 /* 1024 bits message block */
108
0
#define SHA384_DIGEST_LEN       48
109
0
#define SHA512_DIGEST_LEN       64
110
111
typedef struct
112
{
113
  guint64 H[8];
114
115
  guint8 block[SHA2_BLOCK_LEN];
116
  guint8 block_len;
117
118
  guint64 data_len[2];
119
120
  guchar digest[SHA512_DIGEST_LEN];
121
} Sha512sum;
122
123
struct _GChecksum
124
{
125
  GChecksumType type;
126
127
  gchar *digest_str;
128
129
  union {
130
    Md5sum md5;
131
    Sha1sum sha1;
132
    Sha256sum sha256;
133
    Sha512sum sha512;
134
  } sum;
135
};
136
137
/* we need different byte swapping functions because MD5 expects buffers
138
 * to be little-endian, while SHA1 and SHA256 expect them in big-endian
139
 * form.
140
 */
141
142
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
143
#define md5_byte_reverse(buffer,length)
144
#else
145
/* assume that the passed buffer is integer aligned */
146
static inline void
147
md5_byte_reverse (guchar *buffer,
148
                  gulong  length)
149
{
150
  guint32 bit;
151
152
  do
153
    {
154
      bit = (guint32) ((unsigned) buffer[3] << 8 | buffer[2]) << 16 |
155
                      ((unsigned) buffer[1] << 8 | buffer[0]);
156
      * (guint32 *) buffer = bit;
157
      buffer += 4;
158
    }
159
  while (--length);
160
}
161
#endif /* G_BYTE_ORDER == G_LITTLE_ENDIAN */
162
163
#if G_BYTE_ORDER == G_BIG_ENDIAN
164
#define sha_byte_reverse(buffer,length)
165
#else
166
static inline void
167
sha_byte_reverse (guint32 *buffer,
168
                  size_t   length)
169
0
{
170
0
  length /= sizeof (guint32);
171
0
  while (length--)
172
0
    {
173
0
      *buffer = GUINT32_SWAP_LE_BE (*buffer);
174
0
      ++buffer;
175
0
    }
176
0
}
177
#endif /* G_BYTE_ORDER == G_BIG_ENDIAN */
178
179
static gchar *
180
digest_to_string (guint8 *digest,
181
                  gsize   digest_len)
182
0
{
183
0
  gsize i, len = digest_len * 2;
184
0
  gchar *retval;
185
186
0
  retval = g_new (gchar, len + 1);
187
188
0
  for (i = 0; i < digest_len; i++)
189
0
    {
190
0
      guint8 byte = digest[i];
191
192
0
      retval[2 * i] = hex_digits[byte >> 4];
193
0
      retval[2 * i + 1] = hex_digits[byte & 0xf];
194
0
    }
195
196
0
  retval[len] = 0;
197
198
0
  return retval;
199
0
}
200
201
/*
202
 * MD5 Checksum
203
 */
204
205
/* This MD5 digest computation is based on the equivalent code
206
 * written by Colin Plumb. It came with this notice:
207
 *
208
 * This code implements the MD5 message-digest algorithm.
209
 * The algorithm is due to Ron Rivest.  This code was
210
 * written by Colin Plumb in 1993, no copyright is claimed.
211
 * This code is in the public domain; do with it what you wish.
212
 *
213
 * Equivalent code is available from RSA Data Security, Inc.
214
 * This code has been tested against that, and is equivalent,
215
 * except that you don't need to include two pages of legalese
216
 * with every copy.
217
 */
218
219
static void
220
md5_sum_init (Md5sum *md5)
221
0
{
222
  /* arbitrary constants */
223
0
  md5->buf[0] = 0x67452301;
224
0
  md5->buf[1] = 0xefcdab89;
225
0
  md5->buf[2] = 0x98badcfe;
226
0
  md5->buf[3] = 0x10325476;
227
228
0
  md5->bits[0] = md5->bits[1] = 0;
229
0
}
230
231
/*
232
 * The core of the MD5 algorithm, this alters an existing MD5 hash to
233
 * reflect the addition of 16 longwords of new data.  md5_sum_update()
234
 * blocks the data and converts bytes into longwords for this routine.
235
 */
236
static void
237
md5_transform (guint32       buf[4],
238
               guint32 const in[16])
239
0
{
240
0
  guint32 a, b, c, d;
241
242
/* The four core functions - F1 is optimized somewhat */
243
0
#define F1(x, y, z)     (z ^ (x & (y ^ z)))
244
0
#define F2(x, y, z)     F1 (z, x, y)
245
0
#define F3(x, y, z)     (x ^ y ^ z)
246
0
#define F4(x, y, z)     (y ^ (x | ~z))
247
248
/* This is the central step in the MD5 algorithm. */
249
0
#define md5_step(f, w, x, y, z, data, s) \
250
0
        ( w += f (x, y, z) + data,  w = w << s | w >> (32 - s),  w += x )
251
252
0
  a = buf[0];
253
0
  b = buf[1];
254
0
  c = buf[2];
255
0
  d = buf[3];
256
257
0
  md5_step (F1, a, b, c, d, in[0]  + 0xd76aa478,  7);
258
0
  md5_step (F1, d, a, b, c, in[1]  + 0xe8c7b756, 12);
259
0
  md5_step (F1, c, d, a, b, in[2]  + 0x242070db, 17);
260
0
  md5_step (F1, b, c, d, a, in[3]  + 0xc1bdceee, 22);
261
0
  md5_step (F1, a, b, c, d, in[4]  + 0xf57c0faf,  7);
262
0
  md5_step (F1, d, a, b, c, in[5]  + 0x4787c62a, 12);
263
0
  md5_step (F1, c, d, a, b, in[6]  + 0xa8304613, 17);
264
0
  md5_step (F1, b, c, d, a, in[7]  + 0xfd469501, 22);
265
0
  md5_step (F1, a, b, c, d, in[8]  + 0x698098d8,  7);
266
0
  md5_step (F1, d, a, b, c, in[9]  + 0x8b44f7af, 12);
267
0
  md5_step (F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
268
0
  md5_step (F1, b, c, d, a, in[11] + 0x895cd7be, 22);
269
0
  md5_step (F1, a, b, c, d, in[12] + 0x6b901122,  7);
270
0
  md5_step (F1, d, a, b, c, in[13] + 0xfd987193, 12);
271
0
  md5_step (F1, c, d, a, b, in[14] + 0xa679438e, 17);
272
0
  md5_step (F1, b, c, d, a, in[15] + 0x49b40821, 22);
273
        
274
0
  md5_step (F2, a, b, c, d, in[1]  + 0xf61e2562,  5);
275
0
  md5_step (F2, d, a, b, c, in[6]  + 0xc040b340,  9);
276
0
  md5_step (F2, c, d, a, b, in[11] + 0x265e5a51, 14);
277
0
  md5_step (F2, b, c, d, a, in[0]  + 0xe9b6c7aa, 20);
278
0
  md5_step (F2, a, b, c, d, in[5]  + 0xd62f105d,  5);
279
0
  md5_step (F2, d, a, b, c, in[10] + 0x02441453,  9);
280
0
  md5_step (F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
281
0
  md5_step (F2, b, c, d, a, in[4]  + 0xe7d3fbc8, 20);
282
0
  md5_step (F2, a, b, c, d, in[9]  + 0x21e1cde6,  5);
283
0
  md5_step (F2, d, a, b, c, in[14] + 0xc33707d6,  9);
284
0
  md5_step (F2, c, d, a, b, in[3]  + 0xf4d50d87, 14);
285
0
  md5_step (F2, b, c, d, a, in[8]  + 0x455a14ed, 20);
286
0
  md5_step (F2, a, b, c, d, in[13] + 0xa9e3e905,  5);
287
0
  md5_step (F2, d, a, b, c, in[2]  + 0xfcefa3f8,  9);
288
0
  md5_step (F2, c, d, a, b, in[7]  + 0x676f02d9, 14);
289
0
  md5_step (F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
290
291
0
  md5_step (F3, a, b, c, d, in[5]  + 0xfffa3942,  4);
292
0
  md5_step (F3, d, a, b, c, in[8]  + 0x8771f681, 11);
293
0
  md5_step (F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
294
0
  md5_step (F3, b, c, d, a, in[14] + 0xfde5380c, 23);
295
0
  md5_step (F3, a, b, c, d, in[1]  + 0xa4beea44,  4);
296
0
  md5_step (F3, d, a, b, c, in[4]  + 0x4bdecfa9, 11);
297
0
  md5_step (F3, c, d, a, b, in[7]  + 0xf6bb4b60, 16);
298
0
  md5_step (F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
299
0
  md5_step (F3, a, b, c, d, in[13] + 0x289b7ec6,  4);
300
0
  md5_step (F3, d, a, b, c, in[0]  + 0xeaa127fa, 11);
301
0
  md5_step (F3, c, d, a, b, in[3]  + 0xd4ef3085, 16);
302
0
  md5_step (F3, b, c, d, a, in[6]  + 0x04881d05, 23);
303
0
  md5_step (F3, a, b, c, d, in[9]  + 0xd9d4d039,  4);
304
0
  md5_step (F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
305
0
  md5_step (F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
306
0
  md5_step (F3, b, c, d, a, in[2]  + 0xc4ac5665, 23);
307
308
0
  md5_step (F4, a, b, c, d, in[0]  + 0xf4292244,  6);
309
0
  md5_step (F4, d, a, b, c, in[7]  + 0x432aff97, 10);
310
0
  md5_step (F4, c, d, a, b, in[14] + 0xab9423a7, 15);
311
0
  md5_step (F4, b, c, d, a, in[5]  + 0xfc93a039, 21);
312
0
  md5_step (F4, a, b, c, d, in[12] + 0x655b59c3,  6);
313
0
  md5_step (F4, d, a, b, c, in[3]  + 0x8f0ccc92, 10);
314
0
  md5_step (F4, c, d, a, b, in[10] + 0xffeff47d, 15);
315
0
  md5_step (F4, b, c, d, a, in[1]  + 0x85845dd1, 21);
316
0
  md5_step (F4, a, b, c, d, in[8]  + 0x6fa87e4f,  6);
317
0
  md5_step (F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
318
0
  md5_step (F4, c, d, a, b, in[6]  + 0xa3014314, 15);
319
0
  md5_step (F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
320
0
  md5_step (F4, a, b, c, d, in[4]  + 0xf7537e82,  6);
321
0
  md5_step (F4, d, a, b, c, in[11] + 0xbd3af235, 10);
322
0
  md5_step (F4, c, d, a, b, in[2]  + 0x2ad7d2bb, 15);
323
0
  md5_step (F4, b, c, d, a, in[9]  + 0xeb86d391, 21);
324
325
0
  buf[0] += a;
326
0
  buf[1] += b;
327
0
  buf[2] += c;
328
0
  buf[3] += d;
329
330
0
#undef F1
331
0
#undef F2
332
0
#undef F3
333
0
#undef F4
334
0
#undef md5_step
335
0
}
336
337
static void
338
md5_sum_update (Md5sum       *md5,
339
                const guchar *data,
340
                gsize         length)
341
0
{
342
0
  guint32 bit;
343
344
0
  bit = md5->bits[0];
345
0
  md5->bits[0] = bit + ((guint32) length << 3);
346
347
  /* carry from low to high */
348
0
  if (md5->bits[0] < bit)
349
0
    md5->bits[1] += 1;
350
351
0
  md5->bits[1] += length >> 29;
352
353
  /* bytes already in Md5sum->u.data */
354
0
  bit = (bit >> 3) & 0x3f;
355
356
  /* handle any leading odd-sized chunks */
357
0
  if (bit)
358
0
    {
359
0
      guchar *p = md5->u.data + bit;
360
361
0
      bit = MD5_DATASIZE - bit;
362
0
      if (length < bit)
363
0
        {
364
0
          memcpy (p, data, length);
365
0
          return;
366
0
        }
367
368
0
      memcpy (p, data, bit);
369
370
0
      md5_byte_reverse (md5->u.data, 16);
371
0
      md5_transform (md5->buf, md5->u.data32);
372
373
0
      data += bit;
374
0
      length -= bit;
375
0
    }
376
377
  /* process data in 64-byte chunks */
378
0
  while (length >= MD5_DATASIZE)
379
0
    {
380
0
      memcpy (md5->u.data, data, MD5_DATASIZE);
381
382
0
      md5_byte_reverse (md5->u.data, 16);
383
0
      md5_transform (md5->buf, md5->u.data32);
384
385
0
      data += MD5_DATASIZE;
386
0
      length -= MD5_DATASIZE;
387
0
    }
388
389
  /* handle any remaining bytes of data */
390
0
  memcpy (md5->u.data, data, length);
391
0
}
392
393
/* closes a checksum */
394
static void
395
md5_sum_close (Md5sum *md5)
396
0
{
397
0
  guint count;
398
0
  guchar *p;
399
400
  /* Compute number of bytes mod 64 */
401
0
  count = (md5->bits[0] >> 3) & 0x3F;
402
403
  /* Set the first char of padding to 0x80.
404
   * This is safe since there is always at least one byte free
405
   */
406
0
  p = md5->u.data + count;
407
0
  *p++ = 0x80;
408
409
  /* Bytes of padding needed to make 64 bytes */
410
0
  count = MD5_DATASIZE - 1 - count;
411
412
  /* Pad out to 56 mod 64 */
413
0
  if (count < 8)
414
0
    {
415
      /* Two lots of padding:  Pad the first block to 64 bytes */
416
0
      memset (p, 0, count);
417
418
0
      md5_byte_reverse (md5->u.data, 16);
419
0
      md5_transform (md5->buf, md5->u.data32);
420
421
      /* Now fill the next block with 56 bytes */
422
0
      memset (md5->u.data, 0, MD5_DATASIZE - 8);
423
0
    }
424
0
  else
425
0
    {
426
      /* Pad block to 56 bytes */
427
0
      memset (p, 0, count - 8);
428
0
    }
429
430
0
  md5_byte_reverse (md5->u.data, 14);
431
432
  /* Append length in bits and transform */
433
0
  md5->u.data32[14] = md5->bits[0];
434
0
  md5->u.data32[15] = md5->bits[1];
435
436
0
  md5_transform (md5->buf, md5->u.data32);
437
0
  md5_byte_reverse ((guchar *) md5->buf, 4);
438
439
0
  memcpy (md5->digest, md5->buf, 16);
440
441
  /* Reset buffers in case they contain sensitive data */
442
0
  memset (md5->buf, 0, sizeof (md5->buf));
443
0
  memset (md5->u.data, 0, sizeof (md5->u.data));
444
0
}
445
446
static gchar *
447
md5_sum_to_string (Md5sum *md5)
448
0
{
449
0
  return digest_to_string (md5->digest, MD5_DIGEST_LEN);
450
0
}
451
452
static void
453
md5_sum_digest (Md5sum *md5,
454
                guint8 *digest)
455
0
{
456
0
  gint i;
457
458
0
  for (i = 0; i < MD5_DIGEST_LEN; i++)
459
0
    digest[i] = md5->digest[i];
460
0
}
461
462
/*
463
 * SHA-1 Checksum
464
 */
465
466
/* The following implementation comes from D-Bus dbus-sha.c. I've changed
467
 * it to use GLib types and to work more like the MD5 implementation above.
468
 * I left the comments to have a history of this code.
469
 *      -- Emmanuele Bassi, ebassi@gnome.org
470
 */
471
472
/* The following comments have the history of where this code
473
 * comes from. I actually copied it from GNet in GNOME CVS.
474
 * - hp@redhat.com
475
 */
476
477
/*
478
 *  sha.h : Implementation of the Secure Hash Algorithm
479
 *
480
 * Part of the Python Cryptography Toolkit, version 1.0.0
481
 *
482
 * Copyright (C) 1995, A.M. Kuchling
483
 *
484
 * Distribute and use freely; there are no restrictions on further
485
 * dissemination and usage except those imposed by the laws of your
486
 * country of residence.
487
 *
488
 */
489
490
/* SHA: NIST's Secure Hash Algorithm */
491
492
/* Based on SHA code originally posted to sci.crypt by Peter Gutmann
493
   in message <30ajo5$oe8@ccu2.auckland.ac.nz>.
494
   Modified to test for endianness on creation of SHA objects by AMK.
495
   Also, the original specification of SHA was found to have a weakness
496
   by NSA/NIST.  This code implements the fixed version of SHA.
497
*/
498
499
/* Here's the first paragraph of Peter Gutmann's posting:
500
501
The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
502
SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
503
what's changed in the new version.  The fix is a simple change which involves
504
adding a single rotate in the initial expansion function.  It is unknown
505
whether this is an optimal solution to the problem which was discovered in the
506
SHA or whether it's simply a bandaid which fixes the problem with a minimum of
507
effort (for example the reengineering of a great many Capstone chips).
508
*/
509
510
static void
511
sha1_sum_init (Sha1sum *sha1)
512
0
{
513
  /* initialize constants */
514
0
  sha1->buf[0] = 0x67452301L;
515
0
  sha1->buf[1] = 0xEFCDAB89L;
516
0
  sha1->buf[2] = 0x98BADCFEL;
517
0
  sha1->buf[3] = 0x10325476L;
518
0
  sha1->buf[4] = 0xC3D2E1F0L;
519
520
  /* initialize bits */
521
0
  sha1->bits[0] = sha1->bits[1] = 0;
522
0
}
523
524
/* The SHA f()-functions. */
525
526
0
#define f1(x,y,z)       (z ^ (x & (y ^ z)))             /* Rounds  0-19 */
527
0
#define f2(x,y,z)       (x ^ y ^ z)                     /* Rounds 20-39 */
528
0
#define f3(x,y,z)       (( x & y) | (z & (x | y)))      /* Rounds 40-59 */
529
0
#define f4(x,y,z)       (x ^ y ^ z)                     /* Rounds 60-79 */
530
531
/* The SHA Mysterious Constants */
532
#define K1  0x5A827999L                                 /* Rounds  0-19 */
533
#define K2  0x6ED9EBA1L                                 /* Rounds 20-39 */
534
#define K3  0x8F1BBCDCL                                 /* Rounds 40-59 */
535
#define K4  0xCA62C1D6L                                 /* Rounds 60-79 */
536
537
/* 32-bit rotate left - kludged with shifts */
538
0
#define ROTL(n,X) (((X) << n ) | ((X) >> (32 - n)))
539
540
/* The initial expanding function.  The hash function is defined over an
541
   80-word expanded input array W, where the first 16 are copies of the input
542
   data, and the remaining 64 are defined by
543
544
        W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
545
546
   This implementation generates these values on the fly in a circular
547
   buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
548
   optimization.
549
550
   The updated SHA changes the expanding function by adding a rotate of 1
551
   bit.  Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
552
   for this information */
553
554
#define expand(W,i) (W[ i & 15 ] = ROTL (1, (W[ i       & 15] ^ \
555
                                             W[(i - 14) & 15] ^ \
556
                                             W[(i -  8) & 15] ^ \
557
                                             W[(i -  3) & 15])))
558
559
560
/* The prototype SHA sub-round.  The fundamental sub-round is:
561
562
        a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
563
        b' = a;
564
        c' = ROTL( 30, b );
565
        d' = c;
566
        e' = d;
567
568
   but this is implemented by unrolling the loop 5 times and renaming the
569
   variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
570
   This code is then replicated 20 times for each of the 4 functions, using
571
   the next 20 values from the W[] array each time */
572
573
#define subRound(a, b, c, d, e, f, k, data) \
574
0
   (e += ROTL (5, a) + f(b, c, d) + k + data, b = ROTL (30, b))
575
576
static void
577
sha1_transform (guint32  buf[5],
578
                guint32  in[16])
579
0
{
580
0
  guint32 A, B, C, D, E;
581
582
0
  A = buf[0];
583
0
  B = buf[1];
584
0
  C = buf[2];
585
0
  D = buf[3];
586
0
  E = buf[4];
587
588
  /* Heavy mangling, in 4 sub-rounds of 20 iterations each. */
589
0
  subRound (A, B, C, D, E, f1, K1, in[0]);
590
0
  subRound (E, A, B, C, D, f1, K1, in[1]);
591
0
  subRound (D, E, A, B, C, f1, K1, in[2]);
592
0
  subRound (C, D, E, A, B, f1, K1, in[3]);
593
0
  subRound (B, C, D, E, A, f1, K1, in[4]);
594
0
  subRound (A, B, C, D, E, f1, K1, in[5]);
595
0
  subRound (E, A, B, C, D, f1, K1, in[6]);
596
0
  subRound (D, E, A, B, C, f1, K1, in[7]);
597
0
  subRound (C, D, E, A, B, f1, K1, in[8]);
598
0
  subRound (B, C, D, E, A, f1, K1, in[9]);
599
0
  subRound (A, B, C, D, E, f1, K1, in[10]);
600
0
  subRound (E, A, B, C, D, f1, K1, in[11]);
601
0
  subRound (D, E, A, B, C, f1, K1, in[12]);
602
0
  subRound (C, D, E, A, B, f1, K1, in[13]);
603
0
  subRound (B, C, D, E, A, f1, K1, in[14]);
604
0
  subRound (A, B, C, D, E, f1, K1, in[15]);
605
0
  subRound (E, A, B, C, D, f1, K1, expand (in, 16));
606
0
  subRound (D, E, A, B, C, f1, K1, expand (in, 17));
607
0
  subRound (C, D, E, A, B, f1, K1, expand (in, 18));
608
0
  subRound (B, C, D, E, A, f1, K1, expand (in, 19));
609
610
0
  subRound (A, B, C, D, E, f2, K2, expand (in, 20));
611
0
  subRound (E, A, B, C, D, f2, K2, expand (in, 21));
612
0
  subRound (D, E, A, B, C, f2, K2, expand (in, 22));
613
0
  subRound (C, D, E, A, B, f2, K2, expand (in, 23));
614
0
  subRound (B, C, D, E, A, f2, K2, expand (in, 24));
615
0
  subRound (A, B, C, D, E, f2, K2, expand (in, 25));
616
0
  subRound (E, A, B, C, D, f2, K2, expand (in, 26));
617
0
  subRound (D, E, A, B, C, f2, K2, expand (in, 27));
618
0
  subRound (C, D, E, A, B, f2, K2, expand (in, 28));
619
0
  subRound (B, C, D, E, A, f2, K2, expand (in, 29));
620
0
  subRound (A, B, C, D, E, f2, K2, expand (in, 30));
621
0
  subRound (E, A, B, C, D, f2, K2, expand (in, 31));
622
0
  subRound (D, E, A, B, C, f2, K2, expand (in, 32));
623
0
  subRound (C, D, E, A, B, f2, K2, expand (in, 33));
624
0
  subRound (B, C, D, E, A, f2, K2, expand (in, 34));
625
0
  subRound (A, B, C, D, E, f2, K2, expand (in, 35));
626
0
  subRound (E, A, B, C, D, f2, K2, expand (in, 36));
627
0
  subRound (D, E, A, B, C, f2, K2, expand (in, 37));
628
0
  subRound (C, D, E, A, B, f2, K2, expand (in, 38));
629
0
  subRound (B, C, D, E, A, f2, K2, expand (in, 39));
630
631
0
  subRound (A, B, C, D, E, f3, K3, expand (in, 40));
632
0
  subRound (E, A, B, C, D, f3, K3, expand (in, 41));
633
0
  subRound (D, E, A, B, C, f3, K3, expand (in, 42));
634
0
  subRound (C, D, E, A, B, f3, K3, expand (in, 43));
635
0
  subRound (B, C, D, E, A, f3, K3, expand (in, 44));
636
0
  subRound (A, B, C, D, E, f3, K3, expand (in, 45));
637
0
  subRound (E, A, B, C, D, f3, K3, expand (in, 46));
638
0
  subRound (D, E, A, B, C, f3, K3, expand (in, 47));
639
0
  subRound (C, D, E, A, B, f3, K3, expand (in, 48));
640
0
  subRound (B, C, D, E, A, f3, K3, expand (in, 49));
641
0
  subRound (A, B, C, D, E, f3, K3, expand (in, 50));
642
0
  subRound (E, A, B, C, D, f3, K3, expand (in, 51));
643
0
  subRound (D, E, A, B, C, f3, K3, expand (in, 52));
644
0
  subRound (C, D, E, A, B, f3, K3, expand (in, 53));
645
0
  subRound (B, C, D, E, A, f3, K3, expand (in, 54));
646
0
  subRound (A, B, C, D, E, f3, K3, expand (in, 55));
647
0
  subRound (E, A, B, C, D, f3, K3, expand (in, 56));
648
0
  subRound (D, E, A, B, C, f3, K3, expand (in, 57));
649
0
  subRound (C, D, E, A, B, f3, K3, expand (in, 58));
650
0
  subRound (B, C, D, E, A, f3, K3, expand (in, 59));
651
652
0
  subRound (A, B, C, D, E, f4, K4, expand (in, 60));
653
0
  subRound (E, A, B, C, D, f4, K4, expand (in, 61));
654
0
  subRound (D, E, A, B, C, f4, K4, expand (in, 62));
655
0
  subRound (C, D, E, A, B, f4, K4, expand (in, 63));
656
0
  subRound (B, C, D, E, A, f4, K4, expand (in, 64));
657
0
  subRound (A, B, C, D, E, f4, K4, expand (in, 65));
658
0
  subRound (E, A, B, C, D, f4, K4, expand (in, 66));
659
0
  subRound (D, E, A, B, C, f4, K4, expand (in, 67));
660
0
  subRound (C, D, E, A, B, f4, K4, expand (in, 68));
661
0
  subRound (B, C, D, E, A, f4, K4, expand (in, 69));
662
0
  subRound (A, B, C, D, E, f4, K4, expand (in, 70));
663
0
  subRound (E, A, B, C, D, f4, K4, expand (in, 71));
664
0
  subRound (D, E, A, B, C, f4, K4, expand (in, 72));
665
0
  subRound (C, D, E, A, B, f4, K4, expand (in, 73));
666
0
  subRound (B, C, D, E, A, f4, K4, expand (in, 74));
667
0
  subRound (A, B, C, D, E, f4, K4, expand (in, 75));
668
0
  subRound (E, A, B, C, D, f4, K4, expand (in, 76));
669
0
  subRound (D, E, A, B, C, f4, K4, expand (in, 77));
670
0
  subRound (C, D, E, A, B, f4, K4, expand (in, 78));
671
0
  subRound (B, C, D, E, A, f4, K4, expand (in, 79));
672
673
  /* Build message digest */
674
0
  buf[0] += A;
675
0
  buf[1] += B;
676
0
  buf[2] += C;
677
0
  buf[3] += D;
678
0
  buf[4] += E;
679
0
}
680
681
#undef K1
682
#undef K2
683
#undef K3
684
#undef K4
685
#undef f1
686
#undef f2
687
#undef f3
688
#undef f4
689
#undef ROTL
690
#undef expand
691
#undef subRound
692
693
static void
694
sha1_sum_update (Sha1sum      *sha1,
695
                 const guchar *buffer,
696
                 gsize         count)
697
0
{
698
0
  guint32 tmp;
699
0
  guint dataCount;
700
701
  /* Update bitcount */
702
0
  tmp = sha1->bits[0];
703
0
  if ((sha1->bits[0] = tmp + ((guint32) count << 3) ) < tmp)
704
0
    sha1->bits[1] += 1;             /* Carry from low to high */
705
0
  sha1->bits[1] += count >> 29;
706
707
  /* Get count of bytes already in data */
708
0
  dataCount = (guint) (tmp >> 3) & 0x3F;
709
710
  /* Handle any leading odd-sized chunks */
711
0
  if (dataCount)
712
0
    {
713
0
      guchar *p = (guchar *) sha1->data + dataCount;
714
715
0
      dataCount = SHA1_DATASIZE - dataCount;
716
0
      if (count < dataCount)
717
0
        {
718
0
          memcpy (p, buffer, count);
719
0
          return;
720
0
        }
721
722
0
      memcpy (p, buffer, dataCount);
723
724
0
      sha_byte_reverse (sha1->data, SHA1_DATASIZE);
725
0
      sha1_transform (sha1->buf, sha1->data);
726
727
0
      buffer += dataCount;
728
0
      count -= dataCount;
729
0
    }
730
731
  /* Process data in SHA1_DATASIZE chunks */
732
0
  while (count >= SHA1_DATASIZE)
733
0
    {
734
0
      memcpy (sha1->data, buffer, SHA1_DATASIZE);
735
736
0
      sha_byte_reverse (sha1->data, SHA1_DATASIZE);
737
0
      sha1_transform (sha1->buf, sha1->data);
738
739
0
      buffer += SHA1_DATASIZE;
740
0
      count -= SHA1_DATASIZE;
741
0
    }
742
743
  /* Handle any remaining bytes of data. */
744
0
  memcpy (sha1->data, buffer, count);
745
0
}
746
747
/* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern
748
   1 0* (64-bit count of bits processed, MSB-first) */
749
static void
750
sha1_sum_close (Sha1sum *sha1)
751
0
{
752
0
  size_t count;
753
0
  guchar *data_p;
754
755
  /* Compute number of bytes mod 64 */
756
0
  count = (sha1->bits[0] >> 3) & 0x3f;
757
758
  /* Set the first char of padding to 0x80.  This is safe since there is
759
     always at least one byte free */
760
0
  data_p = (guchar *) sha1->data + count;
761
0
  *data_p++ = 0x80;
762
763
  /* Bytes of padding needed to make 64 bytes */
764
0
  count = SHA1_DATASIZE - 1 - count;
765
766
  /* Pad out to 56 mod 64 */
767
0
  if (count < 8)
768
0
    {
769
      /* Two lots of padding:  Pad the first block to 64 bytes */
770
0
      memset (data_p, 0, count);
771
772
0
      sha_byte_reverse (sha1->data, SHA1_DATASIZE);
773
0
      sha1_transform (sha1->buf, sha1->data);
774
775
      /* Now fill the next block with 56 bytes */
776
0
      memset (sha1->data, 0, SHA1_DATASIZE - 8);
777
0
    }
778
0
  else
779
0
    {
780
      /* Pad block to 56 bytes */
781
0
      memset (data_p, 0, count - 8);
782
0
    }
783
784
  /* Append length in bits and transform */
785
0
  sha1->data[14] = sha1->bits[1];
786
0
  sha1->data[15] = sha1->bits[0];
787
788
0
  sha_byte_reverse (sha1->data, SHA1_DATASIZE - 8);
789
0
  sha1_transform (sha1->buf, sha1->data);
790
0
  sha_byte_reverse (sha1->buf, SHA1_DIGEST_LEN);
791
792
0
  memcpy (sha1->digest, sha1->buf, SHA1_DIGEST_LEN);
793
794
  /* Reset buffers in case they contain sensitive data */
795
0
  memset (sha1->buf, 0, sizeof (sha1->buf));
796
0
  memset (sha1->data, 0, sizeof (sha1->data));
797
0
}
798
799
static gchar *
800
sha1_sum_to_string (Sha1sum *sha1)
801
0
{
802
0
  return digest_to_string (sha1->digest, SHA1_DIGEST_LEN);
803
0
}
804
805
static void
806
sha1_sum_digest (Sha1sum *sha1,
807
                 guint8  *digest)
808
0
{
809
0
  size_t i;
810
811
0
  for (i = 0; i < SHA1_DIGEST_LEN; i++)
812
0
    digest[i] = sha1->digest[i];
813
0
}
814
815
/*
816
 * SHA-256 Checksum
817
 */
818
819
/* adapted from the SHA256 implementation in gsk/src/hash/gskhash.c.
820
 *
821
 * Copyright (C) 2006 Dave Benson
822
 * Released under the terms of the GNU Lesser General Public License
823
 */
824
825
static void
826
sha256_sum_init (Sha256sum *sha256)
827
0
{
828
0
  sha256->buf[0] = 0x6a09e667;
829
0
  sha256->buf[1] = 0xbb67ae85;
830
0
  sha256->buf[2] = 0x3c6ef372;
831
0
  sha256->buf[3] = 0xa54ff53a;
832
0
  sha256->buf[4] = 0x510e527f;
833
0
  sha256->buf[5] = 0x9b05688c;
834
0
  sha256->buf[6] = 0x1f83d9ab;
835
0
  sha256->buf[7] = 0x5be0cd19;
836
837
0
  sha256->bits[0] = sha256->bits[1] = 0;
838
0
}
839
840
0
#define GET_UINT32(n,b,i)               G_STMT_START{   \
841
0
    (n) = ((guint32) (b)[(i)    ] << 24)                \
842
0
        | ((guint32) (b)[(i) + 1] << 16)                \
843
0
        | ((guint32) (b)[(i) + 2] <<  8)                \
844
0
        | ((guint32) (b)[(i) + 3]      ); } G_STMT_END
845
846
0
#define PUT_UINT32(n,b,i)               G_STMT_START{   \
847
0
    (b)[(i)    ] = (guint8) ((n) >> 24);                \
848
0
    (b)[(i) + 1] = (guint8) ((n) >> 16);                \
849
0
    (b)[(i) + 2] = (guint8) ((n) >>  8);                \
850
0
    (b)[(i) + 3] = (guint8) ((n)      ); } G_STMT_END
851
852
static void
853
sha256_transform (guint32      buf[8],
854
                  guint8 const data[64])
855
0
{
856
0
  guint32 temp1, temp2, W[64];
857
0
  guint32 A, B, C, D, E, F, G, H;
858
859
0
  GET_UINT32 (W[0],  data,  0);
860
0
  GET_UINT32 (W[1],  data,  4);
861
0
  GET_UINT32 (W[2],  data,  8);
862
0
  GET_UINT32 (W[3],  data, 12);
863
0
  GET_UINT32 (W[4],  data, 16);
864
0
  GET_UINT32 (W[5],  data, 20);
865
0
  GET_UINT32 (W[6],  data, 24);
866
0
  GET_UINT32 (W[7],  data, 28);
867
0
  GET_UINT32 (W[8],  data, 32);
868
0
  GET_UINT32 (W[9],  data, 36);
869
0
  GET_UINT32 (W[10], data, 40);
870
0
  GET_UINT32 (W[11], data, 44);
871
0
  GET_UINT32 (W[12], data, 48);
872
0
  GET_UINT32 (W[13], data, 52);
873
0
  GET_UINT32 (W[14], data, 56);
874
0
  GET_UINT32 (W[15], data, 60);
875
876
0
#define SHR(x,n)        ((x & 0xFFFFFFFF) >> n)
877
0
#define ROTR(x,n)       (SHR (x,n) | (x << (32 - n)))
878
879
0
#define S0(x) (ROTR (x, 7) ^ ROTR (x,18) ^  SHR (x, 3))
880
0
#define S1(x) (ROTR (x,17) ^ ROTR (x,19) ^  SHR (x,10))
881
0
#define S2(x) (ROTR (x, 2) ^ ROTR (x,13) ^ ROTR (x,22))
882
0
#define S3(x) (ROTR (x, 6) ^ ROTR (x,11) ^ ROTR (x,25))
883
884
0
#define F0(x,y,z) ((x & y) | (z & (x | y)))
885
0
#define F1(x,y,z) (z ^ (x & (y ^ z)))
886
887
0
#define R(t)    (W[t] = S1(W[t -  2]) + W[t -  7] + \
888
0
                        S0(W[t - 15]) + W[t - 16])
889
890
0
#define P(a,b,c,d,e,f,g,h,x,K)          G_STMT_START {  \
891
0
        temp1 = h + S3(e) + F1(e,f,g) + K + x;          \
892
0
        temp2 = S2(a) + F0(a,b,c);                      \
893
0
        d += temp1; h = temp1 + temp2; } G_STMT_END
894
895
0
  A = buf[0];
896
0
  B = buf[1];
897
0
  C = buf[2];
898
0
  D = buf[3];
899
0
  E = buf[4];
900
0
  F = buf[5];
901
0
  G = buf[6];
902
0
  H = buf[7];
903
904
0
  P (A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98);
905
0
  P (H, A, B, C, D, E, F, G, W[ 1], 0x71374491);
906
0
  P (G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF);
907
0
  P (F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5);
908
0
  P (E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B);
909
0
  P (D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1);
910
0
  P (C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4);
911
0
  P (B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5);
912
0
  P (A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98);
913
0
  P (H, A, B, C, D, E, F, G, W[ 9], 0x12835B01);
914
0
  P (G, H, A, B, C, D, E, F, W[10], 0x243185BE);
915
0
  P (F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
916
0
  P (E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
917
0
  P (D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
918
0
  P (C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
919
0
  P (B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
920
0
  P (A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
921
0
  P (H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
922
0
  P (G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
923
0
  P (F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
924
0
  P (E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
925
0
  P (D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
926
0
  P (C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
927
0
  P (B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
928
0
  P (A, B, C, D, E, F, G, H, R(24), 0x983E5152);
929
0
  P (H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
930
0
  P (G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
931
0
  P (F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
932
0
  P (E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
933
0
  P (D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
934
0
  P (C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
935
0
  P (B, C, D, E, F, G, H, A, R(31), 0x14292967);
936
0
  P (A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
937
0
  P (H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
938
0
  P (G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
939
0
  P (F, G, H, A, B, C, D, E, R(35), 0x53380D13);
940
0
  P (E, F, G, H, A, B, C, D, R(36), 0x650A7354);
941
0
  P (D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
942
0
  P (C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
943
0
  P (B, C, D, E, F, G, H, A, R(39), 0x92722C85);
944
0
  P (A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
945
0
  P (H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
946
0
  P (G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
947
0
  P (F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
948
0
  P (E, F, G, H, A, B, C, D, R(44), 0xD192E819);
949
0
  P (D, E, F, G, H, A, B, C, R(45), 0xD6990624);
950
0
  P (C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
951
0
  P (B, C, D, E, F, G, H, A, R(47), 0x106AA070);
952
0
  P (A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
953
0
  P (H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
954
0
  P (G, H, A, B, C, D, E, F, R(50), 0x2748774C);
955
0
  P (F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
956
0
  P (E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
957
0
  P (D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
958
0
  P (C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
959
0
  P (B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
960
0
  P (A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
961
0
  P (H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
962
0
  P (G, H, A, B, C, D, E, F, R(58), 0x84C87814);
963
0
  P (F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
964
0
  P (E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
965
0
  P (D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
966
0
  P (C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
967
0
  P (B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
968
969
0
#undef SHR
970
0
#undef ROTR
971
0
#undef S0
972
0
#undef S1
973
0
#undef S2
974
0
#undef S3
975
0
#undef F0
976
0
#undef F1
977
0
#undef R
978
0
#undef P
979
980
0
  buf[0] += A;
981
0
  buf[1] += B;
982
0
  buf[2] += C;
983
0
  buf[3] += D;
984
0
  buf[4] += E;
985
0
  buf[5] += F;
986
0
  buf[6] += G;
987
0
  buf[7] += H;
988
0
}
989
990
static void
991
sha256_sum_update (Sha256sum    *sha256,
992
                   const guchar *buffer,
993
                   gsize         length)
994
0
{
995
0
  guint32 left, fill;
996
0
  const guint8 *input = buffer;
997
998
0
  if (length == 0)
999
0
    return;
1000
1001
0
  left = sha256->bits[0] & 0x3F;
1002
0
  fill = 64 - left;
1003
1004
0
  sha256->bits[0] += length;
1005
0
  sha256->bits[0] &= 0xFFFFFFFF;
1006
1007
0
  if (sha256->bits[0] < length)
1008
0
      sha256->bits[1]++;
1009
1010
0
  if (left > 0 && length >= fill)
1011
0
    {
1012
0
      memcpy ((sha256->data + left), input, fill);
1013
1014
0
      sha256_transform (sha256->buf, sha256->data);
1015
0
      length -= fill;
1016
0
      input += fill;
1017
1018
0
      left = 0;
1019
0
    }
1020
1021
0
  while (length >= SHA256_DATASIZE)
1022
0
    {
1023
0
      sha256_transform (sha256->buf, input);
1024
1025
0
      length -= 64;
1026
0
      input += 64;
1027
0
    }
1028
1029
0
  if (length)
1030
0
    memcpy (sha256->data + left, input, length);
1031
0
}
1032
1033
static guint8 sha256_padding[64] =
1034
{
1035
 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1036
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1037
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1038
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1039
};
1040
1041
static void
1042
sha256_sum_close (Sha256sum *sha256)
1043
0
{
1044
0
  guint32 last, padn;
1045
0
  guint32 high, low;
1046
0
  guint8 msglen[8];
1047
1048
0
  high = (sha256->bits[0] >> 29)
1049
0
       | (sha256->bits[1] <<  3);
1050
0
  low  = (sha256->bits[0] <<  3);
1051
1052
0
  PUT_UINT32 (high, msglen, 0);
1053
0
  PUT_UINT32 (low, msglen, 4);
1054
1055
0
  last = sha256->bits[0] & 0x3F;
1056
0
  padn = (last < 56) ? (56 - last) : (120 - last);
1057
1058
0
  sha256_sum_update (sha256, sha256_padding, padn);
1059
0
  sha256_sum_update (sha256, msglen, 8);
1060
1061
0
  PUT_UINT32 (sha256->buf[0], sha256->digest,  0);
1062
0
  PUT_UINT32 (sha256->buf[1], sha256->digest,  4);
1063
0
  PUT_UINT32 (sha256->buf[2], sha256->digest,  8);
1064
0
  PUT_UINT32 (sha256->buf[3], sha256->digest, 12);
1065
0
  PUT_UINT32 (sha256->buf[4], sha256->digest, 16);
1066
0
  PUT_UINT32 (sha256->buf[5], sha256->digest, 20);
1067
0
  PUT_UINT32 (sha256->buf[6], sha256->digest, 24);
1068
0
  PUT_UINT32 (sha256->buf[7], sha256->digest, 28);
1069
0
}
1070
1071
#undef PUT_UINT32
1072
#undef GET_UINT32
1073
1074
static gchar *
1075
sha256_sum_to_string (Sha256sum *sha256)
1076
0
{
1077
0
  return digest_to_string (sha256->digest, SHA256_DIGEST_LEN);
1078
0
}
1079
1080
static void
1081
sha256_sum_digest (Sha256sum *sha256,
1082
                   guint8    *digest)
1083
0
{
1084
0
  gint i;
1085
1086
0
  for (i = 0; i < SHA256_DIGEST_LEN; i++)
1087
0
    digest[i] = sha256->digest[i];
1088
0
}
1089
1090
/*
1091
 * SHA-384, SHA-512, SHA-512/224 and SHA-512/256 Checksums
1092
 *
1093
 * Implemented following FIPS-180-4 standard at
1094
 * http://csrc.nist.gov/publications/fips/fips180-4/fips180-4.pdf.
1095
 * References in the form [§x.y.z] map to sections in that document.
1096
 *
1097
 *   Author(s): Eduardo Lima Mitev <elima@igalia.com>
1098
 *              Igor Gnatenko <ignatenko@src.gnome.org>
1099
 */
1100
1101
/* SHA-384, SHA-512, SHA-512/224 and SHA-512/256 functions [§4.1.3] */
1102
0
#define Ch(x,y,z)  ((x & y) ^ (~x & z))
1103
0
#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
1104
0
#define SHR(n,x)   (x >> n)
1105
0
#define ROTR(n,x)  (SHR (n, x) | (x << (64 - n)))
1106
0
#define SIGMA0(x)  (ROTR (28, x) ^ ROTR (34, x) ^ ROTR (39, x))
1107
0
#define SIGMA1(x)  (ROTR (14, x) ^ ROTR (18, x) ^ ROTR (41, x))
1108
0
#define sigma0(x)  (ROTR ( 1, x) ^ ROTR ( 8, x) ^ SHR  ( 7, x))
1109
0
#define sigma1(x)  (ROTR (19, x) ^ ROTR (61, x) ^ SHR  ( 6, x))
1110
1111
0
#define PUT_UINT64(n,b,i)                G_STMT_START{   \
1112
0
    (b)[(i)    ] = (guint8) (n >> 56);                   \
1113
0
    (b)[(i) + 1] = (guint8) (n >> 48);                   \
1114
0
    (b)[(i) + 2] = (guint8) (n >> 40);                   \
1115
0
    (b)[(i) + 3] = (guint8) (n >> 32);                   \
1116
0
    (b)[(i) + 4] = (guint8) (n >> 24);                   \
1117
0
    (b)[(i) + 5] = (guint8) (n >> 16);                   \
1118
0
    (b)[(i) + 6] = (guint8) (n >>  8);                   \
1119
0
    (b)[(i) + 7] = (guint8) (n      ); } G_STMT_END
1120
1121
/* SHA-384 and SHA-512 constants [§4.2.3] */
1122
static const guint64 SHA2_K[80] = {
1123
  G_GUINT64_CONSTANT (0x428a2f98d728ae22), G_GUINT64_CONSTANT (0x7137449123ef65cd),
1124
  G_GUINT64_CONSTANT (0xb5c0fbcfec4d3b2f), G_GUINT64_CONSTANT (0xe9b5dba58189dbbc),
1125
  G_GUINT64_CONSTANT (0x3956c25bf348b538), G_GUINT64_CONSTANT (0x59f111f1b605d019),
1126
  G_GUINT64_CONSTANT (0x923f82a4af194f9b), G_GUINT64_CONSTANT (0xab1c5ed5da6d8118),
1127
  G_GUINT64_CONSTANT (0xd807aa98a3030242), G_GUINT64_CONSTANT (0x12835b0145706fbe),
1128
  G_GUINT64_CONSTANT (0x243185be4ee4b28c), G_GUINT64_CONSTANT (0x550c7dc3d5ffb4e2),
1129
  G_GUINT64_CONSTANT (0x72be5d74f27b896f), G_GUINT64_CONSTANT (0x80deb1fe3b1696b1),
1130
  G_GUINT64_CONSTANT (0x9bdc06a725c71235), G_GUINT64_CONSTANT (0xc19bf174cf692694),
1131
  G_GUINT64_CONSTANT (0xe49b69c19ef14ad2), G_GUINT64_CONSTANT (0xefbe4786384f25e3),
1132
  G_GUINT64_CONSTANT (0x0fc19dc68b8cd5b5), G_GUINT64_CONSTANT (0x240ca1cc77ac9c65),
1133
  G_GUINT64_CONSTANT (0x2de92c6f592b0275), G_GUINT64_CONSTANT (0x4a7484aa6ea6e483),
1134
  G_GUINT64_CONSTANT (0x5cb0a9dcbd41fbd4), G_GUINT64_CONSTANT (0x76f988da831153b5),
1135
  G_GUINT64_CONSTANT (0x983e5152ee66dfab), G_GUINT64_CONSTANT (0xa831c66d2db43210),
1136
  G_GUINT64_CONSTANT (0xb00327c898fb213f), G_GUINT64_CONSTANT (0xbf597fc7beef0ee4),
1137
  G_GUINT64_CONSTANT (0xc6e00bf33da88fc2), G_GUINT64_CONSTANT (0xd5a79147930aa725),
1138
  G_GUINT64_CONSTANT (0x06ca6351e003826f), G_GUINT64_CONSTANT (0x142929670a0e6e70),
1139
  G_GUINT64_CONSTANT (0x27b70a8546d22ffc), G_GUINT64_CONSTANT (0x2e1b21385c26c926),
1140
  G_GUINT64_CONSTANT (0x4d2c6dfc5ac42aed), G_GUINT64_CONSTANT (0x53380d139d95b3df),
1141
  G_GUINT64_CONSTANT (0x650a73548baf63de), G_GUINT64_CONSTANT (0x766a0abb3c77b2a8),
1142
  G_GUINT64_CONSTANT (0x81c2c92e47edaee6), G_GUINT64_CONSTANT (0x92722c851482353b),
1143
  G_GUINT64_CONSTANT (0xa2bfe8a14cf10364), G_GUINT64_CONSTANT (0xa81a664bbc423001),
1144
  G_GUINT64_CONSTANT (0xc24b8b70d0f89791), G_GUINT64_CONSTANT (0xc76c51a30654be30),
1145
  G_GUINT64_CONSTANT (0xd192e819d6ef5218), G_GUINT64_CONSTANT (0xd69906245565a910),
1146
  G_GUINT64_CONSTANT (0xf40e35855771202a), G_GUINT64_CONSTANT (0x106aa07032bbd1b8),
1147
  G_GUINT64_CONSTANT (0x19a4c116b8d2d0c8), G_GUINT64_CONSTANT (0x1e376c085141ab53),
1148
  G_GUINT64_CONSTANT (0x2748774cdf8eeb99), G_GUINT64_CONSTANT (0x34b0bcb5e19b48a8),
1149
  G_GUINT64_CONSTANT (0x391c0cb3c5c95a63), G_GUINT64_CONSTANT (0x4ed8aa4ae3418acb),
1150
  G_GUINT64_CONSTANT (0x5b9cca4f7763e373), G_GUINT64_CONSTANT (0x682e6ff3d6b2b8a3),
1151
  G_GUINT64_CONSTANT (0x748f82ee5defb2fc), G_GUINT64_CONSTANT (0x78a5636f43172f60),
1152
  G_GUINT64_CONSTANT (0x84c87814a1f0ab72), G_GUINT64_CONSTANT (0x8cc702081a6439ec),
1153
  G_GUINT64_CONSTANT (0x90befffa23631e28), G_GUINT64_CONSTANT (0xa4506cebde82bde9),
1154
  G_GUINT64_CONSTANT (0xbef9a3f7b2c67915), G_GUINT64_CONSTANT (0xc67178f2e372532b),
1155
  G_GUINT64_CONSTANT (0xca273eceea26619c), G_GUINT64_CONSTANT (0xd186b8c721c0c207),
1156
  G_GUINT64_CONSTANT (0xeada7dd6cde0eb1e), G_GUINT64_CONSTANT (0xf57d4f7fee6ed178),
1157
  G_GUINT64_CONSTANT (0x06f067aa72176fba), G_GUINT64_CONSTANT (0x0a637dc5a2c898a6),
1158
  G_GUINT64_CONSTANT (0x113f9804bef90dae), G_GUINT64_CONSTANT (0x1b710b35131c471b),
1159
  G_GUINT64_CONSTANT (0x28db77f523047d84), G_GUINT64_CONSTANT (0x32caab7b40c72493),
1160
  G_GUINT64_CONSTANT (0x3c9ebe0a15c9bebc), G_GUINT64_CONSTANT (0x431d67c49c100d4c),
1161
  G_GUINT64_CONSTANT (0x4cc5d4becb3e42b6), G_GUINT64_CONSTANT (0x597f299cfc657e2a),
1162
  G_GUINT64_CONSTANT (0x5fcb6fab3ad6faec), G_GUINT64_CONSTANT (0x6c44198c4a475817)
1163
};
1164
1165
1166
static void
1167
sha384_sum_init (Sha512sum *sha512)
1168
0
{
1169
  /* Initial Hash Value [§5.3.4] */
1170
0
  sha512->H[0] = G_GUINT64_CONSTANT (0xcbbb9d5dc1059ed8);
1171
0
  sha512->H[1] = G_GUINT64_CONSTANT (0x629a292a367cd507);
1172
0
  sha512->H[2] = G_GUINT64_CONSTANT (0x9159015a3070dd17);
1173
0
  sha512->H[3] = G_GUINT64_CONSTANT (0x152fecd8f70e5939);
1174
0
  sha512->H[4] = G_GUINT64_CONSTANT (0x67332667ffc00b31);
1175
0
  sha512->H[5] = G_GUINT64_CONSTANT (0x8eb44a8768581511);
1176
0
  sha512->H[6] = G_GUINT64_CONSTANT (0xdb0c2e0d64f98fa7);
1177
0
  sha512->H[7] = G_GUINT64_CONSTANT (0x47b5481dbefa4fa4);
1178
1179
0
  sha512->block_len = 0;
1180
1181
0
  sha512->data_len[0] = 0;
1182
0
  sha512->data_len[1] = 0;
1183
0
}
1184
1185
static void
1186
sha512_sum_init (Sha512sum *sha512)
1187
0
{
1188
  /* Initial Hash Value [§5.3.5] */
1189
0
  sha512->H[0] = G_GUINT64_CONSTANT (0x6a09e667f3bcc908);
1190
0
  sha512->H[1] = G_GUINT64_CONSTANT (0xbb67ae8584caa73b);
1191
0
  sha512->H[2] = G_GUINT64_CONSTANT (0x3c6ef372fe94f82b);
1192
0
  sha512->H[3] = G_GUINT64_CONSTANT (0xa54ff53a5f1d36f1);
1193
0
  sha512->H[4] = G_GUINT64_CONSTANT (0x510e527fade682d1);
1194
0
  sha512->H[5] = G_GUINT64_CONSTANT (0x9b05688c2b3e6c1f);
1195
0
  sha512->H[6] = G_GUINT64_CONSTANT (0x1f83d9abfb41bd6b);
1196
0
  sha512->H[7] = G_GUINT64_CONSTANT (0x5be0cd19137e2179);
1197
1198
0
  sha512->block_len = 0;
1199
1200
0
  sha512->data_len[0] = 0;
1201
0
  sha512->data_len[1] = 0;
1202
0
}
1203
1204
static void
1205
sha512_transform (guint64      H[8],
1206
                  guint8 const data[SHA2_BLOCK_LEN])
1207
0
{
1208
0
  gint i;
1209
0
  gint t;
1210
0
  guint64 a, b, c, d, e, f, g, h;
1211
0
  guint64 M[16];
1212
0
  guint64 W[80];
1213
1214
  /* SHA-512 hash computation [§6.4.2] */
1215
1216
  /* prepare the message schedule */
1217
0
  for (i = 0; i < 16; i++)
1218
0
    {
1219
0
      gint p = i * 8;
1220
1221
0
      M[i] =
1222
0
        ((guint64) data[p + 0] << 56) |
1223
0
        ((guint64) data[p + 1] << 48) |
1224
0
        ((guint64) data[p + 2] << 40) |
1225
0
        ((guint64) data[p + 3] << 32) |
1226
0
        ((guint64) data[p + 4] << 24) |
1227
0
        ((guint64) data[p + 5] << 16) |
1228
0
        ((guint64) data[p + 6] <<  8) |
1229
0
        ((guint64) data[p + 7]      );
1230
0
    }
1231
1232
0
  for (t = 0; t < 80; t++)
1233
0
    if (t < 16)
1234
0
      W[t] = M[t];
1235
0
    else
1236
0
      W[t] = sigma1 (W[t - 2]) + W[t - 7] + sigma0 (W[t - 15]) + W[t - 16];
1237
1238
  /* initialize the eight working variables */
1239
0
  a = H[0];
1240
0
  b = H[1];
1241
0
  c = H[2];
1242
0
  d = H[3];
1243
0
  e = H[4];
1244
0
  f = H[5];
1245
0
  g = H[6];
1246
0
  h = H[7];
1247
1248
0
  for (t = 0; t < 80; t++)
1249
0
    {
1250
0
      guint64 T1, T2;
1251
1252
0
      T1 = h + SIGMA1 (e) + Ch (e, f, g) + SHA2_K[t] + W[t];
1253
0
      T2 = SIGMA0 (a) + Maj (a, b, c);
1254
0
      h = g;
1255
0
      g = f;
1256
0
      f = e;
1257
0
      e = d + T1;
1258
0
      d = c;
1259
0
      c = b;
1260
0
      b = a;
1261
0
      a = T1 + T2;
1262
0
    }
1263
1264
  /* Compute the intermediate hash value H */
1265
0
  H[0] += a;
1266
0
  H[1] += b;
1267
0
  H[2] += c;
1268
0
  H[3] += d;
1269
0
  H[4] += e;
1270
0
  H[5] += f;
1271
0
  H[6] += g;
1272
0
  H[7] += h;
1273
0
}
1274
1275
static void
1276
sha512_sum_update (Sha512sum    *sha512,
1277
                   const guchar *buffer,
1278
                   gsize         length)
1279
0
{
1280
0
  gsize block_left, offset = 0;
1281
1282
0
  if (length == 0)
1283
0
    return;
1284
1285
0
  sha512->data_len[0] += length * 8;
1286
0
  if (sha512->data_len[0] < length)
1287
0
    sha512->data_len[1]++;
1288
1289
  /* try to fill current block */
1290
0
  block_left = SHA2_BLOCK_LEN - sha512->block_len;
1291
0
  if (block_left > 0)
1292
0
    {
1293
0
      gsize fill_len;
1294
1295
0
      fill_len = MIN (block_left, length);
1296
0
      memcpy (sha512->block + sha512->block_len, buffer, fill_len);
1297
0
      sha512->block_len += fill_len;
1298
0
      length -= fill_len;
1299
0
      offset += fill_len;
1300
1301
0
      if (sha512->block_len == SHA2_BLOCK_LEN)
1302
0
        {
1303
0
          sha512_transform (sha512->H, sha512->block);
1304
0
          sha512->block_len = 0;
1305
0
        }
1306
0
    }
1307
1308
  /* process complete blocks */
1309
0
  while (length >= SHA2_BLOCK_LEN)
1310
0
    {
1311
0
      memcpy (sha512->block, buffer + offset, SHA2_BLOCK_LEN);
1312
1313
0
      sha512_transform (sha512->H, sha512->block);
1314
1315
0
      length -= SHA2_BLOCK_LEN;
1316
0
      offset += SHA2_BLOCK_LEN;
1317
0
    }
1318
1319
  /* keep remaining data for next block */
1320
0
  if (length > 0)
1321
0
    {
1322
0
      memcpy (sha512->block, buffer + offset, length);
1323
0
      sha512->block_len = length;
1324
0
    }
1325
0
}
1326
1327
static void
1328
sha512_sum_close (Sha512sum *sha512)
1329
0
{
1330
0
  guint l;
1331
0
  size_t zeros;
1332
0
  guint8 pad[SHA2_BLOCK_LEN * 2] = { 0, };
1333
0
  size_t pad_len = 0;
1334
0
  size_t i;
1335
1336
  /* apply padding [§5.1.2] */
1337
0
  l = sha512->block_len * 8;
1338
1339
0
  if (896 < l + 1)
1340
0
    zeros = 896 - (l + 1) + 128 * 8;
1341
0
  else
1342
0
    zeros = 896 - (l + 1);
1343
1344
0
  pad[0] = 0x80; /* 1000 0000 */
1345
0
  zeros -= 7;
1346
0
  pad_len++;
1347
1348
0
  memset (pad + pad_len, 0x00, zeros / 8);
1349
0
  pad_len += zeros / 8;
1350
0
  zeros = zeros % 8;
1351
0
  (void) zeros;  /* don’t care about the dead store */
1352
1353
  /* put message bit length at the end of padding */
1354
0
  PUT_UINT64 (sha512->data_len[1], pad, pad_len);
1355
0
  pad_len += 8;
1356
1357
0
  PUT_UINT64 (sha512->data_len[0], pad, pad_len);
1358
0
  pad_len += 8;
1359
1360
  /* update checksum with the padded block */
1361
0
  sha512_sum_update (sha512, pad, pad_len);
1362
1363
  /* copy resulting 64-bit words into digest */
1364
0
  for (i = 0; i < 8; i++)
1365
0
    PUT_UINT64 (sha512->H[i], sha512->digest, i * 8);
1366
0
}
1367
1368
static gchar *
1369
sha384_sum_to_string (Sha512sum *sha512)
1370
0
{
1371
0
  return digest_to_string (sha512->digest, SHA384_DIGEST_LEN);
1372
0
}
1373
1374
static gchar *
1375
sha512_sum_to_string (Sha512sum *sha512)
1376
0
{
1377
0
  return digest_to_string (sha512->digest, SHA512_DIGEST_LEN);
1378
0
}
1379
1380
static void
1381
sha384_sum_digest (Sha512sum *sha512,
1382
                   guint8    *digest)
1383
0
{
1384
0
  memcpy (digest, sha512->digest, SHA384_DIGEST_LEN);
1385
0
}
1386
1387
static void
1388
sha512_sum_digest (Sha512sum *sha512,
1389
                   guint8    *digest)
1390
0
{
1391
0
  memcpy (digest, sha512->digest, SHA512_DIGEST_LEN);
1392
0
}
1393
1394
#undef Ch
1395
#undef Maj
1396
#undef SHR
1397
#undef ROTR
1398
#undef SIGMA0
1399
#undef SIGMA1
1400
#undef sigma0
1401
#undef sigma1
1402
1403
#undef PUT_UINT64
1404
1405
/*
1406
 * Public API
1407
 */
1408
1409
/**
1410
 * g_checksum_type_get_length:
1411
 * @checksum_type: a #GChecksumType
1412
 *
1413
 * Gets the length in bytes of digests of type @checksum_type
1414
 *
1415
 * Returns: the checksum length, or -1 if @checksum_type is
1416
 * not supported.
1417
 *
1418
 * Since: 2.16
1419
 */
1420
gssize
1421
g_checksum_type_get_length (GChecksumType checksum_type)
1422
0
{
1423
0
  gssize len = -1;
1424
1425
0
  switch (checksum_type)
1426
0
    {
1427
0
    case G_CHECKSUM_MD5:
1428
0
      len = MD5_DIGEST_LEN;
1429
0
      break;
1430
0
    case G_CHECKSUM_SHA1:
1431
0
      len = SHA1_DIGEST_LEN;
1432
0
      break;
1433
0
    case G_CHECKSUM_SHA256:
1434
0
      len = SHA256_DIGEST_LEN;
1435
0
      break;
1436
0
    case G_CHECKSUM_SHA384:
1437
0
      len = SHA384_DIGEST_LEN;
1438
0
      break;
1439
0
    case G_CHECKSUM_SHA512:
1440
0
      len = SHA512_DIGEST_LEN;
1441
0
      break;
1442
0
    default:
1443
0
      len = -1;
1444
0
      break;
1445
0
    }
1446
1447
0
  return len;
1448
0
}
1449
1450
/**
1451
 * g_checksum_new:
1452
 * @checksum_type: the desired type of checksum
1453
 *
1454
 * Creates a new #GChecksum, using the checksum algorithm @checksum_type.
1455
 * If the @checksum_type is not known, %NULL is returned.
1456
 * A #GChecksum can be used to compute the checksum, or digest, of an
1457
 * arbitrary binary blob, using different hashing algorithms.
1458
 *
1459
 * A #GChecksum works by feeding a binary blob through g_checksum_update()
1460
 * until there is data to be checked; the digest can then be extracted
1461
 * using g_checksum_get_string(), which will return the checksum as a
1462
 * hexadecimal string; or g_checksum_get_digest(), which will return a
1463
 * vector of raw bytes. Once either g_checksum_get_string() or
1464
 * g_checksum_get_digest() have been called on a #GChecksum, the checksum
1465
 * will be closed and it won't be possible to call g_checksum_update()
1466
 * on it anymore.
1467
 *
1468
 * Returns: (transfer full) (nullable): the newly created #GChecksum, or %NULL.
1469
 *   Use g_checksum_free() to free the memory allocated by it.
1470
 *
1471
 * Since: 2.16
1472
 */
1473
GChecksum *
1474
g_checksum_new (GChecksumType checksum_type)
1475
0
{
1476
0
  GChecksum *checksum;
1477
1478
0
  if (! IS_VALID_TYPE (checksum_type))
1479
0
    return NULL;
1480
1481
0
  checksum = g_slice_new0 (GChecksum);
1482
0
  checksum->type = checksum_type;
1483
1484
0
  g_checksum_reset (checksum);
1485
1486
0
  return checksum;
1487
0
}
1488
1489
/**
1490
 * g_checksum_reset:
1491
 * @checksum: the #GChecksum to reset
1492
 *
1493
 * Resets the state of the @checksum back to its initial state.
1494
 *
1495
 * Since: 2.18
1496
 **/
1497
void
1498
g_checksum_reset (GChecksum *checksum)
1499
0
{
1500
0
  g_return_if_fail (checksum != NULL);
1501
1502
0
  g_free (checksum->digest_str);
1503
0
  checksum->digest_str = NULL;
1504
1505
0
  switch (checksum->type)
1506
0
    {
1507
0
    case G_CHECKSUM_MD5:
1508
0
      md5_sum_init (&(checksum->sum.md5));
1509
0
      break;
1510
0
    case G_CHECKSUM_SHA1:
1511
0
      sha1_sum_init (&(checksum->sum.sha1));
1512
0
      break;
1513
0
    case G_CHECKSUM_SHA256:
1514
0
      sha256_sum_init (&(checksum->sum.sha256));
1515
0
      break;
1516
0
    case G_CHECKSUM_SHA384:
1517
0
      sha384_sum_init (&(checksum->sum.sha512));
1518
0
      break;
1519
0
    case G_CHECKSUM_SHA512:
1520
0
      sha512_sum_init (&(checksum->sum.sha512));
1521
0
      break;
1522
0
    default:
1523
0
      g_assert_not_reached ();
1524
0
      break;
1525
0
    }
1526
0
}
1527
1528
/**
1529
 * g_checksum_copy:
1530
 * @checksum: the #GChecksum to copy
1531
 *
1532
 * Copies a #GChecksum. If @checksum has been closed, by calling
1533
 * g_checksum_get_string() or g_checksum_get_digest(), the copied
1534
 * checksum will be closed as well.
1535
 *
1536
 * Returns: (transfer full): the copy of the passed #GChecksum. Use
1537
 *   g_checksum_free() when finished using it.
1538
 *
1539
 * Since: 2.16
1540
 */
1541
GChecksum *
1542
g_checksum_copy (const GChecksum *checksum)
1543
0
{
1544
0
  GChecksum *copy;
1545
1546
0
  g_return_val_if_fail (checksum != NULL, NULL);
1547
1548
0
  copy = g_slice_new (GChecksum);
1549
0
  *copy = *checksum;
1550
1551
0
  copy->digest_str = g_strdup (checksum->digest_str);
1552
1553
0
  return copy;
1554
0
}
1555
1556
/**
1557
 * g_checksum_free:
1558
 * @checksum: a #GChecksum
1559
 *
1560
 * Frees the memory allocated for @checksum.
1561
 *
1562
 * Since: 2.16
1563
 */
1564
void
1565
g_checksum_free (GChecksum *checksum)
1566
0
{
1567
0
  if (G_LIKELY (checksum))
1568
0
    {
1569
0
      g_free (checksum->digest_str);
1570
1571
0
      g_slice_free (GChecksum, checksum);
1572
0
    }
1573
0
}
1574
1575
/* Internal variant of g_checksum_update() which takes an explicit length and
1576
 * doesn’t use strlen() internally. */
1577
static void
1578
checksum_update_internal (GChecksum    *checksum,
1579
                          const guchar *data,
1580
                          size_t        length)
1581
0
{
1582
0
  g_return_if_fail (checksum != NULL);
1583
0
  g_return_if_fail (length == 0 || data != NULL);
1584
1585
0
  if (checksum->digest_str)
1586
0
    {
1587
0
      g_warning ("The checksum '%s' has been closed and cannot be updated "
1588
0
                 "any more.",
1589
0
                 checksum->digest_str);
1590
0
      return;
1591
0
    }
1592
1593
0
  switch (checksum->type)
1594
0
    {
1595
0
    case G_CHECKSUM_MD5:
1596
0
      md5_sum_update (&(checksum->sum.md5), data, length);
1597
0
      break;
1598
0
    case G_CHECKSUM_SHA1:
1599
0
      sha1_sum_update (&(checksum->sum.sha1), data, length);
1600
0
      break;
1601
0
    case G_CHECKSUM_SHA256:
1602
0
      sha256_sum_update (&(checksum->sum.sha256), data, length);
1603
0
      break;
1604
0
    case G_CHECKSUM_SHA384:
1605
0
    case G_CHECKSUM_SHA512:
1606
0
      sha512_sum_update (&(checksum->sum.sha512), data, length);
1607
0
      break;
1608
0
    default:
1609
0
      g_assert_not_reached ();
1610
0
      break;
1611
0
    }
1612
0
}
1613
1614
/**
1615
 * g_checksum_update:
1616
 * @checksum: a #GChecksum
1617
 * @data: (array length=length) (element-type guint8): buffer used to compute the checksum
1618
 * @length: size of the buffer, or -1 if it is a null-terminated string.
1619
 *
1620
 * Feeds @data into an existing #GChecksum. The checksum must still be
1621
 * open, that is g_checksum_get_string() or g_checksum_get_digest() must
1622
 * not have been called on @checksum.
1623
 *
1624
 * Since: 2.16
1625
 */
1626
void
1627
g_checksum_update (GChecksum    *checksum,
1628
                   const guchar *data,
1629
                   gssize        length)
1630
0
{
1631
0
  size_t unsigned_length;
1632
1633
0
  g_return_if_fail (checksum != NULL);
1634
0
  g_return_if_fail (length == 0 || data != NULL);
1635
1636
0
  if (length < 0)
1637
0
    unsigned_length = strlen ((const gchar *) data);
1638
0
  else
1639
0
    unsigned_length = (size_t) length;
1640
1641
0
  checksum_update_internal (checksum, data, unsigned_length);
1642
0
}
1643
1644
/**
1645
 * g_checksum_get_string:
1646
 * @checksum: a #GChecksum
1647
 *
1648
 * Gets the digest as a hexadecimal string.
1649
 *
1650
 * Once this function has been called the #GChecksum can no longer be
1651
 * updated with g_checksum_update().
1652
 *
1653
 * The hexadecimal characters will be lower case.
1654
 *
1655
 * Returns: the hexadecimal representation of the checksum. The
1656
 *   returned string is owned by the checksum and should not be modified
1657
 *   or freed.
1658
 *
1659
 * Since: 2.16
1660
 */
1661
const gchar *
1662
g_checksum_get_string (GChecksum *checksum)
1663
0
{
1664
0
  gchar *str = NULL;
1665
1666
0
  g_return_val_if_fail (checksum != NULL, NULL);
1667
1668
0
  if (checksum->digest_str)
1669
0
    return checksum->digest_str;
1670
1671
0
  switch (checksum->type)
1672
0
    {
1673
0
    case G_CHECKSUM_MD5:
1674
0
      md5_sum_close (&(checksum->sum.md5));
1675
0
      str = md5_sum_to_string (&(checksum->sum.md5));
1676
0
      break;
1677
0
    case G_CHECKSUM_SHA1:
1678
0
      sha1_sum_close (&(checksum->sum.sha1));
1679
0
      str = sha1_sum_to_string (&(checksum->sum.sha1));
1680
0
      break;
1681
0
    case G_CHECKSUM_SHA256:
1682
0
      sha256_sum_close (&(checksum->sum.sha256));
1683
0
      str = sha256_sum_to_string (&(checksum->sum.sha256));
1684
0
      break;
1685
0
    case G_CHECKSUM_SHA384:
1686
0
      sha512_sum_close (&(checksum->sum.sha512));
1687
0
      str = sha384_sum_to_string (&(checksum->sum.sha512));
1688
0
      break;
1689
0
    case G_CHECKSUM_SHA512:
1690
0
      sha512_sum_close (&(checksum->sum.sha512));
1691
0
      str = sha512_sum_to_string (&(checksum->sum.sha512));
1692
0
      break;
1693
0
    default:
1694
0
      g_assert_not_reached ();
1695
0
      break;
1696
0
    }
1697
1698
0
  checksum->digest_str = str;
1699
1700
0
  return checksum->digest_str;
1701
0
}
1702
1703
/**
1704
 * g_checksum_get_digest: (skip)
1705
 * @checksum: a #GChecksum
1706
 * @buffer: (array length=digest_len): output buffer
1707
 * @digest_len: (inout): an inout parameter. The caller initializes it to the size of @buffer.
1708
 *   After the call it contains the length of the digest.
1709
 *
1710
 * Gets the digest from @checksum as a raw binary vector and places it
1711
 * into @buffer. The size of the digest depends on the type of checksum.
1712
 *
1713
 * Once this function has been called, the #GChecksum is closed and can
1714
 * no longer be updated with g_checksum_update().
1715
 *
1716
 * Since: 2.16
1717
 */
1718
void
1719
g_checksum_get_digest (GChecksum  *checksum,
1720
                       guint8     *buffer,
1721
                       gsize      *digest_len)
1722
0
{
1723
0
  gboolean checksum_open = FALSE;
1724
0
  gchar *str = NULL;
1725
0
  gssize signed_len;
1726
0
  gsize len;
1727
1728
0
  g_return_if_fail (checksum != NULL);
1729
1730
0
  signed_len = g_checksum_type_get_length (checksum->type);
1731
0
  g_assert (signed_len >= 0);  /* @checksum should be internally consistent */
1732
0
  len = (size_t) signed_len;
1733
0
  g_return_if_fail (*digest_len >= len);
1734
1735
0
  checksum_open = !!(checksum->digest_str == NULL);
1736
1737
0
  switch (checksum->type)
1738
0
    {
1739
0
    case G_CHECKSUM_MD5:
1740
0
      if (checksum_open)
1741
0
        {
1742
0
          md5_sum_close (&(checksum->sum.md5));
1743
0
          str = md5_sum_to_string (&(checksum->sum.md5));
1744
0
        }
1745
0
      md5_sum_digest (&(checksum->sum.md5), buffer);
1746
0
      break;
1747
0
    case G_CHECKSUM_SHA1:
1748
0
      if (checksum_open)
1749
0
        {
1750
0
          sha1_sum_close (&(checksum->sum.sha1));
1751
0
          str = sha1_sum_to_string (&(checksum->sum.sha1));
1752
0
        }
1753
0
      sha1_sum_digest (&(checksum->sum.sha1), buffer);
1754
0
      break;
1755
0
    case G_CHECKSUM_SHA256:
1756
0
      if (checksum_open)
1757
0
        {
1758
0
          sha256_sum_close (&(checksum->sum.sha256));
1759
0
          str = sha256_sum_to_string (&(checksum->sum.sha256));
1760
0
        }
1761
0
      sha256_sum_digest (&(checksum->sum.sha256), buffer);
1762
0
      break;
1763
0
    case G_CHECKSUM_SHA384:
1764
0
      if (checksum_open)
1765
0
        {
1766
0
          sha512_sum_close (&(checksum->sum.sha512));
1767
0
          str = sha384_sum_to_string (&(checksum->sum.sha512));
1768
0
        }
1769
0
      sha384_sum_digest (&(checksum->sum.sha512), buffer);
1770
0
      break;
1771
0
    case G_CHECKSUM_SHA512:
1772
0
      if (checksum_open)
1773
0
        {
1774
0
          sha512_sum_close (&(checksum->sum.sha512));
1775
0
          str = sha512_sum_to_string (&(checksum->sum.sha512));
1776
0
        }
1777
0
      sha512_sum_digest (&(checksum->sum.sha512), buffer);
1778
0
      break;
1779
0
    default:
1780
0
      g_assert_not_reached ();
1781
0
      break;
1782
0
    }
1783
1784
0
  if (str)
1785
0
    checksum->digest_str = str;
1786
1787
0
  *digest_len = len;
1788
0
}
1789
1790
/**
1791
 * g_compute_checksum_for_data:
1792
 * @checksum_type: a #GChecksumType
1793
 * @data: (array length=length) (element-type guint8): binary blob to compute the digest of
1794
 * @length: length of @data
1795
 *
1796
 * Computes the checksum for a binary @data of @length. This is a
1797
 * convenience wrapper for g_checksum_new(), g_checksum_get_string()
1798
 * and g_checksum_free().
1799
 *
1800
 * The hexadecimal string returned will be in lower case.
1801
 *
1802
 * Returns: (transfer full) (nullable): the digest of the binary data as a
1803
 *   string in hexadecimal, or %NULL if g_checksum_new() fails for
1804
 *   @checksum_type. The returned string should be freed with g_free() when
1805
 *   done using it.
1806
 *
1807
 * Since: 2.16
1808
 */
1809
gchar *
1810
g_compute_checksum_for_data (GChecksumType  checksum_type,
1811
                             const guchar  *data,
1812
                             gsize          length)
1813
0
{
1814
0
  GChecksum *checksum;
1815
0
  gchar *retval;
1816
1817
0
  g_return_val_if_fail (length == 0 || data != NULL, NULL);
1818
1819
0
  checksum = g_checksum_new (checksum_type);
1820
0
  if (!checksum)
1821
0
    return NULL;
1822
1823
0
  checksum_update_internal (checksum, data, length);
1824
0
  retval = g_strdup (g_checksum_get_string (checksum));
1825
0
  g_checksum_free (checksum);
1826
1827
0
  return retval;
1828
0
}
1829
1830
/**
1831
 * g_compute_checksum_for_string:
1832
 * @checksum_type: a #GChecksumType
1833
 * @str: the string to compute the checksum of
1834
 * @length: the length of the string, or -1 if the string is null-terminated.
1835
 *
1836
 * Computes the checksum of a string.
1837
 *
1838
 * The hexadecimal string returned will be in lower case.
1839
 *
1840
 * Returns: (transfer full) (nullable): the checksum as a hexadecimal string,
1841
 *   or %NULL if g_checksum_new() fails for @checksum_type. The returned string
1842
 *   should be freed with g_free() when done using it.
1843
 *
1844
 * Since: 2.16
1845
 */
1846
gchar *
1847
g_compute_checksum_for_string (GChecksumType  checksum_type,
1848
                               const gchar   *str,
1849
                               gssize         length)
1850
0
{
1851
0
  size_t unsigned_length;
1852
1853
0
  g_return_val_if_fail (length == 0 || str != NULL, NULL);
1854
1855
0
  if (length < 0)
1856
0
    unsigned_length = strlen (str);
1857
0
  else
1858
0
    unsigned_length = (size_t) length;
1859
1860
0
  return g_compute_checksum_for_data (checksum_type, (const guchar *) str, unsigned_length);
1861
0
}
1862
1863
/**
1864
 * g_compute_checksum_for_bytes:
1865
 * @checksum_type: a #GChecksumType
1866
 * @data: binary blob to compute the digest of
1867
 *
1868
 * Computes the checksum for a binary @data. This is a
1869
 * convenience wrapper for g_checksum_new(), g_checksum_get_string()
1870
 * and g_checksum_free().
1871
 *
1872
 * The hexadecimal string returned will be in lower case.
1873
 *
1874
 * Returns: (transfer full) (nullable): the digest of the binary data as a
1875
 *   string in hexadecimal, or %NULL if g_checksum_new() fails for
1876
 *   @checksum_type. The returned string should be freed with g_free() when
1877
 *   done using it.
1878
 *
1879
 * Since: 2.34
1880
 */
1881
gchar *
1882
g_compute_checksum_for_bytes (GChecksumType  checksum_type,
1883
                              GBytes        *data)
1884
0
{
1885
0
  gconstpointer byte_data;
1886
0
  gsize length;
1887
1888
0
  g_return_val_if_fail (data != NULL, NULL);
1889
1890
0
  byte_data = g_bytes_get_data (data, &length);
1891
0
  return g_compute_checksum_for_data (checksum_type, byte_data, length);
1892
0
}