1 /* $NetBSD: des.c,v 1.1.1.2 2014/04/24 12:45:30 pettai Exp $ */
4 * Copyright (c) 2005 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * @page page_des DES - Data Encryption Standard crypto interface
39 * See the library functions here: @ref hcrypto_des
41 * DES was created by IBM, modififed by NSA and then adopted by NBS
42 * (now NIST) and published ad FIPS PUB 46 (updated by FIPS 46-1).
44 * Since the 19th May 2005 DES was withdrawn by NIST and should no
45 * longer be used. See @ref page_evp for replacement encryption
46 * algorithms and interfaces.
48 * Read more the iteresting history of DES on Wikipedia
49 * http://www.wikipedia.org/wiki/Data_Encryption_Standard .
51 * @section des_keygen DES key generation
53 * To generate a DES key safely you have to use the code-snippet
54 * below. This is because the DES_random_key() can fail with an
55 * abort() in case of and failure to start the random generator.
57 * There is a replacement function DES_new_random_key(), however that
58 * function does not exists in OpenSSL.
63 * if (RAND_rand(&key, sizeof(key)) != 1)
65 * DES_set_odd_parity(key);
66 * } while (DES_is_weak_key(&key));
69 * @section des_impl DES implementation history
71 * There was no complete BSD licensed, fast, GPL compatible
72 * implementation of DES, so Love wrote the part that was missing,
73 * fast key schedule setup and adapted the interface to the orignal
76 * The document that got me started for real was "Efficient
77 * Implementation of the Data Encryption Standard" by Dag Arne Osvik.
78 * I never got to the PC1 transformation was working, instead I used
79 * table-lookup was used for all key schedule setup. The document was
80 * very useful since it de-mystified other implementations for me.
82 * The core DES function (SBOX + P transformation) is from Richard
83 * Outerbridge public domain DES implementation. My sanity is saved
84 * thanks to his work. Thank you Richard.
94 #include <krb5/krb5-types.h>
97 #include <krb5/roken.h>
102 static void desx(uint32_t [2], DES_key_schedule
*, int);
103 static void IP(uint32_t [2]);
104 static void FP(uint32_t [2]);
106 #include "des-tables.h"
108 #define ROTATE_LEFT28(x,one) \
110 x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \
112 x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \
116 * Set the parity of the key block, used to generate a des key from a
117 * random key. See @ref des_keygen.
119 * @param key key to fixup the parity for.
120 * @ingroup hcrypto_des
124 DES_set_odd_parity(DES_cblock
*key
)
127 for (i
= 0; i
< DES_CBLOCK_LEN
; i
++)
128 (*key
)[i
] = odd_parity
[(*key
)[i
]];
132 * Check if the key have correct parity.
134 * @param key key to check the parity.
135 * @return 1 on success, 0 on failure.
136 * @ingroup hcrypto_des
140 DES_check_key_parity(DES_cblock
*key
)
144 for (i
= 0; i
< DES_CBLOCK_LEN
; i
++)
145 if ((*key
)[i
] != odd_parity
[(*key
)[i
]])
155 static DES_cblock weak_keys
[] = {
156 {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */
157 {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
158 {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
159 {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
160 {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */
161 {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
162 {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
163 {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
164 {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
165 {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
166 {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
167 {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
168 {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
169 {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
170 {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
171 {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}
175 * Checks if the key is any of the weaks keys that makes DES attacks
178 * @param key key to check.
180 * @return 1 if the key is weak, 0 otherwise.
181 * @ingroup hcrypto_des
185 DES_is_weak_key(DES_cblock
*key
)
190 for (i
= 0; i
< sizeof(weak_keys
)/sizeof(weak_keys
[0]); i
++)
191 weak
^= (ct_memcmp(weak_keys
[i
], key
, DES_CBLOCK_LEN
) == 0);
197 * Setup a des key schedule from a key. Deprecated function, use
198 * DES_set_key_unchecked() or DES_set_key_checked() instead.
200 * @param key a key to initialize the key schedule with.
201 * @param ks a key schedule to initialize.
203 * @return 0 on success
204 * @ingroup hcrypto_des
208 DES_set_key(DES_cblock
*key
, DES_key_schedule
*ks
)
210 return DES_set_key_checked(key
, ks
);
214 * Setup a des key schedule from a key. The key is no longer needed
215 * after this transaction and can cleared.
217 * Does NOT check that the key is weak for or have wrong parity.
219 * @param key a key to initialize the key schedule with.
220 * @param ks a key schedule to initialize.
222 * @return 0 on success
223 * @ingroup hcrypto_des
227 DES_set_key_unchecked(DES_cblock
*key
, DES_key_schedule
*ks
)
231 int shifts
[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
232 uint32_t *k
= &ks
->ks
[0];
235 t1
= (*key
)[0] << 24 | (*key
)[1] << 16 | (*key
)[2] << 8 | (*key
)[3];
236 t2
= (*key
)[4] << 24 | (*key
)[5] << 16 | (*key
)[6] << 8 | (*key
)[7];
238 c
= (pc1_c_3
[(t1
>> (5 )) & 0x7] << 3)
239 | (pc1_c_3
[(t1
>> (5 + 8 )) & 0x7] << 2)
240 | (pc1_c_3
[(t1
>> (5 + 8 + 8 )) & 0x7] << 1)
241 | (pc1_c_3
[(t1
>> (5 + 8 + 8 + 8)) & 0x7] << 0)
242 | (pc1_c_4
[(t2
>> (4 )) & 0xf] << 3)
243 | (pc1_c_4
[(t2
>> (4 + 8 )) & 0xf] << 2)
244 | (pc1_c_4
[(t2
>> (4 + 8 + 8 )) & 0xf] << 1)
245 | (pc1_c_4
[(t2
>> (4 + 8 + 8 + 8)) & 0xf] << 0);
248 d
= (pc1_d_3
[(t2
>> (1 )) & 0x7] << 3)
249 | (pc1_d_3
[(t2
>> (1 + 8 )) & 0x7] << 2)
250 | (pc1_d_3
[(t2
>> (1 + 8 + 8 )) & 0x7] << 1)
251 | (pc1_d_3
[(t2
>> (1 + 8 + 8 + 8)) & 0x7] << 0)
252 | (pc1_d_4
[(t1
>> (1 )) & 0xf] << 3)
253 | (pc1_d_4
[(t1
>> (1 + 8 )) & 0xf] << 2)
254 | (pc1_d_4
[(t1
>> (1 + 8 + 8 )) & 0xf] << 1)
255 | (pc1_d_4
[(t1
>> (1 + 8 + 8 + 8)) & 0xf] << 0);
257 for (i
= 0; i
< 16; i
++) {
260 ROTATE_LEFT28(c
, shifts
[i
]);
261 ROTATE_LEFT28(d
, shifts
[i
]);
263 kc
= pc2_c_1
[(c
>> 22) & 0x3f] |
264 pc2_c_2
[((c
>> 16) & 0x30) | ((c
>> 15) & 0xf)] |
265 pc2_c_3
[((c
>> 9 ) & 0x3c) | ((c
>> 8 ) & 0x3)] |
266 pc2_c_4
[((c
>> 2 ) & 0x20) | ((c
>> 1) & 0x18) | (c
& 0x7)];
267 kd
= pc2_d_1
[(d
>> 22) & 0x3f] |
268 pc2_d_2
[((d
>> 15) & 0x30) | ((d
>> 14) & 0xf)] |
269 pc2_d_3
[ (d
>> 7 ) & 0x3f] |
270 pc2_d_4
[((d
>> 1 ) & 0x3c) | ((d
) & 0x3)];
272 /* Change to byte order used by the S boxes */
273 *k
= (kc
& 0x00fc0000L
) << 6;
274 *k
|= (kc
& 0x00000fc0L
) << 10;
275 *k
|= (kd
& 0x00fc0000L
) >> 10;
276 *k
++ |= (kd
& 0x00000fc0L
) >> 6;
277 *k
= (kc
& 0x0003f000L
) << 12;
278 *k
|= (kc
& 0x0000003fL
) << 16;
279 *k
|= (kd
& 0x0003f000L
) >> 4;
280 *k
++ |= (kd
& 0x0000003fL
);
287 * Just like DES_set_key_unchecked() except checking that the key is
288 * not weak for or have correct parity.
290 * @param key a key to initialize the key schedule with.
291 * @param ks a key schedule to initialize.
293 * @return 0 on success, -1 on invalid parity, -2 on weak key.
294 * @ingroup hcrypto_des
298 DES_set_key_checked(DES_cblock
*key
, DES_key_schedule
*ks
)
300 if (!DES_check_key_parity(key
)) {
301 memset(ks
, 0, sizeof(*ks
));
304 if (DES_is_weak_key(key
)) {
305 memset(ks
, 0, sizeof(*ks
));
308 return DES_set_key_unchecked(key
, ks
);
312 * Compatibility function for eay libdes, works just like
313 * DES_set_key_checked().
315 * @param key a key to initialize the key schedule with.
316 * @param ks a key schedule to initialize.
318 * @return 0 on success, -1 on invalid parity, -2 on weak key.
319 * @ingroup hcrypto_des
323 DES_key_sched(DES_cblock
*key
, DES_key_schedule
*ks
)
325 return DES_set_key_checked(key
, ks
);
333 load(const unsigned char *b
, uint32_t v
[2])
346 store(const uint32_t v
[2], unsigned char *b
)
348 b
[0] = (v
[0] >> 24) & 0xff;
349 b
[1] = (v
[0] >> 16) & 0xff;
350 b
[2] = (v
[0] >> 8) & 0xff;
351 b
[3] = (v
[0] >> 0) & 0xff;
352 b
[4] = (v
[1] >> 24) & 0xff;
353 b
[5] = (v
[1] >> 16) & 0xff;
354 b
[6] = (v
[1] >> 8) & 0xff;
355 b
[7] = (v
[1] >> 0) & 0xff;
359 * Encrypt/decrypt a block using DES. Also called ECB mode
361 * @param u data to encrypt
362 * @param ks key schedule to use
363 * @param encp if non zero, encrypt. if zero, decrypt.
365 * @ingroup hcrypto_des
369 DES_encrypt(uint32_t u
[2], DES_key_schedule
*ks
, int encp
)
377 * Encrypt/decrypt a block using DES.
379 * @param input data to encrypt
380 * @param output data to encrypt
381 * @param ks key schedule to use
382 * @param encp if non zero, encrypt. if zero, decrypt.
384 * @ingroup hcrypto_des
388 DES_ecb_encrypt(DES_cblock
*input
, DES_cblock
*output
,
389 DES_key_schedule
*ks
, int encp
)
393 DES_encrypt(u
, ks
, encp
);
398 * Encrypt/decrypt a block using DES in Chain Block Cipher mode (cbc).
400 * The IV must always be diffrent for diffrent input data blocks.
402 * @param in data to encrypt
403 * @param out data to encrypt
404 * @param length length of data
405 * @param ks key schedule to use
406 * @param iv initial vector to use
407 * @param encp if non zero, encrypt. if zero, decrypt.
409 * @ingroup hcrypto_des
413 DES_cbc_encrypt(const void *in
, void *out
, long length
,
414 DES_key_schedule
*ks
, DES_cblock
*iv
, int encp
)
416 const unsigned char *input
= in
;
417 unsigned char *output
= out
;
424 while (length
>= DES_CBLOCK_LEN
) {
426 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
427 DES_encrypt(u
, ks
, 1);
428 uiv
[0] = u
[0]; uiv
[1] = u
[1];
431 length
-= DES_CBLOCK_LEN
;
432 input
+= DES_CBLOCK_LEN
;
433 output
+= DES_CBLOCK_LEN
;
436 unsigned char tmp
[DES_CBLOCK_LEN
];
437 memcpy(tmp
, input
, length
);
438 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
440 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
441 DES_encrypt(u
, ks
, 1);
446 while (length
>= DES_CBLOCK_LEN
) {
448 t
[0] = u
[0]; t
[1] = u
[1];
449 DES_encrypt(u
, ks
, 0);
450 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
452 uiv
[0] = t
[0]; uiv
[1] = t
[1];
454 length
-= DES_CBLOCK_LEN
;
455 input
+= DES_CBLOCK_LEN
;
456 output
+= DES_CBLOCK_LEN
;
459 unsigned char tmp
[DES_CBLOCK_LEN
];
460 memcpy(tmp
, input
, length
);
461 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
463 DES_encrypt(u
, ks
, 0);
464 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
468 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
472 * Encrypt/decrypt a block using DES in Propagating Cipher Block
473 * Chaining mode. This mode is only used for Kerberos 4, and it should
476 * The IV must always be diffrent for diffrent input data blocks.
478 * @param in data to encrypt
479 * @param out data to encrypt
480 * @param length length of data
481 * @param ks key schedule to use
482 * @param iv initial vector to use
483 * @param encp if non zero, encrypt. if zero, decrypt.
485 * @ingroup hcrypto_des
489 DES_pcbc_encrypt(const void *in
, void *out
, long length
,
490 DES_key_schedule
*ks
, DES_cblock
*iv
, int encp
)
492 const unsigned char *input
= in
;
493 unsigned char *output
= out
;
501 while (length
>= DES_CBLOCK_LEN
) {
503 t
[0] = u
[0]; t
[1] = u
[1];
504 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
505 DES_encrypt(u
, ks
, 1);
506 uiv
[0] = u
[0] ^ t
[0]; uiv
[1] = u
[1] ^ t
[1];
509 length
-= DES_CBLOCK_LEN
;
510 input
+= DES_CBLOCK_LEN
;
511 output
+= DES_CBLOCK_LEN
;
514 unsigned char tmp
[DES_CBLOCK_LEN
];
515 memcpy(tmp
, input
, length
);
516 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
518 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
519 DES_encrypt(u
, ks
, 1);
524 while (length
>= DES_CBLOCK_LEN
) {
526 t
[0] = u
[0]; t
[1] = u
[1];
527 DES_encrypt(u
, ks
, 0);
528 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
530 uiv
[0] = t
[0] ^ u
[0]; uiv
[1] = t
[1] ^ u
[1];
532 length
-= DES_CBLOCK_LEN
;
533 input
+= DES_CBLOCK_LEN
;
534 output
+= DES_CBLOCK_LEN
;
537 unsigned char tmp
[DES_CBLOCK_LEN
];
538 memcpy(tmp
, input
, length
);
539 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
541 DES_encrypt(u
, ks
, 0);
542 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
545 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
553 _des3_encrypt(uint32_t u
[2], DES_key_schedule
*ks1
, DES_key_schedule
*ks2
,
554 DES_key_schedule
*ks3
, int encp
)
558 desx(u
, ks1
, 1); /* IP + FP cancel out each other */
570 * Encrypt/decrypt a block using triple DES using EDE mode,
571 * encrypt/decrypt/encrypt.
573 * @param input data to encrypt
574 * @param output data to encrypt
575 * @param ks1 key schedule to use
576 * @param ks2 key schedule to use
577 * @param ks3 key schedule to use
578 * @param encp if non zero, encrypt. if zero, decrypt.
580 * @ingroup hcrypto_des
584 DES_ecb3_encrypt(DES_cblock
*input
,
586 DES_key_schedule
*ks1
,
587 DES_key_schedule
*ks2
,
588 DES_key_schedule
*ks3
,
593 _des3_encrypt(u
, ks1
, ks2
, ks3
, encp
);
599 * Encrypt/decrypt using Triple DES in Chain Block Cipher mode (cbc).
601 * The IV must always be diffrent for diffrent input data blocks.
603 * @param in data to encrypt
604 * @param out data to encrypt
605 * @param length length of data
606 * @param ks1 key schedule to use
607 * @param ks2 key schedule to use
608 * @param ks3 key schedule to use
609 * @param iv initial vector to use
610 * @param encp if non zero, encrypt. if zero, decrypt.
612 * @ingroup hcrypto_des
616 DES_ede3_cbc_encrypt(const void *in
, void *out
,
617 long length
, DES_key_schedule
*ks1
,
618 DES_key_schedule
*ks2
, DES_key_schedule
*ks3
,
619 DES_cblock
*iv
, int encp
)
621 const unsigned char *input
= in
;
622 unsigned char *output
= out
;
629 while (length
>= DES_CBLOCK_LEN
) {
631 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
632 _des3_encrypt(u
, ks1
, ks2
, ks3
, 1);
633 uiv
[0] = u
[0]; uiv
[1] = u
[1];
636 length
-= DES_CBLOCK_LEN
;
637 input
+= DES_CBLOCK_LEN
;
638 output
+= DES_CBLOCK_LEN
;
641 unsigned char tmp
[DES_CBLOCK_LEN
];
642 memcpy(tmp
, input
, length
);
643 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
645 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
646 _des3_encrypt(u
, ks1
, ks2
, ks3
, 1);
651 while (length
>= DES_CBLOCK_LEN
) {
653 t
[0] = u
[0]; t
[1] = u
[1];
654 _des3_encrypt(u
, ks1
, ks2
, ks3
, 0);
655 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
657 uiv
[0] = t
[0]; uiv
[1] = t
[1];
659 length
-= DES_CBLOCK_LEN
;
660 input
+= DES_CBLOCK_LEN
;
661 output
+= DES_CBLOCK_LEN
;
664 unsigned char tmp
[DES_CBLOCK_LEN
];
665 memcpy(tmp
, input
, length
);
666 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
668 _des3_encrypt(u
, ks1
, ks2
, ks3
, 0);
669 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
674 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
678 * Encrypt/decrypt using DES in cipher feedback mode with 64 bit
681 * The IV must always be diffrent for diffrent input data blocks.
683 * @param in data to encrypt
684 * @param out data to encrypt
685 * @param length length of data
686 * @param ks key schedule to use
687 * @param iv initial vector to use
688 * @param num offset into in cipher block encryption/decryption stop last time.
689 * @param encp if non zero, encrypt. if zero, decrypt.
691 * @ingroup hcrypto_des
695 DES_cfb64_encrypt(const void *in
, void *out
,
696 long length
, DES_key_schedule
*ks
, DES_cblock
*iv
,
699 const unsigned char *input
= in
;
700 unsigned char *output
= out
;
701 unsigned char tmp
[DES_CBLOCK_LEN
];
706 assert(*num
>= 0 && *num
< DES_CBLOCK_LEN
);
713 DES_encrypt(uiv
, ks
, 1);
715 for (; i
< DES_CBLOCK_LEN
&& i
< length
; i
++) {
716 output
[i
] = tmp
[i
] ^ input
[i
];
718 if (i
== DES_CBLOCK_LEN
)
723 if (i
== DES_CBLOCK_LEN
)
734 DES_encrypt(uiv
, ks
, 1);
737 for (; i
< DES_CBLOCK_LEN
&& i
< length
; i
++) {
739 output
[i
] = tmp
[i
] ^ input
[i
];
745 if (i
== DES_CBLOCK_LEN
) {
756 * Crete a checksum using DES in CBC encryption mode. This mode is
757 * only used for Kerberos 4, and it should stay that way.
759 * The IV must always be diffrent for diffrent input data blocks.
761 * @param in data to checksum
762 * @param output the checksum
763 * @param length length of data
764 * @param ks key schedule to use
765 * @param iv initial vector to use
767 * @ingroup hcrypto_des
771 DES_cbc_cksum(const void *in
, DES_cblock
*output
,
772 long length
, DES_key_schedule
*ks
, DES_cblock
*iv
)
774 const unsigned char *input
= in
;
776 uint32_t u
[2] = { 0, 0 };
780 while (length
>= DES_CBLOCK_LEN
) {
782 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
783 DES_encrypt(u
, ks
, 1);
784 uiv
[0] = u
[0]; uiv
[1] = u
[1];
786 length
-= DES_CBLOCK_LEN
;
787 input
+= DES_CBLOCK_LEN
;
790 unsigned char tmp
[DES_CBLOCK_LEN
];
791 memcpy(tmp
, input
, length
);
792 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
794 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
795 DES_encrypt(u
, ks
, 1);
800 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0;
809 bitswap8(unsigned char b
)
813 for (i
= 0; i
< 8; i
++) {
814 r
= r
<< 1 | (b
& 1);
821 * Convert a string to a DES key. Use something like
822 * PKCS5_PBKDF2_HMAC_SHA1() to create key from passwords.
824 * @param str The string to convert to a key
825 * @param key the resulting key
827 * @ingroup hcrypto_des
831 DES_string_to_key(const char *str
, DES_cblock
*key
)
833 const unsigned char *s
;
838 memset(key
, 0, sizeof(*key
));
840 s
= (const unsigned char *)str
;
843 for (i
= 0; i
< len
; i
++) {
845 k
[i
% 8] ^= s
[i
] << 1;
847 k
[7 - (i
% 8)] ^= bitswap8(s
[i
]);
849 DES_set_odd_parity(key
);
850 if (DES_is_weak_key(key
))
852 DES_set_key(key
, &ks
);
853 DES_cbc_cksum(s
, key
, len
, &ks
, key
);
854 memset(&ks
, 0, sizeof(ks
));
855 DES_set_odd_parity(key
);
856 if (DES_is_weak_key(key
))
861 * Read password from prompt and create a DES key. Internal uses
862 * DES_string_to_key(). Really, go use a really string2key function
863 * like PKCS5_PBKDF2_HMAC_SHA1().
865 * @param key key to convert to
866 * @param prompt prompt to display user
867 * @param verify prompt twice.
869 * @return 1 on success, non 1 on failure.
873 DES_read_password(DES_cblock
*key
, char *prompt
, int verify
)
878 ret
= UI_UTIL_read_pw_string(buf
, sizeof(buf
) - 1, prompt
, verify
);
880 DES_string_to_key(buf
, key
);
892 DES_cblock k
= "\x01\x02\x04\x08\x10\x20\x40\x80", k2
;
893 uint32_t u
[2] = { 1, 0 };
898 if (u
[0] != 1 || u
[1] != 0)
903 if (memcmp(k
, k2
, 8) != 0)
909 * A portable, public domain, version of the Data Encryption Standard.
911 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
912 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
913 * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
914 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
915 * for humouring me on.
917 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
918 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
921 static uint32_t SP1
[64] = {
922 0x01010400L
, 0x00000000L
, 0x00010000L
, 0x01010404L
,
923 0x01010004L
, 0x00010404L
, 0x00000004L
, 0x00010000L
,
924 0x00000400L
, 0x01010400L
, 0x01010404L
, 0x00000400L
,
925 0x01000404L
, 0x01010004L
, 0x01000000L
, 0x00000004L
,
926 0x00000404L
, 0x01000400L
, 0x01000400L
, 0x00010400L
,
927 0x00010400L
, 0x01010000L
, 0x01010000L
, 0x01000404L
,
928 0x00010004L
, 0x01000004L
, 0x01000004L
, 0x00010004L
,
929 0x00000000L
, 0x00000404L
, 0x00010404L
, 0x01000000L
,
930 0x00010000L
, 0x01010404L
, 0x00000004L
, 0x01010000L
,
931 0x01010400L
, 0x01000000L
, 0x01000000L
, 0x00000400L
,
932 0x01010004L
, 0x00010000L
, 0x00010400L
, 0x01000004L
,
933 0x00000400L
, 0x00000004L
, 0x01000404L
, 0x00010404L
,
934 0x01010404L
, 0x00010004L
, 0x01010000L
, 0x01000404L
,
935 0x01000004L
, 0x00000404L
, 0x00010404L
, 0x01010400L
,
936 0x00000404L
, 0x01000400L
, 0x01000400L
, 0x00000000L
,
937 0x00010004L
, 0x00010400L
, 0x00000000L
, 0x01010004L
};
939 static uint32_t SP2
[64] = {
940 0x80108020L
, 0x80008000L
, 0x00008000L
, 0x00108020L
,
941 0x00100000L
, 0x00000020L
, 0x80100020L
, 0x80008020L
,
942 0x80000020L
, 0x80108020L
, 0x80108000L
, 0x80000000L
,
943 0x80008000L
, 0x00100000L
, 0x00000020L
, 0x80100020L
,
944 0x00108000L
, 0x00100020L
, 0x80008020L
, 0x00000000L
,
945 0x80000000L
, 0x00008000L
, 0x00108020L
, 0x80100000L
,
946 0x00100020L
, 0x80000020L
, 0x00000000L
, 0x00108000L
,
947 0x00008020L
, 0x80108000L
, 0x80100000L
, 0x00008020L
,
948 0x00000000L
, 0x00108020L
, 0x80100020L
, 0x00100000L
,
949 0x80008020L
, 0x80100000L
, 0x80108000L
, 0x00008000L
,
950 0x80100000L
, 0x80008000L
, 0x00000020L
, 0x80108020L
,
951 0x00108020L
, 0x00000020L
, 0x00008000L
, 0x80000000L
,
952 0x00008020L
, 0x80108000L
, 0x00100000L
, 0x80000020L
,
953 0x00100020L
, 0x80008020L
, 0x80000020L
, 0x00100020L
,
954 0x00108000L
, 0x00000000L
, 0x80008000L
, 0x00008020L
,
955 0x80000000L
, 0x80100020L
, 0x80108020L
, 0x00108000L
};
957 static uint32_t SP3
[64] = {
958 0x00000208L
, 0x08020200L
, 0x00000000L
, 0x08020008L
,
959 0x08000200L
, 0x00000000L
, 0x00020208L
, 0x08000200L
,
960 0x00020008L
, 0x08000008L
, 0x08000008L
, 0x00020000L
,
961 0x08020208L
, 0x00020008L
, 0x08020000L
, 0x00000208L
,
962 0x08000000L
, 0x00000008L
, 0x08020200L
, 0x00000200L
,
963 0x00020200L
, 0x08020000L
, 0x08020008L
, 0x00020208L
,
964 0x08000208L
, 0x00020200L
, 0x00020000L
, 0x08000208L
,
965 0x00000008L
, 0x08020208L
, 0x00000200L
, 0x08000000L
,
966 0x08020200L
, 0x08000000L
, 0x00020008L
, 0x00000208L
,
967 0x00020000L
, 0x08020200L
, 0x08000200L
, 0x00000000L
,
968 0x00000200L
, 0x00020008L
, 0x08020208L
, 0x08000200L
,
969 0x08000008L
, 0x00000200L
, 0x00000000L
, 0x08020008L
,
970 0x08000208L
, 0x00020000L
, 0x08000000L
, 0x08020208L
,
971 0x00000008L
, 0x00020208L
, 0x00020200L
, 0x08000008L
,
972 0x08020000L
, 0x08000208L
, 0x00000208L
, 0x08020000L
,
973 0x00020208L
, 0x00000008L
, 0x08020008L
, 0x00020200L
};
975 static uint32_t SP4
[64] = {
976 0x00802001L
, 0x00002081L
, 0x00002081L
, 0x00000080L
,
977 0x00802080L
, 0x00800081L
, 0x00800001L
, 0x00002001L
,
978 0x00000000L
, 0x00802000L
, 0x00802000L
, 0x00802081L
,
979 0x00000081L
, 0x00000000L
, 0x00800080L
, 0x00800001L
,
980 0x00000001L
, 0x00002000L
, 0x00800000L
, 0x00802001L
,
981 0x00000080L
, 0x00800000L
, 0x00002001L
, 0x00002080L
,
982 0x00800081L
, 0x00000001L
, 0x00002080L
, 0x00800080L
,
983 0x00002000L
, 0x00802080L
, 0x00802081L
, 0x00000081L
,
984 0x00800080L
, 0x00800001L
, 0x00802000L
, 0x00802081L
,
985 0x00000081L
, 0x00000000L
, 0x00000000L
, 0x00802000L
,
986 0x00002080L
, 0x00800080L
, 0x00800081L
, 0x00000001L
,
987 0x00802001L
, 0x00002081L
, 0x00002081L
, 0x00000080L
,
988 0x00802081L
, 0x00000081L
, 0x00000001L
, 0x00002000L
,
989 0x00800001L
, 0x00002001L
, 0x00802080L
, 0x00800081L
,
990 0x00002001L
, 0x00002080L
, 0x00800000L
, 0x00802001L
,
991 0x00000080L
, 0x00800000L
, 0x00002000L
, 0x00802080L
};
993 static uint32_t SP5
[64] = {
994 0x00000100L
, 0x02080100L
, 0x02080000L
, 0x42000100L
,
995 0x00080000L
, 0x00000100L
, 0x40000000L
, 0x02080000L
,
996 0x40080100L
, 0x00080000L
, 0x02000100L
, 0x40080100L
,
997 0x42000100L
, 0x42080000L
, 0x00080100L
, 0x40000000L
,
998 0x02000000L
, 0x40080000L
, 0x40080000L
, 0x00000000L
,
999 0x40000100L
, 0x42080100L
, 0x42080100L
, 0x02000100L
,
1000 0x42080000L
, 0x40000100L
, 0x00000000L
, 0x42000000L
,
1001 0x02080100L
, 0x02000000L
, 0x42000000L
, 0x00080100L
,
1002 0x00080000L
, 0x42000100L
, 0x00000100L
, 0x02000000L
,
1003 0x40000000L
, 0x02080000L
, 0x42000100L
, 0x40080100L
,
1004 0x02000100L
, 0x40000000L
, 0x42080000L
, 0x02080100L
,
1005 0x40080100L
, 0x00000100L
, 0x02000000L
, 0x42080000L
,
1006 0x42080100L
, 0x00080100L
, 0x42000000L
, 0x42080100L
,
1007 0x02080000L
, 0x00000000L
, 0x40080000L
, 0x42000000L
,
1008 0x00080100L
, 0x02000100L
, 0x40000100L
, 0x00080000L
,
1009 0x00000000L
, 0x40080000L
, 0x02080100L
, 0x40000100L
};
1011 static uint32_t SP6
[64] = {
1012 0x20000010L
, 0x20400000L
, 0x00004000L
, 0x20404010L
,
1013 0x20400000L
, 0x00000010L
, 0x20404010L
, 0x00400000L
,
1014 0x20004000L
, 0x00404010L
, 0x00400000L
, 0x20000010L
,
1015 0x00400010L
, 0x20004000L
, 0x20000000L
, 0x00004010L
,
1016 0x00000000L
, 0x00400010L
, 0x20004010L
, 0x00004000L
,
1017 0x00404000L
, 0x20004010L
, 0x00000010L
, 0x20400010L
,
1018 0x20400010L
, 0x00000000L
, 0x00404010L
, 0x20404000L
,
1019 0x00004010L
, 0x00404000L
, 0x20404000L
, 0x20000000L
,
1020 0x20004000L
, 0x00000010L
, 0x20400010L
, 0x00404000L
,
1021 0x20404010L
, 0x00400000L
, 0x00004010L
, 0x20000010L
,
1022 0x00400000L
, 0x20004000L
, 0x20000000L
, 0x00004010L
,
1023 0x20000010L
, 0x20404010L
, 0x00404000L
, 0x20400000L
,
1024 0x00404010L
, 0x20404000L
, 0x00000000L
, 0x20400010L
,
1025 0x00000010L
, 0x00004000L
, 0x20400000L
, 0x00404010L
,
1026 0x00004000L
, 0x00400010L
, 0x20004010L
, 0x00000000L
,
1027 0x20404000L
, 0x20000000L
, 0x00400010L
, 0x20004010L
};
1029 static uint32_t SP7
[64] = {
1030 0x00200000L
, 0x04200002L
, 0x04000802L
, 0x00000000L
,
1031 0x00000800L
, 0x04000802L
, 0x00200802L
, 0x04200800L
,
1032 0x04200802L
, 0x00200000L
, 0x00000000L
, 0x04000002L
,
1033 0x00000002L
, 0x04000000L
, 0x04200002L
, 0x00000802L
,
1034 0x04000800L
, 0x00200802L
, 0x00200002L
, 0x04000800L
,
1035 0x04000002L
, 0x04200000L
, 0x04200800L
, 0x00200002L
,
1036 0x04200000L
, 0x00000800L
, 0x00000802L
, 0x04200802L
,
1037 0x00200800L
, 0x00000002L
, 0x04000000L
, 0x00200800L
,
1038 0x04000000L
, 0x00200800L
, 0x00200000L
, 0x04000802L
,
1039 0x04000802L
, 0x04200002L
, 0x04200002L
, 0x00000002L
,
1040 0x00200002L
, 0x04000000L
, 0x04000800L
, 0x00200000L
,
1041 0x04200800L
, 0x00000802L
, 0x00200802L
, 0x04200800L
,
1042 0x00000802L
, 0x04000002L
, 0x04200802L
, 0x04200000L
,
1043 0x00200800L
, 0x00000000L
, 0x00000002L
, 0x04200802L
,
1044 0x00000000L
, 0x00200802L
, 0x04200000L
, 0x00000800L
,
1045 0x04000002L
, 0x04000800L
, 0x00000800L
, 0x00200002L
};
1047 static uint32_t SP8
[64] = {
1048 0x10001040L
, 0x00001000L
, 0x00040000L
, 0x10041040L
,
1049 0x10000000L
, 0x10001040L
, 0x00000040L
, 0x10000000L
,
1050 0x00040040L
, 0x10040000L
, 0x10041040L
, 0x00041000L
,
1051 0x10041000L
, 0x00041040L
, 0x00001000L
, 0x00000040L
,
1052 0x10040000L
, 0x10000040L
, 0x10001000L
, 0x00001040L
,
1053 0x00041000L
, 0x00040040L
, 0x10040040L
, 0x10041000L
,
1054 0x00001040L
, 0x00000000L
, 0x00000000L
, 0x10040040L
,
1055 0x10000040L
, 0x10001000L
, 0x00041040L
, 0x00040000L
,
1056 0x00041040L
, 0x00040000L
, 0x10041000L
, 0x00001000L
,
1057 0x00000040L
, 0x10040040L
, 0x00001000L
, 0x00041040L
,
1058 0x10001000L
, 0x00000040L
, 0x10000040L
, 0x10040000L
,
1059 0x10040040L
, 0x10000000L
, 0x00040000L
, 0x10001040L
,
1060 0x00000000L
, 0x10041040L
, 0x00040040L
, 0x10000040L
,
1061 0x10040000L
, 0x10001000L
, 0x10001040L
, 0x00000000L
,
1062 0x10041040L
, 0x00041000L
, 0x00041000L
, 0x00001040L
,
1063 0x00001040L
, 0x00040040L
, 0x10000000L
, 0x10041000L
};
1070 work
= ((v
[0] >> 4) ^ v
[1]) & 0x0f0f0f0fL
;
1072 v
[0] ^= (work
<< 4);
1073 work
= ((v
[0] >> 16) ^ v
[1]) & 0x0000ffffL
;
1075 v
[0] ^= (work
<< 16);
1076 work
= ((v
[1] >> 2) ^ v
[0]) & 0x33333333L
;
1078 v
[1] ^= (work
<< 2);
1079 work
= ((v
[1] >> 8) ^ v
[0]) & 0x00ff00ffL
;
1081 v
[1] ^= (work
<< 8);
1082 v
[1] = ((v
[1] << 1) | ((v
[1] >> 31) & 1L)) & 0xffffffffL
;
1083 work
= (v
[0] ^ v
[1]) & 0xaaaaaaaaL
;
1086 v
[0] = ((v
[0] << 1) | ((v
[0] >> 31) & 1L)) & 0xffffffffL
;
1094 v
[0] = (v
[0] << 31) | (v
[0] >> 1);
1095 work
= (v
[1] ^ v
[0]) & 0xaaaaaaaaL
;
1098 v
[1] = (v
[1] << 31) | (v
[1] >> 1);
1099 work
= ((v
[1] >> 8) ^ v
[0]) & 0x00ff00ffL
;
1101 v
[1] ^= (work
<< 8);
1102 work
= ((v
[1] >> 2) ^ v
[0]) & 0x33333333L
;
1104 v
[1] ^= (work
<< 2);
1105 work
= ((v
[0] >> 16) ^ v
[1]) & 0x0000ffffL
;
1107 v
[0] ^= (work
<< 16);
1108 work
= ((v
[0] >> 4) ^ v
[1]) & 0x0f0f0f0fL
;
1110 v
[0] ^= (work
<< 4);
1114 desx(uint32_t block
[2], DES_key_schedule
*ks
, int encp
)
1117 uint32_t fval
, work
, right
, left
;
1126 for( round
= 0; round
< 8; round
++ ) {
1127 work
= (right
<< 28) | (right
>> 4);
1129 fval
= SP7
[ work
& 0x3fL
];
1130 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1131 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1132 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1133 work
= right
^ *keys
++;
1134 fval
|= SP8
[ work
& 0x3fL
];
1135 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1136 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1137 fval
|= SP2
[(work
>> 24) & 0x3fL
];
1139 work
= (left
<< 28) | (left
>> 4);
1141 fval
= SP7
[ work
& 0x3fL
];
1142 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1143 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1144 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1145 work
= left
^ *keys
++;
1146 fval
|= SP8
[ work
& 0x3fL
];
1147 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1148 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1149 fval
|= SP2
[(work
>> 24) & 0x3fL
];
1155 for( round
= 0; round
< 8; round
++ ) {
1156 work
= (right
<< 28) | (right
>> 4);
1158 fval
= SP7
[ work
& 0x3fL
];
1159 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1160 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1161 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1162 work
= right
^ *keys
++;
1163 fval
|= SP8
[ work
& 0x3fL
];
1164 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1165 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1166 fval
|= SP2
[(work
>> 24) & 0x3fL
];
1168 work
= (left
<< 28) | (left
>> 4);
1171 fval
= SP7
[ work
& 0x3fL
];
1172 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1173 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1174 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1175 work
= left
^ *keys
++;
1176 fval
|= SP8
[ work
& 0x3fL
];
1177 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1178 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1179 fval
|= SP2
[(work
>> 24) & 0x3fL
];