DES is withdrawn.
[heimdal.git] / lib / hcrypto / des.c
blob942f377da84cb2dbbdbe585eb4b87eba0b0690ac
1 /*
2 * Copyright (c) 2005 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
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
31 * SUCH DAMAGE.
34 /**
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_impl DES implementation history
51 * There was no complete BSD licensed, fast, GPL compatible
52 * implementation of DES, so Love wrote the part that was missing,
53 * fast key schedule setup and adapted the interface to the orignal
54 * libdes.
56 * The document that got me started for real was "Efficient
57 * Implementation of the Data Encryption Standard" by Dag Arne Osvik.
58 * I never got to the PC1 transformation was working, instead I used
59 * table-lookup was used for all key schedule setup. The document was
60 * very useful since it de-mystified other implementations for me.
62 * The core DES function (SBOX + P transformation) is from Richard
63 * Outerbridge public domain DES implementation. My sanity is saved
64 * thanks to his work. Thank you Richard.
67 #ifdef HAVE_CONFIG_H
68 #include <config.h>
69 RCSID("$Id$");
70 #endif
72 #include <stdio.h>
73 #include <stdlib.h>
74 #include <string.h>
75 #include <krb5-types.h>
76 #include <assert.h>
78 #include "des.h"
79 #include "ui.h"
81 static void desx(uint32_t [2], DES_key_schedule *, int);
82 static void IP(uint32_t [2]);
83 static void FP(uint32_t [2]);
85 #include "des-tables.h"
87 #define ROTATE_LEFT28(x,one) \
88 if (one) { \
89 x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \
90 } else { \
91 x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \
98 int
99 DES_set_odd_parity(DES_cblock *key)
101 int i;
102 for (i = 0; i < DES_CBLOCK_LEN; i++)
103 (*key)[i] = odd_parity[(*key)[i]];
104 return 0;
111 /* FIPS 74 */
112 static DES_cblock weak_keys[] = {
113 {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */
114 {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
115 {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
116 {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
117 {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */
118 {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
119 {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
120 {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
121 {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
122 {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
123 {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
124 {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
125 {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
126 {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
127 {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
128 {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}
132 DES_is_weak_key(DES_cblock *key)
134 int i;
136 for (i = 0; i < sizeof(weak_keys)/sizeof(weak_keys[0]); i++) {
137 if (memcmp(weak_keys[i], key, DES_CBLOCK_LEN) == 0)
138 return 1;
140 return 0;
145 * Setup a des key schedule from a key. The key is no longer needed
146 * after this transaction and can cleared.
148 * @param key a key to initialize the key schedule with.
149 * @param ks a key schedule to initialize.
151 * @return 0 on success
152 * @ingroup hcrypto_des
156 DES_set_key(DES_cblock *key, DES_key_schedule *ks)
158 uint32_t t1, t2;
159 uint32_t c, d;
160 int shifts[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
161 uint32_t *k = &ks->ks[0];
162 int i;
164 t1 = (*key)[0] << 24 | (*key)[1] << 16 | (*key)[2] << 8 | (*key)[3];
165 t2 = (*key)[4] << 24 | (*key)[5] << 16 | (*key)[6] << 8 | (*key)[7];
167 c = (pc1_c_3[(t1 >> (5 )) & 0x7] << 3)
168 | (pc1_c_3[(t1 >> (5 + 8 )) & 0x7] << 2)
169 | (pc1_c_3[(t1 >> (5 + 8 + 8 )) & 0x7] << 1)
170 | (pc1_c_3[(t1 >> (5 + 8 + 8 + 8)) & 0x7] << 0)
171 | (pc1_c_4[(t2 >> (4 )) & 0xf] << 3)
172 | (pc1_c_4[(t2 >> (4 + 8 )) & 0xf] << 2)
173 | (pc1_c_4[(t2 >> (4 + 8 + 8 )) & 0xf] << 1)
174 | (pc1_c_4[(t2 >> (4 + 8 + 8 + 8)) & 0xf] << 0);
177 d = (pc1_d_3[(t2 >> (1 )) & 0x7] << 3)
178 | (pc1_d_3[(t2 >> (1 + 8 )) & 0x7] << 2)
179 | (pc1_d_3[(t2 >> (1 + 8 + 8 )) & 0x7] << 1)
180 | (pc1_d_3[(t2 >> (1 + 8 + 8 + 8)) & 0x7] << 0)
181 | (pc1_d_4[(t1 >> (1 )) & 0xf] << 3)
182 | (pc1_d_4[(t1 >> (1 + 8 )) & 0xf] << 2)
183 | (pc1_d_4[(t1 >> (1 + 8 + 8 )) & 0xf] << 1)
184 | (pc1_d_4[(t1 >> (1 + 8 + 8 + 8)) & 0xf] << 0);
186 for (i = 0; i < 16; i++) {
187 uint32_t kc, kd;
189 ROTATE_LEFT28(c, shifts[i]);
190 ROTATE_LEFT28(d, shifts[i]);
192 kc = pc2_c_1[(c >> 22) & 0x3f] |
193 pc2_c_2[((c >> 16) & 0x30) | ((c >> 15) & 0xf)] |
194 pc2_c_3[((c >> 9 ) & 0x3c) | ((c >> 8 ) & 0x3)] |
195 pc2_c_4[((c >> 2 ) & 0x20) | ((c >> 1) & 0x18) | (c & 0x7)];
196 kd = pc2_d_1[(d >> 22) & 0x3f] |
197 pc2_d_2[((d >> 15) & 0x30) | ((d >> 14) & 0xf)] |
198 pc2_d_3[ (d >> 7 ) & 0x3f] |
199 pc2_d_4[((d >> 1 ) & 0x3c) | ((d ) & 0x3)];
201 /* Change to byte order used by the S boxes */
202 *k = (kc & 0x00fc0000L) << 6;
203 *k |= (kc & 0x00000fc0L) << 10;
204 *k |= (kd & 0x00fc0000L) >> 10;
205 *k++ |= (kd & 0x00000fc0L) >> 6;
206 *k = (kc & 0x0003f000L) << 12;
207 *k |= (kc & 0x0000003fL) << 16;
208 *k |= (kd & 0x0003f000L) >> 4;
209 *k++ |= (kd & 0x0000003fL);
212 return 0;
220 DES_set_key_checked(DES_cblock *key, DES_key_schedule *ks)
222 if (DES_is_weak_key(key)) {
223 memset(ks, 0, sizeof(*ks));
224 return 1;
226 return DES_set_key(key, ks);
230 * Compatibility function for eay libdes
234 DES_key_sched(DES_cblock *key, DES_key_schedule *ks)
236 return DES_set_key(key, ks);
243 static void
244 load(const unsigned char *b, uint32_t v[2])
246 v[0] = b[0] << 24;
247 v[0] |= b[1] << 16;
248 v[0] |= b[2] << 8;
249 v[0] |= b[3] << 0;
250 v[1] = b[4] << 24;
251 v[1] |= b[5] << 16;
252 v[1] |= b[6] << 8;
253 v[1] |= b[7] << 0;
256 static void
257 store(const uint32_t v[2], unsigned char *b)
259 b[0] = (v[0] >> 24) & 0xff;
260 b[1] = (v[0] >> 16) & 0xff;
261 b[2] = (v[0] >> 8) & 0xff;
262 b[3] = (v[0] >> 0) & 0xff;
263 b[4] = (v[1] >> 24) & 0xff;
264 b[5] = (v[1] >> 16) & 0xff;
265 b[6] = (v[1] >> 8) & 0xff;
266 b[7] = (v[1] >> 0) & 0xff;
270 * Encrypt/decrypt a block using DES. Also called ECB mode
272 * @param u data to encrypt
273 * @param ks key schedule to use
274 * @param encp if non zero, encrypt. if zero, decrypt.
276 * @ingroup hcrypto_des
279 void
280 DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int encp)
282 IP(u);
283 desx(u, ks, encp);
284 FP(u);
288 * Encrypt/decrypt a block using DES.
290 * @param input data to encrypt
291 * @param output data to encrypt
292 * @param ks key schedule to use
293 * @param encp if non zero, encrypt. if zero, decrypt.
295 * @ingroup hcrypto_des
298 void
299 DES_ecb_encrypt(DES_cblock *input, DES_cblock *output,
300 DES_key_schedule *ks, int encp)
302 uint32_t u[2];
303 load(*input, u);
304 DES_encrypt(u, ks, encp);
305 store(u, *output);
309 * Encrypt/decrypt a block using DES in Chain Block Cipher mode (cbc).
311 * The IV must always be diffrent for diffrent input data blocks.
313 * @param in data to encrypt
314 * @param out data to encrypt
315 * @param length length of data
316 * @param ks key schedule to use
317 * @param iv initial vector to use
318 * @param encp if non zero, encrypt. if zero, decrypt.
320 * @ingroup hcrypto_des
323 void
324 DES_cbc_encrypt(const void *in, void *out, long length,
325 DES_key_schedule *ks, DES_cblock *iv, int encp)
327 const unsigned char *input = in;
328 unsigned char *output = out;
329 uint32_t u[2];
330 uint32_t uiv[2];
332 load(*iv, uiv);
334 if (encp) {
335 while (length >= DES_CBLOCK_LEN) {
336 load(input, u);
337 u[0] ^= uiv[0]; u[1] ^= uiv[1];
338 DES_encrypt(u, ks, 1);
339 uiv[0] = u[0]; uiv[1] = u[1];
340 store(u, output);
342 length -= DES_CBLOCK_LEN;
343 input += DES_CBLOCK_LEN;
344 output += DES_CBLOCK_LEN;
346 if (length) {
347 unsigned char tmp[DES_CBLOCK_LEN];
348 memcpy(tmp, input, length);
349 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
350 load(tmp, u);
351 u[0] ^= uiv[0]; u[1] ^= uiv[1];
352 DES_encrypt(u, ks, 1);
353 store(u, output);
355 } else {
356 uint32_t t[2];
357 while (length >= DES_CBLOCK_LEN) {
358 load(input, u);
359 t[0] = u[0]; t[1] = u[1];
360 DES_encrypt(u, ks, 0);
361 u[0] ^= uiv[0]; u[1] ^= uiv[1];
362 store(u, output);
363 uiv[0] = t[0]; uiv[1] = t[1];
365 length -= DES_CBLOCK_LEN;
366 input += DES_CBLOCK_LEN;
367 output += DES_CBLOCK_LEN;
369 if (length) {
370 unsigned char tmp[DES_CBLOCK_LEN];
371 memcpy(tmp, input, length);
372 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
373 load(tmp, u);
374 DES_encrypt(u, ks, 0);
375 u[0] ^= uiv[0]; u[1] ^= uiv[1];
376 store(u, output);
379 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
383 * Encrypt/decrypt a block using DES in Propagating Cipher Block
384 * Chaining mode. This mode is only used for Kerberos 4, and it should
385 * stay that way.
387 * The IV must always be diffrent for diffrent input data blocks.
389 * @param in data to encrypt
390 * @param out data to encrypt
391 * @param length length of data
392 * @param ks key schedule to use
393 * @param iv initial vector to use
394 * @param encp if non zero, encrypt. if zero, decrypt.
396 * @ingroup hcrypto_des
399 void
400 DES_pcbc_encrypt(const void *in, void *out, long length,
401 DES_key_schedule *ks, DES_cblock *iv, int encp)
403 const unsigned char *input = in;
404 unsigned char *output = out;
405 uint32_t u[2];
406 uint32_t uiv[2];
408 load(*iv, uiv);
410 if (encp) {
411 uint32_t t[2];
412 while (length >= DES_CBLOCK_LEN) {
413 load(input, u);
414 t[0] = u[0]; t[1] = u[1];
415 u[0] ^= uiv[0]; u[1] ^= uiv[1];
416 DES_encrypt(u, ks, 1);
417 uiv[0] = u[0] ^ t[0]; uiv[1] = u[1] ^ t[1];
418 store(u, output);
420 length -= DES_CBLOCK_LEN;
421 input += DES_CBLOCK_LEN;
422 output += DES_CBLOCK_LEN;
424 if (length) {
425 unsigned char tmp[DES_CBLOCK_LEN];
426 memcpy(tmp, input, length);
427 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
428 load(tmp, u);
429 u[0] ^= uiv[0]; u[1] ^= uiv[1];
430 DES_encrypt(u, ks, 1);
431 store(u, output);
433 } else {
434 uint32_t t[2];
435 while (length >= DES_CBLOCK_LEN) {
436 load(input, u);
437 t[0] = u[0]; t[1] = u[1];
438 DES_encrypt(u, ks, 0);
439 u[0] ^= uiv[0]; u[1] ^= uiv[1];
440 store(u, output);
441 uiv[0] = t[0] ^ u[0]; uiv[1] = t[1] ^ u[1];
443 length -= DES_CBLOCK_LEN;
444 input += DES_CBLOCK_LEN;
445 output += DES_CBLOCK_LEN;
447 if (length) {
448 unsigned char tmp[DES_CBLOCK_LEN];
449 memcpy(tmp, input, length);
450 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
451 load(tmp, u);
452 DES_encrypt(u, ks, 0);
453 u[0] ^= uiv[0]; u[1] ^= uiv[1];
456 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
463 static void
464 _des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2,
465 DES_key_schedule *ks3, int encp)
467 IP(u);
468 if (encp) {
469 desx(u, ks1, 1); /* IP + FP cancel out each other */
470 desx(u, ks2, 0);
471 desx(u, ks3, 1);
472 } else {
473 desx(u, ks3, 0);
474 desx(u, ks2, 1);
475 desx(u, ks1, 0);
477 FP(u);
481 * Encrypt/decrypt a block using triple DES using EDE mode,
482 * encrypt/decrypt/encrypt.
484 * @param input data to encrypt
485 * @param output data to encrypt
486 * @param ks1 key schedule to use
487 * @param ks2 key schedule to use
488 * @param ks3 key schedule to use
489 * @param encp if non zero, encrypt. if zero, decrypt.
491 * @ingroup hcrypto_des
494 void
495 DES_ecb3_encrypt(DES_cblock *input,
496 DES_cblock *output,
497 DES_key_schedule *ks1,
498 DES_key_schedule *ks2,
499 DES_key_schedule *ks3,
500 int encp)
502 uint32_t u[2];
503 load(*input, u);
504 _des3_encrypt(u, ks1, ks2, ks3, encp);
505 store(u, *output);
506 return;
510 * Encrypt/decrypt using Triple DES in Chain Block Cipher mode (cbc).
512 * The IV must always be diffrent for diffrent input data blocks.
514 * @param in data to encrypt
515 * @param out data to encrypt
516 * @param length length of data
517 * @param ks1 key schedule to use
518 * @param ks2 key schedule to use
519 * @param ks3 key schedule to use
520 * @param iv initial vector to use
521 * @param encp if non zero, encrypt. if zero, decrypt.
523 * @ingroup hcrypto_des
526 void
527 DES_ede3_cbc_encrypt(const void *in, void *out,
528 long length, DES_key_schedule *ks1,
529 DES_key_schedule *ks2, DES_key_schedule *ks3,
530 DES_cblock *iv, int encp)
532 const unsigned char *input = in;
533 unsigned char *output = out;
534 uint32_t u[2];
535 uint32_t uiv[2];
537 load(*iv, uiv);
539 if (encp) {
540 while (length >= DES_CBLOCK_LEN) {
541 load(input, u);
542 u[0] ^= uiv[0]; u[1] ^= uiv[1];
543 _des3_encrypt(u, ks1, ks2, ks3, 1);
544 uiv[0] = u[0]; uiv[1] = u[1];
545 store(u, output);
547 length -= DES_CBLOCK_LEN;
548 input += DES_CBLOCK_LEN;
549 output += DES_CBLOCK_LEN;
551 if (length) {
552 unsigned char tmp[DES_CBLOCK_LEN];
553 memcpy(tmp, input, length);
554 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
555 load(tmp, u);
556 u[0] ^= uiv[0]; u[1] ^= uiv[1];
557 _des3_encrypt(u, ks1, ks2, ks3, 1);
558 store(u, output);
560 } else {
561 uint32_t t[2];
562 while (length >= DES_CBLOCK_LEN) {
563 load(input, u);
564 t[0] = u[0]; t[1] = u[1];
565 _des3_encrypt(u, ks1, ks2, ks3, 0);
566 u[0] ^= uiv[0]; u[1] ^= uiv[1];
567 store(u, output);
568 uiv[0] = t[0]; uiv[1] = t[1];
570 length -= DES_CBLOCK_LEN;
571 input += DES_CBLOCK_LEN;
572 output += DES_CBLOCK_LEN;
574 if (length) {
575 unsigned char tmp[DES_CBLOCK_LEN];
576 memcpy(tmp, input, length);
577 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
578 load(tmp, u);
579 _des3_encrypt(u, ks1, ks2, ks3, 0);
580 u[0] ^= uiv[0]; u[1] ^= uiv[1];
581 store(u, output);
584 store(uiv, *iv);
585 uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
589 * Encrypt/decrypt using DES in cipher feedback mode with 64 bit
590 * feedback.
592 * The IV must always be diffrent for diffrent input data blocks.
594 * @param in data to encrypt
595 * @param out data to encrypt
596 * @param length length of data
597 * @param ks key schedule to use
598 * @param iv initial vector to use
599 * @param num offset into in cipher block encryption/decryption stop last time.
600 * @param encp if non zero, encrypt. if zero, decrypt.
602 * @ingroup hcrypto_des
605 void
606 DES_cfb64_encrypt(const void *in, void *out,
607 long length, DES_key_schedule *ks, DES_cblock *iv,
608 int *num, int encp)
610 const unsigned char *input = in;
611 unsigned char *output = out;
612 unsigned char tmp[DES_CBLOCK_LEN];
613 uint32_t uiv[2];
615 load(*iv, uiv);
617 assert(*num >= 0 && *num < DES_CBLOCK_LEN);
619 if (encp) {
620 int i = *num;
622 while (length > 0) {
623 if (i == 0)
624 DES_encrypt(uiv, ks, 1);
625 store(uiv, tmp);
626 for (; i < DES_CBLOCK_LEN && i < length; i++) {
627 output[i] = tmp[i] ^ input[i];
629 if (i == DES_CBLOCK_LEN)
630 load(output, uiv);
631 output += i;
632 input += i;
633 length -= i;
634 if (i == DES_CBLOCK_LEN)
635 i = 0;
637 store(uiv, *iv);
638 *num = i;
639 } else {
640 int i = *num;
641 unsigned char c;
643 while (length > 0) {
644 if (i == 0) {
645 DES_encrypt(uiv, ks, 1);
646 store(uiv, tmp);
648 for (; i < DES_CBLOCK_LEN && i < length; i++) {
649 c = input[i];
650 output[i] = tmp[i] ^ input[i];
651 (*iv)[i] = c;
653 output += i;
654 input += i;
655 length -= i;
656 if (i == DES_CBLOCK_LEN) {
657 i = 0;
658 load(*iv, uiv);
661 store(uiv, *iv);
662 *num = i;
667 * Crete a checksum using DES in CBC encryption mode. This mode is
668 * only used for Kerberos 4, and it should stay that way.
670 * The IV must always be diffrent for diffrent input data blocks.
672 * @param in data to checksum
673 * @param output the checksum
674 * @param length length of data
675 * @param ks key schedule to use
676 * @param iv initial vector to use
678 * @ingroup hcrypto_des
681 uint32_t
682 DES_cbc_cksum(const void *in, DES_cblock *output,
683 long length, DES_key_schedule *ks, DES_cblock *iv)
685 const unsigned char *input = in;
686 uint32_t uiv[2];
687 uint32_t u[2] = { 0, 0 };
689 load(*iv, uiv);
691 while (length >= DES_CBLOCK_LEN) {
692 load(input, u);
693 u[0] ^= uiv[0]; u[1] ^= uiv[1];
694 DES_encrypt(u, ks, 1);
695 uiv[0] = u[0]; uiv[1] = u[1];
697 length -= DES_CBLOCK_LEN;
698 input += DES_CBLOCK_LEN;
700 if (length) {
701 unsigned char tmp[DES_CBLOCK_LEN];
702 memcpy(tmp, input, length);
703 memset(tmp + length, 0, DES_CBLOCK_LEN - length);
704 load(tmp, u);
705 u[0] ^= uiv[0]; u[1] ^= uiv[1];
706 DES_encrypt(u, ks, 1);
708 if (output)
709 store(u, *output);
711 uiv[0] = 0; u[0] = 0; uiv[1] = 0;
712 return u[1];
719 static unsigned char
720 bitswap8(unsigned char b)
722 unsigned char r = 0;
723 int i;
724 for (i = 0; i < 8; i++) {
725 r = r << 1 | (b & 1);
726 b = b >> 1;
728 return r;
732 * Convert a string to a DES key. Use something like
733 * PKCS5_PBKDF2_HMAC_SHA1() to create key from passwords.
735 * @param str The string to convert to a key
736 * @param key the resulting key
738 * @ingroup hcrypto_des
741 void
742 DES_string_to_key(const char *str, DES_cblock *key)
744 const unsigned char *s;
745 unsigned char *k;
746 DES_key_schedule ks;
747 size_t i, len;
749 memset(key, 0, sizeof(*key));
750 k = *key;
751 s = (const unsigned char *)str;
753 len = strlen(str);
754 for (i = 0; i < len; i++) {
755 if ((i % 16) < 8)
756 k[i % 8] ^= s[i] << 1;
757 else
758 k[7 - (i % 8)] ^= bitswap8(s[i]);
760 DES_set_odd_parity(key);
761 if (DES_is_weak_key(key))
762 k[7] ^= 0xF0;
763 DES_set_key(key, &ks);
764 DES_cbc_cksum(s, key, len, &ks, key);
765 memset(&ks, 0, sizeof(ks));
766 DES_set_odd_parity(key);
767 if (DES_is_weak_key(key))
768 k[7] ^= 0xF0;
772 * Read password from prompt and create a DES key.
774 * @param key key to convert to
775 * @param prompt prompt to display user
776 * @param verify prompt twice.
778 * @return 1 on success, non 1 on failure.
782 DES_read_password(DES_cblock *key, char *prompt, int verify)
784 char buf[512];
785 int ret;
787 ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify);
788 if (ret == 1)
789 DES_string_to_key(buf, key);
790 return ret;
798 void
799 _DES_ipfp_test(void)
801 DES_cblock k = "\x01\x02\x04\x08\x10\x20\x40\x80", k2;
802 uint32_t u[2] = { 1, 0 };
803 IP(u);
804 FP(u);
805 IP(u);
806 FP(u);
807 if (u[0] != 1 || u[1] != 0)
808 abort();
810 load(k, u);
811 store(u, k2);
812 if (memcmp(k, k2, 8) != 0)
813 abort();
816 /* D3DES (V5.09) -
818 * A portable, public domain, version of the Data Encryption Standard.
820 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
821 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
822 * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
823 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
824 * for humouring me on.
826 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
827 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
830 static uint32_t SP1[64] = {
831 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
832 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
833 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
834 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
835 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
836 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
837 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
838 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
839 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
840 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
841 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
842 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
843 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
844 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
845 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
846 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
848 static uint32_t SP2[64] = {
849 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
850 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
851 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
852 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
853 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
854 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
855 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
856 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
857 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
858 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
859 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
860 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
861 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
862 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
863 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
864 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
866 static uint32_t SP3[64] = {
867 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
868 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
869 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
870 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
871 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
872 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
873 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
874 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
875 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
876 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
877 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
878 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
879 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
880 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
881 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
882 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
884 static uint32_t SP4[64] = {
885 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
886 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
887 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
888 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
889 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
890 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
891 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
892 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
893 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
894 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
895 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
896 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
897 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
898 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
899 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
900 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
902 static uint32_t SP5[64] = {
903 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
904 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
905 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
906 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
907 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
908 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
909 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
910 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
911 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
912 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
913 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
914 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
915 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
916 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
917 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
918 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
920 static uint32_t SP6[64] = {
921 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
922 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
923 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
924 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
925 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
926 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
927 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
928 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
929 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
930 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
931 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
932 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
933 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
934 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
935 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
936 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
938 static uint32_t SP7[64] = {
939 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
940 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
941 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
942 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
943 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
944 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
945 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
946 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
947 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
948 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
949 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
950 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
951 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
952 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
953 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
954 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
956 static uint32_t SP8[64] = {
957 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
958 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
959 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
960 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
961 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
962 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
963 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
964 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
965 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
966 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
967 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
968 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
969 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
970 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
971 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
972 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
974 static void
975 IP(uint32_t v[2])
977 uint32_t work;
979 work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
980 v[1] ^= work;
981 v[0] ^= (work << 4);
982 work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
983 v[1] ^= work;
984 v[0] ^= (work << 16);
985 work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
986 v[0] ^= work;
987 v[1] ^= (work << 2);
988 work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
989 v[0] ^= work;
990 v[1] ^= (work << 8);
991 v[1] = ((v[1] << 1) | ((v[1] >> 31) & 1L)) & 0xffffffffL;
992 work = (v[0] ^ v[1]) & 0xaaaaaaaaL;
993 v[0] ^= work;
994 v[1] ^= work;
995 v[0] = ((v[0] << 1) | ((v[0] >> 31) & 1L)) & 0xffffffffL;
998 static void
999 FP(uint32_t v[2])
1001 uint32_t work;
1003 v[0] = (v[0] << 31) | (v[0] >> 1);
1004 work = (v[1] ^ v[0]) & 0xaaaaaaaaL;
1005 v[1] ^= work;
1006 v[0] ^= work;
1007 v[1] = (v[1] << 31) | (v[1] >> 1);
1008 work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
1009 v[0] ^= work;
1010 v[1] ^= (work << 8);
1011 work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
1012 v[0] ^= work;
1013 v[1] ^= (work << 2);
1014 work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
1015 v[1] ^= work;
1016 v[0] ^= (work << 16);
1017 work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
1018 v[1] ^= work;
1019 v[0] ^= (work << 4);
1022 static void
1023 desx(uint32_t block[2], DES_key_schedule *ks, int encp)
1025 uint32_t *keys;
1026 uint32_t fval, work, right, left;
1027 int round;
1029 left = block[0];
1030 right = block[1];
1032 if (encp) {
1033 keys = &ks->ks[0];
1035 for( round = 0; round < 8; round++ ) {
1036 work = (right << 28) | (right >> 4);
1037 work ^= *keys++;
1038 fval = SP7[ work & 0x3fL];
1039 fval |= SP5[(work >> 8) & 0x3fL];
1040 fval |= SP3[(work >> 16) & 0x3fL];
1041 fval |= SP1[(work >> 24) & 0x3fL];
1042 work = right ^ *keys++;
1043 fval |= SP8[ work & 0x3fL];
1044 fval |= SP6[(work >> 8) & 0x3fL];
1045 fval |= SP4[(work >> 16) & 0x3fL];
1046 fval |= SP2[(work >> 24) & 0x3fL];
1047 left ^= fval;
1048 work = (left << 28) | (left >> 4);
1049 work ^= *keys++;
1050 fval = SP7[ work & 0x3fL];
1051 fval |= SP5[(work >> 8) & 0x3fL];
1052 fval |= SP3[(work >> 16) & 0x3fL];
1053 fval |= SP1[(work >> 24) & 0x3fL];
1054 work = left ^ *keys++;
1055 fval |= SP8[ work & 0x3fL];
1056 fval |= SP6[(work >> 8) & 0x3fL];
1057 fval |= SP4[(work >> 16) & 0x3fL];
1058 fval |= SP2[(work >> 24) & 0x3fL];
1059 right ^= fval;
1061 } else {
1062 keys = &ks->ks[30];
1064 for( round = 0; round < 8; round++ ) {
1065 work = (right << 28) | (right >> 4);
1066 work ^= *keys++;
1067 fval = SP7[ work & 0x3fL];
1068 fval |= SP5[(work >> 8) & 0x3fL];
1069 fval |= SP3[(work >> 16) & 0x3fL];
1070 fval |= SP1[(work >> 24) & 0x3fL];
1071 work = right ^ *keys++;
1072 fval |= SP8[ work & 0x3fL];
1073 fval |= SP6[(work >> 8) & 0x3fL];
1074 fval |= SP4[(work >> 16) & 0x3fL];
1075 fval |= SP2[(work >> 24) & 0x3fL];
1076 left ^= fval;
1077 work = (left << 28) | (left >> 4);
1078 keys -= 4;
1079 work ^= *keys++;
1080 fval = SP7[ work & 0x3fL];
1081 fval |= SP5[(work >> 8) & 0x3fL];
1082 fval |= SP3[(work >> 16) & 0x3fL];
1083 fval |= SP1[(work >> 24) & 0x3fL];
1084 work = left ^ *keys++;
1085 fval |= SP8[ work & 0x3fL];
1086 fval |= SP6[(work >> 8) & 0x3fL];
1087 fval |= SP4[(work >> 16) & 0x3fL];
1088 fval |= SP2[(work >> 24) & 0x3fL];
1089 right ^= fval;
1090 keys -= 4;
1093 block[0] = right;
1094 block[1] = left;