2 * Adapted from hmac.c (HMAC-MD5) for use by SHA1.
3 * by <mcr@sandelman.ottawa.on.ca>. Test cases from RFC2202.
14 #include <sys/types.h>
15 #include "libradius.h"
19 unsigned char* text; pointer to data stream
20 int text_len; length of data stream
21 unsigned char* key; pointer to authentication key
22 int key_len; length of authentication key
23 unsigned char* digest; caller digest to be filled in
26 #ifdef HMAC_SHA1_DATA_PROBLEMS
27 unsigned int sha1_data_problems = 0;
31 lrad_hmac_sha1(const unsigned char *text, int text_len,
32 const unsigned char *key, int key_len,
33 unsigned char *digest)
36 unsigned char k_ipad[65]; /* inner padding -
39 unsigned char k_opad[65]; /* outer padding -
44 /* if key is longer than 64 bytes reset it to key=SHA1(key) */
50 SHA1Update(&tctx, key, key_len);
57 #ifdef HMAC_SHA1_DATA_PROBLEMS
58 if(sha1_data_problems)
62 printf("\nhmac-sha1 key(%d): ", key_len);
64 for (i = 0; i < key_len; i++) {
71 printf("%02x", key[i]);
73 printf("\nDATA: (%d) ",text_len);
76 for (i = 0; i < text_len; i++) {
89 printf("%02x", text[i]);
97 * the HMAC_SHA1 transform looks like:
99 * SHA1(K XOR opad, SHA1(K XOR ipad, text))
101 * where K is an n byte key
102 * ipad is the byte 0x36 repeated 64 times
104 * opad is the byte 0x5c repeated 64 times
105 * and text is the data being protected
108 /* start out by storing key in pads */
109 memset( k_ipad, 0, sizeof(k_ipad));
110 memset( k_opad, 0, sizeof(k_opad));
111 memcpy( k_ipad, key, key_len);
112 memcpy( k_opad, key, key_len);
114 /* XOR key with ipad and opad values */
115 for (i = 0; i < 64; i++) {
122 SHA1Init(&context); /* init context for 1st
124 SHA1Update(&context, k_ipad, 64); /* start with inner pad */
125 SHA1Update(&context, text, text_len); /* then text of datagram */
126 SHA1Final(digest, &context); /* finish up 1st pass */
130 SHA1Init(&context); /* init context for 2nd
132 SHA1Update(&context, k_opad, 64); /* start with outer pad */
133 SHA1Update(&context, digest, 20); /* then results of 1st
135 SHA1Final(digest, &context); /* finish up 2nd pass */
137 #ifdef HMAC_SHA1_DATA_PROBLEMS
138 if(sha1_data_problems)
142 printf("\nhmac-sha1 mac(20): ");
144 for (i = 0; i < 20; i++) {
151 printf("%02x", digest[i]);
159 Test Vectors (Trailing '\0' of a character string not included in test):
162 data = "what do ya want for nothing?"
166 key = 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
169 data = 0xDDDDDDDDDDDDDDDDDDDD...
170 ..DDDDDDDDDDDDDDDDDDDD...
171 ..DDDDDDDDDDDDDDDDDDDD...
172 ..DDDDDDDDDDDDDDDDDDDD...
173 ..DDDDDDDDDDDDDDDDDDDD
175 digest = 0x56be34521d144c88dbb8c733f0e8b3f6
180 * cc -DTESTING -I ../include/ hmac.c md5.c -o hmac
182 * ./hmac Jefe "what do ya want for nothing?"
188 int main(int argc, char **argv)
190 unsigned char digest[20];
198 key_len = strlen(key);
201 text_len = strlen(text);
203 lrad_hmac_sha1(text, text_len, key, key_len, digest);
205 for (i = 0; i < 20; i++) {
206 printf("%02x", digest[i]);