Listing 1: HMAC using SHA-1
int hmac_sha1(unsigned char *hmac,
size_t hmac_size,
const unsigned char *msg,
size_t msg_len,
const void *key,
size_t key_len)
{
unsigned char padded_key[SHA1_BLOCK_SIZE];
unsigned char k1[SHA1_BLOCK_SIZE];
unsigned char k2[SHA1_BLOCK_SIZE];
unsigned char IPAD[SHA1_BLOCK_SIZE];
unsigned char OPAD[SHA1_BLOCK_SIZE];
unsigned char padded_msg[SHA1_BLOCK_SIZE+msg_len];
unsigned char sha1_result[SHA1_OUTPUT_LEN];
unsigned char padded_res[SHA1_BLOCK_SIZE+SHA1_OUTPUT_LEN];
assert(hmac_size <= SHA1_OUTPUT_LEN);
/* pas key with zeros */
utils_pad(padded_key, sizeof(padded_key),
key, key_len, 0x00, SHA1_BLOCK_SIZE);
/* create IPAD */
utils_pad(IPAD, sizeof(IPAD),
NULL, 0, 0x36, SHA1_BLOCK_SIZE);
/* k1 = padded_key xor IPAD */
utils_xor(k1, sizeof(k1),
padded_key, IPAD);
/* create OPAD */
utils_pad(OPAD, sizeof(OPAD),
NULL, 0, 0x5C, SHA1_BLOCK_SIZE);
/* k2 = padded_key xor OPAD */
utils_xor(k2, sizeof(k2),
padded_key, OPAD);
/* append msg to k1 */
utils_append(padded_msg, sizeof(padded_msg),
k1, sizeof(k1), msg, msg_len);
SHA1(padded_msg, sizeof(k1)+msg_len, sha1_result);
/* append previous result to k2 */
utils_append(padded_res, sizeof(padded_res),
k2, sizeof(k2),
sha1_result, sizeof(sha1_result));
SHA1(padded_res, sizeof(k2)+sizeof(sha1_result),
sha1_result);
/* copy the result */
memcpy(hmac, sha1_result, hmac_size);
return 0;
}