2 * Copyright (c) 2005 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
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.
48 RCSID("$Id: des.c 17211 2006-04-24 14:26:19Z lha $");
54 #include <krb5-types.h>
60 static void desx(uint32_t [2], DES_key_schedule *, int);
61 static void IP(uint32_t [2]);
62 static void FP(uint32_t [2]);
64 #include "des-tables.h"
66 #define ROTATE_LEFT28(x,one) \
68 x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \
70 x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \
78 DES_set_odd_parity(DES_cblock *key)
81 for (i = 0; i < DES_CBLOCK_LEN; i++)
82 (*key)[i] = odd_parity[(*key)[i]];
91 static DES_cblock weak_keys[] = {
92 {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */
93 {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
94 {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
95 {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
96 {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */
97 {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
98 {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
99 {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
100 {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
101 {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
102 {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
103 {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
104 {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
105 {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
106 {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
107 {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}
111 DES_is_weak_key(DES_cblock *key)
115 for (i = 0; i < sizeof(weak_keys)/sizeof(weak_keys[0]); i++) {
116 if (memcmp(weak_keys[i], key, DES_CBLOCK_LEN) == 0)
128 DES_set_key(DES_cblock *key, DES_key_schedule *ks)
132 int shifts[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
133 uint32_t *k = &ks->ks[0];
136 t1 = (*key)[0] << 24 | (*key)[1] << 16 | (*key)[2] << 8 | (*key)[3];
137 t2 = (*key)[4] << 24 | (*key)[5] << 16 | (*key)[6] << 8 | (*key)[7];
139 c = (pc1_c_3[(t1 >> (5 )) & 0x7] << 3)
140 | (pc1_c_3[(t1 >> (5 + 8 )) & 0x7] << 2)
141 | (pc1_c_3[(t1 >> (5 + 8 + 8 )) & 0x7] << 1)
142 | (pc1_c_3[(t1 >> (5 + 8 + 8 + 8)) & 0x7] << 0)
143 | (pc1_c_4[(t2 >> (4 )) & 0xf] << 3)
144 | (pc1_c_4[(t2 >> (4 + 8 )) & 0xf] << 2)
145 | (pc1_c_4[(t2 >> (4 + 8 + 8 )) & 0xf] << 1)
146 | (pc1_c_4[(t2 >> (4 + 8 + 8 + 8)) & 0xf] << 0);
149 d = (pc1_d_3[(t2 >> (1 )) & 0x7] << 3)
150 | (pc1_d_3[(t2 >> (1 + 8 )) & 0x7] << 2)
151 | (pc1_d_3[(t2 >> (1 + 8 + 8 )) & 0x7] << 1)
152 | (pc1_d_3[(t2 >> (1 + 8 + 8 + 8)) & 0x7] << 0)
153 | (pc1_d_4[(t1 >> (1 )) & 0xf] << 3)
154 | (pc1_d_4[(t1 >> (1 + 8 )) & 0xf] << 2)
155 | (pc1_d_4[(t1 >> (1 + 8 + 8 )) & 0xf] << 1)
156 | (pc1_d_4[(t1 >> (1 + 8 + 8 + 8)) & 0xf] << 0);
158 for (i = 0; i < 16; i++) {
161 ROTATE_LEFT28(c, shifts[i]);
162 ROTATE_LEFT28(d, shifts[i]);
164 kc = pc2_c_1[(c >> 22) & 0x3f] |
165 pc2_c_2[((c >> 16) & 0x30) | ((c >> 15) & 0xf)] |
166 pc2_c_3[((c >> 9 ) & 0x3c) | ((c >> 8 ) & 0x3)] |
167 pc2_c_4[((c >> 2 ) & 0x20) | ((c >> 1) & 0x18) | (c & 0x7)];
168 kd = pc2_d_1[(d >> 22) & 0x3f] |
169 pc2_d_2[((d >> 15) & 0x30) | ((d >> 14) & 0xf)] |
170 pc2_d_3[ (d >> 7 ) & 0x3f] |
171 pc2_d_4[((d >> 1 ) & 0x3c) | ((d ) & 0x3)];
173 /* Change to byte order used by the S boxes */
174 *k = (kc & 0x00fc0000L) << 6;
175 *k |= (kc & 0x00000fc0L) << 10;
176 *k |= (kd & 0x00fc0000L) >> 10;
177 *k++ |= (kd & 0x00000fc0L) >> 6;
178 *k = (kc & 0x0003f000L) << 12;
179 *k |= (kc & 0x0000003fL) << 16;
180 *k |= (kd & 0x0003f000L) >> 4;
181 *k++ |= (kd & 0x0000003fL);
192 DES_set_key_checked(DES_cblock *key, DES_key_schedule *ks)
194 if (DES_is_weak_key(key)) {
195 memset(ks, 0, sizeof(*ks));
198 return DES_set_key(key, ks);
202 * Compatibility function for eay libdes
206 DES_key_sched(DES_cblock *key, DES_key_schedule *ks)
208 return DES_set_key(key, ks);
216 load(const unsigned char *b, uint32_t v[2])
229 store(const uint32_t v[2], unsigned char *b)
231 b[0] = (v[0] >> 24) & 0xff;
232 b[1] = (v[0] >> 16) & 0xff;
233 b[2] = (v[0] >> 8) & 0xff;
234 b[3] = (v[0] >> 0) & 0xff;
235 b[4] = (v[1] >> 24) & 0xff;
236 b[5] = (v[1] >> 16) & 0xff;
237 b[6] = (v[1] >> 8) & 0xff;
238 b[7] = (v[1] >> 0) & 0xff;
246 DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int forward_encrypt)
249 desx(u, ks, forward_encrypt);
258 DES_ecb_encrypt(DES_cblock *input, DES_cblock *output,
259 DES_key_schedule *ks, int forward_encrypt)
263 DES_encrypt(u, ks, forward_encrypt);
272 DES_cbc_encrypt(const void *in, void *out, long length,
273 DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt)
275 const unsigned char *input = in;
276 unsigned char *output = out;
282 if (forward_encrypt) {
283 while (length >= DES_CBLOCK_LEN) {
285 u[0] ^= uiv[0]; u[1] ^= uiv[1];
286 DES_encrypt(u, ks, 1);
287 uiv[0] = u[0]; uiv[1] = u[1];
290 length -= DES_CBLOCK_LEN;
291 input += DES_CBLOCK_LEN;
292 output += DES_CBLOCK_LEN;
295 unsigned char tmp[DES_CBLOCK_LEN];
296 memcpy(tmp, input, length);
297 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
299 u[0] ^= uiv[0]; u[1] ^= uiv[1];
300 DES_encrypt(u, ks, 1);
305 while (length >= DES_CBLOCK_LEN) {
307 t[0] = u[0]; t[1] = u[1];
308 DES_encrypt(u, ks, 0);
309 u[0] ^= uiv[0]; u[1] ^= uiv[1];
311 uiv[0] = t[0]; uiv[1] = t[1];
313 length -= DES_CBLOCK_LEN;
314 input += DES_CBLOCK_LEN;
315 output += DES_CBLOCK_LEN;
318 unsigned char tmp[DES_CBLOCK_LEN];
319 memcpy(tmp, input, length);
320 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
322 DES_encrypt(u, ks, 0);
323 u[0] ^= uiv[0]; u[1] ^= uiv[1];
327 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
335 DES_pcbc_encrypt(const void *in, void *out, long length,
336 DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt)
338 const unsigned char *input = in;
339 unsigned char *output = out;
345 if (forward_encrypt) {
347 while (length >= DES_CBLOCK_LEN) {
349 t[0] = u[0]; t[1] = u[1];
350 u[0] ^= uiv[0]; u[1] ^= uiv[1];
351 DES_encrypt(u, ks, 1);
352 uiv[0] = u[0] ^ t[0]; uiv[1] = u[1] ^ t[1];
355 length -= DES_CBLOCK_LEN;
356 input += DES_CBLOCK_LEN;
357 output += DES_CBLOCK_LEN;
360 unsigned char tmp[DES_CBLOCK_LEN];
361 memcpy(tmp, input, length);
362 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
364 u[0] ^= uiv[0]; u[1] ^= uiv[1];
365 DES_encrypt(u, ks, 1);
370 while (length >= DES_CBLOCK_LEN) {
372 t[0] = u[0]; t[1] = u[1];
373 DES_encrypt(u, ks, 0);
374 u[0] ^= uiv[0]; u[1] ^= uiv[1];
376 uiv[0] = t[0] ^ u[0]; uiv[1] = t[1] ^ u[1];
378 length -= DES_CBLOCK_LEN;
379 input += DES_CBLOCK_LEN;
380 output += DES_CBLOCK_LEN;
383 unsigned char tmp[DES_CBLOCK_LEN];
384 memcpy(tmp, input, length);
385 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
387 DES_encrypt(u, ks, 0);
388 u[0] ^= uiv[0]; u[1] ^= uiv[1];
391 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
399 _des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2,
400 DES_key_schedule *ks3, int forward_encrypt)
403 if (forward_encrypt) {
404 desx(u, ks1, 1); /* IP + FP cancel out each other */
420 DES_ecb3_encrypt(DES_cblock *input,
422 DES_key_schedule *ks1,
423 DES_key_schedule *ks2,
424 DES_key_schedule *ks3,
429 _des3_encrypt(u, ks1, ks2, ks3, forward_encrypt);
439 DES_ede3_cbc_encrypt(const void *in, void *out,
440 long length, DES_key_schedule *ks1,
441 DES_key_schedule *ks2, DES_key_schedule *ks3,
442 DES_cblock *iv, int forward_encrypt)
444 const unsigned char *input = in;
445 unsigned char *output = out;
451 if (forward_encrypt) {
452 while (length >= DES_CBLOCK_LEN) {
454 u[0] ^= uiv[0]; u[1] ^= uiv[1];
455 _des3_encrypt(u, ks1, ks2, ks3, 1);
456 uiv[0] = u[0]; uiv[1] = u[1];
459 length -= DES_CBLOCK_LEN;
460 input += DES_CBLOCK_LEN;
461 output += DES_CBLOCK_LEN;
464 unsigned char tmp[DES_CBLOCK_LEN];
465 memcpy(tmp, input, length);
466 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
468 u[0] ^= uiv[0]; u[1] ^= uiv[1];
469 _des3_encrypt(u, ks1, ks2, ks3, 1);
474 while (length >= DES_CBLOCK_LEN) {
476 t[0] = u[0]; t[1] = u[1];
477 _des3_encrypt(u, ks1, ks2, ks3, 0);
478 u[0] ^= uiv[0]; u[1] ^= uiv[1];
480 uiv[0] = t[0]; uiv[1] = t[1];
482 length -= DES_CBLOCK_LEN;
483 input += DES_CBLOCK_LEN;
484 output += DES_CBLOCK_LEN;
487 unsigned char tmp[DES_CBLOCK_LEN];
488 memcpy(tmp, input, length);
489 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
491 _des3_encrypt(u, ks1, ks2, ks3, 0);
492 u[0] ^= uiv[0]; u[1] ^= uiv[1];
497 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
505 DES_cfb64_encrypt(const void *in, void *out,
506 long length, DES_key_schedule *ks, DES_cblock *iv,
507 int *num, int forward_encrypt)
509 const unsigned char *input = in;
510 unsigned char *output = out;
511 unsigned char tmp[DES_CBLOCK_LEN];
516 assert(*num >= 0 && *num < DES_CBLOCK_LEN);
518 if (forward_encrypt) {
523 DES_encrypt(uiv, ks, 1);
525 for (; i < DES_CBLOCK_LEN && i < length; i++) {
526 output[i] = tmp[i] ^ input[i];
528 if (i == DES_CBLOCK_LEN)
533 if (i == DES_CBLOCK_LEN)
544 DES_encrypt(uiv, ks, 1);
547 for (; i < DES_CBLOCK_LEN && i < length; i++) {
549 output[i] = tmp[i] ^ input[i];
555 if (i == DES_CBLOCK_LEN) {
570 DES_cbc_cksum(const void *in, DES_cblock *output,
571 long length, DES_key_schedule *ks, DES_cblock *iv)
573 const unsigned char *input = in;
575 uint32_t u[2] = { 0, 0 };
579 while (length >= DES_CBLOCK_LEN) {
581 u[0] ^= uiv[0]; u[1] ^= uiv[1];
582 DES_encrypt(u, ks, 1);
583 uiv[0] = u[0]; uiv[1] = u[1];
585 length -= DES_CBLOCK_LEN;
586 input += DES_CBLOCK_LEN;
589 unsigned char tmp[DES_CBLOCK_LEN];
590 memcpy(tmp, input, length);
591 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
593 u[0] ^= uiv[0]; u[1] ^= uiv[1];
594 DES_encrypt(u, ks, 1);
599 uiv[0] = 0; u[0] = 0; uiv[1] = 0;
608 bitswap8(unsigned char b)
612 for (i = 0; i < 8; i++) {
613 r = r << 1 | (b & 1);
620 DES_string_to_key(const char *str, DES_cblock *key)
622 const unsigned char *s;
627 memset(key, 0, sizeof(*key));
629 s = (const unsigned char *)str;
632 for (i = 0; i < len; i++) {
634 k[i % 8] ^= s[i] << 1;
636 k[7 - (i % 8)] ^= bitswap8(s[i]);
638 DES_set_odd_parity(key);
639 if (DES_is_weak_key(key))
641 DES_set_key(key, &ks);
642 DES_cbc_cksum(s, key, len, &ks, key);
643 memset(&ks, 0, sizeof(ks));
644 DES_set_odd_parity(key);
645 if (DES_is_weak_key(key))
654 DES_read_password(DES_cblock *key, char *prompt, int verify)
659 ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify);
661 DES_string_to_key(buf, key);
673 DES_cblock k = "\x01\x02\x04\x08\x10\x20\x40\x80", k2;
674 uint32_t u[2] = { 1, 0 };
679 if (u[0] != 1 || u[1] != 0)
684 if (memcmp(k, k2, 8) != 0)
690 * A portable, public domain, version of the Data Encryption Standard.
692 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
693 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
694 * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
695 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
696 * for humouring me on.
698 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
699 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
702 static uint32_t SP1[64] = {
703 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
704 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
705 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
706 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
707 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
708 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
709 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
710 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
711 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
712 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
713 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
714 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
715 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
716 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
717 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
718 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
720 static uint32_t SP2[64] = {
721 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
722 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
723 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
724 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
725 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
726 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
727 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
728 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
729 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
730 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
731 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
732 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
733 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
734 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
735 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
736 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
738 static uint32_t SP3[64] = {
739 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
740 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
741 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
742 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
743 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
744 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
745 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
746 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
747 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
748 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
749 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
750 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
751 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
752 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
753 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
754 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
756 static uint32_t SP4[64] = {
757 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
758 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
759 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
760 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
761 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
762 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
763 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
764 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
765 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
766 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
767 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
768 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
769 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
770 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
771 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
772 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
774 static uint32_t SP5[64] = {
775 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
776 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
777 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
778 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
779 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
780 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
781 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
782 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
783 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
784 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
785 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
786 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
787 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
788 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
789 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
790 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
792 static uint32_t SP6[64] = {
793 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
794 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
795 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
796 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
797 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
798 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
799 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
800 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
801 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
802 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
803 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
804 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
805 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
806 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
807 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
808 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
810 static uint32_t SP7[64] = {
811 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
812 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
813 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
814 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
815 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
816 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
817 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
818 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
819 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
820 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
821 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
822 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
823 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
824 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
825 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
826 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
828 static uint32_t SP8[64] = {
829 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
830 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
831 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
832 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
833 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
834 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
835 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
836 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
837 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
838 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
839 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
840 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
841 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
842 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
843 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
844 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
851 work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
854 work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
856 v[0] ^= (work << 16);
857 work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
860 work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
863 v[1] = ((v[1] << 1) | ((v[1] >> 31) & 1L)) & 0xffffffffL;
864 work = (v[0] ^ v[1]) & 0xaaaaaaaaL;
867 v[0] = ((v[0] << 1) | ((v[0] >> 31) & 1L)) & 0xffffffffL;
875 v[0] = (v[0] << 31) | (v[0] >> 1);
876 work = (v[1] ^ v[0]) & 0xaaaaaaaaL;
879 v[1] = (v[1] << 31) | (v[1] >> 1);
880 work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
883 work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
886 work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
888 v[0] ^= (work << 16);
889 work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
895 desx(uint32_t block[2], DES_key_schedule *ks, int forward_encrypt)
898 uint32_t fval, work, right, left;
904 if (forward_encrypt) {
907 for( round = 0; round < 8; round++ ) {
908 work = (right << 28) | (right >> 4);
910 fval = SP7[ work & 0x3fL];
911 fval |= SP5[(work >> 8) & 0x3fL];
912 fval |= SP3[(work >> 16) & 0x3fL];
913 fval |= SP1[(work >> 24) & 0x3fL];
914 work = right ^ *keys++;
915 fval |= SP8[ work & 0x3fL];
916 fval |= SP6[(work >> 8) & 0x3fL];
917 fval |= SP4[(work >> 16) & 0x3fL];
918 fval |= SP2[(work >> 24) & 0x3fL];
920 work = (left << 28) | (left >> 4);
922 fval = SP7[ work & 0x3fL];
923 fval |= SP5[(work >> 8) & 0x3fL];
924 fval |= SP3[(work >> 16) & 0x3fL];
925 fval |= SP1[(work >> 24) & 0x3fL];
926 work = left ^ *keys++;
927 fval |= SP8[ work & 0x3fL];
928 fval |= SP6[(work >> 8) & 0x3fL];
929 fval |= SP4[(work >> 16) & 0x3fL];
930 fval |= SP2[(work >> 24) & 0x3fL];
936 for( round = 0; round < 8; round++ ) {
937 work = (right << 28) | (right >> 4);
939 fval = SP7[ work & 0x3fL];
940 fval |= SP5[(work >> 8) & 0x3fL];
941 fval |= SP3[(work >> 16) & 0x3fL];
942 fval |= SP1[(work >> 24) & 0x3fL];
943 work = right ^ *keys++;
944 fval |= SP8[ work & 0x3fL];
945 fval |= SP6[(work >> 8) & 0x3fL];
946 fval |= SP4[(work >> 16) & 0x3fL];
947 fval |= SP2[(work >> 24) & 0x3fL];
949 work = (left << 28) | (left >> 4);
952 fval = SP7[ work & 0x3fL];
953 fval |= SP5[(work >> 8) & 0x3fL];
954 fval |= SP3[(work >> 16) & 0x3fL];
955 fval |= SP1[(work >> 24) & 0x3fL];
956 work = left ^ *keys++;
957 fval |= SP8[ work & 0x3fL];
958 fval |= SP6[(work >> 8) & 0x3fL];
959 fval |= SP4[(work >> 16) & 0x3fL];
960 fval |= SP2[(work >> 24) & 0x3fL];