summaryrefslogtreecommitdiffstats
path: root/libhmac/hmac.c
diff options
context:
space:
mode:
authorSam Varshavchik2013-08-19 16:39:41 -0400
committerSam Varshavchik2013-08-25 14:43:51 -0400
commit9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch)
tree7a81a04cb51efb078ee350859a64be2ebc6b8813 /libhmac/hmac.c
parenta9520698b770168d1f33d6301463bb70a19655ec (diff)
downloadcourier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2
Initial checkin
Imported from subversion report, converted to git. Updated all paths in scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'libhmac/hmac.c')
-rw-r--r--libhmac/hmac.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/libhmac/hmac.c b/libhmac/hmac.c
new file mode 100644
index 0000000..b624fa9
--- /dev/null
+++ b/libhmac/hmac.c
@@ -0,0 +1,150 @@
+/*
+** Copyright 1998 - 1999 Double Precision, Inc.
+** See COPYING for distribution information.
+*/
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "hmac.h"
+
+
+struct hmac_hashinfo *hmac_list[]= {HMAC_LIST};
+
+struct hhki {
+ const struct hmac_hashinfo *hh;
+ const char *k;
+ size_t kl;
+ unsigned char *kxopad;
+ unsigned char *kxipad;
+
+ void *context;
+ } ;
+
+static void dohashkey(unsigned char *, void *);
+static void docalcc(void *, void *);
+
+void hmac_hashkey(const struct hmac_hashinfo *hh, const char *k,
+ size_t kl, unsigned char *kxopad, unsigned char *kxipad)
+{
+struct hhki i;
+
+ i.hh=hh;
+ i.k=k;
+ i.kl=kl;
+ i.kxopad=kxopad;
+ i.kxipad=kxipad;
+
+ (*hh->hh_allocacontext)( docalcc, (void *)&i );
+}
+
+static void dokeycalc(struct hhki *);
+
+static void docalcc(void *c, void *v)
+{
+struct hhki *i=(struct hhki *)v;
+
+ i->context=c;
+
+ if (i->kl > i->hh->hh_B)
+ (*i->hh->hh_allocaval)(dohashkey, (void *)i);
+ else
+ dokeycalc( i );
+}
+
+static void dohashkey(unsigned char *keybuf, void *v)
+{
+struct hhki *i=(struct hhki *)v;
+
+ (*i->hh->hh_init)(i->context);
+ (*i->hh->hh_hash)(i->context, i->k, i->kl);
+ (*i->hh->hh_endhash)(i->context, i->kl);
+ (*i->hh->hh_getdigest)(i->context, keybuf);
+ i->k=(char *)keybuf;
+ i->kl=i->hh->hh_L;
+ dokeycalc(i);
+}
+
+static void dokeycalc(struct hhki *i)
+{
+char buf[64]; /* Random guess :-) */
+unsigned n;
+unsigned l;
+
+ (*i->hh->hh_init)(i->context);
+ n=0;
+ for (l=0; l<i->hh->hh_B; l++)
+ {
+ buf[n] = ( l < i->kl ? i->k[l]:0) ^ 0x5C;
+ if ( ++n >= sizeof(buf))
+ {
+ (*i->hh->hh_hash)(i->context, buf, sizeof(buf));
+ n=0;
+ }
+ }
+ if (n)
+ (*i->hh->hh_hash)(i->context, buf, n);
+ (*i->hh->hh_getdigest)(i->context, i->kxopad);
+
+ (*i->hh->hh_init)(i->context);
+ n=0;
+ for (l=0; l<i->hh->hh_B; l++)
+ {
+ buf[n] = ( l < i->kl ? i->k[l]:0) ^ 0x36;
+ if ( ++n >= sizeof(buf))
+ {
+ (*i->hh->hh_hash)(i->context, buf, sizeof(buf));
+ n=0;
+ }
+ }
+ if (n)
+ (*i->hh->hh_hash)(i->context, buf, n);
+ (*i->hh->hh_getdigest)(i->context, i->kxipad);
+}
+
+struct hhko {
+ const struct hmac_hashinfo *hh;
+ const char *t;
+ size_t tl;
+ const unsigned char *kxopad;
+ const unsigned char *kxipad;
+ unsigned char *hash;
+ } ;
+
+static void docalch(void *, void *);
+
+void hmac_hashtext (
+ const struct hmac_hashinfo *hh,
+ const char *t,
+ size_t tl,
+ const unsigned char *kxopad,
+ const unsigned char *kxipad,
+ unsigned char *hash)
+{
+struct hhko o;
+
+ o.hh=hh;
+ o.t=t;
+ o.tl=tl;
+ o.kxopad=kxopad;
+ o.kxipad=kxipad;
+ o.hash=hash;
+
+ (*hh->hh_allocacontext)( docalch, (void *)&o );
+}
+
+static void docalch(void *c, void *v)
+{
+struct hhko *o=(struct hhko *)v;
+
+ (o->hh->hh_setdigest)(c, o->kxipad);
+ (o->hh->hh_hash)(c, o->t, o->tl);
+ (o->hh->hh_endhash)(c, o->tl+o->hh->hh_B);
+ (o->hh->hh_getdigest)(c, o->hash);
+
+ (o->hh->hh_setdigest)(c, o->kxopad);
+ (o->hh->hh_hash)(c, o->hash, o->hh->hh_L);
+ (o->hh->hh_endhash)(c, o->hh->hh_L + o->hh->hh_B);
+ (o->hh->hh_getdigest)(c, o->hash);
+}