1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 
5 /**
6   @file hmac_memory.c
7   HMAC support, process a block of memory, Tom St Denis/Dobes Vandermeer
8 */
9 
10 #ifdef LTC_HMAC
11 
12 /**
13    HMAC a block of memory to produce the authentication tag
14    @param hash      The index of the hash to use
15    @param key       The secret key
16    @param keylen    The length of the secret key (octets)
17    @param in        The data to HMAC
18    @param inlen     The length of the data to HMAC (octets)
19    @param out       [out] Destination of the authentication tag
20    @param outlen    [in/out] Max size and resulting size of authentication tag
21    @return CRYPT_OK if successful
22 */
hmac_memory(int hash,const unsigned char * key,unsigned long keylen,const unsigned char * in,unsigned long inlen,unsigned char * out,unsigned long * outlen)23 int hmac_memory(int hash,
24                 const unsigned char *key,  unsigned long keylen,
25                 const unsigned char *in,   unsigned long inlen,
26                       unsigned char *out,  unsigned long *outlen)
27 {
28     hmac_state *hmac;
29     int         err;
30 
31     LTC_ARGCHK(key    != NULL);
32     LTC_ARGCHK(in     != NULL);
33     LTC_ARGCHK(out    != NULL);
34     LTC_ARGCHK(outlen != NULL);
35 
36     /* make sure hash descriptor is valid */
37     if ((err = hash_is_valid(hash)) != CRYPT_OK) {
38        return err;
39     }
40 
41     /* is there a descriptor? */
42     if (hash_descriptor[hash]->hmac_block != NULL) {
43         return hash_descriptor[hash]->hmac_block(key, keylen, in, inlen, out, outlen);
44     }
45 
46     /* nope, so call the hmac functions */
47     /* allocate ram for hmac state */
48     hmac = XMALLOC(sizeof(hmac_state));
49     if (hmac == NULL) {
50        return CRYPT_MEM;
51     }
52 
53     if ((err = hmac_init(hmac, hash, key, keylen)) != CRYPT_OK) {
54        goto LBL_ERR;
55     }
56 
57     if ((err = hmac_process(hmac, in, inlen)) != CRYPT_OK) {
58        goto LBL_ERR;
59     }
60 
61     if ((err = hmac_done(hmac, out, outlen)) != CRYPT_OK) {
62        goto LBL_ERR;
63     }
64 
65    err = CRYPT_OK;
66 LBL_ERR:
67 #ifdef LTC_CLEAN_STACK
68    zeromem(hmac, sizeof(hmac_state));
69 #endif
70 
71    XFREE(hmac);
72    return err;
73 }
74 
75 #endif
76 
77