Coverage Report

Created: 2025-08-28 06:48

/src/tinysparql/subprojects/glib-2.80.3/glib/gchecksum.c
Line
Count
Source (jump to first uncovered line)
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
8.25k
#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
6.54M
#define MD5_DATASIZE    64
64
8.25k
#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
                  gint     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
8.25k
{
183
8.25k
  gsize i, len = digest_len * 2;
184
8.25k
  gchar *retval;
185
186
8.25k
  retval = g_new (gchar, len + 1);
187
188
140k
  for (i = 0; i < digest_len; i++)
189
132k
    {
190
132k
      guint8 byte = digest[i];
191
192
132k
      retval[2 * i] = hex_digits[byte >> 4];
193
132k
      retval[2 * i + 1] = hex_digits[byte & 0xf];
194
132k
    }
195
196
8.25k
  retval[len] = 0;
197
198
8.25k
  return retval;
199
8.25k
}
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
8.25k
{
222
  /* arbitrary constants */
223
8.25k
  md5->buf[0] = 0x67452301;
224
8.25k
  md5->buf[1] = 0xefcdab89;
225
8.25k
  md5->buf[2] = 0x98badcfe;
226
8.25k
  md5->buf[3] = 0x10325476;
227
228
8.25k
  md5->bits[0] = md5->bits[1] = 0;
229
8.25k
}
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
1.65M
{
240
1.65M
  guint32 a, b, c, d;
241
242
/* The four core functions - F1 is optimized somewhat */
243
52.8M
#define F1(x, y, z)     (z ^ (x & (y ^ z)))
244
26.4M
#define F2(x, y, z)     F1 (z, x, y)
245
26.4M
#define F3(x, y, z)     (x ^ y ^ z)
246
26.4M
#define F4(x, y, z)     (y ^ (x | ~z))
247
248
/* This is the central step in the MD5 algorithm. */
249
1.65M
#define md5_step(f, w, x, y, z, data, s) \
250
105M
        ( w += f (x, y, z) + data,  w = w << s | w >> (32 - s),  w += x )
251
252
1.65M
  a = buf[0];
253
1.65M
  b = buf[1];
254
1.65M
  c = buf[2];
255
1.65M
  d = buf[3];
256
257
1.65M
  md5_step (F1, a, b, c, d, in[0]  + 0xd76aa478,  7);
258
1.65M
  md5_step (F1, d, a, b, c, in[1]  + 0xe8c7b756, 12);
259
1.65M
  md5_step (F1, c, d, a, b, in[2]  + 0x242070db, 17);
260
1.65M
  md5_step (F1, b, c, d, a, in[3]  + 0xc1bdceee, 22);
261
1.65M
  md5_step (F1, a, b, c, d, in[4]  + 0xf57c0faf,  7);
262
1.65M
  md5_step (F1, d, a, b, c, in[5]  + 0x4787c62a, 12);
263
1.65M
  md5_step (F1, c, d, a, b, in[6]  + 0xa8304613, 17);
264
1.65M
  md5_step (F1, b, c, d, a, in[7]  + 0xfd469501, 22);
265
1.65M
  md5_step (F1, a, b, c, d, in[8]  + 0x698098d8,  7);
266
1.65M
  md5_step (F1, d, a, b, c, in[9]  + 0x8b44f7af, 12);
267
1.65M
  md5_step (F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
268
1.65M
  md5_step (F1, b, c, d, a, in[11] + 0x895cd7be, 22);
269
1.65M
  md5_step (F1, a, b, c, d, in[12] + 0x6b901122,  7);
270
1.65M
  md5_step (F1, d, a, b, c, in[13] + 0xfd987193, 12);
271
1.65M
  md5_step (F1, c, d, a, b, in[14] + 0xa679438e, 17);
272
1.65M
  md5_step (F1, b, c, d, a, in[15] + 0x49b40821, 22);
273
        
274
1.65M
  md5_step (F2, a, b, c, d, in[1]  + 0xf61e2562,  5);
275
1.65M
  md5_step (F2, d, a, b, c, in[6]  + 0xc040b340,  9);
276
1.65M
  md5_step (F2, c, d, a, b, in[11] + 0x265e5a51, 14);
277
1.65M
  md5_step (F2, b, c, d, a, in[0]  + 0xe9b6c7aa, 20);
278
1.65M
  md5_step (F2, a, b, c, d, in[5]  + 0xd62f105d,  5);
279
1.65M
  md5_step (F2, d, a, b, c, in[10] + 0x02441453,  9);
280
1.65M
  md5_step (F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
281
1.65M
  md5_step (F2, b, c, d, a, in[4]  + 0xe7d3fbc8, 20);
282
1.65M
  md5_step (F2, a, b, c, d, in[9]  + 0x21e1cde6,  5);
283
1.65M
  md5_step (F2, d, a, b, c, in[14] + 0xc33707d6,  9);
284
1.65M
  md5_step (F2, c, d, a, b, in[3]  + 0xf4d50d87, 14);
285
1.65M
  md5_step (F2, b, c, d, a, in[8]  + 0x455a14ed, 20);
286
1.65M
  md5_step (F2, a, b, c, d, in[13] + 0xa9e3e905,  5);
287
1.65M
  md5_step (F2, d, a, b, c, in[2]  + 0xfcefa3f8,  9);
288
1.65M
  md5_step (F2, c, d, a, b, in[7]  + 0x676f02d9, 14);
289
1.65M
  md5_step (F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
290
291
1.65M
  md5_step (F3, a, b, c, d, in[5]  + 0xfffa3942,  4);
292
1.65M
  md5_step (F3, d, a, b, c, in[8]  + 0x8771f681, 11);
293
1.65M
  md5_step (F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
294
1.65M
  md5_step (F3, b, c, d, a, in[14] + 0xfde5380c, 23);
295
1.65M
  md5_step (F3, a, b, c, d, in[1]  + 0xa4beea44,  4);
296
1.65M
  md5_step (F3, d, a, b, c, in[4]  + 0x4bdecfa9, 11);
297
1.65M
  md5_step (F3, c, d, a, b, in[7]  + 0xf6bb4b60, 16);
298
1.65M
  md5_step (F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
299
1.65M
  md5_step (F3, a, b, c, d, in[13] + 0x289b7ec6,  4);
300
1.65M
  md5_step (F3, d, a, b, c, in[0]  + 0xeaa127fa, 11);
301
1.65M
  md5_step (F3, c, d, a, b, in[3]  + 0xd4ef3085, 16);
302
1.65M
  md5_step (F3, b, c, d, a, in[6]  + 0x04881d05, 23);
303
1.65M
  md5_step (F3, a, b, c, d, in[9]  + 0xd9d4d039,  4);
304
1.65M
  md5_step (F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
305
1.65M
  md5_step (F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
306
1.65M
  md5_step (F3, b, c, d, a, in[2]  + 0xc4ac5665, 23);
307
308
1.65M
  md5_step (F4, a, b, c, d, in[0]  + 0xf4292244,  6);
309
1.65M
  md5_step (F4, d, a, b, c, in[7]  + 0x432aff97, 10);
310
1.65M
  md5_step (F4, c, d, a, b, in[14] + 0xab9423a7, 15);
311
1.65M
  md5_step (F4, b, c, d, a, in[5]  + 0xfc93a039, 21);
312
1.65M
  md5_step (F4, a, b, c, d, in[12] + 0x655b59c3,  6);
313
1.65M
  md5_step (F4, d, a, b, c, in[3]  + 0x8f0ccc92, 10);
314
1.65M
  md5_step (F4, c, d, a, b, in[10] + 0xffeff47d, 15);
315
1.65M
  md5_step (F4, b, c, d, a, in[1]  + 0x85845dd1, 21);
316
1.65M
  md5_step (F4, a, b, c, d, in[8]  + 0x6fa87e4f,  6);
317
1.65M
  md5_step (F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
318
1.65M
  md5_step (F4, c, d, a, b, in[6]  + 0xa3014314, 15);
319
1.65M
  md5_step (F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
320
1.65M
  md5_step (F4, a, b, c, d, in[4]  + 0xf7537e82,  6);
321
1.65M
  md5_step (F4, d, a, b, c, in[11] + 0xbd3af235, 10);
322
1.65M
  md5_step (F4, c, d, a, b, in[2]  + 0x2ad7d2bb, 15);
323
1.65M
  md5_step (F4, b, c, d, a, in[9]  + 0xeb86d391, 21);
324
325
1.65M
  buf[0] += a;
326
1.65M
  buf[1] += b;
327
1.65M
  buf[2] += c;
328
1.65M
  buf[3] += d;
329
330
1.65M
#undef F1
331
1.65M
#undef F2
332
1.65M
#undef F3
333
1.65M
#undef F4
334
1.65M
#undef md5_step
335
1.65M
}
336
337
static void
338
md5_sum_update (Md5sum       *md5,
339
                const guchar *data,
340
                gsize         length)
341
41.2k
{
342
41.2k
  guint32 bit;
343
344
41.2k
  bit = md5->bits[0];
345
41.2k
  md5->bits[0] = bit + ((guint32) length << 3);
346
347
  /* carry from low to high */
348
41.2k
  if (md5->bits[0] < bit)
349
0
    md5->bits[1] += 1;
350
351
41.2k
  md5->bits[1] += length >> 29;
352
353
  /* bytes already in Md5sum->u.data */
354
41.2k
  bit = (bit >> 3) & 0x3f;
355
356
  /* handle any leading odd-sized chunks */
357
41.2k
  if (bit)
358
33.0k
    {
359
33.0k
      guchar *p = md5->u.data + bit;
360
361
33.0k
      bit = MD5_DATASIZE - bit;
362
33.0k
      if (length < bit)
363
8.25k
        {
364
8.25k
          memcpy (p, data, length);
365
8.25k
          return;
366
8.25k
        }
367
368
24.7k
      memcpy (p, data, bit);
369
370
24.7k
      md5_byte_reverse (md5->u.data, 16);
371
24.7k
      md5_transform (md5->buf, md5->u.data32);
372
373
24.7k
      data += bit;
374
24.7k
      length -= bit;
375
24.7k
    }
376
377
  /* process data in 64-byte chunks */
378
1.65M
  while (length >= MD5_DATASIZE)
379
1.61M
    {
380
1.61M
      memcpy (md5->u.data, data, MD5_DATASIZE);
381
382
1.61M
      md5_byte_reverse (md5->u.data, 16);
383
1.61M
      md5_transform (md5->buf, md5->u.data32);
384
385
1.61M
      data += MD5_DATASIZE;
386
1.61M
      length -= MD5_DATASIZE;
387
1.61M
    }
388
389
  /* handle any remaining bytes of data */
390
33.0k
  memcpy (md5->u.data, data, length);
391
33.0k
}
392
393
/* closes a checksum */
394
static void
395
md5_sum_close (Md5sum *md5)
396
8.25k
{
397
8.25k
  guint count;
398
8.25k
  guchar *p;
399
400
  /* Compute number of bytes mod 64 */
401
8.25k
  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
8.25k
  p = md5->u.data + count;
407
8.25k
  *p++ = 0x80;
408
409
  /* Bytes of padding needed to make 64 bytes */
410
8.25k
  count = MD5_DATASIZE - 1 - count;
411
412
  /* Pad out to 56 mod 64 */
413
8.25k
  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
8.25k
  else
425
8.25k
    {
426
      /* Pad block to 56 bytes */
427
8.25k
      memset (p, 0, count - 8);
428
8.25k
    }
429
430
8.25k
  md5_byte_reverse (md5->u.data, 14);
431
432
  /* Append length in bits and transform */
433
8.25k
  md5->u.data32[14] = md5->bits[0];
434
8.25k
  md5->u.data32[15] = md5->bits[1];
435
436
8.25k
  md5_transform (md5->buf, md5->u.data32);
437
8.25k
  md5_byte_reverse ((guchar *) md5->buf, 4);
438
439
8.25k
  memcpy (md5->digest, md5->buf, 16);
440
441
  /* Reset buffers in case they contain sensitive data */
442
8.25k
  memset (md5->buf, 0, sizeof (md5->buf));
443
8.25k
  memset (md5->u.data, 0, sizeof (md5->u.data));
444
8.25k
}
445
446
static gchar *
447
md5_sum_to_string (Md5sum *md5)
448
8.25k
{
449
8.25k
  return digest_to_string (md5->digest, MD5_DIGEST_LEN);
450
8.25k
}
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
  gint count;
753
0
  guchar *data_p;
754
755
  /* Compute number of bytes mod 64 */
756
0
  count = (gint) ((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
  gint 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
  gint zeros;
1332
0
  guint8 pad[SHA2_BLOCK_LEN * 2] = { 0, };
1333
0
  guint pad_len = 0;
1334
0
  gint i;
1335
1336
  /* apply padding [§5.1.2] */
1337
0
  l = sha512->block_len * 8;
1338
0
  zeros = 896 - (l + 1);
1339
1340
0
  if (zeros < 0)
1341
0
    zeros += 128 * 8;
1342
1343
0
  pad[0] = 0x80; /* 1000 0000 */
1344
0
  zeros -= 7;
1345
0
  pad_len++;
1346
1347
0
  memset (pad + pad_len, 0x00, zeros / 8);
1348
0
  pad_len += zeros / 8;
1349
0
  zeros = zeros % 8;
1350
0
  (void) zeros;  /* don’t care about the dead store */
1351
1352
  /* put message bit length at the end of padding */
1353
0
  PUT_UINT64 (sha512->data_len[1], pad, pad_len);
1354
0
  pad_len += 8;
1355
1356
0
  PUT_UINT64 (sha512->data_len[0], pad, pad_len);
1357
0
  pad_len += 8;
1358
1359
  /* update checksum with the padded block */
1360
0
  sha512_sum_update (sha512, pad, pad_len);
1361
1362
  /* copy resulting 64-bit words into digest */
1363
0
  for (i = 0; i < 8; i++)
1364
0
    PUT_UINT64 (sha512->H[i], sha512->digest, i * 8);
1365
0
}
1366
1367
static gchar *
1368
sha384_sum_to_string (Sha512sum *sha512)
1369
0
{
1370
0
  return digest_to_string (sha512->digest, SHA384_DIGEST_LEN);
1371
0
}
1372
1373
static gchar *
1374
sha512_sum_to_string (Sha512sum *sha512)
1375
0
{
1376
0
  return digest_to_string (sha512->digest, SHA512_DIGEST_LEN);
1377
0
}
1378
1379
static void
1380
sha384_sum_digest (Sha512sum *sha512,
1381
                   guint8    *digest)
1382
0
{
1383
0
  memcpy (digest, sha512->digest, SHA384_DIGEST_LEN);
1384
0
}
1385
1386
static void
1387
sha512_sum_digest (Sha512sum *sha512,
1388
                   guint8    *digest)
1389
0
{
1390
0
  memcpy (digest, sha512->digest, SHA512_DIGEST_LEN);
1391
0
}
1392
1393
#undef Ch
1394
#undef Maj
1395
#undef SHR
1396
#undef ROTR
1397
#undef SIGMA0
1398
#undef SIGMA1
1399
#undef sigma0
1400
#undef sigma1
1401
1402
#undef PUT_UINT64
1403
1404
/*
1405
 * Public API
1406
 */
1407
1408
/**
1409
 * g_checksum_type_get_length:
1410
 * @checksum_type: a #GChecksumType
1411
 *
1412
 * Gets the length in bytes of digests of type @checksum_type
1413
 *
1414
 * Returns: the checksum length, or -1 if @checksum_type is
1415
 * not supported.
1416
 *
1417
 * Since: 2.16
1418
 */
1419
gssize
1420
g_checksum_type_get_length (GChecksumType checksum_type)
1421
0
{
1422
0
  gssize len = -1;
1423
1424
0
  switch (checksum_type)
1425
0
    {
1426
0
    case G_CHECKSUM_MD5:
1427
0
      len = MD5_DIGEST_LEN;
1428
0
      break;
1429
0
    case G_CHECKSUM_SHA1:
1430
0
      len = SHA1_DIGEST_LEN;
1431
0
      break;
1432
0
    case G_CHECKSUM_SHA256:
1433
0
      len = SHA256_DIGEST_LEN;
1434
0
      break;
1435
0
    case G_CHECKSUM_SHA384:
1436
0
      len = SHA384_DIGEST_LEN;
1437
0
      break;
1438
0
    case G_CHECKSUM_SHA512:
1439
0
      len = SHA512_DIGEST_LEN;
1440
0
      break;
1441
0
    default:
1442
0
      len = -1;
1443
0
      break;
1444
0
    }
1445
1446
0
  return len;
1447
0
}
1448
1449
/**
1450
 * g_checksum_new:
1451
 * @checksum_type: the desired type of checksum
1452
 *
1453
 * Creates a new #GChecksum, using the checksum algorithm @checksum_type.
1454
 * If the @checksum_type is not known, %NULL is returned.
1455
 * A #GChecksum can be used to compute the checksum, or digest, of an
1456
 * arbitrary binary blob, using different hashing algorithms.
1457
 *
1458
 * A #GChecksum works by feeding a binary blob through g_checksum_update()
1459
 * until there is data to be checked; the digest can then be extracted
1460
 * using g_checksum_get_string(), which will return the checksum as a
1461
 * hexadecimal string; or g_checksum_get_digest(), which will return a
1462
 * vector of raw bytes. Once either g_checksum_get_string() or
1463
 * g_checksum_get_digest() have been called on a #GChecksum, the checksum
1464
 * will be closed and it won't be possible to call g_checksum_update()
1465
 * on it anymore.
1466
 *
1467
 * Returns: (transfer full) (nullable): the newly created #GChecksum, or %NULL.
1468
 *   Use g_checksum_free() to free the memory allocated by it.
1469
 *
1470
 * Since: 2.16
1471
 */
1472
GChecksum *
1473
g_checksum_new (GChecksumType checksum_type)
1474
8.25k
{
1475
8.25k
  GChecksum *checksum;
1476
1477
8.25k
  if (! IS_VALID_TYPE (checksum_type))
1478
0
    return NULL;
1479
1480
8.25k
  checksum = g_slice_new0 (GChecksum);
1481
8.25k
  checksum->type = checksum_type;
1482
1483
8.25k
  g_checksum_reset (checksum);
1484
1485
8.25k
  return checksum;
1486
8.25k
}
1487
1488
/**
1489
 * g_checksum_reset:
1490
 * @checksum: the #GChecksum to reset
1491
 *
1492
 * Resets the state of the @checksum back to its initial state.
1493
 *
1494
 * Since: 2.18
1495
 **/
1496
void
1497
g_checksum_reset (GChecksum *checksum)
1498
8.25k
{
1499
8.25k
  g_return_if_fail (checksum != NULL);
1500
1501
8.25k
  g_free (checksum->digest_str);
1502
8.25k
  checksum->digest_str = NULL;
1503
1504
8.25k
  switch (checksum->type)
1505
8.25k
    {
1506
8.25k
    case G_CHECKSUM_MD5:
1507
8.25k
      md5_sum_init (&(checksum->sum.md5));
1508
8.25k
      break;
1509
0
    case G_CHECKSUM_SHA1:
1510
0
      sha1_sum_init (&(checksum->sum.sha1));
1511
0
      break;
1512
0
    case G_CHECKSUM_SHA256:
1513
0
      sha256_sum_init (&(checksum->sum.sha256));
1514
0
      break;
1515
0
    case G_CHECKSUM_SHA384:
1516
0
      sha384_sum_init (&(checksum->sum.sha512));
1517
0
      break;
1518
0
    case G_CHECKSUM_SHA512:
1519
0
      sha512_sum_init (&(checksum->sum.sha512));
1520
0
      break;
1521
0
    default:
1522
0
      g_assert_not_reached ();
1523
0
      break;
1524
8.25k
    }
1525
8.25k
}
1526
1527
/**
1528
 * g_checksum_copy:
1529
 * @checksum: the #GChecksum to copy
1530
 *
1531
 * Copies a #GChecksum. If @checksum has been closed, by calling
1532
 * g_checksum_get_string() or g_checksum_get_digest(), the copied
1533
 * checksum will be closed as well.
1534
 *
1535
 * Returns: (transfer full): the copy of the passed #GChecksum. Use
1536
 *   g_checksum_free() when finished using it.
1537
 *
1538
 * Since: 2.16
1539
 */
1540
GChecksum *
1541
g_checksum_copy (const GChecksum *checksum)
1542
0
{
1543
0
  GChecksum *copy;
1544
1545
0
  g_return_val_if_fail (checksum != NULL, NULL);
1546
1547
0
  copy = g_slice_new (GChecksum);
1548
0
  *copy = *checksum;
1549
1550
0
  copy->digest_str = g_strdup (checksum->digest_str);
1551
1552
0
  return copy;
1553
0
}
1554
1555
/**
1556
 * g_checksum_free:
1557
 * @checksum: a #GChecksum
1558
 *
1559
 * Frees the memory allocated for @checksum.
1560
 *
1561
 * Since: 2.16
1562
 */
1563
void
1564
g_checksum_free (GChecksum *checksum)
1565
8.25k
{
1566
8.25k
  if (G_LIKELY (checksum))
1567
8.25k
    {
1568
8.25k
      g_free (checksum->digest_str);
1569
1570
8.25k
      g_slice_free (GChecksum, checksum);
1571
8.25k
    }
1572
8.25k
}
1573
1574
/**
1575
 * g_checksum_update:
1576
 * @checksum: a #GChecksum
1577
 * @data: (array length=length) (element-type guint8): buffer used to compute the checksum
1578
 * @length: size of the buffer, or -1 if it is a null-terminated string.
1579
 *
1580
 * Feeds @data into an existing #GChecksum. The checksum must still be
1581
 * open, that is g_checksum_get_string() or g_checksum_get_digest() must
1582
 * not have been called on @checksum.
1583
 *
1584
 * Since: 2.16
1585
 */
1586
void
1587
g_checksum_update (GChecksum    *checksum,
1588
                   const guchar *data,
1589
                   gssize        length)
1590
41.2k
{
1591
41.2k
  g_return_if_fail (checksum != NULL);
1592
41.2k
  g_return_if_fail (length == 0 || data != NULL);
1593
1594
41.2k
  if (length < 0)
1595
0
    length = strlen ((const gchar *) data);
1596
1597
41.2k
  if (checksum->digest_str)
1598
0
    {
1599
0
      g_warning ("The checksum '%s' has been closed and cannot be updated "
1600
0
                 "anymore.",
1601
0
                 checksum->digest_str);
1602
0
      return;
1603
0
    }
1604
1605
41.2k
  switch (checksum->type)
1606
41.2k
    {
1607
41.2k
    case G_CHECKSUM_MD5:
1608
41.2k
      md5_sum_update (&(checksum->sum.md5), data, length);
1609
41.2k
      break;
1610
0
    case G_CHECKSUM_SHA1:
1611
0
      sha1_sum_update (&(checksum->sum.sha1), data, length);
1612
0
      break;
1613
0
    case G_CHECKSUM_SHA256:
1614
0
      sha256_sum_update (&(checksum->sum.sha256), data, length);
1615
0
      break;
1616
0
    case G_CHECKSUM_SHA384:
1617
0
    case G_CHECKSUM_SHA512:
1618
0
      sha512_sum_update (&(checksum->sum.sha512), data, length);
1619
0
      break;
1620
0
    default:
1621
0
      g_assert_not_reached ();
1622
0
      break;
1623
41.2k
    }
1624
41.2k
}
1625
1626
/**
1627
 * g_checksum_get_string:
1628
 * @checksum: a #GChecksum
1629
 *
1630
 * Gets the digest as a hexadecimal string.
1631
 *
1632
 * Once this function has been called the #GChecksum can no longer be
1633
 * updated with g_checksum_update().
1634
 *
1635
 * The hexadecimal characters will be lower case.
1636
 *
1637
 * Returns: the hexadecimal representation of the checksum. The
1638
 *   returned string is owned by the checksum and should not be modified
1639
 *   or freed.
1640
 *
1641
 * Since: 2.16
1642
 */
1643
const gchar *
1644
g_checksum_get_string (GChecksum *checksum)
1645
8.25k
{
1646
8.25k
  gchar *str = NULL;
1647
1648
8.25k
  g_return_val_if_fail (checksum != NULL, NULL);
1649
1650
8.25k
  if (checksum->digest_str)
1651
0
    return checksum->digest_str;
1652
1653
8.25k
  switch (checksum->type)
1654
8.25k
    {
1655
8.25k
    case G_CHECKSUM_MD5:
1656
8.25k
      md5_sum_close (&(checksum->sum.md5));
1657
8.25k
      str = md5_sum_to_string (&(checksum->sum.md5));
1658
8.25k
      break;
1659
0
    case G_CHECKSUM_SHA1:
1660
0
      sha1_sum_close (&(checksum->sum.sha1));
1661
0
      str = sha1_sum_to_string (&(checksum->sum.sha1));
1662
0
      break;
1663
0
    case G_CHECKSUM_SHA256:
1664
0
      sha256_sum_close (&(checksum->sum.sha256));
1665
0
      str = sha256_sum_to_string (&(checksum->sum.sha256));
1666
0
      break;
1667
0
    case G_CHECKSUM_SHA384:
1668
0
      sha512_sum_close (&(checksum->sum.sha512));
1669
0
      str = sha384_sum_to_string (&(checksum->sum.sha512));
1670
0
      break;
1671
0
    case G_CHECKSUM_SHA512:
1672
0
      sha512_sum_close (&(checksum->sum.sha512));
1673
0
      str = sha512_sum_to_string (&(checksum->sum.sha512));
1674
0
      break;
1675
0
    default:
1676
0
      g_assert_not_reached ();
1677
0
      break;
1678
8.25k
    }
1679
1680
8.25k
  checksum->digest_str = str;
1681
1682
8.25k
  return checksum->digest_str;
1683
8.25k
}
1684
1685
/**
1686
 * g_checksum_get_digest: (skip)
1687
 * @checksum: a #GChecksum
1688
 * @buffer: (array length=digest_len): output buffer
1689
 * @digest_len: (inout): an inout parameter. The caller initializes it to the size of @buffer.
1690
 *   After the call it contains the length of the digest.
1691
 *
1692
 * Gets the digest from @checksum as a raw binary vector and places it
1693
 * into @buffer. The size of the digest depends on the type of checksum.
1694
 *
1695
 * Once this function has been called, the #GChecksum is closed and can
1696
 * no longer be updated with g_checksum_update().
1697
 *
1698
 * Since: 2.16
1699
 */
1700
void
1701
g_checksum_get_digest (GChecksum  *checksum,
1702
                       guint8     *buffer,
1703
                       gsize      *digest_len)
1704
0
{
1705
0
  gboolean checksum_open = FALSE;
1706
0
  gchar *str = NULL;
1707
0
  gsize len;
1708
1709
0
  g_return_if_fail (checksum != NULL);
1710
1711
0
  len = g_checksum_type_get_length (checksum->type);
1712
0
  g_return_if_fail (*digest_len >= len);
1713
1714
0
  checksum_open = !!(checksum->digest_str == NULL);
1715
1716
0
  switch (checksum->type)
1717
0
    {
1718
0
    case G_CHECKSUM_MD5:
1719
0
      if (checksum_open)
1720
0
        {
1721
0
          md5_sum_close (&(checksum->sum.md5));
1722
0
          str = md5_sum_to_string (&(checksum->sum.md5));
1723
0
        }
1724
0
      md5_sum_digest (&(checksum->sum.md5), buffer);
1725
0
      break;
1726
0
    case G_CHECKSUM_SHA1:
1727
0
      if (checksum_open)
1728
0
        {
1729
0
          sha1_sum_close (&(checksum->sum.sha1));
1730
0
          str = sha1_sum_to_string (&(checksum->sum.sha1));
1731
0
        }
1732
0
      sha1_sum_digest (&(checksum->sum.sha1), buffer);
1733
0
      break;
1734
0
    case G_CHECKSUM_SHA256:
1735
0
      if (checksum_open)
1736
0
        {
1737
0
          sha256_sum_close (&(checksum->sum.sha256));
1738
0
          str = sha256_sum_to_string (&(checksum->sum.sha256));
1739
0
        }
1740
0
      sha256_sum_digest (&(checksum->sum.sha256), buffer);
1741
0
      break;
1742
0
    case G_CHECKSUM_SHA384:
1743
0
      if (checksum_open)
1744
0
        {
1745
0
          sha512_sum_close (&(checksum->sum.sha512));
1746
0
          str = sha384_sum_to_string (&(checksum->sum.sha512));
1747
0
        }
1748
0
      sha384_sum_digest (&(checksum->sum.sha512), buffer);
1749
0
      break;
1750
0
    case G_CHECKSUM_SHA512:
1751
0
      if (checksum_open)
1752
0
        {
1753
0
          sha512_sum_close (&(checksum->sum.sha512));
1754
0
          str = sha512_sum_to_string (&(checksum->sum.sha512));
1755
0
        }
1756
0
      sha512_sum_digest (&(checksum->sum.sha512), buffer);
1757
0
      break;
1758
0
    default:
1759
0
      g_assert_not_reached ();
1760
0
      break;
1761
0
    }
1762
1763
0
  if (str)
1764
0
    checksum->digest_str = str;
1765
1766
0
  *digest_len = len;
1767
0
}
1768
1769
/**
1770
 * g_compute_checksum_for_data:
1771
 * @checksum_type: a #GChecksumType
1772
 * @data: (array length=length) (element-type guint8): binary blob to compute the digest of
1773
 * @length: length of @data
1774
 *
1775
 * Computes the checksum for a binary @data of @length. This is a
1776
 * convenience wrapper for g_checksum_new(), g_checksum_get_string()
1777
 * and g_checksum_free().
1778
 *
1779
 * The hexadecimal string returned will be in lower case.
1780
 *
1781
 * Returns: (transfer full) (nullable): the digest of the binary data as a
1782
 *   string in hexadecimal, or %NULL if g_checksum_new() fails for
1783
 *   @checksum_type. The returned string should be freed with g_free() when
1784
 *   done using it.
1785
 *
1786
 * Since: 2.16
1787
 */
1788
gchar *
1789
g_compute_checksum_for_data (GChecksumType  checksum_type,
1790
                             const guchar  *data,
1791
                             gsize          length)
1792
0
{
1793
0
  GChecksum *checksum;
1794
0
  gchar *retval;
1795
1796
0
  g_return_val_if_fail (length == 0 || data != NULL, NULL);
1797
1798
0
  checksum = g_checksum_new (checksum_type);
1799
0
  if (!checksum)
1800
0
    return NULL;
1801
1802
0
  g_checksum_update (checksum, data, length);
1803
0
  retval = g_strdup (g_checksum_get_string (checksum));
1804
0
  g_checksum_free (checksum);
1805
1806
0
  return retval;
1807
0
}
1808
1809
/**
1810
 * g_compute_checksum_for_string:
1811
 * @checksum_type: a #GChecksumType
1812
 * @str: the string to compute the checksum of
1813
 * @length: the length of the string, or -1 if the string is null-terminated.
1814
 *
1815
 * Computes the checksum of a string.
1816
 *
1817
 * The hexadecimal string returned will be in lower case.
1818
 *
1819
 * Returns: (transfer full) (nullable): the checksum as a hexadecimal string,
1820
 *   or %NULL if g_checksum_new() fails for @checksum_type. The returned string
1821
 *   should be freed with g_free() when done using it.
1822
 *
1823
 * Since: 2.16
1824
 */
1825
gchar *
1826
g_compute_checksum_for_string (GChecksumType  checksum_type,
1827
                               const gchar   *str,
1828
                               gssize         length)
1829
0
{
1830
0
  g_return_val_if_fail (length == 0 || str != NULL, NULL);
1831
1832
0
  if (length < 0)
1833
0
    length = strlen (str);
1834
1835
0
  return g_compute_checksum_for_data (checksum_type, (const guchar *) str, length);
1836
0
}
1837
1838
/**
1839
 * g_compute_checksum_for_bytes:
1840
 * @checksum_type: a #GChecksumType
1841
 * @data: binary blob to compute the digest of
1842
 *
1843
 * Computes the checksum for a binary @data. This is a
1844
 * convenience wrapper for g_checksum_new(), g_checksum_get_string()
1845
 * and g_checksum_free().
1846
 *
1847
 * The hexadecimal string returned will be in lower case.
1848
 *
1849
 * Returns: (transfer full) (nullable): the digest of the binary data as a
1850
 *   string in hexadecimal, or %NULL if g_checksum_new() fails for
1851
 *   @checksum_type. The returned string should be freed with g_free() when
1852
 *   done using it.
1853
 *
1854
 * Since: 2.34
1855
 */
1856
gchar *
1857
g_compute_checksum_for_bytes (GChecksumType  checksum_type,
1858
                              GBytes        *data)
1859
0
{
1860
0
  gconstpointer byte_data;
1861
0
  gsize length;
1862
1863
0
  g_return_val_if_fail (data != NULL, NULL);
1864
1865
0
  byte_data = g_bytes_get_data (data, &length);
1866
0
  return g_compute_checksum_for_data (checksum_type, byte_data, length);
1867
0
}