1 /*	$NetBSD: des.c,v 1.1.1.2 2014/04/24 12:45:30 pettai Exp $	*/
2 
3 /*
4  * Copyright (c) 2005 Kungliga Tekniska Högskolan
5  * (Royal Institute of Technology, Stockholm, Sweden).
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
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.
18  *
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.
22  *
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
33  * SUCH DAMAGE.
34  */
35 
36 /**
37  * @page page_des DES - Data Encryption Standard crypto interface
38  *
39  * See the library functions here: @ref hcrypto_des
40  *
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).
43  *
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.
47  *
48  * Read more the iteresting history of DES on Wikipedia
49  * http://www.wikipedia.org/wiki/Data_Encryption_Standard .
50  *
51  * @section des_keygen DES key generation
52  *
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.
56  *
57  * There is a replacement function DES_new_random_key(), however that
58  * function does not exists in OpenSSL.
59  *
60  * @code
61  * DES_cblock key;
62  * do {
63  *     if (RAND_rand(&key, sizeof(key)) != 1)
64  *          goto failure;
65  *     DES_set_odd_parity(key);
66  * } while (DES_is_weak_key(&key));
67  * @endcode
68  *
69  * @section des_impl DES implementation history
70  *
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
74  * libdes.
75  *
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.
81  *
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.
85  */
86 
87 #include <config.h>
88 
89 #define HC_DEPRECATED
90 
91 #include <stdio.h>
92 #include <stdlib.h>
93 #include <string.h>
94 #include <krb5/krb5-types.h>
95 #include <assert.h>
96 
97 #include <krb5/roken.h>
98 
99 #include "des.h"
100 #include "ui.h"
101 
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]);
105 
106 #include "des-tables.h"
107 
108 #define ROTATE_LEFT28(x,one)				\
109     if (one) {						\
110 	x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27);	\
111     } else {						\
112 	x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26);	\
113     }
114 
115 /**
116  * Set the parity of the key block, used to generate a des key from a
117  * random key. See @ref des_keygen.
118  *
119  * @param key key to fixup the parity for.
120  * @ingroup hcrypto_des
121  */
122 
123 void
DES_set_odd_parity(DES_cblock * key)124 DES_set_odd_parity(DES_cblock *key)
125 {
126     unsigned int i;
127     for (i = 0; i < DES_CBLOCK_LEN; i++)
128 	(*key)[i] = odd_parity[(*key)[i]];
129 }
130 
131 /**
132  * Check if the key have correct parity.
133  *
134  * @param key key to check the parity.
135  * @return 1 on success, 0 on failure.
136  * @ingroup hcrypto_des
137  */
138 
139 int HC_DEPRECATED
DES_check_key_parity(DES_cblock * key)140 DES_check_key_parity(DES_cblock *key)
141 {
142     unsigned int i;
143 
144     for (i = 0; i <  DES_CBLOCK_LEN; i++)
145 	if ((*key)[i] != odd_parity[(*key)[i]])
146 	    return 0;
147     return 1;
148 }
149 
150 /*
151  *
152  */
153 
154 /* FIPS 74 */
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}
172 };
173 
174 /**
175  * Checks if the key is any of the weaks keys that makes DES attacks
176  * trival.
177  *
178  * @param key key to check.
179  *
180  * @return 1 if the key is weak, 0 otherwise.
181  * @ingroup hcrypto_des
182  */
183 
184 int
DES_is_weak_key(DES_cblock * key)185 DES_is_weak_key(DES_cblock *key)
186 {
187     int weak = 0;
188     int i;
189 
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);
192 
193     return !!weak;
194 }
195 
196 /**
197  * Setup a des key schedule from a key. Deprecated function, use
198  * DES_set_key_unchecked() or DES_set_key_checked() instead.
199  *
200  * @param key a key to initialize the key schedule with.
201  * @param ks a key schedule to initialize.
202  *
203  * @return 0 on success
204  * @ingroup hcrypto_des
205  */
206 
207 int HC_DEPRECATED
DES_set_key(DES_cblock * key,DES_key_schedule * ks)208 DES_set_key(DES_cblock *key, DES_key_schedule *ks)
209 {
210     return DES_set_key_checked(key, ks);
211 }
212 
213 /**
214  * Setup a des key schedule from a key. The key is no longer needed
215  * after this transaction and can cleared.
216  *
217  * Does NOT check that the key is weak for or have wrong parity.
218  *
219  * @param key a key to initialize the key schedule with.
220  * @param ks a key schedule to initialize.
221  *
222  * @return 0 on success
223  * @ingroup hcrypto_des
224  */
225 
226 int
DES_set_key_unchecked(DES_cblock * key,DES_key_schedule * ks)227 DES_set_key_unchecked(DES_cblock *key, DES_key_schedule *ks)
228 {
229     uint32_t t1, t2;
230     uint32_t c, d;
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];
233     int i;
234 
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];
237 
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);
246 
247 
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);
256 
257     for (i = 0; i < 16; i++) {
258 	uint32_t kc, kd;
259 
260 	ROTATE_LEFT28(c, shifts[i]);
261 	ROTATE_LEFT28(d, shifts[i]);
262 
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)];
271 
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);
281     }
282 
283     return 0;
284 }
285 
286 /**
287  * Just like DES_set_key_unchecked() except checking that the key is
288  * not weak for or have correct parity.
289  *
290  * @param key a key to initialize the key schedule with.
291  * @param ks a key schedule to initialize.
292  *
293  * @return 0 on success, -1 on invalid parity, -2 on weak key.
294  * @ingroup hcrypto_des
295  */
296 
297 int
DES_set_key_checked(DES_cblock * key,DES_key_schedule * ks)298 DES_set_key_checked(DES_cblock *key, DES_key_schedule *ks)
299 {
300     if (!DES_check_key_parity(key)) {
301 	memset(ks, 0, sizeof(*ks));
302 	return -1;
303     }
304     if (DES_is_weak_key(key)) {
305 	memset(ks, 0, sizeof(*ks));
306 	return -2;
307     }
308     return DES_set_key_unchecked(key, ks);
309 }
310 
311 /**
312  * Compatibility function for eay libdes, works just like
313  * DES_set_key_checked().
314  *
315  * @param key a key to initialize the key schedule with.
316  * @param ks a key schedule to initialize.
317  *
318  * @return 0 on success, -1 on invalid parity, -2 on weak key.
319  * @ingroup hcrypto_des
320  */
321 
322 int
DES_key_sched(DES_cblock * key,DES_key_schedule * ks)323 DES_key_sched(DES_cblock *key, DES_key_schedule *ks)
324 {
325     return DES_set_key_checked(key, ks);
326 }
327 
328 /*
329  *
330  */
331 
332 static void
load(const unsigned char * b,uint32_t v[2])333 load(const unsigned char *b, uint32_t v[2])
334 {
335     v[0] =  b[0] << 24;
336     v[0] |= b[1] << 16;
337     v[0] |= b[2] << 8;
338     v[0] |= b[3] << 0;
339     v[1] =  b[4] << 24;
340     v[1] |= b[5] << 16;
341     v[1] |= b[6] << 8;
342     v[1] |= b[7] << 0;
343 }
344 
345 static void
store(const uint32_t v[2],unsigned char * b)346 store(const uint32_t v[2], unsigned char *b)
347 {
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;
356 }
357 
358 /**
359  * Encrypt/decrypt a block using DES. Also called ECB mode
360  *
361  * @param u data to encrypt
362  * @param ks key schedule to use
363  * @param encp if non zero, encrypt. if zero, decrypt.
364  *
365  * @ingroup hcrypto_des
366  */
367 
368 void
DES_encrypt(uint32_t u[2],DES_key_schedule * ks,int encp)369 DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int encp)
370 {
371     IP(u);
372     desx(u, ks, encp);
373     FP(u);
374 }
375 
376 /**
377  * Encrypt/decrypt a block using DES.
378  *
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.
383  *
384  * @ingroup hcrypto_des
385  */
386 
387 void
DES_ecb_encrypt(DES_cblock * input,DES_cblock * output,DES_key_schedule * ks,int encp)388 DES_ecb_encrypt(DES_cblock *input, DES_cblock *output,
389 		DES_key_schedule *ks, int encp)
390 {
391     uint32_t u[2];
392     load(*input, u);
393     DES_encrypt(u, ks, encp);
394     store(u, *output);
395 }
396 
397 /**
398  * Encrypt/decrypt a block using DES in Chain Block Cipher mode (cbc).
399  *
400  * The IV must always be diffrent for diffrent input data blocks.
401  *
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.
408  *
409  * @ingroup hcrypto_des
410  */
411 
412 void
DES_cbc_encrypt(const void * in,void * out,long length,DES_key_schedule * ks,DES_cblock * iv,int encp)413 DES_cbc_encrypt(const void *in, void *out, long length,
414 		DES_key_schedule *ks, DES_cblock *iv, int encp)
415 {
416     const unsigned char *input = in;
417     unsigned char *output = out;
418     uint32_t u[2];
419     uint32_t uiv[2];
420 
421     load(*iv, uiv);
422 
423     if (encp) {
424 	while (length >= DES_CBLOCK_LEN) {
425 	    load(input, u);
426 	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
427 	    DES_encrypt(u, ks, 1);
428 	    uiv[0] = u[0]; uiv[1] = u[1];
429 	    store(u, output);
430 
431 	    length -= DES_CBLOCK_LEN;
432 	    input += DES_CBLOCK_LEN;
433 	    output += DES_CBLOCK_LEN;
434 	}
435 	if (length) {
436 	    unsigned char tmp[DES_CBLOCK_LEN];
437 	    memcpy(tmp, input, length);
438 	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);
439 	    load(tmp, u);
440 	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
441 	    DES_encrypt(u, ks, 1);
442 	    store(u, output);
443 	}
444     } else {
445 	uint32_t t[2];
446 	while (length >= DES_CBLOCK_LEN) {
447 	    load(input, u);
448 	    t[0] = u[0]; t[1] = u[1];
449 	    DES_encrypt(u, ks, 0);
450 	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
451 	    store(u, output);
452 	    uiv[0] = t[0]; uiv[1] = t[1];
453 
454 	    length -= DES_CBLOCK_LEN;
455 	    input += DES_CBLOCK_LEN;
456 	    output += DES_CBLOCK_LEN;
457 	}
458 	if (length) {
459 	    unsigned char tmp[DES_CBLOCK_LEN];
460 	    memcpy(tmp, input, length);
461 	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);
462 	    load(tmp, u);
463 	    DES_encrypt(u, ks, 0);
464 	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
465 	    store(u, output);
466 	}
467     }
468     uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
469 }
470 
471 /**
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
474  * stay that way.
475  *
476  * The IV must always be diffrent for diffrent input data blocks.
477  *
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.
484  *
485  * @ingroup hcrypto_des
486  */
487 
488 void
DES_pcbc_encrypt(const void * in,void * out,long length,DES_key_schedule * ks,DES_cblock * iv,int encp)489 DES_pcbc_encrypt(const void *in, void *out, long length,
490 		 DES_key_schedule *ks, DES_cblock *iv, int encp)
491 {
492     const unsigned char *input = in;
493     unsigned char *output = out;
494     uint32_t u[2];
495     uint32_t uiv[2];
496 
497     load(*iv, uiv);
498 
499     if (encp) {
500 	uint32_t t[2];
501 	while (length >= DES_CBLOCK_LEN) {
502 	    load(input, u);
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];
507 	    store(u, output);
508 
509 	    length -= DES_CBLOCK_LEN;
510 	    input += DES_CBLOCK_LEN;
511 	    output += DES_CBLOCK_LEN;
512 	}
513 	if (length) {
514 	    unsigned char tmp[DES_CBLOCK_LEN];
515 	    memcpy(tmp, input, length);
516 	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);
517 	    load(tmp, u);
518 	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
519 	    DES_encrypt(u, ks, 1);
520 	    store(u, output);
521 	}
522     } else {
523 	uint32_t t[2];
524 	while (length >= DES_CBLOCK_LEN) {
525 	    load(input, u);
526 	    t[0] = u[0]; t[1] = u[1];
527 	    DES_encrypt(u, ks, 0);
528 	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
529 	    store(u, output);
530 	    uiv[0] = t[0] ^ u[0]; uiv[1] = t[1] ^ u[1];
531 
532 	    length -= DES_CBLOCK_LEN;
533 	    input += DES_CBLOCK_LEN;
534 	    output += DES_CBLOCK_LEN;
535 	}
536 	if (length) {
537 	    unsigned char tmp[DES_CBLOCK_LEN];
538 	    memcpy(tmp, input, length);
539 	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);
540 	    load(tmp, u);
541 	    DES_encrypt(u, ks, 0);
542 	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
543 	}
544     }
545     uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
546 }
547 
548 /*
549  *
550  */
551 
552 static void
_des3_encrypt(uint32_t u[2],DES_key_schedule * ks1,DES_key_schedule * ks2,DES_key_schedule * ks3,int encp)553 _des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2,
554 	      DES_key_schedule *ks3, int encp)
555 {
556     IP(u);
557     if (encp) {
558 	desx(u, ks1, 1); /* IP + FP cancel out each other */
559 	desx(u, ks2, 0);
560 	desx(u, ks3, 1);
561     } else {
562 	desx(u, ks3, 0);
563 	desx(u, ks2, 1);
564 	desx(u, ks1, 0);
565     }
566     FP(u);
567 }
568 
569 /**
570  * Encrypt/decrypt a block using triple DES using EDE mode,
571  * encrypt/decrypt/encrypt.
572  *
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.
579  *
580  * @ingroup hcrypto_des
581  */
582 
583 void
DES_ecb3_encrypt(DES_cblock * input,DES_cblock * output,DES_key_schedule * ks1,DES_key_schedule * ks2,DES_key_schedule * ks3,int encp)584 DES_ecb3_encrypt(DES_cblock *input,
585 		 DES_cblock *output,
586 		 DES_key_schedule *ks1,
587 		 DES_key_schedule *ks2,
588 		 DES_key_schedule *ks3,
589 		 int encp)
590 {
591     uint32_t u[2];
592     load(*input, u);
593     _des3_encrypt(u, ks1, ks2, ks3, encp);
594     store(u, *output);
595     return;
596 }
597 
598 /**
599  * Encrypt/decrypt using Triple DES in Chain Block Cipher mode (cbc).
600  *
601  * The IV must always be diffrent for diffrent input data blocks.
602  *
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.
611  *
612  * @ingroup hcrypto_des
613  */
614 
615 void
DES_ede3_cbc_encrypt(const void * in,void * out,long length,DES_key_schedule * ks1,DES_key_schedule * ks2,DES_key_schedule * ks3,DES_cblock * iv,int encp)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)
620 {
621     const unsigned char *input = in;
622     unsigned char *output = out;
623     uint32_t u[2];
624     uint32_t uiv[2];
625 
626     load(*iv, uiv);
627 
628     if (encp) {
629 	while (length >= DES_CBLOCK_LEN) {
630 	    load(input, u);
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];
634 	    store(u, output);
635 
636 	    length -= DES_CBLOCK_LEN;
637 	    input += DES_CBLOCK_LEN;
638 	    output += DES_CBLOCK_LEN;
639 	}
640 	if (length) {
641 	    unsigned char tmp[DES_CBLOCK_LEN];
642 	    memcpy(tmp, input, length);
643 	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);
644 	    load(tmp, u);
645 	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
646 	    _des3_encrypt(u, ks1, ks2, ks3, 1);
647 	    store(u, output);
648 	}
649     } else {
650 	uint32_t t[2];
651 	while (length >= DES_CBLOCK_LEN) {
652 	    load(input, u);
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];
656 	    store(u, output);
657 	    uiv[0] = t[0]; uiv[1] = t[1];
658 
659 	    length -= DES_CBLOCK_LEN;
660 	    input += DES_CBLOCK_LEN;
661 	    output += DES_CBLOCK_LEN;
662 	}
663 	if (length) {
664 	    unsigned char tmp[DES_CBLOCK_LEN];
665 	    memcpy(tmp, input, length);
666 	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);
667 	    load(tmp, u);
668 	    _des3_encrypt(u, ks1, ks2, ks3, 0);
669 	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
670 	    store(u, output);
671 	}
672     }
673     store(uiv, *iv);
674     uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
675 }
676 
677 /**
678  * Encrypt/decrypt using DES in cipher feedback mode with 64 bit
679  * feedback.
680  *
681  * The IV must always be diffrent for diffrent input data blocks.
682  *
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.
690  *
691  * @ingroup hcrypto_des
692  */
693 
694 void
DES_cfb64_encrypt(const void * in,void * out,long length,DES_key_schedule * ks,DES_cblock * iv,int * num,int encp)695 DES_cfb64_encrypt(const void *in, void *out,
696 		  long length, DES_key_schedule *ks, DES_cblock *iv,
697 		  int *num, int encp)
698 {
699     const unsigned char *input = in;
700     unsigned char *output = out;
701     unsigned char tmp[DES_CBLOCK_LEN];
702     uint32_t uiv[2];
703 
704     load(*iv, uiv);
705 
706     assert(*num >= 0 && *num < DES_CBLOCK_LEN);
707 
708     if (encp) {
709 	int i = *num;
710 
711 	while (length > 0) {
712 	    if (i == 0)
713 		DES_encrypt(uiv, ks, 1);
714 	    store(uiv, tmp);
715 	    for (; i < DES_CBLOCK_LEN && i < length; i++) {
716 		output[i] = tmp[i] ^ input[i];
717 	    }
718 	    if (i == DES_CBLOCK_LEN)
719 		load(output, uiv);
720 	    output += i;
721 	    input += i;
722 	    length -= i;
723 	    if (i == DES_CBLOCK_LEN)
724 		i = 0;
725 	}
726 	store(uiv, *iv);
727 	*num = i;
728     } else {
729 	int i = *num;
730 	unsigned char c;
731 
732 	while (length > 0) {
733 	    if (i == 0) {
734 		DES_encrypt(uiv, ks, 1);
735 		store(uiv, tmp);
736 	    }
737 	    for (; i < DES_CBLOCK_LEN && i < length; i++) {
738 		c = input[i];
739 		output[i] = tmp[i] ^ input[i];
740 		(*iv)[i] = c;
741 	    }
742 	    output += i;
743 	    input += i;
744 	    length -= i;
745 	    if (i == DES_CBLOCK_LEN) {
746 		i = 0;
747 		load(*iv, uiv);
748 	    }
749 	}
750 	store(uiv, *iv);
751 	*num = i;
752     }
753 }
754 
755 /**
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.
758  *
759  * The IV must always be diffrent for diffrent input data blocks.
760  *
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
766  *
767  * @ingroup hcrypto_des
768  */
769 
770 uint32_t
DES_cbc_cksum(const void * in,DES_cblock * output,long length,DES_key_schedule * ks,DES_cblock * iv)771 DES_cbc_cksum(const void *in, DES_cblock *output,
772 	      long length, DES_key_schedule *ks, DES_cblock *iv)
773 {
774     const unsigned char *input = in;
775     uint32_t uiv[2];
776     uint32_t u[2] = { 0, 0 };
777 
778     load(*iv, uiv);
779 
780     while (length >= DES_CBLOCK_LEN) {
781 	load(input, u);
782 	u[0] ^= uiv[0]; u[1] ^= uiv[1];
783 	DES_encrypt(u, ks, 1);
784 	uiv[0] = u[0]; uiv[1] = u[1];
785 
786 	length -= DES_CBLOCK_LEN;
787 	input += DES_CBLOCK_LEN;
788     }
789     if (length) {
790 	unsigned char tmp[DES_CBLOCK_LEN];
791 	memcpy(tmp, input, length);
792 	memset(tmp + length, 0, DES_CBLOCK_LEN - length);
793 	load(tmp, u);
794 	u[0] ^= uiv[0]; u[1] ^= uiv[1];
795 	DES_encrypt(u, ks, 1);
796     }
797     if (output)
798 	store(u, *output);
799 
800     uiv[0] = 0; u[0] = 0; uiv[1] = 0;
801     return u[1];
802 }
803 
804 /*
805  *
806  */
807 
808 static unsigned char
bitswap8(unsigned char b)809 bitswap8(unsigned char b)
810 {
811     unsigned char r = 0;
812     int i;
813     for (i = 0; i < 8; i++) {
814 	r = r << 1 | (b & 1);
815 	b = b >> 1;
816     }
817     return r;
818 }
819 
820 /**
821  * Convert a string to a DES key. Use something like
822  * PKCS5_PBKDF2_HMAC_SHA1() to create key from passwords.
823  *
824  * @param str The string to convert to a key
825  * @param key the resulting key
826  *
827  * @ingroup hcrypto_des
828  */
829 
830 void
DES_string_to_key(const char * str,DES_cblock * key)831 DES_string_to_key(const char *str, DES_cblock *key)
832 {
833     const unsigned char *s;
834     unsigned char *k;
835     DES_key_schedule ks;
836     size_t i, len;
837 
838     memset(key, 0, sizeof(*key));
839     k = *key;
840     s = (const unsigned char *)str;
841 
842     len = strlen(str);
843     for (i = 0; i < len; i++) {
844 	if ((i % 16) < 8)
845 	    k[i % 8] ^= s[i] << 1;
846 	else
847 	    k[7 - (i % 8)] ^= bitswap8(s[i]);
848     }
849     DES_set_odd_parity(key);
850     if (DES_is_weak_key(key))
851 	k[7] ^= 0xF0;
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))
857 	k[7] ^= 0xF0;
858 }
859 
860 /**
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().
864  *
865  * @param key key to convert to
866  * @param prompt prompt to display user
867  * @param verify prompt twice.
868  *
869  * @return 1 on success, non 1 on failure.
870  */
871 
872 int
DES_read_password(DES_cblock * key,char * prompt,int verify)873 DES_read_password(DES_cblock *key, char *prompt, int verify)
874 {
875     char buf[512];
876     int ret;
877 
878     ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify);
879     if (ret == 1)
880 	DES_string_to_key(buf, key);
881     return ret;
882 }
883 
884 /*
885  *
886  */
887 
888 
889 void
_DES_ipfp_test(void)890 _DES_ipfp_test(void)
891 {
892     DES_cblock k = "\x01\x02\x04\x08\x10\x20\x40\x80", k2;
893     uint32_t u[2] = { 1, 0 };
894     IP(u);
895     FP(u);
896     IP(u);
897     FP(u);
898     if (u[0] != 1 || u[1] != 0)
899 	abort();
900 
901     load(k, u);
902     store(u, k2);
903     if (memcmp(k, k2, 8) != 0)
904 	abort();
905 }
906 
907 /* D3DES (V5.09) -
908  *
909  * A portable, public domain, version of the Data Encryption Standard.
910  *
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.
916  *
917  * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
918  * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
919  */
920 
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 };
938 
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 };
956 
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 };
974 
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 };
992 
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 };
1010 
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 };
1028 
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 };
1046 
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 };
1064 
1065 static void
IP(uint32_t v[2])1066 IP(uint32_t v[2])
1067 {
1068     uint32_t work;
1069 
1070     work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
1071     v[1] ^= work;
1072     v[0] ^= (work << 4);
1073     work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
1074     v[1] ^= work;
1075     v[0] ^= (work << 16);
1076     work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
1077     v[0] ^= work;
1078     v[1] ^= (work << 2);
1079     work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
1080     v[0] ^= work;
1081     v[1] ^= (work << 8);
1082     v[1] = ((v[1] << 1) | ((v[1] >> 31) & 1L)) & 0xffffffffL;
1083     work = (v[0] ^ v[1]) & 0xaaaaaaaaL;
1084     v[0] ^= work;
1085     v[1] ^= work;
1086     v[0] = ((v[0] << 1) | ((v[0] >> 31) & 1L)) & 0xffffffffL;
1087 }
1088 
1089 static void
FP(uint32_t v[2])1090 FP(uint32_t v[2])
1091 {
1092     uint32_t work;
1093 
1094     v[0] = (v[0] << 31) | (v[0] >> 1);
1095     work = (v[1] ^ v[0]) & 0xaaaaaaaaL;
1096     v[1] ^= work;
1097     v[0] ^= work;
1098     v[1] = (v[1] << 31) | (v[1] >> 1);
1099     work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
1100     v[0] ^= work;
1101     v[1] ^= (work << 8);
1102     work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
1103     v[0] ^= work;
1104     v[1] ^= (work << 2);
1105     work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
1106     v[1] ^= work;
1107     v[0] ^= (work << 16);
1108     work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
1109     v[1] ^= work;
1110     v[0] ^= (work << 4);
1111 }
1112 
1113 static void
desx(uint32_t block[2],DES_key_schedule * ks,int encp)1114 desx(uint32_t block[2], DES_key_schedule *ks, int encp)
1115 {
1116     uint32_t *keys;
1117     uint32_t fval, work, right, left;
1118     int round;
1119 
1120     left = block[0];
1121     right = block[1];
1122 
1123     if (encp) {
1124 	keys = &ks->ks[0];
1125 
1126 	for( round = 0; round < 8; round++ ) {
1127 	    work  = (right << 28) | (right >> 4);
1128 	    work ^= *keys++;
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];
1138 	    left ^= fval;
1139 	    work  = (left << 28) | (left >> 4);
1140 	    work ^= *keys++;
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];
1150 	    right ^= fval;
1151 	}
1152     } else {
1153 	keys = &ks->ks[30];
1154 
1155 	for( round = 0; round < 8; round++ ) {
1156 	    work  = (right << 28) | (right >> 4);
1157 	    work ^= *keys++;
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];
1167 	    left ^= fval;
1168 	    work  = (left << 28) | (left >> 4);
1169 	    keys -= 4;
1170 	    work ^= *keys++;
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];
1180 	    right ^= fval;
1181 	    keys -= 4;
1182 	}
1183     }
1184     block[0] = right;
1185     block[1] = left;
1186 }
1187