1 /* -*- mode: C; c-file-style: "gnu" -*- */ 2 /* dbus-sha.c SHA-1 implementation 3 * 4 * Copyright (C) 2003 Red Hat Inc. 5 * Copyright (C) 1995 A. M. Kuchling 6 * 7 * Licensed under the Academic Free License version 2.1 8 * 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. 13 * 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. 18 * 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 22 * 23 */ 24 25 #include "dbus-internals.h" 26 #include "dbus-sha.h" 27 #include "dbus-marshal-basic.h" /* for byteswap routines */ 28 #include <string.h> 29 30 /* The following comments have the history of where this code 31 * comes from. I actually copied it from GNet in GNOME CVS. 32 * - hp (at) redhat.com 33 */ 34 35 /* 36 * sha.h : Implementation of the Secure Hash Algorithm 37 * 38 * Part of the Python Cryptography Toolkit, version 1.0.0 39 * 40 * Copyright (C) 1995, A.M. Kuchling 41 * 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. 45 * 46 */ 47 48 /* SHA: NIST's Secure Hash Algorithm */ 49 50 /* Based on SHA code originally posted to sci.crypt by Peter Gutmann 51 in message <30ajo5$oe8 (at) 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. 55 */ 56 57 /* Here's the first paragraph of Peter Gutmann's posting: 58 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). 66 */ 67 68 /** 69 * @defgroup DBusSHA SHA implementation 70 * @ingroup DBusInternals 71 * @brief SHA-1 hash 72 * 73 * Types and functions related to computing SHA-1 hash. 74 */ 75 76 /** 77 * @defgroup DBusSHAInternals SHA implementation details 78 * @ingroup DBusInternals 79 * @brief Internals of SHA implementation. 80 * 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 83 * 84 * @{ 85 */ 86 87 #ifndef DOXYGEN_SHOULD_SKIP_THIS 88 89 /* The SHA block size and message digest sizes, in bytes */ 90 91 #define SHA_DATASIZE 64 92 #define SHA_DIGESTSIZE 20 93 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 (at) cs.arizona.edu for discovering this */ 97 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 */ 104 105 /* The SHA Mysterious Constants */ 106 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 */ 111 112 /* SHA initial values */ 113 114 #define h0init 0x67452301L 115 #define h1init 0xEFCDAB89L 116 #define h2init 0x98BADCFEL 117 #define h3init 0x10325476L 118 #define h4init 0xC3D2E1F0L 119 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 */ 123 124 #define ROTL(n,X) ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) ) 125 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 129 130 W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ] 131 132 This implementation generates these values on the fly in a circular 133 buffer - thanks to Colin Plumb, colin (at) nyx10.cs.du.edu for this 134 optimization. 135 136 The updated SHA changes the expanding function by adding a rotate of 1 137 bit. Thanks to Jim Gillogly, jim (at) rand.org, and an anonymous contributor 138 for this information */ 139 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 ] ) ) ) 142 143 144 /* The prototype SHA sub-round. The fundamental sub-round is: 145 146 a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data; 147 b' = a; 148 c' = ROTL( 30, b ); 149 d' = c; 150 e' = d; 151 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 */ 156 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 ) ) 159 160 #endif /* !DOXYGEN_SHOULD_SKIP_THIS */ 161 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 166 167 Note that this corrupts the context->data area */ 168 169 static void 170 SHATransform(dbus_uint32_t *digest, dbus_uint32_t *data) 171 { 172 dbus_uint32_t A, B, C, D, E; /* Local vars */ 173 dbus_uint32_t eData[16]; /* Expanded data */ 174 175 /* Set up first buffer and local data buffer */ 176 A = digest[0]; 177 B = digest[1]; 178 C = digest[2]; 179 D = digest[3]; 180 E = digest[4]; 181 memmove (eData, data, SHA_DATASIZE); 182 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) ); 204 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) ); 225 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) ); 246 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) ); 267 268 /* Build message digest */ 269 digest[0] += A; 270 digest[1] += B; 271 digest[2] += C; 272 digest[3] += D; 273 digest[4] += E; 274 } 275 276 /* When run on a little-endian CPU we need to perform byte reversal on an 277 array of longwords. */ 278 279 #ifdef WORDS_BIGENDIAN 280 #define swap_words(buffer, byte_count) 281 #else 282 static void 283 swap_words (dbus_uint32_t *buffer, 284 int byte_count) 285 { 286 byte_count /= sizeof (dbus_uint32_t); 287 while (byte_count--) 288 { 289 *buffer = DBUS_UINT32_SWAP_LE_BE (*buffer); 290 ++buffer; 291 } 292 } 293 #endif 294 295 static void 296 sha_init (DBusSHAContext *context) 297 { 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; 304 305 /* Initialise bit count */ 306 context->count_lo = context->count_hi = 0; 307 } 308 309 static void 310 sha_append (DBusSHAContext *context, 311 const unsigned char *buffer, 312 unsigned int count) 313 { 314 dbus_uint32_t tmp; 315 unsigned int dataCount; 316 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; 322 323 /* Get count of bytes already in data */ 324 dataCount = (int) (tmp >> 3) & 0x3F; 325 326 /* Handle any leading odd-sized chunks */ 327 if (dataCount) 328 { 329 unsigned char *p = (unsigned char *) context->data + dataCount; 330 331 dataCount = SHA_DATASIZE - dataCount; 332 if (count < dataCount) 333 { 334 memmove (p, buffer, count); 335 return; 336 } 337 memmove (p, buffer, dataCount); 338 swap_words (context->data, SHA_DATASIZE); 339 SHATransform (context->digest, context->data); 340 buffer += dataCount; 341 count -= dataCount; 342 } 343 344 /* Process data in SHA_DATASIZE chunks */ 345 while (count >= SHA_DATASIZE) 346 { 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; 352 } 353 354 /* Handle any remaining bytes of data. */ 355 memmove (context->data, buffer, count); 356 } 357 358 359 /* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern 360 1 0* (64-bit count of bits processed, MSB-first) */ 361 362 static void 363 sha_finish (DBusSHAContext *context, unsigned char digest[20]) 364 { 365 int count; 366 unsigned char *data_p; 367 368 /* Compute number of bytes mod 64 */ 369 count = (int) context->count_lo; 370 count = (count >> 3) & 0x3F; 371 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; 375 *data_p++ = 0x80; 376 377 /* Bytes of padding needed to make 64 bytes */ 378 count = SHA_DATASIZE - 1 - count; 379 380 /* Pad out to 56 mod 64 */ 381 if (count < 8) 382 { 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); 387 388 /* Now fill the next block with 56 bytes */ 389 memset (context->data, 0, SHA_DATASIZE - 8); 390 } 391 else 392 /* Pad block to 56 bytes */ 393 memset (data_p, 0, count - 8); 394 395 /* Append length in bits and transform */ 396 context->data[14] = context->count_hi; 397 context->data[15] = context->count_lo; 398 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); 403 } 404 405 /** @} */ /* End of internals */ 406 407 /** 408 * @addtogroup DBusSHA 409 * 410 * @{ 411 */ 412 413 /** 414 * Initializes the SHA context. 415 * 416 * @param context an uninitialized context, typically on the stack. 417 */ 418 void 419 _dbus_sha_init (DBusSHAContext *context) 420 { 421 sha_init (context); 422 } 423 424 /** 425 * Feeds more data into an existing shasum computation. 426 * 427 * @param context the SHA context 428 * @param data the additional data to hash 429 */ 430 void 431 _dbus_sha_update (DBusSHAContext *context, 432 const DBusString *data) 433 { 434 unsigned int inputLen; 435 const unsigned char *input; 436 437 input = (const unsigned char*) _dbus_string_get_const_data (data); 438 inputLen = _dbus_string_get_length (data); 439 440 sha_append (context, input, inputLen); 441 } 442 443 /** 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. 448 * 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 452 * 453 */ 454 dbus_bool_t 455 _dbus_sha_final (DBusSHAContext *context, 456 DBusString *results) 457 { 458 unsigned char digest[20]; 459 460 sha_finish (context, digest); 461 462 if (!_dbus_string_append_len (results, digest, 20)) 463 return FALSE; 464 465 /* some kind of security paranoia, though it seems pointless 466 * to me given the nonzeroed stuff flying around 467 */ 468 memset ((void*)context, '\0', sizeof (DBusSHAContext)); 469 470 return TRUE; 471 } 472 473 /** 474 * Computes the ASCII hex-encoded shasum of the given data and 475 * appends it to the output string. 476 * 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 480 */ 481 dbus_bool_t 482 _dbus_sha_compute (const DBusString *data, 483 DBusString *ascii_output) 484 { 485 DBusSHAContext context; 486 DBusString digest; 487 488 _dbus_sha_init (&context); 489 490 _dbus_sha_update (&context, data); 491 492 if (!_dbus_string_init (&digest)) 493 return FALSE; 494 495 if (!_dbus_sha_final (&context, &digest)) 496 goto error; 497 498 if (!_dbus_string_hex_encode (&digest, 0, ascii_output, 499 _dbus_string_get_length (ascii_output))) 500 goto error; 501 502 _dbus_string_free (&digest); 503 504 return TRUE; 505 506 error: 507 _dbus_string_free (&digest); 508 return FALSE; 509 } 510 511 /** @} */ /* end of exported functions */ 512 513 #ifdef DBUS_BUILD_TESTS 514 #include "dbus-test.h" 515 #include <stdio.h> 516 517 static dbus_bool_t 518 check_sha_binary (const unsigned char *input, 519 int input_len, 520 const char *expected) 521 { 522 DBusString input_str; 523 DBusString expected_str; 524 DBusString results; 525 526 _dbus_string_init_const_len (&input_str, input, input_len); 527 _dbus_string_init_const (&expected_str, expected); 528 529 if (!_dbus_string_init (&results)) 530 _dbus_assert_not_reached ("no memory for SHA-1 results"); 531 532 if (!_dbus_sha_compute (&input_str, &results)) 533 _dbus_assert_not_reached ("no memory for SHA-1 results"); 534 535 if (!_dbus_string_equal (&expected_str, &results)) 536 { 537 _dbus_warn ("Expected hash %s got %s for SHA-1 sum\n", 538 expected, 539 _dbus_string_get_const_data (&results)); 540 _dbus_string_free (&results); 541 return FALSE; 542 } 543 544 _dbus_string_free (&results); 545 return TRUE; 546 } 547 548 static dbus_bool_t 549 check_sha_str (const char *input, 550 const char *expected) 551 { 552 return check_sha_binary (input, strlen (input), expected); 553 } 554 555 static dbus_bool_t 556 decode_compact_string (const DBusString *line, 557 DBusString *decoded) 558 { 559 int n_bits; 560 dbus_bool_t current_b; 561 int offset; 562 int next; 563 long val; 564 int length_bytes; 565 566 offset = 0; 567 next = 0; 568 569 if (!_dbus_string_parse_int (line, offset, &val, &next)) 570 { 571 fprintf (stderr, "could not parse length at start of compact string: %s\n", 572 _dbus_string_get_const_data (line)); 573 return FALSE; 574 } 575 576 _dbus_string_skip_blank (line, next, &next); 577 578 offset = next; 579 if (!_dbus_string_parse_int (line, offset, &val, &next)) 580 { 581 fprintf (stderr, "could not parse start bit 'b' in compact string: %s\n", 582 _dbus_string_get_const_data (line)); 583 return FALSE; 584 } 585 586 if (!(val == 0 || val == 1)) 587 { 588 fprintf (stderr, "the value 'b' must be 0 or 1, see sha-1/Readme.txt\n"); 589 return FALSE; 590 } 591 592 _dbus_string_skip_blank (line, next, &next); 593 594 current_b = val; 595 n_bits = 0; 596 597 while (next < _dbus_string_get_length (line)) 598 { 599 int total_bits; 600 601 offset = next; 602 603 if (_dbus_string_get_byte (line, offset) == '^') 604 break; 605 606 if (!_dbus_string_parse_int (line, offset, &val, &next)) 607 { 608 fprintf (stderr, "could not parse bit count in compact string\n"); 609 return FALSE; 610 } 611 612 /* We now append "val" copies of "current_b" bits to the string */ 613 total_bits = n_bits + val; 614 while (n_bits < total_bits) 615 { 616 int byte_containing_next_bit = n_bits / 8; 617 int bit_containing_next_bit = 7 - (n_bits % 8); 618 unsigned char old_byte; 619 620 if (byte_containing_next_bit >= _dbus_string_get_length (decoded)) 621 { 622 if (!_dbus_string_set_length (decoded, byte_containing_next_bit + 1)) 623 _dbus_assert_not_reached ("no memory to extend to next byte"); 624 } 625 626 old_byte = _dbus_string_get_byte (decoded, byte_containing_next_bit); 627 old_byte |= current_b << bit_containing_next_bit; 628 629 #if 0 630 printf ("Appending bit %d to byte %d at bit %d resulting in byte 0x%x\n", 631 current_b, byte_containing_next_bit, 632 bit_containing_next_bit, old_byte); 633 #endif 634 635 _dbus_string_set_byte (decoded, byte_containing_next_bit, old_byte); 636 637 ++n_bits; 638 } 639 640 _dbus_string_skip_blank (line, next, &next); 641 642 current_b = !current_b; 643 } 644 645 length_bytes = (n_bits / 8 + ((n_bits % 8) ? 1 : 0)); 646 647 if (_dbus_string_get_length (decoded) != length_bytes) 648 { 649 fprintf (stderr, "Expected length %d bytes %d bits for compact string, got %d bytes\n", 650 length_bytes, n_bits, _dbus_string_get_length (decoded)); 651 return FALSE; 652 } 653 else 654 return TRUE; 655 } 656 657 static dbus_bool_t 658 get_next_expected_result (DBusString *results, 659 DBusString *result) 660 { 661 DBusString line; 662 dbus_bool_t retval; 663 664 retval = FALSE; 665 666 if (!_dbus_string_init (&line)) 667 _dbus_assert_not_reached ("no memory"); 668 669 next_iteration: 670 while (_dbus_string_pop_line (results, &line)) 671 { 672 _dbus_string_delete_leading_blanks (&line); 673 674 if (_dbus_string_get_length (&line) == 0) 675 goto next_iteration; 676 else if (_dbus_string_starts_with_c_str (&line, "#")) 677 goto next_iteration; 678 else if (_dbus_string_starts_with_c_str (&line, "H>")) 679 { 680 /* don't print */ 681 } 682 else if (_dbus_string_starts_with_c_str (&line, "D>") || 683 _dbus_string_starts_with_c_str (&line, "<D")) 684 goto next_iteration; 685 else 686 { 687 int i; 688 689 if (!_dbus_string_move (&line, 0, result, 0)) 690 _dbus_assert_not_reached ("no memory"); 691 692 i = 0; 693 while (i < _dbus_string_get_length (result)) 694 { 695 switch (_dbus_string_get_byte (result, i)) 696 { 697 case 'A': 698 _dbus_string_set_byte (result, i, 'a'); 699 break; 700 case 'B': 701 _dbus_string_set_byte (result, i, 'b'); 702 break; 703 case 'C': 704 _dbus_string_set_byte (result, i, 'c'); 705 break; 706 case 'D': 707 _dbus_string_set_byte (result, i, 'd'); 708 break; 709 case 'E': 710 _dbus_string_set_byte (result, i, 'e'); 711 break; 712 case 'F': 713 _dbus_string_set_byte (result, i, 'f'); 714 break; 715 case '^': 716 case ' ': 717 _dbus_string_delete (result, i, 1); 718 --i; /* to offset ++i below */ 719 break; 720 } 721 722 ++i; 723 } 724 725 break; 726 } 727 } 728 729 retval = TRUE; 730 731 /* out: */ 732 _dbus_string_free (&line); 733 return retval; 734 } 735 736 static dbus_bool_t 737 process_test_data (const char *test_data_dir) 738 { 739 DBusString tests_file; 740 DBusString results_file; 741 DBusString tests; 742 DBusString results; 743 DBusString line; 744 DBusString tmp; 745 int line_no; 746 dbus_bool_t retval; 747 int success_count; 748 DBusError error; 749 750 retval = FALSE; 751 752 if (!_dbus_string_init (&tests_file)) 753 _dbus_assert_not_reached ("no memory"); 754 755 if (!_dbus_string_init (&results_file)) 756 _dbus_assert_not_reached ("no memory"); 757 758 if (!_dbus_string_init (&tests)) 759 _dbus_assert_not_reached ("no memory"); 760 761 if (!_dbus_string_init (&results)) 762 _dbus_assert_not_reached ("no memory"); 763 764 if (!_dbus_string_init (&line)) 765 _dbus_assert_not_reached ("no memory"); 766 767 if (!_dbus_string_append (&tests_file, test_data_dir)) 768 _dbus_assert_not_reached ("no memory"); 769 770 if (!_dbus_string_append (&results_file, test_data_dir)) 771 _dbus_assert_not_reached ("no memory"); 772 773 _dbus_string_init_const (&tmp, "sha-1/byte-messages.sha1"); 774 if (!_dbus_concat_dir_and_file (&tests_file, &tmp)) 775 _dbus_assert_not_reached ("no memory"); 776 777 _dbus_string_init_const (&tmp, "sha-1/byte-hashes.sha1"); 778 if (!_dbus_concat_dir_and_file (&results_file, &tmp)) 779 _dbus_assert_not_reached ("no memory"); 780 781 dbus_error_init (&error); 782 if (!_dbus_file_get_contents (&tests, &tests_file, &error)) 783 { 784 fprintf (stderr, "could not load test data file %s: %s\n", 785 _dbus_string_get_const_data (&tests_file), 786 error.message); 787 dbus_error_free (&error); 788 goto out; 789 } 790 791 if (!_dbus_file_get_contents (&results, &results_file, &error)) 792 { 793 fprintf (stderr, "could not load results data file %s: %s\n", 794 _dbus_string_get_const_data (&results_file), error.message); 795 dbus_error_free (&error); 796 goto out; 797 } 798 799 success_count = 0; 800 line_no = 0; 801 next_iteration: 802 while (_dbus_string_pop_line (&tests, &line)) 803 { 804 line_no += 1; 805 806 _dbus_string_delete_leading_blanks (&line); 807 808 if (_dbus_string_get_length (&line) == 0) 809 goto next_iteration; 810 else if (_dbus_string_starts_with_c_str (&line, "#")) 811 goto next_iteration; 812 else if (_dbus_string_starts_with_c_str (&line, "H>")) 813 { 814 printf ("SHA-1: %s\n", _dbus_string_get_const_data (&line)); 815 816 if (_dbus_string_find (&line, 0, "Type 3", NULL)) 817 { 818 /* See sha-1/Readme.txt - the "Type 3" tests are 819 * random seeds, rather than data to be hashed. 820 * we'd have to do a little bit more implementation 821 * to use those tests. 822 */ 823 824 printf (" (ending tests due to Type 3 tests seen - this is normal)\n"); 825 break; 826 } 827 } 828 else if (_dbus_string_starts_with_c_str (&line, "D>") || 829 _dbus_string_starts_with_c_str (&line, "<D")) 830 goto next_iteration; 831 else 832 { 833 DBusString test; 834 DBusString result; 835 DBusString next_line; 836 DBusString expected; 837 dbus_bool_t success; 838 839 success = FALSE; 840 841 if (!_dbus_string_init (&next_line)) 842 _dbus_assert_not_reached ("no memory"); 843 844 if (!_dbus_string_init (&expected)) 845 _dbus_assert_not_reached ("no memory"); 846 847 if (!_dbus_string_init (&test)) 848 _dbus_assert_not_reached ("no memory"); 849 850 if (!_dbus_string_init (&result)) 851 _dbus_assert_not_reached ("no memory"); 852 853 /* the "compact strings" are "^"-terminated not 854 * newline-terminated so readahead to find the 855 * "^" 856 */ 857 while (!_dbus_string_find (&line, 0, "^", NULL) && 858 _dbus_string_pop_line (&tests, &next_line)) 859 { 860 if (!_dbus_string_append_byte (&line, ' ') || 861 !_dbus_string_move (&next_line, 0, &line, 862 _dbus_string_get_length (&line))) 863 _dbus_assert_not_reached ("no memory"); 864 } 865 866 if (!decode_compact_string (&line, &test)) 867 { 868 fprintf (stderr, "Failed to decode line %d as a compact string\n", 869 line_no); 870 goto failure; 871 } 872 873 if (!_dbus_sha_compute (&test, &result)) 874 _dbus_assert_not_reached ("no memory for SHA-1 result"); 875 876 if (!get_next_expected_result (&results, &expected)) 877 { 878 fprintf (stderr, "Failed to read an expected result\n"); 879 goto failure; 880 } 881 882 if (!_dbus_string_equal (&result, &expected)) 883 { 884 fprintf (stderr, " for line %d got hash %s expected %s\n", 885 line_no, 886 _dbus_string_get_const_data (&result), 887 _dbus_string_get_const_data (&expected)); 888 goto failure; 889 } 890 else 891 { 892 success_count += 1; 893 } 894 895 success = TRUE; 896 897 failure: 898 _dbus_string_free (&test); 899 _dbus_string_free (&result); 900 _dbus_string_free (&next_line); 901 _dbus_string_free (&expected); 902 903 if (!success) 904 goto out; 905 } 906 } 907 908 retval = TRUE; 909 910 printf ("Passed the %d SHA-1 tests in the test file\n", 911 success_count); 912 913 out: 914 _dbus_string_free (&tests_file); 915 _dbus_string_free (&results_file); 916 _dbus_string_free (&tests); 917 _dbus_string_free (&results); 918 _dbus_string_free (&line); 919 920 return retval; 921 } 922 923 /** 924 * @ingroup DBusSHAInternals 925 * Unit test for SHA computation. 926 * 927 * @returns #TRUE on success. 928 */ 929 dbus_bool_t 930 _dbus_sha_test (const char *test_data_dir) 931 { 932 unsigned char all_bytes[256]; 933 int i; 934 935 if (test_data_dir != NULL) 936 { 937 if (!process_test_data (test_data_dir)) 938 return FALSE; 939 } 940 else 941 printf ("No test data dir\n"); 942 943 i = 0; 944 while (i < 256) 945 { 946 all_bytes[i] = i; 947 ++i; 948 } 949 950 if (!check_sha_binary (all_bytes, 256, 951 "4916d6bdb7f78e6803698cab32d1586ea457dfc8")) 952 return FALSE; 953 954 #define CHECK(input,expected) if (!check_sha_str (input, expected)) return FALSE 955 956 CHECK ("", "da39a3ee5e6b4b0d3255bfef95601890afd80709"); 957 CHECK ("a", "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8"); 958 CHECK ("abc", "a9993e364706816aba3e25717850c26c9cd0d89d"); 959 CHECK ("message digest", "c12252ceda8be8994d5fa0290a47231c1d16aae3"); 960 CHECK ("abcdefghijklmnopqrstuvwxyz", "32d10c7b8cf96570ca04ce37f2a19d84240d3a89"); 961 CHECK ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 962 "761c457bf73b14d27e9e9265c46f4b4dda11f940"); 963 CHECK ("12345678901234567890123456789012345678901234567890123456789012345678901234567890", 964 "50abf5706a150990a08b2c5ea40fa0e585554732"); 965 966 return TRUE; 967 } 968 969 #endif /* DBUS_BUILD_TESTS */ 970