Mercurial > masqmail-0.2
changeset 164:b8c358b2e242
replaced hmac_md5.c with an own implementation of RFC 2104
Until now the sample code of the RFC itself was used,
but it lacked a license or copyright notice.
See the comment in hmac_md5.c for details.
author | meillo@marmaro.de |
---|---|
date | Sun, 18 Jul 2010 22:20:20 +0200 |
parents | 06525982a56c |
children | ca99aa7f052a |
files | src/md5/hmac_md5.c src/md5/hmac_md5.h |
diffstat | 2 files changed, 75 insertions(+), 63 deletions(-) [+] |
line wrap: on
line diff
--- a/src/md5/hmac_md5.c Sun Jul 18 22:03:08 2010 +0200 +++ b/src/md5/hmac_md5.c Sun Jul 18 22:20:20 2010 +0200 @@ -1,71 +1,83 @@ /* -** Function: hmac_md5 +hmac_md5 -- implements RFC 2104 + +Copyright 2010, markus schnalke <meillo@marmaro.de> + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +My motivation to write this code was the lack of a nicely licensed +hmac_md5 function in C. I programmed it following the RFC's text. +Obviously this code is highly similar to the sample code of the RFC. +The code is tested against the test vectors of the RFC. Wikipedia's +HMAC page helped me to understand the algorithm better. + +This hmac_md5 function requires an OpenSSL-compatible MD5 +implementation. There are Public Domain MD5 implementations by Colin +Plumb and by Solar Designer. You probably want to use one of these. */ #include <string.h> #include "md5.h" -#include "hmac_md5.h" + + +const int blocksize = 64; +const int hashsize = 16; + +/* +The computed HMAC will be written to `digest'. +Ensure digest points to hashsize bytes of allocated memory. +*/ void -hmac_md5(unsigned char *text, int text_len, unsigned char *key, int key_len, unsigned char *digest) - /* text; pointer to data stream */ - /* text_len; length of data stream */ - /* key; pointer to authentication key */ - /* key_len; length of authentication key */ - /* digest; caller digest to be filled in */ +hmac_md5(unsigned char* text, int textlen, unsigned char* key, int keylen, unsigned char* digest) { + int i; MD5_CTX context; - unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */ - unsigned char k_opad[65]; /* outer padding - key XORd with opad */ - unsigned char tk[16]; - int i; - /* if key is longer than 64 bytes reset it to key=MD5(key) */ - if (key_len > 64) { + unsigned char ipad[blocksize]; + unsigned char opad[blocksize]; - MD5_CTX tctx; - - MD5_Init(&tctx); - MD5_Update(&tctx, key, key_len); - MD5_Final(tk, &tctx); - - key = tk; - key_len = 16; + /* too long keys are replaced by their hash value */ + if (keylen > blocksize) { + MD5_Init(&context); + MD5_Update(&context, key, keylen); + MD5_Final(digest, &context); + key = digest; + keylen = hashsize; } - /* - * the HMAC_MD5 transform looks like: - * - * MD5(K XOR opad, MD5(K XOR ipad, text)) - * - * where K is an n byte key - * ipad is the byte 0x36 repeated 64 times - * opad is the byte 0x5c repeated 64 times - * and text is the data being protected - */ + /* copy the key into the pads */ + memset(ipad, 0, sizeof(ipad)); + memcpy(ipad, key, keylen); - /* start out by storing key in pads */ - bzero(k_ipad, sizeof k_ipad); - bzero(k_opad, sizeof k_opad); - bcopy(key, k_ipad, key_len); - bcopy(key, k_opad, key_len); + memset(opad, 0, sizeof(opad)); + memcpy(opad, key, keylen); + + /* xor the pads with their ``basic'' value */ + for (i=0; i<blocksize; i++) { + ipad[i] ^= 0x36; + opad[i] ^= 0x5c; + } - /* XOR key with ipad and opad values */ - for (i = 0; i < 64; i++) { - k_ipad[i] ^= 0x36; - k_opad[i] ^= 0x5c; - } - /* - * perform inner MD5 - */ - MD5_Init(&context); /* init context for 1st pass */ - MD5_Update(&context, k_ipad, 64); /* start with inner pad */ - MD5_Update(&context, text, text_len); /* then text of datagram */ - MD5_Final(digest, &context); /* finish up 1st pass */ - /* - * perform outer MD5 - */ - MD5_Init(&context); /* init context for 2nd pass */ - MD5_Update(&context, k_opad, 64); /* start with outer pad */ - MD5_Update(&context, digest, 16); /* then results of 1st hash */ - MD5_Final(digest, &context); /* finish up 2nd pass */ + /* inner pass (ipad ++ message) */ + MD5_Init(&context); + MD5_Update(&context, ipad, sizeof(ipad)); + MD5_Update(&context, text, textlen); + MD5_Final(digest, &context); + + /* outer pass (opad ++ result of inner pass) */ + MD5_Init(&context); + MD5_Update(&context, opad, sizeof(opad)); + MD5_Update(&context, digest, hashsize); + MD5_Final(digest, &context); }
--- a/src/md5/hmac_md5.h Sun Jul 18 22:03:08 2010 +0200 +++ b/src/md5/hmac_md5.h Sun Jul 18 22:20:20 2010 +0200 @@ -1,7 +1,7 @@ -void -hmac_md5(unsigned char *text, int text_len, unsigned char *key, int key_len, unsigned char *digest); - /* text; pointer to data stream */ - /* text_len; length of data stream */ - /* key; pointer to authentication key */ - /* key_len; length of authentication key */ - /* digest; caller digest to be filled in */ +void hmac_md5( + unsigned char* text, /* pointer to the message */ + int textlen, /* length of the message */ + unsigned char* key, /* pointer to the authentication key */ + int keylen, /* length of the key */ + unsigned char* digest /* pointer to allocated memory to store the computed HMAC */ +);