2 * Hashed Message Authentication Code using MD5 (HMAC-MD5)
4 * hmac_md5 was based on sample code in RFC2104 (thanks guys).
6 * Adapted to Bacula by Kern E. Sibbald, February MMI.
9 Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2 of
14 the License, or (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public
22 License along with this program; if not, write to the Free
23 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
30 #define PAD_LEN 64 /* PAD length */
31 #define SIG_LEN 16 /* MD5 signature length */
35 uint8_t* text, /* pointer to data stream */
36 int text_len, /* length of data stream */
37 uint8_t* key, /* pointer to authentication key */
38 int key_len, /* length of authentication key */
39 uint8_t *hmac) /* returned hmac-md5 */
42 uint8_t k_ipad[PAD_LEN]; /* inner padding - key XORd with ipad */
43 uint8_t k_opad[PAD_LEN]; /* outer padding - key XORd with opad */
44 uint8_t keysig[SIG_LEN];
47 /* if key is longer than PAD length, reset it to key=MD5(key) */
48 if (key_len > PAD_LEN) {
52 MD5Update(&md5key, key, key_len);
53 MD5Final(keysig, &md5key);
60 * the HMAC_MD5 transform looks like:
62 * MD5(Key XOR opad, MD5(Key XOR ipad, text))
64 * where Key is an n byte key
65 * ipad is the byte 0x36 repeated 64 times
67 * opad is the byte 0x5c repeated 64 times
68 * and text is the data being protected
71 /* Zero pads and store key */
72 memset(k_ipad, 0, PAD_LEN);
73 memcpy(k_ipad, key, key_len);
74 memcpy(k_opad, k_ipad, PAD_LEN);
76 /* XOR key with ipad and opad values */
77 for (i=0; i<PAD_LEN; i++) {
82 /* perform inner MD5 */
83 MD5Init(&md5c); /* start inner hash */
84 MD5Update(&md5c, k_ipad, PAD_LEN); /* hash inner pad */
85 MD5Update(&md5c, text, text_len); /* hash text */
86 MD5Final(hmac, &md5c); /* store inner hash */
88 /* perform outer MD5 */
89 MD5Init(&md5c); /* start outer hash */
90 MD5Update(&md5c, k_opad, PAD_LEN); /* hash outer pad */
91 MD5Update(&md5c, hmac, SIG_LEN); /* hash inner hash */
92 MD5Final(hmac, &md5c); /* store results */
95 Test Vectors (Trailing '\0' of a character string not included in test):
97 key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
101 digest = 0x9294727a3638bb1c13f48ef8158bfc9d
104 data = "what do ya want for nothing?"
106 digest = 0x750c783e6ab0b503eaa86e310a5db738
108 key = 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
111 data = 0xDDDDDDDDDDDDDDDDDDDD...
112 ..DDDDDDDDDDDDDDDDDDDD...
113 ..DDDDDDDDDDDDDDDDDDDD...
114 ..DDDDDDDDDDDDDDDDDDDD...
115 ..DDDDDDDDDDDDDDDDDDDD
117 digest = 0x56be34521d144c88dbb8c733f0e8b3f6