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