1/* LibTomCrypt, modular cryptographic library -- Tom St Denis 2 * 3 * LibTomCrypt is a library that provides various cryptographic 4 * algorithms in a highly modular and flexible manner. 5 * 6 * The library is free for all purposes without any express 7 * guarantee it works. 8 * 9 * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com 10 */ 11#include "tomcrypt.h" 12 13/** 14 @file hmac_init.c 15 HMAC support, initialize state, Tom St Denis/Dobes Vandermeer 16*/ 17 18#ifdef LTC_HMAC 19 20#define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize 21 22/** 23 Initialize an HMAC context. 24 @param hmac The HMAC state 25 @param hash The index of the hash you want to use 26 @param key The secret key 27 @param keylen The length of the secret key (octets) 28 @return CRYPT_OK if successful 29*/ 30int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen) 31{ 32 unsigned char *buf; 33 unsigned long hashsize; 34 unsigned long i, z; 35 int err; 36 37 LTC_ARGCHK(hmac != NULL); 38 LTC_ARGCHK(key != NULL); 39 40 /* valid hash? */ 41 if ((err = hash_is_valid(hash)) != CRYPT_OK) { 42 return err; 43 } 44 hmac->hash = hash; 45 hashsize = hash_descriptor[hash].hashsize; 46 47 /* valid key length? */ 48 if (keylen == 0) { 49 return CRYPT_INVALID_KEYSIZE; 50 } 51 52 /* allocate ram for buf */ 53 buf = XMALLOC(HMAC_BLOCKSIZE); 54 if (buf == NULL) { 55 return CRYPT_MEM; 56 } 57 58 /* allocate memory for key */ 59 hmac->key = XMALLOC(HMAC_BLOCKSIZE); 60 if (hmac->key == NULL) { 61 XFREE(buf); 62 return CRYPT_MEM; 63 } 64 65 /* (1) make sure we have a large enough key */ 66 if(keylen > HMAC_BLOCKSIZE) { 67 z = HMAC_BLOCKSIZE; 68 if ((err = hash_memory(hash, key, keylen, hmac->key, &z)) != CRYPT_OK) { 69 goto LBL_ERR; 70 } 71 if(hashsize < HMAC_BLOCKSIZE) { 72 zeromem((hmac->key) + hashsize, (size_t)(HMAC_BLOCKSIZE - hashsize)); 73 } 74 keylen = hashsize; 75 } else { 76 XMEMCPY(hmac->key, key, (size_t)keylen); 77 if(keylen < HMAC_BLOCKSIZE) { 78 zeromem((hmac->key) + keylen, (size_t)(HMAC_BLOCKSIZE - keylen)); 79 } 80 } 81 82 /* Create the initial vector for step (3) */ 83 for(i=0; i < HMAC_BLOCKSIZE; i++) { 84 buf[i] = hmac->key[i] ^ 0x36; 85 } 86 87 /* Pre-pend that to the hash data */ 88 if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) { 89 goto LBL_ERR; 90 } 91 92 if ((err = hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE)) != CRYPT_OK) { 93 goto LBL_ERR; 94 } 95 goto done; 96LBL_ERR: 97 /* free the key since we failed */ 98 XFREE(hmac->key); 99done: 100#ifdef LTC_CLEAN_STACK 101 zeromem(buf, HMAC_BLOCKSIZE); 102#endif 103 104 XFREE(buf); 105 return err; 106} 107 108#endif 109 110/* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_init.c,v $ */ 111/* $Revision: 1.5 $ */ 112/* $Date: 2006/11/03 00:39:49 $ */ 113