rpm 5.2.1

- 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 "rpmio_internal.h"
    00008
    00009 #include <rpmbc.h>
    00010
    00011 #include "crc.h"
    00012 #include "md2.h"
    00013 #include "md4.h"
    00014 #include "sha224.h"
    00015 #include "rmd128.h"
    00016 #include "rmd160.h"
    00017 #include "rmd256.h"
    00018 #include "rmd320.h"
    00019 #include "salsa10.h"
    00020 #include "salsa20.h"
    00021 #include "tiger.h"
    00022
    00023 #include "debug.h"
    00024
    00025 #ifdef  SHA_DEBUG
    00026 #define DPRINTF(_a)     fprintf _a
    00027 #else
    00028 #define DPRINTF(_a)
    00029 #endif
    00030
    00031 /* Include Bob Jenkins lookup3 hash */
    00032 #define _JLU3_jlu32l
    00033 #include "lookup3.c"
    00034
    00035 /*@access DIGEST_CTX@*/
    00036
    00040 struct DIGEST_CTX_s {
    00041 /*@observer@*/
    00042     const char * name;
    00043     size_t paramsize;
    00044     size_t datasize;
    00045     size_t digestsize;
    00046     int (*Reset) (void * param)
    00047         /*@modifies param @*/;
    00048     int (*Update) (void * param, const byte * data, size_t size)
    00049         /*@modifies param @*/;
    00050     int (*Digest) (void * param, /*@out@*/ byte * digest)
    00051         /*@modifies param, digest @*/;
    00052     pgpHashAlgo hashalgo;
    00053     rpmDigestFlags flags;
    00054 /*@observer@*/ /*@null@*/
    00055     const char * asn1;
    00056     void * param;
    00057 };
    00058
    00059 pgpHashAlgo rpmDigestAlgo(DIGEST_CTX ctx)
    00060 {
    00061     return (ctx != NULL ? ctx->hashalgo : PGPHASHALGO_NONE);
    00062 }
    00063
    00064 const char * rpmDigestName(DIGEST_CTX ctx)
    00065 {
    00066     return (ctx != NULL ? ctx->name : "UNKNOWN");
    00067 }
    00068
    00069 const char * rpmDigestASN1(DIGEST_CTX ctx)
    00070 {
    00071     return (ctx != NULL ? ctx->asn1 : NULL);
    00072 }
    00073
    00074
    00075 DIGEST_CTX
    00076 rpmDigestDup(DIGEST_CTX octx)
    00077 {
    00078     DIGEST_CTX nctx;
    00079     nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
    00080     nctx->param = memcpy(xcalloc(1, nctx->paramsize), octx->param, nctx->paramsize);
    00081     return nctx;
    00082 }
    00083
    00084 DIGEST_CTX
    00085 rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
    00086 {
    00087     DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx));
    00088     int xx;
    00089
    00090     ctx->hashalgo = hashalgo;
    00091     ctx->flags = flags;
    00092
    00093     switch (hashalgo) {
    00094     case PGPHASHALGO_MD5:
    00095         ctx->name = "MD5";
    00096         ctx->digestsize = 128/8;
    00097         ctx->datasize = 64;
    00098 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
    00099         ctx->paramsize = sizeof(md5Param);
    00100 /*@=sizeoftype@*/
    00101         ctx->param = xcalloc(1, ctx->paramsize);
    00102 /*@-type@*/
    00103         ctx->Reset = (int (*)(void *)) md5Reset;
    00104         ctx->Update = (int (*)(void *, const byte *, size_t)) md5Update;
    00105         ctx->Digest = (int (*)(void *, byte *)) md5Digest;
    00106 /*@=type@*/
    00107         ctx->asn1 = "3020300c06082a864886f70d020505000410";
    00108         break;
    00109     case PGPHASHALGO_SHA1:
    00110         ctx->name = "SHA1";
    00111         ctx->digestsize = 160/8;
    00112         ctx->datasize = 64;
    00113 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
    00114         ctx->paramsize = sizeof(sha1Param);
    00115 /*@=sizeoftype@*/
    00116         ctx->param = xcalloc(1, ctx->paramsize);
    00117 /*@-type@*/
    00118         ctx->Reset = (int (*)(void *)) sha1Reset;
    00119         ctx->Update = (int (*)(void *, const byte *, size_t)) sha1Update;
    00120         ctx->Digest = (int (*)(void *, byte *)) sha1Digest;
    00121 /*@=type@*/
    00122         ctx->asn1 = "3021300906052b0e03021a05000414";
    00123         break;
    00124     case PGPHASHALGO_RIPEMD128:
    00125         ctx->name = "RIPEMD128";
    00126         ctx->digestsize = 128/8;
    00127         ctx->datasize = 64;
    00128 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
    00129         ctx->paramsize = sizeof(rmd128Param);
    00130 /*@=sizeoftype@*/
    00131         ctx->param = xcalloc(1, ctx->paramsize);
    00132 /*@-type@*/
    00133         ctx->Reset = (int (*)(void *)) rmd128Reset;
    00134         ctx->Update = (int (*)(void *, const byte *, size_t)) rmd128Update;
    00135         ctx->Digest = (int (*)(void *, byte *)) rmd128Digest;
    00136 /*@=type@*/
    00137         break;
    00138     case PGPHASHALGO_RIPEMD160:
    00139         ctx->name = "RIPEMD160";
    00140         ctx->digestsize = 160/8;
    00141         ctx->datasize = 64;
    00142 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
    00143         ctx->paramsize = sizeof(rmd160Param);
    00144 /*@=sizeoftype@*/
    00145         ctx->param = xcalloc(1, ctx->paramsize);
    00146 /*@-type@*/
    00147         ctx->Reset = (int (*)(void *)) rmd160Reset;
    00148         ctx->Update = (int (*)(void *, const byte *, size_t)) rmd160Update;
    00149         ctx->Digest = (int (*)(void *, byte *)) rmd160Digest;
    00150 /*@=type@*/
    00151         ctx->asn1 = "3021300906052b2403020105000414";
    00152         break;
    00153     case PGPHASHALGO_RIPEMD256:
    00154         ctx->name = "RIPEMD256";
    00155         ctx->digestsize = 256/8;
    00156         ctx->datasize = 64;
    00157 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
    00158         ctx->paramsize = sizeof(rmd256Param);
    00159 /*@=sizeoftype@*/
    00160         ctx->param = xcalloc(1, ctx->paramsize);
    00161 /*@-type@*/
    00162         ctx->Reset = (int (*)(void *)) rmd256Reset;
    00163         ctx->Update = (int (*)(void *, const byte *, size_t)) rmd256Update;
    00164         ctx->Digest = (int (*)(void *, byte *)) rmd256Digest;
    00165 /*@=type@*/
    00166         break;
    00167     case PGPHASHALGO_RIPEMD320:
    00168         ctx->name = "RIPEMD320";
    00169         ctx->digestsize = 320/8;
    00170         ctx->datasize = 64;
    00171 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
    00172         ctx->paramsize = sizeof(rmd320Param);
    00173 /*@=sizeoftype@*/
    00174         ctx->param = xcalloc(1, ctx->paramsize);
    00175 /*@-type@*/
    00176         ctx->Reset = (int (*)(void *)) rmd320Reset;
    00177         ctx->Update = (int (*)(void *, const byte *, size_t)) rmd320Update;
    00178         ctx->Digest = (int (*)(void *, byte *)) rmd320Digest;
    00179 /*@=type@*/
    00180         break;
    00181     case PGPHASHALGO_SALSA10:
    00182         ctx->name = "SALSA10";
    00183         ctx->digestsize = 512/8;
    00184         ctx->datasize = 64;
    00185 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
    00186         ctx->paramsize = sizeof(salsa10Param);
    00187 /*@=sizeoftype@*/
    00188         ctx->param = xcalloc(1, ctx->paramsize);
    00189 /*@-type@*/
    00190         ctx->Reset = (int (*)(void *)) salsa10Reset;
    00191         ctx->Update = (int (*)(void *, const byte *, size_t)) salsa10Update;
    00192         ctx->Digest = (int (*)(void *, byte *)) salsa10Digest;
    00193 /*@=type@*/
    00194         break;
    00195     case PGPHASHALGO_SALSA20:
    00196         ctx->name = "SALSA20";
    00197         ctx->digestsize = 512/8;
    00198         ctx->datasize = 64;
    00199 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
    00200         ctx->paramsize = sizeof(salsa20Param);
    00201 /*@=sizeoftype@*/
    00202         ctx->param = xcalloc(1, ctx->paramsize);
    00203 /*@-type@*/
    00204         ctx->Reset = (int (*)(void *)) salsa20Reset;
    00205         ctx->Update = (int (*)(void *, const byte *, size_t)) salsa20Update;
    00206         ctx->Digest = (int (*)(void *, byte *)) salsa20Digest;
    00207 /*@=type@*/
    00208         break;
    00209     case PGPHASHALGO_TIGER192:
    00210         ctx->name = "TIGER192";
    00211         ctx->digestsize = 192/8;
    00212         ctx->datasize = 64;
    00213 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
    00214         ctx->paramsize = sizeof(tigerParam);
    00215 /*@=sizeoftype@*/
    00216         ctx->param = xcalloc(1, ctx->paramsize);
    00217 /*@-type@*/
    00218         ctx->Reset = (int (*)(void *)) tigerReset;
    00219         ctx->Update = (int (*)(void *, const byte *, size_t)) tigerUpdate;
    00220         ctx->Digest = (int (*)(void *, byte *)) tigerDigest;
    00221 /*@=type@*/
    00222         ctx->asn1 = "3029300d06092b06010401da470c0205000418";
    00223         break;
    00224     case PGPHASHALGO_MD2:
    00225         ctx->name = "MD2";
    00226         ctx->digestsize = 128/8;
    00227         ctx->datasize = 16;
    00228 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
    00229         ctx->paramsize = sizeof(md2Param);
    00230 /*@=sizeoftype@*/
    00231         ctx->param = xcalloc(1, ctx->paramsize);
    00232 /*@-type@*/
    00233         ctx->Reset = (int (*)(void *)) md2Reset;
    00234         ctx->Update = (int (*)(void *, const byte *, size_t)) md2Update;
    00235         ctx->Digest = (int (*)(void *, byte *)) md2Digest;
    00236 /*@=type@*/
    00237         ctx->asn1 = "3020300c06082a864886f70d020205000410";
    00238         break;
    00239     case PGPHASHALGO_MD4:
    00240         ctx->name = "MD4";
    00241         ctx->digestsize = 128/8;
    00242         ctx->datasize = 64;
    00243 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
    00244         ctx->paramsize = sizeof(md4Param);
    00245 /*@=sizeoftype@*/
    00246         ctx->param = xcalloc(1, ctx->paramsize);
    00247 /*@-type@*/
    00248         ctx->Reset = (int (*)(void *)) md4Reset;
    00249         ctx->Update = (int (*)(void *, const byte *, size_t)) md4Update;
    00250         ctx->Digest = (int (*)(void *, byte *)) md4Digest;
    00251 /*@=type@*/
    00252         break;
    00253     case PGPHASHALGO_CRC32:
    00254         ctx->name = "CRC32";
    00255         ctx->digestsize = 32/8;
    00256         ctx->datasize = 8;
    00257         {   sum32Param * mp = xcalloc(1, sizeof(*mp));
    00258 /*@-type @*/
    00259             mp->update = (rpmuint32_t (*)(rpmuint32_t, const byte *, size_t)) __crc32;
    00260             mp->combine = (rpmuint32_t (*)(rpmuint32_t, rpmuint32_t, size_t)) __crc32_combine;
    00261 /*@=type @*/
    00262             ctx->paramsize = sizeof(*mp);
    00263             ctx->param = mp;
    00264         }
    00265 /*@-type@*/
    00266         ctx->Reset = (int (*)(void *)) sum32Reset;
    00267         ctx->Update = (int (*)(void *, const byte *, size_t)) sum32Update;
    00268         ctx->Digest = (int (*)(void *, byte *)) sum32Digest;
    00269 /*@=type@*/
    00270         break;
    00271     case PGPHASHALGO_ADLER32:
    00272         ctx->name = "ADLER32";
    00273         ctx->digestsize = 32/8;
    00274         ctx->datasize = 8;
    00275         {   sum32Param * mp = xcalloc(1, sizeof(*mp));
    00276 /*@-type @*/
    00277             mp->update = (rpmuint32_t (*)(rpmuint32_t, const byte *, size_t)) __adler32;
    00278             mp->combine = (rpmuint32_t (*)(rpmuint32_t, rpmuint32_t, size_t)) __adler32_combine;
    00279 /*@=type @*/
    00280             ctx->paramsize = sizeof(*mp);
    00281             ctx->param = mp;
    00282         }
    00283 /*@-type@*/
    00284         ctx->Reset = (int (*)(void *)) sum32Reset;
    00285         ctx->Update = (int (*)(void *, const byte *, size_t)) sum32Update;
    00286         ctx->Digest = (int (*)(void *, byte *)) sum32Digest;
    00287 /*@=type@*/
    00288         break;
    00289     case PGPHASHALGO_JLU32:
    00290         ctx->name = "JLU32";
    00291         ctx->digestsize = 32/8;
    00292         ctx->datasize = 8;
    00293         {   sum32Param * mp = xcalloc(1, sizeof(*mp));
    00294 /*@-type @*/
    00295             mp->update = (rpmuint32_t (*)(rpmuint32_t, const byte *, size_t)) jlu32l;
    00296 /*@=type @*/
    00297             ctx->paramsize = sizeof(*mp);
    00298             ctx->param = mp;
    00299         }
    00300 /*@-type@*/
    00301         ctx->Reset = (int (*)(void *)) sum32Reset;
    00302         ctx->Update = (int (*)(void *, const byte *, size_t)) sum32Update;
    00303         ctx->Digest = (int (*)(void *, byte *)) sum32Digest;
    00304 /*@=type@*/
    00305         break;
    00306     case PGPHASHALGO_CRC64:
    00307         ctx->name = "CRC64";
    00308         ctx->digestsize = 64/8;
    00309         ctx->datasize = 8;
    00310         {   sum64Param * mp = xcalloc(1, sizeof(*mp));
    00311 /*@-type@*/
    00312             mp->update = (rpmuint64_t (*)(rpmuint64_t, const byte *, size_t)) __crc64;
    00313             mp->combine = (rpmuint64_t (*)(rpmuint64_t, rpmuint64_t, size_t)) __crc64_combine;
    00314 /*@=type@*/
    00315             ctx->paramsize = sizeof(*mp);
    00316             ctx->param = mp;
    00317         }
    00318 /*@-type@*/
    00319         ctx->Reset = (int (*)(void *)) sum64Reset;
    00320         ctx->Update = (int (*)(void *, const byte *, size_t)) sum64Update;
    00321         ctx->Digest = (int (*)(void *, byte *)) sum64Digest;
    00322 /*@=type@*/
    00323         break;
    00324 #if defined(HAVE_BEECRYPT_API_H)
    00325     case PGPHASHALGO_SHA224:
    00326         ctx->name = "SHA224";
    00327         ctx->digestsize = 224/8;
    00328         ctx->datasize = 64;
    00329 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
    00330         ctx->paramsize = sizeof(sha224Param);
    00331 /*@=sizeoftype@*/
    00332         ctx->param = xcalloc(1, ctx->paramsize);
    00333 /*@-type@*/
    00334         ctx->Reset = (int (*)(void *)) sha224Reset;
    00335         ctx->Update = (int (*)(void *, const byte *, size_t)) sha224Update;
    00336         ctx->Digest = (int (*)(void *, byte *)) sha224Digest;
    00337 /*@=type@*/
    00338         ctx->asn1 = "302d300d06096086480165030402040500041C";
    00339         break;
    00340     case PGPHASHALGO_SHA256:
    00341         ctx->name = "SHA256";
    00342         ctx->digestsize = 256/8;
    00343         ctx->datasize = 64;
    00344 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
    00345         ctx->paramsize = sizeof(sha256Param);
    00346 /*@=sizeoftype@*/
    00347         ctx->param = xcalloc(1, ctx->paramsize);
    00348 /*@-type@*/
    00349         ctx->Reset = (int (*)(void *)) sha256Reset;
    00350         ctx->Update = (int (*)(void *, const byte *, size_t)) sha256Update;
    00351         ctx->Digest = (int (*)(void *, byte *)) sha256Digest;
    00352 /*@=type@*/
    00353         ctx->asn1 = "3031300d060960864801650304020105000420";
    00354         break;
    00355     case PGPHASHALGO_SHA384:
    00356         ctx->name = "SHA384";
    00357         ctx->digestsize = 384/8;
    00358         ctx->datasize = 128;
    00359 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
    00360         ctx->paramsize = sizeof(sha384Param);
    00361 /*@=sizeoftype@*/
    00362         ctx->param = xcalloc(1, ctx->paramsize);
    00363 /*@-type@*/
    00364         ctx->Reset = (int (*)(void *)) sha384Reset;
    00365         ctx->Update = (int (*)(void *, const byte *, size_t)) sha384Update;
    00366         ctx->Digest = (int (*)(void *, byte *)) sha384Digest;
    00367 /*@=type@*/
    00368         ctx->asn1 = "3041300d060960864801650304020205000430";
    00369         break;
    00370     case PGPHASHALGO_SHA512:
    00371         ctx->name = "SHA512";
    00372         ctx->digestsize = 512/8;
    00373         ctx->datasize = 128;
    00374 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
    00375         ctx->paramsize = sizeof(sha512Param);
    00376 /*@=sizeoftype@*/
    00377         ctx->param = xcalloc(1, ctx->paramsize);
    00378 /*@-type@*/
    00379         ctx->Reset = (int (*)(void *)) sha512Reset;
    00380         ctx->Update = (int (*)(void *, const byte *, size_t)) sha512Update;
    00381         ctx->Digest = (int (*)(void *, byte *)) sha512Digest;
    00382 /*@=type@*/
    00383         ctx->asn1 = "3051300d060960864801650304020305000440";
    00384         break;
    00385 #endif
    00386     case PGPHASHALGO_HAVAL_5_160:
    00387     default:
    00388         free(ctx);
    00389         return NULL;
    00390         /*@notreached@*/ break;
    00391     }
    00392
    00393     xx = (*ctx->Reset) (ctx->param);
    00394
    00395 DPRINTF((stderr, "*** Init(%x) ctx %p param %p\n", flags, ctx, ctx->param));
    00396     return ctx;
    00397 }
    00398
    00399 /*@-mustmod@*/ /* LCL: ctx->param may be modified, but ctx is abstract @*/
    00400 int
    00401 rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
    00402 {
    00403     if (ctx == NULL)
    00404         return -1;
    00405
    00406 DPRINTF((stderr, "*** Update(%p,%p,%d) param %p \"%s\"\n", ctx, data, len, ctx->param, ((char *)data)));
    00407     return (*ctx->Update) (ctx->param, data, len);
    00408 }
    00409 /*@=mustmod@*/
    00410
    00411 int
    00412 rpmDigestFinal(DIGEST_CTX ctx, void * datap, size_t *lenp, int asAscii)
    00413 {
    00414     byte * digest;
    00415     char * t;
    00416
    00417     if (ctx == NULL)
    00418         return -1;
    00419     digest = xmalloc(ctx->digestsize);
    00420
    00421 DPRINTF((stderr, "*** Final(%p,%p,%p,%d) param %p digest %p\n", ctx, datap, lenp, asAscii, ctx->param, digest));
    00422 /*@-noeffectuncon@*/ /* FIX: check rc */
    00423     (void) (*ctx->Digest) (ctx->param, digest);
    00424 /*@=noeffectuncon@*/
    00425
    00426     /* Return final digest. */
    00427     if (!asAscii) {
    00428         if (lenp) *lenp = ctx->digestsize;
    00429         if (datap) {
    00430             *(byte **)datap = digest;
    00431             digest = NULL;
    00432         }
    00433     } else {
    00434         if (lenp) *lenp = (2*ctx->digestsize) + 1;
    00435         if (datap) {
    00436             const byte * s = (const byte *) digest;
    00437             static const char hex[] = "0123456789abcdef";
    00438             size_t i;
    00439
    00440             *(char **)datap = t = xmalloc((2*ctx->digestsize) + 1);
    00441             for (i = 0 ; i < ctx->digestsize; i++) {
    00442                 *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
    00443                 *t++ = hex[ (unsigned)((*s++   ) & 0x0f) ];
    00444             }
    00445             *t = '\0';
    00446         }
    00447     }
    00448     if (digest) {
    00449         memset(digest, 0, ctx->digestsize);     /* In case it's sensitive */
    00450         free(digest);
    00451     }
    00452     memset(ctx->param, 0, ctx->paramsize);      /* In case it's sensitive */
    00453     free(ctx->param);
    00454     memset(ctx, 0, sizeof(*ctx));       /* In case it's sensitive */
    00455     free(ctx);
    00456     return 0;
    00457 }