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 lrw_process.c
14 LRW_MODE implementation, Encrypt/decrypt blocks, Tom St Denis
15 */
16
17 #ifdef LTC_LRW_MODE
18
19 /**
20 Process blocks with LRW, since decrypt/encrypt are largely the same they share this code.
21 @param pt The "input" data
22 @param ct [out] The "output" data
23 @param len The length of the input, must be a multiple of 128-bits (16 octets)
24 @param mode LRW_ENCRYPT or LRW_DECRYPT
25 @param lrw The LRW state
26 @return CRYPT_OK if successful
27 */
lrw_process(const unsigned char * pt,unsigned char * ct,unsigned long len,int mode,symmetric_LRW * lrw)28 int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, int mode, symmetric_LRW *lrw)
29 {
30 unsigned char prod[16];
31 int x, err;
32 #ifdef LTC_LRW_TABLES
33 int y;
34 #endif
35
36 LTC_ARGCHK(pt != NULL);
37 LTC_ARGCHK(ct != NULL);
38 LTC_ARGCHK(lrw != NULL);
39
40 if (len & 15) {
41 return CRYPT_INVALID_ARG;
42 }
43
44 while (len) {
45 /* copy pad */
46 XMEMCPY(prod, lrw->pad, 16);
47
48 /* increment IV */
49 for (x = 15; x >= 0; x--) {
50 lrw->IV[x] = (lrw->IV[x] + 1) & 255;
51 if (lrw->IV[x]) {
52 break;
53 }
54 }
55
56 /* update pad */
57 #ifdef LTC_LRW_TABLES
58 /* for each byte changed we undo it's affect on the pad then add the new product */
59 for (; x < 16; x++) {
60 #ifdef LTC_FAST
61 for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
62 *(LTC_FAST_TYPE_PTR_CAST(lrw->pad + y)) ^= *(LTC_FAST_TYPE_PTR_CAST(&lrw->PC[x][lrw->IV[x]][y])) ^ *(LTC_FAST_TYPE_PTR_CAST(&lrw->PC[x][(lrw->IV[x]-1)&255][y]));
63 }
64 #else
65 for (y = 0; y < 16; y++) {
66 lrw->pad[y] ^= lrw->PC[x][lrw->IV[x]][y] ^ lrw->PC[x][(lrw->IV[x]-1)&255][y];
67 }
68 #endif
69 }
70 #else
71 gcm_gf_mult(lrw->tweak, lrw->IV, lrw->pad);
72 #endif
73
74 /* xor prod */
75 #ifdef LTC_FAST
76 for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {
77 *(LTC_FAST_TYPE_PTR_CAST(ct + x)) = *(LTC_FAST_TYPE_PTR_CAST(pt + x)) ^ *(LTC_FAST_TYPE_PTR_CAST(prod + x));
78 }
79 #else
80 for (x = 0; x < 16; x++) {
81 ct[x] = pt[x] ^ prod[x];
82 }
83 #endif
84
85 /* send through cipher */
86 if (mode == LRW_ENCRYPT) {
87 if ((err = cipher_descriptor[lrw->cipher]->ecb_encrypt(ct, ct, &lrw->key)) != CRYPT_OK) {
88 return err;
89 }
90 } else {
91 if ((err = cipher_descriptor[lrw->cipher]->ecb_decrypt(ct, ct, &lrw->key)) != CRYPT_OK) {
92 return err;
93 }
94 }
95
96 /* xor prod */
97 #ifdef LTC_FAST
98 for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {
99 *(LTC_FAST_TYPE_PTR_CAST(ct + x)) = *(LTC_FAST_TYPE_PTR_CAST(ct + x)) ^ *(LTC_FAST_TYPE_PTR_CAST(prod + x));
100 }
101 #else
102 for (x = 0; x < 16; x++) {
103 ct[x] = ct[x] ^ prod[x];
104 }
105 #endif
106
107 /* move to next */
108 pt += 16;
109 ct += 16;
110 len -= 16;
111 }
112
113 return CRYPT_OK;
114 }
115
116 #endif
117 /* ref: $Format:%D$ */
118 /* git commit: $Format:%H$ */
119 /* commit time: $Format:%ai$ */
120