2 * Adapted from hmac.c (HMAC-MD5) for use by SHA1.
3 * by <mcr@sandelman.ottawa.on.ca>. Test cases from RFC2202.
11 #include <freeradius-devel/autoconf.h>
14 #include <sys/types.h>
20 #include <freeradius-devel/sha1.h>
22 #include <freeradius-devel/missing.h>
23 #include <freeradius-devel/libradius.h>
26 uint8_t* text; pointer to data stream
27 int text_len; length of data stream
28 uint8_t* key; pointer to authentication key
29 int key_len; length of authentication key
30 uint8_t* digest; caller digest to be filled in
33 #ifdef HMAC_SHA1_DATA_PROBLEMS
34 unsigned int sha1_data_problems = 0;
38 lrad_hmac_sha1(const uint8_t *text, int text_len,
39 const uint8_t *key, int key_len,
43 uint8_t k_ipad[65]; /* inner padding -
46 uint8_t k_opad[65]; /* outer padding -
51 /* if key is longer than 64 bytes reset it to key=SHA1(key) */
57 SHA1Update(&tctx, key, key_len);
64 #ifdef HMAC_SHA1_DATA_PROBLEMS
65 if(sha1_data_problems)
69 printf("\nhmac-sha1 key(%d): ", key_len);
71 for (i = 0; i < key_len; i++) {
78 printf("%02x", key[i]);
80 printf("\nDATA: (%d) ",text_len);
83 for (i = 0; i < text_len; i++) {
96 printf("%02x", text[i]);
104 * the HMAC_SHA1 transform looks like:
106 * SHA1(K XOR opad, SHA1(K XOR ipad, text))
108 * where K is an n byte key
109 * ipad is the byte 0x36 repeated 64 times
111 * opad is the byte 0x5c repeated 64 times
112 * and text is the data being protected
115 /* start out by storing key in pads */
116 memset( k_ipad, 0, sizeof(k_ipad));
117 memset( k_opad, 0, sizeof(k_opad));
118 memcpy( k_ipad, key, key_len);
119 memcpy( k_opad, key, key_len);
121 /* XOR key with ipad and opad values */
122 for (i = 0; i < 64; i++) {
129 SHA1Init(&context); /* init context for 1st
131 SHA1Update(&context, k_ipad, 64); /* start with inner pad */
132 SHA1Update(&context, text, text_len); /* then text of datagram */
133 SHA1Final(digest, &context); /* finish up 1st pass */
137 SHA1Init(&context); /* init context for 2nd
139 SHA1Update(&context, k_opad, 64); /* start with outer pad */
140 SHA1Update(&context, digest, 20); /* then results of 1st
142 SHA1Final(digest, &context); /* finish up 2nd pass */
144 #ifdef HMAC_SHA1_DATA_PROBLEMS
145 if(sha1_data_problems)
149 printf("\nhmac-sha1 mac(20): ");
151 for (i = 0; i < 20; i++) {
158 printf("%02x", digest[i]);
166 Test Vectors (Trailing '\0' of a character string not included in test):
169 data = "what do ya want for nothing?"
171 digest = effcdf6ae5eb2fa2d27416d5f184df9c259a7c79
173 key = 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
176 data = 0xDDDDDDDDDDDDDDDDDDDD...
177 ..DDDDDDDDDDDDDDDDDDDD...
178 ..DDDDDDDDDDDDDDDDDDDD...
179 ..DDDDDDDDDDDDDDDDDDDD...
180 ..DDDDDDDDDDDDDDDDDDDD
182 digest = 0x56be34521d144c88dbb8c733f0e8b3f6
187 * cc -DTESTING -I ../include/ hmac.c sha1.c -o hmac
189 * ./hmac Jefe "what do ya want for nothing?"
194 int main(int argc, char **argv)
204 key_len = strlen(key);
207 text_len = strlen(text);
209 lrad_hmac_sha1(text, text_len, key, key_len, digest);
211 for (i = 0; i < 20; i++) {
212 printf("%02x", digest[i]);