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 omac_process.c
14   OMAC1 support, process data, Tom St Denis
15 */
16 
17 
18 #ifdef LTC_OMAC
19 
20 /**
21    Process data through OMAC
22    @param omac     The OMAC state
23    @param in       The input data to send through OMAC
24    @param inlen    The length of the input (octets)
25    @return CRYPT_OK if successful
26 */
omac_process(omac_state * omac,const unsigned char * in,unsigned long inlen)27 int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen)
28 {
29    unsigned long n, x;
30    int           err;
31 
32    LTC_ARGCHK(omac  != NULL);
33    LTC_ARGCHK(in    != NULL);
34    if ((err = cipher_is_valid(omac->cipher_idx)) != CRYPT_OK) {
35       return err;
36    }
37 
38    if ((omac->buflen > (int)sizeof(omac->block)) || (omac->buflen < 0) ||
39        (omac->blklen > (int)sizeof(omac->block)) || (omac->buflen > omac->blklen)) {
40       return CRYPT_INVALID_ARG;
41    }
42 
43 #ifdef LTC_FAST
44    {
45      unsigned long blklen = cipher_descriptor[omac->cipher_idx]->block_length;
46 
47      if (omac->buflen == 0 && inlen > blklen) {
48         unsigned long y;
49         for (x = 0; x < (inlen - blklen); x += blklen) {
50             for (y = 0; y < blklen; y += sizeof(LTC_FAST_TYPE)) {
51                 *(LTC_FAST_TYPE_PTR_CAST(&omac->prev[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&in[y]));
52             }
53             in += blklen;
54             if ((err = cipher_descriptor[omac->cipher_idx]->ecb_encrypt(omac->prev, omac->prev, &omac->key)) != CRYPT_OK) {
55                return err;
56             }
57         }
58         inlen -= x;
59      }
60    }
61 #endif
62 
63    while (inlen != 0) {
64        /* ok if the block is full we xor in prev, encrypt and replace prev */
65        if (omac->buflen == omac->blklen) {
66           for (x = 0; x < (unsigned long)omac->blklen; x++) {
67               omac->block[x] ^= omac->prev[x];
68           }
69           if ((err = cipher_descriptor[omac->cipher_idx]->ecb_encrypt(omac->block, omac->prev, &omac->key)) != CRYPT_OK) {
70              return err;
71           }
72           omac->buflen = 0;
73        }
74 
75        /* add bytes */
76        n = MIN(inlen, (unsigned long)(omac->blklen - omac->buflen));
77        XMEMCPY(omac->block + omac->buflen, in, n);
78        omac->buflen  += n;
79        inlen         -= n;
80        in            += n;
81    }
82 
83    return CRYPT_OK;
84 }
85 
86 #endif
87 
88 
89 /* ref:         $Format:%D$ */
90 /* git commit:  $Format:%H$ */
91 /* commit time: $Format:%ai$ */
92