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.
11 Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of
16 the License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public
24 License along with this program; if not, write to the Free
25 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
32 #define PAD_LEN 64 /* PAD length */
33 #define SIG_LEN 16 /* MD5 signature length */
37 uint8_t* text, /* pointer to data stream */
38 int text_len, /* length of data stream */
39 uint8_t* key, /* pointer to authentication key */
40 int key_len, /* length of authentication key */
41 uint8_t *hmac) /* returned hmac-md5 */
44 uint8_t k_ipad[PAD_LEN]; /* inner padding - key XORd with ipad */
45 uint8_t k_opad[PAD_LEN]; /* outer padding - key XORd with opad */
46 uint8_t keysig[SIG_LEN];
49 /* if key is longer than PAD length, reset it to key=MD5(key) */
50 if (key_len > PAD_LEN) {
54 MD5Update(&md5key, key, key_len);
55 MD5Final(keysig, &md5key);
62 * the HMAC_MD5 transform looks like:
64 * MD5(Key XOR opad, MD5(Key XOR ipad, text))
66 * where Key is an n byte key
67 * ipad is the byte 0x36 repeated 64 times
69 * opad is the byte 0x5c repeated 64 times
70 * and text is the data being protected
73 /* Zero pads and store key */
74 memset(k_ipad, 0, PAD_LEN);
75 memcpy(k_ipad, key, key_len);
76 memcpy(k_opad, k_ipad, PAD_LEN);
78 /* XOR key with ipad and opad values */
79 for (i=0; i<PAD_LEN; i++) {
84 /* perform inner MD5 */
85 MD5Init(&md5c); /* start inner hash */
86 MD5Update(&md5c, k_ipad, PAD_LEN); /* hash inner pad */
87 MD5Update(&md5c, text, text_len); /* hash text */
88 MD5Final(hmac, &md5c); /* store inner hash */
90 /* perform outer MD5 */
91 MD5Init(&md5c); /* start outer hash */
92 MD5Update(&md5c, k_opad, PAD_LEN); /* hash outer pad */
93 MD5Update(&md5c, hmac, SIG_LEN); /* hash inner hash */
94 MD5Final(hmac, &md5c); /* store results */
97 Test Vectors (Trailing '\0' of a character string not included in test):
99 key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
103 digest = 0x9294727a3638bb1c13f48ef8158bfc9d
106 data = "what do ya want for nothing?"
108 digest = 0x750c783e6ab0b503eaa86e310a5db738
110 key = 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
113 data = 0xDDDDDDDDDDDDDDDDDDDD...
114 ..DDDDDDDDDDDDDDDDDDDD...
115 ..DDDDDDDDDDDDDDDDDDDD...
116 ..DDDDDDDDDDDDDDDDDDDD...
117 ..DDDDDDDDDDDDDDDDDDDD
119 digest = 0x56be34521d144c88dbb8c733f0e8b3f6