/[mcrypt]/libmcrypt-nm/lib/des.c
ViewVC logotype

Contents of /libmcrypt-nm/lib/des.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Mon May 22 13:09:00 2000 UTC (23 years, 10 months ago) by nmav
Branch: MAIN, mcrypt
CVS Tags: start, HEAD
Changes since 1.1: +0 -0 lines
File MIME type: text/plain

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26