masqmail

view src/md5/hmac_md5.c @ 379:193013200396

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