Line data Source code
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 : if (one) { \
103 : x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \
104 : } else { \
105 : x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \
106 : }
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 89406 : DES_set_odd_parity(DES_cblock *key)
118 : {
119 4530 : unsigned int i;
120 804654 : for (i = 0; i < DES_CBLOCK_LEN; i++)
121 715248 : (*key)[i] = odd_parity[(*key)[i]];
122 89406 : }
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 0 : DES_check_key_parity(DES_cblock *key)
134 : {
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 : }
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 0 : DES_is_weak_key(DES_cblock *key)
179 : {
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 : }
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 0 : DES_set_key(DES_cblock *key, DES_key_schedule *ks)
202 : {
203 0 : return DES_set_key_checked(key, ks);
204 : }
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 89406 : DES_set_key_unchecked(DES_cblock *key, DES_key_schedule *ks)
221 : {
222 4530 : uint32_t t1, t2;
223 4530 : uint32_t c, d;
224 89406 : int shifts[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
225 89406 : uint32_t *k = &ks->ks[0];
226 4530 : int i;
227 :
228 89406 : t1 = (uint32_t)((*key)[0]) << 24
229 89406 : | (uint32_t)((*key)[1]) << 16
230 89406 : | (uint32_t)((*key)[2]) << 8
231 89406 : | (*key)[3];
232 89406 : t2 = (uint32_t)((*key)[4]) << 24
233 89406 : | (uint32_t)((*key)[5]) << 16
234 89406 : | (uint32_t)((*key)[6]) << 8
235 89406 : | (*key)[7];
236 :
237 89406 : c = (pc1_c_3[(t1 >> (5 )) & 0x7] << 3)
238 89406 : | (pc1_c_3[(t1 >> (5 + 8 )) & 0x7] << 2)
239 89406 : | (pc1_c_3[(t1 >> (5 + 8 + 8 )) & 0x7] << 1)
240 89406 : | (pc1_c_3[(t1 >> (5 + 8 + 8 + 8)) & 0x7] << 0)
241 89406 : | (pc1_c_4[(t2 >> (4 )) & 0xf] << 3)
242 89406 : | (pc1_c_4[(t2 >> (4 + 8 )) & 0xf] << 2)
243 89406 : | (pc1_c_4[(t2 >> (4 + 8 + 8 )) & 0xf] << 1)
244 89406 : | (pc1_c_4[(t2 >> (4 + 8 + 8 + 8)) & 0xf] << 0);
245 :
246 :
247 89406 : d = (pc1_d_3[(t2 >> (1 )) & 0x7] << 3)
248 89406 : | (pc1_d_3[(t2 >> (1 + 8 )) & 0x7] << 2)
249 89406 : | (pc1_d_3[(t2 >> (1 + 8 + 8 )) & 0x7] << 1)
250 89406 : | (pc1_d_3[(t2 >> (1 + 8 + 8 + 8)) & 0x7] << 0)
251 89406 : | (pc1_d_4[(t1 >> (1 )) & 0xf] << 3)
252 89406 : | (pc1_d_4[(t1 >> (1 + 8 )) & 0xf] << 2)
253 89406 : | (pc1_d_4[(t1 >> (1 + 8 + 8 )) & 0xf] << 1)
254 89406 : | (pc1_d_4[(t1 >> (1 + 8 + 8 + 8)) & 0xf] << 0);
255 :
256 1519902 : for (i = 0; i < 16; i++) {
257 72480 : uint32_t kc, kd;
258 :
259 1430496 : ROTATE_LEFT28(c, shifts[i]);
260 1430496 : ROTATE_LEFT28(d, shifts[i]);
261 :
262 1430496 : kc = pc2_c_1[(c >> 22) & 0x3f] |
263 1430496 : pc2_c_2[((c >> 16) & 0x30) | ((c >> 15) & 0xf)] |
264 1430496 : pc2_c_3[((c >> 9 ) & 0x3c) | ((c >> 8 ) & 0x3)] |
265 1430496 : pc2_c_4[((c >> 2 ) & 0x20) | ((c >> 1) & 0x18) | (c & 0x7)];
266 1430496 : kd = pc2_d_1[(d >> 22) & 0x3f] |
267 1430496 : pc2_d_2[((d >> 15) & 0x30) | ((d >> 14) & 0xf)] |
268 1430496 : pc2_d_3[ (d >> 7 ) & 0x3f] |
269 1430496 : pc2_d_4[((d >> 1 ) & 0x3c) | ((d ) & 0x3)];
270 :
271 : /* Change to byte order used by the S boxes */
272 1430496 : *k = (kc & 0x00fc0000L) << 6;
273 1430496 : *k |= (kc & 0x00000fc0L) << 10;
274 1430496 : *k |= (kd & 0x00fc0000L) >> 10;
275 1430496 : *k++ |= (kd & 0x00000fc0L) >> 6;
276 1430496 : *k = (kc & 0x0003f000L) << 12;
277 1430496 : *k |= (kc & 0x0000003fL) << 16;
278 1430496 : *k |= (kd & 0x0003f000L) >> 4;
279 1430496 : *k++ |= (kd & 0x0000003fL);
280 : }
281 :
282 89406 : 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 0 : DES_set_key_checked(DES_cblock *key, DES_key_schedule *ks)
298 : {
299 0 : if (!DES_check_key_parity(key)) {
300 0 : memset(ks, 0, sizeof(*ks));
301 0 : return -1;
302 : }
303 0 : if (DES_is_weak_key(key)) {
304 0 : memset(ks, 0, sizeof(*ks));
305 0 : return -2;
306 : }
307 0 : 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 0 : DES_key_sched(DES_cblock *key, DES_key_schedule *ks)
323 : {
324 0 : return DES_set_key_checked(key, ks);
325 : }
326 :
327 : /*
328 : *
329 : */
330 :
331 : static void
332 91034 : load(const unsigned char *b, uint32_t v[2])
333 : {
334 91034 : v[0] = (uint32_t)(b[0]) << 24;
335 91034 : v[0] |= (uint32_t)(b[1]) << 16;
336 91034 : v[0] |= (uint32_t)(b[2]) << 8;
337 91034 : v[0] |= b[3];
338 91034 : v[1] = (uint32_t)(b[4]) << 24;
339 91034 : v[1] |= (uint32_t)(b[5]) << 16;
340 91034 : v[1] |= (uint32_t)(b[6]) << 8;
341 91034 : v[1] |= b[7];
342 91034 : }
343 :
344 : static void
345 91034 : store(const uint32_t v[2], unsigned char *b)
346 : {
347 91034 : b[0] = (v[0] >> 24) & 0xffU;
348 91034 : b[1] = (v[0] >> 16) & 0xffU;
349 91034 : b[2] = (v[0] >> 8) & 0xffU;
350 91034 : b[3] = (v[0] >> 0) & 0xffU;
351 91034 : b[4] = (v[1] >> 24) & 0xffU;
352 91034 : b[5] = (v[1] >> 16) & 0xffU;
353 91034 : b[6] = (v[1] >> 8) & 0xffU;
354 91034 : b[7] = (v[1] >> 0) & 0xffU;
355 86504 : }
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 0 : DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int encp)
369 : {
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 0 : DES_ecb_encrypt(DES_cblock *input, DES_cblock *output,
388 : DES_key_schedule *ks, int encp)
389 : {
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 0 : DES_cbc_encrypt(const void *in, void *out, long length,
413 : DES_key_schedule *ks, DES_cblock *iv, int encp)
414 : {
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 : }
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 : }
443 : } else {
444 : 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 : }
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 : }
466 : }
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 0 : DES_pcbc_encrypt(const void *in, void *out, long length,
489 : DES_key_schedule *ks, DES_cblock *iv, int encp)
490 : {
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 : 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 : }
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 : }
521 : } else {
522 : 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 : }
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 : }
543 : }
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 61232 : _des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2,
553 : DES_key_schedule *ks3, int encp)
554 : {
555 61232 : IP(u);
556 61232 : if (encp) {
557 31434 : desx(u, ks1, 1); /* IP + FP cancel out each other */
558 31434 : desx(u, ks2, 0);
559 31434 : desx(u, ks3, 1);
560 : } else {
561 29798 : desx(u, ks3, 0);
562 29798 : desx(u, ks2, 1);
563 29798 : desx(u, ks1, 0);
564 : }
565 61232 : FP(u);
566 61232 : }
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 0 : 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 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 : }
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 29802 : 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 29802 : const unsigned char *input = in;
621 29802 : unsigned char *output = out;
622 1510 : uint32_t u[2];
623 1510 : uint32_t uiv[2];
624 :
625 29802 : load(*iv, uiv);
626 :
627 29802 : if (encp) {
628 46337 : while (length >= DES_CBLOCK_LEN) {
629 31434 : load(input, u);
630 31434 : u[0] ^= uiv[0]; u[1] ^= uiv[1];
631 31434 : _des3_encrypt(u, ks1, ks2, ks3, 1);
632 31434 : uiv[0] = u[0]; uiv[1] = u[1];
633 31434 : store(u, output);
634 :
635 31434 : length -= DES_CBLOCK_LEN;
636 31434 : input += DES_CBLOCK_LEN;
637 31434 : output += DES_CBLOCK_LEN;
638 : }
639 14903 : 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 : }
648 : } else {
649 : uint32_t t[2];
650 44697 : while (length >= DES_CBLOCK_LEN) {
651 29798 : load(input, u);
652 29798 : t[0] = u[0]; t[1] = u[1];
653 29798 : _des3_encrypt(u, ks1, ks2, ks3, 0);
654 29798 : u[0] ^= uiv[0]; u[1] ^= uiv[1];
655 29798 : store(u, output);
656 29798 : uiv[0] = t[0]; uiv[1] = t[1];
657 :
658 29798 : length -= DES_CBLOCK_LEN;
659 29798 : input += DES_CBLOCK_LEN;
660 29798 : output += DES_CBLOCK_LEN;
661 : }
662 14899 : 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 : }
671 : }
672 29802 : store(uiv, *iv);
673 29802 : uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
674 29802 : }
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 0 : 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 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 : }
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 : }
725 0 : store(uiv, *iv);
726 0 : *num = i;
727 : } 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 : }
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 : }
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 : }
749 : }
750 0 : store(uiv, *iv);
751 0 : *num = i;
752 : }
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 0 : DES_cbc_cksum(const void *in, DES_cblock *output,
772 : long length, DES_key_schedule *ks, DES_cblock *iv)
773 : {
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 : }
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 : }
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 : }
803 :
804 : /*
805 : *
806 : */
807 :
808 : static unsigned char
809 0 : bitswap8(unsigned char b)
810 : {
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 : }
817 0 : return r;
818 : }
819 :
820 : /**
821 : * Convert a string to a DES key. Use something like
822 : * PKCS5_PBKDF2_HMAC_SHA1() to create key from passwords.
823 : *
824 : * @param str The string to convert to a key
825 : * @param key the resulting key
826 : *
827 : * @ingroup hcrypto_des
828 : */
829 :
830 : void
831 0 : DES_string_to_key(const char *str, DES_cblock *key)
832 : {
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 : else
847 0 : k[7 - (i % 8)] ^= bitswap8(s[i]);
848 : }
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 0 : DES_read_password(DES_cblock *key, char *prompt, int verify)
874 : {
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 : }
883 :
884 : /*
885 : *
886 : */
887 :
888 :
889 : void
890 0 : _DES_ipfp_test(void)
891 : {
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 61232 : IP(uint32_t v[2])
1067 : {
1068 3020 : uint32_t work;
1069 :
1070 61232 : work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
1071 61232 : v[1] ^= work;
1072 61232 : v[0] ^= (work << 4);
1073 61232 : work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
1074 61232 : v[1] ^= work;
1075 61232 : v[0] ^= (work << 16);
1076 61232 : work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
1077 61232 : v[0] ^= work;
1078 61232 : v[1] ^= (work << 2);
1079 61232 : work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
1080 61232 : v[0] ^= work;
1081 61232 : v[1] ^= (work << 8);
1082 61232 : v[1] = ((v[1] << 1) | ((v[1] >> 31) & 1L)) & 0xffffffffL;
1083 61232 : work = (v[0] ^ v[1]) & 0xaaaaaaaaL;
1084 61232 : v[0] ^= work;
1085 61232 : v[1] ^= work;
1086 61232 : v[0] = ((v[0] << 1) | ((v[0] >> 31) & 1L)) & 0xffffffffL;
1087 61232 : }
1088 :
1089 : static void
1090 61232 : FP(uint32_t v[2])
1091 : {
1092 3020 : uint32_t work;
1093 :
1094 61232 : v[0] = (v[0] << 31) | (v[0] >> 1);
1095 61232 : work = (v[1] ^ v[0]) & 0xaaaaaaaaL;
1096 61232 : v[1] ^= work;
1097 61232 : v[0] ^= work;
1098 61232 : v[1] = (v[1] << 31) | (v[1] >> 1);
1099 61232 : work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
1100 61232 : v[0] ^= work;
1101 61232 : v[1] ^= (work << 8);
1102 61232 : work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
1103 61232 : v[0] ^= work;
1104 61232 : v[1] ^= (work << 2);
1105 61232 : work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
1106 61232 : v[1] ^= work;
1107 61232 : v[0] ^= (work << 16);
1108 61232 : work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
1109 61232 : v[1] ^= work;
1110 61232 : v[0] ^= (work << 4);
1111 61232 : }
1112 :
1113 : static void
1114 183696 : desx(uint32_t block[2], DES_key_schedule *ks, int encp)
1115 : {
1116 9060 : uint32_t *keys;
1117 9060 : uint32_t fval, work, right, left;
1118 9060 : int round;
1119 :
1120 183696 : left = block[0];
1121 183696 : right = block[1];
1122 :
1123 183696 : if (encp) {
1124 92666 : keys = &ks->ks[0];
1125 :
1126 833994 : for( round = 0; round < 8; round++ ) {
1127 741328 : work = (right << 28) | (right >> 4);
1128 741328 : work ^= *keys++;
1129 741328 : fval = SP7[ work & 0x3fL];
1130 741328 : fval |= SP5[(work >> 8) & 0x3fL];
1131 741328 : fval |= SP3[(work >> 16) & 0x3fL];
1132 741328 : fval |= SP1[(work >> 24) & 0x3fL];
1133 741328 : work = right ^ *keys++;
1134 741328 : fval |= SP8[ work & 0x3fL];
1135 741328 : fval |= SP6[(work >> 8) & 0x3fL];
1136 741328 : fval |= SP4[(work >> 16) & 0x3fL];
1137 741328 : fval |= SP2[(work >> 24) & 0x3fL];
1138 741328 : left ^= fval;
1139 741328 : work = (left << 28) | (left >> 4);
1140 741328 : work ^= *keys++;
1141 741328 : fval = SP7[ work & 0x3fL];
1142 741328 : fval |= SP5[(work >> 8) & 0x3fL];
1143 741328 : fval |= SP3[(work >> 16) & 0x3fL];
1144 741328 : fval |= SP1[(work >> 24) & 0x3fL];
1145 741328 : work = left ^ *keys++;
1146 741328 : fval |= SP8[ work & 0x3fL];
1147 741328 : fval |= SP6[(work >> 8) & 0x3fL];
1148 741328 : fval |= SP4[(work >> 16) & 0x3fL];
1149 741328 : fval |= SP2[(work >> 24) & 0x3fL];
1150 741328 : right ^= fval;
1151 : }
1152 : } else {
1153 91030 : keys = &ks->ks[30];
1154 :
1155 819270 : for( round = 0; round < 8; round++ ) {
1156 728240 : work = (right << 28) | (right >> 4);
1157 728240 : work ^= *keys++;
1158 728240 : fval = SP7[ work & 0x3fL];
1159 728240 : fval |= SP5[(work >> 8) & 0x3fL];
1160 728240 : fval |= SP3[(work >> 16) & 0x3fL];
1161 728240 : fval |= SP1[(work >> 24) & 0x3fL];
1162 728240 : work = right ^ *keys++;
1163 728240 : fval |= SP8[ work & 0x3fL];
1164 728240 : fval |= SP6[(work >> 8) & 0x3fL];
1165 728240 : fval |= SP4[(work >> 16) & 0x3fL];
1166 728240 : fval |= SP2[(work >> 24) & 0x3fL];
1167 728240 : left ^= fval;
1168 728240 : work = (left << 28) | (left >> 4);
1169 728240 : keys -= 4;
1170 728240 : work ^= *keys++;
1171 728240 : fval = SP7[ work & 0x3fL];
1172 728240 : fval |= SP5[(work >> 8) & 0x3fL];
1173 728240 : fval |= SP3[(work >> 16) & 0x3fL];
1174 728240 : fval |= SP1[(work >> 24) & 0x3fL];
1175 728240 : work = left ^ *keys++;
1176 728240 : fval |= SP8[ work & 0x3fL];
1177 728240 : fval |= SP6[(work >> 8) & 0x3fL];
1178 728240 : fval |= SP4[(work >> 16) & 0x3fL];
1179 728240 : fval |= SP2[(work >> 24) & 0x3fL];
1180 728240 : right ^= fval;
1181 728240 : keys -= 4;
1182 : }
1183 : }
1184 183696 : block[0] = right;
1185 183696 : block[1] = left;
1186 183696 : }
|