rpmio/digest.c

Go to the documentation of this file.
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 /*@access DIGEST_CTX@*/
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         /*@modifies param @*/;  
00028     int (*Update) (void * param, const byte * data, size_t size)
00029         /*@modifies param @*/;  
00030     int (*Digest) (void * param, /*@out@*/ byte * digest)
00031         /*@modifies param, digest @*/;  
00032 };
00033 
00034 /*@-boundsread@*/
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 /*@=boundsread@*/
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 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00058         ctx->paramlen = sizeof(md5Param);
00059 /*@=sizeoftype@*/
00060         ctx->param = xcalloc(1, ctx->paramlen);
00061 /*@-type@*/ /* FIX: cast? */
00062         ctx->Reset = (void *) md5Reset;
00063         ctx->Update = (void *) md5Update;
00064         ctx->Digest = (void *) md5Digest;
00065 /*@=type@*/
00066         break;
00067     case PGPHASHALGO_SHA1:
00068         ctx->digestlen = 20;
00069         ctx->datalen = 64;
00070 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00071         ctx->paramlen = sizeof(sha1Param);
00072 /*@=sizeoftype@*/
00073         ctx->param = xcalloc(1, ctx->paramlen);
00074 /*@-type@*/ /* FIX: cast? */
00075         ctx->Reset = (void *) sha1Reset;
00076         ctx->Update = (void *) sha1Update;
00077         ctx->Digest = (void *) sha1Digest;
00078 /*@=type@*/
00079         break;
00080 #if HAVE_BEECRYPT_API_H
00081     case PGPHASHALGO_SHA256:
00082         ctx->digestlen = 32;
00083         ctx->datalen = 64;
00084 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00085         ctx->paramlen = sizeof(sha256Param);
00086 /*@=sizeoftype@*/
00087         ctx->param = xcalloc(1, ctx->paramlen);
00088 /*@-type@*/ /* FIX: cast? */
00089         ctx->Reset = (void *) sha256Reset;
00090         ctx->Update = (void *) sha256Update;
00091         ctx->Digest = (void *) sha256Digest;
00092 /*@=type@*/
00093         break;
00094     case PGPHASHALGO_SHA384:
00095         ctx->digestlen = 48;
00096         ctx->datalen = 128;
00097 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00098         ctx->paramlen = sizeof(sha384Param);
00099 /*@=sizeoftype@*/
00100         ctx->param = xcalloc(1, ctx->paramlen);
00101 /*@-type@*/ /* FIX: cast? */
00102         ctx->Reset = (void *) sha384Reset;
00103         ctx->Update = (void *) sha384Update;
00104         ctx->Digest = (void *) sha384Digest;
00105 /*@=type@*/
00106         break;
00107     case PGPHASHALGO_SHA512:
00108         ctx->digestlen = 64;
00109         ctx->datalen = 128;
00110 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00111         ctx->paramlen = sizeof(sha512Param);
00112 /*@=sizeoftype@*/
00113         ctx->param = xcalloc(1, ctx->paramlen);
00114 /*@-type@*/ /* FIX: cast? */
00115         ctx->Reset = (void *) sha512Reset;
00116         ctx->Update = (void *) sha512Update;
00117         ctx->Digest = (void *) sha512Digest;
00118 /*@=type@*/
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         /*@notreached@*/ break;
00129     }
00130 
00131 /*@-boundsread@*/
00132     xx = (*ctx->Reset) (ctx->param);
00133 /*@=boundsread@*/
00134 
00135 DPRINTF((stderr, "*** Init(%x) ctx %p param %p\n", flags, ctx, ctx->param));
00136     return ctx;
00137 }
00138 
00139 /*@-mustmod@*/ /* LCL: ctx->param may be modified, but ctx is abstract @*/
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 /*@-boundsread@*/
00148     return (*ctx->Update) (ctx->param, data, len);
00149 /*@=boundsread@*/
00150 }
00151 /*@=mustmod@*/
00152 
00153 /*@-boundswrite@*/
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 /*@-noeffectuncon@*/ /* FIX: check rc */
00167     (void) (*ctx->Digest) (ctx->param, digest);
00168 /*@=noeffectuncon@*/
00169 
00170     /* Return final digest. */
00171 /*@-branchstate@*/
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 /*@=branchstate@*/
00193     if (digest) {
00194         memset(digest, 0, ctx->digestlen);      /* In case it's sensitive */
00195         free(digest);
00196     }
00197     memset(ctx->param, 0, ctx->paramlen);       /* In case it's sensitive */
00198     free(ctx->param);
00199     memset(ctx, 0, sizeof(*ctx));       /* In case it's sensitive */
00200     free(ctx);
00201     return 0;
00202 }
00203 /*@=boundswrite@*/

Generated on Fri Oct 12 08:44:54 2007 for rpm by  doxygen 1.5.2