6 #include "rpmio_internal.h"
10 #define DPRINTF(_a) fprintf _a
15 /*@access DIGEST_CTX@*/
18 * MD5/SHA1 digest private data.
21 rpmDigestFlags flags; /*!< Bit(s) to control digest operation. */
22 uint32 datalen; /*!< No. bytes in block of plaintext data. */
23 uint32 paramlen; /*!< No. bytes of digest parameters. */
24 uint32 digestlen; /*!< No. bytes of digest. */
25 void * param; /*!< Digest parameters. */
26 int (*Reset) (void * param)
27 /*@modifies param @*/; /*!< Digest initialize. */
28 int (*Update) (void * param, const byte * data, int len)
29 /*@modifies param @*/; /*!< Digest transform. */
30 int (*Digest) (void * param, /*@out@*/ uint32 * digest)
31 /*@modifies param, digest @*/; /*!< Digest finish. */
36 rpmDigestDup(DIGEST_CTX octx)
39 nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
40 nctx->param = memcpy(xcalloc(1, nctx->paramlen), octx->param, nctx->paramlen);
46 rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
48 DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx));
57 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
58 ctx->paramlen = sizeof(md5Param);
60 ctx->param = xcalloc(1, ctx->paramlen);
61 /*@-type@*/ /* FIX: cast? */
62 ctx->Reset = (void *) md5Reset;
63 ctx->Update = (void *) md5Update;
64 ctx->Digest = (void *) md5Digest;
67 case PGPHASHALGO_SHA1:
70 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
71 ctx->paramlen = sizeof(sha1Param);
73 ctx->param = xcalloc(1, ctx->paramlen);
74 /*@-type@*/ /* FIX: cast? */
75 ctx->Reset = (void *) sha1Reset;
76 ctx->Update = (void *) sha1Update;
77 ctx->Digest = (void *) sha1Digest;
80 case PGPHASHALGO_RIPEMD160:
82 case PGPHASHALGO_TIGER192:
83 case PGPHASHALGO_HAVAL_5_160:
87 /*@notreached@*/ break;
91 xx = (*ctx->Reset) (ctx->param);
94 DPRINTF((stderr, "*** Init(%x) ctx %p param %p\n", flags, ctx, ctx->param));
98 /*@-mustmod@*/ /* LCL: ctx->param may be modified, but ctx is abstract @*/
100 rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
105 DPRINTF((stderr, "*** Update(%p,%p,%d) param %p \"%s\"\n", ctx, data, len, ctx->param, ((char *)data)));
107 return (*ctx->Update) (ctx->param, data, len);
113 static int _ie = 0x44332211;
117 static union _dendian {
120 } *_endian = (union _dendian *)&_ie;
123 #define IS_BIG_ENDIAN() (_endian->b[0] == '\x44')
124 #define IS_LITTLE_ENDIAN() (_endian->b[0] == '\x11')
128 rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
136 digest = xmalloc(ctx->digestlen);
138 DPRINTF((stderr, "*** Final(%p,%p,%p,%d) param %p digest %p\n", ctx, datap, lenp, asAscii, ctx->param, digest));
139 /*@-noeffectuncon@*/ /* FIX: check rc */
140 (void) (*ctx->Digest) (ctx->param, digest);
144 if (IS_LITTLE_ENDIAN())
145 for (i = 0; i < (ctx->digestlen/sizeof(uint32)); i++)
146 digest[i] = swapu32(digest[i]);
149 /* Return final digest. */
152 if (lenp) *lenp = ctx->digestlen;
158 if (lenp) *lenp = (2*ctx->digestlen) + 1;
160 const byte * s = (const byte *) digest;
161 static const char hex[] = "0123456789abcdef";
163 *datap = t = xmalloc((2*ctx->digestlen) + 1);
164 for (i = 0 ; i < ctx->digestlen; i++) {
165 *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
166 *t++ = hex[ (unsigned)((*s++ ) & 0x0f) ];
173 memset(digest, 0, ctx->digestlen); /* In case it's sensitive */
176 memset(ctx->param, 0, ctx->paramlen); /* In case it's sensitive */
178 memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */