1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 
5 /**
6   @file omac_process.c
7   OMAC1 support, process data, Tom St Denis
8 */
9 
10 
11 #ifdef LTC_OMAC
12 
13 /**
14    Process data through OMAC
15    @param omac     The OMAC state
16    @param in       The input data to send through OMAC
17    @param inlen    The length of the input (octets)
18    @return CRYPT_OK if successful
19 */
omac_process(omac_state * omac,const unsigned char * in,unsigned long inlen)20 int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen)
21 {
22    unsigned long n, x;
23    int           err;
24 
25    LTC_ARGCHK(omac  != NULL);
26    LTC_ARGCHK(in    != NULL);
27    if ((err = cipher_is_valid(omac->cipher_idx)) != CRYPT_OK) {
28       return err;
29    }
30 
31    if ((omac->buflen > (int)sizeof(omac->block)) || (omac->buflen < 0) ||
32        (omac->blklen > (int)sizeof(omac->block)) || (omac->buflen > omac->blklen)) {
33       return CRYPT_INVALID_ARG;
34    }
35 
36 #ifdef LTC_FAST
37    {
38      unsigned long blklen = cipher_descriptor[omac->cipher_idx]->block_length;
39 
40      if (omac->buflen == 0 && inlen > blklen) {
41         unsigned long y;
42         for (x = 0; x < (inlen - blklen); x += blklen) {
43             for (y = 0; y < blklen; y += sizeof(LTC_FAST_TYPE)) {
44                 *(LTC_FAST_TYPE_PTR_CAST(&omac->prev[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&in[y]));
45             }
46             in += blklen;
47             if ((err = cipher_descriptor[omac->cipher_idx]->ecb_encrypt(omac->prev, omac->prev, &omac->key)) != CRYPT_OK) {
48                return err;
49             }
50         }
51         inlen -= x;
52      }
53    }
54 #endif
55 
56    while (inlen != 0) {
57        /* ok if the block is full we xor in prev, encrypt and replace prev */
58        if (omac->buflen == omac->blklen) {
59           for (x = 0; x < (unsigned long)omac->blklen; x++) {
60               omac->block[x] ^= omac->prev[x];
61           }
62           if ((err = cipher_descriptor[omac->cipher_idx]->ecb_encrypt(omac->block, omac->prev, &omac->key)) != CRYPT_OK) {
63              return err;
64           }
65           omac->buflen = 0;
66        }
67 
68        /* add bytes */
69        n = MIN(inlen, (unsigned long)(omac->blklen - omac->buflen));
70        XMEMCPY(omac->block + omac->buflen, in, n);
71        omac->buflen  += n;
72        inlen         -= n;
73        in            += n;
74    }
75 
76    return CRYPT_OK;
77 }
78 
79 #endif
80 
81