#include <freeradius-devel/ident.h>
RCSID("$Id$")
#include <freeradius-devel/libradius.h>
#include <freeradius-devel/sha1.h>
#ifdef HMAC_SHA1_DATA_PROBLEMS
unsigned int sha1_data_problems = 0;
#endif
void
fr_hmac_sha1(const uint8_t *text, int text_len,
const uint8_t *key, int key_len,
uint8_t *digest)
{
fr_SHA1_CTX context;
uint8_t k_ipad[65];
uint8_t k_opad[65];
uint8_t tk[20];
int i;
if (key_len > 64) {
fr_SHA1_CTX tctx;
fr_SHA1Init(&tctx);
fr_SHA1Update(&tctx, key, key_len);
fr_SHA1Final(tk, &tctx);
key = tk;
key_len = 20;
}
#ifdef HMAC_SHA1_DATA_PROBLEMS
if(sha1_data_problems)
{
int j,k;
printf("\nhmac-sha1 key(%d): ", key_len);
j=0; k=0;
for (i = 0; i < key_len; i++) {
if(j==4) {
printf("_");
j=0;
}
j++;
printf("%02x", key[i]);
}
printf("\nDATA: (%d) ",text_len);
j=0; k=0;
for (i = 0; i < text_len; i++) {
if(k==20) {
printf("\n ");
k=0;
j=0;
}
if(j==4) {
printf("_");
j=0;
}
k++;
j++;
printf("%02x", text[i]);
}
printf("\n");
}
#endif
memset( k_ipad, 0, sizeof(k_ipad));
memset( k_opad, 0, sizeof(k_opad));
memcpy( k_ipad, key, key_len);
memcpy( k_opad, key, key_len);
for (i = 0; i < 64; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
fr_SHA1Init(&context);
fr_SHA1Update(&context, k_ipad, 64);
fr_SHA1Update(&context, text, text_len);
fr_SHA1Final(digest, &context);
fr_SHA1Init(&context);
fr_SHA1Update(&context, k_opad, 64);
fr_SHA1Update(&context, digest, 20);
fr_SHA1Final(digest, &context);
#ifdef HMAC_SHA1_DATA_PROBLEMS
if(sha1_data_problems)
{
int j;
printf("\nhmac-sha1 mac(20): ");
j=0;
for (i = 0; i < 20; i++) {
if(j==4) {
printf("_");
j=0;
}
j++;
printf("%02x", digest[i]);
}
printf("\n");
}
#endif
}
#ifdef TESTING
#include <stdlib.h>
int main(int argc, char **argv)
{
uint8_t digest[20];
char *key;
int key_len;
char *text;
int text_len;
int i;
key = argv[1];
key_len = strlen(key);
text = argv[2];
text_len = strlen(text);
fr_hmac_sha1(text, text_len, key, key_len, digest);
for (i = 0; i < 20; i++) {
printf("%02x", digest[i]);
}
printf("\n");
exit(0);
return 0;
}
#endif