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;

}