00001
00005 #include "system.h"
00006 #include "rpmio_internal.h"
00007 #include "debug.h"
00008
00009 #ifdef SHA_DEBUG
00010 #define DPRINTF(_a) fprintf _a
00011 #else
00012 #define DPRINTF(_a)
00013 #endif
00014
00015
00016
00020 struct DIGEST_CTX_s {
00021 rpmDigestFlags flags;
00022 uint32_t datalen;
00023 uint32_t paramlen;
00024 uint32_t digestlen;
00025 void * param;
00026 int (*Reset) (void * param)
00027 ;
00028 int (*Update) (void * param, const byte * data, size_t size)
00029 ;
00030 int (*Digest) (void * param, byte * digest)
00031 ;
00032 };
00033
00034
00035 DIGEST_CTX
00036 rpmDigestDup(DIGEST_CTX octx)
00037 {
00038 DIGEST_CTX nctx;
00039 nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
00040 nctx->param = memcpy(xcalloc(1, nctx->paramlen), octx->param, nctx->paramlen);
00041 return nctx;
00042 }
00043
00044
00045 DIGEST_CTX
00046 rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
00047 {
00048 DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx));
00049 int xx;
00050
00051 ctx->flags = flags;
00052
00053 switch (hashalgo) {
00054 case PGPHASHALGO_MD5:
00055 ctx->digestlen = 16;
00056 ctx->datalen = 64;
00057
00058 ctx->paramlen = sizeof(md5Param);
00059
00060 ctx->param = xcalloc(1, ctx->paramlen);
00061
00062 ctx->Reset = (void *) md5Reset;
00063 ctx->Update = (void *) md5Update;
00064 ctx->Digest = (void *) md5Digest;
00065
00066 break;
00067 case PGPHASHALGO_SHA1:
00068 ctx->digestlen = 20;
00069 ctx->datalen = 64;
00070
00071 ctx->paramlen = sizeof(sha1Param);
00072
00073 ctx->param = xcalloc(1, ctx->paramlen);
00074
00075 ctx->Reset = (void *) sha1Reset;
00076 ctx->Update = (void *) sha1Update;
00077 ctx->Digest = (void *) sha1Digest;
00078
00079 break;
00080 #if HAVE_BEECRYPT_API_H
00081 case PGPHASHALGO_SHA256:
00082 ctx->digestlen = 32;
00083 ctx->datalen = 64;
00084
00085 ctx->paramlen = sizeof(sha256Param);
00086
00087 ctx->param = xcalloc(1, ctx->paramlen);
00088
00089 ctx->Reset = (void *) sha256Reset;
00090 ctx->Update = (void *) sha256Update;
00091 ctx->Digest = (void *) sha256Digest;
00092
00093 break;
00094 case PGPHASHALGO_SHA384:
00095 ctx->digestlen = 48;
00096 ctx->datalen = 128;
00097
00098 ctx->paramlen = sizeof(sha384Param);
00099
00100 ctx->param = xcalloc(1, ctx->paramlen);
00101
00102 ctx->Reset = (void *) sha384Reset;
00103 ctx->Update = (void *) sha384Update;
00104 ctx->Digest = (void *) sha384Digest;
00105
00106 break;
00107 case PGPHASHALGO_SHA512:
00108 ctx->digestlen = 64;
00109 ctx->datalen = 128;
00110
00111 ctx->paramlen = sizeof(sha512Param);
00112
00113 ctx->param = xcalloc(1, ctx->paramlen);
00114
00115 ctx->Reset = (void *) sha512Reset;
00116 ctx->Update = (void *) sha512Update;
00117 ctx->Digest = (void *) sha512Digest;
00118
00119 break;
00120 #endif
00121 case PGPHASHALGO_RIPEMD160:
00122 case PGPHASHALGO_MD2:
00123 case PGPHASHALGO_TIGER192:
00124 case PGPHASHALGO_HAVAL_5_160:
00125 default:
00126 free(ctx);
00127 return NULL;
00128 break;
00129 }
00130
00131
00132 xx = (*ctx->Reset) (ctx->param);
00133
00134
00135 DPRINTF((stderr, "*** Init(%x) ctx %p param %p\n", flags, ctx, ctx->param));
00136 return ctx;
00137 }
00138
00139
00140 int
00141 rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
00142 {
00143 if (ctx == NULL)
00144 return -1;
00145
00146 DPRINTF((stderr, "*** Update(%p,%p,%d) param %p \"%s\"\n", ctx, data, len, ctx->param, ((char *)data)));
00147
00148 return (*ctx->Update) (ctx->param, data, len);
00149
00150 }
00151
00152
00153
00154 int
00155 rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
00156 {
00157 byte * digest;
00158 char * t;
00159 int i;
00160
00161 if (ctx == NULL)
00162 return -1;
00163 digest = xmalloc(ctx->digestlen);
00164
00165 DPRINTF((stderr, "*** Final(%p,%p,%p,%d) param %p digest %p\n", ctx, datap, lenp, asAscii, ctx->param, digest));
00166
00167 (void) (*ctx->Digest) (ctx->param, digest);
00168
00169
00170
00171
00172 if (!asAscii) {
00173 if (lenp) *lenp = ctx->digestlen;
00174 if (datap) {
00175 *datap = digest;
00176 digest = NULL;
00177 }
00178 } else {
00179 if (lenp) *lenp = (2*ctx->digestlen) + 1;
00180 if (datap) {
00181 const byte * s = (const byte *) digest;
00182 static const char hex[] = "0123456789abcdef";
00183
00184 *datap = t = xmalloc((2*ctx->digestlen) + 1);
00185 for (i = 0 ; i < ctx->digestlen; i++) {
00186 *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
00187 *t++ = hex[ (unsigned)((*s++ ) & 0x0f) ];
00188 }
00189 *t = '\0';
00190 }
00191 }
00192
00193 if (digest) {
00194 memset(digest, 0, ctx->digestlen);
00195 free(digest);
00196 }
00197 memset(ctx->param, 0, ctx->paramlen);
00198 free(ctx->param);
00199 memset(ctx, 0, sizeof(*ctx));
00200 free(ctx);
00201 return 0;
00202 }
00203