Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

rpmio/digest.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 #include "rpmio_internal.h"
00007 #include "debug.h"
00008 
00009 /*@-redef@*/
00010 typedef unsigned int uint32;
00011 typedef unsigned char byte;
00012 /*@=redef@*/
00013 
00014 /*@access DIGEST_CTX@*/
00015 
00019 struct DIGEST_CTX_s {
00020     rpmDigestFlags flags;       
00021     uint32 digestlen;           
00022     uint32 datalen;             
00023     void (*transform) (DIGEST_CTX); 
00024     int doByteReverse;          
00025     uint32 bits[2];             
00026     uint32 digest[8];           
00027     byte in[64];                
00028 };
00029 
00030 /*
00031  * This code implements SHA-1 as defined in FIPS publication 180-1.
00032  * Based on SHA code originally posted to sci.crypt by Peter Gutmann
00033  * in message <30ajo5$oe8@ccu2.auckland.ac.nz>.
00034  * Modified to test for endianness on creation of SHA objects by AMK.
00035  * Also, the original specification of SHA was found to have a weakness
00036  * by NSA/NIST.  This code implements the fixed version of SHA.
00037  *
00038  * Here's the first paragraph of Peter Gutmann's original posting:
00039  * - The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
00040  * SHA, thanks to Jim Gillogly and an anonymous contributor for the information
00041  * on what's changed in the new version.  The fix is a simple change which
00042  * involves adding a single rotate in the initial expansion function. It is
00043  * unknown whether this is an optimal solution to the problem which was
00044  * discovered in the SHA or whether it's simply a bandaid which fixes the
00045  * problem with a minimum of effort (for example the reengineering of a great
00046  * many Capstone chips).
00047  *
00048  * Copyright (C) 1995, A.M. Kuchling
00049  *
00050  * Distribute and use freely; there are no restrictions on further 
00051  * dissemination and usage except those imposed by the laws of your 
00052  * country of residence.
00053  *
00054  * Adapted to pike and some cleanup by Niels Möller.
00055  * Adapted for rpm use from mhash-0.8.3.
00056  */
00057 
00063 /*#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) )          // Rounds  0-19 */
00064 #define f1(x,y,z)   ( z ^ ( x & ( y ^ z ) ) )           /* Rounds  0-19 */
00065 #define f2(x,y,z)   ( x ^ y ^ z )                       /* Rounds 20-39 */
00066 /*#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) // Rounds 40-59 */
00067 #define f3(x,y,z)   ( ( x & y ) | ( z & ( x | y ) ) )   /* Rounds 40-59 */
00068 #define f4(x,y,z)   ( x ^ y ^ z )                       /* Rounds 60-79 */
00069 
00073 #define K1  0x5A827999L                                 /* Rounds  0-19 */
00074 #define K2  0x6ED9EBA1L                                 /* Rounds 20-39 */
00075 #define K3  0x8F1BBCDCL                                 /* Rounds 40-59 */
00076 #define K4  0xCA62C1D6L                                 /* Rounds 60-79 */
00077 
00081 #define ROTL(n,X)  ( ( (X) << (n) ) | ( (X) >> ( 32 - (n) ) ) )
00082 
00100 #define expand(W,i) ( W[ i & 15 ] = \
00101                       ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
00102                                  W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
00103 
00122 #define subRound(a, b, c, d, e, f, k, data) \
00123     ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
00124 
00140 static void
00141 SHA1Transform(DIGEST_CTX ctx)
00142 {
00143     uint32 * in = (uint32 *) ctx->in;
00144     uint32 A, B, C, D, E;     /* Local vars */
00145 #ifdef  SHA_DEBUG
00146 int i;
00147 #define DPRINTF(_a)     fprintf _a
00148 #else
00149 #define DPRINTF(_a)
00150 #endif
00151 
00152     /* Set up first buffer and local data buffer */
00153     A = ctx->digest[0];
00154     B = ctx->digest[1];
00155     C = ctx->digest[2];
00156     D = ctx->digest[3];
00157     E = ctx->digest[4];
00158 
00159 #ifdef  SHA_DEBUG
00160 for (i = 0; i < 16; i++)
00161 DPRINTF((stderr, "W[%2d]: %08X\n", i, in[i]));
00162 #endif
00163     /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
00164 #ifdef  SHA_DEBUG
00165 i = 0;
00166 #endif
00167     subRound( A, B, C, D, E, f1, K1, in[ 0] );
00168 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, E,A,B,C,D ));
00169     subRound( E, A, B, C, D, f1, K1, in[ 1] );
00170 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, D,E,A,B,C ));
00171     subRound( D, E, A, B, C, f1, K1, in[ 2] );
00172 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, C,D,E,A,B ));
00173     subRound( C, D, E, A, B, f1, K1, in[ 3] );
00174 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, B,C,D,E,A ));
00175     subRound( B, C, D, E, A, f1, K1, in[ 4] );
00176 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, A,B,C,D,E ));
00177     subRound( A, B, C, D, E, f1, K1, in[ 5] );
00178 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, E,A,B,C,D ));
00179     subRound( E, A, B, C, D, f1, K1, in[ 6] );
00180 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, D,E,A,B,C ));
00181     subRound( D, E, A, B, C, f1, K1, in[ 7] );
00182 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, C,D,E,A,B ));
00183     subRound( C, D, E, A, B, f1, K1, in[ 8] );
00184 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, B,C,D,E,A ));
00185     subRound( B, C, D, E, A, f1, K1, in[ 9] );
00186 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, A,B,C,D,E ));
00187     subRound( A, B, C, D, E, f1, K1, in[10] );
00188 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, E,A,B,C,D ));
00189     subRound( E, A, B, C, D, f1, K1, in[11] );
00190 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, D,E,A,B,C ));
00191     subRound( D, E, A, B, C, f1, K1, in[12] );
00192 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, C,D,E,A,B ));
00193     subRound( C, D, E, A, B, f1, K1, in[13] );
00194 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, B,C,D,E,A ));
00195     subRound( B, C, D, E, A, f1, K1, in[14] );
00196 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, A,B,C,D,E ));
00197     subRound( A, B, C, D, E, f1, K1, in[15] );
00198 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, E,A,B,C,D ));
00199     subRound( E, A, B, C, D, f1, K1, expand( in, 16 ) );
00200 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, D,E,A,B,C ));
00201     subRound( D, E, A, B, C, f1, K1, expand( in, 17 ) );
00202 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, C,D,E,A,B ));
00203     subRound( C, D, E, A, B, f1, K1, expand( in, 18 ) );
00204 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, B,C,D,E,A ));
00205     subRound( B, C, D, E, A, f1, K1, expand( in, 19 ) );
00206 
00207 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, A,B,C,D,E ));
00208     subRound( A, B, C, D, E, f2, K2, expand( in, 20 ) );
00209 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, E,A,B,C,D ));
00210     subRound( E, A, B, C, D, f2, K2, expand( in, 21 ) );
00211 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, D,E,A,B,C ));
00212     subRound( D, E, A, B, C, f2, K2, expand( in, 22 ) );
00213 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, C,D,E,A,B ));
00214     subRound( C, D, E, A, B, f2, K2, expand( in, 23 ) );
00215 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, B,C,D,E,A ));
00216     subRound( B, C, D, E, A, f2, K2, expand( in, 24 ) );
00217 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, A,B,C,D,E ));
00218     subRound( A, B, C, D, E, f2, K2, expand( in, 25 ) );
00219 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, E,A,B,C,D ));
00220     subRound( E, A, B, C, D, f2, K2, expand( in, 26 ) );
00221 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, D,E,A,B,C ));
00222     subRound( D, E, A, B, C, f2, K2, expand( in, 27 ) );
00223 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, C,D,E,A,B ));
00224     subRound( C, D, E, A, B, f2, K2, expand( in, 28 ) );
00225 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, B,C,D,E,A ));
00226     subRound( B, C, D, E, A, f2, K2, expand( in, 29 ) );
00227 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, A,B,C,D,E ));
00228     subRound( A, B, C, D, E, f2, K2, expand( in, 30 ) );
00229 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, E,A,B,C,D ));
00230     subRound( E, A, B, C, D, f2, K2, expand( in, 31 ) );
00231 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, D,E,A,B,C ));
00232     subRound( D, E, A, B, C, f2, K2, expand( in, 32 ) );
00233 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, C,D,E,A,B ));
00234     subRound( C, D, E, A, B, f2, K2, expand( in, 33 ) );
00235 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, B,C,D,E,A ));
00236     subRound( B, C, D, E, A, f2, K2, expand( in, 34 ) );
00237 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, A,B,C,D,E ));
00238     subRound( A, B, C, D, E, f2, K2, expand( in, 35 ) );
00239 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, E,A,B,C,D ));
00240     subRound( E, A, B, C, D, f2, K2, expand( in, 36 ) );
00241 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, D,E,A,B,C ));
00242     subRound( D, E, A, B, C, f2, K2, expand( in, 37 ) );
00243 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, C,D,E,A,B ));
00244     subRound( C, D, E, A, B, f2, K2, expand( in, 38 ) );
00245 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, B,C,D,E,A ));
00246     subRound( B, C, D, E, A, f2, K2, expand( in, 39 ) );
00247 
00248 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, A,B,C,D,E ));
00249     subRound( A, B, C, D, E, f3, K3, expand( in, 40 ) );
00250 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, E,A,B,C,D ));
00251     subRound( E, A, B, C, D, f3, K3, expand( in, 41 ) );
00252 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, D,E,A,B,C ));
00253     subRound( D, E, A, B, C, f3, K3, expand( in, 42 ) );
00254 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, C,D,E,A,B ));
00255     subRound( C, D, E, A, B, f3, K3, expand( in, 43 ) );
00256 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, B,C,D,E,A ));
00257     subRound( B, C, D, E, A, f3, K3, expand( in, 44 ) );
00258 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, A,B,C,D,E ));
00259     subRound( A, B, C, D, E, f3, K3, expand( in, 45 ) );
00260 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, E,A,B,C,D ));
00261     subRound( E, A, B, C, D, f3, K3, expand( in, 46 ) );
00262 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, D,E,A,B,C ));
00263     subRound( D, E, A, B, C, f3, K3, expand( in, 47 ) );
00264 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, C,D,E,A,B ));
00265     subRound( C, D, E, A, B, f3, K3, expand( in, 48 ) );
00266 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, B,C,D,E,A ));
00267     subRound( B, C, D, E, A, f3, K3, expand( in, 49 ) );
00268 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, A,B,C,D,E ));
00269     subRound( A, B, C, D, E, f3, K3, expand( in, 50 ) );
00270 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, E,A,B,C,D ));
00271     subRound( E, A, B, C, D, f3, K3, expand( in, 51 ) );
00272 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, D,E,A,B,C ));
00273     subRound( D, E, A, B, C, f3, K3, expand( in, 52 ) );
00274 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, C,D,E,A,B ));
00275     subRound( C, D, E, A, B, f3, K3, expand( in, 53 ) );
00276 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, B,C,D,E,A ));
00277     subRound( B, C, D, E, A, f3, K3, expand( in, 54 ) );
00278 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, A,B,C,D,E ));
00279     subRound( A, B, C, D, E, f3, K3, expand( in, 55 ) );
00280 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, E,A,B,C,D ));
00281     subRound( E, A, B, C, D, f3, K3, expand( in, 56 ) );
00282 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, D,E,A,B,C ));
00283     subRound( D, E, A, B, C, f3, K3, expand( in, 57 ) );
00284 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, C,D,E,A,B ));
00285     subRound( C, D, E, A, B, f3, K3, expand( in, 58 ) );
00286 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, B,C,D,E,A ));
00287     subRound( B, C, D, E, A, f3, K3, expand( in, 59 ) );
00288 
00289 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, A,B,C,D,E ));
00290     subRound( A, B, C, D, E, f4, K4, expand( in, 60 ) );
00291 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, E,A,B,C,D ));
00292     subRound( E, A, B, C, D, f4, K4, expand( in, 61 ) );
00293 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, D,E,A,B,C ));
00294     subRound( D, E, A, B, C, f4, K4, expand( in, 62 ) );
00295 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, C,D,E,A,B ));
00296     subRound( C, D, E, A, B, f4, K4, expand( in, 63 ) );
00297 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, B,C,D,E,A ));
00298     subRound( B, C, D, E, A, f4, K4, expand( in, 64 ) );
00299 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, A,B,C,D,E ));
00300     subRound( A, B, C, D, E, f4, K4, expand( in, 65 ) );
00301 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, E,A,B,C,D ));
00302     subRound( E, A, B, C, D, f4, K4, expand( in, 66 ) );
00303 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, D,E,A,B,C ));
00304     subRound( D, E, A, B, C, f4, K4, expand( in, 67 ) );
00305 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, C,D,E,A,B ));
00306     subRound( C, D, E, A, B, f4, K4, expand( in, 68 ) );
00307 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, B,C,D,E,A ));
00308     subRound( B, C, D, E, A, f4, K4, expand( in, 69 ) );
00309 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, A,B,C,D,E ));
00310     subRound( A, B, C, D, E, f4, K4, expand( in, 70 ) );
00311 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, E,A,B,C,D ));
00312     subRound( E, A, B, C, D, f4, K4, expand( in, 71 ) );
00313 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, D,E,A,B,C ));
00314     subRound( D, E, A, B, C, f4, K4, expand( in, 72 ) );
00315 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, C,D,E,A,B ));
00316     subRound( C, D, E, A, B, f4, K4, expand( in, 73 ) );
00317 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, B,C,D,E,A ));
00318     subRound( B, C, D, E, A, f4, K4, expand( in, 74 ) );
00319 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, A,B,C,D,E ));
00320     subRound( A, B, C, D, E, f4, K4, expand( in, 75 ) );
00321 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, E,A,B,C,D ));
00322     subRound( E, A, B, C, D, f4, K4, expand( in, 76 ) );
00323 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, D,E,A,B,C ));
00324     subRound( D, E, A, B, C, f4, K4, expand( in, 77 ) );
00325 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, C,D,E,A,B ));
00326     subRound( C, D, E, A, B, f4, K4, expand( in, 78 ) );
00327 DPRINTF((stderr, "%5d: %08X %08X %08X %08X %08X\n", i++, B,C,D,E,A ));
00328     subRound( B, C, D, E, A, f4, K4, expand( in, 79 ) );
00329 
00330     /* Build message digest */
00331     ctx->digest[0] += A;
00332     ctx->digest[1] += B;
00333     ctx->digest[2] += C;
00334     ctx->digest[3] += D;
00335     ctx->digest[4] += E;
00336 }
00337 
00338 /*
00339  * This code implements the MD5 message-digest algorithm.
00340  * The algorithm is due to Ron Rivest.  This code was
00341  * written by Colin Plumb in 1993, no copyright is claimed.
00342  * This code is in the public domain; do with it what you wish.
00343  *
00344  * Equivalent code is available from RSA Data Security, Inc.
00345  * This code has been tested against that, and is equivalent,
00346  * except that you don't need to include two pages of legalese
00347  * with every copy.
00348  *
00349  * To compute the message digest of a chunk of bytes, declare an
00350  * MD5Context structure, pass it to MD5Init, call MD5Update as
00351  * needed on buffers full of bytes, and then call MD5Final, which
00352  * will fill a supplied 16-byte array with the digest.
00353  */
00354 
00356 /* #define F1(x, y, z) (x & y | ~x & z) */
00357 #define F1(x, y, z) (z ^ (x & (y ^ z)))
00358 #define F2(x, y, z) F1(z, x, y)
00359 #define F3(x, y, z) (x ^ y ^ z)
00360 #define F4(x, y, z) (y ^ (x | ~z))
00361 
00363 #define MD5STEP(f, w, x, y, z, data, s) \
00364         ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
00365 
00371 static void
00372 MD5Transform(DIGEST_CTX ctx)
00373 {
00374     register uint32 * in = (uint32 *)ctx->in;
00375     register uint32 a = ctx->digest[0];
00376     register uint32 b = ctx->digest[1];
00377     register uint32 c = ctx->digest[2];
00378     register uint32 d = ctx->digest[3];
00379 
00380     MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
00381     MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
00382     MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
00383     MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
00384     MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
00385     MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
00386     MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
00387     MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
00388     MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
00389     MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
00390     MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
00391     MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
00392     MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
00393     MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
00394     MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
00395     MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
00396 
00397     MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
00398     MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
00399     MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
00400     MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
00401     MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
00402     MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
00403     MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
00404     MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
00405     MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
00406     MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
00407     MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
00408     MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
00409     MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
00410     MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
00411     MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
00412     MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
00413 
00414     MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
00415     MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
00416     MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
00417     MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
00418     MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
00419     MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
00420     MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
00421     MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
00422     MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
00423     MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
00424     MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
00425     MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
00426     MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
00427     MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
00428     MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
00429     MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
00430 
00431     MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
00432     MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
00433     MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
00434     MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
00435     MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
00436     MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
00437     MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
00438     MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
00439     MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
00440     MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
00441     MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
00442     MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
00443     MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
00444     MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
00445     MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
00446     MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
00447 
00448     ctx->digest[0] += a;
00449     ctx->digest[1] += b;
00450     ctx->digest[2] += c;
00451     ctx->digest[3] += d;
00452 }
00453 
00454 static int _ie = 0x44332211;
00455 /*@-redef@*/
00456 static union _mendian {
00457 /*@unused@*/ int i;
00458     char b[4];
00459 } *_endian = (union _mendian *)&_ie;
00460 /*@=redef@*/
00461 #define IS_BIG_ENDIAN()         (_endian->b[0] == '\x44')
00462 #define IS_LITTLE_ENDIAN()      (_endian->b[0] == '\x11')
00463 
00464 /*
00465  * Reverse bytes for each integer in buffer.
00466  * @param buf           data buffer (uint32 aligned address)
00467  * @param nbytes        no. bytes of data (multiple of sizeof(uint32))
00468  */
00469 /*@-shadow@*/
00470 static void
00471 byteReverse(byte *buf, unsigned nbytes)
00472         /*@modifies *buf @*/
00473 {
00474     unsigned nlongs = nbytes / sizeof(uint32);
00475     uint32 t;
00476     if (IS_BIG_ENDIAN()) {
00477         do {
00478             t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
00479                 ((unsigned) buf[1] << 8 | buf[0]);
00480             *(uint32 *) buf = t;
00481             buf += 4;
00482         } while (--nlongs);
00483     } else {
00484         do {
00485             t = (uint32) ((unsigned) buf[0] << 8 | buf[1]) << 16 |
00486                 ((unsigned) buf[2] << 8 | buf[3]);
00487             *(uint32 *) buf = t;
00488             buf += 4;
00489         } while (--nlongs);
00490     }
00491 }
00492 /*@=shadow@*/
00493 
00494 DIGEST_CTX
00495 rpmDigestInit(rpmDigestFlags flags)
00496 {
00497     DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx));
00498 
00499 #ifdef  SHA_DEBUG
00500 int i;
00501 DPRINTF((stderr, "*** Init(%x)\n", flags));
00502 #endif
00503     ctx->flags = flags;
00504 
00505     if (flags & RPMDIGEST_MD5) {
00506         ctx->digestlen = 16;
00507         ctx->datalen = 64;
00508         ctx->transform = MD5Transform;
00509         ctx->digest[0] = 0x67452301;
00510         ctx->digest[1] = 0xefcdab89;
00511         ctx->digest[2] = 0x98badcfe;
00512         ctx->digest[3] = 0x10325476;
00513         /* md5 sums are little endian (no swap) so big endian needs the swap. */
00514         ctx->doByteReverse = (IS_BIG_ENDIAN()) ? 1 : 0;
00515     }
00516 
00517     if (flags & RPMDIGEST_SHA1) {
00518         ctx->digestlen = 20;
00519         ctx->datalen = 64;
00520         ctx->transform = SHA1Transform;
00521         ctx->digest[ 0 ] = 0x67452301;
00522         ctx->digest[ 1 ] = 0xefcdab89;
00523         ctx->digest[ 2 ] = 0x98badcfe;
00524         ctx->digest[ 3 ] = 0x10325476;
00525         ctx->digest[ 4 ] = 0xc3d2e1f0;
00526         /* md5 sums are little endian (no swap) so big endian needs the swap. */
00527         ctx->doByteReverse = (IS_BIG_ENDIAN()) ? 0 : 1;
00528 #ifdef  SHA_DEBUG
00529 for (i =0; i < 5; i++)
00530 DPRINTF((stderr, "H[%2d]: %X\n", i, ctx->digest[i]));
00531 #endif
00532     }
00533 
00534     if (flags & RPMDIGEST_REVERSE)
00535         ctx->doByteReverse ^= 1;
00536 
00537     ctx->bits[0] = 0;
00538     ctx->bits[1] = 0;
00539 
00540     return ctx;
00541 }
00542 
00543 void
00544 rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
00545 {
00546     const byte * buf = data;
00547     uint32 t;
00548 
00549     /* Update bitcount */
00550 
00551     t = ctx->bits[0];
00552     if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
00553         ctx->bits[1]++;         /* Carry from low to high */
00554     ctx->bits[1] += len >> 29;
00555 
00556     t = (t >> 3) % ctx->datalen;        /* Bytes already in ctx->in */
00557 
00558     /* Handle any leading odd-sized chunks */
00559     if (t) {
00560         byte *p = (byte *) ctx->in + t;
00561 
00562         t = ctx->datalen - t;   /* Bytes left in ctx->in */
00563         if (len < t) {
00564             memcpy(p, buf, len);
00565             return;
00566         }
00567         memcpy(p, buf, t);
00568         if (ctx->doByteReverse)
00569             byteReverse(ctx->in, ctx->datalen);
00570         /*@-moduncon@*/
00571         ctx->transform(ctx);
00572         /*@=moduncon@*/
00573         buf += t;
00574         len -= t;
00575     }
00576 
00577     /* Process data in ctx->datalen chunks */
00578     for (; len >= ctx->datalen; buf += ctx->datalen, len -= ctx->datalen) {
00579         memmove(ctx->in, buf, ctx->datalen);
00580         if (ctx->doByteReverse)
00581             byteReverse(ctx->in, ctx->datalen);
00582         /*@-moduncon@*/
00583         ctx->transform(ctx);
00584         /*@=moduncon@*/
00585     }
00586 
00587     /* Handle any remaining bytes of data. */
00588     memmove(ctx->in, buf, len);
00589 }
00590 
00591 void
00592 rpmDigestFinal(/*@only@*/ DIGEST_CTX ctx, /*@out@*/ void ** datap,
00593         /*@out@*/ size_t *lenp, int asAscii)
00594 {
00595     unsigned count = (ctx->bits[0] >> 3) % ctx->datalen;
00596     byte * p = ctx->in + count;
00597 
00598     /* Set the first char of padding to 0x80.  This is safe since there is
00599        always at least one byte free */
00600     *p++ = 0x80;
00601 
00602     /* No. bytes of padding needed to fill buffer. */
00603     count = ctx->datalen - 1 - count;
00604 
00605     /* Insure that next block has room for no. of plaintext bits. */
00606     if (count < sizeof(ctx->bits)) {
00607         memset(p, 0, count);
00608         if (ctx->doByteReverse)
00609             byteReverse(ctx->in, ctx->datalen);
00610         /*@-moduncon@*/
00611         ctx->transform(ctx);
00612         /*@=moduncon@*/
00613         p = ctx->in;
00614         count = ctx->datalen;
00615     }
00616 
00617     /* Pad next block with zeroes, add no. of plaintext bits. */
00618     memset(p, 0, count - sizeof(ctx->bits));
00619     if (ctx->doByteReverse)
00620         byteReverse(ctx->in, ctx->datalen - sizeof(ctx->bits));
00621 
00622     if (ctx->flags & (RPMDIGEST_MD5|RPMDIGEST_BCSWAP)) {
00623         ((uint32 *) ctx->in)[14] = ctx->bits[0];
00624         ((uint32 *) ctx->in)[15] = ctx->bits[1];
00625     } else {
00626         ((uint32 *) ctx->in)[14] = ctx->bits[1];
00627         ((uint32 *) ctx->in)[15] = ctx->bits[0];
00628     }
00629     /*@-moduncon@*/
00630     ctx->transform(ctx);
00631     /*@=moduncon@*/
00632 
00633     if (ctx->doByteReverse)
00634         byteReverse((byte *) ctx->digest, ctx->digestlen);
00635 
00636     /* Return final digest. */
00637     if (!asAscii) {
00638         if (lenp) *lenp = ctx->digestlen;
00639         if (datap) {
00640             *datap = xmalloc(ctx->digestlen);
00641             memcpy(*datap, ctx->digest, ctx->digestlen);
00642         }
00643     } else {
00644         if (lenp) *lenp = (2*ctx->digestlen) + 1;
00645         if (datap) {
00646             const byte * s = (const byte *) ctx->digest;
00647             static const char hex[] = "0123456789abcdef";
00648             char * t;
00649             int i;
00650 
00651             *datap = t = xmalloc((2*ctx->digestlen) + 1);
00652 
00653             for (i = 0 ; i < ctx->digestlen; i++) {
00654                 *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
00655                 *t++ = hex[ (unsigned)((*s++   ) & 0x0f) ];
00656             }
00657             *t = '\0';
00658         }
00659     }
00660     memset(ctx, 0, sizeof(*ctx));       /* In case it's sensitive */
00661     free(ctx);
00662 }

Generated at Mon Sep 24 10:37:30 2001 for rpm by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001