index.html
Main Page
|
modules.html
Modules
|
namespaces.html
Namespace List
|
hierarchy.html
Class Hierarchy
|
annotated.html
Data Structures
|
dirs.html
Directories
|
files.html
File List
|
namespacemembers.html
Namespace Members
|
functions.html
Data Fields
|
pages.html
Related Pages
dir_000004.html
dbus
dbus-sha.c
00001
/* -*- mode: C; c-file-style: "gnu" -*- */
00002
/* dbus-sha.c SHA-1 implementation
00003
*
00004
* Copyright (C) 2003 Red Hat Inc.
00005
* Copyright (C) 1995 A. M. Kuchling
00006
*
00007
* Licensed under the Academic Free License version 2.1
00008
*
00009
* This program is free software; you can redistribute it and/or modify
00010
* it under the terms of the GNU General Public License as published by
00011
* the Free Software Foundation; either version 2 of the License, or
00012
* (at your option) any later version.
00013
*
00014
* This program is distributed in the hope that it will be useful,
00015
* but WITHOUT ANY WARRANTY; without even the implied warranty of
00016
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017
* GNU General Public License for more details.
00018
*
00019
* You should have received a copy of the GNU General Public License
00020
* along with this program; if not, write to the Free Software
00021
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022
*
00023
*/
00024
00025
#include "dbus-internals.h"
00026
#include "dbus-sha.h"
00027
#include "dbus-marshal-basic.h"
/* for byteswap routines */
00028
#include <string.h>
00029
00030
/* The following comments have the history of where this code
00031
* comes from. I actually copied it from GNet in GNOME CVS.
00032
* - hp@redhat.com
00033
*/
00034
00035
/*
00036
*  sha.h : Implementation of the Secure Hash Algorithm
00037
*
00038
* Part of the Python Cryptography Toolkit, version 1.0.0
00039
*
00040
* Copyright (C) 1995, A.M. Kuchling
00041
*
00042
* Distribute and use freely; there are no restrictions on further
00043
* dissemination and usage except those imposed by the laws of your
00044
* country of residence.
00045
*
00046
*/
00047
00048
/* SHA: NIST's Secure Hash Algorithm */
00049
00050
/* Based on SHA code originally posted to sci.crypt by Peter Gutmann
00051
in message <30ajo5$oe8@ccu2.auckland.ac.nz>.
00052
Modified to test for endianness on creation of SHA objects by AMK.
00053
Also, the original specification of SHA was found to have a weakness
00054
by NSA/NIST.  This code implements the fixed version of SHA.
00055
*/
00056
00057
/* Here's the first paragraph of Peter Gutmann's posting:
00058
00059
The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
00060
SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
00061
what's changed in the new version.  The fix is a simple change which involves
00062
adding a single rotate in the initial expansion function.  It is unknown
00063
whether this is an optimal solution to the problem which was discovered in the
00064
SHA or whether it's simply a bandaid which fixes the problem with a minimum of
00065
effort (for example the reengineering of a great many Capstone chips).
00066
*/
00067
00087
#ifndef DOXYGEN_SHOULD_SKIP_THIS
00088
00089
/* The SHA block size and message digest sizes, in bytes */
00090
00091
#define SHA_DATASIZE    64
00092
#define SHA_DIGESTSIZE  20
00093
00094
/* The SHA f()-functions.  The f1 and f3 functions can be optimized to
00095
save one boolean operation each - thanks to Rich Schroeppel,
00096
rcs@cs.arizona.edu for discovering this */
00097
00098
/*#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) )          // Rounds  0-19 */
00099
#define f1(x,y,z)  ( z ^ ( x & ( y ^ z ) ) )
/* Rounds  0-19 */
00100
#define f2(x,y,z)  ( x ^ y ^ z )
/* Rounds 20-39 */
00101
/*#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) )   // Rounds 40-59 */
00102
#define f3(x,y,z)  ( ( x & y ) | ( z & ( x | y ) ) )
/* Rounds 40-59 */
00103
#define f4(x,y,z)  ( x ^ y ^ z )
/* Rounds 60-79 */
00104
00105
/* The SHA Mysterious Constants */
00106
00107
#define K1  0x5A827999L
/* Rounds  0-19 */
00108
#define K2  0x6ED9EBA1L
/* Rounds 20-39 */
00109
#define K3  0x8F1BBCDCL
/* Rounds 40-59 */
00110
#define K4  0xCA62C1D6L
/* Rounds 60-79 */
00111
00112
/* SHA initial values */
00113
00114
#define h0init  0x67452301L
00115
#define h1init  0xEFCDAB89L
00116
#define h2init  0x98BADCFEL
00117
#define h3init  0x10325476L
00118
#define h4init  0xC3D2E1F0L
00119
00120
/* Note that it may be necessary to add parentheses to these macros if they
00121
are to be called with expressions as arguments */
00122
/* 32-bit rotate left - kludged with shifts */
00123
00124
#define ROTL(n,X) ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
00125
00126
/* The initial expanding function.  The hash function is defined over an
00127
80-word expanded input array W, where the first 16 are copies of the input
00128
data, and the remaining 64 are defined by
00129
00130
W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
00131
00132
This implementation generates these values on the fly in a circular
00133
buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
00134
optimization.
00135
00136
The updated SHA changes the expanding function by adding a rotate of 1
00137
bit.  Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
00138
for this information */
00139
00140
#define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
00141
W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
00142
00143
00144
/* The prototype SHA sub-round.  The fundamental sub-round is:
00145
00146
a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
00147
b' = a;
00148
c' = ROTL( 30, b );
00149
d' = c;
00150
e' = d;
00151
00152
but this is implemented by unrolling the loop 5 times and renaming the
00153
variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
00154
This code is then replicated 20 times for each of the 4 functions, using
00155
the next 20 values from the W[] array each time */
00156
00157
#define subRound(a, b, c, d, e, f, k, data) \
00158
( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
00159
00160
#endif
/* DOXYGEN_SHOULD_SKIP_THIS */
00161
00162
/* Perform the SHA transformation.  Note that this code, like MD5, seems to
00163
break some optimizing compilers due to the complexity of the expressions
00164
and the size of the basic block.  It may be necessary to split it into
00165
sections, e.g. based on the four subrounds
00166
00167
Note that this corrupts the context->data area */
00168
00169
static
void
00170 SHATransform(
group__DBusTypes.html#ga3
dbus_uint32_t
*digest,
group__DBusTypes.html#ga3
dbus_uint32_t
*data)
00171 {
00172
group__DBusTypes.html#ga3
dbus_uint32_t
A, B, C, D, E;
/* Local vars */
00173
group__DBusTypes.html#ga3
dbus_uint32_t
eData[16];
/* Expanded data */
00174
00175
/* Set up first buffer and local data buffer */
00176   A = digest[0];
00177   B = digest[1];
00178   C = digest[2];
00179   D = digest[3];
00180   E = digest[4];
00181   memmove (eData, data, SHA_DATASIZE);
00182
00183
/* Heavy mangling, in 4 sub-rounds of 20 interations each. */
00184   subRound (A, B, C, D, E, f1, K1, eData[0]);
00185   subRound (E, A, B, C, D, f1, K1, eData[1]);
00186   subRound (D, E, A, B, C, f1, K1, eData[2]);
00187   subRound (C, D, E, A, B, f1, K1, eData[3]);
00188   subRound (B, C, D, E, A, f1, K1, eData[4]);
00189   subRound (A, B, C, D, E, f1, K1, eData[5]);
00190   subRound (E, A, B, C, D, f1, K1, eData[6]);
00191   subRound (D, E, A, B, C, f1, K1, eData[7]);
00192   subRound (C, D, E, A, B, f1, K1, eData[8]);
00193   subRound (B, C, D, E, A, f1, K1, eData[9]);
00194   subRound (A, B, C, D, E, f1, K1, eData[10]);
00195   subRound (E, A, B, C, D, f1, K1, eData[11]);
00196   subRound (D, E, A, B, C, f1, K1, eData[12]);
00197   subRound (C, D, E, A, B, f1, K1, eData[13]);
00198   subRound (B, C, D, E, A, f1, K1, eData[14]);
00199   subRound (A, B, C, D, E, f1, K1, eData[15]);
00200   subRound (E, A, B, C, D, f1, K1, expand ( eData, 16) );
00201   subRound (D, E, A, B, C, f1, K1, expand ( eData, 17) );
00202   subRound (C, D, E, A, B, f1, K1, expand ( eData, 18) );
00203   subRound (B, C, D, E, A, f1, K1, expand ( eData, 19) );
00204
00205   subRound (A, B, C, D, E, f2, K2, expand ( eData, 20) );
00206   subRound (E, A, B, C, D, f2, K2, expand ( eData, 21) );
00207   subRound (D, E, A, B, C, f2, K2, expand ( eData, 22) );
00208   subRound (C, D, E, A, B, f2, K2, expand ( eData, 23) );
00209   subRound (B, C, D, E, A, f2, K2, expand ( eData, 24) );
00210   subRound (A, B, C, D, E, f2, K2, expand ( eData, 25) );
00211   subRound (E, A, B, C, D, f2, K2, expand ( eData, 26) );
00212   subRound (D, E, A, B, C, f2, K2, expand ( eData, 27) );
00213   subRound (C, D, E, A, B, f2, K2, expand ( eData, 28) );
00214   subRound (B, C, D, E, A, f2, K2, expand ( eData, 29) );
00215   subRound (A, B, C, D, E, f2, K2, expand ( eData, 30) );
00216   subRound (E, A, B, C, D, f2, K2, expand ( eData, 31) );
00217   subRound (D, E, A, B, C, f2, K2, expand ( eData, 32) );
00218   subRound (C, D, E, A, B, f2, K2, expand ( eData, 33) );
00219   subRound (B, C, D, E, A, f2, K2, expand ( eData, 34) );
00220   subRound (A, B, C, D, E, f2, K2, expand ( eData, 35) );
00221   subRound (E, A, B, C, D, f2, K2, expand ( eData, 36) );
00222   subRound (D, E, A, B, C, f2, K2, expand ( eData, 37) );
00223   subRound (C, D, E, A, B, f2, K2, expand ( eData, 38) );
00224   subRound (B, C, D, E, A, f2, K2, expand ( eData, 39) );
00225
00226   subRound (A, B, C, D, E, f3, K3, expand ( eData, 40) );
00227   subRound (E, A, B, C, D, f3, K3, expand ( eData, 41) );
00228   subRound (D, E, A, B, C, f3, K3, expand ( eData, 42) );
00229   subRound (C, D, E, A, B, f3, K3, expand ( eData, 43) );
00230   subRound (B, C, D, E, A, f3, K3, expand ( eData, 44) );
00231   subRound (A, B, C, D, E, f3, K3, expand ( eData, 45) );
00232   subRound (E, A, B, C, D, f3, K3, expand ( eData, 46) );
00233   subRound (D, E, A, B, C, f3, K3, expand ( eData, 47) );
00234   subRound (C, D, E, A, B, f3, K3, expand ( eData, 48) );
00235   subRound (B, C, D, E, A, f3, K3, expand ( eData, 49) );
00236   subRound (A, B, C, D, E, f3, K3, expand ( eData, 50) );
00237   subRound (E, A, B, C, D, f3, K3, expand ( eData, 51) );
00238   subRound (D, E, A, B, C, f3, K3, expand ( eData, 52) );
00239   subRound (C, D, E, A, B, f3, K3, expand ( eData, 53) );
00240   subRound (B, C, D, E, A, f3, K3, expand ( eData, 54) );
00241   subRound (A, B, C, D, E, f3, K3, expand ( eData, 55) );
00242   subRound (E, A, B, C, D, f3, K3, expand ( eData, 56) );
00243   subRound (D, E, A, B, C, f3, K3, expand ( eData, 57) );
00244   subRound (C, D, E, A, B, f3, K3, expand ( eData, 58) );
00245   subRound (B, C, D, E, A, f3, K3, expand ( eData, 59) );
00246
00247   subRound (A, B, C, D, E, f4, K4, expand ( eData, 60) );
00248   subRound (E, A, B, C, D, f4, K4, expand ( eData, 61) );
00249   subRound (D, E, A, B, C, f4, K4, expand ( eData, 62) );
00250   subRound (C, D, E, A, B, f4, K4, expand ( eData, 63) );
00251   subRound (B, C, D, E, A, f4, K4, expand ( eData, 64) );
00252   subRound (A, B, C, D, E, f4, K4, expand ( eData, 65) );
00253   subRound (E, A, B, C, D, f4, K4, expand ( eData, 66) );
00254   subRound (D, E, A, B, C, f4, K4, expand ( eData, 67) );
00255   subRound (C, D, E, A, B, f4, K4, expand ( eData, 68) );
00256   subRound (B, C, D, E, A, f4, K4, expand ( eData, 69) );
00257   subRound (A, B, C, D, E, f4, K4, expand ( eData, 70) );
00258   subRound (E, A, B, C, D, f4, K4, expand ( eData, 71) );
00259   subRound (D, E, A, B, C, f4, K4, expand ( eData, 72) );
00260   subRound (C, D, E, A, B, f4, K4, expand ( eData, 73) );
00261   subRound (B, C, D, E, A, f4, K4, expand ( eData, 74) );
00262   subRound (A, B, C, D, E, f4, K4, expand ( eData, 75) );
00263   subRound (E, A, B, C, D, f4, K4, expand ( eData, 76) );
00264   subRound (D, E, A, B, C, f4, K4, expand ( eData, 77) );
00265   subRound (C, D, E, A, B, f4, K4, expand ( eData, 78) );
00266   subRound (B, C, D, E, A, f4, K4, expand ( eData, 79) );
00267
00268
/* Build message digest */
00269   digest[0] += A;
00270   digest[1] += B;
00271   digest[2] += C;
00272   digest[3] += D;
00273   digest[4] += E;
00274 }
00275
00276
/* When run on a little-endian CPU we need to perform byte reversal on an
00277
array of longwords. */
00278
00279
#ifdef WORDS_BIGENDIAN
00280
#define swap_words(buffer, byte_count)
00281
#else
00282
static
void
00283 swap_words (
group__DBusTypes.html#ga3
dbus_uint32_t
*buffer,
00284
int
byte_count)
00285 {
00286   byte_count /=
sizeof
(
group__DBusTypes.html#ga3
dbus_uint32_t
);
00287
while
(byte_count--)
00288     {
00289       *buffer = DBUS_UINT32_SWAP_LE_BE (*buffer);
00290       ++buffer;
00291     }
00292 }
00293
#endif
00294
00295
static
void
00296 sha_init (
structDBusSHAContext.html
DBusSHAContext
*context)
00297 {
00298
/* Set the h-vars to their initial values */
00299   context->
structDBusSHAContext.html#o0
digest
[0] = h0init;
00300   context->
structDBusSHAContext.html#o0
digest
[1] = h1init;
00301   context->
structDBusSHAContext.html#o0
digest
[2] = h2init;
00302   context->
structDBusSHAContext.html#o0
digest
[3] = h3init;
00303   context->
structDBusSHAContext.html#o0
digest
[4] = h4init;
00304
00305
/* Initialise bit count */
00306   context->
structDBusSHAContext.html#o1
count_lo
= context->
structDBusSHAContext.html#o2
count_hi
= 0;
00307 }
00308
00309
static
void
00310 sha_append (
structDBusSHAContext.html
DBusSHAContext
*context,
00311
const
unsigned
char
*buffer,
00312
unsigned
int
count)
00313 {
00314
group__DBusTypes.html#ga3
dbus_uint32_t
tmp;
00315
unsigned
int
dataCount;
00316
00317
/* Update bitcount */
00318   tmp = context->
structDBusSHAContext.html#o1
count_lo
;
00319
if
(( context->
structDBusSHAContext.html#o1
count_lo
= tmp + ( (
group__DBusTypes.html#ga3
dbus_uint32_t
) count << 3) ) < tmp)
00320     context->
structDBusSHAContext.html#o2
count_hi
++;
/* Carry from low to high */
00321   context->
structDBusSHAContext.html#o2
count_hi
+= count >> 29;
00322
00323
/* Get count of bytes already in data */
00324   dataCount = (int) (tmp >> 3) & 0x3F;
00325
00326
/* Handle any leading odd-sized chunks */
00327
if
(dataCount)
00328     {
00329
unsigned
char
*p = (
unsigned
char
*) context->
structDBusSHAContext.html#o3
data
+ dataCount;
00330
00331       dataCount = SHA_DATASIZE - dataCount;
00332
if
(count < dataCount)
00333         {
00334           memmove (p, buffer, count);
00335
return
;
00336         }
00337       memmove (p, buffer, dataCount);
00338       swap_words (context->
structDBusSHAContext.html#o3
data
, SHA_DATASIZE);
00339       SHATransform (context->
structDBusSHAContext.html#o0
digest
, context->
structDBusSHAContext.html#o3
data
);
00340       buffer += dataCount;
00341       count -= dataCount;
00342     }
00343
00344
/* Process data in SHA_DATASIZE chunks */
00345
while
(count >= SHA_DATASIZE)
00346     {
00347       memmove (context->
structDBusSHAContext.html#o3
data
, buffer, SHA_DATASIZE);
00348       swap_words (context->
structDBusSHAContext.html#o3
data
, SHA_DATASIZE);
00349       SHATransform (context->
structDBusSHAContext.html#o0
digest
, context->
structDBusSHAContext.html#o3
data
);
00350       buffer += SHA_DATASIZE;
00351       count -= SHA_DATASIZE;
00352     }
00353
00354
/* Handle any remaining bytes of data. */
00355   memmove (context->
structDBusSHAContext.html#o3
data
, buffer, count);
00356 }
00357
00358
00359
/* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern
00360
1 0* (64-bit count of bits processed, MSB-first) */
00361
00362
static
void
00363 sha_finish (
structDBusSHAContext.html
DBusSHAContext
*context,
unsigned
char
digest[20])
00364 {
00365
int
count;
00366
unsigned
char
*data_p;
00367
00368
/* Compute number of bytes mod 64 */
00369   count = (int) context->
structDBusSHAContext.html#o1
count_lo
;
00370   count = (count >> 3) & 0x3F;
00371
00372
/* Set the first char of padding to 0x80.  This is safe since there is
00373
always at least one byte free */
00374   data_p = (
unsigned
char
*) context->
structDBusSHAContext.html#o3
data
+ count;
00375   *data_p++ = 0x80;
00376
00377
/* Bytes of padding needed to make 64 bytes */
00378   count = SHA_DATASIZE - 1 - count;
00379
00380
/* Pad out to 56 mod 64 */
00381
if
(count < 8)
00382     {
00383
/* Two lots of padding:  Pad the first block to 64 bytes */
00384       memset (data_p, 0, count);
00385       swap_words (context->
structDBusSHAContext.html#o3
data
, SHA_DATASIZE);
00386       SHATransform (context->
structDBusSHAContext.html#o0
digest
, context->
structDBusSHAContext.html#o3
data
);
00387
00388
/* Now fill the next block with 56 bytes */
00389       memset (context->
structDBusSHAContext.html#o3
data
, 0, SHA_DATASIZE - 8);
00390     }
00391
else
00392
/* Pad block to 56 bytes */
00393     memset (data_p, 0, count - 8);
00394
00395
/* Append length in bits and transform */
00396   context->
structDBusSHAContext.html#o3
data
[14] = context->
structDBusSHAContext.html#o2
count_hi
;
00397   context->
structDBusSHAContext.html#o3
data
[15] = context->
structDBusSHAContext.html#o1
count_lo
;
00398
00399   swap_words (context->
structDBusSHAContext.html#o3
data
, SHA_DATASIZE - 8);
00400   SHATransform (context->
structDBusSHAContext.html#o0
digest
, context->
structDBusSHAContext.html#o3
data
);
00401   swap_words (context->
structDBusSHAContext.html#o0
digest
, SHA_DIGESTSIZE);
00402   memmove (digest, context->
structDBusSHAContext.html#o0
digest
, SHA_DIGESTSIZE);
00403 }
00404
/* End of internals */
00406
00418
void
group__DBusSHA.html#ga0
00419
group__DBusSHA.html#ga0
_dbus_sha_init
(
structDBusSHAContext.html
DBusSHAContext
*context)
00420 {
00421   sha_init (context);
00422 }
00423
00430
void
group__DBusSHA.html#ga1
00431
group__DBusSHA.html#ga1
_dbus_sha_update
(
structDBusSHAContext.html
DBusSHAContext
*context,
00432
const
structDBusString.html
DBusString
*data)
00433 {
00434
unsigned
int
inputLen;
00435
const
unsigned
char
*input;
00436
00437   input = (
const
unsigned
char
*) _dbus_string_get_const_data (data);
00438   inputLen = _dbus_string_get_length (data);
00439
00440   sha_append (context, input, inputLen);
00441 }
00442
00454
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusSHA.html#ga2
00455
group__DBusSHA.html#ga2
_dbus_sha_final
(
structDBusSHAContext.html
DBusSHAContext
*context,
00456
structDBusString.html
DBusString
*results)
00457 {
00458
unsigned
char
digest[20];
00459
00460   sha_finish (context, digest);
00461
00462
if
(!
group__DBusString.html#ga34
_dbus_string_append_len
(results, digest, 20))
00463
return
group__DBusMacros.html#ga3
FALSE
;
00464
00465
/* some kind of security paranoia, though it seems pointless
00466
* to me given the nonzeroed stuff flying around
00467
*/
00468   memset ((
void
*)context,
'\0'
,
sizeof
(
structDBusSHAContext.html
DBusSHAContext
));
00469
00470
return
group__DBusMacros.html#ga2
TRUE
;
00471 }
00472
00481
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusSHA.html#ga3
00482
group__DBusSHA.html#ga3
_dbus_sha_compute
(
const
structDBusString.html
DBusString
*data,
00483
structDBusString.html
DBusString
*ascii_output)
00484 {
00485
structDBusSHAContext.html
DBusSHAContext
context;
00486
structDBusString.html
DBusString
digest;
00487
00488
group__DBusSHA.html#ga0
_dbus_sha_init
(&context);
00489
00490
group__DBusSHA.html#ga1
_dbus_sha_update
(&context, data);
00491
00492
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&digest))
00493
return
group__DBusMacros.html#ga3
FALSE
;
00494
00495
if
(!
group__DBusSHA.html#ga2
_dbus_sha_final
(&context, &digest))
00496
goto
error;
00497
00498
if
(!
group__DBusString.html#ga53
_dbus_string_hex_encode
(&digest, 0, ascii_output,
00499                                 _dbus_string_get_length (ascii_output)))
00500
goto
error;
00501
00502
group__DBusString.html#ga9
_dbus_string_free
(&digest);
00503
00504
return
group__DBusMacros.html#ga2
TRUE
;
00505
00506  error:
00507
group__DBusString.html#ga9
_dbus_string_free
(&digest);
00508
return
group__DBusMacros.html#ga3
FALSE
;
00509 }
00510
/* end of exported functions */
00512
00513
#ifdef DBUS_BUILD_TESTS
00514
#include "dbus-test.h"
00515
#include <stdio.h>
00516
00517
static
group__DBusTypes.html#ga2
dbus_bool_t
00518 check_sha_binary (
const
unsigned
char
*input,
00519
int
input_len,
00520
const
char
*expected)
00521 {
00522
structDBusString.html
DBusString
input_str;
00523
structDBusString.html
DBusString
expected_str;
00524
structDBusString.html
DBusString
results;
00525
00526
group__DBusString.html#ga8
_dbus_string_init_const_len
(&input_str, input, input_len);
00527
group__DBusString.html#ga7
_dbus_string_init_const
(&expected_str, expected);
00528
00529
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&results))
00530
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory for SHA-1 results"
);
00531
00532
if
(!
group__DBusSHA.html#ga3
_dbus_sha_compute
(&input_str, &results))
00533
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory for SHA-1 results"
);
00534
00535
if
(!
group__DBusString.html#ga49
_dbus_string_equal
(&expected_str, &results))
00536     {
00537
group__DBusInternalsUtils.html#ga7
_dbus_warn
(
"Expected hash %s got %s for SHA-1 sum\n"
,
00538                   expected,
00539                   _dbus_string_get_const_data (&results));
00540
group__DBusString.html#ga9
_dbus_string_free
(&results);
00541
return
group__DBusMacros.html#ga3
FALSE
;
00542     }
00543
00544
group__DBusString.html#ga9
_dbus_string_free
(&results);
00545
return
group__DBusMacros.html#ga2
TRUE
;
00546 }
00547
00548
static
group__DBusTypes.html#ga2
dbus_bool_t
00549 check_sha_str (
const
char
*input,
00550
const
char
*expected)
00551 {
00552
return
check_sha_binary (input, strlen (input), expected);
00553 }
00554
00555
static
group__DBusTypes.html#ga2
dbus_bool_t
00556 decode_compact_string (
const
structDBusString.html
DBusString
*line,
00557
structDBusString.html
DBusString
*decoded)
00558 {
00559
int
n_bits;
00560
group__DBusTypes.html#ga2
dbus_bool_t
current_b;
00561
int
offset;
00562
int
next;
00563
long
val;
00564
int
length_bytes;
00565
00566   offset = 0;
00567   next = 0;
00568
00569
if
(!
group__DBusString.html#ga62
_dbus_string_parse_int
(line, offset, &val, &next))
00570     {
00571       fprintf (stderr,
"could not parse length at start of compact string: %s\n"
,
00572                _dbus_string_get_const_data (line));
00573
return
group__DBusMacros.html#ga3
FALSE
;
00574     }
00575
00576
group__DBusString.html#ga47
_dbus_string_skip_blank
(line, next, &next);
00577
00578   offset = next;
00579
if
(!
group__DBusString.html#ga62
_dbus_string_parse_int
(line, offset, &val, &next))
00580     {
00581       fprintf (stderr,
"could not parse start bit 'b' in compact string: %s\n"
,
00582                _dbus_string_get_const_data (line));
00583
return
group__DBusMacros.html#ga3
FALSE
;
00584     }
00585
00586
if
(!(val == 0 || val == 1))
00587     {
00588       fprintf (stderr,
"the value 'b' must be 0 or 1, see sha-1/Readme.txt\n"
);
00589
return
group__DBusMacros.html#ga3
FALSE
;
00590     }
00591
00592
group__DBusString.html#ga47
_dbus_string_skip_blank
(line, next, &next);
00593
00594   current_b = val;
00595   n_bits = 0;
00596
00597
while
(next < _dbus_string_get_length (line))
00598     {
00599
int
total_bits;
00600
00601       offset = next;
00602
00603
if
(_dbus_string_get_byte (line, offset) ==
'^'
)
00604
break
;
00605
00606
if
(!
group__DBusString.html#ga62
_dbus_string_parse_int
(line, offset, &val, &next))
00607         {
00608           fprintf (stderr,
"could not parse bit count in compact string\n"
);
00609
return
group__DBusMacros.html#ga3
FALSE
;
00610         }
00611
00612
/* We now append "val" copies of "current_b" bits to the string */
00613       total_bits = n_bits + val;
00614
while
(n_bits < total_bits)
00615         {
00616
int
byte_containing_next_bit = n_bits / 8;
00617
int
bit_containing_next_bit = 7 - (n_bits % 8);
00618
unsigned
char
old_byte;
00619
00620
if
(byte_containing_next_bit >= _dbus_string_get_length (decoded))
00621             {
00622
if
(!
group__DBusString.html#ga21
_dbus_string_set_length
(decoded, byte_containing_next_bit + 1))
00623
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory to extend to next byte"
);
00624             }
00625
00626           old_byte = _dbus_string_get_byte (decoded, byte_containing_next_bit);
00627           old_byte |= current_b << bit_containing_next_bit;
00628
00629
#if 0
00630
printf (
"Appending bit %d to byte %d at bit %d resulting in byte 0x%x\n"
,
00631                   current_b, byte_containing_next_bit,
00632                   bit_containing_next_bit, old_byte);
00633
#endif
00634
00635           _dbus_string_set_byte (decoded, byte_containing_next_bit, old_byte);
00636
00637           ++n_bits;
00638         }
00639
00640
group__DBusString.html#ga47
_dbus_string_skip_blank
(line, next, &next);
00641
00642       current_b = !current_b;
00643     }
00644
00645   length_bytes = (n_bits / 8 + ((n_bits % 8) ? 1 : 0));
00646
00647
if
(_dbus_string_get_length (decoded) != length_bytes)
00648     {
00649       fprintf (stderr,
"Expected length %d bytes %d bits for compact string, got %d bytes\n"
,
00650                length_bytes, n_bits, _dbus_string_get_length (decoded));
00651
return
group__DBusMacros.html#ga3
FALSE
;
00652     }
00653
else
00654
return
group__DBusMacros.html#ga2
TRUE
;
00655 }
00656
00657
static
group__DBusTypes.html#ga2
dbus_bool_t
00658 get_next_expected_result (
structDBusString.html
DBusString
*results,
00659
structDBusString.html
DBusString
*result)
00660 {
00661
structDBusString.html
DBusString
line;
00662
group__DBusTypes.html#ga2
dbus_bool_t
retval;
00663
00664   retval =
group__DBusMacros.html#ga3
FALSE
;
00665
00666
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&line))
00667
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
00668
00669  next_iteration:
00670
while
(
group__DBusString.html#ga48
_dbus_string_pop_line
(results, &line))
00671     {
00672       _dbus_string_delete_leading_blanks (&line);
00673
00674
if
(_dbus_string_get_length (&line) == 0)
00675
goto
next_iteration;
00676
else
if
(_dbus_string_starts_with_c_str (&line,
"#"
))
00677
goto
next_iteration;
00678
else
if
(_dbus_string_starts_with_c_str (&line,
"H>"
))
00679         {
00680
/* don't print */
00681         }
00682
else
if
(_dbus_string_starts_with_c_str (&line,
"D>"
) ||
00683                _dbus_string_starts_with_c_str (&line,
"<D"
))
00684
goto
next_iteration;
00685
else
00686         {
00687
int
i;
00688
00689
if
(!
group__DBusString.html#ga39
_dbus_string_move
(&line, 0, result, 0))
00690
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
00691
00692           i = 0;
00693
while
(i < _dbus_string_get_length (result))
00694             {
00695
switch
(_dbus_string_get_byte (result, i))
00696                 {
00697
case
'A'
:
00698                   _dbus_string_set_byte (result, i,
'a'
);
00699
break
;
00700
case
'B'
:
00701                   _dbus_string_set_byte (result, i,
'b'
);
00702
break
;
00703
case
'C'
:
00704                   _dbus_string_set_byte (result, i,
'c'
);
00705
break
;
00706
case
'D'
:
00707                   _dbus_string_set_byte (result, i,
'd'
);
00708
break
;
00709
case
'E'
:
00710                   _dbus_string_set_byte (result, i,
'e'
);
00711
break
;
00712
case
'F'
:
00713                   _dbus_string_set_byte (result, i,
'f'
);
00714
break
;
00715
case
'^'
:
00716
case
' '
:
00717
group__DBusString.html#ga37
_dbus_string_delete
(result, i, 1);
00718                   --i;
/* to offset ++i below */
00719
break
;
00720                 }
00721
00722               ++i;
00723             }
00724
00725
break
;
00726         }
00727     }
00728
00729   retval =
group__DBusMacros.html#ga2
TRUE
;
00730
00731
/* out: */
00732
group__DBusString.html#ga9
_dbus_string_free
(&line);
00733
return
retval;
00734 }
00735
00736
static
group__DBusTypes.html#ga2
dbus_bool_t
00737 process_test_data (
const
char
*test_data_dir)
00738 {
00739
structDBusString.html
DBusString
tests_file;
00740
structDBusString.html
DBusString
results_file;
00741
structDBusString.html
DBusString
tests;
00742
structDBusString.html
DBusString
results;
00743
structDBusString.html
DBusString
line;
00744
structDBusString.html
DBusString
tmp;
00745
int
line_no;
00746
group__DBusTypes.html#ga2
dbus_bool_t
retval;
00747
int
success_count;
00748
structDBusError.html
DBusError
error;
00749
00750   retval =
group__DBusMacros.html#ga3
FALSE
;
00751
00752
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&tests_file))
00753
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
00754
00755
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&results_file))
00756
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
00757
00758
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&tests))
00759
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
00760
00761
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&results))
00762
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
00763
00764
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&line))
00765
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
00766
00767
if
(!
group__DBusString.html#ga27
_dbus_string_append
(&tests_file, test_data_dir))
00768
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
00769
00770
if
(!
group__DBusString.html#ga27
_dbus_string_append
(&results_file, test_data_dir))
00771
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
00772
00773
group__DBusString.html#ga7
_dbus_string_init_const
(&tmp,
"sha-1/byte-messages.sha1"
);
00774
if
(!
group__DBusInternalsUtils.html#ga90
_dbus_concat_dir_and_file
(&tests_file, &tmp))
00775
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
00776
00777
group__DBusString.html#ga7
_dbus_string_init_const
(&tmp,
"sha-1/byte-hashes.sha1"
);
00778
if
(!
group__DBusInternalsUtils.html#ga90
_dbus_concat_dir_and_file
(&results_file, &tmp))
00779
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
00780
00781
group__DBusErrors.html#ga0
dbus_error_init
(&error);
00782
if
(!
group__DBusInternalsUtils.html#ga85
_dbus_file_get_contents
(&tests, &tests_file, &error))
00783     {
00784       fprintf (stderr,
"could not load test data file %s: %s\n"
,
00785                _dbus_string_get_const_data (&tests_file),
00786                error.
structDBusError.html#o1
message
);
00787
group__DBusErrors.html#ga1
dbus_error_free
(&error);
00788
goto
out;
00789     }
00790
00791
if
(!
group__DBusInternalsUtils.html#ga85
_dbus_file_get_contents
(&results, &results_file, &error))
00792     {
00793       fprintf (stderr,
"could not load results data file %s: %s\n"
,
00794                _dbus_string_get_const_data (&results_file), error.
structDBusError.html#o1
message
);
00795
group__DBusErrors.html#ga1
dbus_error_free
(&error);
00796
goto
out;
00797     }
00798
00799   success_count = 0;
00800   line_no = 0;
00801  next_iteration:
00802
while
(
group__DBusString.html#ga48
_dbus_string_pop_line
(&tests, &line))
00803     {
00804       line_no += 1;
00805
00806       _dbus_string_delete_leading_blanks (&line);
00807
00808
if
(_dbus_string_get_length (&line) == 0)
00809
goto
next_iteration;
00810
else
if
(_dbus_string_starts_with_c_str (&line,
"#"
))
00811
goto
next_iteration;
00812
else
if
(_dbus_string_starts_with_c_str (&line,
"H>"
))
00813         {
00814           printf (
"SHA-1: %s\n"
, _dbus_string_get_const_data (&line));
00815
00816
if
(
group__DBusString.html#ga44
_dbus_string_find
(&line, 0,
"Type 3"
,
group__DBusMacros.html#ga4
NULL
))
00817             {
00818
/* See sha-1/Readme.txt - the "Type 3" tests are
00819
* random seeds, rather than data to be hashed.
00820
* we'd have to do a little bit more implementation
00821
* to use those tests.
00822
*/
00823
00824               printf (
" (ending tests due to Type 3 tests seen - this is normal)\n"
);
00825
break
;
00826             }
00827         }
00828
else
if
(_dbus_string_starts_with_c_str (&line,
"D>"
) ||
00829                _dbus_string_starts_with_c_str (&line,
"<D"
))
00830
goto
next_iteration;
00831
else
00832         {
00833
structDBusString.html
DBusString
test;
00834
structDBusString.html
DBusString
result;
00835
structDBusString.html
DBusString
next_line;
00836
structDBusString.html
DBusString
expected;
00837
group__DBusTypes.html#ga2
dbus_bool_t
success;
00838
00839           success =
group__DBusMacros.html#ga3
FALSE
;
00840
00841
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&next_line))
00842
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
00843
00844
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&expected))
00845
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
00846
00847
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&test))
00848
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
00849
00850
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&result))
00851
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
00852
00853
/* the "compact strings" are "^"-terminated not
00854
* newline-terminated so readahead to find the
00855
* "^"
00856
*/
00857
while
(!
group__DBusString.html#ga44
_dbus_string_find
(&line, 0,
"^"
,
group__DBusMacros.html#ga4
NULL
) &&
00858
group__DBusString.html#ga48
_dbus_string_pop_line
(&tests, &next_line))
00859             {
00860
if
(!
group__DBusString.html#ga35
_dbus_string_append_byte
(&line,
' '
) ||
00861                   !
group__DBusString.html#ga39
_dbus_string_move
(&next_line, 0, &line,
00862                                       _dbus_string_get_length (&line)))
00863
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
00864             }
00865
00866
if
(!decode_compact_string (&line, &test))
00867             {
00868               fprintf (stderr,
"Failed to decode line %d as a compact string\n"
,
00869                        line_no);
00870
goto
failure;
00871             }
00872
00873
if
(!
group__DBusSHA.html#ga3
_dbus_sha_compute
(&test, &result))
00874
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory for SHA-1 result"
);
00875
00876
if
(!get_next_expected_result (&results, &expected))
00877             {
00878               fprintf (stderr,
"Failed to read an expected result\n"
);
00879
goto
failure;
00880             }
00881
00882
if
(!
group__DBusString.html#ga49
_dbus_string_equal
(&result, &expected))
00883             {
00884               fprintf (stderr,
" for line %d got hash %s expected %s\n"
,
00885                        line_no,
00886                        _dbus_string_get_const_data (&result),
00887                        _dbus_string_get_const_data (&expected));
00888
goto
failure;
00889             }
00890
else
00891             {
00892               success_count += 1;
00893             }
00894
00895           success =
group__DBusMacros.html#ga2
TRUE
;
00896
00897         failure:
00898
group__DBusString.html#ga9
_dbus_string_free
(&test);
00899
group__DBusString.html#ga9
_dbus_string_free
(&result);
00900
group__DBusString.html#ga9
_dbus_string_free
(&next_line);
00901
group__DBusString.html#ga9
_dbus_string_free
(&expected);
00902
00903
if
(!success)
00904
goto
out;
00905         }
00906     }
00907
00908   retval =
group__DBusMacros.html#ga2
TRUE
;
00909
00910   printf (
"Passed the %d SHA-1 tests in the test file\n"
,
00911           success_count);
00912
00913  out:
00914
group__DBusString.html#ga9
_dbus_string_free
(&tests_file);
00915
group__DBusString.html#ga9
_dbus_string_free
(&results_file);
00916
group__DBusString.html#ga9
_dbus_string_free
(&tests);
00917
group__DBusString.html#ga9
_dbus_string_free
(&results);
00918
group__DBusString.html#ga9
_dbus_string_free
(&line);
00919
00920
return
retval;
00921 }
00922
00929
group__DBusTypes.html#ga2
dbus_bool_t
00930 _dbus_sha_test (
const
char
*test_data_dir)
00931 {
00932
unsigned
char
all_bytes[256];
00933
int
i;
00934
00935
if
(test_data_dir !=
group__DBusMacros.html#ga4
NULL
)
00936     {
00937
if
(!process_test_data (test_data_dir))
00938
return
group__DBusMacros.html#ga3
FALSE
;
00939     }
00940
else
00941     printf (
"No test data dir\n"
);
00942
00943   i = 0;
00944
while
(i < 256)
00945     {
00946       all_bytes[i] = i;
00947       ++i;
00948     }
00949
00950
if
(!check_sha_binary (all_bytes, 256,
00951
"4916d6bdb7f78e6803698cab32d1586ea457dfc8"
))
00952
return
group__DBusMacros.html#ga3
FALSE
;
00953
00954
#define CHECK(input,expected) if (!check_sha_str (input, expected)) return FALSE
00955
00956   CHECK (
""
,
"da39a3ee5e6b4b0d3255bfef95601890afd80709"
);
00957   CHECK (
"a"
,
"86f7e437faa5a7fce15d1ddcb9eaeaea377667b8"
);
00958   CHECK (
"abc"
,
"a9993e364706816aba3e25717850c26c9cd0d89d"
);
00959   CHECK (
"message digest"
,
"c12252ceda8be8994d5fa0290a47231c1d16aae3"
);
00960   CHECK (
"abcdefghijklmnopqrstuvwxyz"
,
"32d10c7b8cf96570ca04ce37f2a19d84240d3a89"
);
00961   CHECK (
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
,
00962
"761c457bf73b14d27e9e9265c46f4b4dda11f940"
);
00963   CHECK (
"12345678901234567890123456789012345678901234567890123456789012345678901234567890"
,
00964
"50abf5706a150990a08b2c5ea40fa0e585554732"
);
00965
00966
return
group__DBusMacros.html#ga2
TRUE
;
00967 }
00968
00969
#endif
/* DBUS_BUILD_TESTS */
Generated on Tue Sep 13 01:28:07 2005 for D-BUS by
http://www.doxygen.org/index.html
doxygen
1.4.4
