51 broke -E logic completely, rewise it
[tfcrypt.git] / tfxts.c
1 #include <string.h>
2 #include "tfdef.h"
3
4 static inline void xts_mult_x(TF_UNIT_TYPE *x)
5 {
6         size_t i, t, tt;
7
8         for (i = t = 0; i < TF_NR_BLOCK_UNITS; i++) {
9                 tt = x[i] >> (TF_UNIT_BITS-1);
10                 x[i] = ((x[i] << 1) | t) & ((TF_UNIT_TYPE)~0);
11                 t = tt;
12         }
13         if (tt) x[0] ^= IRR_POLY_CONST;
14 }
15
16 static void xts_encrypt(const void *keyx, const void *keyz, void *ctr, void *out, const void *in, size_t sz)
17 {
18         const TF_BYTE_TYPE *uin = in;
19         TF_BYTE_TYPE *uout = out;
20         TF_UNIT_TYPE x[TF_NR_BLOCK_UNITS], y[TF_NR_BLOCK_UNITS];
21         TF_UNIT_TYPE tctr[TF_NR_BLOCK_UNITS];
22         TF_UNIT_TYPE *uctr = ctr;
23         const TF_UNIT_TYPE *ukeyx = keyx, *ukeyz = keyz;
24         size_t sl = sz, i;
25
26         tf_encrypt_rawblk(tctr, uctr, ukeyz);
27
28         if (sl >= (TF_BLOCK_SIZE * 2)) {
29                 do {
30 _last:                  memcpy(x, uin, TF_BLOCK_SIZE);
31                         uin += TF_BLOCK_SIZE;
32                         data_to_words(x, TF_BLOCK_SIZE);
33
34                         ctr_inc(uctr, TF_NR_BLOCK_UNITS);
35                         for (i = 0; i < TF_NR_BLOCK_UNITS; i++) y[i] = x[i] ^ tctr[i];
36                         tf_encrypt_rawblk(x, y, ukeyx);
37                         for (i = 0; i < TF_NR_BLOCK_UNITS; i++) x[i] ^= tctr[i];
38
39                         xts_mult_x(tctr);
40
41                         data_to_words(x, TF_BLOCK_SIZE);
42                         memcpy(uout, x, TF_BLOCK_SIZE);
43                         uout += TF_BLOCK_SIZE;
44                 } while ((sl -= TF_BLOCK_SIZE) >= (TF_BLOCK_SIZE * 2));
45         }
46
47         if (sl) {
48                 if (sl-TF_BLOCK_SIZE == 0) goto _last;
49                 if (sl < TF_BLOCK_SIZE) {
50                         memset(x, 0, TF_BLOCK_SIZE);
51                         memcpy(x, uin, sl);
52                         data_to_words(x, TF_BLOCK_SIZE);
53
54                         ctr_inc(uctr, TF_NR_BLOCK_UNITS);
55                         tf_encrypt_rawblk(y, uctr, ukeyx);
56                         for (i = 0; i < TF_NR_BLOCK_UNITS; i++) y[i] ^= x[i];
57
58                         data_to_words(y, TF_BLOCK_SIZE);
59                         memcpy(uout, y, sl);
60
61                         goto _done;
62                 }
63
64                 memcpy(x, uin, TF_BLOCK_SIZE);
65                 uin += TF_BLOCK_SIZE;
66                 data_to_words(x, TF_BLOCK_SIZE);
67
68                 ctr_inc(uctr, TF_NR_BLOCK_UNITS);
69                 for (i = 0; i < TF_NR_BLOCK_UNITS; i++) y[i] = x[i] ^ tctr[i];
70                 tf_encrypt_rawblk(x, y, ukeyx);
71                 for (i = 0; i < TF_NR_BLOCK_UNITS; i++) x[i] ^= tctr[i];
72
73                 memcpy(y, x, TF_BLOCK_SIZE);
74                 sl -= TF_BLOCK_SIZE;
75
76                 xts_mult_x(tctr);
77
78                 tf_encrypt_rawblk(tctr, uctr, ukeyz);
79
80                 memcpy(x, uin, sl);
81                 data_to_words(x, sl);
82
83                 for (i = 0; i < TF_NR_BLOCK_UNITS; i++) x[i] ^= tctr[i];
84                 tf_encrypt_rawblk(x, x, ukeyx);
85                 for (i = 0; i < TF_NR_BLOCK_UNITS; i++) x[i] ^= tctr[i];
86
87                 data_to_words(x, TF_BLOCK_SIZE);
88                 memcpy(uout, x, TF_BLOCK_SIZE);
89                 uout += TF_BLOCK_SIZE;
90
91                 data_to_words(y, TF_BLOCK_SIZE);
92                 memcpy(uout, y, sl);
93         }
94
95 _done:  memset(tctr, 0, TF_BLOCK_SIZE);
96         memset(x, 0, TF_BLOCK_SIZE);
97         memset(y, 0, TF_BLOCK_SIZE);
98 }
99
100 void tf_xts_encrypt(const void *keyx, const void *keyz, void *ctr, void *out, const void *in, size_t sz, size_t bpi)
101 {
102         const TF_BYTE_TYPE *uin = in;
103         TF_BYTE_TYPE *uout = out;
104         size_t sl = sz, sx = TF_BLOCKS_TO_BYTES(bpi);
105
106         if (sl >= sx) {
107                 do {
108                         xts_encrypt(keyx, keyz, ctr, uout, uin, sx);
109                         uout += sx;
110                         uin += sx;
111                 } while ((sl -= sx) >= sx);
112         }
113
114         if (sl) xts_encrypt(keyx, keyz, ctr, uout, uin, sl);
115 }
116
117 static void xts_decrypt(const void *keyx, const void *keyz, void *ctr, void *out, const void *in, size_t sz)
118 {
119         const TF_BYTE_TYPE *uin = in;
120         TF_BYTE_TYPE *uout = out, *s, *d;
121         TF_UNIT_TYPE x[TF_NR_BLOCK_UNITS], y[TF_NR_BLOCK_UNITS];
122         TF_UNIT_TYPE tctr[TF_NR_BLOCK_UNITS], zctr[TF_NR_BLOCK_UNITS];
123         TF_UNIT_TYPE *uctr = ctr;
124         const TF_UNIT_TYPE *ukeyx = keyx, *ukeyz = keyz;
125         size_t sl = sz, i;
126
127         tf_encrypt_rawblk(tctr, uctr, ukeyz);
128
129         if (sl >= (TF_BLOCK_SIZE * 2)) {
130                 do {
131 _last:                  memcpy(x, uin, TF_BLOCK_SIZE);
132                         uin += TF_BLOCK_SIZE;
133                         data_to_words(x, TF_BLOCK_SIZE);
134
135                         ctr_inc(uctr, TF_NR_BLOCK_UNITS);
136                         for (i = 0; i < TF_NR_BLOCK_UNITS; i++) y[i] = x[i] ^ tctr[i];
137                         tf_decrypt_rawblk(x, y, ukeyx);
138                         for (i = 0; i < TF_NR_BLOCK_UNITS; i++) x[i] ^= tctr[i];
139
140                         xts_mult_x(tctr);
141
142                         data_to_words(x, TF_BLOCK_SIZE);
143                         memcpy(uout, x, TF_BLOCK_SIZE);
144                         uout += TF_BLOCK_SIZE;
145                 } while ((sl -= TF_BLOCK_SIZE) >= (TF_BLOCK_SIZE * 2));
146         }
147
148         if (sl) {
149                 if (sl-TF_BLOCK_SIZE == 0) goto _last;
150                 if (sl < TF_BLOCK_SIZE) {
151                         memset(x, 0, TF_BLOCK_SIZE);
152                         memcpy(x, uin, sl);
153                         data_to_words(x, TF_BLOCK_SIZE);
154
155                         ctr_inc(uctr, TF_NR_BLOCK_UNITS);
156                         tf_encrypt_rawblk(y, uctr, ukeyx);
157                         for (i = 0; i < TF_NR_BLOCK_UNITS; i++) y[i] ^= x[i];
158
159                         data_to_words(y, TF_BLOCK_SIZE);
160                         memcpy(uout, y, sl);
161
162                         goto _done;
163                 }
164
165                 memcpy(x, uin, TF_BLOCK_SIZE);
166                 uin += TF_BLOCK_SIZE;
167                 data_to_words(x, TF_BLOCK_SIZE);
168
169                 ctr_inc(uctr, TF_NR_BLOCK_UNITS);
170                 memcpy(zctr, tctr, TF_BLOCK_SIZE);
171                 xts_mult_x(tctr);
172
173                 tf_encrypt_rawblk(tctr, uctr, ukeyz);
174
175                 for (i = 0; i < TF_NR_BLOCK_UNITS; i++) x[i] ^= tctr[i];
176                 tf_decrypt_rawblk(x, x, ukeyx);
177                 for (i = 0; i < TF_NR_BLOCK_UNITS; i++) x[i] ^= tctr[i];
178
179                 sl -= TF_BLOCK_SIZE;
180                 memcpy(y, uin, sl);
181                 data_to_words(y, sl);
182
183                 s = (TF_BYTE_TYPE *)y;
184                 d = (TF_BYTE_TYPE *)x;
185                 memcpy(s+sl, d+sl, TF_BLOCK_SIZE-sl);
186                 for (i = 0; i < TF_NR_BLOCK_UNITS; i++) y[i] ^= zctr[i];
187                 tf_decrypt_rawblk(y, y, ukeyx);
188                 for (i = 0; i < TF_NR_BLOCK_UNITS; i++) y[i] ^= zctr[i];
189
190                 data_to_words(y, TF_BLOCK_SIZE);
191                 memcpy(uout, y, TF_BLOCK_SIZE);
192                 uout += TF_BLOCK_SIZE;
193
194                 data_to_words(x, TF_BLOCK_SIZE);
195                 memcpy(uout, x, sl);
196         }
197
198 _done:  memset(tctr, 0, TF_BLOCK_SIZE);
199         memset(zctr, 0, TF_BLOCK_SIZE);
200         memset(x, 0, TF_BLOCK_SIZE);
201         memset(y, 0, TF_BLOCK_SIZE);
202 }
203
204 void tf_xts_decrypt(const void *keyx, const void *keyz, void *ctr, void *out, const void *in, size_t sz, size_t bpi)
205 {
206         const TF_BYTE_TYPE *uin = in;
207         TF_BYTE_TYPE *uout = out;
208         size_t sl = sz, sx = TF_BLOCKS_TO_BYTES(bpi);
209
210         if (sl >= sx) {
211                 do {
212                         xts_decrypt(keyx, keyz, ctr, uout, uin, sx);
213                         uout += sx;
214                         uin += sx;
215                 } while ((sl -= sx) >= sx);
216         }
217
218         if (sl) xts_decrypt(keyx, keyz, ctr, uout, uin, sl);
219 }