masqmail-0.2

annotate src/md5/hmac_md5.c @ 170:0f0e4e7cd762

added misc/list-versions This script helps to check if the versions numbers in the project are the same as the one for the release. This script is motivated by the 0.2.27 release in which masqmail introduces itself as being version 0.2.26.
author meillo@marmaro.de
date Mon, 19 Jul 2010 14:01:13 +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 }