diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 | 
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 | 
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /libhmac/hmac.c | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-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.c | 150 | 
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); +} | 
