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/ident.h>
14 #include <freeradius-devel/libradius.h>
15 #include <freeradius-devel/sha1.h>
19 uint8_t* text; pointer to data stream
20 int text_len; length of data stream
21 uint8_t* key; pointer to authentication key
22 int key_len; length of authentication key
23 uint8_t* digest; caller digest to be filled in
26 #ifdef HMAC_SHA1_DATA_PROBLEMS
27 unsigned int sha1_data_problems = 0;
31 fr_hmac_sha1(const uint8_t *text, int text_len,
32 const uint8_t *key, int key_len,
36 uint8_t k_ipad[65]; /* inner padding -
39 uint8_t k_opad[65]; /* outer padding -
44 /* if key is longer than 64 bytes reset it to key=SHA1(key) */
50 fr_SHA1Update(&tctx, key, key_len);
51 fr_SHA1Final(tk, &tctx);
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 fr_SHA1Init(&context); /* init context for 1st
124 fr_SHA1Update(&context, k_ipad, 64); /* start with inner pad */
125 fr_SHA1Update(&context, text, text_len); /* then text of datagram */
126 fr_SHA1Final(digest, &context); /* finish up 1st pass */
130 fr_SHA1Init(&context); /* init context for 2nd
132 fr_SHA1Update(&context, k_opad, 64); /* start with outer pad */
133 fr_SHA1Update(&context, digest, 20); /* then results of 1st
135 fr_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?"
164 digest = effcdf6ae5eb2fa2d27416d5f184df9c259a7c79
166 key = 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
169 data = 0xDDDDDDDDDDDDDDDDDDDD...
170 ..DDDDDDDDDDDDDDDDDDDD...
171 ..DDDDDDDDDDDDDDDDDDDD...
172 ..DDDDDDDDDDDDDDDDDDDD...
173 ..DDDDDDDDDDDDDDDDDDDD
175 digest = 0x56be34521d144c88dbb8c733f0e8b3f6
180 * cc -DTESTING -I ../include/ hmac.c sha1.c -o hmac
182 * ./hmac Jefe "what do ya want for nothing?"
187 int main(int argc, char **argv)
197 key_len = strlen(key);
200 text_len = strlen(text);
202 fr_hmac_sha1(text, text_len, key, key_len, digest);
204 for (i = 0; i < 20; i++) {
205 printf("%02x", digest[i]);