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/autoconf.h>
17 #include <sys/types.h>
23 #include <freeradius-devel/sha1.h>
25 #include <freeradius-devel/missing.h>
26 #include <freeradius-devel/libradius.h>
29 uint8_t* text; pointer to data stream
30 int text_len; length of data stream
31 uint8_t* key; pointer to authentication key
32 int key_len; length of authentication key
33 uint8_t* digest; caller digest to be filled in
36 #ifdef HMAC_SHA1_DATA_PROBLEMS
37 unsigned int sha1_data_problems = 0;
41 lrad_hmac_sha1(const uint8_t *text, int text_len,
42 const uint8_t *key, int key_len,
46 uint8_t k_ipad[65]; /* inner padding -
49 uint8_t k_opad[65]; /* outer padding -
54 /* if key is longer than 64 bytes reset it to key=SHA1(key) */
60 SHA1Update(&tctx, key, key_len);
67 #ifdef HMAC_SHA1_DATA_PROBLEMS
68 if(sha1_data_problems)
72 printf("\nhmac-sha1 key(%d): ", key_len);
74 for (i = 0; i < key_len; i++) {
81 printf("%02x", key[i]);
83 printf("\nDATA: (%d) ",text_len);
86 for (i = 0; i < text_len; i++) {
99 printf("%02x", text[i]);
107 * the HMAC_SHA1 transform looks like:
109 * SHA1(K XOR opad, SHA1(K XOR ipad, text))
111 * where K is an n byte key
112 * ipad is the byte 0x36 repeated 64 times
114 * opad is the byte 0x5c repeated 64 times
115 * and text is the data being protected
118 /* start out by storing key in pads */
119 memset( k_ipad, 0, sizeof(k_ipad));
120 memset( k_opad, 0, sizeof(k_opad));
121 memcpy( k_ipad, key, key_len);
122 memcpy( k_opad, key, key_len);
124 /* XOR key with ipad and opad values */
125 for (i = 0; i < 64; i++) {
132 SHA1Init(&context); /* init context for 1st
134 SHA1Update(&context, k_ipad, 64); /* start with inner pad */
135 SHA1Update(&context, text, text_len); /* then text of datagram */
136 SHA1Final(digest, &context); /* finish up 1st pass */
140 SHA1Init(&context); /* init context for 2nd
142 SHA1Update(&context, k_opad, 64); /* start with outer pad */
143 SHA1Update(&context, digest, 20); /* then results of 1st
145 SHA1Final(digest, &context); /* finish up 2nd pass */
147 #ifdef HMAC_SHA1_DATA_PROBLEMS
148 if(sha1_data_problems)
152 printf("\nhmac-sha1 mac(20): ");
154 for (i = 0; i < 20; i++) {
161 printf("%02x", digest[i]);
169 Test Vectors (Trailing '\0' of a character string not included in test):
172 data = "what do ya want for nothing?"
174 digest = effcdf6ae5eb2fa2d27416d5f184df9c259a7c79
176 key = 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
179 data = 0xDDDDDDDDDDDDDDDDDDDD...
180 ..DDDDDDDDDDDDDDDDDDDD...
181 ..DDDDDDDDDDDDDDDDDDDD...
182 ..DDDDDDDDDDDDDDDDDDDD...
183 ..DDDDDDDDDDDDDDDDDDDD
185 digest = 0x56be34521d144c88dbb8c733f0e8b3f6
190 * cc -DTESTING -I ../include/ hmac.c sha1.c -o hmac
192 * ./hmac Jefe "what do ya want for nothing?"
197 int main(int argc, char **argv)
207 key_len = strlen(key);
210 text_len = strlen(text);
212 lrad_hmac_sha1(text, text_len, key, key_len, digest);
214 for (i = 0; i < 20; i++) {
215 printf("%02x", digest[i]);