Back to index

courier  0.68.2
hmac.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 1998 - 1999 Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 
00006 #if    HAVE_CONFIG_H
00007 #include      "config.h"
00008 #endif
00009 
00010 #include      "hmac.h"
00011 
00012 
00013 struct hmac_hashinfo *hmac_list[]= {HMAC_LIST};
00014 
00015 struct hhki {
00016        const struct hmac_hashinfo *hh;
00017        const char *k;
00018         size_t kl;
00019        unsigned char *kxopad;
00020        unsigned char *kxipad;
00021 
00022        void *context;
00023        } ;
00024 
00025 static void dohashkey(unsigned char *, void *);
00026 static void docalcc(void *, void *);
00027 
00028 void hmac_hashkey(const struct hmac_hashinfo *hh, const char *k,
00029         size_t kl, unsigned char *kxopad, unsigned char *kxipad)
00030 {
00031 struct hhki i;
00032 
00033        i.hh=hh;
00034        i.k=k;
00035        i.kl=kl;
00036        i.kxopad=kxopad;
00037        i.kxipad=kxipad;
00038 
00039        (*hh->hh_allocacontext)( docalcc, (void *)&i );
00040 }
00041 
00042 static void dokeycalc(struct hhki *);
00043 
00044 static void docalcc(void *c, void *v)
00045 {
00046 struct hhki *i=(struct hhki *)v;
00047 
00048        i->context=c;
00049 
00050        if (i->kl > i->hh->hh_B)
00051               (*i->hh->hh_allocaval)(dohashkey, (void *)i);
00052        else
00053               dokeycalc( i );
00054 }
00055 
00056 static void dohashkey(unsigned char *keybuf, void *v)
00057 {
00058 struct hhki *i=(struct hhki *)v;
00059 
00060        (*i->hh->hh_init)(i->context);
00061        (*i->hh->hh_hash)(i->context, i->k, i->kl);
00062        (*i->hh->hh_endhash)(i->context, i->kl);
00063        (*i->hh->hh_getdigest)(i->context, keybuf);
00064        i->k=(char *)keybuf;
00065        i->kl=i->hh->hh_L;
00066        dokeycalc(i);
00067 }
00068 
00069 static void dokeycalc(struct hhki *i)
00070 {
00071 char   buf[64];      /* Random guess :-) */
00072 unsigned n;
00073 unsigned l;
00074 
00075        (*i->hh->hh_init)(i->context);
00076        n=0;
00077        for (l=0; l<i->hh->hh_B; l++)
00078        {
00079               buf[n] = ( l < i->kl ? i->k[l]:0) ^ 0x5C;
00080               if ( ++n >= sizeof(buf))
00081               {
00082                      (*i->hh->hh_hash)(i->context, buf, sizeof(buf));
00083                      n=0;
00084               }
00085        }
00086        if (n)
00087               (*i->hh->hh_hash)(i->context, buf, n);
00088        (*i->hh->hh_getdigest)(i->context, i->kxopad);
00089 
00090        (*i->hh->hh_init)(i->context);
00091        n=0;
00092        for (l=0; l<i->hh->hh_B; l++)
00093        {
00094               buf[n] = ( l < i->kl ? i->k[l]:0) ^ 0x36;
00095               if ( ++n >= sizeof(buf))
00096               {
00097                      (*i->hh->hh_hash)(i->context, buf, sizeof(buf));
00098                      n=0;
00099               }
00100        }
00101        if (n)
00102               (*i->hh->hh_hash)(i->context, buf, n);
00103        (*i->hh->hh_getdigest)(i->context, i->kxipad);
00104 }
00105 
00106 struct hhko {
00107        const struct hmac_hashinfo *hh;
00108        const char *t;
00109         size_t tl;
00110        const unsigned char *kxopad;
00111        const unsigned char *kxipad;
00112        unsigned char *hash;
00113        } ;
00114 
00115 static void docalch(void *, void *);
00116 
00117 void hmac_hashtext (
00118         const struct hmac_hashinfo *hh,
00119         const char *t,
00120         size_t tl,
00121         const unsigned char *kxopad,
00122         const unsigned char *kxipad,
00123         unsigned char *hash)
00124 {
00125 struct hhko o;
00126 
00127        o.hh=hh;
00128        o.t=t;
00129        o.tl=tl;
00130        o.kxopad=kxopad;
00131        o.kxipad=kxipad;
00132        o.hash=hash;
00133 
00134        (*hh->hh_allocacontext)( docalch, (void *)&o );
00135 }
00136 
00137 static void docalch(void *c, void *v)
00138 {
00139 struct hhko *o=(struct hhko *)v;
00140 
00141        (o->hh->hh_setdigest)(c, o->kxipad);
00142        (o->hh->hh_hash)(c, o->t, o->tl);
00143        (o->hh->hh_endhash)(c, o->tl+o->hh->hh_B);
00144        (o->hh->hh_getdigest)(c, o->hash);
00145 
00146        (o->hh->hh_setdigest)(c, o->kxopad);
00147        (o->hh->hh_hash)(c, o->hash, o->hh->hh_L);
00148        (o->hh->hh_endhash)(c, o->hh->hh_L + o->hh->hh_B);
00149        (o->hh->hh_getdigest)(c, o->hash);
00150 }