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