/***********************************************************
* libsrs_alt - A simple SRS implementation *
***********************************************************/
/* (C)2004 Miles Wilton <miles@mirtol.com> */
/* License: GPL */
/* This file:
hmac.c
Perform HMAC
*/
#include <stdlib.h>
#include <string.h>
#include "hmac.h"
/***********************************************************
mHMAC_start - Init HMAC structure and start DIGEST
*/
int mHMAC_start(mHMAC *hmac, mHMAC_DIGEST *hmac_digest, char *secret, int secret_len)
{
char ipad[mHMAC_MAX_BLOCK_SIZE];
int n;
if(!hmac_digest)
return -1;
// Setup hmac
hmac->hmac_digest = hmac_digest;
hmac->digest_struct = malloc(hmac_digest->digest_struct_size);
// Compile secret
if(secret_len > hmac_digest->block_size)
{
// Digest the secret because it's too long
hmac_digest->DIGEST_start(hmac->digest_struct);
hmac_digest->DIGEST_process(hmac->digest_struct, secret, secret_len);
hmac_digest->DIGEST_end(hmac->digest_struct, hmac->secret);
memset(hmac->secret + hmac_digest->digest_length, 0, hmac_digest->block_size - hmac_digest->digest_length);
}
else
{
memcpy(hmac->secret, secret, secret_len);
memset(hmac->secret + secret_len, 0, hmac_digest->block_size - secret_len);
}
// Start DIGEST, beginning with compiled secret XORed with 0x36
memcpy(ipad, hmac->secret, hmac_digest->block_size);
for(n = 0; n < hmac_digest->block_size; n++)
ipad[n] ^= 0x36;
hmac_digest->DIGEST_start(hmac->digest_struct);
hmac_digest->DIGEST_process(hmac->digest_struct, ipad, hmac_digest->block_size);
return 0;
}
/***********************************************************
mHMAC_process - Add a string to hash
*/
int mHMAC_process(mHMAC *hmac, unsigned char *data, int data_len)
{
return hmac->hmac_digest->DIGEST_process(hmac->digest_struct, data, data_len);
}
/***********************************************************
mHMAC_end - Finalise hash
*/
int mHMAC_end(mHMAC *hmac, unsigned char *hash_buffer)
{
char opad[mHMAC_MAX_BLOCK_SIZE];
int n;
hmac->hmac_digest->DIGEST_end(hmac->digest_struct, hmac->hash);
// Start second DIGEST, beginning with compiled secret XORed with 0x5C
memcpy(opad, hmac->secret, hmac->hmac_digest->block_size);
for(n = 0; n < hmac->hmac_digest->block_size; n++)
opad[n] ^= 0x5C;
hmac->hmac_digest->DIGEST_start(hmac->digest_struct);
hmac->hmac_digest->DIGEST_process(hmac->digest_struct, opad, hmac->hmac_digest->block_size);
// Append our first hash
hmac->hmac_digest->DIGEST_process(hmac->digest_struct, hmac->hash, hmac->hmac_digest->digest_length);
// And finish
hmac->hmac_digest->DIGEST_end(hmac->digest_struct, hmac->hash);
if(hash_buffer)
mHMAC_gethash(hmac, hash_buffer);
return 0;
}
/***********************************************************
mHMAC_gethash - Get hash string
*/
int mHMAC_gethash(mHMAC *hmac, unsigned char *hash_buffer)
{
memcpy(hash_buffer, hmac->hash, hmac->hmac_digest->digest_length);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1