• 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_done.c
15   HMAC support, terminate stream, Tom St Denis/Dobes Vandermeer
16 */
17 
18 #ifdef LTC_HMAC
19 
20 #define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
21 
22 /**
23    Terminate an HMAC session
24    @param hmac    The HMAC state
25    @param out     [out] The destination of the HMAC authentication tag
26    @param outlen  [in/out]  The max size and resulting size of the HMAC authentication tag
27    @return CRYPT_OK if successful
28 */
hmac_done(hmac_state * hmac,unsigned char * out,unsigned long * outlen)29 int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen)
30 {
31     unsigned char *buf, *isha;
32     unsigned long hashsize, i;
33     int hash, err;
34 
35     LTC_ARGCHK(hmac  != NULL);
36     LTC_ARGCHK(out   != NULL);
37 
38     /* test hash */
39     hash = hmac->hash;
40     if((err = hash_is_valid(hash)) != CRYPT_OK) {
41         return err;
42     }
43 
44     /* get the hash message digest size */
45     hashsize = hash_descriptor[hash].hashsize;
46 
47     /* allocate buffers */
48     buf  = XMALLOC(HMAC_BLOCKSIZE);
49     isha = XMALLOC(hashsize);
50     if (buf == NULL || isha == NULL) {
51        if (buf != NULL) {
52           XFREE(buf);
53        }
54        if (isha != NULL) {
55           XFREE(isha);
56        }
57        return CRYPT_MEM;
58     }
59 
60     /* Get the hash of the first HMAC vector plus the data */
61     if ((err = hash_descriptor[hash].done(&hmac->md, isha)) != CRYPT_OK) {
62        goto LBL_ERR;
63     }
64 
65     /* Create the second HMAC vector vector for step (3) */
66     for(i=0; i < HMAC_BLOCKSIZE; i++) {
67         buf[i] = hmac->key[i] ^ 0x5C;
68     }
69 
70     /* Now calculate the "outer" hash for step (5), (6), and (7) */
71     if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) {
72        goto LBL_ERR;
73     }
74     if ((err = hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE)) != CRYPT_OK) {
75        goto LBL_ERR;
76     }
77     if ((err = hash_descriptor[hash].process(&hmac->md, isha, hashsize)) != CRYPT_OK) {
78        goto LBL_ERR;
79     }
80     if ((err = hash_descriptor[hash].done(&hmac->md, buf)) != CRYPT_OK) {
81        goto LBL_ERR;
82     }
83 
84     /* copy to output  */
85     for (i = 0; i < hashsize && i < *outlen; i++) {
86         out[i] = buf[i];
87     }
88     *outlen = i;
89 
90     err = CRYPT_OK;
91 LBL_ERR:
92     XFREE(hmac->key);
93 #ifdef LTC_CLEAN_STACK
94     zeromem(isha, hashsize);
95     zeromem(buf,  hashsize);
96     zeromem(hmac, sizeof(*hmac));
97 #endif
98 
99     XFREE(isha);
100     XFREE(buf);
101 
102     return err;
103 }
104 
105 #endif
106 
107 /* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_done.c,v $ */
108 /* $Revision: 1.5 $ */
109 /* $Date: 2006/11/03 00:39:49 $ */
110