• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
hmac_init(hmac_state * hmac,int hash,const unsigned char * key,unsigned long keylen)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