masqmail

annotate src/md5/hmac_md5.c @ 369:19d57eb1b6a1

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