2 * hmac.c For the sake of illustration we provide the following
3 * sample code for the implementation of HMAC-MD5 as well
4 * as some corresponding test vectors (the code is based
5 * on MD5 code as described in [MD5]).
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * Copyright 2000,2006 The FreeRADIUS server project
28 #include <freeradius-devel/ident.h>
31 #include <freeradius-devel/libradius.h>
32 #include <freeradius-devel/md5.h>
35 unsigned char* text; pointer to data stream
36 int text_len; length of data stream
37 unsigned char* key; pointer to authentication key
38 int key_len; length of authentication key
39 unsigned char* digest; caller digest to be filled in
43 lrad_hmac_md5(const uint8_t *text, int text_len,
44 const uint8_t *key, int key_len,
48 uint8_t k_ipad[65]; /* inner padding -
51 uint8_t k_opad[65]; /* outer padding -
56 /* if key is longer than 64 bytes reset it to key=MD5(key) */
62 lrad_MD5Update(&tctx, key, key_len);
63 lrad_MD5Final(tk, &tctx);
70 * the HMAC_MD5 transform looks like:
72 * MD5(K XOR opad, MD5(K XOR ipad, text))
74 * where K is an n byte key
75 * ipad is the byte 0x36 repeated 64 times
77 * opad is the byte 0x5c repeated 64 times
78 * and text is the data being protected
81 /* start out by storing key in pads */
82 memset( k_ipad, 0, sizeof(k_ipad));
83 memset( k_opad, 0, sizeof(k_opad));
84 memcpy( k_ipad, key, key_len);
85 memcpy( k_opad, key, key_len);
87 /* XOR key with ipad and opad values */
88 for (i = 0; i < 64; i++) {
95 lrad_MD5Init(&context); /* init context for 1st
97 lrad_MD5Update(&context, k_ipad, 64); /* start with inner pad */
98 lrad_MD5Update(&context, text, text_len); /* then text of datagram */
99 lrad_MD5Final(digest, &context); /* finish up 1st pass */
103 lrad_MD5Init(&context); /* init context for 2nd
105 lrad_MD5Update(&context, k_opad, 64); /* start with outer pad */
106 lrad_MD5Update(&context, digest, 16); /* then results of 1st
108 lrad_MD5Final(digest, &context); /* finish up 2nd pass */
112 Test Vectors (Trailing '\0' of a character string not included in test):
114 key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
118 digest = 0x9294727a3638bb1c13f48ef8158bfc9d
121 data = "what do ya want for nothing?"
123 digest = 0x750c783e6ab0b503eaa86e310a5db738
125 key = 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
128 data = 0xDDDDDDDDDDDDDDDDDDDD...
129 ..DDDDDDDDDDDDDDDDDDDD...
130 ..DDDDDDDDDDDDDDDDDDDD...
131 ..DDDDDDDDDDDDDDDDDDDD...
132 ..DDDDDDDDDDDDDDDDDDDD
134 digest = 0x56be34521d144c88dbb8c733f0e8b3f6
139 * cc -DTESTING -I ../include/ hmac.c md5.c -o hmac
141 * ./hmac Jefe "what do ya want for nothing?"
146 int main(int argc, char **argv)
156 key_len = strlen(key);
159 text_len = strlen(text);
161 lrad_hmac_md5(text, text_len, key, key_len, digest);
163 for (i = 0; i < 16; i++) {
164 printf("%02x", digest[i]);