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