Home | History | Annotate | Download | only in hmac
      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 (at) 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 */
     30 int 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;
     96 LBL_ERR:
     97     /* free the key since we failed */
     98     XFREE(hmac->key);
     99 done:
    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