Coverage Report

Created: 2026-01-16 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/third_party/heimdal/lib/hcrypto/des.c
Line
Count
Source
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
#include <config.h>
86
#include <roken.h>
87
88
#define HC_DEPRECATED
89
#include <krb5-types.h>
90
#include <assert.h>
91
92
#include "des.h"
93
#include "ui.h"
94
95
static void desx(uint32_t [2], DES_key_schedule *, int);
96
static void IP(uint32_t [2]);
97
static void FP(uint32_t [2]);
98
99
#include "des-tables.h"
100
101
#define ROTATE_LEFT28(x,one)        \
102
0
    if (one) {           \
103
0
  x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27);  \
104
0
    } else {           \
105
0
  x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26);  \
106
0
    }
107
108
/**
109
 * Set the parity of the key block, used to generate a des key from a
110
 * random key. See @ref des_keygen.
111
 *
112
 * @param key key to fixup the parity for.
113
 * @ingroup hcrypto_des
114
 */
115
116
void
117
DES_set_odd_parity(DES_cblock *key)
118
0
{
119
0
    unsigned int i;
120
0
    for (i = 0; i < DES_CBLOCK_LEN; i++)
121
0
  (*key)[i] = odd_parity[(*key)[i]];
122
0
}
123
124
/**
125
 * Check if the key have correct parity.
126
 *
127
 * @param key key to check the parity.
128
 * @return 1 on success, 0 on failure.
129
 * @ingroup hcrypto_des
130
 */
131
132
int HC_DEPRECATED
133
DES_check_key_parity(DES_cblock *key)
134
0
{
135
0
    unsigned int i;
136
137
0
    for (i = 0; i <  DES_CBLOCK_LEN; i++)
138
0
  if ((*key)[i] != odd_parity[(*key)[i]])
139
0
      return 0;
140
0
    return 1;
141
0
}
142
143
/*
144
 *
145
 */
146
147
/* FIPS 74 */
148
static DES_cblock weak_keys[] = {
149
    {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */
150
    {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
151
    {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
152
    {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
153
    {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */
154
    {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
155
    {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
156
    {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
157
    {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
158
    {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
159
    {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
160
    {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
161
    {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
162
    {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
163
    {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
164
    {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}
165
};
166
167
/**
168
 * Checks if the key is any of the weaks keys that makes DES attacks
169
 * trival.
170
 *
171
 * @param key key to check.
172
 *
173
 * @return 1 if the key is weak, 0 otherwise.
174
 * @ingroup hcrypto_des
175
 */
176
177
int
178
DES_is_weak_key(DES_cblock *key)
179
0
{
180
0
    int weak = 0;
181
0
    int i;
182
183
0
    for (i = 0; i < sizeof(weak_keys)/sizeof(weak_keys[0]); i++)
184
0
  weak ^= (ct_memcmp(weak_keys[i], key, DES_CBLOCK_LEN) == 0);
185
186
0
    return !!weak;
187
0
}
188
189
/**
190
 * Setup a des key schedule from a key. Deprecated function, use
191
 * DES_set_key_unchecked() or DES_set_key_checked() instead.
192
 *
193
 * @param key a key to initialize the key schedule with.
194
 * @param ks a key schedule to initialize.
195
 *
196
 * @return 0 on success
197
 * @ingroup hcrypto_des
198
 */
199
200
int HC_DEPRECATED
201
DES_set_key(DES_cblock *key, DES_key_schedule *ks)
202
0
{
203
0
    return DES_set_key_checked(key, ks);
204
0
}
205
206
/**
207
 * Setup a des key schedule from a key. The key is no longer needed
208
 * after this transaction and can cleared.
209
 *
210
 * Does NOT check that the key is weak for or have wrong parity.
211
 *
212
 * @param key a key to initialize the key schedule with.
213
 * @param ks a key schedule to initialize.
214
 *
215
 * @return 0 on success
216
 * @ingroup hcrypto_des
217
 */
218
219
int
220
DES_set_key_unchecked(DES_cblock *key, DES_key_schedule *ks)
221
0
{
222
0
    uint32_t t1, t2;
223
0
    uint32_t c, d;
224
0
    int shifts[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
225
0
    uint32_t *k = &ks->ks[0];
226
0
    int i;
227
228
0
    t1 = (uint32_t)((*key)[0]) << 24
229
0
       | (uint32_t)((*key)[1]) << 16
230
0
       | (uint32_t)((*key)[2]) << 8
231
0
       | (*key)[3];
232
0
    t2 = (uint32_t)((*key)[4]) << 24
233
0
       | (uint32_t)((*key)[5]) << 16
234
0
       | (uint32_t)((*key)[6]) << 8
235
0
       | (*key)[7];
236
237
0
    c =   (pc1_c_3[(t1 >> (5            )) & 0x7] << 3)
238
0
  | (pc1_c_3[(t1 >> (5 + 8        )) & 0x7] << 2)
239
0
  | (pc1_c_3[(t1 >> (5 + 8 + 8    )) & 0x7] << 1)
240
0
  | (pc1_c_3[(t1 >> (5 + 8 + 8 + 8)) & 0x7] << 0)
241
0
  | (pc1_c_4[(t2 >> (4            )) & 0xf] << 3)
242
0
  | (pc1_c_4[(t2 >> (4 + 8        )) & 0xf] << 2)
243
0
  | (pc1_c_4[(t2 >> (4 + 8 + 8    )) & 0xf] << 1)
244
0
  | (pc1_c_4[(t2 >> (4 + 8 + 8 + 8)) & 0xf] << 0);
245
246
247
0
    d =   (pc1_d_3[(t2 >> (1            )) & 0x7] << 3)
248
0
  | (pc1_d_3[(t2 >> (1 + 8        )) & 0x7] << 2)
249
0
  | (pc1_d_3[(t2 >> (1 + 8 + 8    )) & 0x7] << 1)
250
0
  | (pc1_d_3[(t2 >> (1 + 8 + 8 + 8)) & 0x7] << 0)
251
0
  | (pc1_d_4[(t1 >> (1            )) & 0xf] << 3)
252
0
  | (pc1_d_4[(t1 >> (1 + 8        )) & 0xf] << 2)
253
0
  | (pc1_d_4[(t1 >> (1 + 8 + 8    )) & 0xf] << 1)
254
0
  | (pc1_d_4[(t1 >> (1 + 8 + 8 + 8)) & 0xf] << 0);
255
256
0
    for (i = 0; i < 16; i++) {
257
0
  uint32_t kc, kd;
258
259
0
  ROTATE_LEFT28(c, shifts[i]);
260
0
  ROTATE_LEFT28(d, shifts[i]);
261
262
0
  kc = pc2_c_1[(c >> 22) & 0x3f] |
263
0
      pc2_c_2[((c >> 16) & 0x30) | ((c >> 15) & 0xf)] |
264
0
      pc2_c_3[((c >> 9 ) & 0x3c) | ((c >> 8 ) & 0x3)] |
265
0
      pc2_c_4[((c >> 2 ) & 0x20) | ((c >> 1) & 0x18) | (c & 0x7)];
266
0
  kd = pc2_d_1[(d >> 22) & 0x3f] |
267
0
      pc2_d_2[((d >> 15) & 0x30) | ((d >> 14) & 0xf)] |
268
0
      pc2_d_3[ (d >> 7 ) & 0x3f] |
269
0
      pc2_d_4[((d >> 1 ) & 0x3c) | ((d      ) & 0x3)];
270
271
  /* Change to byte order used by the S boxes */
272
0
  *k  =    (kc & 0x00fc0000L) << 6;
273
0
  *k |=    (kc & 0x00000fc0L) << 10;
274
0
  *k |=    (kd & 0x00fc0000L) >> 10;
275
0
  *k++  |= (kd & 0x00000fc0L) >> 6;
276
0
  *k  =    (kc & 0x0003f000L) << 12;
277
0
  *k |=    (kc & 0x0000003fL) << 16;
278
0
  *k |=    (kd & 0x0003f000L) >> 4;
279
0
  *k++  |= (kd & 0x0000003fL);
280
0
    }
281
282
0
    return 0;
283
0
}
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
0
{
299
0
    if (!DES_check_key_parity(key)) {
300
0
  memset(ks, 0, sizeof(*ks));
301
0
  return -1;
302
0
    }
303
0
    if (DES_is_weak_key(key)) {
304
0
  memset(ks, 0, sizeof(*ks));
305
0
  return -2;
306
0
    }
307
0
    return DES_set_key_unchecked(key, ks);
308
0
}
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
0
{
324
0
    return DES_set_key_checked(key, ks);
325
0
}
326
327
/*
328
 *
329
 */
330
331
static void
332
load(const unsigned char *b, uint32_t v[2])
333
0
{
334
0
    v[0] =  (uint32_t)(b[0]) << 24;
335
0
    v[0] |= (uint32_t)(b[1]) << 16;
336
0
    v[0] |= (uint32_t)(b[2]) << 8;
337
0
    v[0] |= b[3];
338
0
    v[1] =  (uint32_t)(b[4]) << 24;
339
0
    v[1] |= (uint32_t)(b[5]) << 16;
340
0
    v[1] |= (uint32_t)(b[6]) << 8;
341
0
    v[1] |= b[7];
342
0
}
343
344
static void
345
store(const uint32_t v[2], unsigned char *b)
346
0
{
347
0
    b[0] = (v[0] >> 24) & 0xffU;
348
0
    b[1] = (v[0] >> 16) & 0xffU;
349
0
    b[2] = (v[0] >>  8) & 0xffU;
350
0
    b[3] = (v[0] >>  0) & 0xffU;
351
0
    b[4] = (v[1] >> 24) & 0xffU;
352
0
    b[5] = (v[1] >> 16) & 0xffU;
353
0
    b[6] = (v[1] >>  8) & 0xffU;
354
0
    b[7] = (v[1] >>  0) & 0xffU;
355
0
}
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
0
{
370
0
    IP(u);
371
0
    desx(u, ks, encp);
372
0
    FP(u);
373
0
}
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
0
{
390
0
    uint32_t u[2];
391
0
    load(*input, u);
392
0
    DES_encrypt(u, ks, encp);
393
0
    store(u, *output);
394
0
}
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
0
{
415
0
    const unsigned char *input = in;
416
0
    unsigned char *output = out;
417
0
    uint32_t u[2];
418
0
    uint32_t uiv[2];
419
420
0
    load(*iv, uiv);
421
422
0
    if (encp) {
423
0
  while (length >= DES_CBLOCK_LEN) {
424
0
      load(input, u);
425
0
      u[0] ^= uiv[0]; u[1] ^= uiv[1];
426
0
      DES_encrypt(u, ks, 1);
427
0
      uiv[0] = u[0]; uiv[1] = u[1];
428
0
      store(u, output);
429
430
0
      length -= DES_CBLOCK_LEN;
431
0
      input += DES_CBLOCK_LEN;
432
0
      output += DES_CBLOCK_LEN;
433
0
  }
434
0
  if (length) {
435
0
      unsigned char tmp[DES_CBLOCK_LEN];
436
0
      memcpy(tmp, input, length);
437
0
      memset(tmp + length, 0, DES_CBLOCK_LEN - length);
438
0
      load(tmp, u);
439
0
      u[0] ^= uiv[0]; u[1] ^= uiv[1];
440
0
      DES_encrypt(u, ks, 1);
441
0
      store(u, output);
442
0
  }
443
0
    } else {
444
0
  uint32_t t[2];
445
0
  while (length >= DES_CBLOCK_LEN) {
446
0
      load(input, u);
447
0
      t[0] = u[0]; t[1] = u[1];
448
0
      DES_encrypt(u, ks, 0);
449
0
      u[0] ^= uiv[0]; u[1] ^= uiv[1];
450
0
      store(u, output);
451
0
      uiv[0] = t[0]; uiv[1] = t[1];
452
453
0
      length -= DES_CBLOCK_LEN;
454
0
      input += DES_CBLOCK_LEN;
455
0
      output += DES_CBLOCK_LEN;
456
0
  }
457
0
  if (length) {
458
0
      unsigned char tmp[DES_CBLOCK_LEN];
459
0
      memcpy(tmp, input, length);
460
0
      memset(tmp + length, 0, DES_CBLOCK_LEN - length);
461
0
      load(tmp, u);
462
0
      DES_encrypt(u, ks, 0);
463
0
      u[0] ^= uiv[0]; u[1] ^= uiv[1];
464
0
      store(u, output);
465
0
  }
466
0
    }
467
0
    uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
468
0
}
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
0
{
491
0
    const unsigned char *input = in;
492
0
    unsigned char *output = out;
493
0
    uint32_t u[2];
494
0
    uint32_t uiv[2];
495
496
0
    load(*iv, uiv);
497
498
0
    if (encp) {
499
0
  uint32_t t[2];
500
0
  while (length >= DES_CBLOCK_LEN) {
501
0
      load(input, u);
502
0
      t[0] = u[0]; t[1] = u[1];
503
0
      u[0] ^= uiv[0]; u[1] ^= uiv[1];
504
0
      DES_encrypt(u, ks, 1);
505
0
      uiv[0] = u[0] ^ t[0]; uiv[1] = u[1] ^ t[1];
506
0
      store(u, output);
507
508
0
      length -= DES_CBLOCK_LEN;
509
0
      input += DES_CBLOCK_LEN;
510
0
      output += DES_CBLOCK_LEN;
511
0
  }
512
0
  if (length) {
513
0
      unsigned char tmp[DES_CBLOCK_LEN];
514
0
      memcpy(tmp, input, length);
515
0
      memset(tmp + length, 0, DES_CBLOCK_LEN - length);
516
0
      load(tmp, u);
517
0
      u[0] ^= uiv[0]; u[1] ^= uiv[1];
518
0
      DES_encrypt(u, ks, 1);
519
0
      store(u, output);
520
0
  }
521
0
    } else {
522
0
  uint32_t t[2];
523
0
  while (length >= DES_CBLOCK_LEN) {
524
0
      load(input, u);
525
0
      t[0] = u[0]; t[1] = u[1];
526
0
      DES_encrypt(u, ks, 0);
527
0
      u[0] ^= uiv[0]; u[1] ^= uiv[1];
528
0
      store(u, output);
529
0
      uiv[0] = t[0] ^ u[0]; uiv[1] = t[1] ^ u[1];
530
531
0
      length -= DES_CBLOCK_LEN;
532
0
      input += DES_CBLOCK_LEN;
533
0
      output += DES_CBLOCK_LEN;
534
0
  }
535
0
  if (length) {
536
0
      unsigned char tmp[DES_CBLOCK_LEN];
537
0
      memcpy(tmp, input, length);
538
0
      memset(tmp + length, 0, DES_CBLOCK_LEN - length);
539
0
      load(tmp, u);
540
0
      DES_encrypt(u, ks, 0);
541
0
      u[0] ^= uiv[0]; u[1] ^= uiv[1];
542
0
  }
543
0
    }
544
0
    uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
545
0
}
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
0
{
555
0
    IP(u);
556
0
    if (encp) {
557
0
  desx(u, ks1, 1); /* IP + FP cancel out each other */
558
0
  desx(u, ks2, 0);
559
0
  desx(u, ks3, 1);
560
0
    } else {
561
0
  desx(u, ks3, 0);
562
0
  desx(u, ks2, 1);
563
0
  desx(u, ks1, 0);
564
0
    }
565
0
    FP(u);
566
0
}
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
0
{
590
0
    uint32_t u[2];
591
0
    load(*input, u);
592
0
    _des3_encrypt(u, ks1, ks2, ks3, encp);
593
0
    store(u, *output);
594
0
    return;
595
0
}
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
0
{
620
0
    const unsigned char *input = in;
621
0
    unsigned char *output = out;
622
0
    uint32_t u[2];
623
0
    uint32_t uiv[2];
624
625
0
    load(*iv, uiv);
626
627
0
    if (encp) {
628
0
  while (length >= DES_CBLOCK_LEN) {
629
0
      load(input, u);
630
0
      u[0] ^= uiv[0]; u[1] ^= uiv[1];
631
0
      _des3_encrypt(u, ks1, ks2, ks3, 1);
632
0
      uiv[0] = u[0]; uiv[1] = u[1];
633
0
      store(u, output);
634
635
0
      length -= DES_CBLOCK_LEN;
636
0
      input += DES_CBLOCK_LEN;
637
0
      output += DES_CBLOCK_LEN;
638
0
  }
639
0
  if (length) {
640
0
      unsigned char tmp[DES_CBLOCK_LEN];
641
0
      memcpy(tmp, input, length);
642
0
      memset(tmp + length, 0, DES_CBLOCK_LEN - length);
643
0
      load(tmp, u);
644
0
      u[0] ^= uiv[0]; u[1] ^= uiv[1];
645
0
      _des3_encrypt(u, ks1, ks2, ks3, 1);
646
0
      store(u, output);
647
0
  }
648
0
    } else {
649
0
  uint32_t t[2];
650
0
  while (length >= DES_CBLOCK_LEN) {
651
0
      load(input, u);
652
0
      t[0] = u[0]; t[1] = u[1];
653
0
      _des3_encrypt(u, ks1, ks2, ks3, 0);
654
0
      u[0] ^= uiv[0]; u[1] ^= uiv[1];
655
0
      store(u, output);
656
0
      uiv[0] = t[0]; uiv[1] = t[1];
657
658
0
      length -= DES_CBLOCK_LEN;
659
0
      input += DES_CBLOCK_LEN;
660
0
      output += DES_CBLOCK_LEN;
661
0
  }
662
0
  if (length) {
663
0
      unsigned char tmp[DES_CBLOCK_LEN];
664
0
      memcpy(tmp, input, length);
665
0
      memset(tmp + length, 0, DES_CBLOCK_LEN - length);
666
0
      load(tmp, u);
667
0
      _des3_encrypt(u, ks1, ks2, ks3, 0);
668
0
      u[0] ^= uiv[0]; u[1] ^= uiv[1];
669
0
      store(u, output);
670
0
  }
671
0
    }
672
0
    store(uiv, *iv);
673
0
    uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
674
0
}
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
0
{
698
0
    const unsigned char *input = in;
699
0
    unsigned char *output = out;
700
0
    unsigned char tmp[DES_CBLOCK_LEN];
701
0
    uint32_t uiv[2];
702
703
0
    load(*iv, uiv);
704
705
0
    assert(*num >= 0 && *num < DES_CBLOCK_LEN);
706
707
0
    if (encp) {
708
0
  int i = *num;
709
710
0
  while (length > 0) {
711
0
      if (i == 0)
712
0
    DES_encrypt(uiv, ks, 1);
713
0
      store(uiv, tmp);
714
0
      for (; i < DES_CBLOCK_LEN && i < length; i++) {
715
0
    output[i] = tmp[i] ^ input[i];
716
0
      }
717
0
      if (i == DES_CBLOCK_LEN)
718
0
    load(output, uiv);
719
0
      output += i;
720
0
      input += i;
721
0
      length -= i;
722
0
      if (i == DES_CBLOCK_LEN)
723
0
    i = 0;
724
0
  }
725
0
  store(uiv, *iv);
726
0
  *num = i;
727
0
    } else {
728
0
  int i = *num;
729
0
  unsigned char c;
730
731
0
  memset(tmp, 0, DES_CBLOCK_LEN);
732
0
  while (length > 0) {
733
0
      if (i == 0) {
734
0
    DES_encrypt(uiv, ks, 1);
735
0
    store(uiv, tmp);
736
0
      }
737
0
      for (; i < DES_CBLOCK_LEN && i < length; i++) {
738
0
    c = input[i];
739
0
    output[i] = tmp[i] ^ input[i];
740
0
    (*iv)[i] = c;
741
0
      }
742
0
      output += i;
743
0
      input += i;
744
0
      length -= i;
745
0
      if (i == DES_CBLOCK_LEN) {
746
0
    i = 0;
747
0
    load(*iv, uiv);
748
0
      }
749
0
  }
750
0
  store(uiv, *iv);
751
0
  *num = i;
752
0
    }
753
0
}
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
771
DES_cbc_cksum(const void *in, DES_cblock *output,
772
        long length, DES_key_schedule *ks, DES_cblock *iv)
773
0
{
774
0
    const unsigned char *input = in;
775
0
    uint32_t uiv[2];
776
0
    uint32_t u[2] = { 0, 0 };
777
778
0
    load(*iv, uiv);
779
780
0
    while (length >= DES_CBLOCK_LEN) {
781
0
  load(input, u);
782
0
  u[0] ^= uiv[0]; u[1] ^= uiv[1];
783
0
  DES_encrypt(u, ks, 1);
784
0
  uiv[0] = u[0]; uiv[1] = u[1];
785
786
0
  length -= DES_CBLOCK_LEN;
787
0
  input += DES_CBLOCK_LEN;
788
0
    }
789
0
    if (length) {
790
0
  unsigned char tmp[DES_CBLOCK_LEN];
791
0
  memcpy(tmp, input, length);
792
0
  memset(tmp + length, 0, DES_CBLOCK_LEN - length);
793
0
  load(tmp, u);
794
0
  u[0] ^= uiv[0]; u[1] ^= uiv[1];
795
0
  DES_encrypt(u, ks, 1);
796
0
    }
797
0
    if (output)
798
0
  store(u, *output);
799
800
0
    uiv[0] = 0; u[0] = 0; uiv[1] = 0;
801
0
    return u[1];
802
0
}
803
804
/*
805
 *
806
 */
807
808
static unsigned char
809
bitswap8(unsigned char b)
810
0
{
811
0
    unsigned char r = 0;
812
0
    int i;
813
0
    for (i = 0; i < 8; i++) {
814
0
  r = r << 1 | (b & 1);
815
0
  b = b >> 1;
816
0
    }
817
0
    return r;
818
0
}
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
831
DES_string_to_key(const char *str, DES_cblock *key)
832
0
{
833
0
    const unsigned char *s;
834
0
    unsigned char *k;
835
0
    DES_key_schedule ks;
836
0
    size_t i, len;
837
838
0
    memset(key, 0, sizeof(*key));
839
0
    k = *key;
840
0
    s = (const unsigned char *)str;
841
842
0
    len = strlen(str);
843
0
    for (i = 0; i < len; i++) {
844
0
  if ((i % 16) < 8)
845
0
      k[i % 8] ^= s[i] << 1;
846
0
  else
847
0
      k[7 - (i % 8)] ^= bitswap8(s[i]);
848
0
    }
849
0
    DES_set_odd_parity(key);
850
0
    if (DES_is_weak_key(key))
851
0
  k[7] ^= 0xF0;
852
0
    DES_set_key(key, &ks);
853
0
    DES_cbc_cksum(s, key, len, &ks, key);
854
0
    memset_s(&ks, sizeof(ks), 0, sizeof(ks));
855
0
    DES_set_odd_parity(key);
856
0
    if (DES_is_weak_key(key))
857
0
  k[7] ^= 0xF0;
858
0
}
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
873
DES_read_password(DES_cblock *key, char *prompt, int verify)
874
0
{
875
0
    char buf[512];
876
0
    int ret;
877
878
0
    ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify);
879
0
    if (ret == 1)
880
0
  DES_string_to_key(buf, key);
881
0
    return ret;
882
0
}
883
884
/*
885
 *
886
 */
887
888
889
void
890
_DES_ipfp_test(void)
891
0
{
892
0
    DES_cblock k = "\x01\x02\x04\x08\x10\x20\x40\x80", k2;
893
0
    uint32_t u[2] = { 1, 0 };
894
0
    IP(u);
895
0
    FP(u);
896
0
    IP(u);
897
0
    FP(u);
898
0
    if (u[0] != 1 || u[1] != 0)
899
0
  abort();
900
901
0
    load(k, u);
902
0
    store(u, k2);
903
0
    if (memcmp(k, k2, 8) != 0)
904
0
  abort();
905
0
}
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
1066
IP(uint32_t v[2])
1067
0
{
1068
0
    uint32_t work;
1069
1070
0
    work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
1071
0
    v[1] ^= work;
1072
0
    v[0] ^= (work << 4);
1073
0
    work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
1074
0
    v[1] ^= work;
1075
0
    v[0] ^= (work << 16);
1076
0
    work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
1077
0
    v[0] ^= work;
1078
0
    v[1] ^= (work << 2);
1079
0
    work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
1080
0
    v[0] ^= work;
1081
0
    v[1] ^= (work << 8);
1082
0
    v[1] = ((v[1] << 1) | ((v[1] >> 31) & 1L)) & 0xffffffffL;
1083
0
    work = (v[0] ^ v[1]) & 0xaaaaaaaaL;
1084
0
    v[0] ^= work;
1085
0
    v[1] ^= work;
1086
0
    v[0] = ((v[0] << 1) | ((v[0] >> 31) & 1L)) & 0xffffffffL;
1087
0
}
1088
1089
static void
1090
FP(uint32_t v[2])
1091
0
{
1092
0
    uint32_t work;
1093
1094
0
    v[0] = (v[0] << 31) | (v[0] >> 1);
1095
0
    work = (v[1] ^ v[0]) & 0xaaaaaaaaL;
1096
0
    v[1] ^= work;
1097
0
    v[0] ^= work;
1098
0
    v[1] = (v[1] << 31) | (v[1] >> 1);
1099
0
    work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
1100
0
    v[0] ^= work;
1101
0
    v[1] ^= (work << 8);
1102
0
    work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
1103
0
    v[0] ^= work;
1104
0
    v[1] ^= (work << 2);
1105
0
    work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
1106
0
    v[1] ^= work;
1107
0
    v[0] ^= (work << 16);
1108
0
    work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
1109
0
    v[1] ^= work;
1110
0
    v[0] ^= (work << 4);
1111
0
}
1112
1113
static void
1114
desx(uint32_t block[2], DES_key_schedule *ks, int encp)
1115
0
{
1116
0
    uint32_t *keys;
1117
0
    uint32_t fval, work, right, left;
1118
0
    int round;
1119
1120
0
    left = block[0];
1121
0
    right = block[1];
1122
1123
0
    if (encp) {
1124
0
  keys = &ks->ks[0];
1125
1126
0
  for( round = 0; round < 8; round++ ) {
1127
0
      work  = (right << 28) | (right >> 4);
1128
0
      work ^= *keys++;
1129
0
      fval  = SP7[ work     & 0x3fL];
1130
0
      fval |= SP5[(work >>  8) & 0x3fL];
1131
0
      fval |= SP3[(work >> 16) & 0x3fL];
1132
0
      fval |= SP1[(work >> 24) & 0x3fL];
1133
0
      work  = right ^ *keys++;
1134
0
      fval |= SP8[ work     & 0x3fL];
1135
0
      fval |= SP6[(work >>  8) & 0x3fL];
1136
0
      fval |= SP4[(work >> 16) & 0x3fL];
1137
0
      fval |= SP2[(work >> 24) & 0x3fL];
1138
0
      left ^= fval;
1139
0
      work  = (left << 28) | (left >> 4);
1140
0
      work ^= *keys++;
1141
0
      fval  = SP7[ work     & 0x3fL];
1142
0
      fval |= SP5[(work >>  8) & 0x3fL];
1143
0
      fval |= SP3[(work >> 16) & 0x3fL];
1144
0
      fval |= SP1[(work >> 24) & 0x3fL];
1145
0
      work  = left ^ *keys++;
1146
0
      fval |= SP8[ work     & 0x3fL];
1147
0
      fval |= SP6[(work >>  8) & 0x3fL];
1148
0
      fval |= SP4[(work >> 16) & 0x3fL];
1149
0
      fval |= SP2[(work >> 24) & 0x3fL];
1150
0
      right ^= fval;
1151
0
  }
1152
0
    } else {
1153
0
  keys = &ks->ks[30];
1154
1155
0
  for( round = 0; round < 8; round++ ) {
1156
0
      work  = (right << 28) | (right >> 4);
1157
0
      work ^= *keys++;
1158
0
      fval  = SP7[ work     & 0x3fL];
1159
0
      fval |= SP5[(work >>  8) & 0x3fL];
1160
0
      fval |= SP3[(work >> 16) & 0x3fL];
1161
0
      fval |= SP1[(work >> 24) & 0x3fL];
1162
0
      work  = right ^ *keys++;
1163
0
      fval |= SP8[ work     & 0x3fL];
1164
0
      fval |= SP6[(work >>  8) & 0x3fL];
1165
0
      fval |= SP4[(work >> 16) & 0x3fL];
1166
0
      fval |= SP2[(work >> 24) & 0x3fL];
1167
0
      left ^= fval;
1168
0
      work  = (left << 28) | (left >> 4);
1169
0
      keys -= 4;
1170
0
      work ^= *keys++;
1171
0
      fval  = SP7[ work     & 0x3fL];
1172
0
      fval |= SP5[(work >>  8) & 0x3fL];
1173
0
      fval |= SP3[(work >> 16) & 0x3fL];
1174
0
      fval |= SP1[(work >> 24) & 0x3fL];
1175
0
      work  = left ^ *keys++;
1176
0
      fval |= SP8[ work     & 0x3fL];
1177
0
      fval |= SP6[(work >>  8) & 0x3fL];
1178
0
      fval |= SP4[(work >> 16) & 0x3fL];
1179
0
      fval |= SP2[(work >> 24) & 0x3fL];
1180
0
      right ^= fval;
1181
0
      keys -= 4;
1182
0
  }
1183
0
    }
1184
0
    block[0] = right;
1185
0
    block[1] = left;
1186
0
}