1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-sha.c SHA-1 implementation
4 * Copyright (C) 2003 Red Hat Inc.
5 * Copyright (C) 1995 A. M. Kuchling
7 * Licensed under the Academic Free License version 1.2
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "dbus-internals.h"
26 #include "dbus-marshal.h"
30 /* The following comments have the history of where this code
31 * comes from. I actually copied it from GNet in GNOME CVS.
36 * sha.h : Implementation of the Secure Hash Algorithm
38 * Part of the Python Cryptography Toolkit, version 1.0.0
40 * Copyright (C) 1995, A.M. Kuchling
42 * Distribute and use freely; there are no restrictions on further
43 * dissemination and usage except those imposed by the laws of your
44 * country of residence.
48 /* SHA: NIST's Secure Hash Algorithm */
50 /* Based on SHA code originally posted to sci.crypt by Peter Gutmann
51 in message <30ajo5$oe8@ccu2.auckland.ac.nz>.
52 Modified to test for endianness on creation of SHA objects by AMK.
53 Also, the original specification of SHA was found to have a weakness
54 by NSA/NIST. This code implements the fixed version of SHA.
57 /* Here's the first paragraph of Peter Gutmann's posting:
59 The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
60 SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
61 what's changed in the new version. The fix is a simple change which involves
62 adding a single rotate in the initial expansion function. It is unknown
63 whether this is an optimal solution to the problem which was discovered in the
64 SHA or whether it's simply a bandaid which fixes the problem with a minimum of
65 effort (for example the reengineering of a great many Capstone chips).
69 * @defgroup DBusSHA SHA implementation
70 * @ingroup DBusInternals
73 * Types and functions related to computing SHA-1 hash.
77 * @defgroup DBusSHAInternals SHA implementation details
78 * @ingroup DBusInternals
79 * @brief Internals of SHA implementation.
81 * The implementation of SHA-1 (see http://www.itl.nist.gov/fipspubs/fip180-1.htm).
82 * This SHA implementation was written by A.M. Kuchling
87 #ifndef DOXYGEN_SHOULD_SKIP_THIS
89 /* The SHA block size and message digest sizes, in bytes */
91 #define SHA_DATASIZE 64
92 #define SHA_DIGESTSIZE 20
94 /* The SHA f()-functions. The f1 and f3 functions can be optimized to
95 save one boolean operation each - thanks to Rich Schroeppel,
96 rcs@cs.arizona.edu for discovering this */
98 /*#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) // Rounds 0-19 */
99 #define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */
100 #define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
101 /*#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) // Rounds 40-59 */
102 #define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */
103 #define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
105 /* The SHA Mysterious Constants */
107 #define K1 0x5A827999L /* Rounds 0-19 */
108 #define K2 0x6ED9EBA1L /* Rounds 20-39 */
109 #define K3 0x8F1BBCDCL /* Rounds 40-59 */
110 #define K4 0xCA62C1D6L /* Rounds 60-79 */
112 /* SHA initial values */
114 #define h0init 0x67452301L
115 #define h1init 0xEFCDAB89L
116 #define h2init 0x98BADCFEL
117 #define h3init 0x10325476L
118 #define h4init 0xC3D2E1F0L
120 /* Note that it may be necessary to add parentheses to these macros if they
121 are to be called with expressions as arguments */
122 /* 32-bit rotate left - kludged with shifts */
124 #define ROTL(n,X) ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
126 /* The initial expanding function. The hash function is defined over an
127 80-word expanded input array W, where the first 16 are copies of the input
128 data, and the remaining 64 are defined by
130 W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
132 This implementation generates these values on the fly in a circular
133 buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
136 The updated SHA changes the expanding function by adding a rotate of 1
137 bit. Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
138 for this information */
140 #define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
141 W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
144 /* The prototype SHA sub-round. The fundamental sub-round is:
146 a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
152 but this is implemented by unrolling the loop 5 times and renaming the
153 variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
154 This code is then replicated 20 times for each of the 4 functions, using
155 the next 20 values from the W[] array each time */
157 #define subRound(a, b, c, d, e, f, k, data) \
158 ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
160 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
162 /* Perform the SHA transformation. Note that this code, like MD5, seems to
163 break some optimizing compilers due to the complexity of the expressions
164 and the size of the basic block. It may be necessary to split it into
165 sections, e.g. based on the four subrounds
167 Note that this corrupts the context->data area */
170 SHATransform(dbus_uint32_t *digest, dbus_uint32_t *data)
172 dbus_uint32_t A, B, C, D, E; /* Local vars */
173 dbus_uint32_t eData[16]; /* Expanded data */
175 /* Set up first buffer and local data buffer */
181 memmove (eData, data, SHA_DATASIZE);
183 /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
184 subRound (A, B, C, D, E, f1, K1, eData[0]);
185 subRound (E, A, B, C, D, f1, K1, eData[1]);
186 subRound (D, E, A, B, C, f1, K1, eData[2]);
187 subRound (C, D, E, A, B, f1, K1, eData[3]);
188 subRound (B, C, D, E, A, f1, K1, eData[4]);
189 subRound (A, B, C, D, E, f1, K1, eData[5]);
190 subRound (E, A, B, C, D, f1, K1, eData[6]);
191 subRound (D, E, A, B, C, f1, K1, eData[7]);
192 subRound (C, D, E, A, B, f1, K1, eData[8]);
193 subRound (B, C, D, E, A, f1, K1, eData[9]);
194 subRound (A, B, C, D, E, f1, K1, eData[10]);
195 subRound (E, A, B, C, D, f1, K1, eData[11]);
196 subRound (D, E, A, B, C, f1, K1, eData[12]);
197 subRound (C, D, E, A, B, f1, K1, eData[13]);
198 subRound (B, C, D, E, A, f1, K1, eData[14]);
199 subRound (A, B, C, D, E, f1, K1, eData[15]);
200 subRound (E, A, B, C, D, f1, K1, expand ( eData, 16) );
201 subRound (D, E, A, B, C, f1, K1, expand ( eData, 17) );
202 subRound (C, D, E, A, B, f1, K1, expand ( eData, 18) );
203 subRound (B, C, D, E, A, f1, K1, expand ( eData, 19) );
205 subRound (A, B, C, D, E, f2, K2, expand ( eData, 20) );
206 subRound (E, A, B, C, D, f2, K2, expand ( eData, 21) );
207 subRound (D, E, A, B, C, f2, K2, expand ( eData, 22) );
208 subRound (C, D, E, A, B, f2, K2, expand ( eData, 23) );
209 subRound (B, C, D, E, A, f2, K2, expand ( eData, 24) );
210 subRound (A, B, C, D, E, f2, K2, expand ( eData, 25) );
211 subRound (E, A, B, C, D, f2, K2, expand ( eData, 26) );
212 subRound (D, E, A, B, C, f2, K2, expand ( eData, 27) );
213 subRound (C, D, E, A, B, f2, K2, expand ( eData, 28) );
214 subRound (B, C, D, E, A, f2, K2, expand ( eData, 29) );
215 subRound (A, B, C, D, E, f2, K2, expand ( eData, 30) );
216 subRound (E, A, B, C, D, f2, K2, expand ( eData, 31) );
217 subRound (D, E, A, B, C, f2, K2, expand ( eData, 32) );
218 subRound (C, D, E, A, B, f2, K2, expand ( eData, 33) );
219 subRound (B, C, D, E, A, f2, K2, expand ( eData, 34) );
220 subRound (A, B, C, D, E, f2, K2, expand ( eData, 35) );
221 subRound (E, A, B, C, D, f2, K2, expand ( eData, 36) );
222 subRound (D, E, A, B, C, f2, K2, expand ( eData, 37) );
223 subRound (C, D, E, A, B, f2, K2, expand ( eData, 38) );
224 subRound (B, C, D, E, A, f2, K2, expand ( eData, 39) );
226 subRound (A, B, C, D, E, f3, K3, expand ( eData, 40) );
227 subRound (E, A, B, C, D, f3, K3, expand ( eData, 41) );
228 subRound (D, E, A, B, C, f3, K3, expand ( eData, 42) );
229 subRound (C, D, E, A, B, f3, K3, expand ( eData, 43) );
230 subRound (B, C, D, E, A, f3, K3, expand ( eData, 44) );
231 subRound (A, B, C, D, E, f3, K3, expand ( eData, 45) );
232 subRound (E, A, B, C, D, f3, K3, expand ( eData, 46) );
233 subRound (D, E, A, B, C, f3, K3, expand ( eData, 47) );
234 subRound (C, D, E, A, B, f3, K3, expand ( eData, 48) );
235 subRound (B, C, D, E, A, f3, K3, expand ( eData, 49) );
236 subRound (A, B, C, D, E, f3, K3, expand ( eData, 50) );
237 subRound (E, A, B, C, D, f3, K3, expand ( eData, 51) );
238 subRound (D, E, A, B, C, f3, K3, expand ( eData, 52) );
239 subRound (C, D, E, A, B, f3, K3, expand ( eData, 53) );
240 subRound (B, C, D, E, A, f3, K3, expand ( eData, 54) );
241 subRound (A, B, C, D, E, f3, K3, expand ( eData, 55) );
242 subRound (E, A, B, C, D, f3, K3, expand ( eData, 56) );
243 subRound (D, E, A, B, C, f3, K3, expand ( eData, 57) );
244 subRound (C, D, E, A, B, f3, K3, expand ( eData, 58) );
245 subRound (B, C, D, E, A, f3, K3, expand ( eData, 59) );
247 subRound (A, B, C, D, E, f4, K4, expand ( eData, 60) );
248 subRound (E, A, B, C, D, f4, K4, expand ( eData, 61) );
249 subRound (D, E, A, B, C, f4, K4, expand ( eData, 62) );
250 subRound (C, D, E, A, B, f4, K4, expand ( eData, 63) );
251 subRound (B, C, D, E, A, f4, K4, expand ( eData, 64) );
252 subRound (A, B, C, D, E, f4, K4, expand ( eData, 65) );
253 subRound (E, A, B, C, D, f4, K4, expand ( eData, 66) );
254 subRound (D, E, A, B, C, f4, K4, expand ( eData, 67) );
255 subRound (C, D, E, A, B, f4, K4, expand ( eData, 68) );
256 subRound (B, C, D, E, A, f4, K4, expand ( eData, 69) );
257 subRound (A, B, C, D, E, f4, K4, expand ( eData, 70) );
258 subRound (E, A, B, C, D, f4, K4, expand ( eData, 71) );
259 subRound (D, E, A, B, C, f4, K4, expand ( eData, 72) );
260 subRound (C, D, E, A, B, f4, K4, expand ( eData, 73) );
261 subRound (B, C, D, E, A, f4, K4, expand ( eData, 74) );
262 subRound (A, B, C, D, E, f4, K4, expand ( eData, 75) );
263 subRound (E, A, B, C, D, f4, K4, expand ( eData, 76) );
264 subRound (D, E, A, B, C, f4, K4, expand ( eData, 77) );
265 subRound (C, D, E, A, B, f4, K4, expand ( eData, 78) );
266 subRound (B, C, D, E, A, f4, K4, expand ( eData, 79) );
268 /* Build message digest */
276 /* When run on a little-endian CPU we need to perform byte reversal on an
277 array of longwords. */
279 #ifdef WORDS_BIGENDIAN
280 #define swap_words(buffer, byte_count)
283 swap_words (dbus_uint32_t *buffer,
286 byte_count /= sizeof (dbus_uint32_t);
289 *buffer = DBUS_UINT32_SWAP_LE_BE (*buffer);
296 sha_init (DBusSHAContext *context)
298 /* Set the h-vars to their initial values */
299 context->digest[0] = h0init;
300 context->digest[1] = h1init;
301 context->digest[2] = h2init;
302 context->digest[3] = h3init;
303 context->digest[4] = h4init;
305 /* Initialise bit count */
306 context->count_lo = context->count_hi = 0;
310 sha_append (DBusSHAContext *context,
311 const unsigned char *buffer,
315 unsigned int dataCount;
317 /* Update bitcount */
318 tmp = context->count_lo;
319 if (( context->count_lo = tmp + ( ( dbus_uint32_t) count << 3) ) < tmp)
320 context->count_hi++; /* Carry from low to high */
321 context->count_hi += count >> 29;
323 /* Get count of bytes already in data */
324 dataCount = (int) (tmp >> 3) & 0x3F;
326 /* Handle any leading odd-sized chunks */
329 unsigned char *p = (unsigned char *) context->data + dataCount;
331 dataCount = SHA_DATASIZE - dataCount;
332 if (count < dataCount)
334 memmove (p, buffer, count);
337 memmove (p, buffer, dataCount);
338 swap_words (context->data, SHA_DATASIZE);
339 SHATransform (context->digest, context->data);
344 /* Process data in SHA_DATASIZE chunks */
345 while (count >= SHA_DATASIZE)
347 memmove (context->data, buffer, SHA_DATASIZE);
348 swap_words (context->data, SHA_DATASIZE);
349 SHATransform (context->digest, context->data);
350 buffer += SHA_DATASIZE;
351 count -= SHA_DATASIZE;
354 /* Handle any remaining bytes of data. */
355 memmove (context->data, buffer, count);
359 /* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern
360 1 0* (64-bit count of bits processed, MSB-first) */
363 sha_finish (DBusSHAContext *context, unsigned char digest[20])
366 unsigned char *data_p;
368 /* Compute number of bytes mod 64 */
369 count = (int) context->count_lo;
370 count = (count >> 3) & 0x3F;
372 /* Set the first char of padding to 0x80. This is safe since there is
373 always at least one byte free */
374 data_p = (unsigned char *) context->data + count;
377 /* Bytes of padding needed to make 64 bytes */
378 count = SHA_DATASIZE - 1 - count;
380 /* Pad out to 56 mod 64 */
383 /* Two lots of padding: Pad the first block to 64 bytes */
384 memset (data_p, 0, count);
385 swap_words (context->data, SHA_DATASIZE);
386 SHATransform (context->digest, context->data);
388 /* Now fill the next block with 56 bytes */
389 memset (context->data, 0, SHA_DATASIZE - 8);
392 /* Pad block to 56 bytes */
393 memset (data_p, 0, count - 8);
395 /* Append length in bits and transform */
396 context->data[14] = context->count_hi;
397 context->data[15] = context->count_lo;
399 swap_words (context->data, SHA_DATASIZE - 8);
400 SHATransform (context->digest, context->data);
401 swap_words (context->digest, SHA_DIGESTSIZE);
402 memmove (digest, context->digest, SHA_DIGESTSIZE);
405 /** @} */ /* End of internals */
408 * @addtogroup DBusSHA
414 * Initializes the SHA context.
416 * @param context an uninitialized context, typically on the stack.
419 _dbus_sha_init (DBusSHAContext *context)
425 * Feeds more data into an existing shasum computation.
427 * @param context the SHA context
428 * @param data the additional data to hash
431 _dbus_sha_update (DBusSHAContext *context,
432 const DBusString *data)
434 unsigned int inputLen;
435 unsigned char *input;
437 _dbus_string_get_const_data (data, (const char**) &input);
438 inputLen = _dbus_string_get_length (data);
440 sha_append (context, input, inputLen);
444 * SHA finalization. Ends an SHA message-digest operation, writing the
445 * the message digest and zeroing the context. The results are
446 * returned as a raw 20-byte digest, not as the ascii-hex-digits
447 * string form of the digest.
449 * @param context the SHA context
450 * @param results string to append the 20-byte SHA digest to
451 * @returns #FALSE if not enough memory to append the digest
455 _dbus_sha_final (DBusSHAContext *context,
458 unsigned char digest[20];
460 sha_finish (context, digest);
462 if (!_dbus_string_append_len (results, digest, 20))
465 /* some kind of security paranoia, though it seems pointless
466 * to me given the nonzeroed stuff flying around
468 memset ((void*)context, '\0', sizeof (DBusSHAContext));
474 * Computes the ASCII hex-encoded shasum of the given data and
475 * appends it to the output string.
477 * @param data input data to be hashed
478 * @param ascii_output string to append ASCII shasum to
479 * @returns #FALSE if not enough memory
482 _dbus_sha_compute (const DBusString *data,
483 DBusString *ascii_output)
485 DBusSHAContext context;
488 _dbus_sha_init (&context);
490 _dbus_sha_update (&context, data);
492 if (!_dbus_string_init (&digest, _DBUS_INT_MAX))
495 if (!_dbus_sha_final (&context, &digest))
498 if (!_dbus_string_hex_encode (&digest, 0, ascii_output,
499 _dbus_string_get_length (ascii_output)))
502 _dbus_string_free (&digest);
507 _dbus_string_free (&digest);
511 /** @} */ /* end of exported functions */
513 #ifdef DBUS_BUILD_TESTS
514 #include "dbus-test.h"
518 check_sha_binary (const unsigned char *input,
520 const char *expected)
522 DBusString input_str;
523 DBusString expected_str;
526 _dbus_string_init_const_len (&input_str, input, input_len);
527 _dbus_string_init_const (&expected_str, expected);
529 if (!_dbus_string_init (&results, _DBUS_INT_MAX))
530 _dbus_assert_not_reached ("no memory for SHA-1 results");
532 if (!_dbus_sha_compute (&input_str, &results))
533 _dbus_assert_not_reached ("no memory for SHA-1 results");
535 if (!_dbus_string_equal (&expected_str, &results))
538 _dbus_string_get_const_data (&results, &s);
539 _dbus_warn ("Expected hash %s got %s for SHA-1 sum\n",
541 _dbus_string_free (&results);
545 _dbus_string_free (&results);
550 check_sha_str (const char *input,
551 const char *expected)
553 return check_sha_binary (input, strlen (input), expected);
557 decode_compact_string (const DBusString *line,
561 dbus_bool_t current_b;
570 if (!_dbus_string_parse_int (line, offset, &val, &next))
573 _dbus_string_get_const_data (line, &s);
574 fprintf (stderr, "could not parse length at start of compact string: %s\n",
579 _dbus_string_skip_blank (line, next, &next);
582 if (!_dbus_string_parse_int (line, offset, &val, &next))
585 _dbus_string_get_const_data (line, &s);
586 fprintf (stderr, "could not parse start bit 'b' in compact string: %s\n",
591 if (!(val == 0 || val == 1))
593 fprintf (stderr, "the value 'b' must be 0 or 1, see sha-1/Readme.txt\n");
597 _dbus_string_skip_blank (line, next, &next);
602 while (next < _dbus_string_get_length (line))
608 if (_dbus_string_get_byte (line, offset) == '^')
611 if (!_dbus_string_parse_int (line, offset, &val, &next))
613 fprintf (stderr, "could not parse bit count in compact string\n");
617 /* We now append "val" copies of "current_b" bits to the string */
618 total_bits = n_bits + val;
619 while (n_bits < total_bits)
621 int byte_containing_next_bit = n_bits / 8;
622 int bit_containing_next_bit = 7 - (n_bits % 8);
623 unsigned char old_byte;
625 if (byte_containing_next_bit >= _dbus_string_get_length (decoded))
627 if (!_dbus_string_set_length (decoded, byte_containing_next_bit + 1))
628 _dbus_assert_not_reached ("no memory to extend to next byte");
631 old_byte = _dbus_string_get_byte (decoded, byte_containing_next_bit);
632 old_byte |= current_b << bit_containing_next_bit;
635 printf ("Appending bit %d to byte %d at bit %d resulting in byte 0x%x\n",
636 current_b, byte_containing_next_bit,
637 bit_containing_next_bit, old_byte);
640 _dbus_string_set_byte (decoded, byte_containing_next_bit, old_byte);
645 _dbus_string_skip_blank (line, next, &next);
647 current_b = !current_b;
650 length_bytes = (n_bits / 8 + ((n_bits % 8) ? 1 : 0));
652 if (_dbus_string_get_length (decoded) != length_bytes)
654 fprintf (stderr, "Expected length %d bytes %d bits for compact string, got %d bytes\n",
655 length_bytes, n_bits, _dbus_string_get_length (decoded));
663 get_next_expected_result (DBusString *results,
671 if (!_dbus_string_init (&line, _DBUS_INT_MAX))
672 _dbus_assert_not_reached ("no memory");
675 while (_dbus_string_pop_line (results, &line))
677 _dbus_string_delete_leading_blanks (&line);
679 if (_dbus_string_get_length (&line) == 0)
681 else if (_dbus_string_starts_with_c_str (&line, "#"))
683 else if (_dbus_string_starts_with_c_str (&line, "H>"))
686 _dbus_string_get_const_data (&line, &s);
689 else if (_dbus_string_starts_with_c_str (&line, "D>") ||
690 _dbus_string_starts_with_c_str (&line, "<D"))
696 if (!_dbus_string_move (&line, 0, result, 0))
697 _dbus_assert_not_reached ("no memory");
700 while (i < _dbus_string_get_length (result))
702 switch (_dbus_string_get_byte (result, i))
705 _dbus_string_set_byte (result, i, 'a');
708 _dbus_string_set_byte (result, i, 'b');
711 _dbus_string_set_byte (result, i, 'c');
714 _dbus_string_set_byte (result, i, 'd');
717 _dbus_string_set_byte (result, i, 'e');
720 _dbus_string_set_byte (result, i, 'f');
724 _dbus_string_delete (result, i, 1);
725 --i; /* to offset ++i below */
739 _dbus_string_free (&line);
744 process_test_data (const char *test_data_dir)
746 DBusString tests_file;
747 DBusString results_file;
759 if (!_dbus_string_init (&tests_file, _DBUS_INT_MAX))
760 _dbus_assert_not_reached ("no memory");
762 if (!_dbus_string_init (&results_file, _DBUS_INT_MAX))
763 _dbus_assert_not_reached ("no memory");
765 if (!_dbus_string_init (&tests, _DBUS_INT_MAX))
766 _dbus_assert_not_reached ("no memory");
768 if (!_dbus_string_init (&results, _DBUS_INT_MAX))
769 _dbus_assert_not_reached ("no memory");
771 if (!_dbus_string_init (&line, _DBUS_INT_MAX))
772 _dbus_assert_not_reached ("no memory");
774 if (!_dbus_string_append (&tests_file, test_data_dir))
775 _dbus_assert_not_reached ("no memory");
777 if (!_dbus_string_append (&results_file, test_data_dir))
778 _dbus_assert_not_reached ("no memory");
780 _dbus_string_init_const (&tmp, "sha-1/byte-messages.sha1");
781 if (!_dbus_concat_dir_and_file (&tests_file, &tmp))
782 _dbus_assert_not_reached ("no memory");
784 _dbus_string_init_const (&tmp, "sha-1/byte-hashes.sha1");
785 if (!_dbus_concat_dir_and_file (&results_file, &tmp))
786 _dbus_assert_not_reached ("no memory");
788 dbus_error_init (&error);
789 if (!_dbus_file_get_contents (&tests, &tests_file, &error))
792 _dbus_string_get_const_data (&tests_file, &s);
793 fprintf (stderr, "could not load test data file %s: %s\n",
795 dbus_error_free (&error);
799 if (!_dbus_file_get_contents (&results, &results_file, &error))
802 _dbus_string_get_const_data (&results_file, &s);
803 fprintf (stderr, "could not load results data file %s: %s\n",
805 dbus_error_free (&error);
812 while (_dbus_string_pop_line (&tests, &line))
816 _dbus_string_delete_leading_blanks (&line);
818 if (_dbus_string_get_length (&line) == 0)
820 else if (_dbus_string_starts_with_c_str (&line, "#"))
822 else if (_dbus_string_starts_with_c_str (&line, "H>"))
825 _dbus_string_get_const_data (&line, &s);
826 printf ("SHA-1: %s\n", s);
828 if (_dbus_string_find (&line, 0, "Type 3", NULL))
830 /* See sha-1/Readme.txt - the "Type 3" tests are
831 * random seeds, rather than data to be hashed.
832 * we'd have to do a little bit more implementation
833 * to use those tests.
836 printf (" (ending tests due to Type 3 tests seen - this is normal)\n");
840 else if (_dbus_string_starts_with_c_str (&line, "D>") ||
841 _dbus_string_starts_with_c_str (&line, "<D"))
847 DBusString next_line;
853 if (!_dbus_string_init (&next_line, _DBUS_INT_MAX))
854 _dbus_assert_not_reached ("no memory");
856 if (!_dbus_string_init (&expected, _DBUS_INT_MAX))
857 _dbus_assert_not_reached ("no memory");
859 if (!_dbus_string_init (&test, _DBUS_INT_MAX))
860 _dbus_assert_not_reached ("no memory");
862 if (!_dbus_string_init (&result, _DBUS_INT_MAX))
863 _dbus_assert_not_reached ("no memory");
865 /* the "compact strings" are "^"-terminated not
866 * newline-terminated so readahead to find the
869 while (!_dbus_string_find (&line, 0, "^", NULL) &&
870 _dbus_string_pop_line (&tests, &next_line))
872 if (!_dbus_string_append_byte (&line, ' ') ||
873 !_dbus_string_move (&next_line, 0, &line,
874 _dbus_string_get_length (&line)))
875 _dbus_assert_not_reached ("no memory");
878 if (!decode_compact_string (&line, &test))
880 fprintf (stderr, "Failed to decode line %d as a compact string\n",
885 if (!_dbus_sha_compute (&test, &result))
886 _dbus_assert_not_reached ("no memory for SHA-1 result");
888 if (!get_next_expected_result (&results, &expected))
890 fprintf (stderr, "Failed to read an expected result\n");
894 if (!_dbus_string_equal (&result, &expected))
899 _dbus_string_get_const_data (&result, &s1);
900 _dbus_string_get_const_data (&expected, &s2);
902 fprintf (stderr, " for line %d got hash %s expected %s\n",
909 _dbus_string_get_const_data (&result, &s);
910 /* printf (" Got expected: %s\n", s); */
917 _dbus_string_free (&test);
918 _dbus_string_free (&result);
919 _dbus_string_free (&next_line);
920 _dbus_string_free (&expected);
929 printf ("Passed the %d SHA-1 tests in the test file\n",
933 _dbus_string_free (&tests_file);
934 _dbus_string_free (&results_file);
935 _dbus_string_free (&tests);
936 _dbus_string_free (&results);
937 _dbus_string_free (&line);
943 * @ingroup DBusSHAInternals
944 * Unit test for SHA computation.
946 * @returns #TRUE on success.
949 _dbus_sha_test (const char *test_data_dir)
951 unsigned char all_bytes[256];
954 if (test_data_dir != NULL)
956 if (!process_test_data (test_data_dir))
960 printf ("No test data dir\n");
969 if (!check_sha_binary (all_bytes, 256,
970 "4916d6bdb7f78e6803698cab32d1586ea457dfc8"))
973 #define CHECK(input,expected) if (!check_sha_str (input, expected)) return FALSE
975 CHECK ("", "da39a3ee5e6b4b0d3255bfef95601890afd80709");
976 CHECK ("a", "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8");
977 CHECK ("abc", "a9993e364706816aba3e25717850c26c9cd0d89d");
978 CHECK ("message digest", "c12252ceda8be8994d5fa0290a47231c1d16aae3");
979 CHECK ("abcdefghijklmnopqrstuvwxyz", "32d10c7b8cf96570ca04ce37f2a19d84240d3a89");
980 CHECK ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
981 "761c457bf73b14d27e9e9265c46f4b4dda11f940");
982 CHECK ("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
983 "50abf5706a150990a08b2c5ea40fa0e585554732");
988 #endif /* DBUS_BUILD_TESTS */