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