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