Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/bearssl/src/symcipher/des_tab.c
39482 views
1
/*
2
* Copyright (c) 2016 Thomas Pornin <[email protected]>
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
Fconf(uint32_t r0, uint32_t skl, uint32_t skr)
206
{
207
uint32_t r1;
208
209
r1 = (r0 << 16) | (r0 >> 16);
210
return
211
S1[((r1 >> 11) ^ (skl >> 18)) & 0x3F]
212
| S2[((r0 >> 23) ^ (skl >> 12)) & 0x3F]
213
| S3[((r0 >> 19) ^ (skl >> 6)) & 0x3F]
214
| S4[((r0 >> 15) ^ (skl )) & 0x3F]
215
| S5[((r0 >> 11) ^ (skr >> 18)) & 0x3F]
216
| S6[((r0 >> 7) ^ (skr >> 12)) & 0x3F]
217
| S7[((r0 >> 3) ^ (skr >> 6)) & 0x3F]
218
| S8[((r1 >> 15) ^ (skr )) & 0x3F];
219
}
220
221
static void
222
process_block_unit(uint32_t *pl, uint32_t *pr, const uint32_t *skey)
223
{
224
int i;
225
uint32_t l, r;
226
227
l = *pl;
228
r = *pr;
229
for (i = 0; i < 16; i ++) {
230
uint32_t t;
231
232
t = l ^ Fconf(r, skey[(i << 1) + 0], skey[(i << 1) + 1]);
233
l = r;
234
r = t;
235
}
236
*pl = r;
237
*pr = l;
238
}
239
240
/* see inner.h */
241
void
242
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
buf = block;
248
l = br_dec32be(buf);
249
r = br_dec32be(buf + 4);
250
br_des_do_IP(&l, &r);
251
while (num_rounds -- > 0) {
252
process_block_unit(&l, &r, skey);
253
skey += 32;
254
}
255
br_des_do_invIP(&l, &r);
256
br_enc32be(buf, l);
257
br_enc32be(buf + 4, r);
258
}
259
260
static void
261
keysched_unit(uint32_t *skey, const void *key)
262
{
263
int i;
264
265
br_des_keysched_unit(skey, key);
266
267
/*
268
* Apply PC-2 to get the 48-bit subkeys.
269
*/
270
for (i = 0; i < 16; i ++) {
271
uint32_t xl, xr, ul, ur;
272
int j;
273
274
xl = skey[(i << 1) + 0];
275
xr = skey[(i << 1) + 1];
276
ul = 0;
277
ur = 0;
278
for (j = 0; j < 28; j ++) {
279
ul |= (xl & 1) << PC2left[j];
280
ur |= (xr & 1) << PC2right[j];
281
xl >>= 1;
282
xr >>= 1;
283
}
284
skey[(i << 1) + 0] = ul;
285
skey[(i << 1) + 1] = ur;
286
}
287
}
288
289
/* see inner.h */
290
unsigned
291
br_des_tab_keysched(uint32_t *skey, const void *key, size_t key_len)
292
{
293
switch (key_len) {
294
case 8:
295
keysched_unit(skey, key);
296
return 1;
297
case 16:
298
keysched_unit(skey, key);
299
keysched_unit(skey + 32, (const unsigned char *)key + 8);
300
br_des_rev_skey(skey + 32);
301
memcpy(skey + 64, skey, 32 * sizeof *skey);
302
return 3;
303
default:
304
keysched_unit(skey, key);
305
keysched_unit(skey + 32, (const unsigned char *)key + 8);
306
br_des_rev_skey(skey + 32);
307
keysched_unit(skey + 64, (const unsigned char *)key + 16);
308
return 3;
309
}
310
}
311
312