#include #include #include #include #include "algs.h" typedef struct hmac_md5_96_state HMAC_MD5_96_STATE; struct hmac_md5_96_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 = md5_init(); md5_process_bytes(h,&kblk[0],64); return(h); } static void mac_va(HMAC_MD5_96_STATE *s, int nb, va_list ap, void *into) { void *h; const void *buf; int len; unsigned char first[16]; h = md5_clone(s->k_xor_ipad); for (;nb>0;nb--) { buf = va_arg(ap,const void *); len = va_arg(ap,int); md5_process_bytes(h,buf,len); } md5_result(h,&first[0]); h = md5_clone(s->k_xor_opad); md5_process_bytes(h,&first[0],16); md5_result(h,into); } static void *mac_hmac_md5_96_init(const void *key) { HMAC_MD5_96_STATE *s; s = malloc(sizeof(HMAC_MD5_96_STATE)); if (! s) return(0); s->k_xor_opad = init_xor_block(key,16,0x5c); s->k_xor_ipad = init_xor_block(key,16,0x36); return(s); } static int mac_hmac_md5_96_check(void *state, const void *vs, int nblk, ...) { va_list ap; char tmp[16]; va_start(ap,nblk); mac_va(state,nblk,ap,&tmp[0]); va_end(ap); return(!bcmp(&tmp[0],vs,12)); } static void mac_hmac_md5_96_gen(void *state, void *into, int nblk, ...) { va_list ap; char tmp[16]; va_start(ap,nblk); mac_va(state,nblk,ap,&tmp[0]); va_end(ap); bcopy(&tmp[0],into,12); } static void mac_hmac_md5_96_done(void *state) { HMAC_MD5_96_STATE *s; s = state; md5_drop(s->k_xor_opad); md5_drop(s->k_xor_ipad); free(s); } MACALG macalg_hmac_md5_96 = { "hmac-md5-96", 12, 16, mac_hmac_md5_96_init, mac_hmac_md5_96_check, mac_hmac_md5_96_gen, mac_hmac_md5_96_done };