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