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

digest.c

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

Generated on Mon Apr 4 20:06:30 2005 for rpm by  doxygen 1.4.1