rpm
4.5
|
00001 00005 #include "system.h" 00006 00007 #include <zlib.h> 00008 00009 #include "rpmio_internal.h" 00010 00011 #include "md2.h" 00012 #include "md4.h" 00013 #include "sha224.h" 00014 #include "rmd128.h" 00015 #include "rmd160.h" 00016 #include "rmd256.h" 00017 #include "rmd320.h" 00018 #include "salsa10.h" 00019 #include "salsa20.h" 00020 #include "tiger.h" 00021 00022 #include "debug.h" 00023 00024 #ifdef SHA_DEBUG 00025 #define DPRINTF(_a) fprintf _a 00026 #else 00027 #define DPRINTF(_a) 00028 #endif 00029 00030 #if !defined(ZLIB_H) || defined(__LCLINT__) 00031 00033 /*@-shadow@*/ 00034 static uint32_t crc32(uint32_t crc, const byte * data, size_t size) 00035 /*@*/ 00036 { 00037 static uint32_t polynomial = 0xedb88320; /* reflected 0x04c11db7 */ 00038 static uint32_t xorout = 0xffffffff; 00039 static uint32_t table[256]; 00040 00041 crc ^= xorout; 00042 00043 if (data == NULL) { 00044 /* generate the table of CRC remainders for all possible bytes */ 00045 uint32_t c; 00046 uint32_t i, j; 00047 for (i = 0; i < 256; i++) { 00048 c = i; 00049 for (j = 0; j < 8; j++) { 00050 if (c & 1) 00051 c = polynomial ^ (c >> 1); 00052 else 00053 c = (c >> 1); 00054 } 00055 table[i] = c; 00056 } 00057 } else 00058 while (size) { 00059 crc = table[(crc ^ *data) & 0xff] ^ (crc >> 8); 00060 size--; 00061 data++; 00062 } 00063 00064 crc ^= xorout; 00065 00066 return crc; 00067 00068 } 00069 /*@=shadow@*/ 00070 #endif 00071 00072 /* Include Bob Jenkins lookup3 hash */ 00073 #define _JLU3_jlu32l 00074 #include "lookup3.c" 00075 00078 typedef struct { 00079 uint32_t crc; 00080 uint32_t (*update) (uint32_t crc, const byte * data, size_t size); 00081 uint32_t (*combine) (uint32_t crc1, uint32_t crc2, size_t len2); 00082 } sum32Param; 00083 00086 static int sum32Reset(register sum32Param* mp) 00087 /*@modifies *mp @*/ 00088 { 00089 if (mp->update) 00090 mp->crc = (*mp->update) (0, NULL, 0); 00091 return 0; 00092 } 00093 00096 static int sum32Update(sum32Param* mp, const byte* data, size_t size) 00097 /*@modifies *mp @*/ 00098 { 00099 if (mp->update) 00100 mp->crc = (*mp->update) (mp->crc, data, size); 00101 return 0; 00102 } 00103 00106 static int sum32Digest(sum32Param* mp, byte* data) 00107 /*@modifies *mp, data @*/ 00108 { 00109 uint32_t c = mp->crc; 00110 00111 data[ 0] = (byte)(c >> 24); 00112 data[ 1] = (byte)(c >> 16); 00113 data[ 2] = (byte)(c >> 8); 00114 data[ 3] = (byte)(c ); 00115 00116 (void) sum32Reset(mp); 00117 00118 return 0; 00119 } 00120 00121 /* 00122 * ECMA-182 polynomial, see 00123 * http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-182.pdf 00124 */ 00127 static uint64_t crc64(uint64_t crc, const byte * data, size_t size) 00128 /*@*/ 00129 { 00130 static uint64_t polynomial = 00131 0xc96c5795d7870f42ULL; /* reflected 0x42f0e1eba9ea3693ULL */ 00132 static uint64_t xorout = 0xffffffffffffffffULL; 00133 static uint64_t table[256]; 00134 00135 crc ^= xorout; 00136 00137 if (data == NULL) { 00138 /* generate the table of CRC remainders for all possible bytes */ 00139 uint64_t c; 00140 uint32_t i, j; 00141 for (i = 0; i < 256; i++) { 00142 c = i; 00143 for (j = 0; j < 8; j++) { 00144 if (c & 1) 00145 c = polynomial ^ (c >> 1); 00146 else 00147 c = (c >> 1); 00148 } 00149 table[i] = c; 00150 } 00151 } else 00152 while (size) { 00153 crc = table[(crc ^ *data) & 0xff] ^ (crc >> 8); 00154 size--; 00155 data++; 00156 } 00157 00158 crc ^= xorout; 00159 00160 return crc; 00161 00162 } 00163 00164 /* 00165 * Swiped from zlib, using uint64_t rather than unsigned long computation. 00166 * Use at your own risk, uint64_t problems with compilers may exist. 00167 */ 00168 #define GF2_DIM 64 00169 00172 static uint64_t gf2_matrix_times(uint64_t *mat, uint64_t vec) 00173 /*@*/ 00174 { 00175 uint64_t sum; 00176 00177 sum = 0; 00178 while (vec) { 00179 if (vec & 1) 00180 sum ^= *mat; 00181 vec >>= 1; 00182 mat++; 00183 } 00184 return sum; 00185 } 00186 00189 static void gf2_matrix_square(/*@out@*/ uint64_t *square, uint64_t *mat) 00190 /*@modifies square @*/ 00191 { 00192 int n; 00193 00194 for (n = 0; n < GF2_DIM; n++) 00195 square[n] = gf2_matrix_times(mat, mat[n]); 00196 } 00197 00200 static uint64_t crc64_combine(uint64_t crc1, uint64_t crc2, size_t len2) 00201 /*@*/ 00202 { 00203 int n; 00204 uint64_t row; 00205 uint64_t even[GF2_DIM]; /* even-power-of-two zeros operator */ 00206 uint64_t odd[GF2_DIM]; /* odd-power-of-two zeros operator */ 00207 00208 /* degenerate case */ 00209 if (len2 == 0) 00210 return crc1; 00211 00212 /* put operator for one zero bit in odd */ 00213 odd[0] = 0xc96c5795d7870f42ULL; /* reflected 0x42f0e1eba9ea3693ULL */ 00214 row = 1; 00215 for (n = 1; n < GF2_DIM; n++) { 00216 odd[n] = row; 00217 row <<= 1; 00218 } 00219 00220 /* put operator for two zero bits in even */ 00221 gf2_matrix_square(even, odd); 00222 00223 /* put operator for four zero bits in odd */ 00224 gf2_matrix_square(odd, even); 00225 00226 /* apply len2 zeros to crc1 (first square will put the operator for one 00227 zero byte, eight zero bits, in even) */ 00228 do { 00229 /* apply zeros operator for this bit of len2 */ 00230 gf2_matrix_square(even, odd); 00231 if (len2 & 1) 00232 crc1 = gf2_matrix_times(even, crc1); 00233 len2 >>= 1; 00234 00235 /* if no more bits set, then done */ 00236 if (len2 == 0) 00237 break; 00238 00239 /* another iteration of the loop with odd and even swapped */ 00240 gf2_matrix_square(odd, even); 00241 if (len2 & 1) 00242 crc1 = gf2_matrix_times(odd, crc1); 00243 len2 >>= 1; 00244 00245 /* if no more bits set, then done */ 00246 } while (len2 != 0); 00247 00248 /* return combined crc */ 00249 crc1 ^= crc2; 00250 return crc1; 00251 } 00252 00255 typedef struct { 00256 uint64_t crc; 00257 uint64_t (*update) (uint64_t crc, const byte * data, size_t size); 00258 uint64_t (*combine) (uint64_t crc1, uint64_t crc2, size_t len2); 00259 } sum64Param; 00260 00263 static int sum64Reset(register sum64Param* mp) 00264 /*@modifies *mp @*/ 00265 { 00266 if (mp->update) 00267 mp->crc = (*mp->update) (0, NULL, 0); 00268 return 0; 00269 } 00270 00273 static int sum64Update(sum64Param* mp, const byte* data, size_t size) 00274 /*@modifies *mp @*/ 00275 { 00276 if (mp->update) 00277 mp->crc = (*mp->update) (mp->crc, data, size); 00278 return 0; 00279 } 00280 00283 static int sum64Digest(sum64Param* mp, byte* data) 00284 /*@modifies *mp, data @*/ 00285 { 00286 uint64_t c = mp->crc; 00287 00288 data[ 0] = (byte)(c >> 56); 00289 data[ 1] = (byte)(c >> 48); 00290 data[ 2] = (byte)(c >> 40); 00291 data[ 3] = (byte)(c >> 32); 00292 data[ 4] = (byte)(c >> 24); 00293 data[ 5] = (byte)(c >> 16); 00294 data[ 6] = (byte)(c >> 8); 00295 data[ 7] = (byte)(c ); 00296 00297 (void) sum64Reset(mp); 00298 00299 return 0; 00300 } 00301 00302 /*@access DIGEST_CTX@*/ 00303 00307 struct DIGEST_CTX_s { 00308 /*@observer@*/ 00309 const char * name; 00310 size_t paramsize; 00311 size_t datasize; 00312 size_t digestsize; 00313 int (*Reset) (void * param) 00314 /*@modifies param @*/; 00315 int (*Update) (void * param, const byte * data, size_t size) 00316 /*@modifies param @*/; 00317 int (*Digest) (void * param, /*@out@*/ byte * digest) 00318 /*@modifies param, digest @*/; 00319 rpmDigestFlags flags; 00320 void * param; 00321 }; 00322 00323 /*@-boundsread@*/ 00324 DIGEST_CTX 00325 rpmDigestDup(DIGEST_CTX octx) 00326 { 00327 DIGEST_CTX nctx; 00328 nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx)); 00329 nctx->param = memcpy(xcalloc(1, nctx->paramsize), octx->param, nctx->paramsize); 00330 return nctx; 00331 } 00332 /*@=boundsread@*/ 00333 00334 DIGEST_CTX 00335 rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags) 00336 { 00337 DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx)); 00338 int xx; 00339 00340 ctx->flags = flags; 00341 00342 switch (hashalgo) { 00343 case PGPHASHALGO_MD5: 00344 ctx->name = "MD5"; 00345 ctx->digestsize = 128/8; 00346 ctx->datasize = 64; 00347 /*@-sizeoftype@*/ /* FIX: union, not void pointer */ 00348 ctx->paramsize = sizeof(md5Param); 00349 /*@=sizeoftype@*/ 00350 ctx->param = xcalloc(1, ctx->paramsize); 00351 /*@-type@*/ 00352 ctx->Reset = (void *) md5Reset; 00353 ctx->Update = (void *) md5Update; 00354 ctx->Digest = (void *) md5Digest; 00355 /*@=type@*/ 00356 break; 00357 case PGPHASHALGO_SHA1: 00358 ctx->name = "SHA-1"; 00359 ctx->digestsize = 160/8; 00360 ctx->datasize = 64; 00361 /*@-sizeoftype@*/ /* FIX: union, not void pointer */ 00362 ctx->paramsize = sizeof(sha1Param); 00363 /*@=sizeoftype@*/ 00364 ctx->param = xcalloc(1, ctx->paramsize); 00365 /*@-type@*/ 00366 ctx->Reset = (void *) sha1Reset; 00367 ctx->Update = (void *) sha1Update; 00368 ctx->Digest = (void *) sha1Digest; 00369 /*@=type@*/ 00370 break; 00371 case PGPHASHALGO_RIPEMD128: 00372 ctx->name = "RIPEMD-128"; 00373 ctx->digestsize = 128/8; 00374 ctx->datasize = 64; 00375 /*@-sizeoftype@*/ /* FIX: union, not void pointer */ 00376 ctx->paramsize = sizeof(rmd128Param); 00377 /*@=sizeoftype@*/ 00378 ctx->param = xcalloc(1, ctx->paramsize); 00379 /*@-type@*/ 00380 ctx->Reset = (void *) rmd128Reset; 00381 ctx->Update = (void *) rmd128Update; 00382 ctx->Digest = (void *) rmd128Digest; 00383 /*@=type@*/ 00384 break; 00385 case PGPHASHALGO_RIPEMD160: 00386 ctx->name = "RIPEMD-160"; 00387 ctx->digestsize = 160/8; 00388 ctx->datasize = 64; 00389 /*@-sizeoftype@*/ /* FIX: union, not void pointer */ 00390 ctx->paramsize = sizeof(rmd160Param); 00391 /*@=sizeoftype@*/ 00392 ctx->param = xcalloc(1, ctx->paramsize); 00393 /*@-type@*/ 00394 ctx->Reset = (void *) rmd160Reset; 00395 ctx->Update = (void *) rmd160Update; 00396 ctx->Digest = (void *) rmd160Digest; 00397 /*@=type@*/ 00398 break; 00399 case PGPHASHALGO_RIPEMD256: 00400 ctx->name = "RIPEMD-256"; 00401 ctx->digestsize = 256/8; 00402 ctx->datasize = 64; 00403 /*@-sizeoftype@*/ /* FIX: union, not void pointer */ 00404 ctx->paramsize = sizeof(rmd256Param); 00405 /*@=sizeoftype@*/ 00406 ctx->param = xcalloc(1, ctx->paramsize); 00407 /*@-type@*/ 00408 ctx->Reset = (void *) rmd256Reset; 00409 ctx->Update = (void *) rmd256Update; 00410 ctx->Digest = (void *) rmd256Digest; 00411 /*@=type@*/ 00412 break; 00413 case PGPHASHALGO_RIPEMD320: 00414 ctx->name = "RIPEMD-320"; 00415 ctx->digestsize = 320/8; 00416 ctx->datasize = 64; 00417 /*@-sizeoftype@*/ /* FIX: union, not void pointer */ 00418 ctx->paramsize = sizeof(rmd320Param); 00419 /*@=sizeoftype@*/ 00420 ctx->param = xcalloc(1, ctx->paramsize); 00421 /*@-type@*/ 00422 ctx->Reset = (void *) rmd320Reset; 00423 ctx->Update = (void *) rmd320Update; 00424 ctx->Digest = (void *) rmd320Digest; 00425 /*@=type@*/ 00426 break; 00427 case PGPHASHALGO_SALSA10: 00428 ctx->name = "SALSA-10"; 00429 ctx->digestsize = 512/8; 00430 ctx->datasize = 64; 00431 /*@-sizeoftype@*/ /* FIX: union, not void pointer */ 00432 ctx->paramsize = sizeof(salsa10Param); 00433 /*@=sizeoftype@*/ 00434 ctx->param = xcalloc(1, ctx->paramsize); 00435 /*@-type@*/ 00436 ctx->Reset = (void *) salsa10Reset; 00437 ctx->Update = (void *) salsa10Update; 00438 ctx->Digest = (void *) salsa10Digest; 00439 /*@=type@*/ 00440 break; 00441 case PGPHASHALGO_SALSA20: 00442 ctx->name = "SALSA-20"; 00443 ctx->digestsize = 512/8; 00444 ctx->datasize = 64; 00445 /*@-sizeoftype@*/ /* FIX: union, not void pointer */ 00446 ctx->paramsize = sizeof(salsa20Param); 00447 /*@=sizeoftype@*/ 00448 ctx->param = xcalloc(1, ctx->paramsize); 00449 /*@-type@*/ 00450 ctx->Reset = (void *) salsa20Reset; 00451 ctx->Update = (void *) salsa20Update; 00452 ctx->Digest = (void *) salsa20Digest; 00453 /*@=type@*/ 00454 break; 00455 case PGPHASHALGO_TIGER192: 00456 ctx->name = "TIGER-192"; 00457 ctx->digestsize = 192/8; 00458 ctx->datasize = 64; 00459 /*@-sizeoftype@*/ /* FIX: union, not void pointer */ 00460 ctx->paramsize = sizeof(tigerParam); 00461 /*@=sizeoftype@*/ 00462 ctx->param = xcalloc(1, ctx->paramsize); 00463 /*@-type@*/ 00464 ctx->Reset = (void *) tigerReset; 00465 ctx->Update = (void *) tigerUpdate; 00466 ctx->Digest = (void *) tigerDigest; 00467 /*@=type@*/ 00468 break; 00469 case PGPHASHALGO_MD2: 00470 ctx->name = "MD2"; 00471 ctx->digestsize = 128/8; 00472 ctx->datasize = 16; 00473 /*@-sizeoftype@*/ /* FIX: union, not void pointer */ 00474 ctx->paramsize = sizeof(md2Param); 00475 /*@=sizeoftype@*/ 00476 ctx->param = xcalloc(1, ctx->paramsize); 00477 /*@-type@*/ 00478 ctx->Reset = (void *) md2Reset; 00479 ctx->Update = (void *) md2Update; 00480 ctx->Digest = (void *) md2Digest; 00481 /*@=type@*/ 00482 break; 00483 case PGPHASHALGO_MD4: 00484 ctx->name = "MD4"; 00485 ctx->digestsize = 128/8; 00486 ctx->datasize = 64; 00487 /*@-sizeoftype@*/ /* FIX: union, not void pointer */ 00488 ctx->paramsize = sizeof(md4Param); 00489 /*@=sizeoftype@*/ 00490 ctx->param = xcalloc(1, ctx->paramsize); 00491 /*@-type@*/ 00492 ctx->Reset = (void *) md4Reset; 00493 ctx->Update = (void *) md4Update; 00494 ctx->Digest = (void *) md4Digest; 00495 /*@=type@*/ 00496 break; 00497 case PGPHASHALGO_CRC32: 00498 ctx->name = "CRC-32"; 00499 ctx->digestsize = 32/8; 00500 ctx->datasize = 8; 00501 { sum32Param * mp = xcalloc(1, sizeof(*mp)); 00502 /*@-type @*/ 00503 mp->update = (void *) crc32; 00504 #if defined(ZLIB_H) 00505 mp->combine = (void *) crc32_combine; 00506 #endif 00507 /*@=type @*/ 00508 ctx->paramsize = sizeof(*mp); 00509 ctx->param = mp; 00510 } 00511 /*@-type@*/ 00512 ctx->Reset = (void *) sum32Reset; 00513 ctx->Update = (void *) sum32Update; 00514 ctx->Digest = (void *) sum32Digest; 00515 /*@=type@*/ 00516 break; 00517 case PGPHASHALGO_ADLER32: 00518 ctx->name = "ADLER-32"; 00519 ctx->digestsize = 32/8; 00520 ctx->datasize = 8; 00521 { sum32Param * mp = xcalloc(1, sizeof(*mp)); 00522 /*@-type @*/ 00523 #if defined(ZLIB_H) 00524 mp->update = (void *) adler32; 00525 mp->combine = (void *) adler32_combine; 00526 #endif 00527 /*@=type @*/ 00528 ctx->paramsize = sizeof(*mp); 00529 ctx->param = mp; 00530 } 00531 /*@-type@*/ 00532 ctx->Reset = (void *) sum32Reset; 00533 ctx->Update = (void *) sum32Update; 00534 ctx->Digest = (void *) sum32Digest; 00535 /*@=type@*/ 00536 break; 00537 case PGPHASHALGO_JLU32: 00538 ctx->name = "JLU-32"; 00539 ctx->digestsize = 32/8; 00540 ctx->datasize = 8; 00541 { sum32Param * mp = xcalloc(1, sizeof(*mp)); 00542 /*@-type @*/ 00543 mp->update = (void *) jlu32l; 00544 /*@=type @*/ 00545 ctx->paramsize = sizeof(*mp); 00546 ctx->param = mp; 00547 } 00548 /*@-type@*/ 00549 ctx->Reset = (void *) sum32Reset; 00550 ctx->Update = (void *) sum32Update; 00551 ctx->Digest = (void *) sum32Digest; 00552 /*@=type@*/ 00553 break; 00554 case PGPHASHALGO_CRC64: 00555 ctx->name = "CRC-64"; 00556 ctx->digestsize = 64/8; 00557 ctx->datasize = 8; 00558 { sum64Param * mp = xcalloc(1, sizeof(*mp)); 00559 /*@-type@*/ 00560 mp->update = (void *) crc64; 00561 mp->combine = (void *) crc64_combine; 00562 /*@=type@*/ 00563 ctx->paramsize = sizeof(*mp); 00564 ctx->param = mp; 00565 } 00566 /*@-type@*/ 00567 ctx->Reset = (void *) sum64Reset; 00568 ctx->Update = (void *) sum64Update; 00569 ctx->Digest = (void *) sum64Digest; 00570 /*@=type@*/ 00571 break; 00572 #if HAVE_BEECRYPT_API_H 00573 case PGPHASHALGO_SHA224: 00574 ctx->name = "SHA-224"; 00575 ctx->digestsize = 224/8; 00576 ctx->datasize = 64; 00577 /*@-sizeoftype@*/ /* FIX: union, not void pointer */ 00578 ctx->paramsize = sizeof(sha224Param); 00579 /*@=sizeoftype@*/ 00580 ctx->param = xcalloc(1, ctx->paramsize); 00581 /*@-type@*/ 00582 ctx->Reset = (void *) sha224Reset; 00583 ctx->Update = (void *) sha224Update; 00584 ctx->Digest = (void *) sha224Digest; 00585 /*@=type@*/ 00586 break; 00587 case PGPHASHALGO_SHA256: 00588 ctx->name = "SHA-256"; 00589 ctx->digestsize = 256/8; 00590 ctx->datasize = 64; 00591 /*@-sizeoftype@*/ /* FIX: union, not void pointer */ 00592 ctx->paramsize = sizeof(sha256Param); 00593 /*@=sizeoftype@*/ 00594 ctx->param = xcalloc(1, ctx->paramsize); 00595 /*@-type@*/ 00596 ctx->Reset = (void *) sha256Reset; 00597 ctx->Update = (void *) sha256Update; 00598 ctx->Digest = (void *) sha256Digest; 00599 /*@=type@*/ 00600 break; 00601 case PGPHASHALGO_SHA384: 00602 ctx->name = "SHA-384"; 00603 ctx->digestsize = 384/8; 00604 ctx->datasize = 128; 00605 /*@-sizeoftype@*/ /* FIX: union, not void pointer */ 00606 ctx->paramsize = sizeof(sha384Param); 00607 /*@=sizeoftype@*/ 00608 ctx->param = xcalloc(1, ctx->paramsize); 00609 /*@-type@*/ 00610 ctx->Reset = (void *) sha384Reset; 00611 ctx->Update = (void *) sha384Update; 00612 ctx->Digest = (void *) sha384Digest; 00613 /*@=type@*/ 00614 break; 00615 case PGPHASHALGO_SHA512: 00616 ctx->name = "SHA-512"; 00617 ctx->digestsize = 512/8; 00618 ctx->datasize = 128; 00619 /*@-sizeoftype@*/ /* FIX: union, not void pointer */ 00620 ctx->paramsize = sizeof(sha512Param); 00621 /*@=sizeoftype@*/ 00622 ctx->param = xcalloc(1, ctx->paramsize); 00623 /*@-type@*/ 00624 ctx->Reset = (void *) sha512Reset; 00625 ctx->Update = (void *) sha512Update; 00626 ctx->Digest = (void *) sha512Digest; 00627 /*@=type@*/ 00628 break; 00629 #endif 00630 case PGPHASHALGO_HAVAL_5_160: 00631 default: 00632 free(ctx); 00633 return NULL; 00634 /*@notreached@*/ break; 00635 } 00636 00637 /*@-boundsread@*/ 00638 xx = (*ctx->Reset) (ctx->param); 00639 /*@=boundsread@*/ 00640 00641 DPRINTF((stderr, "*** Init(%x) ctx %p param %p\n", flags, ctx, ctx->param)); 00642 return ctx; 00643 } 00644 00645 /*@-mustmod@*/ /* LCL: ctx->param may be modified, but ctx is abstract @*/ 00646 int 00647 rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len) 00648 { 00649 if (ctx == NULL) 00650 return -1; 00651 00652 DPRINTF((stderr, "*** Update(%p,%p,%d) param %p \"%s\"\n", ctx, data, len, ctx->param, ((char *)data))); 00653 /*@-boundsread@*/ 00654 return (*ctx->Update) (ctx->param, data, len); 00655 /*@=boundsread@*/ 00656 } 00657 /*@=mustmod@*/ 00658 00659 /*@-boundswrite@*/ 00660 int 00661 rpmDigestFinal(DIGEST_CTX ctx, void * datap, size_t *lenp, int asAscii) 00662 { 00663 byte * digest; 00664 char * t; 00665 int i; 00666 00667 if (ctx == NULL) 00668 return -1; 00669 digest = xmalloc(ctx->digestsize); 00670 00671 DPRINTF((stderr, "*** Final(%p,%p,%p,%d) param %p digest %p\n", ctx, datap, lenp, asAscii, ctx->param, digest)); 00672 /*@-noeffectuncon@*/ /* FIX: check rc */ 00673 (void) (*ctx->Digest) (ctx->param, digest); 00674 /*@=noeffectuncon@*/ 00675 00676 /* Return final digest. */ 00677 /*@-branchstate@*/ 00678 if (!asAscii) { 00679 if (lenp) *lenp = ctx->digestsize; 00680 if (datap) { 00681 *(byte **)datap = digest; 00682 digest = NULL; 00683 } 00684 } else { 00685 if (lenp) *lenp = (2*ctx->digestsize) + 1; 00686 if (datap) { 00687 const byte * s = (const byte *) digest; 00688 static const char hex[] = "0123456789abcdef"; 00689 00690 *(char **)datap = t = xmalloc((2*ctx->digestsize) + 1); 00691 for (i = 0 ; i < ctx->digestsize; i++) { 00692 *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ]; 00693 *t++ = hex[ (unsigned)((*s++ ) & 0x0f) ]; 00694 } 00695 *t = '\0'; 00696 } 00697 } 00698 /*@=branchstate@*/ 00699 if (digest) { 00700 memset(digest, 0, ctx->digestsize); /* In case it's sensitive */ 00701 free(digest); 00702 } 00703 memset(ctx->param, 0, ctx->paramsize); /* In case it's sensitive */ 00704 free(ctx->param); 00705 memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ 00706 free(ctx); 00707 return 0; 00708 } 00709 /*@=boundswrite@*/ 00710 00711 pgpHashAlgo rpmDigestHashAlgo = PGPHASHALGO_MD5; 00712 00716 struct poptOption rpmDigestPoptTable[] = { 00717 { "md2", '\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_MD2, 00718 NULL, NULL }, 00719 { "md4", '\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_MD4, 00720 NULL, NULL }, 00721 { "md5", '\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_MD5, 00722 NULL, NULL }, 00723 { "sha1",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SHA1, 00724 NULL, NULL }, 00725 { "sha224",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SHA224, 00726 NULL, NULL }, 00727 { "sha256",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SHA256, 00728 NULL, NULL }, 00729 { "sha384",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SHA384, 00730 NULL, NULL }, 00731 { "sha512",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SHA512, 00732 NULL, NULL }, 00733 { "salsa10",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SALSA10, 00734 NULL, NULL }, 00735 { "salsa20",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SALSA20, 00736 NULL, NULL }, 00737 { "rmd128",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_RIPEMD128, 00738 NULL, NULL }, 00739 { "rmd160",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_RIPEMD160, 00740 NULL, NULL }, 00741 { "rmd256",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_RIPEMD256, 00742 NULL, NULL }, 00743 { "rmd320",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_RIPEMD320, 00744 NULL, NULL }, 00745 { "tiger",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_TIGER192, 00746 NULL, NULL }, 00747 { "crc32",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_CRC32, 00748 NULL, NULL }, 00749 { "crc64",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_CRC64, 00750 NULL, NULL }, 00751 { "adler32",'\0', POPT_ARG_VAL,&rpmDigestHashAlgo, PGPHASHALGO_ADLER32, 00752 NULL, NULL }, 00753 { "jlu32",'\0', POPT_ARG_VAL,&rpmDigestHashAlgo, PGPHASHALGO_JLU32, 00754 NULL, NULL }, 00755 { "nodigest",'\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &rpmDigestHashAlgo, PGPHASHALGO_NONE, 00756 N_("no hash algorithm"), NULL }, 00757 { "alldigests",'\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &rpmDigestHashAlgo, 256, 00758 N_("all hash algorithm(s)"), NULL }, 00759 POPT_TABLEEND 00760 };