/src/libtomcrypt/src/mac/hmac/hmac_done.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ |
2 | | /* SPDX-License-Identifier: Unlicense */ |
3 | | #include "tomcrypt_private.h" |
4 | | |
5 | | /** |
6 | | @file hmac_done.c |
7 | | HMAC support, terminate stream, Tom St Denis/Dobes Vandermeer |
8 | | */ |
9 | | |
10 | | #ifdef LTC_HMAC |
11 | | |
12 | 1.68M | #define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize |
13 | | |
14 | | /** |
15 | | Terminate an HMAC session |
16 | | @param hmac The HMAC state |
17 | | @param out [out] The destination of the HMAC authentication tag |
18 | | @param outlen [in/out] The max size and resulting size of the HMAC authentication tag |
19 | | @return CRYPT_OK if successful |
20 | | */ |
21 | | int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen) |
22 | 22.8k | { |
23 | 22.8k | unsigned char *buf, *isha; |
24 | 22.8k | unsigned long hashsize, i; |
25 | 22.8k | int hash, err; |
26 | | |
27 | 22.8k | LTC_ARGCHK(hmac != NULL); |
28 | 22.8k | LTC_ARGCHK(out != NULL); |
29 | | |
30 | | /* test hash */ |
31 | 22.8k | hash = hmac->hash; |
32 | 22.8k | if((err = hash_is_valid(hash)) != CRYPT_OK) { |
33 | 0 | return err; |
34 | 0 | } |
35 | | |
36 | | /* get the hash message digest size */ |
37 | 22.8k | hashsize = hash_descriptor[hash].hashsize; |
38 | | |
39 | | /* allocate buffers */ |
40 | 22.8k | buf = XMALLOC(LTC_HMAC_BLOCKSIZE); |
41 | 22.8k | isha = XMALLOC(hashsize); |
42 | 22.8k | if (buf == NULL || isha == NULL) { |
43 | 0 | if (buf != NULL) { |
44 | 0 | XFREE(buf); |
45 | 0 | } |
46 | 0 | if (isha != NULL) { |
47 | 0 | XFREE(isha); |
48 | 0 | } |
49 | 0 | return CRYPT_MEM; |
50 | 0 | } |
51 | | |
52 | | /* Get the hash of the first HMAC vector plus the data */ |
53 | 22.8k | if ((err = hash_descriptor[hash].done(&hmac->md, isha)) != CRYPT_OK) { |
54 | 0 | goto LBL_ERR; |
55 | 0 | } |
56 | | |
57 | | /* Create the second HMAC vector vector for step (3) */ |
58 | 1.64M | for(i=0; i < LTC_HMAC_BLOCKSIZE; i++) { |
59 | 1.62M | buf[i] = hmac->key[i] ^ 0x5C; |
60 | 1.62M | } |
61 | | |
62 | | /* Now calculate the "outer" hash for step (5), (6), and (7) */ |
63 | 22.8k | if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) { |
64 | 0 | goto LBL_ERR; |
65 | 0 | } |
66 | 22.8k | if ((err = hash_descriptor[hash].process(&hmac->md, buf, LTC_HMAC_BLOCKSIZE)) != CRYPT_OK) { |
67 | 0 | goto LBL_ERR; |
68 | 0 | } |
69 | 22.8k | if ((err = hash_descriptor[hash].process(&hmac->md, isha, hashsize)) != CRYPT_OK) { |
70 | 0 | goto LBL_ERR; |
71 | 0 | } |
72 | 22.8k | if ((err = hash_descriptor[hash].done(&hmac->md, buf)) != CRYPT_OK) { |
73 | 0 | goto LBL_ERR; |
74 | 0 | } |
75 | | |
76 | | /* copy to output */ |
77 | 718k | for (i = 0; i < hashsize && i < *outlen; i++) { |
78 | 695k | out[i] = buf[i]; |
79 | 695k | } |
80 | 22.8k | *outlen = i; |
81 | | |
82 | 22.8k | err = CRYPT_OK; |
83 | 22.8k | LBL_ERR: |
84 | | #ifdef LTC_CLEAN_STACK |
85 | | zeromem(isha, hashsize); |
86 | | zeromem(buf, hashsize); |
87 | | zeromem(hmac, sizeof(*hmac)); |
88 | | #endif |
89 | | |
90 | 22.8k | XFREE(isha); |
91 | 22.8k | XFREE(buf); |
92 | | |
93 | 22.8k | return err; |
94 | 22.8k | } |
95 | | |
96 | | #endif |