Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

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 datalen;             
00023     uint32 paramlen;            
00024     uint32 digestlen;           
00025     void * param;               
00026     int (*Reset) (void * param)
00027         /*@modifies param @*/;  
00028     int (*Update) (void * param, const byte * data, int len)
00029         /*@modifies param @*/;  
00030     int (*Digest) (void * param, /*@out@*/ uint32 * digest)
00031         /*@modifies param, digest @*/;  
00032 };
00033 
00034 /*@-boundsread@*/
00035 DIGEST_CTX
00036 rpmDigestDup(DIGEST_CTX octx)
00037 {
00038     DIGEST_CTX nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
00039     nctx->param = memcpy(xcalloc(1, nctx->paramlen), octx->param, nctx->paramlen);
00040     return nctx;
00041 }
00042 /*@=boundsread@*/
00043 
00044 DIGEST_CTX
00045 rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
00046 {
00047     DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx));
00048     int xx;
00049 
00050     ctx->flags = flags;
00051 
00052     switch (hashalgo) {
00053     case PGPHASHALGO_MD5:
00054         ctx->digestlen = 16;
00055         ctx->datalen = 64;
00056         /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00057         ctx->paramlen = sizeof(md5Param);
00058         /*@=sizeoftype@*/
00059         ctx->param = xcalloc(1, ctx->paramlen);
00060         /*@-type@*/ /* FIX: cast? */
00061         ctx->Reset = (void *) md5Reset;
00062         ctx->Update = (void *) md5Update;
00063         ctx->Digest = (void *) md5Digest;
00064         /*@=type@*/
00065         break;
00066     case PGPHASHALGO_SHA1:
00067         ctx->digestlen = 20;
00068         ctx->datalen = 64;
00069         /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00070         ctx->paramlen = sizeof(sha1Param);
00071         /*@=sizeoftype@*/
00072         ctx->param = xcalloc(1, ctx->paramlen);
00073         /*@-type@*/ /* FIX: cast? */
00074         ctx->Reset = (void *) sha1Reset;
00075         ctx->Update = (void *) sha1Update;
00076         ctx->Digest = (void *) sha1Digest;
00077         /*@=type@*/
00078         break;
00079     case PGPHASHALGO_RIPEMD160:
00080     case PGPHASHALGO_MD2:
00081     case PGPHASHALGO_TIGER192:
00082     case PGPHASHALGO_HAVAL_5_160:
00083     default:
00084         free(ctx);
00085         return NULL;
00086         /*@notreached@*/ break;
00087     }
00088 
00089 /*@-boundsread@*/
00090     xx = (*ctx->Reset) (ctx->param);
00091 /*@=boundsread@*/
00092 
00093 DPRINTF((stderr, "*** Init(%x) ctx %p param %p\n", flags, ctx, ctx->param));
00094     return ctx;
00095 }
00096 
00097 /*@-mustmod@*/ /* LCL: ctx->param may be modified, but ctx is abstract @*/
00098 int
00099 rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
00100 {
00101 DPRINTF((stderr, "*** Update(%p,%p,%d) param %p \"%s\"\n", ctx, data, len, ctx->param, ((char *)data)));
00102 /*@-boundsread@*/
00103     return (*ctx->Update) (ctx->param, data, len);
00104 /*@=boundsread@*/
00105 }
00106 /*@=mustmod@*/
00107 
00108 /*@unchecked@*/
00109 static int _ie = 0x44332211;
00110 /*@-redef@*/
00111 /*@unchecked@*/
00112 static union _dendian {
00113 /*@unused@*/ int i;
00114     char b[4];
00115 } *_endian = (union _dendian *)&_ie;
00116 /*@=redef@*/
00117 #define        IS_BIG_ENDIAN()         (_endian->b[0] == '\x44')
00118 #define        IS_LITTLE_ENDIAN()      (_endian->b[0] == '\x11')
00119 
00120 /*@-boundswrite@*/
00121 int
00122 rpmDigestFinal(/*@only@*/ DIGEST_CTX ctx, /*@out@*/ void ** datap,
00123         /*@out@*/ size_t *lenp, int asAscii)
00124 {
00125     uint32 * digest = xmalloc(ctx->digestlen);
00126     char * t;
00127     int i;
00128 
00129 DPRINTF((stderr, "*** Final(%p,%p,%p,%d) param %p digest %p\n", ctx, datap, lenp, asAscii, ctx->param, digest));
00130     /*@-noeffectuncon@*/ /* FIX: check rc */
00131     (void) (*ctx->Digest) (ctx->param, digest);
00132     /*@=noeffectuncon@*/
00133 
00134     /*@-sizeoftype@*/
00135     if (IS_LITTLE_ENDIAN())
00136     for (i = 0; i < (ctx->digestlen/sizeof(uint32)); i++)
00137         digest[i] = swapu32(digest[i]);
00138     /*@=sizeoftype@*/
00139 
00140     /* Return final digest. */
00141     /*@-branchstate@*/
00142     if (!asAscii) {
00143         if (lenp) *lenp = ctx->digestlen;
00144         if (datap) {
00145             *datap = digest;
00146             digest = NULL;
00147         }
00148     } else {
00149         if (lenp) *lenp = (2*ctx->digestlen) + 1;
00150         if (datap) {
00151             const byte * s = (const byte *) digest;
00152             static const char hex[] = "0123456789abcdef";
00153 
00154             *datap = t = xmalloc((2*ctx->digestlen) + 1);
00155             for (i = 0 ; i < ctx->digestlen; i++) {
00156                 *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
00157                 *t++ = hex[ (unsigned)((*s++   ) & 0x0f) ];
00158             }
00159             *t = '\0';
00160         }
00161     }
00162     /*@=branchstate@*/
00163     if (digest) {
00164         memset(digest, 0, ctx->digestlen);      /* In case it's sensitive */
00165         free(digest);
00166     }
00167     memset(ctx->param, 0, ctx->paramlen);       /* In case it's sensitive */
00168     free(ctx->param);
00169     memset(ctx, 0, sizeof(*ctx));       /* In case it's sensitive */
00170     free(ctx);
00171     return 0;
00172 }
00173 /*@=boundswrite@*/

Generated on Wed Sep 4 12:49:55 2002 for rpm by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002