]> pd.if.org Git - zpackage/blob - libtomcrypt/src/mac/omac/omac_process.c
4ae2bd11c5219fcc2a9067dca23565c9d1dff5fc
[zpackage] / libtomcrypt / src / mac / omac / omac_process.c
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  */
9 #include "tomcrypt.h"
10
11 /**
12   @file omac_process.c
13   OMAC1 support, process data, Tom St Denis
14 */
15
16
17 #ifdef LTC_OMAC
18
19 /**
20    Process data through OMAC
21    @param omac     The OMAC state
22    @param in       The input data to send through OMAC
23    @param inlen    The length of the input (octets)
24    @return CRYPT_OK if successful
25 */
26 int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen)
27 {
28    unsigned long n, x;
29    int           err;
30
31    LTC_ARGCHK(omac  != NULL);
32    LTC_ARGCHK(in    != NULL);
33    if ((err = cipher_is_valid(omac->cipher_idx)) != CRYPT_OK) {
34       return err;
35    }
36
37    if ((omac->buflen > (int)sizeof(omac->block)) || (omac->buflen < 0) ||
38        (omac->blklen > (int)sizeof(omac->block)) || (omac->buflen > omac->blklen)) {
39       return CRYPT_INVALID_ARG;
40    }
41
42 #ifdef LTC_FAST
43    {
44      unsigned long blklen = cipher_descriptor[omac->cipher_idx].block_length;
45
46      if (omac->buflen == 0 && inlen > blklen) {
47         unsigned long y;
48         for (x = 0; x < (inlen - blklen); x += blklen) {
49             for (y = 0; y < blklen; y += sizeof(LTC_FAST_TYPE)) {
50                 *(LTC_FAST_TYPE_PTR_CAST(&omac->prev[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&in[y]));
51             }
52             in += blklen;
53             if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key)) != CRYPT_OK) {
54                return err;
55             }
56         }
57         inlen -= x;
58      }
59    }
60 #endif
61
62    while (inlen != 0) {
63        /* ok if the block is full we xor in prev, encrypt and replace prev */
64        if (omac->buflen == omac->blklen) {
65           for (x = 0; x < (unsigned long)omac->blklen; x++) {
66               omac->block[x] ^= omac->prev[x];
67           }
68           if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key)) != CRYPT_OK) {
69              return err;
70           }
71           omac->buflen = 0;
72        }
73
74        /* add bytes */
75        n = MIN(inlen, (unsigned long)(omac->blklen - omac->buflen));
76        XMEMCPY(omac->block + omac->buflen, in, n);
77        omac->buflen  += n;
78        inlen         -= n;
79        in            += n;
80    }
81
82    return CRYPT_OK;
83 }
84
85 #endif
86
87
88 /* ref:         $Format:%D$ */
89 /* git commit:  $Format:%H$ */
90 /* commit time: $Format:%ai$ */