rpm  5.4.4
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 
00013 #include "arirang.h"
00014 
00015 #include "blake.h"
00016 
00017 #include "bmw.h"
00018 
00019 #include "chi.h"
00020 
00021 #include "cubehash.h"
00022 
00023 #include "echo.h"
00024 #undef  BitSequence
00025 #undef  DataLength
00026 #undef  HashReturn
00027 #undef  hashState
00028 #undef  Init
00029 #undef  Update
00030 #undef  Final
00031 #undef  Hash
00032 
00033 #include "edon-r.h"
00034 
00035 #include "fugue.h"
00036 
00037 #include "groestl.h"
00038 #undef  BitSequence
00039 #undef  DataLength
00040 #undef  HashReturn
00041 #undef  hashState
00042 #undef  Init
00043 #undef  Update
00044 #undef  Final
00045 #undef  Hash
00046 
00047 #include "hamsi.h"
00048 
00049 #include "jh.h"
00050 
00051 #include "keccak.h"
00052 #undef  BitSequence
00053 #undef  DataLength
00054 #undef  HashReturn
00055 #undef  hashState
00056 #undef  Init
00057 #undef  Update
00058 #undef  Final
00059 #undef  Hash
00060 
00061 #include "lane.h"
00062 
00063 #include "luffa.h"
00064 
00065 #include "md2.h"
00066 #include "md6.h"
00067 
00068 #include "shabal.h"
00069 
00070 #include "shavite3.h"
00071 #undef  BitSequence
00072 #undef  DataLength
00073 #undef  HashReturn
00074 #undef  hashState
00075 #undef  Init
00076 #undef  Update
00077 #undef  Final
00078 #undef  Hash
00079 
00080 #include "simd.h"
00081 #undef  BitSequence
00082 #undef  DataLength
00083 #undef  HashReturn
00084 #undef  hashState
00085 #undef  Init
00086 #undef  Update
00087 #undef  Final
00088 #undef  Hash
00089 
00090 #include "salsa10.h"
00091 #include "salsa20.h"
00092 
00093 #include "skein.h"
00094 
00095 #include "tib3.h"
00096 #undef  BitSequence
00097 #undef  DataLength
00098 #undef  HashReturn
00099 #undef  hashState
00100 #undef  Init
00101 #undef  Update
00102 #undef  Final
00103 #undef  Hash
00104 
00105 #include "tiger.h"
00106 
00107 #include "debug.h"
00108 
00109 /*@unchecked@*/
00110 int _ctx_debug = 0;
00111 
00112 #ifdef  _DIGEST_DEBUG
00113 #define DPRINTF(_a)     if (_ctx_debug < 0) fprintf _a
00114 #else
00115 #define DPRINTF(_a)
00116 #endif
00117 
00118 /* Include Bob Jenkins lookup3 hash */
00119 #define _JLU3_jlu32l
00120 #include "lookup3.c"
00121 
00122 /*@access DIGEST_CTX@*/
00123 
00127 struct DIGEST_CTX_s {
00128     struct rpmioItem_s _item;   
00129 /*@observer@*/
00130     const char * name;          
00131     size_t paramsize;           
00132     size_t blocksize;           
00133     size_t digestsize;          
00134     int (*Reset) (void * param)
00135         /*@modifies param @*/;  
00136     int (*Update) (void * param, const byte * data, size_t size)
00137         /*@modifies param @*/;  
00138     int (*Digest) (void * param, /*@out@*/ byte * digest)
00139         /*@modifies param, digest @*/;  
00140     pgpHashAlgo hashalgo;       
00141     rpmDigestFlags flags;       
00142 /*@observer@*/ /*@null@*/
00143     const char * asn1;          
00144     void * param;               
00145     void * salt;                
00146 };
00147 
00148 static void ctxFini(void * _ctx)
00149         /*@modifies _ctx @*/
00150 {
00151     DIGEST_CTX ctx = _ctx;
00152     if (ctx->param != NULL && ctx->paramsize > 0)
00153         memset(ctx->param, 0, ctx->paramsize);  /* In case it's sensitive */
00154     ctx->param = _free(ctx->param);
00155     if (ctx->salt != NULL && ctx->blocksize > 0)
00156         memset(ctx->salt, 0, 2*ctx->paramsize); /* In case it's sensitive */
00157     ctx->salt = _free(ctx->salt);
00158     ctx->name = NULL;
00159     ctx->paramsize = 0;
00160     ctx->blocksize = 0;
00161     ctx->digestsize = 0;
00162     ctx->Reset = NULL;
00163     ctx->Update = NULL;
00164     ctx->Digest = NULL;
00165     ctx->hashalgo = 0;
00166     ctx->flags = 0;
00167     ctx->asn1 = NULL;
00168 }
00169 
00170 /*@unchecked@*/ /*@only@*/ /*@null@*/
00171 rpmioPool _ctxPool;
00172 
00173 static DIGEST_CTX ctxGetPool(rpmioPool pool)
00174 {
00175     DIGEST_CTX ctx;
00176 
00177     if (_ctxPool == NULL) {
00178 ANNOTATE_BENIGN_RACE(&_ctxPool, "");
00179         _ctxPool = rpmioNewPool("ctx", sizeof(*ctx), -1, _ctx_debug,
00180                         NULL, NULL, ctxFini);
00181         pool = _ctxPool;
00182     }
00183     ctx = (DIGEST_CTX) rpmioGetPool(pool, sizeof(*ctx));
00184     memset(((char *)ctx)+sizeof(ctx->_item), 0, sizeof(*ctx)-sizeof(ctx->_item));
00185     return ctx;
00186 }
00187 
00188 pgpHashAlgo rpmDigestAlgo(DIGEST_CTX ctx)
00189 {
00190     return (ctx != NULL ? ctx->hashalgo : PGPHASHALGO_NONE);
00191 }
00192 
00193 rpmDigestFlags rpmDigestF(DIGEST_CTX ctx)
00194 {
00195     return (ctx != NULL ? ctx->flags : RPMDIGEST_NONE);
00196 }
00197 
00198 const char * rpmDigestName(DIGEST_CTX ctx)
00199 {
00200     return (ctx != NULL ? ctx->name : "UNKNOWN");
00201 }
00202 
00203 const char * rpmDigestASN1(DIGEST_CTX ctx)
00204 {
00205     return (ctx != NULL ? ctx->asn1 : NULL);
00206 }
00207 
00208 DIGEST_CTX
00209 rpmDigestDup(DIGEST_CTX octx)
00210 {
00211     DIGEST_CTX nctx = ctxGetPool(_ctxPool);
00212 
00213     nctx->name = octx->name;
00214     nctx->digestsize = octx->digestsize;
00215     nctx->blocksize = octx->blocksize;
00216     nctx->paramsize = octx->paramsize;
00217     nctx->Reset = octx->Reset;
00218     nctx->Update = octx->Update;
00219     nctx->Digest = octx->Digest;
00220     nctx->hashalgo = octx->hashalgo;
00221     nctx->flags = octx->flags;
00222     nctx->asn1 = octx->asn1;
00223     nctx->param = (octx->param != NULL && octx->paramsize > 0)
00224             ? memcpy(DRD_xmalloc(nctx->paramsize), octx->param, nctx->paramsize)
00225             : NULL;
00226     nctx->salt = (octx->salt != NULL && octx->blocksize > 0)
00227             ? memcpy(DRD_xmalloc(nctx->blocksize), octx->salt, nctx->blocksize)
00228             : NULL;
00229     return (DIGEST_CTX)rpmioLinkPoolItem((rpmioItem)nctx, __FUNCTION__, __FILE__, __LINE__);
00230 }
00231 
00232 static int noopReset(void * param)
00233 {
00234     return 0;
00235 }
00236 
00237 /* XXX impedance match bytes -> bits length. */
00238 static int md6_Update(void * param, const byte * _data, size_t _len)
00239 {
00240     return md6_update(param, (unsigned char *) _data, (rpmuint64_t)(8 * _len));
00241 }
00242 
00243 DIGEST_CTX
00244 rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
00245 {
00246     DIGEST_CTX ctx = ctxGetPool(_ctxPool);
00247     int xx;
00248 
00249     ctx->name = "";
00250     ctx->paramsize = 0;
00251     ctx->blocksize = 64;
00252     ctx->digestsize = 0;
00253     ctx->Reset = NULL;
00254     ctx->Update = NULL;
00255     ctx->Digest = NULL;
00256     ctx->hashalgo = hashalgo;
00257     ctx->flags = flags;
00258     ctx->asn1 = NULL;
00259     ctx->param = NULL;
00260     ctx->salt = NULL;
00261 
00262     switch (hashalgo) {
00263     case PGPHASHALGO_MD5:
00264         ctx->name = "MD5";
00265         ctx->digestsize = 128/8;
00266 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00267         ctx->paramsize = sizeof(md5Param);
00268 /*@=sizeoftype@*/
00269         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00270 /*@-type@*/
00271         ctx->Reset = (int (*)(void *)) md5Reset;
00272         ctx->Update = (int (*)(void *, const byte *, size_t)) md5Update;
00273         ctx->Digest = (int (*)(void *, byte *)) md5Digest;
00274 /*@=type@*/
00275         ctx->asn1 = "3020300c06082a864886f70d020505000410";
00276         break;
00277     case PGPHASHALGO_SHA1:
00278         ctx->name = "SHA1";
00279         ctx->digestsize = 160/8;
00280 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00281         ctx->paramsize = sizeof(sha1Param);
00282 /*@=sizeoftype@*/
00283         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00284 /*@-type@*/
00285         ctx->Reset = (int (*)(void *)) sha1Reset;
00286         ctx->Update = (int (*)(void *, const byte *, size_t)) sha1Update;
00287         ctx->Digest = (int (*)(void *, byte *)) sha1Digest;
00288 /*@=type@*/
00289         ctx->asn1 = "3021300906052b0e03021a05000414";
00290         break;
00291     case PGPHASHALGO_RIPEMD128:
00292         ctx->name = "RIPEMD128";
00293         ctx->digestsize = 128/8;
00294 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00295         ctx->paramsize = sizeof(ripemd128Param);
00296 /*@=sizeoftype@*/
00297         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00298 /*@-type@*/
00299         ctx->Reset = (int (*)(void *)) ripemd128Reset;
00300         ctx->Update = (int (*)(void *, const byte *, size_t)) ripemd128Update;
00301         ctx->Digest = (int (*)(void *, byte *)) ripemd128Digest;
00302 /*@=type@*/
00303         break;
00304     case PGPHASHALGO_RIPEMD160:
00305         ctx->name = "RIPEMD160";
00306         ctx->digestsize = 160/8;
00307 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00308         ctx->paramsize = sizeof(ripemd160Param);
00309 /*@=sizeoftype@*/
00310         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00311 /*@-type@*/
00312         ctx->Reset = (int (*)(void *)) ripemd160Reset;
00313         ctx->Update = (int (*)(void *, const byte *, size_t)) ripemd160Update;
00314         ctx->Digest = (int (*)(void *, byte *)) ripemd160Digest;
00315 /*@=type@*/
00316         ctx->asn1 = "3021300906052b2403020105000414";
00317         break;
00318     case PGPHASHALGO_RIPEMD256:
00319         ctx->name = "RIPEMD256";
00320         ctx->digestsize = 256/8;
00321 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00322         ctx->paramsize = sizeof(ripemd256Param);
00323 /*@=sizeoftype@*/
00324         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00325 /*@-type@*/
00326         ctx->Reset = (int (*)(void *)) ripemd256Reset;
00327         ctx->Update = (int (*)(void *, const byte *, size_t)) ripemd256Update;
00328         ctx->Digest = (int (*)(void *, byte *)) ripemd256Digest;
00329 /*@=type@*/
00330         break;
00331     case PGPHASHALGO_RIPEMD320:
00332         ctx->name = "RIPEMD320";
00333         ctx->digestsize = 320/8;
00334 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00335         ctx->paramsize = sizeof(ripemd320Param);
00336 /*@=sizeoftype@*/
00337         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00338 /*@-type@*/
00339         ctx->Reset = (int (*)(void *)) ripemd320Reset;
00340         ctx->Update = (int (*)(void *, const byte *, size_t)) ripemd320Update;
00341         ctx->Digest = (int (*)(void *, byte *)) ripemd320Digest;
00342 /*@=type@*/
00343         break;
00344     case PGPHASHALGO_SALSA10:
00345         ctx->name = "SALSA10";
00346         ctx->digestsize = 512/8;
00347 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00348         ctx->paramsize = sizeof(salsa10Param);
00349 /*@=sizeoftype@*/
00350         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00351 /*@-type@*/
00352         ctx->Reset = (int (*)(void *)) salsa10Reset;
00353         ctx->Update = (int (*)(void *, const byte *, size_t)) salsa10Update;
00354         ctx->Digest = (int (*)(void *, byte *)) salsa10Digest;
00355 /*@=type@*/
00356         break;
00357     case PGPHASHALGO_SALSA20:
00358         ctx->name = "SALSA20";
00359         ctx->digestsize = 512/8;
00360 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00361         ctx->paramsize = sizeof(salsa20Param);
00362 /*@=sizeoftype@*/
00363         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00364 /*@-type@*/
00365         ctx->Reset = (int (*)(void *)) salsa20Reset;
00366         ctx->Update = (int (*)(void *, const byte *, size_t)) salsa20Update;
00367         ctx->Digest = (int (*)(void *, byte *)) salsa20Digest;
00368 /*@=type@*/
00369         break;
00370     case PGPHASHALGO_TIGER192:
00371         ctx->name = "TIGER192";
00372         ctx->digestsize = 192/8;
00373 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00374         ctx->paramsize = sizeof(tigerParam);
00375 /*@=sizeoftype@*/
00376         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00377 /*@-type@*/
00378         ctx->Reset = (int (*)(void *)) tigerReset;
00379         ctx->Update = (int (*)(void *, const byte *, size_t)) tigerUpdate;
00380         ctx->Digest = (int (*)(void *, byte *)) tigerDigest;
00381 /*@=type@*/
00382         ctx->asn1 = "3029300d06092b06010401da470c0205000418";
00383         break;
00384     case PGPHASHALGO_MD2:
00385         ctx->name = "MD2";
00386         ctx->digestsize = 128/8;
00387         ctx->blocksize = 16;
00388 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00389         ctx->paramsize = sizeof(md2Param);
00390 /*@=sizeoftype@*/
00391         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00392 /*@-type@*/
00393         ctx->Reset = (int (*)(void *)) md2Reset;
00394         ctx->Update = (int (*)(void *, const byte *, size_t)) md2Update;
00395         ctx->Digest = (int (*)(void *, byte *)) md2Digest;
00396 /*@=type@*/
00397         ctx->asn1 = "3020300c06082a864886f70d020205000410";
00398         break;
00399     case PGPHASHALGO_MD4:
00400         ctx->name = "MD4";
00401         ctx->digestsize = 128/8;
00402 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00403         ctx->paramsize = sizeof(md4Param);
00404 /*@=sizeoftype@*/
00405         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00406 /*@-type@*/
00407         ctx->Reset = (int (*)(void *)) md4Reset;
00408         ctx->Update = (int (*)(void *, const byte *, size_t)) md4Update;
00409         ctx->Digest = (int (*)(void *, byte *)) md4Digest;
00410 /*@=type@*/
00411         break;
00412     case PGPHASHALGO_CRC32:
00413         ctx->name = "CRC32";
00414         ctx->digestsize = 32/8;
00415         ctx->blocksize = 8;
00416         {   sum32Param * mp = DRD_xcalloc(1, sizeof(*mp));
00417 /*@-type @*/
00418             mp->update = (rpmuint32_t (*)(rpmuint32_t, const byte *, size_t)) __crc32;
00419             mp->combine = (rpmuint32_t (*)(rpmuint32_t, rpmuint32_t, size_t)) __crc32_combine;
00420 /*@=type @*/
00421             ctx->paramsize = sizeof(*mp);
00422             ctx->param = mp;
00423         }
00424 /*@-type@*/
00425         ctx->Reset = (int (*)(void *)) sum32Reset;
00426         ctx->Update = (int (*)(void *, const byte *, size_t)) sum32Update;
00427         ctx->Digest = (int (*)(void *, byte *)) sum32Digest;
00428 /*@=type@*/
00429         break;
00430     case PGPHASHALGO_ADLER32:
00431         ctx->name = "ADLER32";
00432         ctx->digestsize = 32/8;
00433         ctx->blocksize = 8;
00434         {   sum32Param * mp = DRD_xcalloc(1, sizeof(*mp));
00435 /*@-type @*/
00436             mp->update = (rpmuint32_t (*)(rpmuint32_t, const byte *, size_t)) __adler32;
00437             mp->combine = (rpmuint32_t (*)(rpmuint32_t, rpmuint32_t, size_t)) __adler32_combine;
00438 /*@=type @*/
00439             ctx->paramsize = sizeof(*mp);
00440             ctx->param = mp;
00441         }
00442 /*@-type@*/
00443         ctx->Reset = (int (*)(void *)) sum32Reset;
00444         ctx->Update = (int (*)(void *, const byte *, size_t)) sum32Update;
00445         ctx->Digest = (int (*)(void *, byte *)) sum32Digest;
00446 /*@=type@*/
00447         break;
00448     case PGPHASHALGO_JLU32:
00449         ctx->name = "JLU32";
00450         ctx->digestsize = 32/8;
00451         ctx->blocksize = 8;
00452         {   sum32Param * mp = DRD_xcalloc(1, sizeof(*mp));
00453 /*@-type @*/
00454             mp->update = (rpmuint32_t (*)(rpmuint32_t, const byte *, size_t)) jlu32l;
00455 /*@=type @*/
00456             ctx->paramsize = sizeof(*mp);
00457             ctx->param = mp;
00458         }
00459 /*@-type@*/
00460         ctx->Reset = (int (*)(void *)) sum32Reset;
00461         ctx->Update = (int (*)(void *, const byte *, size_t)) sum32Update;
00462         ctx->Digest = (int (*)(void *, byte *)) sum32Digest;
00463 /*@=type@*/
00464         break;
00465     case PGPHASHALGO_CRC64:
00466         ctx->name = "CRC64";
00467         ctx->digestsize = 64/8;
00468         ctx->blocksize = 8;
00469         {   sum64Param * mp = DRD_xcalloc(1, sizeof(*mp));
00470 /*@-type@*/
00471             mp->update = (rpmuint64_t (*)(rpmuint64_t, const byte *, size_t)) __crc64;
00472             mp->combine = (rpmuint64_t (*)(rpmuint64_t, rpmuint64_t, size_t)) __crc64_combine;
00473 /*@=type@*/
00474             ctx->paramsize = sizeof(*mp);
00475             ctx->param = mp;
00476         }
00477 /*@-type@*/
00478         ctx->Reset = (int (*)(void *)) sum64Reset;
00479         ctx->Update = (int (*)(void *, const byte *, size_t)) sum64Update;
00480         ctx->Digest = (int (*)(void *, byte *)) sum64Digest;
00481 /*@=type@*/
00482         break;
00483     case PGPHASHALGO_SHA224:
00484         ctx->name = "SHA224";
00485         ctx->digestsize = 224/8;
00486 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00487         ctx->paramsize = sizeof(sha224Param);
00488 /*@=sizeoftype@*/
00489         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00490 /*@-type@*/
00491         ctx->Reset = (int (*)(void *)) sha224Reset;
00492         ctx->Update = (int (*)(void *, const byte *, size_t)) sha224Update;
00493         ctx->Digest = (int (*)(void *, byte *)) sha224Digest;
00494 /*@=type@*/
00495         ctx->asn1 = "302d300d06096086480165030402040500041C";
00496         break;
00497     case PGPHASHALGO_SHA256:
00498         ctx->name = "SHA256";
00499         ctx->digestsize = 256/8;
00500 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00501         ctx->paramsize = sizeof(sha256Param);
00502 /*@=sizeoftype@*/
00503         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00504 /*@-type@*/
00505         ctx->Reset = (int (*)(void *)) sha256Reset;
00506         ctx->Update = (int (*)(void *, const byte *, size_t)) sha256Update;
00507         ctx->Digest = (int (*)(void *, byte *)) sha256Digest;
00508 /*@=type@*/
00509         ctx->asn1 = "3031300d060960864801650304020105000420";
00510         break;
00511     case PGPHASHALGO_SHA384:
00512         ctx->name = "SHA384";
00513         ctx->digestsize = 384/8;
00514         ctx->blocksize = 128;
00515 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00516         ctx->paramsize = sizeof(sha384Param);
00517 /*@=sizeoftype@*/
00518         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00519 /*@-type@*/
00520         ctx->Reset = (int (*)(void *)) sha384Reset;
00521         ctx->Update = (int (*)(void *, const byte *, size_t)) sha384Update;
00522         ctx->Digest = (int (*)(void *, byte *)) sha384Digest;
00523 /*@=type@*/
00524         ctx->asn1 = "3041300d060960864801650304020205000430";
00525         break;
00526     case PGPHASHALGO_SHA512:
00527         ctx->name = "SHA512";
00528         ctx->digestsize = 512/8;
00529         ctx->blocksize = 128;
00530 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00531         ctx->paramsize = sizeof(sha512Param);
00532 /*@=sizeoftype@*/
00533         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00534 /*@-type@*/
00535         ctx->Reset = (int (*)(void *)) sha512Reset;
00536         ctx->Update = (int (*)(void *, const byte *, size_t)) sha512Update;
00537         ctx->Digest = (int (*)(void *, byte *)) sha512Digest;
00538 /*@=type@*/
00539         ctx->asn1 = "3051300d060960864801650304020305000440";
00540         break;
00541     case PGPHASHALGO_SKEIN_224: ctx->digestsize = 224/8; goto skein256;
00542     case PGPHASHALGO_SKEIN_256: ctx->digestsize = 256/8; goto skein256;
00543 skein256:
00544         ctx->name = "SKEIN256";
00545 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00546         ctx->paramsize = sizeof(Skein_256_Ctxt_t);
00547 /*@=sizeoftype@*/
00548         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00549         (void) Skein_256_Init((Skein_256_Ctxt_t *)ctx->param,
00550                                 (int)(8 * ctx->digestsize));
00551         ctx->Reset = (int (*)(void *)) noopReset;
00552         ctx->Update = (int (*)(void *, const byte *, size_t)) Skein_256_Update;
00553         ctx->Digest = (int (*)(void *, byte *)) Skein_256_Final;
00554         break;
00555     case PGPHASHALGO_SKEIN_384: ctx->digestsize = 384/8; goto skein512;
00556     case PGPHASHALGO_SKEIN_512: ctx->digestsize = 512/8; goto skein512;
00557 skein512:
00558         ctx->name = "SKEIN512";
00559 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00560         ctx->paramsize = sizeof(Skein_512_Ctxt_t);
00561 /*@=sizeoftype@*/
00562         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00563         (void) Skein_512_Init((Skein_512_Ctxt_t *)ctx->param,
00564                                 (int)(8 * ctx->digestsize));
00565         ctx->Reset = (int (*)(void *)) noopReset;
00566         ctx->Update = (int (*)(void *, const byte *, size_t)) Skein_512_Update;
00567         ctx->Digest = (int (*)(void *, byte *)) Skein_512_Final;
00568         break;
00569     case PGPHASHALGO_SKEIN_1024:
00570         ctx->name = "SKEIN1024";
00571         ctx->digestsize = 1024/8;
00572 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00573         ctx->paramsize = sizeof(Skein1024_Ctxt_t);
00574 /*@=sizeoftype@*/
00575         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00576         (void) Skein1024_Init((Skein1024_Ctxt_t *)ctx->param,
00577                                 (int)(8 * ctx->digestsize));
00578         ctx->Reset = (int (*)(void *)) noopReset;
00579         ctx->Update = (int (*)(void *, const byte *, size_t)) Skein1024_Update;
00580         ctx->Digest = (int (*)(void *, byte *)) Skein1024_Final;
00581         break;
00582     case PGPHASHALGO_ARIRANG_224: ctx->digestsize = 224/8; goto arirang;
00583     case PGPHASHALGO_ARIRANG_256: ctx->digestsize = 256/8; goto arirang;
00584     case PGPHASHALGO_ARIRANG_384: ctx->digestsize = 384/8; goto arirang;
00585     case PGPHASHALGO_ARIRANG_512: ctx->digestsize = 512/8; goto arirang;
00586 arirang:
00587         ctx->name = "ARIRANG";
00588 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00589         ctx->paramsize = sizeof(arirangParam);
00590 /*@=sizeoftype@*/
00591         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00592         (void) arirangInit(ctx->param, (int)(8 * ctx->digestsize));
00593         ctx->Reset = (int (*)(void *)) arirangReset;
00594         ctx->Update = (int (*)(void *, const byte *, size_t)) arirangUpdate;
00595         ctx->Digest = (int (*)(void *, byte *)) arirangDigest;
00596         break;
00597     case PGPHASHALGO_BLAKE_224: ctx->digestsize = 224/8; goto blake;
00598     case PGPHASHALGO_BLAKE_256: ctx->digestsize = 256/8; goto blake;
00599     case PGPHASHALGO_BLAKE_384: ctx->digestsize = 384/8; goto blake;
00600     case PGPHASHALGO_BLAKE_512: ctx->digestsize = 512/8; goto blake;
00601 blake:
00602         ctx->name = "BLAKE";
00603 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00604         ctx->paramsize = sizeof(blakeParam);
00605 /*@=sizeoftype@*/
00606         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00607         (void) blakeInit(ctx->param, (int)(8 * ctx->digestsize));
00608         ctx->Reset = (int (*)(void *)) blakeReset;
00609         ctx->Update = (int (*)(void *, const byte *, size_t)) blakeUpdate;
00610         ctx->Digest = (int (*)(void *, byte *)) blakeDigest;
00611         break;
00612     case PGPHASHALGO_BMW_224: ctx->digestsize = 224/8; goto bmw;
00613     case PGPHASHALGO_BMW_256: ctx->digestsize = 256/8; goto bmw;
00614     case PGPHASHALGO_BMW_384: ctx->digestsize = 384/8; goto bmw;
00615     case PGPHASHALGO_BMW_512: ctx->digestsize = 512/8; goto bmw;
00616 bmw:
00617         ctx->name = "BMW";
00618 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00619         ctx->paramsize = sizeof(bmwParam);
00620 /*@=sizeoftype@*/
00621         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00622         (void) bmwInit(ctx->param, (int)(8 * ctx->digestsize));
00623         ctx->Reset = (int (*)(void *)) bmwReset;
00624         ctx->Update = (int (*)(void *, const byte *, size_t)) bmwUpdate;
00625         ctx->Digest = (int (*)(void *, byte *)) bmwDigest;
00626         break;
00627     case PGPHASHALGO_CHI_224: ctx->digestsize = 224/8; goto chi;
00628     case PGPHASHALGO_CHI_256: ctx->digestsize = 256/8; goto chi;
00629     case PGPHASHALGO_CHI_384: ctx->digestsize = 384/8; goto chi;
00630     case PGPHASHALGO_CHI_512: ctx->digestsize = 512/8; goto chi;
00631 chi:
00632         ctx->name = "CHI";
00633 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00634         ctx->paramsize = sizeof(chiParam);
00635 /*@=sizeoftype@*/
00636         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00637         (void) chiInit(ctx->param, (int)(8 * ctx->digestsize));
00638         ctx->Reset = (int (*)(void *)) chiReset;
00639         ctx->Update = (int (*)(void *, const byte *, size_t)) chiUpdate;
00640         ctx->Digest = (int (*)(void *, byte *)) chiDigest;
00641         break;
00642     case PGPHASHALGO_CUBEHASH_224: ctx->digestsize = 224/8; goto cubehash;
00643     case PGPHASHALGO_CUBEHASH_256: ctx->digestsize = 256/8; goto cubehash;
00644     case PGPHASHALGO_CUBEHASH_384: ctx->digestsize = 384/8; goto cubehash;
00645     case PGPHASHALGO_CUBEHASH_512: ctx->digestsize = 512/8; goto cubehash;
00646 cubehash:
00647         ctx->name = "CUBEHASH";
00648 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00649         ctx->paramsize = sizeof(cubehashParam);
00650 /*@=sizeoftype@*/
00651         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00652         (void) cubehashInit(ctx->param, (int)(8 * ctx->digestsize),
00653                                 (int)((ctx->flags >> 8) & 0xff),
00654                                 (int)((ctx->flags     ) & 0xff));
00655         ctx->Reset = (int (*)(void *)) cubehashReset;
00656         ctx->Update = (int (*)(void *, const byte *, size_t)) cubehashUpdate;
00657         ctx->Digest = (int (*)(void *, byte *)) cubehashDigest;
00658         break;
00659     case PGPHASHALGO_ECHO_224: ctx->digestsize = 224/8; goto echo;
00660     case PGPHASHALGO_ECHO_256: ctx->digestsize = 256/8; goto echo;
00661     case PGPHASHALGO_ECHO_384: ctx->digestsize = 384/8; goto echo;
00662     case PGPHASHALGO_ECHO_512: ctx->digestsize = 512/8; goto echo;
00663 echo:
00664         ctx->name = "ECHO";
00665 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00666         ctx->paramsize = sizeof(echo_hashState);
00667 /*@=sizeoftype@*/
00668         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00669         (void) echo_Init((echo_hashState *)ctx->param,
00670                                 (int)(8 * ctx->digestsize));
00671         ctx->Reset = (int (*)(void *)) noopReset;
00672         ctx->Update = (int (*)(void *, const byte *, size_t)) _echo_Update;
00673         ctx->Digest = (int (*)(void *, byte *)) echo_Final;
00674         break;
00675     case PGPHASHALGO_EDONR_224: ctx->digestsize = 224/8; goto edonr;
00676     case PGPHASHALGO_EDONR_256: ctx->digestsize = 256/8; goto edonr;
00677     case PGPHASHALGO_EDONR_384: ctx->digestsize = 384/8; goto edonr;
00678     case PGPHASHALGO_EDONR_512: ctx->digestsize = 512/8; goto edonr;
00679 edonr:
00680         ctx->name = "EDON-R";
00681 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00682         ctx->paramsize = sizeof(edonr_hashState);
00683 /*@=sizeoftype@*/
00684         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00685         (void) edonr_Init((edonr_hashState *)ctx->param,
00686                                 (int)(8 * ctx->digestsize));
00687         ctx->Reset = (int (*)(void *)) noopReset;
00688         ctx->Update = (int (*)(void *, const byte *, size_t)) edonr_Update;
00689         ctx->Digest = (int (*)(void *, byte *)) edonr_Final;
00690         break;
00691     case PGPHASHALGO_FUGUE_224: ctx->digestsize = 224/8; goto fugue;
00692     case PGPHASHALGO_FUGUE_256: ctx->digestsize = 256/8; goto fugue;
00693     case PGPHASHALGO_FUGUE_384: ctx->digestsize = 384/8; goto fugue;
00694     case PGPHASHALGO_FUGUE_512: ctx->digestsize = 512/8; goto fugue;
00695 fugue:
00696         ctx->name = "FUGUE";
00697 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00698         ctx->paramsize = sizeof(fugueParam);
00699 /*@=sizeoftype@*/
00700         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00701         (void) fugueInit(ctx->param, (int)(8 * ctx->digestsize));
00702         ctx->Reset = (int (*)(void *)) fugueReset;
00703         ctx->Update = (int (*)(void *, const byte *, size_t)) fugueUpdate;
00704         ctx->Digest = (int (*)(void *, byte *)) fugueDigest;
00705         break;
00706     case PGPHASHALGO_GROESTL_224: ctx->digestsize = 224/8; goto groestl;
00707     case PGPHASHALGO_GROESTL_256: ctx->digestsize = 256/8; goto groestl;
00708     case PGPHASHALGO_GROESTL_384: ctx->digestsize = 384/8; goto groestl;
00709     case PGPHASHALGO_GROESTL_512: ctx->digestsize = 512/8; goto groestl;
00710 groestl:
00711         ctx->name = "GROESTL";
00712 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00713         ctx->paramsize = sizeof(groestl_hashState);
00714 /*@=sizeoftype@*/
00715         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00716         (void) groestl_Init((groestl_hashState *)ctx->param,
00717                                 (int)(8 * ctx->digestsize));
00718         ctx->Reset = (int (*)(void *)) noopReset;
00719         ctx->Update = (int (*)(void *, const byte *, size_t)) _groestl_Update;
00720         ctx->Digest = (int (*)(void *, byte *)) groestl_Final;
00721         break;
00722     case PGPHASHALGO_HAMSI_224: ctx->digestsize = 224/8; goto hamsi;
00723     case PGPHASHALGO_HAMSI_256: ctx->digestsize = 256/8; goto hamsi;
00724     case PGPHASHALGO_HAMSI_384: ctx->digestsize = 384/8; goto hamsi;
00725     case PGPHASHALGO_HAMSI_512: ctx->digestsize = 512/8; goto hamsi;
00726 hamsi:
00727         ctx->name = "HAMSI";
00728 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00729         ctx->paramsize = sizeof(hamsiParam);
00730 /*@=sizeoftype@*/
00731         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00732         (void) hamsiInit(ctx->param, (int)(8 * ctx->digestsize));
00733         ctx->Reset = (int (*)(void *)) hamsiReset;
00734         ctx->Update = (int (*)(void *, const byte *, size_t)) hamsiUpdate;
00735         ctx->Digest = (int (*)(void *, byte *)) hamsiDigest;
00736         break;
00737     case PGPHASHALGO_JH_224: ctx->digestsize = 224/8; goto jh;
00738     case PGPHASHALGO_JH_256: ctx->digestsize = 256/8; goto jh;
00739     case PGPHASHALGO_JH_384: ctx->digestsize = 384/8; goto jh;
00740     case PGPHASHALGO_JH_512: ctx->digestsize = 512/8; goto jh;
00741 jh:
00742         ctx->name = "JH";
00743 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00744         ctx->paramsize = sizeof(jhParam);
00745 /*@=sizeoftype@*/
00746         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00747         (void) jhInit(ctx->param, (int)(8 * ctx->digestsize));
00748         ctx->Reset = (int (*)(void *)) jhReset;
00749         ctx->Update = (int (*)(void *, const byte *, size_t)) jhUpdate;
00750         ctx->Digest = (int (*)(void *, byte *)) jhDigest;
00751         break;
00752     case PGPHASHALGO_KECCAK_224: ctx->digestsize = 224/8; goto keccak;
00753     case PGPHASHALGO_KECCAK_256: ctx->digestsize = 256/8; goto keccak;
00754     case PGPHASHALGO_KECCAK_384: ctx->digestsize = 384/8; goto keccak;
00755     case PGPHASHALGO_KECCAK_512: ctx->digestsize = 512/8; goto keccak;
00756 keccak:
00757         ctx->name = "KECCAK";
00758 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00759         ctx->paramsize = sizeof(keccak_hashState);
00760 /*@=sizeoftype@*/
00761         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00762         (void) keccak_Init((keccak_hashState *)ctx->param,
00763                                 (int)(8 * ctx->digestsize));
00764         ctx->Reset = (int (*)(void *)) noopReset;
00765         ctx->Update = (int (*)(void *, const byte *, size_t)) _keccak_Update;
00766         ctx->Digest = (int (*)(void *, byte *)) keccak_Final;
00767         break;
00768     case PGPHASHALGO_LANE_224: ctx->digestsize = 224/8; goto lane;
00769     case PGPHASHALGO_LANE_256: ctx->digestsize = 256/8; goto lane;
00770     case PGPHASHALGO_LANE_384: ctx->digestsize = 384/8; goto lane;
00771     case PGPHASHALGO_LANE_512: ctx->digestsize = 512/8; goto lane;
00772 lane:
00773         ctx->name = "LANE";
00774 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00775         ctx->paramsize = sizeof(laneParam);
00776 /*@=sizeoftype@*/
00777         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00778         (void) laneInit(ctx->param, (int)(8 * ctx->digestsize));
00779         ctx->Reset = (int (*)(void *)) laneReset;
00780         ctx->Update = (int (*)(void *, const byte *, size_t)) laneUpdate;
00781         ctx->Digest = (int (*)(void *, byte *)) laneDigest;
00782         break;
00783     case PGPHASHALGO_LUFFA_224: ctx->digestsize = 224/8; goto luffa;
00784     case PGPHASHALGO_LUFFA_256: ctx->digestsize = 256/8; goto luffa;
00785     case PGPHASHALGO_LUFFA_384: ctx->digestsize = 384/8; goto luffa;
00786     case PGPHASHALGO_LUFFA_512: ctx->digestsize = 512/8; goto luffa;
00787 luffa:
00788         ctx->name = "LUFFA";
00789 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00790         ctx->paramsize = sizeof(luffaParam);
00791 /*@=sizeoftype@*/
00792         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00793         (void) luffaInit(ctx->param, (int)(8 * ctx->digestsize));
00794         ctx->Reset = (int (*)(void *)) luffaReset;
00795         ctx->Update = (int (*)(void *, const byte *, size_t)) luffaUpdate;
00796         ctx->Digest = (int (*)(void *, byte *)) luffaDigest;
00797         break;
00798     case PGPHASHALGO_MD6_224: ctx->digestsize = 224/8; goto md6;
00799     case PGPHASHALGO_MD6_256: ctx->digestsize = 256/8; goto md6;
00800     case PGPHASHALGO_MD6_384: ctx->digestsize = 384/8; goto md6;
00801     case PGPHASHALGO_MD6_512: ctx->digestsize = 512/8; goto md6;
00802 md6:
00803         ctx->name = "MD6";
00804 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00805         ctx->paramsize = sizeof(md6_state);
00806 /*@=sizeoftype@*/
00807         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00808         {   int d = (8 * ctx->digestsize);      /* no. of bits in digest */
00809             int L = md6_default_L;              /* no. of parallel passes */
00810             unsigned char *K = NULL;            /* key */
00811             int keylen = 0;                     /* key length (bytes) */
00812             int r = md6_default_r(d, keylen);   /* no. of rounds */
00813 
00814             if (ctx->flags != 0) {
00815                 r = ((ctx->flags >> 8) & 0xffff);
00816                 L = ((ctx->flags     ) & 0xff);
00817                 if (r <= 0 || r > 255) r = md6_default_r(d, keylen);
00818             }
00819             (void) md6_full_init((md6_state *)ctx->param,
00820                         d, K, keylen, L, r);
00821         }
00822         ctx->Reset = (int (*)(void *)) noopReset;
00823         ctx->Update = (int (*)(void *, const byte *, size_t)) md6_Update;
00824         ctx->Digest = (int (*)(void *, byte *)) md6_final;
00825         break;
00826 #ifdef  NOTYET
00827     case PGPHASHALGO_SHABAL_192: ctx->digestsize = 192/8; goto shabal;
00828 #endif
00829     case PGPHASHALGO_SHABAL_224: ctx->digestsize = 224/8; goto shabal;
00830     case PGPHASHALGO_SHABAL_256: ctx->digestsize = 256/8; goto shabal;
00831     case PGPHASHALGO_SHABAL_384: ctx->digestsize = 384/8; goto shabal;
00832     case PGPHASHALGO_SHABAL_512: ctx->digestsize = 512/8; goto shabal;
00833 shabal:
00834         ctx->name = "SHABAL";
00835 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00836         ctx->paramsize = sizeof(shabalParam);
00837 /*@=sizeoftype@*/
00838         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00839         (void) shabalInit(ctx->param, (int)(8 * ctx->digestsize));
00840         ctx->Reset = (int (*)(void *)) shabalReset;
00841         ctx->Update = (int (*)(void *, const byte *, size_t)) shabalUpdate;
00842         ctx->Digest = (int (*)(void *, byte *)) shabalDigest;
00843         break;
00844     case PGPHASHALGO_SHAVITE3_224: ctx->digestsize = 224/8; goto shavite3;
00845     case PGPHASHALGO_SHAVITE3_256: ctx->digestsize = 256/8; goto shavite3;
00846     case PGPHASHALGO_SHAVITE3_384: ctx->digestsize = 384/8; goto shavite3;
00847     case PGPHASHALGO_SHAVITE3_512: ctx->digestsize = 512/8; goto shavite3;
00848 shavite3:
00849         ctx->name = "SHAVITE3";
00850 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00851         ctx->paramsize = sizeof(shavite3_hashState);
00852 /*@=sizeoftype@*/
00853         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00854         (void) shavite3_Init((shavite3_hashState *)ctx->param,
00855                                 (int)(8 * ctx->digestsize));
00856         ctx->Reset = (int (*)(void *)) noopReset;
00857         ctx->Update = (int (*)(void *, const byte *, size_t)) _shavite3_Update;
00858         ctx->Digest = (int (*)(void *, byte *)) shavite3_Final;
00859         break;
00860     case PGPHASHALGO_SIMD_224: ctx->digestsize = 224/8; goto simd;
00861     case PGPHASHALGO_SIMD_256: ctx->digestsize = 256/8; goto simd;
00862     case PGPHASHALGO_SIMD_384: ctx->digestsize = 384/8; goto simd;
00863     case PGPHASHALGO_SIMD_512: ctx->digestsize = 512/8; goto simd;
00864 simd:
00865         ctx->name = "SIMD";
00866 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00867         ctx->paramsize = sizeof(simd_hashState);
00868 /*@=sizeoftype@*/
00869         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00870         (void) simd_Init((simd_hashState *)ctx->param,
00871                                 (int)(8 * ctx->digestsize));
00872         ctx->Reset = (int (*)(void *)) noopReset;
00873         ctx->Update = (int (*)(void *, const byte *, size_t)) _simd_Update;
00874         ctx->Digest = (int (*)(void *, byte *)) simd_Final;
00875         break;
00876     case PGPHASHALGO_TIB3_224: ctx->digestsize = 224/8; goto tib3;
00877     case PGPHASHALGO_TIB3_256: ctx->digestsize = 256/8; goto tib3;
00878     case PGPHASHALGO_TIB3_384: ctx->digestsize = 384/8; goto tib3;
00879     case PGPHASHALGO_TIB3_512: ctx->digestsize = 512/8; goto tib3;
00880 tib3:
00881         ctx->name = "TIB3";
00882 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00883         ctx->paramsize = sizeof(tib3_hashState);
00884 /*@=sizeoftype@*/
00885         ctx->param = DRD_xcalloc(1, ctx->paramsize);
00886         (void) tib3_Init((tib3_hashState *)ctx->param,
00887                                 (int)(8 * ctx->digestsize));
00888         ctx->Reset = (int (*)(void *)) noopReset;
00889         ctx->Update = (int (*)(void *, const byte *, size_t)) _tib3_Update;
00890         ctx->Digest = (int (*)(void *, byte *)) tib3_Final;
00891         break;
00892     case PGPHASHALGO_HAVAL_5_160:
00893     default:
00894         (void)rpmioFreePoolItem((rpmioItem)ctx, __FUNCTION__, __FILE__, __LINE__);
00895         return NULL;
00896         /*@notreached@*/ break;
00897     }
00898 
00899     xx = (*ctx->Reset) (ctx->param);
00900 
00901 DPRINTF((stderr, "==> ctx %p ==== Init(%s, %x) param %p\n", ctx, ctx->name, flags, ctx->param));
00902     return (DIGEST_CTX)rpmioLinkPoolItem((rpmioItem)ctx, __FUNCTION__, __FILE__, __LINE__);
00903 }
00904 
00905 /*@-mustmod@*/ /* LCL: ctx->param may be modified, but ctx is abstract @*/
00906 int
00907 rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
00908 {
00909     if (ctx == NULL)
00910         return -1;
00911 
00912 DPRINTF((stderr, "==> ctx %p ==== Update(%s,%p[%u]) param %p\n", ctx, ctx->name, data, (unsigned)len, ctx->param));
00913     return (*ctx->Update) (ctx->param, data, len);
00914 }
00915 /*@=mustmod@*/
00916 
00917 #define HMAC_IPAD       0x36
00918 #define HMAC_OPAD       0x5c
00919 
00920 int
00921 rpmDigestFinal(DIGEST_CTX ctx, void * datap, size_t *lenp, int asAscii)
00922 {
00923     byte * digest;
00924     char * t;
00925 
00926     if (ctx == NULL)
00927         return -1;
00928     digest = DRD_xmalloc(ctx->digestsize);
00929 
00930 DPRINTF((stderr, "==> ctx %p ==== Final(%s,%p,%p,%d) param %p digest %p[%u]\n", ctx, ctx->name, datap, lenp, asAscii, ctx->param, digest, (unsigned)ctx->digestsize));
00931 /*@-noeffectuncon@*/ /* FIX: check rc */
00932     (void) (*ctx->Digest) (ctx->param, digest);
00933 /*@=noeffectuncon@*/
00934 
00935     /* If keyed HMAC, re-hash with key material. */
00936     if (ctx->salt != NULL) {
00937         DIGEST_CTX kctx = rpmDigestInit(ctx->hashalgo, RPMDIGEST_NONE);
00938         byte * salt = ctx->salt;
00939         byte * kdigest = NULL;
00940         size_t kdigestlen = 0;
00941         unsigned i;
00942         for (i = 0; i < ctx->blocksize; i++)
00943             salt[i] ^= HMAC_OPAD;
00944         rpmDigestUpdate(kctx, ctx->salt, ctx->blocksize);
00945         ctx->salt = _free(ctx->salt);
00946         rpmDigestUpdate(kctx, digest, ctx->digestsize);
00947         (void) rpmDigestFinal(kctx, &kdigest, &kdigestlen, 0);
00948         memcpy(digest, kdigest, kdigestlen);
00949         kdigest = _free(kdigest);
00950     }
00951 
00952     /* Return final digest. */
00953     if (!asAscii) {
00954         if (lenp) *lenp = ctx->digestsize;
00955         if (datap) {
00956             *(byte **)datap = digest;
00957             digest = NULL;
00958         }
00959     } else {
00960         if (lenp) *lenp = (2*ctx->digestsize);
00961         if (datap) {
00962             const byte * s = (const byte *) digest;
00963             static const char hex[] = "0123456789abcdef";
00964             size_t i;
00965 
00966             *(char **)datap = t = DRD_xmalloc((2*ctx->digestsize) + 1);
00967             for (i = 0 ; i < ctx->digestsize; i++) {
00968                 *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
00969                 *t++ = hex[ (unsigned)((*s++   ) & 0x0f) ];
00970             }
00971             *t = '\0';
00972         }
00973     }
00974     if (digest) {
00975         memset(digest, 0, ctx->digestsize);     /* In case it's sensitive */
00976         free(digest);
00977     }
00978     (void)rpmioFreePoolItem((rpmioItem)ctx, __FUNCTION__, __FILE__, __LINE__);
00979     return 0;
00980 }
00981 
00982 int
00983 rpmHmacInit(DIGEST_CTX ctx, const void * key, size_t keylen)
00984 {
00985     int rc = 0;
00986 
00987     if (ctx == NULL)
00988         return -1;
00989     if (key != NULL) {
00990         byte * salt = DRD_xcalloc(1, ctx->blocksize);
00991         unsigned i;
00992         if (keylen == 0) keylen = strlen(key);
00993         ctx->salt = salt;
00994 DPRINTF((stderr, "==> ctx %p ==== HMAC(%s,%p[%u])\n", ctx, ctx->name, key, (unsigned)keylen));
00995         if (keylen > ctx->blocksize) {
00996             /* If key is larger than digestlen, then hash the material. */
00997             DIGEST_CTX kctx = rpmDigestInit(ctx->hashalgo, RPMDIGEST_NONE);
00998             byte * kdigest = NULL;
00999             size_t kdigestlen = 0;
01000             rpmDigestUpdate(kctx, key, keylen);
01001             (void) rpmDigestFinal(kctx, &kdigest, &kdigestlen, 0);
01002             memcpy(ctx->salt, kdigest, kdigestlen);
01003             kdigest = _free(kdigest);
01004         } else
01005             memcpy(ctx->salt, key, keylen);
01006 
01007         salt = ctx->salt;
01008         for (i = 0; i < ctx->blocksize; i++)
01009             salt[i] ^= HMAC_IPAD;
01010         rpmDigestUpdate(ctx, ctx->salt, ctx->blocksize);
01011         for (i = 0; i < ctx->blocksize; i++)
01012             salt[i] ^= HMAC_IPAD;
01013     }
01014     return rc;
01015 }