1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 
5 /**
6   @file xcbc_process.c
7   XCBC Support, process blocks with XCBC
8 */
9 
10 #ifdef LTC_XCBC
11 
12 /** Process data through XCBC-MAC
13   @param xcbc     The XCBC-MAC state
14   @param in       Input data to process
15   @param inlen    Length of input in octets
16   Return CRYPT_OK on success
17 */
xcbc_process(xcbc_state * xcbc,const unsigned char * in,unsigned long inlen)18 int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen)
19 {
20    int err;
21 #ifdef LTC_FAST
22    int x;
23 #endif
24 
25    LTC_ARGCHK(xcbc != NULL);
26    LTC_ARGCHK(in   != NULL);
27 
28    /* check structure */
29    if ((err = cipher_is_valid(xcbc->cipher)) != CRYPT_OK) {
30       return err;
31    }
32 
33    if ((xcbc->blocksize > cipher_descriptor[xcbc->cipher]->block_length) || (xcbc->blocksize < 0) ||
34        (xcbc->buflen > xcbc->blocksize) || (xcbc->buflen < 0)) {
35       return CRYPT_INVALID_ARG;
36    }
37 
38 #ifdef LTC_FAST
39    if (xcbc->buflen == 0) {
40        while (inlen > (unsigned long)xcbc->blocksize) {
41            for (x = 0; x < xcbc->blocksize; x += sizeof(LTC_FAST_TYPE)) {
42               *(LTC_FAST_TYPE_PTR_CAST(&(xcbc->IV[x]))) ^= *(LTC_FAST_TYPE_PTR_CAST(&(in[x])));
43            }
44            cipher_descriptor[xcbc->cipher]->ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key);
45            in    += xcbc->blocksize;
46            inlen -= xcbc->blocksize;
47        }
48    }
49 #endif
50 
51    while (inlen) {
52       if (xcbc->buflen == xcbc->blocksize) {
53          cipher_descriptor[xcbc->cipher]->ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key);
54          xcbc->buflen = 0;
55       }
56       xcbc->IV[xcbc->buflen++] ^= *in++;
57       --inlen;
58    }
59    return CRYPT_OK;
60 }
61 
62 #endif
63 
64