~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/heimdal/lib/hcrypto/des.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

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