meillo@0: /* meillo@0: ** Function: hmac_md5 meillo@0: */ meillo@0: meillo@0: #include meillo@0: #include "global.h" meillo@0: #include "md5.h" meillo@0: #include "hmac_md5.h" meillo@0: meillo@0: void hmac_md5(unsigned char *text, int text_len, meillo@0: unsigned char* key, int key_len, unsigned char *digest) meillo@0: /* text; pointer to data stream */ meillo@0: /* text_len; length of data stream */ meillo@0: /* key; pointer to authentication key */ meillo@0: /* key_len; length of authentication key */ meillo@0: /* digest; caller digest to be filled in */ meillo@0: meillo@0: { meillo@0: MD5_CTX context; meillo@0: unsigned char k_ipad[65]; /* inner padding - meillo@0: * key XORd with ipad meillo@0: */ meillo@0: unsigned char k_opad[65]; /* outer padding - meillo@0: * key XORd with opad meillo@0: */ meillo@0: unsigned char tk[16]; meillo@0: int i; meillo@0: /* if key is longer than 64 bytes reset it to key=MD5(key) */ meillo@0: if (key_len > 64) { meillo@0: meillo@0: MD5_CTX tctx; meillo@0: meillo@0: MD5Init(&tctx); meillo@0: MD5Update(&tctx, key, key_len); meillo@0: MD5Final(tk, &tctx); meillo@0: meillo@0: key = tk; meillo@0: key_len = 16; meillo@0: } meillo@0: meillo@0: /* meillo@0: * the HMAC_MD5 transform looks like: meillo@0: * meillo@0: * MD5(K XOR opad, MD5(K XOR ipad, text)) meillo@0: * meillo@0: * where K is an n byte key meillo@0: * ipad is the byte 0x36 repeated 64 times meillo@0: * opad is the byte 0x5c repeated 64 times meillo@0: * and text is the data being protected meillo@0: */ meillo@0: meillo@0: /* start out by storing key in pads */ meillo@0: bzero( k_ipad, sizeof k_ipad); meillo@0: bzero( k_opad, sizeof k_opad); meillo@0: bcopy( key, k_ipad, key_len); meillo@0: bcopy( key, k_opad, key_len); meillo@0: meillo@0: /* XOR key with ipad and opad values */ meillo@0: for (i=0; i<64; i++) { meillo@0: k_ipad[i] ^= 0x36; meillo@0: k_opad[i] ^= 0x5c; meillo@0: } meillo@0: /* meillo@0: * perform inner MD5 meillo@0: */ meillo@0: MD5Init(&context); /* init context for 1st meillo@0: * pass */ meillo@0: MD5Update(&context, k_ipad, 64); /* start with inner pad */ meillo@0: MD5Update(&context, text, text_len); /* then text of datagram */ meillo@0: MD5Final(digest, &context); /* finish up 1st pass */ meillo@0: /* meillo@0: * perform outer MD5 meillo@0: */ meillo@0: MD5Init(&context); /* init context for 2nd meillo@0: * pass */ meillo@0: MD5Update(&context, k_opad, 64); /* start with outer pad */ meillo@0: MD5Update(&context, digest, 16); /* then results of 1st meillo@0: * hash */ meillo@0: MD5Final(digest, &context); /* finish up 2nd pass */ meillo@0: }