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