rpm 5.3.7

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