File Coverage

src/symcipher/des_tab.c
Criterion Covered Total %
statement 0 64 0.0
branch 0 8 0.0
condition n/a
subroutine n/a
pod n/a
total 0 72 0.0


line stmt bran cond sub pod time code
1             /*
2             * Copyright (c) 2016 Thomas Pornin
3             *
4             * Permission is hereby granted, free of charge, to any person obtaining
5             * a copy of this software and associated documentation files (the
6             * "Software"), to deal in the Software without restriction, including
7             * without limitation the rights to use, copy, modify, merge, publish,
8             * distribute, sublicense, and/or sell copies of the Software, and to
9             * permit persons to whom the Software is furnished to do so, subject to
10             * the following conditions:
11             *
12             * The above copyright notice and this permission notice shall be
13             * included in all copies or substantial portions of the Software.
14             *
15             * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16             * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17             * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18             * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19             * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20             * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21             * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22             * SOFTWARE.
23             */
24              
25             #include "inner.h"
26              
27             /*
28             * PC2left[x] tells where bit x goes when applying PC-2. 'x' is a bit
29             * position in the left rotated key word. Both position are in normal
30             * order (rightmost bit is 0).
31             */
32             static const unsigned char PC2left[] = {
33             16, 3, 7, 24, 20, 11, 24,
34             13, 2, 10, 24, 22, 5, 15,
35             23, 1, 9, 21, 12, 24, 6,
36             4, 14, 18, 8, 17, 0, 19
37             };
38              
39             /*
40             * Similar to PC2left[x], for the right rotated key word.
41             */
42             static const unsigned char PC2right[] = {
43             8, 18, 24, 6, 22, 15, 3,
44             10, 12, 19, 5, 14, 11, 24,
45             4, 23, 16, 9, 24, 20, 2,
46             24, 7, 13, 0, 21, 17, 1
47             };
48              
49             /*
50             * S-boxes and PC-1 merged.
51             */
52             static const uint32_t S1[] = {
53             0x00808200, 0x00000000, 0x00008000, 0x00808202,
54             0x00808002, 0x00008202, 0x00000002, 0x00008000,
55             0x00000200, 0x00808200, 0x00808202, 0x00000200,
56             0x00800202, 0x00808002, 0x00800000, 0x00000002,
57             0x00000202, 0x00800200, 0x00800200, 0x00008200,
58             0x00008200, 0x00808000, 0x00808000, 0x00800202,
59             0x00008002, 0x00800002, 0x00800002, 0x00008002,
60             0x00000000, 0x00000202, 0x00008202, 0x00800000,
61             0x00008000, 0x00808202, 0x00000002, 0x00808000,
62             0x00808200, 0x00800000, 0x00800000, 0x00000200,
63             0x00808002, 0x00008000, 0x00008200, 0x00800002,
64             0x00000200, 0x00000002, 0x00800202, 0x00008202,
65             0x00808202, 0x00008002, 0x00808000, 0x00800202,
66             0x00800002, 0x00000202, 0x00008202, 0x00808200,
67             0x00000202, 0x00800200, 0x00800200, 0x00000000,
68             0x00008002, 0x00008200, 0x00000000, 0x00808002
69             };
70              
71             static const uint32_t S2[] = {
72             0x40084010, 0x40004000, 0x00004000, 0x00084010,
73             0x00080000, 0x00000010, 0x40080010, 0x40004010,
74             0x40000010, 0x40084010, 0x40084000, 0x40000000,
75             0x40004000, 0x00080000, 0x00000010, 0x40080010,
76             0x00084000, 0x00080010, 0x40004010, 0x00000000,
77             0x40000000, 0x00004000, 0x00084010, 0x40080000,
78             0x00080010, 0x40000010, 0x00000000, 0x00084000,
79             0x00004010, 0x40084000, 0x40080000, 0x00004010,
80             0x00000000, 0x00084010, 0x40080010, 0x00080000,
81             0x40004010, 0x40080000, 0x40084000, 0x00004000,
82             0x40080000, 0x40004000, 0x00000010, 0x40084010,
83             0x00084010, 0x00000010, 0x00004000, 0x40000000,
84             0x00004010, 0x40084000, 0x00080000, 0x40000010,
85             0x00080010, 0x40004010, 0x40000010, 0x00080010,
86             0x00084000, 0x00000000, 0x40004000, 0x00004010,
87             0x40000000, 0x40080010, 0x40084010, 0x00084000
88             };
89              
90             static const uint32_t S3[] = {
91             0x00000104, 0x04010100, 0x00000000, 0x04010004,
92             0x04000100, 0x00000000, 0x00010104, 0x04000100,
93             0x00010004, 0x04000004, 0x04000004, 0x00010000,
94             0x04010104, 0x00010004, 0x04010000, 0x00000104,
95             0x04000000, 0x00000004, 0x04010100, 0x00000100,
96             0x00010100, 0x04010000, 0x04010004, 0x00010104,
97             0x04000104, 0x00010100, 0x00010000, 0x04000104,
98             0x00000004, 0x04010104, 0x00000100, 0x04000000,
99             0x04010100, 0x04000000, 0x00010004, 0x00000104,
100             0x00010000, 0x04010100, 0x04000100, 0x00000000,
101             0x00000100, 0x00010004, 0x04010104, 0x04000100,
102             0x04000004, 0x00000100, 0x00000000, 0x04010004,
103             0x04000104, 0x00010000, 0x04000000, 0x04010104,
104             0x00000004, 0x00010104, 0x00010100, 0x04000004,
105             0x04010000, 0x04000104, 0x00000104, 0x04010000,
106             0x00010104, 0x00000004, 0x04010004, 0x00010100
107             };
108              
109             static const uint32_t S4[] = {
110             0x80401000, 0x80001040, 0x80001040, 0x00000040,
111             0x00401040, 0x80400040, 0x80400000, 0x80001000,
112             0x00000000, 0x00401000, 0x00401000, 0x80401040,
113             0x80000040, 0x00000000, 0x00400040, 0x80400000,
114             0x80000000, 0x00001000, 0x00400000, 0x80401000,
115             0x00000040, 0x00400000, 0x80001000, 0x00001040,
116             0x80400040, 0x80000000, 0x00001040, 0x00400040,
117             0x00001000, 0x00401040, 0x80401040, 0x80000040,
118             0x00400040, 0x80400000, 0x00401000, 0x80401040,
119             0x80000040, 0x00000000, 0x00000000, 0x00401000,
120             0x00001040, 0x00400040, 0x80400040, 0x80000000,
121             0x80401000, 0x80001040, 0x80001040, 0x00000040,
122             0x80401040, 0x80000040, 0x80000000, 0x00001000,
123             0x80400000, 0x80001000, 0x00401040, 0x80400040,
124             0x80001000, 0x00001040, 0x00400000, 0x80401000,
125             0x00000040, 0x00400000, 0x00001000, 0x00401040
126             };
127              
128             static const uint32_t S5[] = {
129             0x00000080, 0x01040080, 0x01040000, 0x21000080,
130             0x00040000, 0x00000080, 0x20000000, 0x01040000,
131             0x20040080, 0x00040000, 0x01000080, 0x20040080,
132             0x21000080, 0x21040000, 0x00040080, 0x20000000,
133             0x01000000, 0x20040000, 0x20040000, 0x00000000,
134             0x20000080, 0x21040080, 0x21040080, 0x01000080,
135             0x21040000, 0x20000080, 0x00000000, 0x21000000,
136             0x01040080, 0x01000000, 0x21000000, 0x00040080,
137             0x00040000, 0x21000080, 0x00000080, 0x01000000,
138             0x20000000, 0x01040000, 0x21000080, 0x20040080,
139             0x01000080, 0x20000000, 0x21040000, 0x01040080,
140             0x20040080, 0x00000080, 0x01000000, 0x21040000,
141             0x21040080, 0x00040080, 0x21000000, 0x21040080,
142             0x01040000, 0x00000000, 0x20040000, 0x21000000,
143             0x00040080, 0x01000080, 0x20000080, 0x00040000,
144             0x00000000, 0x20040000, 0x01040080, 0x20000080
145             };
146              
147             static const uint32_t S6[] = {
148             0x10000008, 0x10200000, 0x00002000, 0x10202008,
149             0x10200000, 0x00000008, 0x10202008, 0x00200000,
150             0x10002000, 0x00202008, 0x00200000, 0x10000008,
151             0x00200008, 0x10002000, 0x10000000, 0x00002008,
152             0x00000000, 0x00200008, 0x10002008, 0x00002000,
153             0x00202000, 0x10002008, 0x00000008, 0x10200008,
154             0x10200008, 0x00000000, 0x00202008, 0x10202000,
155             0x00002008, 0x00202000, 0x10202000, 0x10000000,
156             0x10002000, 0x00000008, 0x10200008, 0x00202000,
157             0x10202008, 0x00200000, 0x00002008, 0x10000008,
158             0x00200000, 0x10002000, 0x10000000, 0x00002008,
159             0x10000008, 0x10202008, 0x00202000, 0x10200000,
160             0x00202008, 0x10202000, 0x00000000, 0x10200008,
161             0x00000008, 0x00002000, 0x10200000, 0x00202008,
162             0x00002000, 0x00200008, 0x10002008, 0x00000000,
163             0x10202000, 0x10000000, 0x00200008, 0x10002008
164             };
165              
166             static const uint32_t S7[] = {
167             0x00100000, 0x02100001, 0x02000401, 0x00000000,
168             0x00000400, 0x02000401, 0x00100401, 0x02100400,
169             0x02100401, 0x00100000, 0x00000000, 0x02000001,
170             0x00000001, 0x02000000, 0x02100001, 0x00000401,
171             0x02000400, 0x00100401, 0x00100001, 0x02000400,
172             0x02000001, 0x02100000, 0x02100400, 0x00100001,
173             0x02100000, 0x00000400, 0x00000401, 0x02100401,
174             0x00100400, 0x00000001, 0x02000000, 0x00100400,
175             0x02000000, 0x00100400, 0x00100000, 0x02000401,
176             0x02000401, 0x02100001, 0x02100001, 0x00000001,
177             0x00100001, 0x02000000, 0x02000400, 0x00100000,
178             0x02100400, 0x00000401, 0x00100401, 0x02100400,
179             0x00000401, 0x02000001, 0x02100401, 0x02100000,
180             0x00100400, 0x00000000, 0x00000001, 0x02100401,
181             0x00000000, 0x00100401, 0x02100000, 0x00000400,
182             0x02000001, 0x02000400, 0x00000400, 0x00100001
183             };
184              
185             static const uint32_t S8[] = {
186             0x08000820, 0x00000800, 0x00020000, 0x08020820,
187             0x08000000, 0x08000820, 0x00000020, 0x08000000,
188             0x00020020, 0x08020000, 0x08020820, 0x00020800,
189             0x08020800, 0x00020820, 0x00000800, 0x00000020,
190             0x08020000, 0x08000020, 0x08000800, 0x00000820,
191             0x00020800, 0x00020020, 0x08020020, 0x08020800,
192             0x00000820, 0x00000000, 0x00000000, 0x08020020,
193             0x08000020, 0x08000800, 0x00020820, 0x00020000,
194             0x00020820, 0x00020000, 0x08020800, 0x00000800,
195             0x00000020, 0x08020020, 0x00000800, 0x00020820,
196             0x08000800, 0x00000020, 0x08000020, 0x08020000,
197             0x08020020, 0x08000000, 0x00020000, 0x08000820,
198             0x00000000, 0x08020820, 0x00020020, 0x08000020,
199             0x08020000, 0x08000800, 0x08000820, 0x00000000,
200             0x08020820, 0x00020800, 0x00020800, 0x00000820,
201             0x00000820, 0x00020020, 0x08000000, 0x08020800
202             };
203              
204             static inline uint32_t
205 0           Fconf(uint32_t r0, uint32_t skl, uint32_t skr)
206             {
207             uint32_t r1;
208              
209 0           r1 = (r0 << 16) | (r0 >> 16);
210             return
211 0           S1[((r1 >> 11) ^ (skl >> 18)) & 0x3F]
212 0           | S2[((r0 >> 23) ^ (skl >> 12)) & 0x3F]
213 0           | S3[((r0 >> 19) ^ (skl >> 6)) & 0x3F]
214 0           | S4[((r0 >> 15) ^ (skl )) & 0x3F]
215 0           | S5[((r0 >> 11) ^ (skr >> 18)) & 0x3F]
216 0           | S6[((r0 >> 7) ^ (skr >> 12)) & 0x3F]
217 0           | S7[((r0 >> 3) ^ (skr >> 6)) & 0x3F]
218 0           | S8[((r1 >> 15) ^ (skr )) & 0x3F];
219             }
220              
221             static void
222 0           process_block_unit(uint32_t *pl, uint32_t *pr, const uint32_t *skey)
223             {
224             int i;
225             uint32_t l, r;
226              
227 0           l = *pl;
228 0           r = *pr;
229 0 0         for (i = 0; i < 16; i ++) {
230             uint32_t t;
231              
232 0           t = l ^ Fconf(r, skey[(i << 1) + 0], skey[(i << 1) + 1]);
233 0           l = r;
234 0           r = t;
235             }
236 0           *pl = r;
237 0           *pr = l;
238 0           }
239              
240             /* see inner.h */
241             void
242 0           br_des_tab_process_block(unsigned num_rounds, const uint32_t *skey, void *block)
243             {
244             unsigned char *buf;
245             uint32_t l, r;
246              
247 0           buf = block;
248 0           l = br_dec32be(buf);
249 0           r = br_dec32be(buf + 4);
250 0           br_des_do_IP(&l, &r);
251 0 0         while (num_rounds -- > 0) {
252 0           process_block_unit(&l, &r, skey);
253 0           skey += 32;
254             }
255 0           br_des_do_invIP(&l, &r);
256 0           br_enc32be(buf, l);
257 0           br_enc32be(buf + 4, r);
258 0           }
259              
260             static void
261 0           keysched_unit(uint32_t *skey, const void *key)
262             {
263             int i;
264              
265 0           br_des_keysched_unit(skey, key);
266              
267             /*
268             * Apply PC-2 to get the 48-bit subkeys.
269             */
270 0 0         for (i = 0; i < 16; i ++) {
271             uint32_t xl, xr, ul, ur;
272             int j;
273              
274 0           xl = skey[(i << 1) + 0];
275 0           xr = skey[(i << 1) + 1];
276 0           ul = 0;
277 0           ur = 0;
278 0 0         for (j = 0; j < 28; j ++) {
279 0           ul |= (xl & 1) << PC2left[j];
280 0           ur |= (xr & 1) << PC2right[j];
281 0           xl >>= 1;
282 0           xr >>= 1;
283             }
284 0           skey[(i << 1) + 0] = ul;
285 0           skey[(i << 1) + 1] = ur;
286             }
287 0           }
288              
289             /* see inner.h */
290             unsigned
291 0           br_des_tab_keysched(uint32_t *skey, const void *key, size_t key_len)
292             {
293 0           switch (key_len) {
294 0           case 8:
295 0           keysched_unit(skey, key);
296 0           return 1;
297 0           case 16:
298 0           keysched_unit(skey, key);
299 0           keysched_unit(skey + 32, (const unsigned char *)key + 8);
300 0           br_des_rev_skey(skey + 32);
301 0           memcpy(skey + 64, skey, 32 * sizeof *skey);
302 0           return 3;
303 0           default:
304 0           keysched_unit(skey, key);
305 0           keysched_unit(skey + 32, (const unsigned char *)key + 8);
306 0           br_des_rev_skey(skey + 32);
307 0           keysched_unit(skey + 64, (const unsigned char *)key + 16);
308 0           return 3;
309             }
310             }