00001
00005 #include "system.h"
00006 #include "rpmio_internal.h"
00007 #include "debug.h"
00008
00009 typedef unsigned int uint32;
00010 typedef unsigned char byte;
00011
00015 struct DIGEST_CTX_s {
00016 rpmDigestFlags flags;
00017 uint32 digestlen;
00018 uint32 datalen;
00019 void (*transform) (DIGEST_CTX);
00020 int doByteReverse;
00021 uint32 bits[2];
00022 uint32 digest[8];
00023 byte in[64];
00024 };
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00059
00060 #define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) )
00061 #define f2(x,y,z) ( x ^ y ^ z )
00062
00063 #define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) )
00064 #define f4(x,y,z) ( x ^ y ^ z )
00065
00069 #define K1 0x5A827999L
00070 #define K2 0x6ED9EBA1L
00071 #define K3 0x8F1BBCDCL
00072 #define K4 0xCA62C1D6L
00073
00077 #define ROTL(n,X) ( ( (X) << (n) ) | ( (X) >> ( 32 - (n) ) ) )
00078
00096 #define expand(W,i) ( W[ i & 15 ] = \
00097 ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
00098 W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
00099
00118 #define subRound(a, b, c, d, e, f, k, data) \
00119 ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
00120
00136 static void
00137 SHA1Transform(DIGEST_CTX ctx)
00138 {
00139 uint32 * in = (uint32 *) ctx->in;
00140 uint32 A, B, C, D, E;
00141
00142
00143 A = ctx->digest[0];
00144 B = ctx->digest[1];
00145 C = ctx->digest[2];
00146 D = ctx->digest[3];
00147 E = ctx->digest[4];
00148
00149
00150 subRound( A, B, C, D, E, f1, K1, in[ 0] );
00151 subRound( E, A, B, C, D, f1, K1, in[ 1] );
00152 subRound( D, E, A, B, C, f1, K1, in[ 2] );
00153 subRound( C, D, E, A, B, f1, K1, in[ 3] );
00154 subRound( B, C, D, E, A, f1, K1, in[ 4] );
00155 subRound( A, B, C, D, E, f1, K1, in[ 5] );
00156 subRound( E, A, B, C, D, f1, K1, in[ 6] );
00157 subRound( D, E, A, B, C, f1, K1, in[ 7] );
00158 subRound( C, D, E, A, B, f1, K1, in[ 8] );
00159 subRound( B, C, D, E, A, f1, K1, in[ 9] );
00160 subRound( A, B, C, D, E, f1, K1, in[10] );
00161 subRound( E, A, B, C, D, f1, K1, in[11] );
00162 subRound( D, E, A, B, C, f1, K1, in[12] );
00163 subRound( C, D, E, A, B, f1, K1, in[13] );
00164 subRound( B, C, D, E, A, f1, K1, in[14] );
00165 subRound( A, B, C, D, E, f1, K1, in[15] );
00166 subRound( E, A, B, C, D, f1, K1, expand( in, 16 ) );
00167 subRound( D, E, A, B, C, f1, K1, expand( in, 17 ) );
00168 subRound( C, D, E, A, B, f1, K1, expand( in, 18 ) );
00169 subRound( B, C, D, E, A, f1, K1, expand( in, 19 ) );
00170
00171 subRound( A, B, C, D, E, f2, K2, expand( in, 20 ) );
00172 subRound( E, A, B, C, D, f2, K2, expand( in, 21 ) );
00173 subRound( D, E, A, B, C, f2, K2, expand( in, 22 ) );
00174 subRound( C, D, E, A, B, f2, K2, expand( in, 23 ) );
00175 subRound( B, C, D, E, A, f2, K2, expand( in, 24 ) );
00176 subRound( A, B, C, D, E, f2, K2, expand( in, 25 ) );
00177 subRound( E, A, B, C, D, f2, K2, expand( in, 26 ) );
00178 subRound( D, E, A, B, C, f2, K2, expand( in, 27 ) );
00179 subRound( C, D, E, A, B, f2, K2, expand( in, 28 ) );
00180 subRound( B, C, D, E, A, f2, K2, expand( in, 29 ) );
00181 subRound( A, B, C, D, E, f2, K2, expand( in, 30 ) );
00182 subRound( E, A, B, C, D, f2, K2, expand( in, 31 ) );
00183 subRound( D, E, A, B, C, f2, K2, expand( in, 32 ) );
00184 subRound( C, D, E, A, B, f2, K2, expand( in, 33 ) );
00185 subRound( B, C, D, E, A, f2, K2, expand( in, 34 ) );
00186 subRound( A, B, C, D, E, f2, K2, expand( in, 35 ) );
00187 subRound( E, A, B, C, D, f2, K2, expand( in, 36 ) );
00188 subRound( D, E, A, B, C, f2, K2, expand( in, 37 ) );
00189 subRound( C, D, E, A, B, f2, K2, expand( in, 38 ) );
00190 subRound( B, C, D, E, A, f2, K2, expand( in, 39 ) );
00191
00192 subRound( A, B, C, D, E, f3, K3, expand( in, 40 ) );
00193 subRound( E, A, B, C, D, f3, K3, expand( in, 41 ) );
00194 subRound( D, E, A, B, C, f3, K3, expand( in, 42 ) );
00195 subRound( C, D, E, A, B, f3, K3, expand( in, 43 ) );
00196 subRound( B, C, D, E, A, f3, K3, expand( in, 44 ) );
00197 subRound( A, B, C, D, E, f3, K3, expand( in, 45 ) );
00198 subRound( E, A, B, C, D, f3, K3, expand( in, 46 ) );
00199 subRound( D, E, A, B, C, f3, K3, expand( in, 47 ) );
00200 subRound( C, D, E, A, B, f3, K3, expand( in, 48 ) );
00201 subRound( B, C, D, E, A, f3, K3, expand( in, 49 ) );
00202 subRound( A, B, C, D, E, f3, K3, expand( in, 50 ) );
00203 subRound( E, A, B, C, D, f3, K3, expand( in, 51 ) );
00204 subRound( D, E, A, B, C, f3, K3, expand( in, 52 ) );
00205 subRound( C, D, E, A, B, f3, K3, expand( in, 53 ) );
00206 subRound( B, C, D, E, A, f3, K3, expand( in, 54 ) );
00207 subRound( A, B, C, D, E, f3, K3, expand( in, 55 ) );
00208 subRound( E, A, B, C, D, f3, K3, expand( in, 56 ) );
00209 subRound( D, E, A, B, C, f3, K3, expand( in, 57 ) );
00210 subRound( C, D, E, A, B, f3, K3, expand( in, 58 ) );
00211 subRound( B, C, D, E, A, f3, K3, expand( in, 59 ) );
00212
00213 subRound( A, B, C, D, E, f4, K4, expand( in, 60 ) );
00214 subRound( E, A, B, C, D, f4, K4, expand( in, 61 ) );
00215 subRound( D, E, A, B, C, f4, K4, expand( in, 62 ) );
00216 subRound( C, D, E, A, B, f4, K4, expand( in, 63 ) );
00217 subRound( B, C, D, E, A, f4, K4, expand( in, 64 ) );
00218 subRound( A, B, C, D, E, f4, K4, expand( in, 65 ) );
00219 subRound( E, A, B, C, D, f4, K4, expand( in, 66 ) );
00220 subRound( D, E, A, B, C, f4, K4, expand( in, 67 ) );
00221 subRound( C, D, E, A, B, f4, K4, expand( in, 68 ) );
00222 subRound( B, C, D, E, A, f4, K4, expand( in, 69 ) );
00223 subRound( A, B, C, D, E, f4, K4, expand( in, 70 ) );
00224 subRound( E, A, B, C, D, f4, K4, expand( in, 71 ) );
00225 subRound( D, E, A, B, C, f4, K4, expand( in, 72 ) );
00226 subRound( C, D, E, A, B, f4, K4, expand( in, 73 ) );
00227 subRound( B, C, D, E, A, f4, K4, expand( in, 74 ) );
00228 subRound( A, B, C, D, E, f4, K4, expand( in, 75 ) );
00229 subRound( E, A, B, C, D, f4, K4, expand( in, 76 ) );
00230 subRound( D, E, A, B, C, f4, K4, expand( in, 77 ) );
00231 subRound( C, D, E, A, B, f4, K4, expand( in, 78 ) );
00232 subRound( B, C, D, E, A, f4, K4, expand( in, 79 ) );
00233
00234
00235 ctx->digest[0] += A;
00236 ctx->digest[1] += B;
00237 ctx->digest[2] += C;
00238 ctx->digest[3] += D;
00239 ctx->digest[4] += E;
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00260
00261 #define F1(x, y, z) (z ^ (x & (y ^ z)))
00262 #define F2(x, y, z) F1(z, x, y)
00263 #define F3(x, y, z) (x ^ y ^ z)
00264 #define F4(x, y, z) (y ^ (x | ~z))
00265
00267 #define MD5STEP(f, w, x, y, z, data, s) \
00268 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
00269
00275 static void
00276 MD5Transform(DIGEST_CTX ctx)
00277 {
00278 register uint32 * in = (uint32 *)ctx->in;
00279 register uint32 a = ctx->digest[0];
00280 register uint32 b = ctx->digest[1];
00281 register uint32 c = ctx->digest[2];
00282 register uint32 d = ctx->digest[3];
00283
00284 MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
00285 MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
00286 MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
00287 MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
00288 MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
00289 MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
00290 MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
00291 MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
00292 MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
00293 MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
00294 MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
00295 MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
00296 MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
00297 MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
00298 MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
00299 MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
00300
00301 MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
00302 MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
00303 MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
00304 MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
00305 MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
00306 MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
00307 MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
00308 MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
00309 MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
00310 MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
00311 MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
00312 MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
00313 MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
00314 MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
00315 MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
00316 MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
00317
00318 MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
00319 MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
00320 MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
00321 MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
00322 MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
00323 MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
00324 MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
00325 MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
00326 MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
00327 MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
00328 MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
00329 MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
00330 MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
00331 MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
00332 MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
00333 MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
00334
00335 MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
00336 MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
00337 MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
00338 MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
00339 MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
00340 MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
00341 MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
00342 MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
00343 MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
00344 MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
00345 MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
00346 MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
00347 MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
00348 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
00349 MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
00350 MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
00351
00352 ctx->digest[0] += a;
00353 ctx->digest[1] += b;
00354 ctx->digest[2] += c;
00355 ctx->digest[3] += d;
00356 }
00357
00358 static int _ie = 0x44332211;
00359 static union _mendian { int i; char b[4]; } *_endian = (union _mendian *)&_ie;
00360 #define IS_BIG_ENDIAN() (_endian->b[0] == '\x44')
00361 #define IS_LITTLE_ENDIAN() (_endian->b[0] == '\x11')
00362
00363
00364
00365
00366
00367
00368 static void
00369 byteReverse(byte *buf, unsigned nbytes)
00370 {
00371 unsigned nlongs = nbytes / sizeof(uint32);
00372 uint32 t;
00373 do {
00374 t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
00375 ((unsigned) buf[1] << 8 | buf[0]);
00376 *(uint32 *) buf = t;
00377 buf += 4;
00378 } while (--nlongs);
00379 }
00380
00381 DIGEST_CTX
00382 rpmDigestInit(rpmDigestFlags flags)
00383 {
00384 DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx));
00385
00386 ctx->flags = flags;
00387
00388 if (flags & RPMDIGEST_MD5) {
00389 ctx->digestlen = 16;
00390 ctx->datalen = 64;
00391 ctx->transform = MD5Transform;
00392 ctx->digest[0] = 0x67452301;
00393 ctx->digest[1] = 0xefcdab89;
00394 ctx->digest[2] = 0x98badcfe;
00395 ctx->digest[3] = 0x10325476;
00396 }
00397
00398 if (flags & RPMDIGEST_SHA1) {
00399 ctx->digestlen = 20;
00400 ctx->datalen = 64;
00401 ctx->transform = SHA1Transform;
00402 ctx->digest[ 0 ] = 0x67452301;
00403 ctx->digest[ 1 ] = 0xefcdab89;
00404 ctx->digest[ 2 ] = 0x98badcfe;
00405 ctx->digest[ 3 ] = 0x10325476;
00406 ctx->digest[ 4 ] = 0xc3d2e1f0;
00407 }
00408
00409
00410 ctx->doByteReverse = (IS_BIG_ENDIAN()) ? 1 : 0;
00411 if (flags & RPMDIGEST_NATIVE)
00412 ctx->doByteReverse = 0;
00413
00414 ctx->bits[0] = 0;
00415 ctx->bits[1] = 0;
00416
00417 return ctx;
00418 }
00419
00420 void
00421 rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
00422 {
00423 const byte * buf = data;
00424 uint32 t;
00425
00426
00427
00428 t = ctx->bits[0];
00429 if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
00430 ctx->bits[1]++;
00431 ctx->bits[1] += len >> 29;
00432
00433 t = (t >> 3) % ctx->datalen;
00434
00435
00436 if (t) {
00437 byte *p = (byte *) ctx->in + t;
00438
00439 t = ctx->datalen - t;
00440 if (len < t) {
00441 memcpy(p, buf, len);
00442 return;
00443 }
00444 memcpy(p, buf, t);
00445 if (ctx->doByteReverse)
00446 byteReverse(ctx->in, ctx->datalen);
00447 ctx->transform(ctx);
00448 buf += t;
00449 len -= t;
00450 }
00451
00452
00453 for (; len >= ctx->datalen; buf += ctx->datalen, len -= ctx->datalen) {
00454 memcpy(ctx->in, buf, ctx->datalen);
00455 if (ctx->doByteReverse)
00456 byteReverse(ctx->in, ctx->datalen);
00457 ctx->transform(ctx);
00458 }
00459
00460
00461 memcpy(ctx->in, buf, len);
00462 }
00463
00464 void
00465 rpmDigestFinal( DIGEST_CTX ctx, void ** datap,
00466 size_t *lenp, int asAscii)
00467 {
00468 unsigned count = (ctx->bits[0] >> 3) % ctx->datalen;
00469 byte * p = ctx->in + count;
00470
00471
00472
00473 *p++ = 0x80;
00474
00475
00476 count = ctx->datalen - 1 - count;
00477
00478
00479 if (count < sizeof(ctx->bits)) {
00480 memset(p, 0, count);
00481 if (ctx->doByteReverse)
00482 byteReverse(ctx->in, ctx->datalen);
00483 ctx->transform(ctx);
00484 p = ctx->in;
00485 count = ctx->datalen;
00486 }
00487
00488
00489 memset(p, 0, count - sizeof(ctx->bits));
00490 if (ctx->doByteReverse)
00491 byteReverse(ctx->in, ctx->datalen - sizeof(ctx->bits));
00492 ((uint32 *) ctx->in)[14] = ctx->bits[0];
00493 ((uint32 *) ctx->in)[15] = ctx->bits[1];
00494 ctx->transform(ctx);
00495
00496
00497 if (ctx->doByteReverse)
00498 byteReverse((byte *) ctx->digest, ctx->digestlen);
00499
00500 if (!asAscii) {
00501 if (lenp) *lenp = ctx->digestlen;
00502 if (datap) {
00503 *datap = xmalloc(ctx->digestlen);
00504 memcpy(*datap, ctx->digest, ctx->digestlen);
00505 }
00506 } else {
00507 if (lenp) *lenp = (2*ctx->digestlen) + 1;
00508 if (datap) {
00509 const byte * s = (const byte *) ctx->digest;
00510 static const char hex[] = "0123456789abcdef";
00511 char * t;
00512 int i;
00513
00514 *datap = t = xmalloc((2*ctx->digestlen) + 1);
00515
00516 for (i = 0 ; i < ctx->digestlen; i++) {
00517 *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
00518 *t++ = hex[ (unsigned)((*s++ ) & 0x0f) ];
00519 }
00520 *t = '\0';
00521 }
00522 }
00523 memset(ctx, 0, sizeof(*ctx));
00524 free(ctx);
00525 }