]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/hmac.c
Alpha integration of Dir plugin
[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    Bacula® - The Network Backup Solution
12
13    Copyright (C) 2001-2006 Free Software Foundation Europe e.V.
14
15    The main author of Bacula is Kern Sibbald, with contributions from
16    many others, a complete list can be found in the file AUTHORS.
17    This program is Free Software; you can redistribute it and/or
18    modify it under the terms of version two of the GNU Lesser General 
19    Public License as published by the Free Software Foundation plus 
20    additions in the file LICENSE.
21
22    This program is distributed in the hope that it will be useful, but
23    WITHOUT ANY WARRANTY; without even the implied warranty of
24    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25    Lesser General Public License for more details.
26
27    You should have received a copy of the GNU General Public License
28    along with this program; if not, write to the Free Software
29    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30    02110-1301, USA.
31
32    Bacula® is a registered trademark of John Walker.
33    The licensor of Bacula is the Free Software Foundation Europe
34    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
35    Switzerland, email:ftf@fsfeurope.org.
36 */
37
38 #include "bacula.h"
39
40 #define PAD_LEN 64           /* PAD length */
41 #define SIG_LEN MD5HashSize  /* MD5 digest length */
42
43 void
44 hmac_md5(
45     uint8_t*  text,            /* pointer to data stream */
46     int   text_len,            /* length of data stream */
47     uint8_t*  key,             /* pointer to authentication key */
48     int   key_len,             /* length of authentication key */
49     uint8_t  *hmac)            /* returned hmac-md5 */
50 {
51    MD5Context md5c;
52    uint8_t k_ipad[PAD_LEN];    /* inner padding - key XORd with ipad */
53    uint8_t k_opad[PAD_LEN];    /* outer padding - key XORd with opad */
54    uint8_t keysig[SIG_LEN];
55    int i;
56
57    /* if key is longer than PAD length, reset it to key=MD5(key) */
58    if (key_len > PAD_LEN) {
59       MD5Context md5key;
60
61       MD5Init(&md5key);
62       MD5Update(&md5key, key, key_len);
63       MD5Final(keysig, &md5key);
64
65       key = keysig;
66       key_len = SIG_LEN;
67    }
68
69    /*
70     * the HMAC_MD5 transform looks like:
71     *
72     * MD5(Key XOR opad, MD5(Key XOR ipad, text))
73     *
74     * where Key is an n byte key
75     * ipad is the byte 0x36 repeated 64 times
76
77     * opad is the byte 0x5c repeated 64 times
78     * and text is the data being protected
79     */
80
81    /* Zero pads and store key */
82    memset(k_ipad, 0, PAD_LEN);
83    memcpy(k_ipad, key, key_len);
84    memcpy(k_opad, k_ipad, PAD_LEN);
85
86    /* XOR key with ipad and opad values */
87    for (i=0; i<PAD_LEN; i++) {
88       k_ipad[i] ^= 0x36;
89       k_opad[i] ^= 0x5c;
90    }
91
92    /* perform inner MD5 */
93    MD5Init(&md5c);                    /* start inner hash */
94    MD5Update(&md5c, k_ipad, PAD_LEN); /* hash inner pad */
95    MD5Update(&md5c, text, text_len);  /* hash text */
96    MD5Final(hmac, &md5c);             /* store inner hash */
97
98    /* perform outer MD5 */
99    MD5Init(&md5c);                    /* start outer hash */
100    MD5Update(&md5c, k_opad, PAD_LEN); /* hash outer pad */
101    MD5Update(&md5c, hmac, SIG_LEN);   /* hash inner hash */
102    MD5Final(hmac, &md5c);             /* store results */
103 }
104 /*
105 Test Vectors (Trailing '\0' of a character string not included in test):
106
107   key =         0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
108   key_len =     16 bytes
109   data =        "Hi There"
110   data_len =    8  bytes
111   digest =      0x9294727a3638bb1c13f48ef8158bfc9d
112
113   key =         "Jefe"
114   data =        "what do ya want for nothing?"
115   data_len =    28 bytes
116   digest =      0x750c783e6ab0b503eaa86e310a5db738
117
118   key =         0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
119
120   key_len       16 bytes
121   data =        0xDDDDDDDDDDDDDDDDDDDD...
122                 ..DDDDDDDDDDDDDDDDDDDD...
123                 ..DDDDDDDDDDDDDDDDDDDD...
124                 ..DDDDDDDDDDDDDDDDDDDD...
125                 ..DDDDDDDDDDDDDDDDDDDD
126   data_len =    50 bytes
127   digest =      0x56be34521d144c88dbb8c733f0e8b3f6
128 */