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,v 1.14 2005/06/18 22:47:17 lha Exp $");
54 #include <krb5-types.h>
58 static void desx(uint32_t [2], DES_key_schedule *, int);
59 static void IP(uint32_t [2]);
60 static void FP(uint32_t [2]);
62 #include "des-tables.h"
64 #define ROTATE_LEFT28(x,one) \
66 x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \
68 x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \
76 DES_set_odd_parity(DES_cblock *key)
79 for (i = 0; i < DES_CBLOCK_LEN; i++)
80 (*key)[i] = odd_parity[(*key)[i]];
89 static DES_cblock weak_keys[] = {
90 {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */
91 {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
92 {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
93 {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
94 {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */
95 {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
96 {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
97 {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
98 {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
99 {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
100 {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
101 {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
102 {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
103 {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
104 {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
105 {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}
109 DES_is_weak_key(DES_cblock *key)
113 for (i = 0; i < sizeof(weak_keys)/sizeof(weak_keys[0]); i++) {
114 if (memcmp(weak_keys[i], key, DES_CBLOCK_LEN) == 0)
126 DES_set_key(DES_cblock *key, DES_key_schedule *ks)
130 int shifts[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
131 uint32_t *k = &ks->ks[0];
134 t1 = (*key)[0] << 24 | (*key)[1] << 16 | (*key)[2] << 8 | (*key)[3];
135 t2 = (*key)[4] << 24 | (*key)[5] << 16 | (*key)[6] << 8 | (*key)[7];
137 c = (pc1_c_3[(t1 >> (5 )) & 0x7] << 3)
138 | (pc1_c_3[(t1 >> (5 + 8 )) & 0x7] << 2)
139 | (pc1_c_3[(t1 >> (5 + 8 + 8 )) & 0x7] << 1)
140 | (pc1_c_3[(t1 >> (5 + 8 + 8 + 8)) & 0x7] << 0)
141 | (pc1_c_4[(t2 >> (4 )) & 0xf] << 3)
142 | (pc1_c_4[(t2 >> (4 + 8 )) & 0xf] << 2)
143 | (pc1_c_4[(t2 >> (4 + 8 + 8 )) & 0xf] << 1)
144 | (pc1_c_4[(t2 >> (4 + 8 + 8 + 8)) & 0xf] << 0);
147 d = (pc1_d_3[(t2 >> (1 )) & 0x7] << 3)
148 | (pc1_d_3[(t2 >> (1 + 8 )) & 0x7] << 2)
149 | (pc1_d_3[(t2 >> (1 + 8 + 8 )) & 0x7] << 1)
150 | (pc1_d_3[(t2 >> (1 + 8 + 8 + 8)) & 0x7] << 0)
151 | (pc1_d_4[(t1 >> (1 )) & 0xf] << 3)
152 | (pc1_d_4[(t1 >> (1 + 8 )) & 0xf] << 2)
153 | (pc1_d_4[(t1 >> (1 + 8 + 8 )) & 0xf] << 1)
154 | (pc1_d_4[(t1 >> (1 + 8 + 8 + 8)) & 0xf] << 0);
156 for (i = 0; i < 16; i++) {
159 ROTATE_LEFT28(c, shifts[i]);
160 ROTATE_LEFT28(d, shifts[i]);
162 kc = pc2_c_1[(c >> 22) & 0x3f] |
163 pc2_c_2[((c >> 16) & 0x30) | ((c >> 15) & 0xf)] |
164 pc2_c_3[((c >> 9 ) & 0x3c) | ((c >> 8 ) & 0x3)] |
165 pc2_c_4[((c >> 2 ) & 0x20) | ((c >> 1) & 0x18) | (c & 0x7)];
166 kd = pc2_d_1[(d >> 22) & 0x3f] |
167 pc2_d_2[((d >> 15) & 0x30) | ((d >> 14) & 0xf)] |
168 pc2_d_3[ (d >> 7 ) & 0x3f] |
169 pc2_d_4[((d >> 1 ) & 0x3c) | ((d ) & 0x3)];
171 /* Change to byte order used by the S boxes */
172 *k = (kc & 0x00fc0000L) << 6;
173 *k |= (kc & 0x00000fc0L) << 10;
174 *k |= (kd & 0x00fc0000L) >> 10;
175 *k++ |= (kd & 0x00000fc0L) >> 6;
176 *k = (kc & 0x0003f000L) << 12;
177 *k |= (kc & 0x0000003fL) << 16;
178 *k |= (kd & 0x0003f000L) >> 4;
179 *k++ |= (kd & 0x0000003fL);
190 DES_set_key_checked(DES_cblock *key, DES_key_schedule *ks)
192 if (DES_is_weak_key(key)) {
193 memset(ks, 0, sizeof(*ks));
196 return DES_set_key(key, ks);
200 * Compatibility function for eay libdes
204 DES_key_sched(DES_cblock *key, DES_key_schedule *ks)
206 return DES_set_key(key, ks);
214 load(const unsigned char *b, uint32_t v[2])
227 store(const uint32_t v[2], unsigned char *b)
229 b[0] = (v[0] >> 24) & 0xff;
230 b[1] = (v[0] >> 16) & 0xff;
231 b[2] = (v[0] >> 8) & 0xff;
232 b[3] = (v[0] >> 0) & 0xff;
233 b[4] = (v[1] >> 24) & 0xff;
234 b[5] = (v[1] >> 16) & 0xff;
235 b[6] = (v[1] >> 8) & 0xff;
236 b[7] = (v[1] >> 0) & 0xff;
244 DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int forward_encrypt)
247 desx(u, ks, forward_encrypt);
256 DES_ecb_encrypt(DES_cblock *input, DES_cblock *output,
257 DES_key_schedule *ks, int forward_encrypt)
261 DES_encrypt(u, ks, forward_encrypt);
270 DES_cbc_encrypt(unsigned char *input, unsigned char *output, long length,
271 DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt)
278 if (forward_encrypt) {
279 while (length >= DES_CBLOCK_LEN) {
281 u[0] ^= uiv[0]; u[1] ^= uiv[1];
282 DES_encrypt(u, ks, 1);
283 uiv[0] = u[0]; uiv[1] = u[1];
286 length -= DES_CBLOCK_LEN;
287 input += DES_CBLOCK_LEN;
288 output += DES_CBLOCK_LEN;
291 unsigned char tmp[DES_CBLOCK_LEN];
292 memcpy(tmp, input, length);
293 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
295 u[0] ^= uiv[0]; u[1] ^= uiv[1];
296 DES_encrypt(u, ks, 1);
301 while (length >= DES_CBLOCK_LEN) {
303 t[0] = u[0]; t[1] = u[1];
304 DES_encrypt(u, ks, 0);
305 u[0] ^= uiv[0]; u[1] ^= uiv[1];
307 uiv[0] = t[0]; uiv[1] = t[1];
309 length -= DES_CBLOCK_LEN;
310 input += DES_CBLOCK_LEN;
311 output += DES_CBLOCK_LEN;
314 unsigned char tmp[DES_CBLOCK_LEN];
315 memcpy(tmp, input, length);
316 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
318 DES_encrypt(u, ks, 0);
319 u[0] ^= uiv[0]; u[1] ^= uiv[1];
323 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
331 DES_pcbc_encrypt(unsigned char *input, unsigned char *output, long length,
332 DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt)
339 if (forward_encrypt) {
341 while (length >= DES_CBLOCK_LEN) {
343 t[0] = u[0]; t[1] = u[1];
344 u[0] ^= uiv[0]; u[1] ^= uiv[1];
345 DES_encrypt(u, ks, 1);
346 uiv[0] = u[0] ^ t[0]; uiv[1] = u[1] ^ t[1];
349 length -= DES_CBLOCK_LEN;
350 input += DES_CBLOCK_LEN;
351 output += DES_CBLOCK_LEN;
354 unsigned char tmp[DES_CBLOCK_LEN];
355 memcpy(tmp, input, length);
356 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
358 u[0] ^= uiv[0]; u[1] ^= uiv[1];
359 DES_encrypt(u, ks, 1);
364 while (length >= DES_CBLOCK_LEN) {
366 t[0] = u[0]; t[1] = u[1];
367 DES_encrypt(u, ks, 0);
368 u[0] ^= uiv[0]; u[1] ^= uiv[1];
370 uiv[0] = t[0] ^ u[0]; uiv[1] = t[1] ^ u[1];
372 length -= DES_CBLOCK_LEN;
373 input += DES_CBLOCK_LEN;
374 output += DES_CBLOCK_LEN;
377 unsigned char tmp[DES_CBLOCK_LEN];
378 memcpy(tmp, input, length);
379 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
381 DES_encrypt(u, ks, 0);
382 u[0] ^= uiv[0]; u[1] ^= uiv[1];
385 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
393 _des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2,
394 DES_key_schedule *ks3, int forward_encrypt)
397 if (forward_encrypt) {
398 desx(u, ks1, 1); /* IP + FP cancel out each other */
414 DES_ecb3_encrypt(DES_cblock *input,
416 DES_key_schedule *ks1,
417 DES_key_schedule *ks2,
418 DES_key_schedule *ks3,
423 _des3_encrypt(u, ks1, ks2, ks3, forward_encrypt);
433 DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
434 long length, DES_key_schedule *ks1,
435 DES_key_schedule *ks2, DES_key_schedule *ks3,
436 DES_cblock *iv, int forward_encrypt)
443 if (forward_encrypt) {
444 while (length >= DES_CBLOCK_LEN) {
446 u[0] ^= uiv[0]; u[1] ^= uiv[1];
447 _des3_encrypt(u, ks1, ks2, ks3, 1);
448 uiv[0] = u[0]; uiv[1] = u[1];
451 length -= DES_CBLOCK_LEN;
452 input += DES_CBLOCK_LEN;
453 output += DES_CBLOCK_LEN;
456 unsigned char tmp[DES_CBLOCK_LEN];
457 memcpy(tmp, input, length);
458 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
460 u[0] ^= uiv[0]; u[1] ^= uiv[1];
461 _des3_encrypt(u, ks1, ks2, ks3, 1);
466 while (length >= DES_CBLOCK_LEN) {
468 t[0] = u[0]; t[1] = u[1];
469 _des3_encrypt(u, ks1, ks2, ks3, 0);
470 u[0] ^= uiv[0]; u[1] ^= uiv[1];
472 uiv[0] = t[0]; uiv[1] = t[1];
474 length -= DES_CBLOCK_LEN;
475 input += DES_CBLOCK_LEN;
476 output += DES_CBLOCK_LEN;
479 unsigned char tmp[DES_CBLOCK_LEN];
480 memcpy(tmp, input, length);
481 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
483 _des3_encrypt(u, ks1, ks2, ks3, 0);
484 u[0] ^= uiv[0]; u[1] ^= uiv[1];
489 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
497 DES_cfb64_encrypt(unsigned char *input, unsigned char *output,
498 long length, DES_key_schedule *ks, DES_cblock *iv,
499 int *num, int forward_encrypt)
501 unsigned char tmp[DES_CBLOCK_LEN];
506 if (forward_encrypt) {
511 DES_encrypt(uiv, ks, 1);
513 for (; i < DES_CBLOCK_LEN && i < length; i++) {
514 output[i] = tmp[i] ^ input[i];
516 if (i == DES_CBLOCK_LEN)
521 if (i == DES_CBLOCK_LEN)
532 DES_encrypt(uiv, ks, 1);
535 for (; i < DES_CBLOCK_LEN && i < length; i++) {
537 output[i] = tmp[i] ^ input[i];
543 if (i == DES_CBLOCK_LEN) {
558 DES_cbc_cksum(const unsigned char *input, DES_cblock *output,
559 long length, DES_key_schedule *ks, DES_cblock *iv)
562 uint32_t u[2] = { 0, 0 };
566 while (length >= DES_CBLOCK_LEN) {
568 u[0] ^= uiv[0]; u[1] ^= uiv[1];
569 DES_encrypt(u, ks, 1);
570 uiv[0] = u[0]; uiv[1] = u[1];
572 length -= DES_CBLOCK_LEN;
573 input += DES_CBLOCK_LEN;
576 unsigned char tmp[DES_CBLOCK_LEN];
577 memcpy(tmp, input, length);
578 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
580 u[0] ^= uiv[0]; u[1] ^= uiv[1];
581 DES_encrypt(u, ks, 1);
586 uiv[0] = 0; u[0] = 0; uiv[1] = 0;
595 bitswap8(unsigned char b)
599 for (i = 0; i < 8; i++) {
600 r = r << 1 | (b & 1);
607 DES_string_to_key(const char *str, DES_cblock *key)
609 const unsigned char *s;
614 memset(key, 0, sizeof(*key));
616 s = (const unsigned char *)str;
619 for (i = 0; i < len; i++) {
621 k[i % 8] ^= s[i] << 1;
623 k[7 - (i % 8)] ^= bitswap8(s[i]);
625 DES_set_odd_parity(key);
626 if (DES_is_weak_key(key))
628 DES_set_key(key, &ks);
629 DES_cbc_cksum(s, key, len, &ks, key);
630 memset(&ks, 0, sizeof(ks));
631 DES_set_odd_parity(key);
632 if (DES_is_weak_key(key))
641 DES_read_password(DES_cblock *key, char *prompt, int verify)
646 ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify);
648 DES_string_to_key(buf, key);
660 DES_cblock k = "\x01\x02\x04\x08\x10\x20\x40\x80", k2;
661 uint32_t u[2] = { 1, 0 };
666 if (u[0] != 1 || u[1] != 0)
671 if (memcmp(k, k2, 8) != 0)
677 * A portable, public domain, version of the Data Encryption Standard.
679 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
680 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
681 * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
682 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
683 * for humouring me on.
685 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
686 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
689 static uint32_t SP1[64] = {
690 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
691 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
692 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
693 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
694 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
695 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
696 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
697 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
698 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
699 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
700 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
701 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
702 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
703 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
704 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
705 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
707 static uint32_t SP2[64] = {
708 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
709 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
710 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
711 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
712 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
713 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
714 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
715 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
716 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
717 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
718 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
719 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
720 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
721 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
722 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
723 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
725 static uint32_t SP3[64] = {
726 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
727 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
728 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
729 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
730 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
731 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
732 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
733 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
734 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
735 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
736 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
737 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
738 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
739 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
740 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
741 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
743 static uint32_t SP4[64] = {
744 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
745 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
746 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
747 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
748 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
749 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
750 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
751 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
752 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
753 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
754 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
755 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
756 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
757 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
758 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
759 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
761 static uint32_t SP5[64] = {
762 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
763 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
764 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
765 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
766 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
767 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
768 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
769 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
770 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
771 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
772 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
773 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
774 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
775 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
776 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
777 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
779 static uint32_t SP6[64] = {
780 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
781 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
782 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
783 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
784 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
785 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
786 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
787 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
788 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
789 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
790 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
791 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
792 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
793 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
794 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
795 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
797 static uint32_t SP7[64] = {
798 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
799 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
800 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
801 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
802 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
803 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
804 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
805 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
806 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
807 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
808 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
809 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
810 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
811 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
812 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
813 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
815 static uint32_t SP8[64] = {
816 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
817 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
818 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
819 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
820 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
821 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
822 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
823 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
824 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
825 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
826 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
827 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
828 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
829 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
830 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
831 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
838 work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
841 work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
843 v[0] ^= (work << 16);
844 work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
847 work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
850 v[1] = ((v[1] << 1) | ((v[1] >> 31) & 1L)) & 0xffffffffL;
851 work = (v[0] ^ v[1]) & 0xaaaaaaaaL;
854 v[0] = ((v[0] << 1) | ((v[0] >> 31) & 1L)) & 0xffffffffL;
862 v[0] = (v[0] << 31) | (v[0] >> 1);
863 work = (v[1] ^ v[0]) & 0xaaaaaaaaL;
866 v[1] = (v[1] << 31) | (v[1] >> 1);
867 work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
870 work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
873 work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
875 v[0] ^= (work << 16);
876 work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
882 desx(uint32_t block[2], DES_key_schedule *ks, int forward_encrypt)
885 uint32_t fval, work, right, left;
891 if (forward_encrypt) {
894 for( round = 0; round < 8; round++ ) {
895 work = (right << 28) | (right >> 4);
897 fval = SP7[ work & 0x3fL];
898 fval |= SP5[(work >> 8) & 0x3fL];
899 fval |= SP3[(work >> 16) & 0x3fL];
900 fval |= SP1[(work >> 24) & 0x3fL];
901 work = right ^ *keys++;
902 fval |= SP8[ work & 0x3fL];
903 fval |= SP6[(work >> 8) & 0x3fL];
904 fval |= SP4[(work >> 16) & 0x3fL];
905 fval |= SP2[(work >> 24) & 0x3fL];
907 work = (left << 28) | (left >> 4);
909 fval = SP7[ work & 0x3fL];
910 fval |= SP5[(work >> 8) & 0x3fL];
911 fval |= SP3[(work >> 16) & 0x3fL];
912 fval |= SP1[(work >> 24) & 0x3fL];
913 work = left ^ *keys++;
914 fval |= SP8[ work & 0x3fL];
915 fval |= SP6[(work >> 8) & 0x3fL];
916 fval |= SP4[(work >> 16) & 0x3fL];
917 fval |= SP2[(work >> 24) & 0x3fL];
923 for( round = 0; round < 8; round++ ) {
924 work = (right << 28) | (right >> 4);
926 fval = SP7[ work & 0x3fL];
927 fval |= SP5[(work >> 8) & 0x3fL];
928 fval |= SP3[(work >> 16) & 0x3fL];
929 fval |= SP1[(work >> 24) & 0x3fL];
930 work = right ^ *keys++;
931 fval |= SP8[ work & 0x3fL];
932 fval |= SP6[(work >> 8) & 0x3fL];
933 fval |= SP4[(work >> 16) & 0x3fL];
934 fval |= SP2[(work >> 24) & 0x3fL];
936 work = (left << 28) | (left >> 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 = left ^ *keys++;
944 fval |= SP8[ work & 0x3fL];
945 fval |= SP6[(work >> 8) & 0x3fL];
946 fval |= SP4[(work >> 16) & 0x3fL];
947 fval |= SP2[(work >> 24) & 0x3fL];