Home | History | Annotate | Download | only in dbus
      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