#include #include #include #include #include "algs.h" typedef struct hmac_sha1_state HMAC_SHA1_STATE; struct hmac_sha1_state { void *k_xor_opad; void *k_xor_ipad; } ; static void *init_xor_block(const void *key, int keylen, unsigned char xorv) { unsigned char kblk[64]; int i; void *h; if (keylen > 64) abort(); bcopy(key,&kblk[0],keylen); if (keylen < 64) bzero(&kblk[keylen],64-keylen); for (i=0;i<64;i++) kblk[i] ^= xorv; h = sha1_init(); sha1_process_bytes(h,&kblk[0],64); return(h); } static void mac_va(HMAC_SHA1_STATE *s, int nb, va_list ap, void *into) { void *h; const void *buf; int len; unsigned char first[20]; h = sha1_clone(s->k_xor_ipad); for (;nb>0;nb--) { buf = va_arg(ap,const void *); len = va_arg(ap,int); sha1_process_bytes(h,buf,len); } sha1_result(h,&first[0]); h = sha1_clone(s->k_xor_opad); sha1_process_bytes(h,&first[0],20); sha1_result(h,into); } static void *mac_hmac_sha1_init(const void *key) { HMAC_SHA1_STATE *s; s = malloc(sizeof(HMAC_SHA1_STATE)); if (! s) return(0); s->k_xor_opad = init_xor_block(key,20,0x5c); s->k_xor_ipad = init_xor_block(key,20,0x36); return(s); } static int mac_hmac_sha1_check(void *state, const void *vs, int nblk, ...) { va_list ap; char tmp[20]; va_start(ap,nblk); mac_va(state,nblk,ap,&tmp[0]); va_end(ap); return(!bcmp(&tmp[0],vs,20)); } static void mac_hmac_sha1_gen(void *state, void *into, int nblk, ...) { va_list ap; va_start(ap,nblk); mac_va(state,nblk,ap,into); va_end(ap); } static void mac_hmac_sha1_done(void *state) { HMAC_SHA1_STATE *s; s = state; sha1_drop(s->k_xor_opad); sha1_drop(s->k_xor_ipad); free(s); } MACALG macalg_hmac_sha1 = { "hmac-sha1", 20, 20, mac_hmac_sha1_init, mac_hmac_sha1_check, mac_hmac_sha1_gen, mac_hmac_sha1_done };