hmac_sha1.c (1696B)
1 /* Adapted from RFC2104 hmac_md5, some code-style changes and data streaming support. */ 2 3 #include <string.h> 4 #include <stdio.h> 5 6 #include "hmac_sha1.h" 7 8 void 9 hmac_sha1_init(SHA_CTX *ctx, const unsigned char *key, size_t key_len, 10 unsigned char *k_opad, size_t k_opadlen) 11 { 12 SHA_CTX tctx; 13 unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */ 14 unsigned char tk[20]; 15 int i; 16 17 /* if key is longer than 64 bytes reset it to key=SHA1(key) */ 18 if (key_len > 64) { 19 SHA1_Init(&tctx); 20 SHA1_Update(&tctx, key, key_len); 21 SHA1_Final(tk, &tctx); 22 23 key = tk; 24 key_len = 20; 25 } 26 27 /* 28 * the HMAC_SHA1 transform looks like: 29 * 30 * SHA1(K XOR opad, SHA1(K XOR ipad, text)) 31 * 32 * where K is an n byte key 33 * ipad is the byte 0x36 repeated 64 times 34 * opad is the byte 0x5c repeated 64 times 35 * and text is the data being protected 36 */ 37 38 /* start out by storing key in pads */ 39 memset(k_ipad, 0, sizeof(k_ipad)); 40 memset(k_opad, 0, k_opadlen); 41 memcpy(k_ipad, key, key_len); 42 memcpy(k_opad, key, key_len); 43 44 /* XOR key with ipad and opad values */ 45 for (i = 0; i < 64; i++) { 46 k_ipad[i] ^= 0x36; 47 k_opad[i] ^= 0x5c; 48 } 49 /* perform inner SHA1 */ 50 SHA1_Init(ctx); /* init context for 1st pass */ 51 SHA1_Update(ctx, k_ipad, 64); /* start with inner pad */ 52 } 53 54 void 55 hmac_sha1_final(SHA_CTX *ctx, const unsigned char *k_opad, unsigned char *digest) 56 { 57 SHA1_Final(digest, ctx); /* finish up 1st pass */ 58 /* perform outer SHA1 */ 59 SHA1_Init(ctx); /* init context for 2nd pass */ 60 SHA1_Update(ctx, k_opad, 64); /* start with outer pad */ 61 SHA1_Update(ctx, digest, 20); /* then results of 1st hash */ 62 SHA1_Final(digest, ctx); /* finish up 2nd pass */ 63 }