- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

# rpmio/digest.c

Go to the documentation of this file.

    00001
    00005 #include "system.h"
    00006
    00007 #include <zlib.h>
    00008
    00009 #include "rpmio_internal.h"
    00010
    00011 #include <rpmbc.h>
    00012
    00013 #include "md2.h"
    00014 #include "md4.h"
    00015 #include "sha224.h"
    00016 #include "rmd128.h"
    00017 #include "rmd160.h"
    00018 #include "rmd256.h"
    00019 #include "rmd320.h"
    00020 #include "salsa10.h"
    00021 #include "salsa20.h"
    00022 #include "tiger.h"
    00023
    00024 #include "debug.h"
    00025
    00026 #ifdef  SHA_DEBUG
    00027 #define DPRINTF(_a)     fprintf _a
    00028 #else
    00029 #define DPRINTF(_a)
    00030 #endif
    00031
    00032 #if !defined(ZLIB_H) || defined(__LCLINT__)
    00033
    00035 /*@-shadow@*/
    00036 static uint32_t crc32(uint32_t crc, const byte * data, size_t size)
    00037         /*@*/
    00038 {
    00039     static uint32_t polynomial = 0xedb88320;    /* reflected 0x04c11db7 */
    00040     static uint32_t xorout = 0xffffffff;
    00041     static uint32_t table[256];
    00042
    00043     crc ^= xorout;
    00044
    00045     if (data == NULL) {
    00046         /* generate the table of CRC remainders for all possible bytes */
    00047         uint32_t c;
    00048         uint32_t i, j;
    00049         for (i = 0;  i < 256;  i++) {
    00050             c = i;
    00051             for (j = 0;  j < 8;  j++) {
    00052                 if (c & 1)
    00053                     c = polynomial ^ (c >> 1);
    00054                 else
    00055                     c = (c >> 1);
    00056             }
    00057             table[i] = c;
    00058         }
    00059     } else
    00060     while (size) {
    00061         crc = table[(crc ^ *data) & 0xff] ^ (crc >> 8);
    00062         size--;
    00063         data++;
    00064     }
    00065
    00066     crc ^= xorout;
    00067
    00068     return crc;
    00069
    00070 }
    00071 /*@=shadow@*/
    00072 #endif
    00073
    00074 /* Include Bob Jenkins lookup3 hash */
    00075 #define _JLU3_jlu32l
    00076 #include "lookup3.c"
    00077
    00080 typedef struct {
    00081         uint32_t crc;
    00082         uint32_t (*update)  (uint32_t crc, const byte * data, size_t size);
    00083         uint32_t (*combine) (uint32_t crc1, uint32_t crc2, size_t len2);
    00084 } sum32Param;
    00085
    00088 static int sum32Reset(register sum32Param* mp)
    00089         /*@modifies *mp @*/
    00090 {
    00091     if (mp->update)
    00092         mp->crc = (*mp->update) (0, NULL, 0);
    00093     return 0;
    00094 }
    00095
    00098 static int sum32Update(sum32Param* mp, const byte* data, size_t size)
    00099         /*@modifies *mp @*/
    00100 {
    00101     if (mp->update)
    00102         mp->crc = (*mp->update) (mp->crc, data, size);
    00103     return 0;
    00104 }
    00105
    00108 static int sum32Digest(sum32Param* mp, byte* data)
    00109         /*@modifies *mp, data @*/
    00110 {
    00111         uint32_t c = mp->crc;
    00112
    00113         data[ 0] = (byte)(c >> 24);
    00114         data[ 1] = (byte)(c >> 16);
    00115         data[ 2] = (byte)(c >>  8);
    00116         data[ 3] = (byte)(c      );
    00117
    00118         (void) sum32Reset(mp);
    00119
    00120         return 0;
    00121 }
    00122
    00123 /*
    00124  * ECMA-182 polynomial, see
    00125  *     http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-182.pdf
    00126  */
    00129 static uint64_t crc64(uint64_t crc, const byte * data, size_t size)
    00130         /*@*/
    00131 {
    00132     static uint64_t polynomial =
    00133         0xc96c5795d7870f42ULL;  /* reflected 0x42f0e1eba9ea3693ULL */
    00134     static uint64_t xorout = 0xffffffffffffffffULL;
    00135     static uint64_t table[256];
    00136
    00137     crc ^= xorout;
    00138
    00139     if (data == NULL) {
    00140         /* generate the table of CRC remainders for all possible bytes */
    00141         uint64_t c;
    00142         uint32_t i, j;
    00143         for (i = 0;  i < 256;  i++) {
    00144             c = i;
    00145             for (j = 0;  j < 8;  j++) {
    00146                 if (c & 1)
    00147                     c = polynomial ^ (c >> 1);
    00148                 else
    00149                     c = (c >> 1);
    00150             }
    00151             table[i] = c;
    00152         }
    00153     } else
    00154     while (size) {
    00155         crc = table[(crc ^ *data) & 0xff] ^ (crc >> 8);
    00156         size--;
    00157         data++;
    00158     }
    00159
    00160     crc ^= xorout;
    00161
    00162     return crc;
    00163
    00164 }
    00165
    00166 /*
    00167  * Swiped from zlib, using uint64_t rather than unsigned long computation.
    00168  * Use at your own risk, uint64_t problems with compilers may exist.
    00169  */
    00170 #define GF2_DIM 64
    00171
    00174 static uint64_t gf2_matrix_times(uint64_t *mat, uint64_t vec)
    00175         /*@*/
    00176 {
    00177     uint64_t sum;
    00178
    00179     sum = 0;
    00180     while (vec) {
    00181         if (vec & 1)
    00182             sum ^= *mat;
    00183         vec >>= 1;
    00184         mat++;
    00185     }
    00186     return sum;
    00187 }
    00188
    00191 static void gf2_matrix_square(/*@out@*/ uint64_t *square, uint64_t *mat)
    00192         /*@modifies square @*/
    00193 {
    00194     int n;
    00195
    00196     for (n = 0; n < GF2_DIM; n++)
    00197         square[n] = gf2_matrix_times(mat, mat[n]);
    00198 }
    00199
    00202 static uint64_t crc64_combine(uint64_t crc1, uint64_t crc2, size_t len2)
    00203         /*@*/
    00204 {
    00205     int n;
    00206     uint64_t row;
    00207     uint64_t even[GF2_DIM];    /* even-power-of-two zeros operator */
    00208     uint64_t odd[GF2_DIM];     /* odd-power-of-two zeros operator */
    00209
    00210     /* degenerate case */
    00211     if (len2 == 0)
    00212         return crc1;
    00213
    00214     /* put operator for one zero bit in odd */
    00215     odd[0] = 0xc96c5795d7870f42ULL;     /* reflected 0x42f0e1eba9ea3693ULL */
    00216     row = 1;
    00217     for (n = 1; n < GF2_DIM; n++) {
    00218         odd[n] = row;
    00219         row <<= 1;
    00220     }
    00221
    00222     /* put operator for two zero bits in even */
    00223     gf2_matrix_square(even, odd);
    00224
    00225     /* put operator for four zero bits in odd */
    00226     gf2_matrix_square(odd, even);
    00227
    00228     /* apply len2 zeros to crc1 (first square will put the operator for one
    00229        zero byte, eight zero bits, in even) */
    00230     do {
    00231         /* apply zeros operator for this bit of len2 */
    00232         gf2_matrix_square(even, odd);
    00233         if (len2 & 1)
    00234             crc1 = gf2_matrix_times(even, crc1);
    00235         len2 >>= 1;
    00236
    00237         /* if no more bits set, then done */
    00238         if (len2 == 0)
    00239             break;
    00240
    00241         /* another iteration of the loop with odd and even swapped */
    00242         gf2_matrix_square(odd, even);
    00243         if (len2 & 1)
    00244             crc1 = gf2_matrix_times(odd, crc1);
    00245         len2 >>= 1;
    00246
    00247         /* if no more bits set, then done */
    00248     } while (len2 != 0);
    00249
    00250     /* return combined crc */
    00251     crc1 ^= crc2;
    00252     return crc1;
    00253 }
    00254
    00257 typedef struct {
    00258         uint64_t crc;
    00259         uint64_t (*update)  (uint64_t crc, const byte * data, size_t size);
    00260         uint64_t (*combine) (uint64_t crc1, uint64_t crc2, size_t len2);
    00261 } sum64Param;
    00262
    00265 static int sum64Reset(register sum64Param* mp)
    00266         /*@modifies *mp @*/
    00267 {
    00268     if (mp->update)
    00269         mp->crc = (*mp->update) (0, NULL, 0);
    00270     return 0;
    00271 }
    00272
    00275 static int sum64Update(sum64Param* mp, const byte* data, size_t size)
    00276         /*@modifies *mp @*/
    00277 {
    00278     if (mp->update)
    00279         mp->crc = (*mp->update) (mp->crc, data, size);
    00280     return 0;
    00281 }
    00282
    00285 static int sum64Digest(sum64Param* mp, byte* data)
    00286         /*@modifies *mp, data @*/
    00287 {
    00288         uint64_t c = mp->crc;
    00289
    00290         data[ 0] = (byte)(c >> 56);
    00291         data[ 1] = (byte)(c >> 48);
    00292         data[ 2] = (byte)(c >> 40);
    00293         data[ 3] = (byte)(c >> 32);
    00294         data[ 4] = (byte)(c >> 24);
    00295         data[ 5] = (byte)(c >> 16);
    00296         data[ 6] = (byte)(c >>  8);
    00297         data[ 7] = (byte)(c      );
    00298
    00299         (void) sum64Reset(mp);
    00300
    00301         return 0;
    00302 }
    00303
    00304 /*@access DIGEST_CTX@*/
    00305
    00309 struct DIGEST_CTX_s {
    00310 /*@observer@*/
    00311     const char * name;
    00312     size_t paramsize;
    00313     size_t datasize;
    00314     size_t digestsize;
    00315     int (*Reset) (void * param)
    00316         /*@modifies param @*/;
    00317     int (*Update) (void * param, const byte * data, size_t size)
    00318         /*@modifies param @*/;
    00319     int (*Digest) (void * param, /*@out@*/ byte * digest)
    00320         /*@modifies param, digest @*/;
    00321     rpmDigestFlags flags;
    00322     void * param;
    00323 };
    00324
    00325 DIGEST_CTX
    00326 rpmDigestDup(DIGEST_CTX octx)
    00327 {
    00328     DIGEST_CTX nctx;
    00329     nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
    00330     nctx->param = memcpy(xcalloc(1, nctx->paramsize), octx->param, nctx->paramsize);
    00331     return nctx;
    00332 }
    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 = (int (*)(void *)) md5Reset;
    00353         ctx->Update = (int (*)(void *, const byte *, size_t)) md5Update;
    00354         ctx->Digest = (int (*)(void *, byte *)) 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 = (int (*)(void *)) sha1Reset;
    00367         ctx->Update = (int (*)(void *, const byte *, size_t)) sha1Update;
    00368         ctx->Digest = (int (*)(void *, byte *)) 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 = (int (*)(void *)) rmd128Reset;
    00381         ctx->Update = (int (*)(void *, const byte *, size_t)) rmd128Update;
    00382         ctx->Digest = (int (*)(void *, byte *)) 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 = (int (*)(void *)) rmd160Reset;
    00395         ctx->Update = (int (*)(void *, const byte *, size_t)) rmd160Update;
    00396         ctx->Digest = (int (*)(void *, byte *)) 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 = (int (*)(void *)) rmd256Reset;
    00409         ctx->Update = (int (*)(void *, const byte *, size_t)) rmd256Update;
    00410         ctx->Digest = (int (*)(void *, byte *)) 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 = (int (*)(void *)) rmd320Reset;
    00423         ctx->Update = (int (*)(void *, const byte *, size_t)) rmd320Update;
    00424         ctx->Digest = (int (*)(void *, byte *)) 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 = (int (*)(void *)) salsa10Reset;
    00437         ctx->Update = (int (*)(void *, const byte *, size_t)) salsa10Update;
    00438         ctx->Digest = (int (*)(void *, byte *)) 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 = (int (*)(void *)) salsa20Reset;
    00451         ctx->Update = (int (*)(void *, const byte *, size_t)) salsa20Update;
    00452         ctx->Digest = (int (*)(void *, byte *)) 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 = (int (*)(void *)) tigerReset;
    00465         ctx->Update = (int (*)(void *, const byte *, size_t)) tigerUpdate;
    00466         ctx->Digest = (int (*)(void *, byte *)) 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 = (int (*)(void *)) md2Reset;
    00479         ctx->Update = (int (*)(void *, const byte *, size_t)) md2Update;
    00480         ctx->Digest = (int (*)(void *, byte *)) 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 = (int (*)(void *)) md4Reset;
    00493         ctx->Update = (int (*)(void *, const byte *, size_t)) md4Update;
    00494         ctx->Digest = (int (*)(void *, byte *)) 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 = (uint32_t (*)(uint32_t, const byte *, size_t)) crc32;
    00504 #if defined(ZLIB_H)
    00505             mp->combine = (uint32_t (*)(uint32_t, uint32_t, size_t)) crc32_combine;
    00506 #endif
    00507 /*@=type @*/
    00508             ctx->paramsize = sizeof(*mp);
    00509             ctx->param = mp;
    00510         }
    00511 /*@-type@*/
    00512         ctx->Reset = (int (*)(void *)) sum32Reset;
    00513         ctx->Update = (int (*)(void *, const byte *, size_t)) sum32Update;
    00514         ctx->Digest = (int (*)(void *, byte *)) 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 = (uint32_t (*)(uint32_t, const byte *, size_t)) adler32;
    00525             mp->combine = (uint32_t (*)(uint32_t, uint32_t, size_t)) adler32_combine;
    00526 #endif
    00527 /*@=type @*/
    00528             ctx->paramsize = sizeof(*mp);
    00529             ctx->param = mp;
    00530         }
    00531 /*@-type@*/
    00532         ctx->Reset = (int (*)(void *)) sum32Reset;
    00533         ctx->Update = (int (*)(void *, const byte *, size_t)) sum32Update;
    00534         ctx->Digest = (int (*)(void *, byte *)) 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 = (uint32_t (*)(uint32_t, const byte *, size_t)) jlu32l;
    00544 /*@=type @*/
    00545             ctx->paramsize = sizeof(*mp);
    00546             ctx->param = mp;
    00547         }
    00548 /*@-type@*/
    00549         ctx->Reset = (int (*)(void *)) sum32Reset;
    00550         ctx->Update = (int (*)(void *, const byte *, size_t)) sum32Update;
    00551         ctx->Digest = (int (*)(void *, byte *)) 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 = (uint64_t (*)(uint64_t, const byte *, size_t)) crc64;
    00561             mp->combine = (uint64_t (*)(uint64_t, uint64_t, size_t)) crc64_combine;
    00562 /*@=type@*/
    00563             ctx->paramsize = sizeof(*mp);
    00564             ctx->param = mp;
    00565         }
    00566 /*@-type@*/
    00567         ctx->Reset = (int (*)(void *)) sum64Reset;
    00568         ctx->Update = (int (*)(void *, const byte *, size_t)) sum64Update;
    00569         ctx->Digest = (int (*)(void *, byte *)) sum64Digest;
    00570 /*@=type@*/
    00571         break;
    00572 #if defined(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 = (int (*)(void *)) sha224Reset;
    00583         ctx->Update = (int (*)(void *, const byte *, size_t)) sha224Update;
    00584         ctx->Digest = (int (*)(void *, byte *)) 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 = (int (*)(void *)) sha256Reset;
    00597         ctx->Update = (int (*)(void *, const byte *, size_t)) sha256Update;
    00598         ctx->Digest = (int (*)(void *, byte *)) 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 = (int (*)(void *)) sha384Reset;
    00611         ctx->Update = (int (*)(void *, const byte *, size_t)) sha384Update;
    00612         ctx->Digest = (int (*)(void *, byte *)) 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 = (int (*)(void *)) sha512Reset;
    00625         ctx->Update = (int (*)(void *, const byte *, size_t)) sha512Update;
    00626         ctx->Digest = (int (*)(void *, byte *)) 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     xx = (*ctx->Reset) (ctx->param);
    00638
    00639 DPRINTF((stderr, "*** Init(%x) ctx %p param %p\n", flags, ctx, ctx->param));
    00640     return ctx;
    00641 }
    00642
    00643 /*@-mustmod@*/ /* LCL: ctx->param may be modified, but ctx is abstract @*/
    00644 int
    00645 rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
    00646 {
    00647     if (ctx == NULL)
    00648         return -1;
    00649
    00650 DPRINTF((stderr, "*** Update(%p,%p,%d) param %p \"%s\"\n", ctx, data, len, ctx->param, ((char *)data)));
    00651     return (*ctx->Update) (ctx->param, data, len);
    00652 }
    00653 /*@=mustmod@*/
    00654
    00655 int
    00656 rpmDigestFinal(DIGEST_CTX ctx, void * datap, size_t *lenp, int asAscii)
    00657 {
    00658     byte * digest;
    00659     char * t;
    00660
    00661     if (ctx == NULL)
    00662         return -1;
    00663     digest = xmalloc(ctx->digestsize);
    00664
    00665 DPRINTF((stderr, "*** Final(%p,%p,%p,%d) param %p digest %p\n", ctx, datap, lenp, asAscii, ctx->param, digest));
    00666 /*@-noeffectuncon@*/ /* FIX: check rc */
    00667     (void) (*ctx->Digest) (ctx->param, digest);
    00668 /*@=noeffectuncon@*/
    00669
    00670     /* Return final digest. */
    00671     if (!asAscii) {
    00672         if (lenp) *lenp = ctx->digestsize;
    00673         if (datap) {
    00674             *(byte **)datap = digest;
    00675             digest = NULL;
    00676         }
    00677     } else {
    00678         if (lenp) *lenp = (2*ctx->digestsize) + 1;
    00679         if (datap) {
    00680             const byte * s = (const byte *) digest;
    00681             static const char hex[] = "0123456789abcdef";
    00682             size_t i;
    00683
    00684             *(char **)datap = t = xmalloc((2*ctx->digestsize) + 1);
    00685             for (i = 0 ; i < ctx->digestsize; i++) {
    00686                 *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
    00687                 *t++ = hex[ (unsigned)((*s++   ) & 0x0f) ];
    00688             }
    00689             *t = '\0';
    00690         }
    00691     }
    00692     if (digest) {
    00693         memset(digest, 0, ctx->digestsize);     /* In case it's sensitive */
    00694         free(digest);
    00695     }
    00696     memset(ctx->param, 0, ctx->paramsize);      /* In case it's sensitive */
    00697     free(ctx->param);
    00698     memset(ctx, 0, sizeof(*ctx));       /* In case it's sensitive */
    00699     free(ctx);
    00700     return 0;
    00701 }
    00702
    00703 pgpHashAlgo rpmDigestHashAlgo = PGPHASHALGO_MD5;
    00704
    00708 struct poptOption rpmDigestPoptTable[] = {
    00709  { "md2", '\0', POPT_ARG_VAL,   &rpmDigestHashAlgo, PGPHASHALGO_MD2,
    00710         NULL, NULL },
    00711  { "md4", '\0', POPT_ARG_VAL,   &rpmDigestHashAlgo, PGPHASHALGO_MD4,
    00712         NULL, NULL },
    00713  { "md5", '\0', POPT_ARG_VAL,   &rpmDigestHashAlgo, PGPHASHALGO_MD5,
    00714         NULL, NULL },
    00715  { "sha1",'\0', POPT_ARG_VAL,   &rpmDigestHashAlgo, PGPHASHALGO_SHA1,
    00716         NULL, NULL },
    00717  { "sha224",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SHA224,
    00718         NULL, NULL },
    00719  { "sha256",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SHA256,
    00720         NULL, NULL },
    00721  { "sha384",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SHA384,
    00722         NULL, NULL },
    00723  { "sha512",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SHA512,
    00724         NULL, NULL },
    00725  { "salsa10",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SALSA10,
    00726         NULL, NULL },
    00727  { "salsa20",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_SALSA20,
    00728         NULL, NULL },
    00729  { "rmd128",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_RIPEMD128,
    00730         NULL, NULL },
    00731  { "rmd160",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_RIPEMD160,
    00732         NULL, NULL },
    00733  { "rmd256",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_RIPEMD256,
    00734         NULL, NULL },
    00735  { "rmd320",'\0', POPT_ARG_VAL, &rpmDigestHashAlgo, PGPHASHALGO_RIPEMD320,
    00736         NULL, NULL },
    00737  { "tiger",'\0', POPT_ARG_VAL,  &rpmDigestHashAlgo, PGPHASHALGO_TIGER192,
    00738         NULL, NULL },
    00739  { "crc32",'\0', POPT_ARG_VAL,  &rpmDigestHashAlgo, PGPHASHALGO_CRC32,
    00740         NULL, NULL },
    00741  { "crc64",'\0', POPT_ARG_VAL,  &rpmDigestHashAlgo, PGPHASHALGO_CRC64,
    00742         NULL, NULL },
    00743  { "adler32",'\0', POPT_ARG_VAL,&rpmDigestHashAlgo, PGPHASHALGO_ADLER32,
    00744         NULL, NULL },
    00745  { "jlu32",'\0', POPT_ARG_VAL,&rpmDigestHashAlgo, PGPHASHALGO_JLU32,
    00746         NULL, NULL },
    00747     POPT_TABLEEND
    00748 };