masqmail

annotate src/md5/hmac_md5.c @ 305:794071925a22

refactored complex conditions
author meillo@marmaro.de
date Sun, 24 Apr 2011 15:10:11 +0200
parents 10da50168dab
children 41958685480d
rev   line source
meillo@0 1 /*
meillo@211 2 hmac_md5 -- implements RFC 2104
meillo@211 3
meillo@211 4 Copyright 2010, markus schnalke <meillo@marmaro.de>
meillo@211 5
meillo@211 6 Permission to use, copy, modify, and/or distribute this software for any
meillo@211 7 purpose with or without fee is hereby granted, provided that the above
meillo@211 8 copyright notice and this permission notice appear in all copies.
meillo@211 9
meillo@211 10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
meillo@211 11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
meillo@211 12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
meillo@211 13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
meillo@211 14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
meillo@211 15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
meillo@211 16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
meillo@211 17
meillo@211 18
meillo@211 19 My motivation to write this code was the lack of a nicely licensed
meillo@211 20 hmac_md5 function in C. I programmed it following the RFC's text.
meillo@211 21 Obviously this code is highly similar to the sample code of the RFC.
meillo@211 22 The code is tested against the test vectors of the RFC. Wikipedia's
meillo@211 23 HMAC page helped me to understand the algorithm better.
meillo@211 24
meillo@211 25 This hmac_md5 function requires an OpenSSL-compatible MD5
meillo@211 26 implementation. There are Public Domain MD5 implementations by Colin
meillo@211 27 Plumb and by Solar Designer. You probably want to use one of these.
meillo@0 28 */
meillo@0 29
meillo@0 30 #include <string.h>
meillo@0 31 #include "md5.h"
meillo@0 32
meillo@211 33
meillo@211 34 const int blocksize = 64;
meillo@211 35 const int hashsize = 16;
meillo@211 36
meillo@211 37
meillo@211 38 /*
meillo@211 39 The computed HMAC will be written to `digest'.
meillo@211 40 Ensure digest points to hashsize bytes of allocated memory.
meillo@211 41 */
meillo@10 42 void
meillo@211 43 hmac_md5(unsigned char* text, int textlen, unsigned char* key, int keylen, unsigned char* digest)
meillo@10 44 {
meillo@211 45 int i;
meillo@10 46 MD5_CTX context;
meillo@211 47 unsigned char ipad[blocksize];
meillo@211 48 unsigned char opad[blocksize];
meillo@0 49
meillo@211 50 /* too long keys are replaced by their hash value */
meillo@211 51 if (keylen > blocksize) {
meillo@211 52 MD5_Init(&context);
meillo@211 53 MD5_Update(&context, key, keylen);
meillo@211 54 MD5_Final(digest, &context);
meillo@211 55 key = digest;
meillo@211 56 keylen = hashsize;
meillo@10 57 }
meillo@0 58
meillo@211 59 /* copy the key into the pads */
meillo@211 60 memset(ipad, 0, sizeof(ipad));
meillo@211 61 memcpy(ipad, key, keylen);
meillo@0 62
meillo@211 63 memset(opad, 0, sizeof(opad));
meillo@211 64 memcpy(opad, key, keylen);
meillo@0 65
meillo@211 66 /* xor the pads with their ``basic'' value */
meillo@211 67 for (i=0; i<blocksize; i++) {
meillo@211 68 ipad[i] ^= 0x36;
meillo@211 69 opad[i] ^= 0x5c;
meillo@10 70 }
meillo@211 71
meillo@211 72 /* inner pass (ipad ++ message) */
meillo@211 73 MD5_Init(&context);
meillo@211 74 MD5_Update(&context, ipad, sizeof(ipad));
meillo@211 75 MD5_Update(&context, text, textlen);
meillo@211 76 MD5_Final(digest, &context);
meillo@211 77
meillo@211 78 /* outer pass (opad ++ result of inner pass) */
meillo@211 79 MD5_Init(&context);
meillo@211 80 MD5_Update(&context, opad, sizeof(opad));
meillo@211 81 MD5_Update(&context, digest, hashsize);
meillo@211 82 MD5_Final(digest, &context);
meillo@0 83 }