Home | History | Annotate | Download | only in dbus
      1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
      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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     22  *
     23  */
     24 
     25 #include <config.h>
     26 #include "dbus-internals.h"
     27 #include "dbus-sha.h"
     28 #include "dbus-marshal-basic.h" /* for byteswap routines */
     29 #include <string.h>
     30 
     31 /* The following comments have the history of where this code
     32  * comes from. I actually copied it from GNet in GNOME CVS.
     33  * - hp (at) redhat.com
     34  */
     35 
     36 /*
     37  *  sha.h : Implementation of the Secure Hash Algorithm
     38  *
     39  * Part of the Python Cryptography Toolkit, version 1.0.0
     40  *
     41  * Copyright (C) 1995, A.M. Kuchling
     42  *
     43  * Distribute and use freely; there are no restrictions on further
     44  * dissemination and usage except those imposed by the laws of your
     45  * country of residence.
     46  *
     47  */
     48 
     49 /* SHA: NIST's Secure Hash Algorithm */
     50 
     51 /* Based on SHA code originally posted to sci.crypt by Peter Gutmann
     52    in message <30ajo5$oe8 (at) ccu2.auckland.ac.nz>.
     53    Modified to test for endianness on creation of SHA objects by AMK.
     54    Also, the original specification of SHA was found to have a weakness
     55    by NSA/NIST.  This code implements the fixed version of SHA.
     56 */
     57 
     58 /* Here's the first paragraph of Peter Gutmann's posting:
     59 
     60 The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
     61 SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
     62 what's changed in the new version.  The fix is a simple change which involves
     63 adding a single rotate in the initial expansion function.  It is unknown
     64 whether this is an optimal solution to the problem which was discovered in the
     65 SHA or whether it's simply a bandaid which fixes the problem with a minimum of
     66 effort (for example the reengineering of a great many Capstone chips).
     67 */
     68 
     69 /**
     70  * @defgroup DBusSHA SHA implementation
     71  * @ingroup  DBusInternals
     72  * @brief SHA-1 hash
     73  *
     74  * Types and functions related to computing SHA-1 hash.
     75  */
     76 
     77 /**
     78  * @defgroup DBusSHAInternals SHA implementation details
     79  * @ingroup  DBusInternals
     80  * @brief Internals of SHA implementation.
     81  *
     82  * The implementation of SHA-1 (see http://www.itl.nist.gov/fipspubs/fip180-1.htm).
     83  * This SHA implementation was written by A.M. Kuchling
     84  *
     85  * @{
     86  */
     87 
     88 #ifndef DOXYGEN_SHOULD_SKIP_THIS
     89 
     90 /* The SHA block size and message digest sizes, in bytes */
     91 
     92 #define SHA_DATASIZE    64
     93 #define SHA_DIGESTSIZE  20
     94 
     95 /* The SHA f()-functions.  The f1 and f3 functions can be optimized to
     96    save one boolean operation each - thanks to Rich Schroeppel,
     97    rcs (at) cs.arizona.edu for discovering this */
     98 
     99 /*#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) )          // Rounds  0-19 */
    100 #define f1(x,y,z)  ( z ^ ( x & ( y ^ z ) ) )           /* Rounds  0-19 */
    101 #define f2(x,y,z)  ( x ^ y ^ z )                       /* Rounds 20-39 */
    102 /*#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) )   // Rounds 40-59 */
    103 #define f3(x,y,z)  ( ( x & y ) | ( z & ( x | y ) ) )   /* Rounds 40-59 */
    104 #define f4(x,y,z)  ( x ^ y ^ z )                       /* Rounds 60-79 */
    105 
    106 /* The SHA Mysterious Constants */
    107 
    108 #define K1  0x5A827999L                                 /* Rounds  0-19 */
    109 #define K2  0x6ED9EBA1L                                 /* Rounds 20-39 */
    110 #define K3  0x8F1BBCDCL                                 /* Rounds 40-59 */
    111 #define K4  0xCA62C1D6L                                 /* Rounds 60-79 */
    112 
    113 /* SHA initial values */
    114 
    115 #define h0init  0x67452301L
    116 #define h1init  0xEFCDAB89L
    117 #define h2init  0x98BADCFEL
    118 #define h3init  0x10325476L
    119 #define h4init  0xC3D2E1F0L
    120 
    121 /* Note that it may be necessary to add parentheses to these macros if they
    122    are to be called with expressions as arguments */
    123 /* 32-bit rotate left - kludged with shifts */
    124 
    125 #define ROTL(n,X) ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
    126 
    127 /* The initial expanding function.  The hash function is defined over an
    128    80-word expanded input array W, where the first 16 are copies of the input
    129    data, and the remaining 64 are defined by
    130 
    131         W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
    132 
    133    This implementation generates these values on the fly in a circular
    134    buffer - thanks to Colin Plumb, colin (at) nyx10.cs.du.edu for this
    135    optimization.
    136 
    137    The updated SHA changes the expanding function by adding a rotate of 1
    138    bit.  Thanks to Jim Gillogly, jim (at) rand.org, and an anonymous contributor
    139    for this information */
    140 
    141 #define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
    142                                                  W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
    143 
    144 
    145 /* The prototype SHA sub-round.  The fundamental sub-round is:
    146 
    147         a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
    148         b' = a;
    149         c' = ROTL( 30, b );
    150         d' = c;
    151         e' = d;
    152 
    153    but this is implemented by unrolling the loop 5 times and renaming the
    154    variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
    155    This code is then replicated 20 times for each of the 4 functions, using
    156    the next 20 values from the W[] array each time */
    157 
    158 #define subRound(a, b, c, d, e, f, k, data) \
    159    ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
    160 
    161 #endif /* !DOXYGEN_SHOULD_SKIP_THIS */
    162 
    163 /* Perform the SHA transformation.  Note that this code, like MD5, seems to
    164    break some optimizing compilers due to the complexity of the expressions
    165    and the size of the basic block.  It may be necessary to split it into
    166    sections, e.g. based on the four subrounds
    167 
    168    Note that this corrupts the context->data area */
    169 
    170 static void
    171 SHATransform(dbus_uint32_t *digest, dbus_uint32_t *data)
    172 {
    173   dbus_uint32_t A, B, C, D, E;     /* Local vars */
    174   dbus_uint32_t eData[16];       /* Expanded data */
    175 
    176   /* Set up first buffer and local data buffer */
    177   A = digest[0];
    178   B = digest[1];
    179   C = digest[2];
    180   D = digest[3];
    181   E = digest[4];
    182   memmove (eData, data, SHA_DATASIZE);
    183 
    184   /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
    185   subRound (A, B, C, D, E, f1, K1, eData[0]);
    186   subRound (E, A, B, C, D, f1, K1, eData[1]);
    187   subRound (D, E, A, B, C, f1, K1, eData[2]);
    188   subRound (C, D, E, A, B, f1, K1, eData[3]);
    189   subRound (B, C, D, E, A, f1, K1, eData[4]);
    190   subRound (A, B, C, D, E, f1, K1, eData[5]);
    191   subRound (E, A, B, C, D, f1, K1, eData[6]);
    192   subRound (D, E, A, B, C, f1, K1, eData[7]);
    193   subRound (C, D, E, A, B, f1, K1, eData[8]);
    194   subRound (B, C, D, E, A, f1, K1, eData[9]);
    195   subRound (A, B, C, D, E, f1, K1, eData[10]);
    196   subRound (E, A, B, C, D, f1, K1, eData[11]);
    197   subRound (D, E, A, B, C, f1, K1, eData[12]);
    198   subRound (C, D, E, A, B, f1, K1, eData[13]);
    199   subRound (B, C, D, E, A, f1, K1, eData[14]);
    200   subRound (A, B, C, D, E, f1, K1, eData[15]);
    201   subRound (E, A, B, C, D, f1, K1, expand ( eData, 16) );
    202   subRound (D, E, A, B, C, f1, K1, expand ( eData, 17) );
    203   subRound (C, D, E, A, B, f1, K1, expand ( eData, 18) );
    204   subRound (B, C, D, E, A, f1, K1, expand ( eData, 19) );
    205 
    206   subRound (A, B, C, D, E, f2, K2, expand ( eData, 20) );
    207   subRound (E, A, B, C, D, f2, K2, expand ( eData, 21) );
    208   subRound (D, E, A, B, C, f2, K2, expand ( eData, 22) );
    209   subRound (C, D, E, A, B, f2, K2, expand ( eData, 23) );
    210   subRound (B, C, D, E, A, f2, K2, expand ( eData, 24) );
    211   subRound (A, B, C, D, E, f2, K2, expand ( eData, 25) );
    212   subRound (E, A, B, C, D, f2, K2, expand ( eData, 26) );
    213   subRound (D, E, A, B, C, f2, K2, expand ( eData, 27) );
    214   subRound (C, D, E, A, B, f2, K2, expand ( eData, 28) );
    215   subRound (B, C, D, E, A, f2, K2, expand ( eData, 29) );
    216   subRound (A, B, C, D, E, f2, K2, expand ( eData, 30) );
    217   subRound (E, A, B, C, D, f2, K2, expand ( eData, 31) );
    218   subRound (D, E, A, B, C, f2, K2, expand ( eData, 32) );
    219   subRound (C, D, E, A, B, f2, K2, expand ( eData, 33) );
    220   subRound (B, C, D, E, A, f2, K2, expand ( eData, 34) );
    221   subRound (A, B, C, D, E, f2, K2, expand ( eData, 35) );
    222   subRound (E, A, B, C, D, f2, K2, expand ( eData, 36) );
    223   subRound (D, E, A, B, C, f2, K2, expand ( eData, 37) );
    224   subRound (C, D, E, A, B, f2, K2, expand ( eData, 38) );
    225   subRound (B, C, D, E, A, f2, K2, expand ( eData, 39) );
    226 
    227   subRound (A, B, C, D, E, f3, K3, expand ( eData, 40) );
    228   subRound (E, A, B, C, D, f3, K3, expand ( eData, 41) );
    229   subRound (D, E, A, B, C, f3, K3, expand ( eData, 42) );
    230   subRound (C, D, E, A, B, f3, K3, expand ( eData, 43) );
    231   subRound (B, C, D, E, A, f3, K3, expand ( eData, 44) );
    232   subRound (A, B, C, D, E, f3, K3, expand ( eData, 45) );
    233   subRound (E, A, B, C, D, f3, K3, expand ( eData, 46) );
    234   subRound (D, E, A, B, C, f3, K3, expand ( eData, 47) );
    235   subRound (C, D, E, A, B, f3, K3, expand ( eData, 48) );
    236   subRound (B, C, D, E, A, f3, K3, expand ( eData, 49) );
    237   subRound (A, B, C, D, E, f3, K3, expand ( eData, 50) );
    238   subRound (E, A, B, C, D, f3, K3, expand ( eData, 51) );
    239   subRound (D, E, A, B, C, f3, K3, expand ( eData, 52) );
    240   subRound (C, D, E, A, B, f3, K3, expand ( eData, 53) );
    241   subRound (B, C, D, E, A, f3, K3, expand ( eData, 54) );
    242   subRound (A, B, C, D, E, f3, K3, expand ( eData, 55) );
    243   subRound (E, A, B, C, D, f3, K3, expand ( eData, 56) );
    244   subRound (D, E, A, B, C, f3, K3, expand ( eData, 57) );
    245   subRound (C, D, E, A, B, f3, K3, expand ( eData, 58) );
    246   subRound (B, C, D, E, A, f3, K3, expand ( eData, 59) );
    247 
    248   subRound (A, B, C, D, E, f4, K4, expand ( eData, 60) );
    249   subRound (E, A, B, C, D, f4, K4, expand ( eData, 61) );
    250   subRound (D, E, A, B, C, f4, K4, expand ( eData, 62) );
    251   subRound (C, D, E, A, B, f4, K4, expand ( eData, 63) );
    252   subRound (B, C, D, E, A, f4, K4, expand ( eData, 64) );
    253   subRound (A, B, C, D, E, f4, K4, expand ( eData, 65) );
    254   subRound (E, A, B, C, D, f4, K4, expand ( eData, 66) );
    255   subRound (D, E, A, B, C, f4, K4, expand ( eData, 67) );
    256   subRound (C, D, E, A, B, f4, K4, expand ( eData, 68) );
    257   subRound (B, C, D, E, A, f4, K4, expand ( eData, 69) );
    258   subRound (A, B, C, D, E, f4, K4, expand ( eData, 70) );
    259   subRound (E, A, B, C, D, f4, K4, expand ( eData, 71) );
    260   subRound (D, E, A, B, C, f4, K4, expand ( eData, 72) );
    261   subRound (C, D, E, A, B, f4, K4, expand ( eData, 73) );
    262   subRound (B, C, D, E, A, f4, K4, expand ( eData, 74) );
    263   subRound (A, B, C, D, E, f4, K4, expand ( eData, 75) );
    264   subRound (E, A, B, C, D, f4, K4, expand ( eData, 76) );
    265   subRound (D, E, A, B, C, f4, K4, expand ( eData, 77) );
    266   subRound (C, D, E, A, B, f4, K4, expand ( eData, 78) );
    267   subRound (B, C, D, E, A, f4, K4, expand ( eData, 79) );
    268 
    269   /* Build message digest */
    270   digest[0] += A;
    271   digest[1] += B;
    272   digest[2] += C;
    273   digest[3] += D;
    274   digest[4] += E;
    275 }
    276 
    277 /* When run on a little-endian CPU we need to perform byte reversal on an
    278    array of longwords. */
    279 
    280 #ifdef WORDS_BIGENDIAN
    281 #define swap_words(buffer, byte_count)
    282 #else
    283 static void
    284 swap_words (dbus_uint32_t *buffer,
    285             int            byte_count)
    286 {
    287   byte_count /= sizeof (dbus_uint32_t);
    288   while (byte_count--)
    289     {
    290       *buffer = DBUS_UINT32_SWAP_LE_BE (*buffer);
    291       ++buffer;
    292     }
    293 }
    294 #endif
    295 
    296 static void
    297 sha_init (DBusSHAContext *context)
    298 {
    299   /* Set the h-vars to their initial values */
    300   context->digest[0] = h0init;
    301   context->digest[1] = h1init;
    302   context->digest[2] = h2init;
    303   context->digest[3] = h3init;
    304   context->digest[4] = h4init;
    305 
    306   /* Initialise bit count */
    307   context->count_lo = context->count_hi = 0;
    308 }
    309 
    310 static void
    311 sha_append (DBusSHAContext      *context,
    312             const unsigned char *buffer,
    313             unsigned int         count)
    314 {
    315   dbus_uint32_t tmp;
    316   unsigned int dataCount;
    317 
    318   /* Update bitcount */
    319   tmp = context->count_lo;
    320   if (( context->count_lo = tmp + ( ( dbus_uint32_t) count << 3) ) < tmp)
    321     context->count_hi++;             /* Carry from low to high */
    322   context->count_hi += count >> 29;
    323 
    324   /* Get count of bytes already in data */
    325   dataCount = (int) (tmp >> 3) & 0x3F;
    326 
    327   /* Handle any leading odd-sized chunks */
    328   if (dataCount)
    329     {
    330       unsigned char *p = (unsigned char *) context->data + dataCount;
    331 
    332       dataCount = SHA_DATASIZE - dataCount;
    333       if (count < dataCount)
    334         {
    335           memmove (p, buffer, count);
    336           return;
    337         }
    338       memmove (p, buffer, dataCount);
    339       swap_words (context->data, SHA_DATASIZE);
    340       SHATransform (context->digest, context->data);
    341       buffer += dataCount;
    342       count -= dataCount;
    343     }
    344 
    345   /* Process data in SHA_DATASIZE chunks */
    346   while (count >= SHA_DATASIZE)
    347     {
    348       memmove (context->data, buffer, SHA_DATASIZE);
    349       swap_words (context->data, SHA_DATASIZE);
    350       SHATransform (context->digest, context->data);
    351       buffer += SHA_DATASIZE;
    352       count -= SHA_DATASIZE;
    353     }
    354 
    355   /* Handle any remaining bytes of data. */
    356   memmove (context->data, buffer, count);
    357 }
    358 
    359 
    360 /* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern
    361    1 0* (64-bit count of bits processed, MSB-first) */
    362 
    363 static void
    364 sha_finish (DBusSHAContext *context, unsigned char digest[20])
    365 {
    366   int count;
    367   unsigned char *data_p;
    368 
    369   /* Compute number of bytes mod 64 */
    370   count = (int) context->count_lo;
    371   count = (count >> 3) & 0x3F;
    372 
    373   /* Set the first char of padding to 0x80.  This is safe since there is
    374      always at least one byte free */
    375   data_p = (unsigned char *) context->data + count;
    376   *data_p++ = 0x80;
    377 
    378   /* Bytes of padding needed to make 64 bytes */
    379   count = SHA_DATASIZE - 1 - count;
    380 
    381   /* Pad out to 56 mod 64 */
    382   if (count < 8)
    383     {
    384       /* Two lots of padding:  Pad the first block to 64 bytes */
    385       memset (data_p, 0, count);
    386       swap_words (context->data, SHA_DATASIZE);
    387       SHATransform (context->digest, context->data);
    388 
    389       /* Now fill the next block with 56 bytes */
    390       memset (context->data, 0, SHA_DATASIZE - 8);
    391     }
    392   else
    393     /* Pad block to 56 bytes */
    394     memset (data_p, 0, count - 8);
    395 
    396   /* Append length in bits and transform */
    397   context->data[14] = context->count_hi;
    398   context->data[15] = context->count_lo;
    399 
    400   swap_words (context->data, SHA_DATASIZE - 8);
    401   SHATransform (context->digest, context->data);
    402   swap_words (context->digest, SHA_DIGESTSIZE);
    403   memmove (digest, context->digest, SHA_DIGESTSIZE);
    404 }
    405 
    406 /** @} */ /* End of internals */
    407 
    408 /**
    409  * @addtogroup DBusSHA
    410  *
    411  * @{
    412  */
    413 
    414 /**
    415  * Initializes the SHA context.
    416  *
    417  * @param context an uninitialized context, typically on the stack.
    418  */
    419 void
    420 _dbus_sha_init (DBusSHAContext *context)
    421 {
    422   sha_init (context);
    423 }
    424 
    425 /**
    426  * Feeds more data into an existing shasum computation.
    427  *
    428  * @param context the SHA context
    429  * @param data the additional data to hash
    430  */
    431 void
    432 _dbus_sha_update (DBusSHAContext   *context,
    433                   const DBusString *data)
    434 {
    435   unsigned int inputLen;
    436   const unsigned char *input;
    437 
    438   input = (const unsigned char*) _dbus_string_get_const_data (data);
    439   inputLen = _dbus_string_get_length (data);
    440 
    441   sha_append (context, input, inputLen);
    442 }
    443 
    444 /**
    445  * SHA finalization. Ends an SHA message-digest operation, writing the
    446  * the message digest and zeroing the context.  The results are
    447  * returned as a raw 20-byte digest, not as the ascii-hex-digits
    448  * string form of the digest.
    449  *
    450  * @param context the SHA context
    451  * @param results string to append the 20-byte SHA digest to
    452  * @returns #FALSE if not enough memory to append the digest
    453  *
    454  */
    455 dbus_bool_t
    456 _dbus_sha_final (DBusSHAContext   *context,
    457                  DBusString       *results)
    458 {
    459   unsigned char digest[20];
    460 
    461   sha_finish (context, digest);
    462 
    463   if (!_dbus_string_append_len (results, digest, 20))
    464     return FALSE;
    465 
    466   /* some kind of security paranoia, though it seems pointless
    467    * to me given the nonzeroed stuff flying around
    468    */
    469   _DBUS_ZERO(*context);
    470 
    471   return TRUE;
    472 }
    473 
    474 /**
    475  * Computes the ASCII hex-encoded shasum of the given data and
    476  * appends it to the output string.
    477  *
    478  * @param data input data to be hashed
    479  * @param ascii_output string to append ASCII shasum to
    480  * @returns #FALSE if not enough memory
    481  */
    482 dbus_bool_t
    483 _dbus_sha_compute (const DBusString *data,
    484                    DBusString       *ascii_output)
    485 {
    486   DBusSHAContext context;
    487   DBusString digest;
    488 
    489   _dbus_sha_init (&context);
    490 
    491   _dbus_sha_update (&context, data);
    492 
    493   if (!_dbus_string_init (&digest))
    494     return FALSE;
    495 
    496   if (!_dbus_sha_final (&context, &digest))
    497     goto error;
    498 
    499   if (!_dbus_string_hex_encode (&digest, 0, ascii_output,
    500                                 _dbus_string_get_length (ascii_output)))
    501     goto error;
    502 
    503   _dbus_string_free (&digest);
    504 
    505   return TRUE;
    506 
    507  error:
    508   _dbus_string_free (&digest);
    509   return FALSE;
    510 }
    511 
    512 /** @} */ /* end of exported functions */
    513 
    514 #ifdef DBUS_BUILD_TESTS
    515 #include "dbus-test.h"
    516 #include <stdio.h>
    517 
    518 static dbus_bool_t
    519 check_sha_binary (const unsigned char *input,
    520                   int                  input_len,
    521                   const char          *expected)
    522 {
    523   DBusString input_str;
    524   DBusString expected_str;
    525   DBusString results;
    526 
    527   _dbus_string_init_const_len (&input_str, input, input_len);
    528   _dbus_string_init_const (&expected_str, expected);
    529 
    530   if (!_dbus_string_init (&results))
    531     _dbus_assert_not_reached ("no memory for SHA-1 results");
    532 
    533   if (!_dbus_sha_compute (&input_str, &results))
    534     _dbus_assert_not_reached ("no memory for SHA-1 results");
    535 
    536   if (!_dbus_string_equal (&expected_str, &results))
    537     {
    538       _dbus_warn ("Expected hash %s got %s for SHA-1 sum\n",
    539                   expected,
    540                   _dbus_string_get_const_data (&results));
    541       _dbus_string_free (&results);
    542       return FALSE;
    543     }
    544 
    545   _dbus_string_free (&results);
    546   return TRUE;
    547 }
    548 
    549 static dbus_bool_t
    550 check_sha_str (const char *input,
    551                const char *expected)
    552 {
    553   return check_sha_binary (input, strlen (input), expected);
    554 }
    555 
    556 static dbus_bool_t
    557 decode_compact_string (const DBusString *line,
    558                        DBusString       *decoded)
    559 {
    560   int n_bits;
    561   dbus_bool_t current_b;
    562   int offset;
    563   int next;
    564   long val;
    565   int length_bytes;
    566 
    567   offset = 0;
    568   next = 0;
    569 
    570   if (!_dbus_string_parse_int (line, offset, &val, &next))
    571     {
    572       fprintf (stderr, "could not parse length at start of compact string: %s\n",
    573                _dbus_string_get_const_data (line));
    574       return FALSE;
    575     }
    576 
    577   _dbus_string_skip_blank (line, next, &next);
    578 
    579   offset = next;
    580   if (!_dbus_string_parse_int (line, offset, &val, &next))
    581     {
    582       fprintf (stderr, "could not parse start bit 'b' in compact string: %s\n",
    583                _dbus_string_get_const_data (line));
    584       return FALSE;
    585     }
    586 
    587   if (!(val == 0 || val == 1))
    588     {
    589       fprintf (stderr, "the value 'b' must be 0 or 1, see sha-1/Readme.txt\n");
    590       return FALSE;
    591     }
    592 
    593   _dbus_string_skip_blank (line, next, &next);
    594 
    595   current_b = val;
    596   n_bits = 0;
    597 
    598   while (next < _dbus_string_get_length (line))
    599     {
    600       int total_bits;
    601 
    602       offset = next;
    603 
    604       if (_dbus_string_get_byte (line, offset) == '^')
    605         break;
    606 
    607       if (!_dbus_string_parse_int (line, offset, &val, &next))
    608         {
    609           fprintf (stderr, "could not parse bit count in compact string\n");
    610           return FALSE;
    611         }
    612 
    613       /* We now append "val" copies of "current_b" bits to the string */
    614       total_bits = n_bits + val;
    615       while (n_bits < total_bits)
    616         {
    617           int byte_containing_next_bit = n_bits / 8;
    618           int bit_containing_next_bit = 7 - (n_bits % 8);
    619           unsigned char old_byte;
    620 
    621           if (byte_containing_next_bit >= _dbus_string_get_length (decoded))
    622             {
    623               if (!_dbus_string_set_length (decoded, byte_containing_next_bit + 1))
    624                 _dbus_assert_not_reached ("no memory to extend to next byte");
    625             }
    626 
    627           old_byte = _dbus_string_get_byte (decoded, byte_containing_next_bit);
    628           old_byte |= current_b << bit_containing_next_bit;
    629 
    630 #if 0
    631           printf ("Appending bit %d to byte %d at bit %d resulting in byte 0x%x\n",
    632                   current_b, byte_containing_next_bit,
    633                   bit_containing_next_bit, old_byte);
    634 #endif
    635 
    636           _dbus_string_set_byte (decoded, byte_containing_next_bit, old_byte);
    637 
    638           ++n_bits;
    639         }
    640 
    641       _dbus_string_skip_blank (line, next, &next);
    642 
    643       current_b = !current_b;
    644     }
    645 
    646   length_bytes = (n_bits / 8 + ((n_bits % 8) ? 1 : 0));
    647 
    648   if (_dbus_string_get_length (decoded) != length_bytes)
    649     {
    650       fprintf (stderr, "Expected length %d bytes %d bits for compact string, got %d bytes\n",
    651                length_bytes, n_bits, _dbus_string_get_length (decoded));
    652       return FALSE;
    653     }
    654   else
    655     return TRUE;
    656 }
    657 
    658 static dbus_bool_t
    659 get_next_expected_result (DBusString *results,
    660                           DBusString *result)
    661 {
    662   DBusString line;
    663   dbus_bool_t retval;
    664 
    665   retval = FALSE;
    666 
    667   if (!_dbus_string_init (&line))
    668     _dbus_assert_not_reached ("no memory");
    669 
    670  next_iteration:
    671   while (_dbus_string_pop_line (results, &line))
    672     {
    673       _dbus_string_delete_leading_blanks (&line);
    674 
    675       if (_dbus_string_get_length (&line) == 0)
    676         goto next_iteration;
    677       else if (_dbus_string_starts_with_c_str (&line, "#"))
    678         goto next_iteration;
    679       else if (_dbus_string_starts_with_c_str (&line, "H>"))
    680         {
    681           /* don't print */
    682         }
    683       else if (_dbus_string_starts_with_c_str (&line, "D>") ||
    684                _dbus_string_starts_with_c_str (&line, "<D"))
    685         goto next_iteration;
    686       else
    687         {
    688           int i;
    689 
    690           if (!_dbus_string_move (&line, 0, result, 0))
    691             _dbus_assert_not_reached ("no memory");
    692 
    693           i = 0;
    694           while (i < _dbus_string_get_length (result))
    695             {
    696               switch (_dbus_string_get_byte (result, i))
    697                 {
    698                 case 'A':
    699                   _dbus_string_set_byte (result, i, 'a');
    700                   break;
    701                 case 'B':
    702                   _dbus_string_set_byte (result, i, 'b');
    703                   break;
    704                 case 'C':
    705                   _dbus_string_set_byte (result, i, 'c');
    706                   break;
    707                 case 'D':
    708                   _dbus_string_set_byte (result, i, 'd');
    709                   break;
    710                 case 'E':
    711                   _dbus_string_set_byte (result, i, 'e');
    712                   break;
    713                 case 'F':
    714                   _dbus_string_set_byte (result, i, 'f');
    715                   break;
    716                 case '^':
    717                 case ' ':
    718                   _dbus_string_delete (result, i, 1);
    719                   --i; /* to offset ++i below */
    720                   break;
    721                 }
    722 
    723               ++i;
    724             }
    725 
    726           break;
    727         }
    728     }
    729 
    730   retval = TRUE;
    731 
    732   /* out: */
    733   _dbus_string_free (&line);
    734   return retval;
    735 }
    736 
    737 static dbus_bool_t
    738 process_test_data (const char *test_data_dir)
    739 {
    740   DBusString tests_file;
    741   DBusString results_file;
    742   DBusString tests;
    743   DBusString results;
    744   DBusString line;
    745   DBusString tmp;
    746   int line_no;
    747   dbus_bool_t retval;
    748   int success_count;
    749   DBusError error = DBUS_ERROR_INIT;
    750 
    751   retval = FALSE;
    752 
    753   if (!_dbus_string_init (&tests_file))
    754     _dbus_assert_not_reached ("no memory");
    755 
    756   if (!_dbus_string_init (&results_file))
    757     _dbus_assert_not_reached ("no memory");
    758 
    759   if (!_dbus_string_init (&tests))
    760     _dbus_assert_not_reached ("no memory");
    761 
    762   if (!_dbus_string_init (&results))
    763     _dbus_assert_not_reached ("no memory");
    764 
    765   if (!_dbus_string_init (&line))
    766     _dbus_assert_not_reached ("no memory");
    767 
    768   if (!_dbus_string_append (&tests_file, test_data_dir))
    769     _dbus_assert_not_reached ("no memory");
    770 
    771   if (!_dbus_string_append (&results_file, test_data_dir))
    772     _dbus_assert_not_reached ("no memory");
    773 
    774   _dbus_string_init_const (&tmp, "sha-1/byte-messages.sha1");
    775   if (!_dbus_concat_dir_and_file (&tests_file, &tmp))
    776     _dbus_assert_not_reached ("no memory");
    777 
    778   _dbus_string_init_const (&tmp, "sha-1/byte-hashes.sha1");
    779   if (!_dbus_concat_dir_and_file (&results_file, &tmp))
    780     _dbus_assert_not_reached ("no memory");
    781 
    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