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