1 |
|
2 |
/* Sofware DES functions |
3 |
* written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted from |
4 |
* the 1977 public-domain program by Jim Gillogly |
5 |
* Modified for additional speed - 6 December 1988 Phil Karn |
6 |
* Modified for parameterized key schedules - Jan 1991 Phil Karn |
7 |
* Callers now allocate a key schedule as follows: |
8 |
* kn = (char (*)[8])malloc(sizeof(char) * 8 * 16); |
9 |
* or |
10 |
* char kn[16][8]; |
11 |
*/ |
12 |
|
13 |
/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos |
14 |
* All modifications are placed under the license of libmcrypt. |
15 |
*/ |
16 |
|
17 |
/* $Id: des.c,v 1.7 2000/02/09 15:15:06 nikos Exp $ */ |
18 |
|
19 |
#include "libdefs.h" |
20 |
#include "swap.h" |
21 |
#include "bzero.h" |
22 |
#include "des.h" |
23 |
|
24 |
/* #define NULL 0 */ |
25 |
|
26 |
static void permute_ip(), permute_fp(), perminit_ip(), spinit(), perminit_fp(); |
27 |
static word32 f(); |
28 |
|
29 |
|
30 |
/* Tables defined in the Data Encryption Standard documents */ |
31 |
|
32 |
/* initial permutation IP */ |
33 |
static char ip[] = { |
34 |
58, 50, 42, 34, 26, 18, 10, 2, |
35 |
60, 52, 44, 36, 28, 20, 12, 4, |
36 |
62, 54, 46, 38, 30, 22, 14, 6, |
37 |
64, 56, 48, 40, 32, 24, 16, 8, |
38 |
57, 49, 41, 33, 25, 17, 9, 1, |
39 |
59, 51, 43, 35, 27, 19, 11, 3, |
40 |
61, 53, 45, 37, 29, 21, 13, 5, |
41 |
63, 55, 47, 39, 31, 23, 15, 7 |
42 |
}; |
43 |
|
44 |
/* final permutation IP^-1 */ |
45 |
static char fp[] = { |
46 |
40, 8, 48, 16, 56, 24, 64, 32, |
47 |
39, 7, 47, 15, 55, 23, 63, 31, |
48 |
38, 6, 46, 14, 54, 22, 62, 30, |
49 |
37, 5, 45, 13, 53, 21, 61, 29, |
50 |
36, 4, 44, 12, 52, 20, 60, 28, |
51 |
35, 3, 43, 11, 51, 19, 59, 27, |
52 |
34, 2, 42, 10, 50, 18, 58, 26, |
53 |
33, 1, 41, 9, 49, 17, 57, 25 |
54 |
}; |
55 |
|
56 |
/* expansion operation matrix |
57 |
* This is for reference only; it is unused in the code |
58 |
* as the f() function performs it implicitly for speed |
59 |
*/ |
60 |
#ifdef notdef |
61 |
static char ei[] = { |
62 |
32, 1, 2, 3, 4, 5, |
63 |
4, 5, 6, 7, 8, 9, |
64 |
8, 9, 10, 11, 12, 13, |
65 |
12, 13, 14, 15, 16, 17, |
66 |
16, 17, 18, 19, 20, 21, |
67 |
20, 21, 22, 23, 24, 25, |
68 |
24, 25, 26, 27, 28, 29, |
69 |
28, 29, 30, 31, 32, 1 |
70 |
}; |
71 |
#endif |
72 |
|
73 |
/* permuted choice table (key) */ |
74 |
static char pc1[] = { |
75 |
57, 49, 41, 33, 25, 17, 9, |
76 |
1, 58, 50, 42, 34, 26, 18, |
77 |
10, 2, 59, 51, 43, 35, 27, |
78 |
19, 11, 3, 60, 52, 44, 36, |
79 |
|
80 |
63, 55, 47, 39, 31, 23, 15, |
81 |
7, 62, 54, 46, 38, 30, 22, |
82 |
14, 6, 61, 53, 45, 37, 29, |
83 |
21, 13, 5, 28, 20, 12, 4 |
84 |
}; |
85 |
|
86 |
/* number left rotations of pc1 */ |
87 |
static char totrot[] = { |
88 |
1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 |
89 |
}; |
90 |
|
91 |
/* permuted choice key (table) */ |
92 |
static char pc2[] = { |
93 |
14, 17, 11, 24, 1, 5, |
94 |
3, 28, 15, 6, 21, 10, |
95 |
23, 19, 12, 4, 26, 8, |
96 |
16, 7, 27, 20, 13, 2, |
97 |
41, 52, 31, 37, 47, 55, |
98 |
30, 40, 51, 45, 33, 48, |
99 |
44, 49, 39, 56, 34, 53, |
100 |
46, 42, 50, 36, 29, 32 |
101 |
}; |
102 |
|
103 |
/* The (in)famous S-boxes */ |
104 |
static char si[8][64] = { |
105 |
/* S1 */ |
106 |
{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, |
107 |
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, |
108 |
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, |
109 |
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}, |
110 |
|
111 |
/* S2 */ |
112 |
{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, |
113 |
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, |
114 |
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, |
115 |
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}, |
116 |
|
117 |
/* S3 */ |
118 |
{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, |
119 |
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, |
120 |
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, |
121 |
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}, |
122 |
|
123 |
/* S4 */ |
124 |
{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, |
125 |
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, |
126 |
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, |
127 |
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}, |
128 |
|
129 |
/* S5 */ |
130 |
{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, |
131 |
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, |
132 |
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, |
133 |
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}, |
134 |
|
135 |
/* S6 */ |
136 |
{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, |
137 |
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, |
138 |
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, |
139 |
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}, |
140 |
|
141 |
/* S7 */ |
142 |
{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, |
143 |
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, |
144 |
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, |
145 |
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}, |
146 |
|
147 |
/* S8 */ |
148 |
{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, |
149 |
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, |
150 |
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, |
151 |
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}, |
152 |
|
153 |
}; |
154 |
|
155 |
/* 32-bit permutation function P used on the output of the S-boxes */ |
156 |
static char p32i[] = { |
157 |
16, 7, 20, 21, |
158 |
29, 12, 28, 17, |
159 |
1, 15, 23, 26, |
160 |
5, 18, 31, 10, |
161 |
2, 8, 24, 14, |
162 |
32, 27, 3, 9, |
163 |
19, 13, 30, 6, |
164 |
22, 11, 4, 25 |
165 |
}; |
166 |
|
167 |
/* End of DES-defined tables */ |
168 |
|
169 |
/* Lookup tables initialized once only at startup by desinit() */ |
170 |
|
171 |
/* bit 0 is left-most in byte */ |
172 |
static int bytebit[] = { |
173 |
0200, 0100, 040, 020, 010, 04, 02, 01 |
174 |
}; |
175 |
|
176 |
static int nibblebit[] = { |
177 |
010, 04, 02, 01 |
178 |
}; |
179 |
|
180 |
/* Allocate space and initialize DES lookup arrays |
181 |
* mode == 0: standard Data Encryption Algorithm |
182 |
*/ |
183 |
int _mcrypt_desinit(DES_KEY* key) |
184 |
{ |
185 |
|
186 |
spinit(key); |
187 |
perminit_ip( key); |
188 |
perminit_fp( key); |
189 |
|
190 |
return 0; |
191 |
} |
192 |
|
193 |
|
194 |
/* Set key (initialize key schedule array) */ |
195 |
void _mcrypt_des_set_key(DES_KEY* dkey, char* user_key, int len) |
196 |
{ |
197 |
char pc1m[56]; /* place to modify pc1 into */ |
198 |
char pcr[56]; /* place to rotate pc1 into */ |
199 |
register int i, j, l; |
200 |
int m; |
201 |
|
202 |
Bzero( dkey, sizeof(DES_KEY)); |
203 |
_mcrypt_desinit(dkey); |
204 |
|
205 |
/* Clear key schedule */ |
206 |
|
207 |
|
208 |
for (j = 0; j < 56; j++) { /* convert pc1 to bits of key */ |
209 |
l = pc1[j] - 1; /* integer bit location */ |
210 |
m = l & 07; /* find bit */ |
211 |
pc1m[j] = (user_key[l >> 3] & /* find which key byte l is in */ |
212 |
bytebit[m]) /* and which bit of that byte */ |
213 |
? 1 : 0; /* and store 1-bit result */ |
214 |
|
215 |
} |
216 |
for (i = 0; i < 16; i++) { /* key chunk for each iteration */ |
217 |
for (j = 0; j < 56; j++) /* rotate pc1 the right amount */ |
218 |
pcr[j] = |
219 |
pc1m[(l = j + totrot[i]) < |
220 |
(j < 28 ? 28 : 56) ? l : l - 28]; |
221 |
/* rotate left and right halves independently */ |
222 |
for (j = 0; j < 48; j++) { /* select bits individually */ |
223 |
/* check bit that goes to kn[j] */ |
224 |
if (pcr[pc2[j] - 1]) { |
225 |
/* mask it in if it's there */ |
226 |
l = j % 6; |
227 |
dkey->kn[i][j / 6] |= bytebit[l] >> 2; |
228 |
} |
229 |
} |
230 |
} |
231 |
} |
232 |
|
233 |
/* In-place encryption of 64-bit block */ |
234 |
void _mcrypt_des_encrypt(DES_KEY *key, char* block) |
235 |
{ |
236 |
register word32 left, right; |
237 |
register char *knp; |
238 |
word32 work[2]; /* Working data storage */ |
239 |
|
240 |
permute_ip(block, key, (char *) work); /* Initial Permutation */ |
241 |
#ifndef WORDS_BIGENDIAN |
242 |
left = byteswap(work[0]); |
243 |
right = byteswap(work[1]); |
244 |
#else |
245 |
left = work[0]; |
246 |
right = work[1]; |
247 |
#endif |
248 |
|
249 |
/* Do the 16 rounds. |
250 |
* The rounds are numbered from 0 to 15. On even rounds |
251 |
* the right half is fed to f() and the result exclusive-ORs |
252 |
* the left half; on odd rounds the reverse is done. |
253 |
*/ |
254 |
knp = &key->kn[0][0]; |
255 |
left ^= f(key, right, knp); |
256 |
knp += 8; |
257 |
right ^= f( key, left, knp); |
258 |
knp += 8; |
259 |
left ^= f( key, right, knp); |
260 |
knp += 8; |
261 |
right ^= f( key, left, knp); |
262 |
knp += 8; |
263 |
left ^= f( key, right, knp); |
264 |
knp += 8; |
265 |
right ^= f( key, left, knp); |
266 |
knp += 8; |
267 |
left ^= f( key, right, knp); |
268 |
knp += 8; |
269 |
right ^= f( key, left, knp); |
270 |
knp += 8; |
271 |
left ^= f( key, right, knp); |
272 |
knp += 8; |
273 |
right ^= f( key, left, knp); |
274 |
knp += 8; |
275 |
left ^= f( key, right, knp); |
276 |
knp += 8; |
277 |
right ^= f( key, left, knp); |
278 |
knp += 8; |
279 |
left ^= f( key, right, knp); |
280 |
knp += 8; |
281 |
right ^= f( key, left, knp); |
282 |
knp += 8; |
283 |
left ^= f( key, right, knp); |
284 |
knp += 8; |
285 |
right ^= f( key, left, knp); |
286 |
|
287 |
/* Left/right half swap, plus byte swap if little-endian */ |
288 |
#ifndef WORDS_BIGENDIAN |
289 |
work[1] = byteswap(left); |
290 |
work[0] = byteswap(right); |
291 |
#else |
292 |
work[0] = right; |
293 |
work[1] = left; |
294 |
#endif |
295 |
permute_fp((char *) work, key, block); /* Inverse initial permutation */ |
296 |
} |
297 |
/* In-place decryption of 64-bit block. This function is the mirror |
298 |
* image of encryption; exactly the same steps are taken, but in |
299 |
* reverse order |
300 |
*/ |
301 |
void _mcrypt_des_decrypt(DES_KEY* key, char* block) |
302 |
{ |
303 |
register word32 left, right; |
304 |
register char *knp; |
305 |
word32 work[2]; /* Working data storage */ |
306 |
|
307 |
permute_ip(block, key, (char *) work); /* Initial permutation */ |
308 |
|
309 |
/* Left/right half swap, plus byte swap if little-endian */ |
310 |
#ifndef WORDS_BIGENDIAN |
311 |
right = byteswap(work[0]); |
312 |
left = byteswap(work[1]); |
313 |
#else |
314 |
right = work[0]; |
315 |
left = work[1]; |
316 |
#endif |
317 |
/* Do the 16 rounds in reverse order. |
318 |
* The rounds are numbered from 15 to 0. On even rounds |
319 |
* the right half is fed to f() and the result exclusive-ORs |
320 |
* the left half; on odd rounds the reverse is done. |
321 |
*/ |
322 |
knp = &key->kn[15][0]; |
323 |
right ^= f( key, left, knp); |
324 |
knp -= 8; |
325 |
left ^= f( key, right, knp); |
326 |
knp -= 8; |
327 |
right ^= f( key, left, knp); |
328 |
knp -= 8; |
329 |
left ^= f( key, right, knp); |
330 |
knp -= 8; |
331 |
right ^= f( key, left, knp); |
332 |
knp -= 8; |
333 |
left ^= f( key, right, knp); |
334 |
knp -= 8; |
335 |
right ^= f( key, left, knp); |
336 |
knp -= 8; |
337 |
left ^= f( key, right, knp); |
338 |
knp -= 8; |
339 |
right ^= f( key, left, knp); |
340 |
knp -= 8; |
341 |
left ^= f( key, right, knp); |
342 |
knp -= 8; |
343 |
right ^= f( key, left, knp); |
344 |
knp -= 8; |
345 |
left ^= f( key, right, knp); |
346 |
knp -= 8; |
347 |
right ^= f( key, left, knp); |
348 |
knp -= 8; |
349 |
left ^= f( key, right, knp); |
350 |
knp -= 8; |
351 |
right ^= f( key, left, knp); |
352 |
knp -= 8; |
353 |
left ^= f( key, right, knp); |
354 |
|
355 |
#ifndef WORDS_BIGENDIAN |
356 |
work[0] = byteswap(left); |
357 |
work[1] = byteswap(right); |
358 |
#else |
359 |
work[0] = left; |
360 |
work[1] = right; |
361 |
#endif |
362 |
permute_fp((char *) work, key, block); /* Inverse initial permutation */ |
363 |
} |
364 |
|
365 |
/* Permute inblock with perm */ |
366 |
static void permute_ip(char* inblock, DES_KEY *key, char* outblock) |
367 |
{ |
368 |
register char *ib, *ob; /* ptr to input or output block */ |
369 |
register char *p, *q; |
370 |
register int j; |
371 |
|
372 |
/* Clear output block */ |
373 |
Bzero(outblock, 8); |
374 |
|
375 |
ib = inblock; |
376 |
for (j = 0; j < 16; j += 2, ib++) { /* for each input nibble */ |
377 |
ob = outblock; |
378 |
p = key->iperm[j][(*ib >> 4) & 0xf]; |
379 |
q = key->iperm[j + 1][*ib & 0xf]; |
380 |
/* and each output byte, OR the masks together */ |
381 |
*ob++ |= *p++ | *q++; |
382 |
*ob++ |= *p++ | *q++; |
383 |
*ob++ |= *p++ | *q++; |
384 |
*ob++ |= *p++ | *q++; |
385 |
*ob++ |= *p++ | *q++; |
386 |
*ob++ |= *p++ | *q++; |
387 |
*ob++ |= *p++ | *q++; |
388 |
*ob++ |= *p++ | *q++; |
389 |
} |
390 |
} |
391 |
|
392 |
/* Permute inblock with perm */ |
393 |
static void permute_fp(char* inblock, DES_KEY *key, char* outblock) |
394 |
{ |
395 |
register char *ib, *ob; /* ptr to input or output block */ |
396 |
register char *p, *q; |
397 |
register int j; |
398 |
|
399 |
/* Clear output block */ |
400 |
Bzero(outblock, 8); |
401 |
|
402 |
ib = inblock; |
403 |
for (j = 0; j < 16; j += 2, ib++) { /* for each input nibble */ |
404 |
ob = outblock; |
405 |
p = key->fperm[j][(*ib >> 4) & 0xf]; |
406 |
q = key->fperm[j + 1][*ib & 0xf]; |
407 |
/* and each output byte, OR the masks together */ |
408 |
*ob++ |= *p++ | *q++; |
409 |
*ob++ |= *p++ | *q++; |
410 |
*ob++ |= *p++ | *q++; |
411 |
*ob++ |= *p++ | *q++; |
412 |
*ob++ |= *p++ | *q++; |
413 |
*ob++ |= *p++ | *q++; |
414 |
*ob++ |= *p++ | *q++; |
415 |
*ob++ |= *p++ | *q++; |
416 |
} |
417 |
} |
418 |
|
419 |
/* The nonlinear function f(r,k), the heart of DES */ |
420 |
static word32 f(DES_KEY* key, register word32 r, register char* subkey) |
421 |
{ |
422 |
register word32 *spp; |
423 |
register word32 rval, rt; |
424 |
register int er; |
425 |
|
426 |
#ifdef TRACE |
427 |
printf("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ", |
428 |
r, |
429 |
subkey[0], subkey[1], subkey[2], |
430 |
subkey[3], subkey[4], subkey[5], subkey[6], subkey[7]); |
431 |
#endif |
432 |
/* Run E(R) ^ K through the combined S & P boxes. |
433 |
* This code takes advantage of a convenient regularity in |
434 |
* E, namely that each group of 6 bits in E(R) feeding |
435 |
* a single S-box is a contiguous segment of R. |
436 |
*/ |
437 |
subkey += 7; |
438 |
|
439 |
/* Compute E(R) for each block of 6 bits, and run thru boxes */ |
440 |
er = ((int) r << 1) | ((r & 0x80000000) ? 1 : 0); |
441 |
spp = &key->sp[7][0]; |
442 |
rval = spp[(er ^ *subkey--) & 0x3f]; |
443 |
spp -= 64; |
444 |
rt = (word32) r >> 3; |
445 |
rval |= spp[((int) rt ^ *subkey--) & 0x3f]; |
446 |
spp -= 64; |
447 |
rt >>= 4; |
448 |
rval |= spp[((int) rt ^ *subkey--) & 0x3f]; |
449 |
spp -= 64; |
450 |
rt >>= 4; |
451 |
rval |= spp[((int) rt ^ *subkey--) & 0x3f]; |
452 |
spp -= 64; |
453 |
rt >>= 4; |
454 |
rval |= spp[((int) rt ^ *subkey--) & 0x3f]; |
455 |
spp -= 64; |
456 |
rt >>= 4; |
457 |
rval |= spp[((int) rt ^ *subkey--) & 0x3f]; |
458 |
spp -= 64; |
459 |
rt >>= 4; |
460 |
rval |= spp[((int) rt ^ *subkey--) & 0x3f]; |
461 |
spp -= 64; |
462 |
rt >>= 4; |
463 |
rt |= (r & 1) << 5; |
464 |
rval |= spp[((int) rt ^ *subkey) & 0x3f]; |
465 |
#ifdef TRACE |
466 |
printf(" %08lx\n", rval); |
467 |
#endif |
468 |
return rval; |
469 |
} |
470 |
/* initialize a perm array */ |
471 |
static void perminit_ip(DES_KEY *key) |
472 |
{ |
473 |
register int l, j, k; |
474 |
int i, m; |
475 |
|
476 |
/* Clear the permutation array */ |
477 |
Bzero(key->iperm, 16 * 16 * 8); |
478 |
|
479 |
for (i = 0; i < 16; i++) /* each input nibble position */ |
480 |
for (j = 0; j < 16; j++) /* each possible input nibble */ |
481 |
for (k = 0; k < 64; k++) { /* each output bit position */ |
482 |
l = ip[k] - 1; /* where does this bit come from */ |
483 |
if ((l >> 2) != i) /* does it come from input posn? */ |
484 |
continue; /* if not, bit k is 0 */ |
485 |
if (!(j & nibblebit[l & 3])) |
486 |
continue; /* any such bit in input? */ |
487 |
m = k & 07; /* which bit is this in the byte */ |
488 |
key->iperm[i][j][k >> 3] |= bytebit[m]; |
489 |
} |
490 |
} |
491 |
|
492 |
static void perminit_fp(DES_KEY *key) |
493 |
{ |
494 |
register int l, j, k; |
495 |
int i, m; |
496 |
|
497 |
/* Clear the permutation array */ |
498 |
Bzero( key->fperm, 16 * 16 * 8); |
499 |
|
500 |
for (i = 0; i < 16; i++) /* each input nibble position */ |
501 |
for (j = 0; j < 16; j++) /* each possible input nibble */ |
502 |
for (k = 0; k < 64; k++) { /* each output bit position */ |
503 |
l = fp[k] - 1; /* where does this bit come from */ |
504 |
if ((l >> 2) != i) /* does it come from input posn? */ |
505 |
continue; /* if not, bit k is 0 */ |
506 |
if (!(j & nibblebit[l & 3])) |
507 |
continue; /* any such bit in input? */ |
508 |
m = k & 07; /* which bit is this in the byte */ |
509 |
key->fperm[i][j][k >> 3] |= bytebit[m]; |
510 |
} |
511 |
} |
512 |
|
513 |
/* Initialize the lookup table for the combined S and P boxes */ |
514 |
static void spinit(DES_KEY *key) |
515 |
{ |
516 |
char pbox[32]; |
517 |
int p, i, s, j, rowcol; |
518 |
word32 val; |
519 |
|
520 |
/* Compute pbox, the inverse of p32i. |
521 |
* This is easier to work with |
522 |
*/ |
523 |
for (p = 0; p < 32; p++) { |
524 |
for (i = 0; i < 32; i++) { |
525 |
if (p32i[i] - 1 == p) { |
526 |
pbox[p] = i; |
527 |
break; |
528 |
} |
529 |
} |
530 |
} |
531 |
for (s = 0; s < 8; s++) { /* For each S-box */ |
532 |
for (i = 0; i < 64; i++) { /* For each possible input */ |
533 |
val = 0; |
534 |
/* The row number is formed from the first and last |
535 |
* bits; the column number is from the middle 4 |
536 |
*/ |
537 |
rowcol = |
538 |
(i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & |
539 |
0xf); |
540 |
for (j = 0; j < 4; j++) { /* For each output bit */ |
541 |
if (si[s][rowcol] & (8 >> j)) { |
542 |
val |= |
543 |
1L << (31 - pbox[4 * s + j]); |
544 |
} |
545 |
} |
546 |
key->sp[s][i] = val; |
547 |
|
548 |
#ifdef DEBUG |
549 |
printf("sp[%d][%2d] = %08lx\n", s, i, key->sp[s][i]); |
550 |
#endif |
551 |
} |
552 |
} |
553 |
} |
554 |
|