1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4
5 #ifdef LTC_CCM_MODE
6
7 /**
8 Terminate a CCM stream
9 @param ccm The CCM state
10 @param tag [out] The destination for the MAC tag
11 @param taglen [in/out] The length of the MAC tag
12 @return CRYPT_OK on success
13 */
ccm_done(ccm_state * ccm,unsigned char * tag,unsigned long * taglen)14 int ccm_done(ccm_state *ccm,
15 unsigned char *tag, unsigned long *taglen)
16 {
17 unsigned long x, y;
18 int err;
19
20 LTC_ARGCHK(ccm != NULL);
21
22 /* Check all data have been processed */
23 if (ccm->ptlen != ccm->current_ptlen) {
24 return CRYPT_ERROR;
25 }
26
27 LTC_ARGCHK(tag != NULL);
28 LTC_ARGCHK(taglen != NULL);
29
30 if (ccm->x != 0) {
31 if ((err = cipher_descriptor[ccm->cipher]->ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) {
32 return err;
33 }
34 }
35
36 /* setup CTR for the TAG (zero the count) */
37 for (y = 15; y > 15 - ccm->L; y--) {
38 ccm->ctr[y] = 0x00;
39 }
40 if ((err = cipher_descriptor[ccm->cipher]->ecb_encrypt(ccm->ctr, ccm->CTRPAD, &ccm->K)) != CRYPT_OK) {
41 return err;
42 }
43
44 cipher_descriptor[ccm->cipher]->done(&ccm->K);
45
46 /* store the TAG */
47 for (x = 0; x < 16 && x < *taglen; x++) {
48 tag[x] = ccm->PAD[x] ^ ccm->CTRPAD[x];
49 }
50 *taglen = x;
51
52 return CRYPT_OK;
53 }
54
55 #endif
56