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("$Heimdal: des.c 17211 2006-04-24 14:26:19Z lha $"
55 #include <krb5-types.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) \
69 x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \
71 x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \
79 DES_set_odd_parity(DES_cblock
*key
)
82 for (i
= 0; i
< DES_CBLOCK_LEN
; i
++)
83 (*key
)[i
] = odd_parity
[(*key
)[i
]];
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
)
116 for (i
= 0; i
< sizeof(weak_keys
)/sizeof(weak_keys
[0]); i
++) {
117 if (memcmp(weak_keys
[i
], key
, DES_CBLOCK_LEN
) == 0)
129 DES_set_key(DES_cblock
*key
, DES_key_schedule
*ks
)
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];
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
++) {
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
);
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
));
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
);
217 load(const unsigned char *b
, uint32_t v
[2])
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;
247 DES_encrypt(uint32_t u
[2], DES_key_schedule
*ks
, int forward_encrypt
)
250 desx(u
, ks
, forward_encrypt
);
259 DES_ecb_encrypt(DES_cblock
*input
, DES_cblock
*output
,
260 DES_key_schedule
*ks
, int forward_encrypt
)
264 DES_encrypt(u
, ks
, forward_encrypt
);
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
;
283 if (forward_encrypt
) {
284 while (length
>= DES_CBLOCK_LEN
) {
286 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
287 DES_encrypt(u
, ks
, 1);
288 uiv
[0] = u
[0]; uiv
[1] = u
[1];
291 length
-= DES_CBLOCK_LEN
;
292 input
+= DES_CBLOCK_LEN
;
293 output
+= DES_CBLOCK_LEN
;
296 unsigned char tmp
[DES_CBLOCK_LEN
];
297 memcpy(tmp
, input
, length
);
298 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
300 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
301 DES_encrypt(u
, ks
, 1);
306 while (length
>= DES_CBLOCK_LEN
) {
308 t
[0] = u
[0]; t
[1] = u
[1];
309 DES_encrypt(u
, ks
, 0);
310 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
312 uiv
[0] = t
[0]; uiv
[1] = t
[1];
314 length
-= DES_CBLOCK_LEN
;
315 input
+= DES_CBLOCK_LEN
;
316 output
+= DES_CBLOCK_LEN
;
319 unsigned char tmp
[DES_CBLOCK_LEN
];
320 memcpy(tmp
, input
, length
);
321 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
323 DES_encrypt(u
, ks
, 0);
324 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
328 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
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
;
346 if (forward_encrypt
) {
348 while (length
>= DES_CBLOCK_LEN
) {
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];
356 length
-= DES_CBLOCK_LEN
;
357 input
+= DES_CBLOCK_LEN
;
358 output
+= DES_CBLOCK_LEN
;
361 unsigned char tmp
[DES_CBLOCK_LEN
];
362 memcpy(tmp
, input
, length
);
363 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
365 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
366 DES_encrypt(u
, ks
, 1);
371 while (length
>= DES_CBLOCK_LEN
) {
373 t
[0] = u
[0]; t
[1] = u
[1];
374 DES_encrypt(u
, ks
, 0);
375 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
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
;
384 unsigned char tmp
[DES_CBLOCK_LEN
];
385 memcpy(tmp
, input
, length
);
386 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
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;
400 _des3_encrypt(uint32_t u
[2], DES_key_schedule
*ks1
, DES_key_schedule
*ks2
,
401 DES_key_schedule
*ks3
, int forward_encrypt
)
404 if (forward_encrypt
) {
405 desx(u
, ks1
, 1); /* IP + FP cancel out each other */
421 DES_ecb3_encrypt(DES_cblock
*input
,
423 DES_key_schedule
*ks1
,
424 DES_key_schedule
*ks2
,
425 DES_key_schedule
*ks3
,
430 _des3_encrypt(u
, ks1
, ks2
, ks3
, forward_encrypt
);
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
;
452 if (forward_encrypt
) {
453 while (length
>= DES_CBLOCK_LEN
) {
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];
460 length
-= DES_CBLOCK_LEN
;
461 input
+= DES_CBLOCK_LEN
;
462 output
+= DES_CBLOCK_LEN
;
465 unsigned char tmp
[DES_CBLOCK_LEN
];
466 memcpy(tmp
, input
, length
);
467 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
469 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
470 _des3_encrypt(u
, ks1
, ks2
, ks3
, 1);
475 while (length
>= DES_CBLOCK_LEN
) {
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];
481 uiv
[0] = t
[0]; uiv
[1] = t
[1];
483 length
-= DES_CBLOCK_LEN
;
484 input
+= DES_CBLOCK_LEN
;
485 output
+= DES_CBLOCK_LEN
;
488 unsigned char tmp
[DES_CBLOCK_LEN
];
489 memcpy(tmp
, input
, length
);
490 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
492 _des3_encrypt(u
, ks1
, ks2
, ks3
, 0);
493 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
498 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
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
];
517 assert(*num
>= 0 && *num
< DES_CBLOCK_LEN
);
519 if (forward_encrypt
) {
524 DES_encrypt(uiv
, ks
, 1);
526 for (; i
< DES_CBLOCK_LEN
&& i
< length
; i
++) {
527 output
[i
] = tmp
[i
] ^ input
[i
];
529 if (i
== DES_CBLOCK_LEN
)
534 if (i
== DES_CBLOCK_LEN
)
545 DES_encrypt(uiv
, ks
, 1);
548 for (; i
< DES_CBLOCK_LEN
&& i
< length
; i
++) {
550 output
[i
] = tmp
[i
] ^ input
[i
];
556 if (i
== DES_CBLOCK_LEN
) {
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
;
576 uint32_t u
[2] = { 0, 0 };
580 while (length
>= DES_CBLOCK_LEN
) {
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
;
590 unsigned char tmp
[DES_CBLOCK_LEN
];
591 memcpy(tmp
, input
, length
);
592 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
594 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
595 DES_encrypt(u
, ks
, 1);
600 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0;
609 bitswap8(unsigned char b
)
613 for (i
= 0; i
< 8; i
++) {
614 r
= r
<< 1 | (b
& 1);
621 DES_string_to_key(const char *str
, DES_cblock
*key
)
623 const unsigned char *s
;
628 memset(key
, 0, sizeof(*key
));
630 s
= (const unsigned char *)str
;
633 for (i
= 0; i
< len
; i
++) {
635 k
[i
% 8] ^= s
[i
] << 1;
637 k
[7 - (i
% 8)] ^= bitswap8(s
[i
]);
639 DES_set_odd_parity(key
);
640 if (DES_is_weak_key(key
))
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
))
655 DES_read_password(DES_cblock
*key
, char *prompt
, int verify
)
660 ret
= UI_UTIL_read_pw_string(buf
, sizeof(buf
) - 1, prompt
, verify
);
662 DES_string_to_key(buf
, key
);
674 DES_cblock k
= "\x01\x02\x04\x08\x10\x20\x40\x80", k2
;
675 uint32_t u
[2] = { 1, 0 };
680 if (u
[0] != 1 || u
[1] != 0)
685 if (memcmp(k
, k2
, 8) != 0)
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
};
852 work
= ((v
[0] >> 4) ^ v
[1]) & 0x0f0f0f0fL
;
855 work
= ((v
[0] >> 16) ^ v
[1]) & 0x0000ffffL
;
857 v
[0] ^= (work
<< 16);
858 work
= ((v
[1] >> 2) ^ v
[0]) & 0x33333333L
;
861 work
= ((v
[1] >> 8) ^ v
[0]) & 0x00ff00ffL
;
864 v
[1] = ((v
[1] << 1) | ((v
[1] >> 31) & 1L)) & 0xffffffffL
;
865 work
= (v
[0] ^ v
[1]) & 0xaaaaaaaaL
;
868 v
[0] = ((v
[0] << 1) | ((v
[0] >> 31) & 1L)) & 0xffffffffL
;
876 v
[0] = (v
[0] << 31) | (v
[0] >> 1);
877 work
= (v
[1] ^ v
[0]) & 0xaaaaaaaaL
;
880 v
[1] = (v
[1] << 31) | (v
[1] >> 1);
881 work
= ((v
[1] >> 8) ^ v
[0]) & 0x00ff00ffL
;
884 work
= ((v
[1] >> 2) ^ v
[0]) & 0x33333333L
;
887 work
= ((v
[0] >> 16) ^ v
[1]) & 0x0000ffffL
;
889 v
[0] ^= (work
<< 16);
890 work
= ((v
[0] >> 4) ^ v
[1]) & 0x0f0f0f0fL
;
896 desx(uint32_t block
[2], DES_key_schedule
*ks
, int forward_encrypt
)
899 uint32_t fval
, work
, right
, left
;
905 if (forward_encrypt
) {
908 for( round
= 0; round
< 8; round
++ ) {
909 work
= (right
<< 28) | (right
>> 4);
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
];
921 work
= (left
<< 28) | (left
>> 4);
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
];
937 for( round
= 0; round
< 8; round
++ ) {
938 work
= (right
<< 28) | (right
>> 4);
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
];
950 work
= (left
<< 28) | (left
>> 4);
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
];