1/*	$NetBSD: des.c,v 1.3 2023/06/19 21:41:43 christos 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#include <krb5/roken.h>
89
90#define HC_DEPRECATED
91#include <krb5/krb5-types.h>
92#include <assert.h>
93
94#include "des.h"
95#include "ui.h"
96
97static void desx(uint32_t [2], DES_key_schedule *, int);
98static void IP(uint32_t [2]);
99static void FP(uint32_t [2]);
100
101#include "des-tables.h"
102
103#define ROTATE_LEFT28(x,one)				\
104    if (one) {						\
105	x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27);	\
106    } else {						\
107	x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26);	\
108    }
109
110/**
111 * Set the parity of the key block, used to generate a des key from a
112 * random key. See @ref des_keygen.
113 *
114 * @param key key to fixup the parity for.
115 * @ingroup hcrypto_des
116 */
117
118void
119DES_set_odd_parity(DES_cblock *key)
120{
121    unsigned int i;
122    for (i = 0; i < DES_CBLOCK_LEN; i++)
123	(*key)[i] = odd_parity[(*key)[i]];
124}
125
126/**
127 * Check if the key have correct parity.
128 *
129 * @param key key to check the parity.
130 * @return 1 on success, 0 on failure.
131 * @ingroup hcrypto_des
132 */
133
134int HC_DEPRECATED
135DES_check_key_parity(DES_cblock *key)
136{
137    unsigned int i;
138
139    for (i = 0; i <  DES_CBLOCK_LEN; i++)
140	if ((*key)[i] != odd_parity[(*key)[i]])
141	    return 0;
142    return 1;
143}
144
145/*
146 *
147 */
148
149/* FIPS 74 */
150static DES_cblock weak_keys[] = {
151    {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */
152    {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
153    {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
154    {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
155    {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */
156    {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
157    {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
158    {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
159    {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
160    {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
161    {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
162    {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
163    {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
164    {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
165    {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
166    {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}
167};
168
169/**
170 * Checks if the key is any of the weaks keys that makes DES attacks
171 * trival.
172 *
173 * @param key key to check.
174 *
175 * @return 1 if the key is weak, 0 otherwise.
176 * @ingroup hcrypto_des
177 */
178
179int
180DES_is_weak_key(DES_cblock *key)
181{
182    int weak = 0;
183    int i;
184
185    for (i = 0; i < sizeof(weak_keys)/sizeof(weak_keys[0]); i++)
186	weak ^= (ct_memcmp(weak_keys[i], key, DES_CBLOCK_LEN) == 0);
187
188    return !!weak;
189}
190
191/**
192 * Setup a des key schedule from a key. Deprecated function, use
193 * DES_set_key_unchecked() or DES_set_key_checked() instead.
194 *
195 * @param key a key to initialize the key schedule with.
196 * @param ks a key schedule to initialize.
197 *
198 * @return 0 on success
199 * @ingroup hcrypto_des
200 */
201
202int HC_DEPRECATED
203DES_set_key(DES_cblock *key, DES_key_schedule *ks)
204{
205    return DES_set_key_checked(key, ks);
206}
207
208/**
209 * Setup a des key schedule from a key. The key is no longer needed
210 * after this transaction and can cleared.
211 *
212 * Does NOT check that the key is weak for or have wrong parity.
213 *
214 * @param key a key to initialize the key schedule with.
215 * @param ks a key schedule to initialize.
216 *
217 * @return 0 on success
218 * @ingroup hcrypto_des
219 */
220
221int
222DES_set_key_unchecked(DES_cblock *key, DES_key_schedule *ks)
223{
224    uint32_t t1, t2;
225    uint32_t c, d;
226    int shifts[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
227    uint32_t *k = &ks->ks[0];
228    int i;
229
230    t1 = (uint32_t)(*key)[0] << 24 | (*key)[1] << 16 | (*key)[2] << 8 | (*key)[3];
231    t2 = (uint32_t)(*key)[4] << 24 | (*key)[5] << 16 | (*key)[6] << 8 | (*key)[7];
232
233    c =   (pc1_c_3[(t1 >> (5            )) & 0x7] << 3)
234	| (pc1_c_3[(t1 >> (5 + 8        )) & 0x7] << 2)
235	| (pc1_c_3[(t1 >> (5 + 8 + 8    )) & 0x7] << 1)
236	| (pc1_c_3[(t1 >> (5 + 8 + 8 + 8)) & 0x7] << 0)
237	| (pc1_c_4[(t2 >> (4            )) & 0xf] << 3)
238	| (pc1_c_4[(t2 >> (4 + 8        )) & 0xf] << 2)
239	| (pc1_c_4[(t2 >> (4 + 8 + 8    )) & 0xf] << 1)
240	| (pc1_c_4[(t2 >> (4 + 8 + 8 + 8)) & 0xf] << 0);
241
242
243    d =   (pc1_d_3[(t2 >> (1            )) & 0x7] << 3)
244	| (pc1_d_3[(t2 >> (1 + 8        )) & 0x7] << 2)
245	| (pc1_d_3[(t2 >> (1 + 8 + 8    )) & 0x7] << 1)
246	| (pc1_d_3[(t2 >> (1 + 8 + 8 + 8)) & 0x7] << 0)
247	| (pc1_d_4[(t1 >> (1            )) & 0xf] << 3)
248	| (pc1_d_4[(t1 >> (1 + 8        )) & 0xf] << 2)
249	| (pc1_d_4[(t1 >> (1 + 8 + 8    )) & 0xf] << 1)
250	| (pc1_d_4[(t1 >> (1 + 8 + 8 + 8)) & 0xf] << 0);
251
252    for (i = 0; i < 16; i++) {
253	uint32_t kc, kd;
254
255	ROTATE_LEFT28(c, shifts[i]);
256	ROTATE_LEFT28(d, shifts[i]);
257
258	kc = pc2_c_1[(c >> 22) & 0x3f] |
259	    pc2_c_2[((c >> 16) & 0x30) | ((c >> 15) & 0xf)] |
260	    pc2_c_3[((c >> 9 ) & 0x3c) | ((c >> 8 ) & 0x3)] |
261	    pc2_c_4[((c >> 2 ) & 0x20) | ((c >> 1) & 0x18) | (c & 0x7)];
262	kd = pc2_d_1[(d >> 22) & 0x3f] |
263	    pc2_d_2[((d >> 15) & 0x30) | ((d >> 14) & 0xf)] |
264	    pc2_d_3[ (d >> 7 ) & 0x3f] |
265	    pc2_d_4[((d >> 1 ) & 0x3c) | ((d      ) & 0x3)];
266
267	/* Change to byte order used by the S boxes */
268	*k  =    (kc & 0x00fc0000L) << 6;
269	*k |=    (kc & 0x00000fc0L) << 10;
270	*k |=    (kd & 0x00fc0000L) >> 10;
271	*k++  |= (kd & 0x00000fc0L) >> 6;
272	*k  =    (kc & 0x0003f000L) << 12;
273	*k |=    (kc & 0x0000003fL) << 16;
274	*k |=    (kd & 0x0003f000L) >> 4;
275	*k++  |= (kd & 0x0000003fL);
276    }
277
278    return 0;
279}
280
281/**
282 * Just like DES_set_key_unchecked() except checking that the key is
283 * not weak for or have correct parity.
284 *
285 * @param key a key to initialize the key schedule with.
286 * @param ks a key schedule to initialize.
287 *
288 * @return 0 on success, -1 on invalid parity, -2 on weak key.
289 * @ingroup hcrypto_des
290 */
291
292int
293DES_set_key_checked(DES_cblock *key, DES_key_schedule *ks)
294{
295    if (!DES_check_key_parity(key)) {
296	memset(ks, 0, sizeof(*ks));
297	return -1;
298    }
299    if (DES_is_weak_key(key)) {
300	memset(ks, 0, sizeof(*ks));
301	return -2;
302    }
303    return DES_set_key_unchecked(key, ks);
304}
305
306/**
307 * Compatibility function for eay libdes, works just like
308 * DES_set_key_checked().
309 *
310 * @param key a key to initialize the key schedule with.
311 * @param ks a key schedule to initialize.
312 *
313 * @return 0 on success, -1 on invalid parity, -2 on weak key.
314 * @ingroup hcrypto_des
315 */
316
317int
318DES_key_sched(DES_cblock *key, DES_key_schedule *ks)
319{
320    return DES_set_key_checked(key, ks);
321}
322
323/*
324 *
325 */
326
327static void
328load(const unsigned char *b, uint32_t v[2])
329{
330    v[0] =  (uint32_t)b[0] << 24U;
331    v[0] |= b[1] << 16U;
332    v[0] |= b[2] << 8U;
333    v[0] |= b[3] << 0U;
334    v[1] =  (uint32_t)b[4] << 24U;
335    v[1] |= b[5] << 16U;
336    v[1] |= b[6] << 8U;
337    v[1] |= b[7] << 0U;
338}
339
340static void
341store(const uint32_t v[2], unsigned char *b)
342{
343    b[0] = (v[0] >> 24) & 0xffU;
344    b[1] = (v[0] >> 16) & 0xffU;
345    b[2] = (v[0] >>  8) & 0xffU;
346    b[3] = (v[0] >>  0) & 0xffU;
347    b[4] = (v[1] >> 24) & 0xffU;
348    b[5] = (v[1] >> 16) & 0xffU;
349    b[6] = (v[1] >>  8) & 0xffU;
350    b[7] = (v[1] >>  0) & 0xffU;
351}
352
353/**
354 * Encrypt/decrypt a block using DES. Also called ECB mode
355 *
356 * @param u data to encrypt
357 * @param ks key schedule to use
358 * @param encp if non zero, encrypt. if zero, decrypt.
359 *
360 * @ingroup hcrypto_des
361 */
362
363void
364DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int encp)
365{
366    IP(u);
367    desx(u, ks, encp);
368    FP(u);
369}
370
371/**
372 * Encrypt/decrypt a block using DES.
373 *
374 * @param input data to encrypt
375 * @param output data to encrypt
376 * @param ks key schedule to use
377 * @param encp if non zero, encrypt. if zero, decrypt.
378 *
379 * @ingroup hcrypto_des
380 */
381
382void
383DES_ecb_encrypt(DES_cblock *input, DES_cblock *output,
384		DES_key_schedule *ks, int encp)
385{
386    uint32_t u[2];
387    load(*input, u);
388    DES_encrypt(u, ks, encp);
389    store(u, *output);
390}
391
392/**
393 * Encrypt/decrypt a block using DES in Chain Block Cipher mode (cbc).
394 *
395 * The IV must always be diffrent for diffrent input data blocks.
396 *
397 * @param in data to encrypt
398 * @param out data to encrypt
399 * @param length length of data
400 * @param ks key schedule to use
401 * @param iv initial vector to use
402 * @param encp if non zero, encrypt. if zero, decrypt.
403 *
404 * @ingroup hcrypto_des
405 */
406
407void
408DES_cbc_encrypt(const void *in, void *out, long length,
409		DES_key_schedule *ks, DES_cblock *iv, int encp)
410{
411    const unsigned char *input = in;
412    unsigned char *output = out;
413    uint32_t u[2];
414    uint32_t uiv[2];
415
416    load(*iv, uiv);
417
418    if (encp) {
419	while (length >= DES_CBLOCK_LEN) {
420	    load(input, u);
421	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
422	    DES_encrypt(u, ks, 1);
423	    uiv[0] = u[0]; uiv[1] = u[1];
424	    store(u, output);
425
426	    length -= DES_CBLOCK_LEN;
427	    input += DES_CBLOCK_LEN;
428	    output += DES_CBLOCK_LEN;
429	}
430	if (length) {
431	    unsigned char tmp[DES_CBLOCK_LEN];
432	    memcpy(tmp, input, length);
433	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);
434	    load(tmp, u);
435	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
436	    DES_encrypt(u, ks, 1);
437	    store(u, output);
438	}
439    } else {
440	uint32_t t[2];
441	while (length >= DES_CBLOCK_LEN) {
442	    load(input, u);
443	    t[0] = u[0]; t[1] = u[1];
444	    DES_encrypt(u, ks, 0);
445	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
446	    store(u, output);
447	    uiv[0] = t[0]; uiv[1] = t[1];
448
449	    length -= DES_CBLOCK_LEN;
450	    input += DES_CBLOCK_LEN;
451	    output += DES_CBLOCK_LEN;
452	}
453	if (length) {
454	    unsigned char tmp[DES_CBLOCK_LEN];
455	    memcpy(tmp, input, length);
456	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);
457	    load(tmp, u);
458	    DES_encrypt(u, ks, 0);
459	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
460	    store(u, output);
461	}
462    }
463    uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
464}
465
466/**
467 * Encrypt/decrypt a block using DES in Propagating Cipher Block
468 * Chaining mode. This mode is only used for Kerberos 4, and it should
469 * stay that way.
470 *
471 * The IV must always be diffrent for diffrent input data blocks.
472 *
473 * @param in data to encrypt
474 * @param out data to encrypt
475 * @param length length of data
476 * @param ks key schedule to use
477 * @param iv initial vector to use
478 * @param encp if non zero, encrypt. if zero, decrypt.
479 *
480 * @ingroup hcrypto_des
481 */
482
483void
484DES_pcbc_encrypt(const void *in, void *out, long length,
485		 DES_key_schedule *ks, DES_cblock *iv, int encp)
486{
487    const unsigned char *input = in;
488    unsigned char *output = out;
489    uint32_t u[2];
490    uint32_t uiv[2];
491
492    load(*iv, uiv);
493
494    if (encp) {
495	uint32_t t[2];
496	while (length >= DES_CBLOCK_LEN) {
497	    load(input, u);
498	    t[0] = u[0]; t[1] = u[1];
499	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
500	    DES_encrypt(u, ks, 1);
501	    uiv[0] = u[0] ^ t[0]; uiv[1] = u[1] ^ t[1];
502	    store(u, output);
503
504	    length -= DES_CBLOCK_LEN;
505	    input += DES_CBLOCK_LEN;
506	    output += DES_CBLOCK_LEN;
507	}
508	if (length) {
509	    unsigned char tmp[DES_CBLOCK_LEN];
510	    memcpy(tmp, input, length);
511	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);
512	    load(tmp, u);
513	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
514	    DES_encrypt(u, ks, 1);
515	    store(u, output);
516	}
517    } else {
518	uint32_t t[2];
519	while (length >= DES_CBLOCK_LEN) {
520	    load(input, u);
521	    t[0] = u[0]; t[1] = u[1];
522	    DES_encrypt(u, ks, 0);
523	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
524	    store(u, output);
525	    uiv[0] = t[0] ^ u[0]; uiv[1] = t[1] ^ u[1];
526
527	    length -= DES_CBLOCK_LEN;
528	    input += DES_CBLOCK_LEN;
529	    output += DES_CBLOCK_LEN;
530	}
531	if (length) {
532	    unsigned char tmp[DES_CBLOCK_LEN];
533	    memcpy(tmp, input, length);
534	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);
535	    load(tmp, u);
536	    DES_encrypt(u, ks, 0);
537	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
538	}
539    }
540    uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
541}
542
543/*
544 *
545 */
546
547static void
548_des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2,
549	      DES_key_schedule *ks3, int encp)
550{
551    IP(u);
552    if (encp) {
553	desx(u, ks1, 1); /* IP + FP cancel out each other */
554	desx(u, ks2, 0);
555	desx(u, ks3, 1);
556    } else {
557	desx(u, ks3, 0);
558	desx(u, ks2, 1);
559	desx(u, ks1, 0);
560    }
561    FP(u);
562}
563
564/**
565 * Encrypt/decrypt a block using triple DES using EDE mode,
566 * encrypt/decrypt/encrypt.
567 *
568 * @param input data to encrypt
569 * @param output data to encrypt
570 * @param ks1 key schedule to use
571 * @param ks2 key schedule to use
572 * @param ks3 key schedule to use
573 * @param encp if non zero, encrypt. if zero, decrypt.
574 *
575 * @ingroup hcrypto_des
576 */
577
578void
579DES_ecb3_encrypt(DES_cblock *input,
580		 DES_cblock *output,
581		 DES_key_schedule *ks1,
582		 DES_key_schedule *ks2,
583		 DES_key_schedule *ks3,
584		 int encp)
585{
586    uint32_t u[2];
587    load(*input, u);
588    _des3_encrypt(u, ks1, ks2, ks3, encp);
589    store(u, *output);
590    return;
591}
592
593/**
594 * Encrypt/decrypt using Triple DES in Chain Block Cipher mode (cbc).
595 *
596 * The IV must always be diffrent for diffrent input data blocks.
597 *
598 * @param in data to encrypt
599 * @param out data to encrypt
600 * @param length length of data
601 * @param ks1 key schedule to use
602 * @param ks2 key schedule to use
603 * @param ks3 key schedule to use
604 * @param iv initial vector to use
605 * @param encp if non zero, encrypt. if zero, decrypt.
606 *
607 * @ingroup hcrypto_des
608 */
609
610void
611DES_ede3_cbc_encrypt(const void *in, void *out,
612		     long length, DES_key_schedule *ks1,
613		     DES_key_schedule *ks2, DES_key_schedule *ks3,
614		     DES_cblock *iv, int encp)
615{
616    const unsigned char *input = in;
617    unsigned char *output = out;
618    uint32_t u[2];
619    uint32_t uiv[2];
620
621    load(*iv, uiv);
622
623    if (encp) {
624	while (length >= DES_CBLOCK_LEN) {
625	    load(input, u);
626	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
627	    _des3_encrypt(u, ks1, ks2, ks3, 1);
628	    uiv[0] = u[0]; uiv[1] = u[1];
629	    store(u, output);
630
631	    length -= DES_CBLOCK_LEN;
632	    input += DES_CBLOCK_LEN;
633	    output += DES_CBLOCK_LEN;
634	}
635	if (length) {
636	    unsigned char tmp[DES_CBLOCK_LEN];
637	    memcpy(tmp, input, length);
638	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);
639	    load(tmp, u);
640	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
641	    _des3_encrypt(u, ks1, ks2, ks3, 1);
642	    store(u, output);
643	}
644    } else {
645	uint32_t t[2];
646	while (length >= DES_CBLOCK_LEN) {
647	    load(input, u);
648	    t[0] = u[0]; t[1] = u[1];
649	    _des3_encrypt(u, ks1, ks2, ks3, 0);
650	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
651	    store(u, output);
652	    uiv[0] = t[0]; uiv[1] = t[1];
653
654	    length -= DES_CBLOCK_LEN;
655	    input += DES_CBLOCK_LEN;
656	    output += DES_CBLOCK_LEN;
657	}
658	if (length) {
659	    unsigned char tmp[DES_CBLOCK_LEN];
660	    memcpy(tmp, input, length);
661	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);
662	    load(tmp, u);
663	    _des3_encrypt(u, ks1, ks2, ks3, 0);
664	    u[0] ^= uiv[0]; u[1] ^= uiv[1];
665	    store(u, output);
666	}
667    }
668    store(uiv, *iv);
669    uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
670}
671
672/**
673 * Encrypt/decrypt using DES in cipher feedback mode with 64 bit
674 * feedback.
675 *
676 * The IV must always be diffrent for diffrent input data blocks.
677 *
678 * @param in data to encrypt
679 * @param out data to encrypt
680 * @param length length of data
681 * @param ks key schedule to use
682 * @param iv initial vector to use
683 * @param num offset into in cipher block encryption/decryption stop last time.
684 * @param encp if non zero, encrypt. if zero, decrypt.
685 *
686 * @ingroup hcrypto_des
687 */
688
689void
690DES_cfb64_encrypt(const void *in, void *out,
691		  long length, DES_key_schedule *ks, DES_cblock *iv,
692		  int *num, int encp)
693{
694    const unsigned char *input = in;
695    unsigned char *output = out;
696    unsigned char tmp[DES_CBLOCK_LEN];
697    uint32_t uiv[2];
698
699    load(*iv, uiv);
700
701    assert(*num >= 0 && *num < DES_CBLOCK_LEN);
702
703    if (encp) {
704	int i = *num;
705
706	while (length > 0) {
707	    if (i == 0)
708		DES_encrypt(uiv, ks, 1);
709	    store(uiv, tmp);
710	    for (; i < DES_CBLOCK_LEN && i < length; i++) {
711		output[i] = tmp[i] ^ input[i];
712	    }
713	    if (i == DES_CBLOCK_LEN)
714		load(output, uiv);
715	    output += i;
716	    input += i;
717	    length -= i;
718	    if (i == DES_CBLOCK_LEN)
719		i = 0;
720	}
721	store(uiv, *iv);
722	*num = i;
723    } else {
724	int i = *num;
725	unsigned char c;
726
727	while (length > 0) {
728	    if (i == 0) {
729		DES_encrypt(uiv, ks, 1);
730		store(uiv, tmp);
731	    }
732	    for (; i < DES_CBLOCK_LEN && i < length; i++) {
733		c = input[i];
734		output[i] = tmp[i] ^ input[i];
735		(*iv)[i] = c;
736	    }
737	    output += i;
738	    input += i;
739	    length -= i;
740	    if (i == DES_CBLOCK_LEN) {
741		i = 0;
742		load(*iv, uiv);
743	    }
744	}
745	store(uiv, *iv);
746	*num = i;
747    }
748}
749
750/**
751 * Crete a checksum using DES in CBC encryption mode. This mode is
752 * only used for Kerberos 4, and it should stay that way.
753 *
754 * The IV must always be diffrent for diffrent input data blocks.
755 *
756 * @param in data to checksum
757 * @param output the checksum
758 * @param length length of data
759 * @param ks key schedule to use
760 * @param iv initial vector to use
761 *
762 * @ingroup hcrypto_des
763 */
764
765uint32_t
766DES_cbc_cksum(const void *in, DES_cblock *output,
767	      long length, DES_key_schedule *ks, DES_cblock *iv)
768{
769    const unsigned char *input = in;
770    uint32_t uiv[2];
771    uint32_t u[2] = { 0, 0 };
772
773    load(*iv, uiv);
774
775    while (length >= DES_CBLOCK_LEN) {
776	load(input, u);
777	u[0] ^= uiv[0]; u[1] ^= uiv[1];
778	DES_encrypt(u, ks, 1);
779	uiv[0] = u[0]; uiv[1] = u[1];
780
781	length -= DES_CBLOCK_LEN;
782	input += DES_CBLOCK_LEN;
783    }
784    if (length) {
785	unsigned char tmp[DES_CBLOCK_LEN];
786	memcpy(tmp, input, length);
787	memset(tmp + length, 0, DES_CBLOCK_LEN - length);
788	load(tmp, u);
789	u[0] ^= uiv[0]; u[1] ^= uiv[1];
790	DES_encrypt(u, ks, 1);
791    }
792    if (output)
793	store(u, *output);
794
795    uiv[0] = 0; u[0] = 0; uiv[1] = 0;
796    return u[1];
797}
798
799/*
800 *
801 */
802
803static unsigned char
804bitswap8(unsigned char b)
805{
806    unsigned char r = 0;
807    int i;
808    for (i = 0; i < 8; i++) {
809	r = r << 1 | (b & 1);
810	b = b >> 1;
811    }
812    return r;
813}
814
815/**
816 * Convert a string to a DES key. Use something like
817 * PKCS5_PBKDF2_HMAC_SHA1() to create key from passwords.
818 *
819 * @param str The string to convert to a key
820 * @param key the resulting key
821 *
822 * @ingroup hcrypto_des
823 */
824
825void
826DES_string_to_key(const char *str, DES_cblock *key)
827{
828    const unsigned char *s;
829    unsigned char *k;
830    DES_key_schedule ks;
831    size_t i, len;
832
833    memset(key, 0, sizeof(*key));
834    k = *key;
835    s = (const unsigned char *)str;
836
837    len = strlen(str);
838    for (i = 0; i < len; i++) {
839	if ((i % 16) < 8)
840	    k[i % 8] ^= s[i] << 1;
841	else
842	    k[7 - (i % 8)] ^= bitswap8(s[i]);
843    }
844    DES_set_odd_parity(key);
845    if (DES_is_weak_key(key))
846	k[7] ^= 0xF0;
847    DES_set_key(key, &ks);
848    DES_cbc_cksum(s, key, len, &ks, key);
849    memset(&ks, 0, sizeof(ks));
850    DES_set_odd_parity(key);
851    if (DES_is_weak_key(key))
852	k[7] ^= 0xF0;
853}
854
855/**
856 * Read password from prompt and create a DES key. Internal uses
857 * DES_string_to_key(). Really, go use a really string2key function
858 * like PKCS5_PBKDF2_HMAC_SHA1().
859 *
860 * @param key key to convert to
861 * @param prompt prompt to display user
862 * @param verify prompt twice.
863 *
864 * @return 1 on success, non 1 on failure.
865 */
866
867int
868DES_read_password(DES_cblock *key, char *prompt, int verify)
869{
870    char buf[512];
871    int ret;
872
873    ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify);
874    if (ret == 1)
875	DES_string_to_key(buf, key);
876    return ret;
877}
878
879/*
880 *
881 */
882
883
884void
885_DES_ipfp_test(void)
886{
887    DES_cblock k = "\x01\x02\x04\x08\x10\x20\x40\x80", k2;
888    uint32_t u[2] = { 1, 0 };
889    IP(u);
890    FP(u);
891    IP(u);
892    FP(u);
893    if (u[0] != 1 || u[1] != 0)
894	abort();
895
896    load(k, u);
897    store(u, k2);
898    if (memcmp(k, k2, 8) != 0)
899	abort();
900}
901
902/* D3DES (V5.09) -
903 *
904 * A portable, public domain, version of the Data Encryption Standard.
905 *
906 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
907 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
908 * code;  Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
909 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
910 * for humouring me on.
911 *
912 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
913 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
914 */
915
916static uint32_t SP1[64] = {
917    0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
918    0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
919    0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
920    0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
921    0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
922    0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
923    0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
924    0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
925    0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
926    0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
927    0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
928    0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
929    0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
930    0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
931    0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
932    0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
933
934static uint32_t SP2[64] = {
935    0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
936    0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
937    0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
938    0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
939    0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
940    0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
941    0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
942    0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
943    0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
944    0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
945    0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
946    0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
947    0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
948    0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
949    0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
950    0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
951
952static uint32_t SP3[64] = {
953    0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
954    0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
955    0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
956    0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
957    0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
958    0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
959    0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
960    0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
961    0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
962    0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
963    0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
964    0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
965    0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
966    0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
967    0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
968    0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
969
970static uint32_t SP4[64] = {
971    0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
972    0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
973    0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
974    0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
975    0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
976    0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
977    0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
978    0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
979    0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
980    0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
981    0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
982    0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
983    0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
984    0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
985    0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
986    0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
987
988static uint32_t SP5[64] = {
989    0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
990    0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
991    0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
992    0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
993    0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
994    0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
995    0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
996    0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
997    0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
998    0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
999    0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
1000    0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
1001    0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
1002    0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
1003    0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
1004    0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
1005
1006static uint32_t SP6[64] = {
1007    0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
1008    0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
1009    0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
1010    0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
1011    0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
1012    0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
1013    0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
1014    0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
1015    0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
1016    0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
1017    0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
1018    0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
1019    0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
1020    0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
1021    0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
1022    0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
1023
1024static uint32_t SP7[64] = {
1025    0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
1026    0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
1027    0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
1028    0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
1029    0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
1030    0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
1031    0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
1032    0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
1033    0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
1034    0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
1035    0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
1036    0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
1037    0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
1038    0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
1039    0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
1040    0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
1041
1042static uint32_t SP8[64] = {
1043    0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
1044    0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
1045    0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
1046    0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
1047    0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
1048    0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
1049    0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
1050    0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
1051    0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
1052    0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
1053    0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
1054    0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
1055    0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
1056    0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
1057    0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
1058    0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
1059
1060static void
1061IP(uint32_t v[2])
1062{
1063    uint32_t work;
1064
1065    work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
1066    v[1] ^= work;
1067    v[0] ^= (work << 4);
1068    work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
1069    v[1] ^= work;
1070    v[0] ^= (work << 16);
1071    work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
1072    v[0] ^= work;
1073    v[1] ^= (work << 2);
1074    work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
1075    v[0] ^= work;
1076    v[1] ^= (work << 8);
1077    v[1] = ((v[1] << 1) | ((v[1] >> 31) & 1L)) & 0xffffffffL;
1078    work = (v[0] ^ v[1]) & 0xaaaaaaaaL;
1079    v[0] ^= work;
1080    v[1] ^= work;
1081    v[0] = ((v[0] << 1) | ((v[0] >> 31) & 1L)) & 0xffffffffL;
1082}
1083
1084static void
1085FP(uint32_t v[2])
1086{
1087    uint32_t work;
1088
1089    v[0] = (v[0] << 31) | (v[0] >> 1);
1090    work = (v[1] ^ v[0]) & 0xaaaaaaaaL;
1091    v[1] ^= work;
1092    v[0] ^= work;
1093    v[1] = (v[1] << 31) | (v[1] >> 1);
1094    work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
1095    v[0] ^= work;
1096    v[1] ^= (work << 8);
1097    work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
1098    v[0] ^= work;
1099    v[1] ^= (work << 2);
1100    work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
1101    v[1] ^= work;
1102    v[0] ^= (work << 16);
1103    work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
1104    v[1] ^= work;
1105    v[0] ^= (work << 4);
1106}
1107
1108static void
1109desx(uint32_t block[2], DES_key_schedule *ks, int encp)
1110{
1111    uint32_t *keys;
1112    uint32_t fval, work, right, left;
1113    int round;
1114
1115    left = block[0];
1116    right = block[1];
1117
1118    if (encp) {
1119	keys = &ks->ks[0];
1120
1121	for( round = 0; round < 8; round++ ) {
1122	    work  = (right << 28) | (right >> 4);
1123	    work ^= *keys++;
1124	    fval  = SP7[ work     & 0x3fL];
1125	    fval |= SP5[(work >>  8) & 0x3fL];
1126	    fval |= SP3[(work >> 16) & 0x3fL];
1127	    fval |= SP1[(work >> 24) & 0x3fL];
1128	    work  = right ^ *keys++;
1129	    fval |= SP8[ work     & 0x3fL];
1130	    fval |= SP6[(work >>  8) & 0x3fL];
1131	    fval |= SP4[(work >> 16) & 0x3fL];
1132	    fval |= SP2[(work >> 24) & 0x3fL];
1133	    left ^= fval;
1134	    work  = (left << 28) | (left >> 4);
1135	    work ^= *keys++;
1136	    fval  = SP7[ work     & 0x3fL];
1137	    fval |= SP5[(work >>  8) & 0x3fL];
1138	    fval |= SP3[(work >> 16) & 0x3fL];
1139	    fval |= SP1[(work >> 24) & 0x3fL];
1140	    work  = left ^ *keys++;
1141	    fval |= SP8[ work     & 0x3fL];
1142	    fval |= SP6[(work >>  8) & 0x3fL];
1143	    fval |= SP4[(work >> 16) & 0x3fL];
1144	    fval |= SP2[(work >> 24) & 0x3fL];
1145	    right ^= fval;
1146	}
1147    } else {
1148	keys = &ks->ks[30];
1149
1150	for( round = 0; round < 8; round++ ) {
1151	    work  = (right << 28) | (right >> 4);
1152	    work ^= *keys++;
1153	    fval  = SP7[ work     & 0x3fL];
1154	    fval |= SP5[(work >>  8) & 0x3fL];
1155	    fval |= SP3[(work >> 16) & 0x3fL];
1156	    fval |= SP1[(work >> 24) & 0x3fL];
1157	    work  = right ^ *keys++;
1158	    fval |= SP8[ work     & 0x3fL];
1159	    fval |= SP6[(work >>  8) & 0x3fL];
1160	    fval |= SP4[(work >> 16) & 0x3fL];
1161	    fval |= SP2[(work >> 24) & 0x3fL];
1162	    left ^= fval;
1163	    work  = (left << 28) | (left >> 4);
1164	    keys -= 4;
1165	    work ^= *keys++;
1166	    fval  = SP7[ work     & 0x3fL];
1167	    fval |= SP5[(work >>  8) & 0x3fL];
1168	    fval |= SP3[(work >> 16) & 0x3fL];
1169	    fval |= SP1[(work >> 24) & 0x3fL];
1170	    work  = left ^ *keys++;
1171	    fval |= SP8[ work     & 0x3fL];
1172	    fval |= SP6[(work >>  8) & 0x3fL];
1173	    fval |= SP4[(work >> 16) & 0x3fL];
1174	    fval |= SP2[(work >> 24) & 0x3fL];
1175	    right ^= fval;
1176	    keys -= 4;
1177	}
1178    }
1179    block[0] = right;
1180    block[1] = left;
1181}
1182