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 * @page page_des DES - Data Encryption Standard crypto interface
37 * See the library functions here: @ref hcrypto_des
39 * DES was created by IBM, modififed by NSA and then adopted by NBS
40 * (now NIST) and published ad FIPS PUB 46 (updated by FIPS 46-1).
42 * Since the 19th May 2005 DES was withdrawn by NIST and should no
43 * longer be used. See @ref page_evp for replacement encryption
44 * algorithms and interfaces.
46 * Read more the iteresting history of DES on Wikipedia
47 * http://www.wikipedia.org/wiki/Data_Encryption_Standard .
49 * @section des_keygen DES key generation
51 * To generate a DES key safely you have to use the code-snippet
52 * below. This is because the DES_random_key() can fail with an
53 * abort() in case of and failure to start the random generator.
55 * There is a replacement function DES_new_random_key(), however that
56 * function does not exists in OpenSSL.
61 * if (RAND_rand(&key, sizeof(key)) != 1)
63 * DES_set_odd_parity(key);
64 * } while (DES_is_weak_key(&key));
67 * @section des_impl DES implementation history
69 * There was no complete BSD licensed, fast, GPL compatible
70 * implementation of DES, so Love wrote the part that was missing,
71 * fast key schedule setup and adapted the interface to the orignal
74 * The document that got me started for real was "Efficient
75 * Implementation of the Data Encryption Standard" by Dag Arne Osvik.
76 * I never got to the PC1 transformation was working, instead I used
77 * table-lookup was used for all key schedule setup. The document was
78 * very useful since it de-mystified other implementations for me.
80 * The core DES function (SBOX + P transformation) is from Richard
81 * Outerbridge public domain DES implementation. My sanity is saved
82 * thanks to his work. Thank you Richard.
92 #include <krb5-types.h>
98 static void desx(uint32_t [2], DES_key_schedule
*, int);
99 static void IP(uint32_t [2]);
100 static void FP(uint32_t [2]);
102 #include "des-tables.h"
104 #define ROTATE_LEFT28(x,one) \
106 x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \
108 x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \
112 * Set the parity of the key block, used to generate a des key from a
113 * random key. See @ref des_keygen.
115 * @param key key to fixup the parity for.
116 * @ingroup hcrypto_des
120 DES_set_odd_parity(DES_cblock
*key
)
123 for (i
= 0; i
< DES_CBLOCK_LEN
; i
++)
124 (*key
)[i
] = odd_parity
[(*key
)[i
]];
128 * Check if the key have correct parity.
130 * @param key key to check the parity.
131 * @return 1 on success, 0 on failure.
132 * @ingroup hcrypto_des
136 DES_check_key_parity(DES_cblock
*key
)
140 for (i
= 0; i
< DES_CBLOCK_LEN
; i
++)
141 if ((*key
)[i
] != odd_parity
[(*key
)[i
]])
151 static DES_cblock weak_keys
[] = {
152 {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */
153 {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
154 {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
155 {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
156 {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */
157 {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
158 {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
159 {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
160 {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
161 {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
162 {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
163 {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
164 {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
165 {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
166 {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
167 {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}
171 * Checks if the key is any of the weaks keys that makes DES attacks
174 * @param key key to check.
176 * @return 1 if the key is weak, 0 otherwise.
177 * @ingroup hcrypto_des
181 DES_is_weak_key(DES_cblock
*key
)
185 /* Not constant time size if the key is weak, the app should not use it. */
186 for (i
= 0; i
< sizeof(weak_keys
)/sizeof(weak_keys
[0]); i
++) {
187 if (memcmp(weak_keys
[i
], key
, DES_CBLOCK_LEN
) == 0)
194 * Setup a des key schedule from a key. Deprecated function, use
195 * DES_set_key_unchecked() or DES_set_key_checked() instead.
197 * @param key a key to initialize the key schedule with.
198 * @param ks a key schedule to initialize.
200 * @return 0 on success
201 * @ingroup hcrypto_des
205 DES_set_key(DES_cblock
*key
, DES_key_schedule
*ks
)
207 return DES_set_key_checked(key
, ks
);
211 * Setup a des key schedule from a key. The key is no longer needed
212 * after this transaction and can cleared.
214 * Does NOT check that the key is weak for or have wrong parity.
216 * @param key a key to initialize the key schedule with.
217 * @param ks a key schedule to initialize.
219 * @return 0 on success
220 * @ingroup hcrypto_des
224 DES_set_key_unchecked(DES_cblock
*key
, DES_key_schedule
*ks
)
228 int shifts
[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
229 uint32_t *k
= &ks
->ks
[0];
232 t1
= (*key
)[0] << 24 | (*key
)[1] << 16 | (*key
)[2] << 8 | (*key
)[3];
233 t2
= (*key
)[4] << 24 | (*key
)[5] << 16 | (*key
)[6] << 8 | (*key
)[7];
235 c
= (pc1_c_3
[(t1
>> (5 )) & 0x7] << 3)
236 | (pc1_c_3
[(t1
>> (5 + 8 )) & 0x7] << 2)
237 | (pc1_c_3
[(t1
>> (5 + 8 + 8 )) & 0x7] << 1)
238 | (pc1_c_3
[(t1
>> (5 + 8 + 8 + 8)) & 0x7] << 0)
239 | (pc1_c_4
[(t2
>> (4 )) & 0xf] << 3)
240 | (pc1_c_4
[(t2
>> (4 + 8 )) & 0xf] << 2)
241 | (pc1_c_4
[(t2
>> (4 + 8 + 8 )) & 0xf] << 1)
242 | (pc1_c_4
[(t2
>> (4 + 8 + 8 + 8)) & 0xf] << 0);
245 d
= (pc1_d_3
[(t2
>> (1 )) & 0x7] << 3)
246 | (pc1_d_3
[(t2
>> (1 + 8 )) & 0x7] << 2)
247 | (pc1_d_3
[(t2
>> (1 + 8 + 8 )) & 0x7] << 1)
248 | (pc1_d_3
[(t2
>> (1 + 8 + 8 + 8)) & 0x7] << 0)
249 | (pc1_d_4
[(t1
>> (1 )) & 0xf] << 3)
250 | (pc1_d_4
[(t1
>> (1 + 8 )) & 0xf] << 2)
251 | (pc1_d_4
[(t1
>> (1 + 8 + 8 )) & 0xf] << 1)
252 | (pc1_d_4
[(t1
>> (1 + 8 + 8 + 8)) & 0xf] << 0);
254 for (i
= 0; i
< 16; i
++) {
257 ROTATE_LEFT28(c
, shifts
[i
]);
258 ROTATE_LEFT28(d
, shifts
[i
]);
260 kc
= pc2_c_1
[(c
>> 22) & 0x3f] |
261 pc2_c_2
[((c
>> 16) & 0x30) | ((c
>> 15) & 0xf)] |
262 pc2_c_3
[((c
>> 9 ) & 0x3c) | ((c
>> 8 ) & 0x3)] |
263 pc2_c_4
[((c
>> 2 ) & 0x20) | ((c
>> 1) & 0x18) | (c
& 0x7)];
264 kd
= pc2_d_1
[(d
>> 22) & 0x3f] |
265 pc2_d_2
[((d
>> 15) & 0x30) | ((d
>> 14) & 0xf)] |
266 pc2_d_3
[ (d
>> 7 ) & 0x3f] |
267 pc2_d_4
[((d
>> 1 ) & 0x3c) | ((d
) & 0x3)];
269 /* Change to byte order used by the S boxes */
270 *k
= (kc
& 0x00fc0000L
) << 6;
271 *k
|= (kc
& 0x00000fc0L
) << 10;
272 *k
|= (kd
& 0x00fc0000L
) >> 10;
273 *k
++ |= (kd
& 0x00000fc0L
) >> 6;
274 *k
= (kc
& 0x0003f000L
) << 12;
275 *k
|= (kc
& 0x0000003fL
) << 16;
276 *k
|= (kd
& 0x0003f000L
) >> 4;
277 *k
++ |= (kd
& 0x0000003fL
);
284 * Just like DES_set_key_unchecked() except checking that the key is
285 * not weak for or have correct parity.
287 * @param key a key to initialize the key schedule with.
288 * @param ks a key schedule to initialize.
290 * @return 0 on success, -1 on invalid parity, -2 on weak key.
291 * @ingroup hcrypto_des
295 DES_set_key_checked(DES_cblock
*key
, DES_key_schedule
*ks
)
297 if (!DES_check_key_parity(key
)) {
298 memset(ks
, 0, sizeof(*ks
));
301 if (DES_is_weak_key(key
)) {
302 memset(ks
, 0, sizeof(*ks
));
305 return DES_set_key_unchecked(key
, ks
);
309 * Compatibility function for eay libdes, works just like
310 * DES_set_key_checked().
312 * @param key a key to initialize the key schedule with.
313 * @param ks a key schedule to initialize.
315 * @return 0 on success, -1 on invalid parity, -2 on weak key.
316 * @ingroup hcrypto_des
320 DES_key_sched(DES_cblock
*key
, DES_key_schedule
*ks
)
322 return DES_set_key_checked(key
, ks
);
330 load(const unsigned char *b
, uint32_t v
[2])
343 store(const uint32_t v
[2], unsigned char *b
)
345 b
[0] = (v
[0] >> 24) & 0xff;
346 b
[1] = (v
[0] >> 16) & 0xff;
347 b
[2] = (v
[0] >> 8) & 0xff;
348 b
[3] = (v
[0] >> 0) & 0xff;
349 b
[4] = (v
[1] >> 24) & 0xff;
350 b
[5] = (v
[1] >> 16) & 0xff;
351 b
[6] = (v
[1] >> 8) & 0xff;
352 b
[7] = (v
[1] >> 0) & 0xff;
356 * Encrypt/decrypt a block using DES. Also called ECB mode
358 * @param u data to encrypt
359 * @param ks key schedule to use
360 * @param encp if non zero, encrypt. if zero, decrypt.
362 * @ingroup hcrypto_des
366 DES_encrypt(uint32_t u
[2], DES_key_schedule
*ks
, int encp
)
374 * Encrypt/decrypt a block using DES.
376 * @param input data to encrypt
377 * @param output data to encrypt
378 * @param ks key schedule to use
379 * @param encp if non zero, encrypt. if zero, decrypt.
381 * @ingroup hcrypto_des
385 DES_ecb_encrypt(DES_cblock
*input
, DES_cblock
*output
,
386 DES_key_schedule
*ks
, int encp
)
390 DES_encrypt(u
, ks
, encp
);
395 * Encrypt/decrypt a block using DES in Chain Block Cipher mode (cbc).
397 * The IV must always be diffrent for diffrent input data blocks.
399 * @param in data to encrypt
400 * @param out data to encrypt
401 * @param length length of data
402 * @param ks key schedule to use
403 * @param iv initial vector to use
404 * @param encp if non zero, encrypt. if zero, decrypt.
406 * @ingroup hcrypto_des
410 DES_cbc_encrypt(const void *in
, void *out
, long length
,
411 DES_key_schedule
*ks
, DES_cblock
*iv
, int encp
)
413 const unsigned char *input
= in
;
414 unsigned char *output
= out
;
421 while (length
>= DES_CBLOCK_LEN
) {
423 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
424 DES_encrypt(u
, ks
, 1);
425 uiv
[0] = u
[0]; uiv
[1] = u
[1];
428 length
-= DES_CBLOCK_LEN
;
429 input
+= DES_CBLOCK_LEN
;
430 output
+= DES_CBLOCK_LEN
;
433 unsigned char tmp
[DES_CBLOCK_LEN
];
434 memcpy(tmp
, input
, length
);
435 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
437 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
438 DES_encrypt(u
, ks
, 1);
443 while (length
>= DES_CBLOCK_LEN
) {
445 t
[0] = u
[0]; t
[1] = u
[1];
446 DES_encrypt(u
, ks
, 0);
447 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
449 uiv
[0] = t
[0]; uiv
[1] = t
[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 DES_encrypt(u
, ks
, 0);
461 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
465 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
469 * Encrypt/decrypt a block using DES in Propagating Cipher Block
470 * Chaining mode. This mode is only used for Kerberos 4, and it should
473 * The IV must always be diffrent for diffrent input data blocks.
475 * @param in data to encrypt
476 * @param out data to encrypt
477 * @param length length of data
478 * @param ks key schedule to use
479 * @param iv initial vector to use
480 * @param encp if non zero, encrypt. if zero, decrypt.
482 * @ingroup hcrypto_des
486 DES_pcbc_encrypt(const void *in
, void *out
, long length
,
487 DES_key_schedule
*ks
, DES_cblock
*iv
, int encp
)
489 const unsigned char *input
= in
;
490 unsigned char *output
= out
;
498 while (length
>= DES_CBLOCK_LEN
) {
500 t
[0] = u
[0]; t
[1] = u
[1];
501 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
502 DES_encrypt(u
, ks
, 1);
503 uiv
[0] = u
[0] ^ t
[0]; uiv
[1] = u
[1] ^ t
[1];
506 length
-= DES_CBLOCK_LEN
;
507 input
+= DES_CBLOCK_LEN
;
508 output
+= DES_CBLOCK_LEN
;
511 unsigned char tmp
[DES_CBLOCK_LEN
];
512 memcpy(tmp
, input
, length
);
513 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
515 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
516 DES_encrypt(u
, ks
, 1);
521 while (length
>= DES_CBLOCK_LEN
) {
523 t
[0] = u
[0]; t
[1] = u
[1];
524 DES_encrypt(u
, ks
, 0);
525 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
527 uiv
[0] = t
[0] ^ u
[0]; uiv
[1] = t
[1] ^ u
[1];
529 length
-= DES_CBLOCK_LEN
;
530 input
+= DES_CBLOCK_LEN
;
531 output
+= DES_CBLOCK_LEN
;
534 unsigned char tmp
[DES_CBLOCK_LEN
];
535 memcpy(tmp
, input
, length
);
536 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
538 DES_encrypt(u
, ks
, 0);
539 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
542 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
550 _des3_encrypt(uint32_t u
[2], DES_key_schedule
*ks1
, DES_key_schedule
*ks2
,
551 DES_key_schedule
*ks3
, int encp
)
555 desx(u
, ks1
, 1); /* IP + FP cancel out each other */
567 * Encrypt/decrypt a block using triple DES using EDE mode,
568 * encrypt/decrypt/encrypt.
570 * @param input data to encrypt
571 * @param output data to encrypt
572 * @param ks1 key schedule to use
573 * @param ks2 key schedule to use
574 * @param ks3 key schedule to use
575 * @param encp if non zero, encrypt. if zero, decrypt.
577 * @ingroup hcrypto_des
581 DES_ecb3_encrypt(DES_cblock
*input
,
583 DES_key_schedule
*ks1
,
584 DES_key_schedule
*ks2
,
585 DES_key_schedule
*ks3
,
590 _des3_encrypt(u
, ks1
, ks2
, ks3
, encp
);
596 * Encrypt/decrypt using Triple DES in Chain Block Cipher mode (cbc).
598 * The IV must always be diffrent for diffrent input data blocks.
600 * @param in data to encrypt
601 * @param out data to encrypt
602 * @param length length of data
603 * @param ks1 key schedule to use
604 * @param ks2 key schedule to use
605 * @param ks3 key schedule to use
606 * @param iv initial vector to use
607 * @param encp if non zero, encrypt. if zero, decrypt.
609 * @ingroup hcrypto_des
613 DES_ede3_cbc_encrypt(const void *in
, void *out
,
614 long length
, DES_key_schedule
*ks1
,
615 DES_key_schedule
*ks2
, DES_key_schedule
*ks3
,
616 DES_cblock
*iv
, int encp
)
618 const unsigned char *input
= in
;
619 unsigned char *output
= out
;
626 while (length
>= DES_CBLOCK_LEN
) {
628 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
629 _des3_encrypt(u
, ks1
, ks2
, ks3
, 1);
630 uiv
[0] = u
[0]; uiv
[1] = u
[1];
633 length
-= DES_CBLOCK_LEN
;
634 input
+= DES_CBLOCK_LEN
;
635 output
+= DES_CBLOCK_LEN
;
638 unsigned char tmp
[DES_CBLOCK_LEN
];
639 memcpy(tmp
, input
, length
);
640 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
642 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
643 _des3_encrypt(u
, ks1
, ks2
, ks3
, 1);
648 while (length
>= DES_CBLOCK_LEN
) {
650 t
[0] = u
[0]; t
[1] = u
[1];
651 _des3_encrypt(u
, ks1
, ks2
, ks3
, 0);
652 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
654 uiv
[0] = t
[0]; uiv
[1] = t
[1];
656 length
-= DES_CBLOCK_LEN
;
657 input
+= DES_CBLOCK_LEN
;
658 output
+= DES_CBLOCK_LEN
;
661 unsigned char tmp
[DES_CBLOCK_LEN
];
662 memcpy(tmp
, input
, length
);
663 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
665 _des3_encrypt(u
, ks1
, ks2
, ks3
, 0);
666 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
671 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0; u
[1] = 0;
675 * Encrypt/decrypt using DES in cipher feedback mode with 64 bit
678 * The IV must always be diffrent for diffrent input data blocks.
680 * @param in data to encrypt
681 * @param out data to encrypt
682 * @param length length of data
683 * @param ks key schedule to use
684 * @param iv initial vector to use
685 * @param num offset into in cipher block encryption/decryption stop last time.
686 * @param encp if non zero, encrypt. if zero, decrypt.
688 * @ingroup hcrypto_des
692 DES_cfb64_encrypt(const void *in
, void *out
,
693 long length
, DES_key_schedule
*ks
, DES_cblock
*iv
,
696 const unsigned char *input
= in
;
697 unsigned char *output
= out
;
698 unsigned char tmp
[DES_CBLOCK_LEN
];
703 assert(*num
>= 0 && *num
< DES_CBLOCK_LEN
);
710 DES_encrypt(uiv
, ks
, 1);
712 for (; i
< DES_CBLOCK_LEN
&& i
< length
; i
++) {
713 output
[i
] = tmp
[i
] ^ input
[i
];
715 if (i
== DES_CBLOCK_LEN
)
720 if (i
== DES_CBLOCK_LEN
)
731 DES_encrypt(uiv
, ks
, 1);
734 for (; i
< DES_CBLOCK_LEN
&& i
< length
; i
++) {
736 output
[i
] = tmp
[i
] ^ input
[i
];
742 if (i
== DES_CBLOCK_LEN
) {
753 * Crete a checksum using DES in CBC encryption mode. This mode is
754 * only used for Kerberos 4, and it should stay that way.
756 * The IV must always be diffrent for diffrent input data blocks.
758 * @param in data to checksum
759 * @param output the checksum
760 * @param length length of data
761 * @param ks key schedule to use
762 * @param iv initial vector to use
764 * @ingroup hcrypto_des
768 DES_cbc_cksum(const void *in
, DES_cblock
*output
,
769 long length
, DES_key_schedule
*ks
, DES_cblock
*iv
)
771 const unsigned char *input
= in
;
773 uint32_t u
[2] = { 0, 0 };
777 while (length
>= DES_CBLOCK_LEN
) {
779 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
780 DES_encrypt(u
, ks
, 1);
781 uiv
[0] = u
[0]; uiv
[1] = u
[1];
783 length
-= DES_CBLOCK_LEN
;
784 input
+= DES_CBLOCK_LEN
;
787 unsigned char tmp
[DES_CBLOCK_LEN
];
788 memcpy(tmp
, input
, length
);
789 memset(tmp
+ length
, 0, DES_CBLOCK_LEN
- length
);
791 u
[0] ^= uiv
[0]; u
[1] ^= uiv
[1];
792 DES_encrypt(u
, ks
, 1);
797 uiv
[0] = 0; u
[0] = 0; uiv
[1] = 0;
806 bitswap8(unsigned char b
)
810 for (i
= 0; i
< 8; i
++) {
811 r
= r
<< 1 | (b
& 1);
818 * Convert a string to a DES key. Use something like
819 * PKCS5_PBKDF2_HMAC_SHA1() to create key from passwords.
821 * @param str The string to convert to a key
822 * @param key the resulting key
824 * @ingroup hcrypto_des
828 DES_string_to_key(const char *str
, DES_cblock
*key
)
830 const unsigned char *s
;
835 memset(key
, 0, sizeof(*key
));
837 s
= (const unsigned char *)str
;
840 for (i
= 0; i
< len
; i
++) {
842 k
[i
% 8] ^= s
[i
] << 1;
844 k
[7 - (i
% 8)] ^= bitswap8(s
[i
]);
846 DES_set_odd_parity(key
);
847 if (DES_is_weak_key(key
))
849 DES_set_key(key
, &ks
);
850 DES_cbc_cksum(s
, key
, len
, &ks
, key
);
851 memset(&ks
, 0, sizeof(ks
));
852 DES_set_odd_parity(key
);
853 if (DES_is_weak_key(key
))
858 * Read password from prompt and create a DES key. Internal uses
859 * DES_string_to_key(). Really, go use a really string2key function
860 * like PKCS5_PBKDF2_HMAC_SHA1().
862 * @param key key to convert to
863 * @param prompt prompt to display user
864 * @param verify prompt twice.
866 * @return 1 on success, non 1 on failure.
870 DES_read_password(DES_cblock
*key
, char *prompt
, int verify
)
875 ret
= UI_UTIL_read_pw_string(buf
, sizeof(buf
) - 1, prompt
, verify
);
877 DES_string_to_key(buf
, key
);
889 DES_cblock k
= "\x01\x02\x04\x08\x10\x20\x40\x80", k2
;
890 uint32_t u
[2] = { 1, 0 };
895 if (u
[0] != 1 || u
[1] != 0)
900 if (memcmp(k
, k2
, 8) != 0)
906 * A portable, public domain, version of the Data Encryption Standard.
908 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
909 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
910 * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
911 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
912 * for humouring me on.
914 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
915 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
918 static uint32_t SP1
[64] = {
919 0x01010400L
, 0x00000000L
, 0x00010000L
, 0x01010404L
,
920 0x01010004L
, 0x00010404L
, 0x00000004L
, 0x00010000L
,
921 0x00000400L
, 0x01010400L
, 0x01010404L
, 0x00000400L
,
922 0x01000404L
, 0x01010004L
, 0x01000000L
, 0x00000004L
,
923 0x00000404L
, 0x01000400L
, 0x01000400L
, 0x00010400L
,
924 0x00010400L
, 0x01010000L
, 0x01010000L
, 0x01000404L
,
925 0x00010004L
, 0x01000004L
, 0x01000004L
, 0x00010004L
,
926 0x00000000L
, 0x00000404L
, 0x00010404L
, 0x01000000L
,
927 0x00010000L
, 0x01010404L
, 0x00000004L
, 0x01010000L
,
928 0x01010400L
, 0x01000000L
, 0x01000000L
, 0x00000400L
,
929 0x01010004L
, 0x00010000L
, 0x00010400L
, 0x01000004L
,
930 0x00000400L
, 0x00000004L
, 0x01000404L
, 0x00010404L
,
931 0x01010404L
, 0x00010004L
, 0x01010000L
, 0x01000404L
,
932 0x01000004L
, 0x00000404L
, 0x00010404L
, 0x01010400L
,
933 0x00000404L
, 0x01000400L
, 0x01000400L
, 0x00000000L
,
934 0x00010004L
, 0x00010400L
, 0x00000000L
, 0x01010004L
};
936 static uint32_t SP2
[64] = {
937 0x80108020L
, 0x80008000L
, 0x00008000L
, 0x00108020L
,
938 0x00100000L
, 0x00000020L
, 0x80100020L
, 0x80008020L
,
939 0x80000020L
, 0x80108020L
, 0x80108000L
, 0x80000000L
,
940 0x80008000L
, 0x00100000L
, 0x00000020L
, 0x80100020L
,
941 0x00108000L
, 0x00100020L
, 0x80008020L
, 0x00000000L
,
942 0x80000000L
, 0x00008000L
, 0x00108020L
, 0x80100000L
,
943 0x00100020L
, 0x80000020L
, 0x00000000L
, 0x00108000L
,
944 0x00008020L
, 0x80108000L
, 0x80100000L
, 0x00008020L
,
945 0x00000000L
, 0x00108020L
, 0x80100020L
, 0x00100000L
,
946 0x80008020L
, 0x80100000L
, 0x80108000L
, 0x00008000L
,
947 0x80100000L
, 0x80008000L
, 0x00000020L
, 0x80108020L
,
948 0x00108020L
, 0x00000020L
, 0x00008000L
, 0x80000000L
,
949 0x00008020L
, 0x80108000L
, 0x00100000L
, 0x80000020L
,
950 0x00100020L
, 0x80008020L
, 0x80000020L
, 0x00100020L
,
951 0x00108000L
, 0x00000000L
, 0x80008000L
, 0x00008020L
,
952 0x80000000L
, 0x80100020L
, 0x80108020L
, 0x00108000L
};
954 static uint32_t SP3
[64] = {
955 0x00000208L
, 0x08020200L
, 0x00000000L
, 0x08020008L
,
956 0x08000200L
, 0x00000000L
, 0x00020208L
, 0x08000200L
,
957 0x00020008L
, 0x08000008L
, 0x08000008L
, 0x00020000L
,
958 0x08020208L
, 0x00020008L
, 0x08020000L
, 0x00000208L
,
959 0x08000000L
, 0x00000008L
, 0x08020200L
, 0x00000200L
,
960 0x00020200L
, 0x08020000L
, 0x08020008L
, 0x00020208L
,
961 0x08000208L
, 0x00020200L
, 0x00020000L
, 0x08000208L
,
962 0x00000008L
, 0x08020208L
, 0x00000200L
, 0x08000000L
,
963 0x08020200L
, 0x08000000L
, 0x00020008L
, 0x00000208L
,
964 0x00020000L
, 0x08020200L
, 0x08000200L
, 0x00000000L
,
965 0x00000200L
, 0x00020008L
, 0x08020208L
, 0x08000200L
,
966 0x08000008L
, 0x00000200L
, 0x00000000L
, 0x08020008L
,
967 0x08000208L
, 0x00020000L
, 0x08000000L
, 0x08020208L
,
968 0x00000008L
, 0x00020208L
, 0x00020200L
, 0x08000008L
,
969 0x08020000L
, 0x08000208L
, 0x00000208L
, 0x08020000L
,
970 0x00020208L
, 0x00000008L
, 0x08020008L
, 0x00020200L
};
972 static uint32_t SP4
[64] = {
973 0x00802001L
, 0x00002081L
, 0x00002081L
, 0x00000080L
,
974 0x00802080L
, 0x00800081L
, 0x00800001L
, 0x00002001L
,
975 0x00000000L
, 0x00802000L
, 0x00802000L
, 0x00802081L
,
976 0x00000081L
, 0x00000000L
, 0x00800080L
, 0x00800001L
,
977 0x00000001L
, 0x00002000L
, 0x00800000L
, 0x00802001L
,
978 0x00000080L
, 0x00800000L
, 0x00002001L
, 0x00002080L
,
979 0x00800081L
, 0x00000001L
, 0x00002080L
, 0x00800080L
,
980 0x00002000L
, 0x00802080L
, 0x00802081L
, 0x00000081L
,
981 0x00800080L
, 0x00800001L
, 0x00802000L
, 0x00802081L
,
982 0x00000081L
, 0x00000000L
, 0x00000000L
, 0x00802000L
,
983 0x00002080L
, 0x00800080L
, 0x00800081L
, 0x00000001L
,
984 0x00802001L
, 0x00002081L
, 0x00002081L
, 0x00000080L
,
985 0x00802081L
, 0x00000081L
, 0x00000001L
, 0x00002000L
,
986 0x00800001L
, 0x00002001L
, 0x00802080L
, 0x00800081L
,
987 0x00002001L
, 0x00002080L
, 0x00800000L
, 0x00802001L
,
988 0x00000080L
, 0x00800000L
, 0x00002000L
, 0x00802080L
};
990 static uint32_t SP5
[64] = {
991 0x00000100L
, 0x02080100L
, 0x02080000L
, 0x42000100L
,
992 0x00080000L
, 0x00000100L
, 0x40000000L
, 0x02080000L
,
993 0x40080100L
, 0x00080000L
, 0x02000100L
, 0x40080100L
,
994 0x42000100L
, 0x42080000L
, 0x00080100L
, 0x40000000L
,
995 0x02000000L
, 0x40080000L
, 0x40080000L
, 0x00000000L
,
996 0x40000100L
, 0x42080100L
, 0x42080100L
, 0x02000100L
,
997 0x42080000L
, 0x40000100L
, 0x00000000L
, 0x42000000L
,
998 0x02080100L
, 0x02000000L
, 0x42000000L
, 0x00080100L
,
999 0x00080000L
, 0x42000100L
, 0x00000100L
, 0x02000000L
,
1000 0x40000000L
, 0x02080000L
, 0x42000100L
, 0x40080100L
,
1001 0x02000100L
, 0x40000000L
, 0x42080000L
, 0x02080100L
,
1002 0x40080100L
, 0x00000100L
, 0x02000000L
, 0x42080000L
,
1003 0x42080100L
, 0x00080100L
, 0x42000000L
, 0x42080100L
,
1004 0x02080000L
, 0x00000000L
, 0x40080000L
, 0x42000000L
,
1005 0x00080100L
, 0x02000100L
, 0x40000100L
, 0x00080000L
,
1006 0x00000000L
, 0x40080000L
, 0x02080100L
, 0x40000100L
};
1008 static uint32_t SP6
[64] = {
1009 0x20000010L
, 0x20400000L
, 0x00004000L
, 0x20404010L
,
1010 0x20400000L
, 0x00000010L
, 0x20404010L
, 0x00400000L
,
1011 0x20004000L
, 0x00404010L
, 0x00400000L
, 0x20000010L
,
1012 0x00400010L
, 0x20004000L
, 0x20000000L
, 0x00004010L
,
1013 0x00000000L
, 0x00400010L
, 0x20004010L
, 0x00004000L
,
1014 0x00404000L
, 0x20004010L
, 0x00000010L
, 0x20400010L
,
1015 0x20400010L
, 0x00000000L
, 0x00404010L
, 0x20404000L
,
1016 0x00004010L
, 0x00404000L
, 0x20404000L
, 0x20000000L
,
1017 0x20004000L
, 0x00000010L
, 0x20400010L
, 0x00404000L
,
1018 0x20404010L
, 0x00400000L
, 0x00004010L
, 0x20000010L
,
1019 0x00400000L
, 0x20004000L
, 0x20000000L
, 0x00004010L
,
1020 0x20000010L
, 0x20404010L
, 0x00404000L
, 0x20400000L
,
1021 0x00404010L
, 0x20404000L
, 0x00000000L
, 0x20400010L
,
1022 0x00000010L
, 0x00004000L
, 0x20400000L
, 0x00404010L
,
1023 0x00004000L
, 0x00400010L
, 0x20004010L
, 0x00000000L
,
1024 0x20404000L
, 0x20000000L
, 0x00400010L
, 0x20004010L
};
1026 static uint32_t SP7
[64] = {
1027 0x00200000L
, 0x04200002L
, 0x04000802L
, 0x00000000L
,
1028 0x00000800L
, 0x04000802L
, 0x00200802L
, 0x04200800L
,
1029 0x04200802L
, 0x00200000L
, 0x00000000L
, 0x04000002L
,
1030 0x00000002L
, 0x04000000L
, 0x04200002L
, 0x00000802L
,
1031 0x04000800L
, 0x00200802L
, 0x00200002L
, 0x04000800L
,
1032 0x04000002L
, 0x04200000L
, 0x04200800L
, 0x00200002L
,
1033 0x04200000L
, 0x00000800L
, 0x00000802L
, 0x04200802L
,
1034 0x00200800L
, 0x00000002L
, 0x04000000L
, 0x00200800L
,
1035 0x04000000L
, 0x00200800L
, 0x00200000L
, 0x04000802L
,
1036 0x04000802L
, 0x04200002L
, 0x04200002L
, 0x00000002L
,
1037 0x00200002L
, 0x04000000L
, 0x04000800L
, 0x00200000L
,
1038 0x04200800L
, 0x00000802L
, 0x00200802L
, 0x04200800L
,
1039 0x00000802L
, 0x04000002L
, 0x04200802L
, 0x04200000L
,
1040 0x00200800L
, 0x00000000L
, 0x00000002L
, 0x04200802L
,
1041 0x00000000L
, 0x00200802L
, 0x04200000L
, 0x00000800L
,
1042 0x04000002L
, 0x04000800L
, 0x00000800L
, 0x00200002L
};
1044 static uint32_t SP8
[64] = {
1045 0x10001040L
, 0x00001000L
, 0x00040000L
, 0x10041040L
,
1046 0x10000000L
, 0x10001040L
, 0x00000040L
, 0x10000000L
,
1047 0x00040040L
, 0x10040000L
, 0x10041040L
, 0x00041000L
,
1048 0x10041000L
, 0x00041040L
, 0x00001000L
, 0x00000040L
,
1049 0x10040000L
, 0x10000040L
, 0x10001000L
, 0x00001040L
,
1050 0x00041000L
, 0x00040040L
, 0x10040040L
, 0x10041000L
,
1051 0x00001040L
, 0x00000000L
, 0x00000000L
, 0x10040040L
,
1052 0x10000040L
, 0x10001000L
, 0x00041040L
, 0x00040000L
,
1053 0x00041040L
, 0x00040000L
, 0x10041000L
, 0x00001000L
,
1054 0x00000040L
, 0x10040040L
, 0x00001000L
, 0x00041040L
,
1055 0x10001000L
, 0x00000040L
, 0x10000040L
, 0x10040000L
,
1056 0x10040040L
, 0x10000000L
, 0x00040000L
, 0x10001040L
,
1057 0x00000000L
, 0x10041040L
, 0x00040040L
, 0x10000040L
,
1058 0x10040000L
, 0x10001000L
, 0x10001040L
, 0x00000000L
,
1059 0x10041040L
, 0x00041000L
, 0x00041000L
, 0x00001040L
,
1060 0x00001040L
, 0x00040040L
, 0x10000000L
, 0x10041000L
};
1067 work
= ((v
[0] >> 4) ^ v
[1]) & 0x0f0f0f0fL
;
1069 v
[0] ^= (work
<< 4);
1070 work
= ((v
[0] >> 16) ^ v
[1]) & 0x0000ffffL
;
1072 v
[0] ^= (work
<< 16);
1073 work
= ((v
[1] >> 2) ^ v
[0]) & 0x33333333L
;
1075 v
[1] ^= (work
<< 2);
1076 work
= ((v
[1] >> 8) ^ v
[0]) & 0x00ff00ffL
;
1078 v
[1] ^= (work
<< 8);
1079 v
[1] = ((v
[1] << 1) | ((v
[1] >> 31) & 1L)) & 0xffffffffL
;
1080 work
= (v
[0] ^ v
[1]) & 0xaaaaaaaaL
;
1083 v
[0] = ((v
[0] << 1) | ((v
[0] >> 31) & 1L)) & 0xffffffffL
;
1091 v
[0] = (v
[0] << 31) | (v
[0] >> 1);
1092 work
= (v
[1] ^ v
[0]) & 0xaaaaaaaaL
;
1095 v
[1] = (v
[1] << 31) | (v
[1] >> 1);
1096 work
= ((v
[1] >> 8) ^ v
[0]) & 0x00ff00ffL
;
1098 v
[1] ^= (work
<< 8);
1099 work
= ((v
[1] >> 2) ^ v
[0]) & 0x33333333L
;
1101 v
[1] ^= (work
<< 2);
1102 work
= ((v
[0] >> 16) ^ v
[1]) & 0x0000ffffL
;
1104 v
[0] ^= (work
<< 16);
1105 work
= ((v
[0] >> 4) ^ v
[1]) & 0x0f0f0f0fL
;
1107 v
[0] ^= (work
<< 4);
1111 desx(uint32_t block
[2], DES_key_schedule
*ks
, int encp
)
1114 uint32_t fval
, work
, right
, left
;
1123 for( round
= 0; round
< 8; round
++ ) {
1124 work
= (right
<< 28) | (right
>> 4);
1126 fval
= SP7
[ work
& 0x3fL
];
1127 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1128 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1129 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1130 work
= right
^ *keys
++;
1131 fval
|= SP8
[ work
& 0x3fL
];
1132 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1133 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1134 fval
|= SP2
[(work
>> 24) & 0x3fL
];
1136 work
= (left
<< 28) | (left
>> 4);
1138 fval
= SP7
[ work
& 0x3fL
];
1139 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1140 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1141 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1142 work
= left
^ *keys
++;
1143 fval
|= SP8
[ work
& 0x3fL
];
1144 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1145 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1146 fval
|= SP2
[(work
>> 24) & 0x3fL
];
1152 for( round
= 0; round
< 8; round
++ ) {
1153 work
= (right
<< 28) | (right
>> 4);
1155 fval
= SP7
[ work
& 0x3fL
];
1156 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1157 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1158 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1159 work
= right
^ *keys
++;
1160 fval
|= SP8
[ work
& 0x3fL
];
1161 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1162 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1163 fval
|= SP2
[(work
>> 24) & 0x3fL
];
1165 work
= (left
<< 28) | (left
>> 4);
1168 fval
= SP7
[ work
& 0x3fL
];
1169 fval
|= SP5
[(work
>> 8) & 0x3fL
];
1170 fval
|= SP3
[(work
>> 16) & 0x3fL
];
1171 fval
|= SP1
[(work
>> 24) & 0x3fL
];
1172 work
= left
^ *keys
++;
1173 fval
|= SP8
[ work
& 0x3fL
];
1174 fval
|= SP6
[(work
>> 8) & 0x3fL
];
1175 fval
|= SP4
[(work
>> 16) & 0x3fL
];
1176 fval
|= SP2
[(work
>> 24) & 0x3fL
];