No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / dist / heimdal / lib / hcrypto / des.c
blob551e538a52d9cfbc44388868a2bbb2ae3fb717c2
1 /*
2 * Copyright (c) 2005 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
35 * The document that got me started for real was "Efficient
36 * Implementation of the Data Encryption Standard" by Dag Arne Osvik.
37 * I never got to the PC1 transformation was working, instead I used
38 * table-lookup was used for all key schedule setup. The document was
39 * very useful since it de-mystified other implementations for me.
41 * The core DES function (SBOX + P transformation) is from Richard
42 * Outerbridge public domain DES implementation. My sanity is saved
43 * thanks to his work. Thank you Richard.
46 #ifdef HAVE_CONFIG_H
47 #include <config.h>
48 __RCSID("$Heimdal: des.c 17211 2006-04-24 14:26:19Z lha $"
49 "$NetBSD$");
50 #endif
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <krb5-types.h>
56 #include <assert.h>
58 #include "des.h"
59 #include "ui.h"
61 static void desx(uint32_t [2], DES_key_schedule *, int);
62 static void IP(uint32_t [2]);
63 static void FP(uint32_t [2]);
65 #include "des-tables.h"
67 #define ROTATE_LEFT28(x,one) \
68 if (one) { \
69 x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \
70 } else { \
71 x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \
78 int
79 DES_set_odd_parity(DES_cblock *key)
81 int i;
82 for (i = 0; i < DES_CBLOCK_LEN; i++)
83 (*key)[i] = odd_parity[(*key)[i]];
84 return 0;
91 /* FIPS 74 */
92 static DES_cblock weak_keys[] = {
93 {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */
94 {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
95 {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
96 {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
97 {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */
98 {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
99 {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
100 {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
101 {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
102 {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
103 {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
104 {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
105 {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
106 {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
107 {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
108 {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}
112 DES_is_weak_key(DES_cblock *key)
114 int i;
116 for (i = 0; i < sizeof(weak_keys)/sizeof(weak_keys[0]); i++) {
117 if (memcmp(weak_keys[i], key, DES_CBLOCK_LEN) == 0)
118 return 1;
120 return 0;
129 DES_set_key(DES_cblock *key, DES_key_schedule *ks)
131 uint32_t t1, t2;
132 uint32_t c, d;
133 int shifts[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
134 uint32_t *k = &ks->ks[0];
135 int i;
137 t1 = (*key)[0] << 24 | (*key)[1] << 16 | (*key)[2] << 8 | (*key)[3];
138 t2 = (*key)[4] << 24 | (*key)[5] << 16 | (*key)[6] << 8 | (*key)[7];
140 c = (pc1_c_3[(t1 >> (5 )) & 0x7] << 3)
141 | (pc1_c_3[(t1 >> (5 + 8 )) & 0x7] << 2)
142 | (pc1_c_3[(t1 >> (5 + 8 + 8 )) & 0x7] << 1)
143 | (pc1_c_3[(t1 >> (5 + 8 + 8 + 8)) & 0x7] << 0)
144 | (pc1_c_4[(t2 >> (4 )) & 0xf] << 3)
145 | (pc1_c_4[(t2 >> (4 + 8 )) & 0xf] << 2)
146 | (pc1_c_4[(t2 >> (4 + 8 + 8 )) & 0xf] << 1)
147 | (pc1_c_4[(t2 >> (4 + 8 + 8 + 8)) & 0xf] << 0);
150 d = (pc1_d_3[(t2 >> (1 )) & 0x7] << 3)
151 | (pc1_d_3[(t2 >> (1 + 8 )) & 0x7] << 2)
152 | (pc1_d_3[(t2 >> (1 + 8 + 8 )) & 0x7] << 1)
153 | (pc1_d_3[(t2 >> (1 + 8 + 8 + 8)) & 0x7] << 0)
154 | (pc1_d_4[(t1 >> (1 )) & 0xf] << 3)
155 | (pc1_d_4[(t1 >> (1 + 8 )) & 0xf] << 2)
156 | (pc1_d_4[(t1 >> (1 + 8 + 8 )) & 0xf] << 1)
157 | (pc1_d_4[(t1 >> (1 + 8 + 8 + 8)) & 0xf] << 0);
159 for (i = 0; i < 16; i++) {
160 uint32_t kc, kd;
162 ROTATE_LEFT28(c, shifts[i]);
163 ROTATE_LEFT28(d, shifts[i]);
165 kc = pc2_c_1[(c >> 22) & 0x3f] |
166 pc2_c_2[((c >> 16) & 0x30) | ((c >> 15) & 0xf)] |
167 pc2_c_3[((c >> 9 ) & 0x3c) | ((c >> 8 ) & 0x3)] |
168 pc2_c_4[((c >> 2 ) & 0x20) | ((c >> 1) & 0x18) | (c & 0x7)];
169 kd = pc2_d_1[(d >> 22) & 0x3f] |
170 pc2_d_2[((d >> 15) & 0x30) | ((d >> 14) & 0xf)] |
171 pc2_d_3[ (d >> 7 ) & 0x3f] |
172 pc2_d_4[((d >> 1 ) & 0x3c) | ((d ) & 0x3)];
174 /* Change to byte order used by the S boxes */
175 *k = (kc & 0x00fc0000L) << 6;
176 *k |= (kc & 0x00000fc0L) << 10;
177 *k |= (kd & 0x00fc0000L) >> 10;
178 *k++ |= (kd & 0x00000fc0L) >> 6;
179 *k = (kc & 0x0003f000L) << 12;
180 *k |= (kc & 0x0000003fL) << 16;
181 *k |= (kd & 0x0003f000L) >> 4;
182 *k++ |= (kd & 0x0000003fL);
185 return 0;
193 DES_set_key_checked(DES_cblock *key, DES_key_schedule *ks)
195 if (DES_is_weak_key(key)) {
196 memset(ks, 0, sizeof(*ks));
197 return 1;
199 return DES_set_key(key, ks);
203 * Compatibility function for eay libdes
207 DES_key_sched(DES_cblock *key, DES_key_schedule *ks)
209 return DES_set_key(key, ks);
216 static void
217 load(const unsigned char *b, uint32_t v[2])
219 v[0] = b[0] << 24;
220 v[0] |= b[1] << 16;
221 v[0] |= b[2] << 8;
222 v[0] |= b[3] << 0;
223 v[1] = b[4] << 24;
224 v[1] |= b[5] << 16;
225 v[1] |= b[6] << 8;
226 v[1] |= b[7] << 0;
229 static void
230 store(const uint32_t v[2], unsigned char *b)
232 b[0] = (v[0] >> 24) & 0xff;
233 b[1] = (v[0] >> 16) & 0xff;
234 b[2] = (v[0] >> 8) & 0xff;
235 b[3] = (v[0] >> 0) & 0xff;
236 b[4] = (v[1] >> 24) & 0xff;
237 b[5] = (v[1] >> 16) & 0xff;
238 b[6] = (v[1] >> 8) & 0xff;
239 b[7] = (v[1] >> 0) & 0xff;
246 void
247 DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int forward_encrypt)
249 IP(u);
250 desx(u, ks, forward_encrypt);
251 FP(u);
258 void
259 DES_ecb_encrypt(DES_cblock *input, DES_cblock *output,
260 DES_key_schedule *ks, int forward_encrypt)
262 uint32_t u[2];
263 load(*input, u);
264 DES_encrypt(u, ks, forward_encrypt);
265 store(u, *output);
272 void
273 DES_cbc_encrypt(const void *in, void *out, long length,
274 DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt)
276 const unsigned char *input = in;
277 unsigned char *output = out;
278 uint32_t u[2];
279 uint32_t uiv[2];
281 load(*iv, uiv);
283 if (forward_encrypt) {
284 while (length >= DES_CBLOCK_LEN) {
285 load(input, u);
286 u[0] ^= uiv[0]; u[1] ^= uiv[1];
287 DES_encrypt(u, ks, 1);
288 uiv[0] = u[0]; uiv[1] = u[1];
289 store(u, output);
291 length -= DES_CBLOCK_LEN;
292 input += DES_CBLOCK_LEN;
293 output += DES_CBLOCK_LEN;
295 if (length) {
296 unsigned char tmp[DES_CBLOCK_LEN];
297 memcpy(tmp, input, length);
298 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
299 load(tmp, u);
300 u[0] ^= uiv[0]; u[1] ^= uiv[1];
301 DES_encrypt(u, ks, 1);
302 store(u, output);
304 } else {
305 uint32_t t[2];
306 while (length >= DES_CBLOCK_LEN) {
307 load(input, u);
308 t[0] = u[0]; t[1] = u[1];
309 DES_encrypt(u, ks, 0);
310 u[0] ^= uiv[0]; u[1] ^= uiv[1];
311 store(u, output);
312 uiv[0] = t[0]; uiv[1] = t[1];
314 length -= DES_CBLOCK_LEN;
315 input += DES_CBLOCK_LEN;
316 output += DES_CBLOCK_LEN;
318 if (length) {
319 unsigned char tmp[DES_CBLOCK_LEN];
320 memcpy(tmp, input, length);
321 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
322 load(tmp, u);
323 DES_encrypt(u, ks, 0);
324 u[0] ^= uiv[0]; u[1] ^= uiv[1];
325 store(u, output);
328 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
335 void
336 DES_pcbc_encrypt(const void *in, void *out, long length,
337 DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt)
339 const unsigned char *input = in;
340 unsigned char *output = out;
341 uint32_t u[2];
342 uint32_t uiv[2];
344 load(*iv, uiv);
346 if (forward_encrypt) {
347 uint32_t t[2];
348 while (length >= DES_CBLOCK_LEN) {
349 load(input, u);
350 t[0] = u[0]; t[1] = u[1];
351 u[0] ^= uiv[0]; u[1] ^= uiv[1];
352 DES_encrypt(u, ks, 1);
353 uiv[0] = u[0] ^ t[0]; uiv[1] = u[1] ^ t[1];
354 store(u, output);
356 length -= DES_CBLOCK_LEN;
357 input += DES_CBLOCK_LEN;
358 output += DES_CBLOCK_LEN;
360 if (length) {
361 unsigned char tmp[DES_CBLOCK_LEN];
362 memcpy(tmp, input, length);
363 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
364 load(tmp, u);
365 u[0] ^= uiv[0]; u[1] ^= uiv[1];
366 DES_encrypt(u, ks, 1);
367 store(u, output);
369 } else {
370 uint32_t t[2];
371 while (length >= DES_CBLOCK_LEN) {
372 load(input, u);
373 t[0] = u[0]; t[1] = u[1];
374 DES_encrypt(u, ks, 0);
375 u[0] ^= uiv[0]; u[1] ^= uiv[1];
376 store(u, output);
377 uiv[0] = t[0] ^ u[0]; uiv[1] = t[1] ^ u[1];
379 length -= DES_CBLOCK_LEN;
380 input += DES_CBLOCK_LEN;
381 output += DES_CBLOCK_LEN;
383 if (length) {
384 unsigned char tmp[DES_CBLOCK_LEN];
385 memcpy(tmp, input, length);
386 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
387 load(tmp, u);
388 DES_encrypt(u, ks, 0);
389 u[0] ^= uiv[0]; u[1] ^= uiv[1];
392 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
399 static void
400 _des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2,
401 DES_key_schedule *ks3, int forward_encrypt)
403 IP(u);
404 if (forward_encrypt) {
405 desx(u, ks1, 1); /* IP + FP cancel out each other */
406 desx(u, ks2, 0);
407 desx(u, ks3, 1);
408 } else {
409 desx(u, ks3, 0);
410 desx(u, ks2, 1);
411 desx(u, ks1, 0);
413 FP(u);
420 void
421 DES_ecb3_encrypt(DES_cblock *input,
422 DES_cblock *output,
423 DES_key_schedule *ks1,
424 DES_key_schedule *ks2,
425 DES_key_schedule *ks3,
426 int forward_encrypt)
428 uint32_t u[2];
429 load(*input, u);
430 _des3_encrypt(u, ks1, ks2, ks3, forward_encrypt);
431 store(u, *output);
432 return;
439 void
440 DES_ede3_cbc_encrypt(const void *in, void *out,
441 long length, DES_key_schedule *ks1,
442 DES_key_schedule *ks2, DES_key_schedule *ks3,
443 DES_cblock *iv, int forward_encrypt)
445 const unsigned char *input = in;
446 unsigned char *output = out;
447 uint32_t u[2];
448 uint32_t uiv[2];
450 load(*iv, uiv);
452 if (forward_encrypt) {
453 while (length >= DES_CBLOCK_LEN) {
454 load(input, u);
455 u[0] ^= uiv[0]; u[1] ^= uiv[1];
456 _des3_encrypt(u, ks1, ks2, ks3, 1);
457 uiv[0] = u[0]; uiv[1] = u[1];
458 store(u, output);
460 length -= DES_CBLOCK_LEN;
461 input += DES_CBLOCK_LEN;
462 output += DES_CBLOCK_LEN;
464 if (length) {
465 unsigned char tmp[DES_CBLOCK_LEN];
466 memcpy(tmp, input, length);
467 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
468 load(tmp, u);
469 u[0] ^= uiv[0]; u[1] ^= uiv[1];
470 _des3_encrypt(u, ks1, ks2, ks3, 1);
471 store(u, output);
473 } else {
474 uint32_t t[2];
475 while (length >= DES_CBLOCK_LEN) {
476 load(input, u);
477 t[0] = u[0]; t[1] = u[1];
478 _des3_encrypt(u, ks1, ks2, ks3, 0);
479 u[0] ^= uiv[0]; u[1] ^= uiv[1];
480 store(u, output);
481 uiv[0] = t[0]; uiv[1] = t[1];
483 length -= DES_CBLOCK_LEN;
484 input += DES_CBLOCK_LEN;
485 output += DES_CBLOCK_LEN;
487 if (length) {
488 unsigned char tmp[DES_CBLOCK_LEN];
489 memcpy(tmp, input, length);
490 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
491 load(tmp, u);
492 _des3_encrypt(u, ks1, ks2, ks3, 0);
493 u[0] ^= uiv[0]; u[1] ^= uiv[1];
494 store(u, output);
497 store(uiv, *iv);
498 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
505 void
506 DES_cfb64_encrypt(const void *in, void *out,
507 long length, DES_key_schedule *ks, DES_cblock *iv,
508 int *num, int forward_encrypt)
510 const unsigned char *input = in;
511 unsigned char *output = out;
512 unsigned char tmp[DES_CBLOCK_LEN];
513 uint32_t uiv[2];
515 load(*iv, uiv);
517 assert(*num >= 0 && *num < DES_CBLOCK_LEN);
519 if (forward_encrypt) {
520 int i = *num;
522 while (length > 0) {
523 if (i == 0)
524 DES_encrypt(uiv, ks, 1);
525 store(uiv, tmp);
526 for (; i < DES_CBLOCK_LEN && i < length; i++) {
527 output[i] = tmp[i] ^ input[i];
529 if (i == DES_CBLOCK_LEN)
530 load(output, uiv);
531 output += i;
532 input += i;
533 length -= i;
534 if (i == DES_CBLOCK_LEN)
535 i = 0;
537 store(uiv, *iv);
538 *num = i;
539 } else {
540 int i = *num;
541 unsigned char c;
543 while (length > 0) {
544 if (i == 0) {
545 DES_encrypt(uiv, ks, 1);
546 store(uiv, tmp);
548 for (; i < DES_CBLOCK_LEN && i < length; i++) {
549 c = input[i];
550 output[i] = tmp[i] ^ input[i];
551 (*iv)[i] = c;
553 output += i;
554 input += i;
555 length -= i;
556 if (i == DES_CBLOCK_LEN) {
557 i = 0;
558 load(*iv, uiv);
561 store(uiv, *iv);
562 *num = i;
570 uint32_t
571 DES_cbc_cksum(const void *in, DES_cblock *output,
572 long length, DES_key_schedule *ks, DES_cblock *iv)
574 const unsigned char *input = in;
575 uint32_t uiv[2];
576 uint32_t u[2] = { 0, 0 };
578 load(*iv, uiv);
580 while (length >= DES_CBLOCK_LEN) {
581 load(input, u);
582 u[0] ^= uiv[0]; u[1] ^= uiv[1];
583 DES_encrypt(u, ks, 1);
584 uiv[0] = u[0]; uiv[1] = u[1];
586 length -= DES_CBLOCK_LEN;
587 input += DES_CBLOCK_LEN;
589 if (length) {
590 unsigned char tmp[DES_CBLOCK_LEN];
591 memcpy(tmp, input, length);
592 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
593 load(tmp, u);
594 u[0] ^= uiv[0]; u[1] ^= uiv[1];
595 DES_encrypt(u, ks, 1);
597 if (output)
598 store(u, *output);
600 uiv[0] = 0; u[0] = 0; uiv[1] = 0;
601 return u[1];
608 static unsigned char
609 bitswap8(unsigned char b)
611 unsigned char r = 0;
612 int i;
613 for (i = 0; i < 8; i++) {
614 r = r << 1 | (b & 1);
615 b = b >> 1;
617 return r;
620 void
621 DES_string_to_key(const char *str, DES_cblock *key)
623 const unsigned char *s;
624 unsigned char *k;
625 DES_key_schedule ks;
626 size_t i, len;
628 memset(key, 0, sizeof(*key));
629 k = *key;
630 s = (const unsigned char *)str;
632 len = strlen(str);
633 for (i = 0; i < len; i++) {
634 if ((i % 16) < 8)
635 k[i % 8] ^= s[i] << 1;
636 else
637 k[7 - (i % 8)] ^= bitswap8(s[i]);
639 DES_set_odd_parity(key);
640 if (DES_is_weak_key(key))
641 k[7] ^= 0xF0;
642 DES_set_key(key, &ks);
643 DES_cbc_cksum(s, key, len, &ks, key);
644 memset(&ks, 0, sizeof(ks));
645 DES_set_odd_parity(key);
646 if (DES_is_weak_key(key))
647 k[7] ^= 0xF0;
655 DES_read_password(DES_cblock *key, char *prompt, int verify)
657 char buf[512];
658 int ret;
660 ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify);
661 if (ret == 0)
662 DES_string_to_key(buf, key);
663 return ret;
671 void
672 _DES_ipfp_test(void)
674 DES_cblock k = "\x01\x02\x04\x08\x10\x20\x40\x80", k2;
675 uint32_t u[2] = { 1, 0 };
676 IP(u);
677 FP(u);
678 IP(u);
679 FP(u);
680 if (u[0] != 1 || u[1] != 0)
681 abort();
683 load(k, u);
684 store(u, k2);
685 if (memcmp(k, k2, 8) != 0)
686 abort();
689 /* D3DES (V5.09) -
691 * A portable, public domain, version of the Data Encryption Standard.
693 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
694 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
695 * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
696 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
697 * for humouring me on.
699 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
700 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
703 static uint32_t SP1[64] = {
704 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
705 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
706 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
707 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
708 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
709 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
710 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
711 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
712 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
713 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
714 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
715 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
716 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
717 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
718 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
719 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
721 static uint32_t SP2[64] = {
722 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
723 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
724 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
725 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
726 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
727 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
728 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
729 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
730 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
731 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
732 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
733 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
734 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
735 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
736 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
737 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
739 static uint32_t SP3[64] = {
740 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
741 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
742 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
743 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
744 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
745 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
746 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
747 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
748 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
749 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
750 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
751 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
752 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
753 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
754 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
755 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
757 static uint32_t SP4[64] = {
758 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
759 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
760 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
761 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
762 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
763 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
764 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
765 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
766 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
767 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
768 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
769 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
770 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
771 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
772 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
773 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
775 static uint32_t SP5[64] = {
776 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
777 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
778 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
779 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
780 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
781 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
782 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
783 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
784 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
785 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
786 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
787 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
788 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
789 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
790 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
791 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
793 static uint32_t SP6[64] = {
794 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
795 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
796 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
797 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
798 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
799 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
800 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
801 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
802 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
803 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
804 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
805 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
806 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
807 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
808 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
809 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
811 static uint32_t SP7[64] = {
812 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
813 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
814 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
815 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
816 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
817 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
818 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
819 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
820 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
821 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
822 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
823 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
824 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
825 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
826 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
827 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
829 static uint32_t SP8[64] = {
830 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
831 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
832 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
833 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
834 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
835 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
836 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
837 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
838 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
839 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
840 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
841 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
842 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
843 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
844 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
845 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
847 static void
848 IP(uint32_t v[2])
850 uint32_t work;
852 work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
853 v[1] ^= work;
854 v[0] ^= (work << 4);
855 work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
856 v[1] ^= work;
857 v[0] ^= (work << 16);
858 work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
859 v[0] ^= work;
860 v[1] ^= (work << 2);
861 work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
862 v[0] ^= work;
863 v[1] ^= (work << 8);
864 v[1] = ((v[1] << 1) | ((v[1] >> 31) & 1L)) & 0xffffffffL;
865 work = (v[0] ^ v[1]) & 0xaaaaaaaaL;
866 v[0] ^= work;
867 v[1] ^= work;
868 v[0] = ((v[0] << 1) | ((v[0] >> 31) & 1L)) & 0xffffffffL;
871 static void
872 FP(uint32_t v[2])
874 uint32_t work;
876 v[0] = (v[0] << 31) | (v[0] >> 1);
877 work = (v[1] ^ v[0]) & 0xaaaaaaaaL;
878 v[1] ^= work;
879 v[0] ^= work;
880 v[1] = (v[1] << 31) | (v[1] >> 1);
881 work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
882 v[0] ^= work;
883 v[1] ^= (work << 8);
884 work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
885 v[0] ^= work;
886 v[1] ^= (work << 2);
887 work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
888 v[1] ^= work;
889 v[0] ^= (work << 16);
890 work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
891 v[1] ^= work;
892 v[0] ^= (work << 4);
895 static void
896 desx(uint32_t block[2], DES_key_schedule *ks, int forward_encrypt)
898 uint32_t *keys;
899 uint32_t fval, work, right, left;
900 int round;
902 left = block[0];
903 right = block[1];
905 if (forward_encrypt) {
906 keys = &ks->ks[0];
908 for( round = 0; round < 8; round++ ) {
909 work = (right << 28) | (right >> 4);
910 work ^= *keys++;
911 fval = SP7[ work & 0x3fL];
912 fval |= SP5[(work >> 8) & 0x3fL];
913 fval |= SP3[(work >> 16) & 0x3fL];
914 fval |= SP1[(work >> 24) & 0x3fL];
915 work = right ^ *keys++;
916 fval |= SP8[ work & 0x3fL];
917 fval |= SP6[(work >> 8) & 0x3fL];
918 fval |= SP4[(work >> 16) & 0x3fL];
919 fval |= SP2[(work >> 24) & 0x3fL];
920 left ^= fval;
921 work = (left << 28) | (left >> 4);
922 work ^= *keys++;
923 fval = SP7[ work & 0x3fL];
924 fval |= SP5[(work >> 8) & 0x3fL];
925 fval |= SP3[(work >> 16) & 0x3fL];
926 fval |= SP1[(work >> 24) & 0x3fL];
927 work = left ^ *keys++;
928 fval |= SP8[ work & 0x3fL];
929 fval |= SP6[(work >> 8) & 0x3fL];
930 fval |= SP4[(work >> 16) & 0x3fL];
931 fval |= SP2[(work >> 24) & 0x3fL];
932 right ^= fval;
934 } else {
935 keys = &ks->ks[30];
937 for( round = 0; round < 8; round++ ) {
938 work = (right << 28) | (right >> 4);
939 work ^= *keys++;
940 fval = SP7[ work & 0x3fL];
941 fval |= SP5[(work >> 8) & 0x3fL];
942 fval |= SP3[(work >> 16) & 0x3fL];
943 fval |= SP1[(work >> 24) & 0x3fL];
944 work = right ^ *keys++;
945 fval |= SP8[ work & 0x3fL];
946 fval |= SP6[(work >> 8) & 0x3fL];
947 fval |= SP4[(work >> 16) & 0x3fL];
948 fval |= SP2[(work >> 24) & 0x3fL];
949 left ^= fval;
950 work = (left << 28) | (left >> 4);
951 keys -= 4;
952 work ^= *keys++;
953 fval = SP7[ work & 0x3fL];
954 fval |= SP5[(work >> 8) & 0x3fL];
955 fval |= SP3[(work >> 16) & 0x3fL];
956 fval |= SP1[(work >> 24) & 0x3fL];
957 work = left ^ *keys++;
958 fval |= SP8[ work & 0x3fL];
959 fval |= SP6[(work >> 8) & 0x3fL];
960 fval |= SP4[(work >> 16) & 0x3fL];
961 fval |= SP2[(work >> 24) & 0x3fL];
962 right ^= fval;
963 keys -= 4;
966 block[0] = right;
967 block[1] = left;