masqmail-0.2

annotate src/md5/hmac_md5.c @ 165:ca99aa7f052a

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