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
00032 #define _JLU3_jlu32l
00033 #include "lookup3.c"
00034
00035
00036
00040 struct DIGEST_CTX_s {
00041
00042 const char * name;
00043 size_t paramsize;
00044 size_t datasize;
00045 size_t digestsize;
00046 int (*Reset) (void * param)
00047 ;
00048 int (*Update) (void * param, const byte * data, size_t size)
00049 ;
00050 int (*Digest) (void * param, byte * digest)
00051 ;
00052 pgpHashAlgo hashalgo;
00053 rpmDigestFlags flags;
00054
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
00099 ctx->paramsize = sizeof(md5Param);
00100
00101 ctx->param = xcalloc(1, ctx->paramsize);
00102
00103 ctx->Reset = (int (*)(void *)) md5Reset;
00104 ctx->Update = (int (*)(void *, const byte *, size_t)) md5Update;
00105 ctx->Digest = (int (*)(void *, byte *)) md5Digest;
00106
00107 ctx->asn1 = "3020300c06082a864886f70d020505000410";
00108 break;
00109 case PGPHASHALGO_SHA1:
00110 ctx->name = "SHA1";
00111 ctx->digestsize = 160/8;
00112 ctx->datasize = 64;
00113
00114 ctx->paramsize = sizeof(sha1Param);
00115
00116 ctx->param = xcalloc(1, ctx->paramsize);
00117
00118 ctx->Reset = (int (*)(void *)) sha1Reset;
00119 ctx->Update = (int (*)(void *, const byte *, size_t)) sha1Update;
00120 ctx->Digest = (int (*)(void *, byte *)) sha1Digest;
00121
00122 ctx->asn1 = "3021300906052b0e03021a05000414";
00123 break;
00124 case PGPHASHALGO_RIPEMD128:
00125 ctx->name = "RIPEMD128";
00126 ctx->digestsize = 128/8;
00127 ctx->datasize = 64;
00128
00129 ctx->paramsize = sizeof(rmd128Param);
00130
00131 ctx->param = xcalloc(1, ctx->paramsize);
00132
00133 ctx->Reset = (int (*)(void *)) rmd128Reset;
00134 ctx->Update = (int (*)(void *, const byte *, size_t)) rmd128Update;
00135 ctx->Digest = (int (*)(void *, byte *)) rmd128Digest;
00136
00137 break;
00138 case PGPHASHALGO_RIPEMD160:
00139 ctx->name = "RIPEMD160";
00140 ctx->digestsize = 160/8;
00141 ctx->datasize = 64;
00142
00143 ctx->paramsize = sizeof(rmd160Param);
00144
00145 ctx->param = xcalloc(1, ctx->paramsize);
00146
00147 ctx->Reset = (int (*)(void *)) rmd160Reset;
00148 ctx->Update = (int (*)(void *, const byte *, size_t)) rmd160Update;
00149 ctx->Digest = (int (*)(void *, byte *)) rmd160Digest;
00150
00151 ctx->asn1 = "3021300906052b2403020105000414";
00152 break;
00153 case PGPHASHALGO_RIPEMD256:
00154 ctx->name = "RIPEMD256";
00155 ctx->digestsize = 256/8;
00156 ctx->datasize = 64;
00157
00158 ctx->paramsize = sizeof(rmd256Param);
00159
00160 ctx->param = xcalloc(1, ctx->paramsize);
00161
00162 ctx->Reset = (int (*)(void *)) rmd256Reset;
00163 ctx->Update = (int (*)(void *, const byte *, size_t)) rmd256Update;
00164 ctx->Digest = (int (*)(void *, byte *)) rmd256Digest;
00165
00166 break;
00167 case PGPHASHALGO_RIPEMD320:
00168 ctx->name = "RIPEMD320";
00169 ctx->digestsize = 320/8;
00170 ctx->datasize = 64;
00171
00172 ctx->paramsize = sizeof(rmd320Param);
00173
00174 ctx->param = xcalloc(1, ctx->paramsize);
00175
00176 ctx->Reset = (int (*)(void *)) rmd320Reset;
00177 ctx->Update = (int (*)(void *, const byte *, size_t)) rmd320Update;
00178 ctx->Digest = (int (*)(void *, byte *)) rmd320Digest;
00179
00180 break;
00181 case PGPHASHALGO_SALSA10:
00182 ctx->name = "SALSA10";
00183 ctx->digestsize = 512/8;
00184 ctx->datasize = 64;
00185
00186 ctx->paramsize = sizeof(salsa10Param);
00187
00188 ctx->param = xcalloc(1, ctx->paramsize);
00189
00190 ctx->Reset = (int (*)(void *)) salsa10Reset;
00191 ctx->Update = (int (*)(void *, const byte *, size_t)) salsa10Update;
00192 ctx->Digest = (int (*)(void *, byte *)) salsa10Digest;
00193
00194 break;
00195 case PGPHASHALGO_SALSA20:
00196 ctx->name = "SALSA20";
00197 ctx->digestsize = 512/8;
00198 ctx->datasize = 64;
00199
00200 ctx->paramsize = sizeof(salsa20Param);
00201
00202 ctx->param = xcalloc(1, ctx->paramsize);
00203
00204 ctx->Reset = (int (*)(void *)) salsa20Reset;
00205 ctx->Update = (int (*)(void *, const byte *, size_t)) salsa20Update;
00206 ctx->Digest = (int (*)(void *, byte *)) salsa20Digest;
00207
00208 break;
00209 case PGPHASHALGO_TIGER192:
00210 ctx->name = "TIGER192";
00211 ctx->digestsize = 192/8;
00212 ctx->datasize = 64;
00213
00214 ctx->paramsize = sizeof(tigerParam);
00215
00216 ctx->param = xcalloc(1, ctx->paramsize);
00217
00218 ctx->Reset = (int (*)(void *)) tigerReset;
00219 ctx->Update = (int (*)(void *, const byte *, size_t)) tigerUpdate;
00220 ctx->Digest = (int (*)(void *, byte *)) tigerDigest;
00221
00222 ctx->asn1 = "3029300d06092b06010401da470c0205000418";
00223 break;
00224 case PGPHASHALGO_MD2:
00225 ctx->name = "MD2";
00226 ctx->digestsize = 128/8;
00227 ctx->datasize = 16;
00228
00229 ctx->paramsize = sizeof(md2Param);
00230
00231 ctx->param = xcalloc(1, ctx->paramsize);
00232
00233 ctx->Reset = (int (*)(void *)) md2Reset;
00234 ctx->Update = (int (*)(void *, const byte *, size_t)) md2Update;
00235 ctx->Digest = (int (*)(void *, byte *)) md2Digest;
00236
00237 ctx->asn1 = "3020300c06082a864886f70d020205000410";
00238 break;
00239 case PGPHASHALGO_MD4:
00240 ctx->name = "MD4";
00241 ctx->digestsize = 128/8;
00242 ctx->datasize = 64;
00243
00244 ctx->paramsize = sizeof(md4Param);
00245
00246 ctx->param = xcalloc(1, ctx->paramsize);
00247
00248 ctx->Reset = (int (*)(void *)) md4Reset;
00249 ctx->Update = (int (*)(void *, const byte *, size_t)) md4Update;
00250 ctx->Digest = (int (*)(void *, byte *)) md4Digest;
00251
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
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
00262 ctx->paramsize = sizeof(*mp);
00263 ctx->param = mp;
00264 }
00265
00266 ctx->Reset = (int (*)(void *)) sum32Reset;
00267 ctx->Update = (int (*)(void *, const byte *, size_t)) sum32Update;
00268 ctx->Digest = (int (*)(void *, byte *)) sum32Digest;
00269
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
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
00280 ctx->paramsize = sizeof(*mp);
00281 ctx->param = mp;
00282 }
00283
00284 ctx->Reset = (int (*)(void *)) sum32Reset;
00285 ctx->Update = (int (*)(void *, const byte *, size_t)) sum32Update;
00286 ctx->Digest = (int (*)(void *, byte *)) sum32Digest;
00287
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
00295 mp->update = (rpmuint32_t (*)(rpmuint32_t, const byte *, size_t)) jlu32l;
00296
00297 ctx->paramsize = sizeof(*mp);
00298 ctx->param = mp;
00299 }
00300
00301 ctx->Reset = (int (*)(void *)) sum32Reset;
00302 ctx->Update = (int (*)(void *, const byte *, size_t)) sum32Update;
00303 ctx->Digest = (int (*)(void *, byte *)) sum32Digest;
00304
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
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
00315 ctx->paramsize = sizeof(*mp);
00316 ctx->param = mp;
00317 }
00318
00319 ctx->Reset = (int (*)(void *)) sum64Reset;
00320 ctx->Update = (int (*)(void *, const byte *, size_t)) sum64Update;
00321 ctx->Digest = (int (*)(void *, byte *)) sum64Digest;
00322
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
00330 ctx->paramsize = sizeof(sha224Param);
00331
00332 ctx->param = xcalloc(1, ctx->paramsize);
00333
00334 ctx->Reset = (int (*)(void *)) sha224Reset;
00335 ctx->Update = (int (*)(void *, const byte *, size_t)) sha224Update;
00336 ctx->Digest = (int (*)(void *, byte *)) sha224Digest;
00337
00338 ctx->asn1 = "302d300d06096086480165030402040500041C";
00339 break;
00340 case PGPHASHALGO_SHA256:
00341 ctx->name = "SHA256";
00342 ctx->digestsize = 256/8;
00343 ctx->datasize = 64;
00344
00345 ctx->paramsize = sizeof(sha256Param);
00346
00347 ctx->param = xcalloc(1, ctx->paramsize);
00348
00349 ctx->Reset = (int (*)(void *)) sha256Reset;
00350 ctx->Update = (int (*)(void *, const byte *, size_t)) sha256Update;
00351 ctx->Digest = (int (*)(void *, byte *)) sha256Digest;
00352
00353 ctx->asn1 = "3031300d060960864801650304020105000420";
00354 break;
00355 case PGPHASHALGO_SHA384:
00356 ctx->name = "SHA384";
00357 ctx->digestsize = 384/8;
00358 ctx->datasize = 128;
00359
00360 ctx->paramsize = sizeof(sha384Param);
00361
00362 ctx->param = xcalloc(1, ctx->paramsize);
00363
00364 ctx->Reset = (int (*)(void *)) sha384Reset;
00365 ctx->Update = (int (*)(void *, const byte *, size_t)) sha384Update;
00366 ctx->Digest = (int (*)(void *, byte *)) sha384Digest;
00367
00368 ctx->asn1 = "3041300d060960864801650304020205000430";
00369 break;
00370 case PGPHASHALGO_SHA512:
00371 ctx->name = "SHA512";
00372 ctx->digestsize = 512/8;
00373 ctx->datasize = 128;
00374
00375 ctx->paramsize = sizeof(sha512Param);
00376
00377 ctx->param = xcalloc(1, ctx->paramsize);
00378
00379 ctx->Reset = (int (*)(void *)) sha512Reset;
00380 ctx->Update = (int (*)(void *, const byte *, size_t)) sha512Update;
00381 ctx->Digest = (int (*)(void *, byte *)) sha512Digest;
00382
00383 ctx->asn1 = "3051300d060960864801650304020305000440";
00384 break;
00385 #endif
00386 case PGPHASHALGO_HAVAL_5_160:
00387 default:
00388 free(ctx);
00389 return NULL;
00390 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
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
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
00423 (void) (*ctx->Digest) (ctx->param, digest);
00424
00425
00426
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);
00450 free(digest);
00451 }
00452 memset(ctx->param, 0, ctx->paramsize);
00453 free(ctx->param);
00454 memset(ctx, 0, sizeof(*ctx));
00455 free(ctx);
00456 return 0;
00457 }