1 // SPDX-License-Identifier: BSD-2-Clause
2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3  *
4  * LibTomCrypt is a library that provides various cryptographic
5  * algorithms in a highly modular and flexible manner.
6  *
7  * The library is free for all purposes without any express
8  * guarantee it works.
9  */
10 #include "tomcrypt_private.h"
11 
12 /**
13   @file xcbc_done.c
14   XCBC Support, terminate the state
15 */
16 
17 #ifdef LTC_XCBC
18 
19 /** Terminate the XCBC-MAC state
20   @param xcbc     XCBC state to terminate
21   @param out      [out] Destination for the MAC tag
22   @param outlen   [in/out] Destination size and final tag size
23   Return CRYPT_OK on success
24 */
xcbc_done(xcbc_state * xcbc,unsigned char * out,unsigned long * outlen)25 int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen)
26 {
27    int err, x;
28    LTC_ARGCHK(xcbc != NULL);
29    LTC_ARGCHK(out  != NULL);
30 
31    /* check structure */
32    if ((err = cipher_is_valid(xcbc->cipher)) != CRYPT_OK) {
33       return err;
34    }
35 
36    if ((xcbc->blocksize > cipher_descriptor[xcbc->cipher]->block_length) || (xcbc->blocksize < 0) ||
37        (xcbc->buflen > xcbc->blocksize) || (xcbc->buflen < 0)) {
38       return CRYPT_INVALID_ARG;
39    }
40 
41    /* which key do we use? */
42    if (xcbc->buflen == xcbc->blocksize) {
43       /* k2 */
44       for (x = 0; x < xcbc->blocksize; x++) {
45          xcbc->IV[x] ^= xcbc->K[1][x];
46       }
47    } else {
48       xcbc->IV[xcbc->buflen] ^= 0x80;
49       /* k3 */
50       for (x = 0; x < xcbc->blocksize; x++) {
51          xcbc->IV[x] ^= xcbc->K[2][x];
52       }
53    }
54 
55    /* encrypt */
56    cipher_descriptor[xcbc->cipher]->ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key);
57    cipher_descriptor[xcbc->cipher]->done(&xcbc->key);
58 
59    /* extract tag */
60    for (x = 0; x < xcbc->blocksize && (unsigned long)x < *outlen; x++) {
61       out[x] = xcbc->IV[x];
62    }
63    *outlen = x;
64 
65 #ifdef LTC_CLEAN_STACK
66    zeromem(xcbc, sizeof(*xcbc));
67 #endif
68    return CRYPT_OK;
69 }
70 
71 #endif
72 
73 /* ref:         $Format:%D$ */
74 /* git commit:  $Format:%H$ */
75 /* commit time: $Format:%ai$ */
76 
77