]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/hmac.c
Update Makefiles for Irix and kernstodo
[bacula/bacula] / bacula / src / lib / hmac.c
1 /*
2  *  Hashed Message Authentication Code using MD5 (HMAC-MD5)
3  *
4  * hmac_md5 was based on sample code in RFC2104 (thanks guys).
5  * 
6  * Adapted to Bacula by Kern E. Sibbald, February MMI.
7  *
8  *   Version $Id$
9  */
10 /*
11    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
12
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.
17
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.
22
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,
26    MA 02111-1307, USA.
27
28  */
29
30 #include "bacula.h"
31
32 #define PAD_LEN 64                    /* PAD length */
33 #define SIG_LEN 16                    /* MD5 signature length */
34
35 void
36 hmac_md5(
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 */
42 {
43    MD5Context md5c;
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];
47    int i;
48
49    /* if key is longer than PAD length, reset it to key=MD5(key) */
50    if (key_len > PAD_LEN) {
51       MD5Context md5key;
52
53       MD5Init(&md5key);
54       MD5Update(&md5key, key, key_len);
55       MD5Final(keysig, &md5key);
56
57       key = keysig;
58       key_len = SIG_LEN;
59    }
60
61    /*
62     * the HMAC_MD5 transform looks like:
63     *
64     * MD5(Key XOR opad, MD5(Key XOR ipad, text))
65     *
66     * where Key is an n byte key
67     * ipad is the byte 0x36 repeated 64 times
68
69     * opad is the byte 0x5c repeated 64 times
70     * and text is the data being protected
71     */
72
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); 
77
78    /* XOR key with ipad and opad values */
79    for (i=0; i<PAD_LEN; i++) {
80       k_ipad[i] ^= 0x36;
81       k_opad[i] ^= 0x5c;
82    }
83
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 */
89
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 */
95 }
96 /*
97 Test Vectors (Trailing '\0' of a character string not included in test):
98
99   key =         0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
100   key_len =     16 bytes
101   data =        "Hi There"
102   data_len =    8  bytes
103   digest =      0x9294727a3638bb1c13f48ef8158bfc9d
104
105   key =         "Jefe"
106   data =        "what do ya want for nothing?"
107   data_len =    28 bytes
108   digest =      0x750c783e6ab0b503eaa86e310a5db738
109
110   key =         0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
111
112   key_len       16 bytes
113   data =        0xDDDDDDDDDDDDDDDDDDDD...
114                 ..DDDDDDDDDDDDDDDDDDDD...
115                 ..DDDDDDDDDDDDDDDDDDDD...
116                 ..DDDDDDDDDDDDDDDDDDDD...
117                 ..DDDDDDDDDDDDDDDDDDDD
118   data_len =    50 bytes
119   digest =      0x56be34521d144c88dbb8c733f0e8b3f6
120 */