]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libstrongswan/plugins/des/des_crypter.c
Fixed some typos, courtesy of codespell
[thirdparty/strongswan.git] / src / libstrongswan / plugins / des / des_crypter.c
CommitLineData
7b767025
TB
1/*
2 * Copyright (C) 2009 Tobias Brunner
3 * Copyright (C) 2006 Martin Willi
462129d3
MW
4 * Hochschule fuer Technik Rapperswil
5 *
6 * Derived from Plutos DES library by Eric Young.
7 *
8 * Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
9 * All rights reserved.
10 *
11 * This package is an SSL implementation written
12 * by Eric Young (eay@cryptsoft.com).
13 * The implementation was written so as to conform with Netscapes SSL.
7daf5226 14 *
462129d3 15 * This library is free for commercial and non-commercial use as long as
2db6d5b8 16 * the following conditions are adhered to.
7daf5226 17 *
462129d3
MW
18 * Copyright remains Eric Young's, and as such any Copyright notices in
19 * the code are not to be removed.
20 * If this package is used in a product, Eric Young should be given attribution
21 * as the author of the parts of the library used.
22 * This can be in the form of a textual message at program startup or
23 * in documentation (online or textual) provided with the package.
7daf5226 24 *
462129d3
MW
25 * Redistribution and use in source and binary forms, with or without
26 * modification, are permitted provided that the following conditions
27 * are met:
28 * 1. Redistributions of source code must retain the copyright
29 * notice, this list of conditions and the following disclaimer.
30 * 2. Redistributions in binary form must reproduce the above copyright
31 * notice, this list of conditions and the following disclaimer in the
32 * documentation and/or other materials provided with the distribution.
33 * 3. All advertising materials mentioning features or use of this software
34 * must display the following acknowledgement:
35 * "This product includes cryptographic software written by
36 * Eric Young (eay@cryptsoft.com)"
2db6d5b8 37 * The word 'cryptographic' can be left out if the routines from the library
462129d3 38 * being used are not cryptographic related :-).
7daf5226 39 * 4. If you include any Windows specific code (or a derivative thereof) from
462129d3
MW
40 * the apps directory (application code) you must include an acknowledgement:
41 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
7daf5226 42 *
462129d3
MW
43 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 * SUCH DAMAGE.
54 *
55 * The licence and distribution terms for any publically available version or
56 * derivative of this code cannot be changed. i.e. this code cannot simply be
57 * copied and put under another distribution licence
58 * [including the GNU Public Licence.]
59 */
60
61#include "des_crypter.h"
62
b5fd65e9 63typedef u_char des_cblock[DES_BLOCK_SIZE];
462129d3
MW
64
65typedef struct des_ks_struct {
66 des_cblock _;
67} des_key_schedule[16];
68
69
70typedef struct private_des_crypter_t private_des_crypter_t;
71
72/**
73 * Private data for des_crypter_t
74 */
75struct private_des_crypter_t {
7daf5226 76
462129d3
MW
77 /**
78 * Public part of this class.
79 */
80 des_crypter_t public;
7daf5226 81
462129d3 82 /**
f3bb1bd0 83 * Key size, depends on algorithm...
462129d3
MW
84 */
85 size_t key_size;
7daf5226 86
462129d3
MW
87 union {
88 /** key schedule for single des */
89 des_key_schedule ks;
90 /** key schedule for 3des */
91 des_key_schedule ks3[3];
92 };
93};
94
95
96#define DES_ENCRYPT 1
97#define DES_DECRYPT 0
98
b12c53ce 99#define DES_LONG uint32_t
462129d3
MW
100
101#if defined(WIN32) || defined(WIN16)
102#ifndef MSDOS
103#define MSDOS
104#endif
105#endif
106
107#ifndef DES_DEFAULT_OPTIONS
108/* the following is tweaked from a config script, that is why it is a
109 * protected undef/define */
110#ifndef DES_PTR
111#define DES_PTR
112#endif
113
114/* This helps C compiler generate the correct code for multiple functional
7a1fed28 115 * units. It reduces register dependencies at the expense of 2 more
462129d3
MW
116 * registers */
117#ifndef DES_RISC1
118#define DES_RISC1
119#endif
120
121#ifndef DES_RISC2
122#undef DES_RISC2
123#endif
124
125#if defined(DES_RISC1) && defined(DES_RISC2)
126YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
127#endif
128
129/* Unroll the inner loop, this sometimes helps, sometimes hinders.
f3bb1bd0 130 * Very much CPU dependent */
462129d3
MW
131#ifndef DES_UNROLL
132#define DES_UNROLL
133#endif
134
135/* These default values were supplied by
136 * Peter Gutman <pgut001@cs.auckland.ac.nz>
137 * They are only used if nothing else has been defined */
138#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
139/* Special defines which change the way the code is built depending on the
140 CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
141 even newer MIPS CPU's, but at the moment one size fits all for
142 optimization options. Older Sparc's work better with only UNROLL, but
143 there's no way to tell at compile time what it is you're running on */
7daf5226 144
462129d3
MW
145#if defined( sun ) /* Newer Sparc's */
146#define DES_PTR
147#define DES_RISC1
148#define DES_UNROLL
149#elif defined( __ultrix ) /* Older MIPS */
150#define DES_PTR
151#define DES_RISC2
152#define DES_UNROLL
153#elif defined( __osf1__ ) /* Alpha */
154#define DES_PTR
155#define DES_RISC2
156#elif defined ( _AIX ) /* RS6000 */
157 /* Unknown */
158#elif defined( __hpux ) /* HP-PA */
159 /* Unknown */
160#elif defined( __aux ) /* 68K */
161 /* Unknown */
162#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
163#define DES_UNROLL
164#elif defined( __sgi ) /* Newer MIPS */
165#define DES_PTR
166#define DES_RISC2
167#define DES_UNROLL
168#elif defined( i386 ) /* x86 boxes, should be gcc */
169#define DES_PTR
170#define DES_RISC1
171#define DES_UNROLL
172#endif /* Systems-specific speed defines */
173#endif
174
175#endif /* DES_DEFAULT_OPTIONS */
176
177#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */
178#include <stdlib.h>
179#include <errno.h>
180#include <time.h>
181#include <io.h>
182#ifndef RAND
183#define RAND
184#endif
185#undef NOPROTO
186#endif
187
188#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
189#ifndef __KERNEL__
190#include <string.h>
191#else
192#include <linux/string.h>
193#endif
194#endif
195
196#ifndef RAND
197#define RAND
198#endif
199
200#ifdef linux
201#undef RAND
202#endif
203
204#ifdef MSDOS
205#define getpid() 2
206#define RAND
207#undef NOPROTO
208#endif
209
210#if defined(NOCONST)
211#define const
212#endif
213
214#ifdef __STDC__
215#undef NOPROTO
216#endif
217
218#ifdef RAND
219#define srandom(s) srand(s)
220#define random rand
221#endif
222
223#define ITERATIONS 16
224#define HALF_ITERATIONS 8
225
226/* used in des_read and des_write */
227#define MAXWRITE (1024*16)
228#define BSIZE (MAXWRITE+4)
229
230#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \
231 l|=((DES_LONG)(*((c)++)))<< 8L, \
232 l|=((DES_LONG)(*((c)++)))<<16L, \
233 l|=((DES_LONG)(*((c)++)))<<24L)
234
235/* NOTE - c is not incremented as per c2l */
236#define c2ln(c,l1,l2,n) { \
237 c+=n; \
238 l1=l2=0; \
239 switch (n) { \
240 case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
241 case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
242 case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
243 case 5: l2|=((DES_LONG)(*(--(c)))); \
244 case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
245 case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
246 case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
247 case 1: l1|=((DES_LONG)(*(--(c)))); \
248} \
249}
250
251#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
252 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
253 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
254 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
255
256/* replacements for htonl and ntohl since I have no idea what to do
257 * when faced with machines with 8 byte longs. */
258#define HDRSIZE 4
259
260#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \
261 l|=((DES_LONG)(*((c)++)))<<16L, \
262 l|=((DES_LONG)(*((c)++)))<< 8L, \
263 l|=((DES_LONG)(*((c)++))))
264
265#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
266 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
267 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
268 *((c)++)=(unsigned char)(((l) )&0xff))
269
270/* NOTE - c is not incremented as per l2c */
271#define l2cn(l1,l2,c,n) { \
272 c+=n; \
273 switch (n) { \
274 case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
275 case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
276 case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
277 case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
278 case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
279 case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
280 case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
281 case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
282} \
283}
284
285#if defined(WIN32)
286#define ROTATE(a,n) (_lrotr(a,n))
287#else
288#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
289#endif
290
291/* Don't worry about the LOAD_DATA() stuff, that is used by
292 * fcrypt() to add it's little bit to the front */
293
294#ifdef DES_FCRYPT
295
296#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
297{ DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
298
299#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
300 t=R^(R>>16L); \
301 u=t&E0; t&=E1; \
302 tmp=(u<<16); u^=R^s[S ]; u^=tmp; \
303 tmp=(t<<16); t^=R^s[S+1]; t^=tmp
304#else
305#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
306#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
307 u=R^s[S ]; \
308 t=R^s[S+1]
309#endif
310
311/* The changes to this macro may help or hinder, depending on the
2db6d5b8 312 * compiler and the architecture. gcc2 always seems to do well :-).
462129d3
MW
313 * Inspired by Dana How <how@isl.stanford.edu>
314 * DO NOT use the alternative version on machines with 8 byte longs.
315 * It does not seem to work on the Alpha, even when DES_LONG is 4
316 * bytes, probably an issue of accessing non-word aligned objects :-( */
317#ifdef DES_PTR
318
f3bb1bd0 319/* It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there
462129d3
MW
320 * is no reason to not xor all the sub items together. This potentially
321 * saves a register since things can be xored directly into L */
322
323#if defined(DES_RISC1) || defined(DES_RISC2)
324#ifdef DES_RISC1
325#define D_ENCRYPT(LL,R,S) { \
326 unsigned int u1,u2,u3; \
327 LOAD_DATA(R,S,u,t,E0,E1,u1); \
328 u2=(int)u>>8L; \
329 u1=(int)u&0xfc; \
330 u2&=0xfc; \
331 t=ROTATE(t,4); \
332 u>>=16L; \
333 LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
334 LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
335 u3=(int)(u>>8L); \
336 u1=(int)u&0xfc; \
337 u3&=0xfc; \
338 LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
339 LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
340 u2=(int)t>>8L; \
341 u1=(int)t&0xfc; \
342 u2&=0xfc; \
343 t>>=16L; \
344 LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
345 LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
346 u3=(int)t>>8L; \
347 u1=(int)t&0xfc; \
348 u3&=0xfc; \
349 LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
350 LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }
351#endif
352#ifdef DES_RISC2
353#define D_ENCRYPT(LL,R,S) { \
354 unsigned int u1,u2,s1,s2; \
355 LOAD_DATA(R,S,u,t,E0,E1,u1); \
356 u2=(int)u>>8L; \
357 u1=(int)u&0xfc; \
358 u2&=0xfc; \
359 t=ROTATE(t,4); \
360 LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
361 LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
362 s1=(int)(u>>16L); \
363 s2=(int)(u>>24L); \
364 s1&=0xfc; \
365 s2&=0xfc; \
366 LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
367 LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
368 u2=(int)t>>8L; \
369 u1=(int)t&0xfc; \
370 u2&=0xfc; \
371 LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
372 LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
373 s1=(int)(t>>16L); \
374 s2=(int)(t>>24L); \
375 s1&=0xfc; \
376 s2&=0xfc; \
377 LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
378 LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }
379#endif
380#else
381#define D_ENCRYPT(LL,R,S) { \
382 LOAD_DATA_tmp(R,S,u,t,E0,E1); \
383 t=ROTATE(t,4); \
384 LL^= \
385 *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \
386 *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
387 *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
388 *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
389 *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \
390 *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
391 *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
392 *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }
393#endif
394
395#else /* original version */
396
397#if defined(DES_RISC1) || defined(DES_RISC2)
398#ifdef DES_RISC1
399#define D_ENCRYPT(LL,R,S) {\
400 unsigned int u1,u2,u3; \
401 LOAD_DATA(R,S,u,t,E0,E1,u1); \
402 u>>=2L; \
403 t=ROTATE(t,6); \
404 u2=(int)u>>8L; \
405 u1=(int)u&0x3f; \
406 u2&=0x3f; \
407 u>>=16L; \
408 LL^=des_SPtrans[0][u1]; \
409 LL^=des_SPtrans[2][u2]; \
410 u3=(int)u>>8L; \
411 u1=(int)u&0x3f; \
412 u3&=0x3f; \
413 LL^=des_SPtrans[4][u1]; \
414 LL^=des_SPtrans[6][u3]; \
415 u2=(int)t>>8L; \
416 u1=(int)t&0x3f; \
417 u2&=0x3f; \
418 t>>=16L; \
419 LL^=des_SPtrans[1][u1]; \
420 LL^=des_SPtrans[3][u2]; \
421 u3=(int)t>>8L; \
422 u1=(int)t&0x3f; \
423 u3&=0x3f; \
424 LL^=des_SPtrans[5][u1]; \
425 LL^=des_SPtrans[7][u3]; }
426#endif
427#ifdef DES_RISC2
428#define D_ENCRYPT(LL,R,S) {\
429 unsigned int u1,u2,s1,s2; \
430 LOAD_DATA(R,S,u,t,E0,E1,u1); \
431 u>>=2L; \
432 t=ROTATE(t,6); \
433 u2=(int)u>>8L; \
434 u1=(int)u&0x3f; \
435 u2&=0x3f; \
436 LL^=des_SPtrans[0][u1]; \
437 LL^=des_SPtrans[2][u2]; \
438 s1=(int)u>>16L; \
439 s2=(int)u>>24L; \
440 s1&=0x3f; \
441 s2&=0x3f; \
442 LL^=des_SPtrans[4][s1]; \
443 LL^=des_SPtrans[6][s2]; \
444 u2=(int)t>>8L; \
445 u1=(int)t&0x3f; \
446 u2&=0x3f; \
447 LL^=des_SPtrans[1][u1]; \
448 LL^=des_SPtrans[3][u2]; \
449 s1=(int)t>>16; \
450 s2=(int)t>>24L; \
451 s1&=0x3f; \
452 s2&=0x3f; \
453 LL^=des_SPtrans[5][s1]; \
454 LL^=des_SPtrans[7][s2]; }
455#endif
456
457#else
458
459#define D_ENCRYPT(LL,R,S) {\
460 LOAD_DATA_tmp(R,S,u,t,E0,E1); \
461 t=ROTATE(t,4); \
462 LL^=\
463 des_SPtrans[0][(u>> 2L)&0x3f]^ \
464 des_SPtrans[2][(u>>10L)&0x3f]^ \
465 des_SPtrans[4][(u>>18L)&0x3f]^ \
466 des_SPtrans[6][(u>>26L)&0x3f]^ \
467 des_SPtrans[1][(t>> 2L)&0x3f]^ \
468 des_SPtrans[3][(t>>10L)&0x3f]^ \
469 des_SPtrans[5][(t>>18L)&0x3f]^ \
470 des_SPtrans[7][(t>>26L)&0x3f]; }
471#endif
472#endif
473
474 /* IP and FP
475 * The problem is more of a geometric problem that random bit fiddling.
476 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
477 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
478 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
479 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
480
481 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
482 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
483 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
484 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
485
486 The output has been subject to swaps of the form
487 0 1 -> 3 1 but the odd and even bits have been put into
488 2 3 2 0
489 different words. The main trick is to remember that
490 t=((l>>size)^r)&(mask);
491 r^=t;
492 l^=(t<<size);
493 can be used to swap and move bits between words.
494
495 So l = 0 1 2 3 r = 16 17 18 19
496 4 5 6 7 20 21 22 23
497 8 9 10 11 24 25 26 27
498 12 13 14 15 28 29 30 31
499 becomes (for size == 2 and mask == 0x3333)
500 t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
501 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
502 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
503 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
504
505 Thanks for hints from Richard Outerbridge - he told me IP&FP
506 could be done in 15 xor, 10 shifts and 5 ands.
507 When I finally started to think of the problem in 2D
508 I first got ~42 operations without xors. When I remembered
509 how to use xors :-) I got it to its final state.
510 */
511#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
512 (b)^=(t),\
513 (a)^=((t)<<(n)))
514
515#define IP(l,r) \
516{ \
517 register DES_LONG tt; \
518 PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
519 PERM_OP(l,r,tt,16,0x0000ffffL); \
520 PERM_OP(r,l,tt, 2,0x33333333L); \
521 PERM_OP(l,r,tt, 8,0x00ff00ffL); \
522 PERM_OP(r,l,tt, 1,0x55555555L); \
523}
524
525#define FP(l,r) \
526{ \
527 register DES_LONG tt; \
528 PERM_OP(l,r,tt, 1,0x55555555L); \
529 PERM_OP(r,l,tt, 8,0x00ff00ffL); \
530 PERM_OP(l,r,tt, 2,0x33333333L); \
531 PERM_OP(r,l,tt,16,0x0000ffffL); \
532 PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
533}
534
535#ifndef NOPROTO
536void fcrypt_body(DES_LONG *out,des_key_schedule ks,
537 DES_LONG Eswap0, DES_LONG Eswap1);
538#else
539void fcrypt_body();
540#endif
541
542static const DES_LONG des_skb[8][64]={
543 { /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
544 0x00000000L,0x00000010L,0x20000000L,0x20000010L,
545 0x00010000L,0x00010010L,0x20010000L,0x20010010L,
546 0x00000800L,0x00000810L,0x20000800L,0x20000810L,
547 0x00010800L,0x00010810L,0x20010800L,0x20010810L,
548 0x00000020L,0x00000030L,0x20000020L,0x20000030L,
549 0x00010020L,0x00010030L,0x20010020L,0x20010030L,
550 0x00000820L,0x00000830L,0x20000820L,0x20000830L,
551 0x00010820L,0x00010830L,0x20010820L,0x20010830L,
552 0x00080000L,0x00080010L,0x20080000L,0x20080010L,
553 0x00090000L,0x00090010L,0x20090000L,0x20090010L,
554 0x00080800L,0x00080810L,0x20080800L,0x20080810L,
555 0x00090800L,0x00090810L,0x20090800L,0x20090810L,
556 0x00080020L,0x00080030L,0x20080020L,0x20080030L,
557 0x00090020L,0x00090030L,0x20090020L,0x20090030L,
558 0x00080820L,0x00080830L,0x20080820L,0x20080830L,
559 0x00090820L,0x00090830L,0x20090820L,0x20090830L,
560 },
561 { /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
562 0x00000000L,0x02000000L,0x00002000L,0x02002000L,
563 0x00200000L,0x02200000L,0x00202000L,0x02202000L,
564 0x00000004L,0x02000004L,0x00002004L,0x02002004L,
565 0x00200004L,0x02200004L,0x00202004L,0x02202004L,
566 0x00000400L,0x02000400L,0x00002400L,0x02002400L,
567 0x00200400L,0x02200400L,0x00202400L,0x02202400L,
568 0x00000404L,0x02000404L,0x00002404L,0x02002404L,
569 0x00200404L,0x02200404L,0x00202404L,0x02202404L,
570 0x10000000L,0x12000000L,0x10002000L,0x12002000L,
571 0x10200000L,0x12200000L,0x10202000L,0x12202000L,
572 0x10000004L,0x12000004L,0x10002004L,0x12002004L,
573 0x10200004L,0x12200004L,0x10202004L,0x12202004L,
574 0x10000400L,0x12000400L,0x10002400L,0x12002400L,
575 0x10200400L,0x12200400L,0x10202400L,0x12202400L,
576 0x10000404L,0x12000404L,0x10002404L,0x12002404L,
577 0x10200404L,0x12200404L,0x10202404L,0x12202404L,
578 },
579 { /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
580 0x00000000L,0x00000001L,0x00040000L,0x00040001L,
581 0x01000000L,0x01000001L,0x01040000L,0x01040001L,
582 0x00000002L,0x00000003L,0x00040002L,0x00040003L,
583 0x01000002L,0x01000003L,0x01040002L,0x01040003L,
584 0x00000200L,0x00000201L,0x00040200L,0x00040201L,
585 0x01000200L,0x01000201L,0x01040200L,0x01040201L,
586 0x00000202L,0x00000203L,0x00040202L,0x00040203L,
587 0x01000202L,0x01000203L,0x01040202L,0x01040203L,
588 0x08000000L,0x08000001L,0x08040000L,0x08040001L,
589 0x09000000L,0x09000001L,0x09040000L,0x09040001L,
590 0x08000002L,0x08000003L,0x08040002L,0x08040003L,
591 0x09000002L,0x09000003L,0x09040002L,0x09040003L,
592 0x08000200L,0x08000201L,0x08040200L,0x08040201L,
593 0x09000200L,0x09000201L,0x09040200L,0x09040201L,
594 0x08000202L,0x08000203L,0x08040202L,0x08040203L,
595 0x09000202L,0x09000203L,0x09040202L,0x09040203L,
596 },
597 { /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
598 0x00000000L,0x00100000L,0x00000100L,0x00100100L,
599 0x00000008L,0x00100008L,0x00000108L,0x00100108L,
600 0x00001000L,0x00101000L,0x00001100L,0x00101100L,
601 0x00001008L,0x00101008L,0x00001108L,0x00101108L,
602 0x04000000L,0x04100000L,0x04000100L,0x04100100L,
603 0x04000008L,0x04100008L,0x04000108L,0x04100108L,
604 0x04001000L,0x04101000L,0x04001100L,0x04101100L,
605 0x04001008L,0x04101008L,0x04001108L,0x04101108L,
606 0x00020000L,0x00120000L,0x00020100L,0x00120100L,
607 0x00020008L,0x00120008L,0x00020108L,0x00120108L,
608 0x00021000L,0x00121000L,0x00021100L,0x00121100L,
609 0x00021008L,0x00121008L,0x00021108L,0x00121108L,
610 0x04020000L,0x04120000L,0x04020100L,0x04120100L,
611 0x04020008L,0x04120008L,0x04020108L,0x04120108L,
612 0x04021000L,0x04121000L,0x04021100L,0x04121100L,
613 0x04021008L,0x04121008L,0x04021108L,0x04121108L,
614 },
615 { /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
616 0x00000000L,0x10000000L,0x00010000L,0x10010000L,
617 0x00000004L,0x10000004L,0x00010004L,0x10010004L,
618 0x20000000L,0x30000000L,0x20010000L,0x30010000L,
619 0x20000004L,0x30000004L,0x20010004L,0x30010004L,
620 0x00100000L,0x10100000L,0x00110000L,0x10110000L,
621 0x00100004L,0x10100004L,0x00110004L,0x10110004L,
622 0x20100000L,0x30100000L,0x20110000L,0x30110000L,
623 0x20100004L,0x30100004L,0x20110004L,0x30110004L,
624 0x00001000L,0x10001000L,0x00011000L,0x10011000L,
625 0x00001004L,0x10001004L,0x00011004L,0x10011004L,
626 0x20001000L,0x30001000L,0x20011000L,0x30011000L,
627 0x20001004L,0x30001004L,0x20011004L,0x30011004L,
628 0x00101000L,0x10101000L,0x00111000L,0x10111000L,
629 0x00101004L,0x10101004L,0x00111004L,0x10111004L,
630 0x20101000L,0x30101000L,0x20111000L,0x30111000L,
631 0x20101004L,0x30101004L,0x20111004L,0x30111004L,
632 },
633 { /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
634 0x00000000L,0x08000000L,0x00000008L,0x08000008L,
635 0x00000400L,0x08000400L,0x00000408L,0x08000408L,
636 0x00020000L,0x08020000L,0x00020008L,0x08020008L,
637 0x00020400L,0x08020400L,0x00020408L,0x08020408L,
638 0x00000001L,0x08000001L,0x00000009L,0x08000009L,
639 0x00000401L,0x08000401L,0x00000409L,0x08000409L,
640 0x00020001L,0x08020001L,0x00020009L,0x08020009L,
641 0x00020401L,0x08020401L,0x00020409L,0x08020409L,
642 0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
643 0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
644 0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
645 0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
646 0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
647 0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
648 0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
649 0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
650 },
651 { /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
652 0x00000000L,0x00000100L,0x00080000L,0x00080100L,
653 0x01000000L,0x01000100L,0x01080000L,0x01080100L,
654 0x00000010L,0x00000110L,0x00080010L,0x00080110L,
655 0x01000010L,0x01000110L,0x01080010L,0x01080110L,
656 0x00200000L,0x00200100L,0x00280000L,0x00280100L,
657 0x01200000L,0x01200100L,0x01280000L,0x01280100L,
658 0x00200010L,0x00200110L,0x00280010L,0x00280110L,
659 0x01200010L,0x01200110L,0x01280010L,0x01280110L,
660 0x00000200L,0x00000300L,0x00080200L,0x00080300L,
661 0x01000200L,0x01000300L,0x01080200L,0x01080300L,
662 0x00000210L,0x00000310L,0x00080210L,0x00080310L,
663 0x01000210L,0x01000310L,0x01080210L,0x01080310L,
664 0x00200200L,0x00200300L,0x00280200L,0x00280300L,
665 0x01200200L,0x01200300L,0x01280200L,0x01280300L,
666 0x00200210L,0x00200310L,0x00280210L,0x00280310L,
667 0x01200210L,0x01200310L,0x01280210L,0x01280310L,
668 },
669 { /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
670 0x00000000L,0x04000000L,0x00040000L,0x04040000L,
671 0x00000002L,0x04000002L,0x00040002L,0x04040002L,
672 0x00002000L,0x04002000L,0x00042000L,0x04042000L,
673 0x00002002L,0x04002002L,0x00042002L,0x04042002L,
674 0x00000020L,0x04000020L,0x00040020L,0x04040020L,
675 0x00000022L,0x04000022L,0x00040022L,0x04040022L,
676 0x00002020L,0x04002020L,0x00042020L,0x04042020L,
677 0x00002022L,0x04002022L,0x00042022L,0x04042022L,
678 0x00000800L,0x04000800L,0x00040800L,0x04040800L,
679 0x00000802L,0x04000802L,0x00040802L,0x04040802L,
680 0x00002800L,0x04002800L,0x00042800L,0x04042800L,
681 0x00002802L,0x04002802L,0x00042802L,0x04042802L,
682 0x00000820L,0x04000820L,0x00040820L,0x04040820L,
683 0x00000822L,0x04000822L,0x00040822L,0x04040822L,
684 0x00002820L,0x04002820L,0x00042820L,0x04042820L,
685 0x00002822L,0x04002822L,0x00042822L,0x04042822L,
686 }
687};
688
689const DES_LONG des_SPtrans[8][64]={
690 {
691 /* nibble 0 */
692 0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
693 0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
694 0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
695 0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
696 0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
697 0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
698 0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
699 0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
700 0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
701 0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
702 0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
703 0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
704 0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
705 0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
706 0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
707 0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
708 },
709 { /* nibble 1 */
710 0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
711 0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
712 0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
713 0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
714 0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
715 0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
716 0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
717 0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
718 0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
719 0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
720 0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
721 0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
722 0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
723 0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
724 0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
725 0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
726 },
727 { /* nibble 2 */
728 0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
729 0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
730 0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
731 0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
732 0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
733 0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
734 0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
735 0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
736 0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
737 0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
738 0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
739 0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
740 0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
741 0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
742 0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
743 0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
744 },
745 { /* nibble 3 */
746 0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
747 0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
748 0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
749 0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
750 0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
751 0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
752 0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
753 0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
754 0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
755 0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
756 0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
757 0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
758 0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
759 0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
760 0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
761 0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
762 },
763 { /* nibble 4 */
764 0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
765 0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
766 0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
767 0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
768 0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
769 0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
770 0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
771 0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
772 0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
773 0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
774 0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
775 0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
776 0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
777 0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
778 0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
779 0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
780 },
781 { /* nibble 5 */
782 0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
783 0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
784 0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
785 0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
786 0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
787 0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
788 0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
789 0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
790 0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
791 0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
792 0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
793 0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
794 0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
795 0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
796 0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
797 0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
798 },
799 { /* nibble 6 */
800 0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
801 0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
802 0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
803 0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
804 0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
805 0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
806 0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
807 0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
808 0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
809 0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
810 0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
811 0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
812 0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
813 0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
814 0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
815 0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
816 },
817 { /* nibble 7 */
818 0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
819 0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
820 0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
821 0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
822 0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
823 0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
824 0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
825 0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
826 0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
827 0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
828 0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
829 0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
830 0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
831 0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
832 0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
833 0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
834 }
835};
836
837#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
838 (a)=(a)^(t)^(t>>(16-(n))))
839
840static const unsigned char odd_parity[256]={
841 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
842 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
843 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
844 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
845 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
846 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
847 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
848 112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
849 128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
850 145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
851 161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
852 176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
853 193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
854 208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
855 224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
856 241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254
857};
858
859/**
860 * Create key schedule for a single DES 64Bit key
861 */
862static int des_set_key(des_cblock *key, des_key_schedule *schedule)
863{
864 static int shifts2[16] = {0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
865 register DES_LONG c,d,t,s,t2;
866 register unsigned char *in;
867 register DES_LONG *k;
868 register int i;
cbbb71c4 869 des_cblock odd;
462129d3
MW
870
871 for (i = 0; i < sizeof(des_cblock); i++)
872 {
cbbb71c4 873 odd[i] = odd_parity[(*key)[i]];
462129d3
MW
874 }
875
876 k=(DES_LONG *)schedule;
cbbb71c4 877 in=(unsigned char *)&odd;
462129d3
MW
878
879 c2l(in,c);
880 c2l(in,d);
881
7daf5226 882 /* do PC1 in 60 simple operations */
462129d3
MW
883/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
884 HPERM_OP(c,t,-2, 0xcccc0000L);
885 HPERM_OP(c,t,-1, 0xaaaa0000L);
886 HPERM_OP(c,t, 8, 0x00ff0000L);
887 HPERM_OP(c,t,-1, 0xaaaa0000L);
888 HPERM_OP(d,t,-8, 0xff000000L);
889 HPERM_OP(d,t, 8, 0x00ff0000L);
890 HPERM_OP(d,t, 2, 0x33330000L);
891 d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
892 d=(d>>8)|((c&0xf0000000L)>>4);
893 c&=0x0fffffffL; */
894
895 /* I now do it in 47 simple operations :-)
896 * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
897 * for the inspiration. :-) */
898 PERM_OP (d,c,t,4,0x0f0f0f0fL);
899 HPERM_OP(c,t,-2,0xcccc0000L);
900 HPERM_OP(d,t,-2,0xcccc0000L);
901 PERM_OP (d,c,t,1,0x55555555L);
902 PERM_OP (c,d,t,8,0x00ff00ffL);
903 PERM_OP (d,c,t,1,0x55555555L);
904 d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
905 ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
906 c&=0x0fffffffL;
907
908 for (i=0; i<ITERATIONS; i++)
909 {
910 if (shifts2[i])
911 { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
912 else
913 { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
914 c&=0x0fffffffL;
915 d&=0x0fffffffL;
916 /* could be a few less shifts but I am to lazy at this
917 * point in time to investigate */
918 s= des_skb[0][ (c )&0x3f ]|
919 des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
920 des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
921 des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
922 ((c>>22L)&0x38)];
923 t= des_skb[4][ (d )&0x3f ]|
924 des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
925 des_skb[6][ (d>>15L)&0x3f ]|
926 des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
927
928 /* table contained 0213 4657 */
929 t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
930 *(k++)=ROTATE(t2,30)&0xffffffffL;
931
932 t2=((s>>16L)|(t&0xffff0000L));
933 *(k++)=ROTATE(t2,26)&0xffffffffL;
934 }
935 return(0);
936}
937
938
939static void des_encrypt(DES_LONG *data, des_key_schedule ks, int enc)
940{
941 register DES_LONG l,r,t,u;
942#ifdef DES_PTR
943 register unsigned char *des_SP=(unsigned char *)des_SPtrans;
944#endif
945#ifndef DES_UNROLL
946 register int i;
947#endif
948 register DES_LONG *s;
949
950 r=data[0];
951 l=data[1];
952
953 IP(r,l);
954 /* Things have been modified so that the initial rotate is
955 * done outside the loop. This required the
956 * des_SPtrans values in sp.h to be rotated 1 bit to the right.
957 * One perl script later and things have a 5% speed up on a sparc2.
958 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
959 * for pointing this out. */
960 /* clear the top bits on machines with 8byte longs */
961 /* shift left by 2 */
962 r=ROTATE(r,29)&0xffffffffL;
963 l=ROTATE(l,29)&0xffffffffL;
964
965 s=(DES_LONG *)ks;
966 /* I don't know if it is worth the effort of loop unrolling the
967 * inner loop */
968 if (enc)
969 {
970#ifdef DES_UNROLL
971 D_ENCRYPT(l,r, 0); /* 1 */
972 D_ENCRYPT(r,l, 2); /* 2 */
973 D_ENCRYPT(l,r, 4); /* 3 */
974 D_ENCRYPT(r,l, 6); /* 4 */
975 D_ENCRYPT(l,r, 8); /* 5 */
976 D_ENCRYPT(r,l,10); /* 6 */
977 D_ENCRYPT(l,r,12); /* 7 */
978 D_ENCRYPT(r,l,14); /* 8 */
979 D_ENCRYPT(l,r,16); /* 9 */
980 D_ENCRYPT(r,l,18); /* 10 */
981 D_ENCRYPT(l,r,20); /* 11 */
982 D_ENCRYPT(r,l,22); /* 12 */
983 D_ENCRYPT(l,r,24); /* 13 */
984 D_ENCRYPT(r,l,26); /* 14 */
985 D_ENCRYPT(l,r,28); /* 15 */
986 D_ENCRYPT(r,l,30); /* 16 */
987#else
988 for (i=0; i<32; i+=8)
989{
990 D_ENCRYPT(l,r,i+0); /* 1 */
991 D_ENCRYPT(r,l,i+2); /* 2 */
992 D_ENCRYPT(l,r,i+4); /* 3 */
993 D_ENCRYPT(r,l,i+6); /* 4 */
994}
995#endif
996 }
997 else
998{
999#ifdef DES_UNROLL
1000 D_ENCRYPT(l,r,30); /* 16 */
1001 D_ENCRYPT(r,l,28); /* 15 */
1002 D_ENCRYPT(l,r,26); /* 14 */
1003 D_ENCRYPT(r,l,24); /* 13 */
1004 D_ENCRYPT(l,r,22); /* 12 */
1005 D_ENCRYPT(r,l,20); /* 11 */
1006 D_ENCRYPT(l,r,18); /* 10 */
1007 D_ENCRYPT(r,l,16); /* 9 */
1008 D_ENCRYPT(l,r,14); /* 8 */
1009 D_ENCRYPT(r,l,12); /* 7 */
1010 D_ENCRYPT(l,r,10); /* 6 */
1011 D_ENCRYPT(r,l, 8); /* 5 */
1012 D_ENCRYPT(l,r, 6); /* 4 */
1013 D_ENCRYPT(r,l, 4); /* 3 */
1014 D_ENCRYPT(l,r, 2); /* 2 */
1015 D_ENCRYPT(r,l, 0); /* 1 */
1016#else
1017 for (i=30; i>0; i-=8)
1018{
1019 D_ENCRYPT(l,r,i-0); /* 16 */
1020 D_ENCRYPT(r,l,i-2); /* 15 */
1021 D_ENCRYPT(l,r,i-4); /* 14 */
1022 D_ENCRYPT(r,l,i-6); /* 13 */
1023}
1024#endif
1025}
1026
1027 /* rotate and clear the top bits on machines with 8byte longs */
1028 l=ROTATE(l,3)&0xffffffffL;
1029 r=ROTATE(r,3)&0xffffffffL;
1030
1031 FP(r,l);
1032 data[0]=l;
1033 data[1]=r;
1034 l=r=t=u=0;
1035}
1036
1037/**
1038 * DES CBC encrypt decrypt routine
1039 */
7daf5226 1040static void des_cbc_encrypt(des_cblock *input, des_cblock *output, long length,
462129d3
MW
1041 des_key_schedule schedule, des_cblock *ivec, int enc)
1042{
1043 register DES_LONG tin0,tin1;
1044 register DES_LONG tout0,tout1,xor0,xor1;
1045 register unsigned char *in,*out;
1046 register long l=length;
1047 DES_LONG tin[2];
1048 unsigned char *iv;
1049
1050 in=(unsigned char *)input;
1051 out=(unsigned char *)output;
1052 iv=(unsigned char *)ivec;
1053
1054 if (enc)
1055 {
1056 c2l(iv,tout0);
1057 c2l(iv,tout1);
1058 for (l-=8; l>=0; l-=8)
1059 {
1060 c2l(in,tin0);
1061 c2l(in,tin1);
1062 tin0^=tout0; tin[0]=tin0;
1063 tin1^=tout1; tin[1]=tin1;
1064 des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
1065 tout0=tin[0]; l2c(tout0,out);
1066 tout1=tin[1]; l2c(tout1,out);
1067 }
1068 if (l != -8)
1069 {
1070 c2ln(in,tin0,tin1,l+8);
1071 tin0^=tout0; tin[0]=tin0;
1072 tin1^=tout1; tin[1]=tin1;
1073 des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
1074 tout0=tin[0]; l2c(tout0,out);
1075 tout1=tin[1]; l2c(tout1,out);
1076 }
1077 }
1078 else
1079 {
1080 c2l(iv,xor0);
1081 c2l(iv,xor1);
1082 for (l-=8; l>=0; l-=8)
1083 {
1084 c2l(in,tin0); tin[0]=tin0;
1085 c2l(in,tin1); tin[1]=tin1;
1086 des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
1087 tout0=tin[0]^xor0;
1088 tout1=tin[1]^xor1;
1089 l2c(tout0,out);
1090 l2c(tout1,out);
1091 xor0=tin0;
1092 xor1=tin1;
1093 }
1094 if (l != -8)
1095 {
1096 c2l(in,tin0); tin[0]=tin0;
1097 c2l(in,tin1); tin[1]=tin1;
1098 des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
1099 tout0=tin[0]^xor0;
1100 tout1=tin[1]^xor1;
1101 l2cn(tout0,tout1,out,l+8);
1102 /* xor0=tin0;
1103 xor1=tin1; */
1104 }
1105 }
1106 tin0=tin1=tout0=tout1=xor0=xor1=0;
1107 tin[0]=tin[1]=0;
1108}
1109
7b767025
TB
1110/**
1111 * DES ECB encrypt decrypt routine
1112 */
7daf5226 1113static void des_ecb_encrypt(des_cblock *input, des_cblock *output, long length,
7b767025
TB
1114 des_key_schedule schedule, int enc)
1115{
1116 register DES_LONG tin0,tin1;
1117 register DES_LONG tout0,tout1;
1118 register unsigned char *in,*out;
1119 register long l=length;
1120 DES_LONG tin[2];
1121
1122 in=(unsigned char *)input;
1123 out=(unsigned char *)output;
1124
1125 if (enc)
1126 {
1127 for (l-=8; l>=0; l-=8)
1128 {
6e7c0b1e
TB
1129 c2l(in,tin0); tin[0]=tin0;
1130 c2l(in,tin1); tin[1]=tin1;
7b767025
TB
1131 des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
1132 tout0=tin[0]; l2c(tout0,out);
1133 tout1=tin[1]; l2c(tout1,out);
1134 }
1135 if (l != -8)
1136 {
1137 c2ln(in,tin0,tin1,l+8);
1138 tin[0]=tin0;
1139 tin[1]=tin1;
1140 des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
1141 tout0=tin[0]; l2c(tout0,out);
1142 tout1=tin[1]; l2c(tout1,out);
1143 }
1144 }
1145 else
1146 {
1147 for (l-=8; l>=0; l-=8)
1148 {
1149 c2l(in,tin0); tin[0]=tin0;
1150 c2l(in,tin1); tin[1]=tin1;
1151 des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
6e7c0b1e
TB
1152 tout0=tin[0]; l2c(tout0,out);
1153 tout1=tin[1]; l2c(tout1,out);
7b767025
TB
1154 }
1155 if (l != -8)
1156 {
1157 c2l(in,tin0); tin[0]=tin0;
1158 c2l(in,tin1); tin[1]=tin1;
1159 des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
6e7c0b1e
TB
1160 tout0=tin[0];
1161 tout1=tin[1];
7b767025
TB
1162 l2cn(tout0,tout1,out,l+8);
1163 }
1164 }
1165 tin0=tin1=tout0=tout1=0;
1166 tin[0]=tin[1]=0;
1167}
1168
462129d3
MW
1169static void des_encrypt2(DES_LONG *data, des_key_schedule ks, int enc)
1170{
1171 register DES_LONG l,r,t,u;
1172#ifdef DES_PTR
1173 register unsigned char *des_SP=(unsigned char *)des_SPtrans;
1174#endif
1175#ifndef DES_UNROLL
1176 register int i;
1177#endif
1178 register DES_LONG *s;
1179
1180 r=data[0];
1181 l=data[1];
1182
1183 /* Things have been modified so that the initial rotate is
1184 * done outside the loop. This required the
1185 * des_SPtrans values in sp.h to be rotated 1 bit to the right.
1186 * One perl script later and things have a 5% speed up on a sparc2.
1187 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
1188 * for pointing this out.
1189 * clear the top bits on machines with 8byte longs */
1190 r=ROTATE(r,29)&0xffffffffL;
1191 l=ROTATE(l,29)&0xffffffffL;
1192
1193 s=(DES_LONG *)ks;
1194 /* I don't know if it is worth the effort of loop unrolling the
1195 * inner loop */
1196 if (enc)
1197 {
1198#ifdef DES_UNROLL
1199 D_ENCRYPT(l,r, 0); /* 1 */
1200 D_ENCRYPT(r,l, 2); /* 2 */
1201 D_ENCRYPT(l,r, 4); /* 3 */
1202 D_ENCRYPT(r,l, 6); /* 4 */
1203 D_ENCRYPT(l,r, 8); /* 5 */
1204 D_ENCRYPT(r,l,10); /* 6 */
1205 D_ENCRYPT(l,r,12); /* 7 */
1206 D_ENCRYPT(r,l,14); /* 8 */
1207 D_ENCRYPT(l,r,16); /* 9 */
1208 D_ENCRYPT(r,l,18); /* 10 */
1209 D_ENCRYPT(l,r,20); /* 11 */
1210 D_ENCRYPT(r,l,22); /* 12 */
1211 D_ENCRYPT(l,r,24); /* 13 */
1212 D_ENCRYPT(r,l,26); /* 14 */
1213 D_ENCRYPT(l,r,28); /* 15 */
1214 D_ENCRYPT(r,l,30); /* 16 */
1215#else
1216 for (i=0; i<32; i+=8)
1217{
1218 D_ENCRYPT(l,r,i+0); /* 1 */
1219 D_ENCRYPT(r,l,i+2); /* 2 */
1220 D_ENCRYPT(l,r,i+4); /* 3 */
1221 D_ENCRYPT(r,l,i+6); /* 4 */
1222}
1223#endif
1224 }
1225 else
1226{
1227#ifdef DES_UNROLL
1228 D_ENCRYPT(l,r,30); /* 16 */
1229 D_ENCRYPT(r,l,28); /* 15 */
1230 D_ENCRYPT(l,r,26); /* 14 */
1231 D_ENCRYPT(r,l,24); /* 13 */
1232 D_ENCRYPT(l,r,22); /* 12 */
1233 D_ENCRYPT(r,l,20); /* 11 */
1234 D_ENCRYPT(l,r,18); /* 10 */
1235 D_ENCRYPT(r,l,16); /* 9 */
1236 D_ENCRYPT(l,r,14); /* 8 */
1237 D_ENCRYPT(r,l,12); /* 7 */
1238 D_ENCRYPT(l,r,10); /* 6 */
1239 D_ENCRYPT(r,l, 8); /* 5 */
1240 D_ENCRYPT(l,r, 6); /* 4 */
1241 D_ENCRYPT(r,l, 4); /* 3 */
1242 D_ENCRYPT(l,r, 2); /* 2 */
1243 D_ENCRYPT(r,l, 0); /* 1 */
1244#else
1245 for (i=30; i>0; i-=8)
1246{
1247 D_ENCRYPT(l,r,i-0); /* 16 */
1248 D_ENCRYPT(r,l,i-2); /* 15 */
1249 D_ENCRYPT(l,r,i-4); /* 14 */
1250 D_ENCRYPT(r,l,i-6); /* 13 */
1251}
1252#endif
1253}
1254 /* rotate and clear the top bits on machines with 8byte longs */
1255 data[0]=ROTATE(l,3)&0xffffffffL;
1256 data[1]=ROTATE(r,3)&0xffffffffL;
1257 l=r=t=u=0;
1258}
1259
1260/**
1261 * Single block 3DES EDE encrypt routine
1262 */
7daf5226 1263static void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
462129d3
MW
1264 des_key_schedule ks2, des_key_schedule ks3)
1265{
1266 register DES_LONG l,r;
1267
1268 l=data[0];
1269 r=data[1];
1270 IP(l,r);
1271 data[0]=l;
1272 data[1]=r;
1273 des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
1274 des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
1275 des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
1276 l=data[0];
1277 r=data[1];
1278 FP(r,l);
1279 data[0]=l;
1280 data[1]=r;
1281}
1282
1283/**
1284 * Single block 3DES EDE decrypt routine
1285 */
7daf5226 1286static void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
462129d3
MW
1287 des_key_schedule ks2, des_key_schedule ks3)
1288{
1289 register DES_LONG l,r;
1290
1291 l=data[0];
1292 r=data[1];
1293 IP(l,r);
1294 data[0]=l;
1295 data[1]=r;
1296 des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
1297 des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
1298 des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
1299 l=data[0];
1300 r=data[1];
1301 FP(r,l);
1302 data[0]=l;
1303 data[1]=r;
1304}
1305
1306/**
1307 * 3DES EDE CBC encrypt/decrypt routine
1308 */
1309static void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output, long length,
1310 des_key_schedule ks1, des_key_schedule ks2,
1311 des_key_schedule ks3, des_cblock *ivec, int enc)
1312{
1313 register DES_LONG tin0,tin1;
1314 register DES_LONG tout0,tout1,xor0,xor1;
1315 register unsigned char *in,*out;
1316 register long l=length;
1317 DES_LONG tin[2];
1318 unsigned char *iv;
1319
1320 in=(unsigned char *)input;
1321 out=(unsigned char *)output;
1322 iv=(unsigned char *)ivec;
1323
1324 if (enc)
1325 {
1326 c2l(iv,tout0);
1327 c2l(iv,tout1);
1328 for (l-=8; l>=0; l-=8)
1329 {
1330 c2l(in,tin0);
1331 c2l(in,tin1);
1332 tin0^=tout0;
1333 tin1^=tout1;
1334
1335 tin[0]=tin0;
1336 tin[1]=tin1;
1337 des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
1338 tout0=tin[0];
1339 tout1=tin[1];
1340
1341 l2c(tout0,out);
1342 l2c(tout1,out);
1343 }
1344 if (l != -8)
1345 {
1346 c2ln(in,tin0,tin1,l+8);
1347 tin0^=tout0;
1348 tin1^=tout1;
1349
1350 tin[0]=tin0;
1351 tin[1]=tin1;
1352 des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
1353 tout0=tin[0];
1354 tout1=tin[1];
1355
1356 l2c(tout0,out);
1357 l2c(tout1,out);
1358 }
1359 iv=(unsigned char *)ivec;
1360 l2c(tout0,iv);
1361 l2c(tout1,iv);
1362 }
1363 else
1364 {
1365 register DES_LONG t0,t1;
1366
1367 c2l(iv,xor0);
1368 c2l(iv,xor1);
1369 for (l-=8; l>=0; l-=8)
1370 {
1371 c2l(in,tin0);
1372 c2l(in,tin1);
1373
1374 t0=tin0;
1375 t1=tin1;
1376
1377 tin[0]=tin0;
1378 tin[1]=tin1;
1379 des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
1380 tout0=tin[0];
1381 tout1=tin[1];
1382
1383 tout0^=xor0;
1384 tout1^=xor1;
1385 l2c(tout0,out);
1386 l2c(tout1,out);
1387 xor0=t0;
1388 xor1=t1;
1389 }
1390 if (l != -8)
1391 {
1392 c2l(in,tin0);
1393 c2l(in,tin1);
7daf5226 1394
462129d3
MW
1395 t0=tin0;
1396 t1=tin1;
1397
1398 tin[0]=tin0;
1399 tin[1]=tin1;
1400 des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
1401 tout0=tin[0];
1402 tout1=tin[1];
7daf5226 1403
462129d3
MW
1404 tout0^=xor0;
1405 tout1^=xor1;
1406 l2cn(tout0,tout1,out,l+8);
1407 xor0=t0;
1408 xor1=t1;
1409 }
1410
1411 iv=(unsigned char *)ivec;
1412 l2c(xor0,iv);
1413 l2c(xor1,iv);
1414 }
1415 tin0=tin1=tout0=tout1=xor0=xor1=0;
1416 tin[0]=tin[1]=0;
1417}
1418
3b96189a 1419METHOD(crypter_t, decrypt, bool,
af403caf 1420 private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
462129d3
MW
1421{
1422 des_cblock ivb;
b12c53ce 1423 uint8_t *out;
7daf5226 1424
f5475fa4
MW
1425 out = data.ptr;
1426 if (decrypted)
1427 {
1428 *decrypted = chunk_alloc(data.len);
4ce78f93 1429 out = decrypted->ptr;
f5475fa4 1430 }
462129d3 1431 memcpy(&ivb, iv.ptr, sizeof(des_cblock));
f5475fa4 1432 des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
462129d3 1433 data.len, this->ks, &ivb, DES_DECRYPT);
3b96189a 1434 return TRUE;
462129d3
MW
1435}
1436
1437
e35abbe5 1438METHOD(crypter_t, encrypt, bool,
af403caf 1439 private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
462129d3
MW
1440{
1441 des_cblock ivb;
b12c53ce 1442 uint8_t *out;
7daf5226 1443
f5475fa4
MW
1444 out = data.ptr;
1445 if (encrypted)
1446 {
1447 *encrypted = chunk_alloc(data.len);
4ce78f93 1448 out = encrypted->ptr;
f5475fa4 1449 }
462129d3 1450 memcpy(&ivb, iv.ptr, sizeof(des_cblock));
f5475fa4 1451 des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
462129d3 1452 data.len, this->ks, &ivb, DES_ENCRYPT);
e35abbe5 1453 return TRUE;
462129d3
MW
1454}
1455
3b96189a 1456METHOD(crypter_t, decrypt_ecb, bool,
af403caf 1457 private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
7b767025 1458{
b12c53ce 1459 uint8_t *out;
7daf5226 1460
7b767025
TB
1461 out = data.ptr;
1462 if (decrypted)
1463 {
1464 *decrypted = chunk_alloc(data.len);
1465 out = decrypted->ptr;
1466 }
1467 des_ecb_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
1468 data.len, this->ks, DES_DECRYPT);
3b96189a 1469 return TRUE;
7b767025
TB
1470}
1471
e35abbe5 1472METHOD(crypter_t, encrypt_ecb, bool,
af403caf 1473 private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
7b767025 1474{
b12c53ce 1475 uint8_t *out;
7daf5226 1476
7b767025
TB
1477 out = data.ptr;
1478 if (encrypted)
1479 {
1480 *encrypted = chunk_alloc(data.len);
1481 out = encrypted->ptr;
1482 }
1483 des_ecb_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
1484 data.len, this->ks, DES_ENCRYPT);
e35abbe5 1485 return TRUE;
7b767025
TB
1486}
1487
3b96189a 1488METHOD(crypter_t, decrypt3, bool,
af403caf 1489 private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
462129d3
MW
1490{
1491 des_cblock ivb;
b12c53ce 1492 uint8_t *out;
7daf5226 1493
f5475fa4
MW
1494 out = data.ptr;
1495 if (decrypted)
1496 {
1497 *decrypted = chunk_alloc(data.len);
4ce78f93 1498 out = decrypted->ptr;
f5475fa4 1499 }
462129d3 1500 memcpy(&ivb, iv.ptr, sizeof(des_cblock));
f5475fa4 1501 des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
462129d3
MW
1502 data.len, this->ks3[0], this->ks3[1], this->ks3[2],
1503 &ivb, DES_DECRYPT);
3b96189a 1504 return TRUE;
462129d3
MW
1505}
1506
e35abbe5 1507METHOD(crypter_t, encrypt3, bool,
af403caf 1508 private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
462129d3
MW
1509{
1510 des_cblock ivb;
b12c53ce 1511 uint8_t *out;
7daf5226 1512
f5475fa4
MW
1513 out = data.ptr;
1514 if (encrypted)
1515 {
1516 *encrypted = chunk_alloc(data.len);
4ce78f93 1517 out = encrypted->ptr;
f5475fa4 1518 }
462129d3 1519 memcpy(&ivb, iv.ptr, sizeof(des_cblock));
f5475fa4 1520 des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
462129d3
MW
1521 data.len, this->ks3[0], this->ks3[1], this->ks3[2],
1522 &ivb, DES_ENCRYPT);
e35abbe5 1523 return TRUE;
462129d3
MW
1524}
1525
af403caf
MW
1526METHOD(crypter_t, get_block_size, size_t,
1527 private_des_crypter_t *this)
462129d3
MW
1528{
1529 return sizeof(des_cblock);
1530}
1531
f7c04c5b
MW
1532METHOD(crypter_t, get_iv_size, size_t,
1533 private_des_crypter_t *this)
1534{
1535 return sizeof(des_cblock);
1536}
1537
af403caf
MW
1538METHOD(crypter_t, get_key_size, size_t,
1539 private_des_crypter_t *this)
462129d3
MW
1540{
1541 return this->key_size;
1542}
1543
ce73fc19 1544METHOD(crypter_t, set_key, bool,
af403caf 1545 private_des_crypter_t *this, chunk_t key)
462129d3 1546{
462129d3 1547 des_set_key((des_cblock*)(key.ptr), &this->ks);
ce73fc19 1548 return TRUE;
462129d3
MW
1549}
1550
ce73fc19 1551METHOD(crypter_t, set_key3, bool,
af403caf 1552 private_des_crypter_t *this, chunk_t key)
7daf5226 1553{
462129d3
MW
1554 des_set_key((des_cblock*)(key.ptr) + 0, &this->ks3[0]);
1555 des_set_key((des_cblock*)(key.ptr) + 1, &this->ks3[1]);
1556 des_set_key((des_cblock*)(key.ptr) + 2, &this->ks3[2]);
ce73fc19 1557 return TRUE;
462129d3
MW
1558}
1559
af403caf
MW
1560METHOD(crypter_t, destroy, void,
1561 private_des_crypter_t *this)
462129d3 1562{
f7812f64 1563 memwipe(this, sizeof(*this));
462129d3
MW
1564 free(this);
1565}
1566
1567/*
1568 * Described in header
1569 */
1570des_crypter_t *des_crypter_create(encryption_algorithm_t algo)
1571{
af403caf 1572 private_des_crypter_t *this;
7daf5226 1573
af403caf 1574 INIT(this,
ba31fe1f
MW
1575 .public = {
1576 .crypter = {
1577 .get_block_size = _get_block_size,
1578 .get_iv_size = _get_iv_size,
1579 .get_key_size = _get_key_size,
1580 .destroy = _destroy,
1581 },
af403caf
MW
1582 },
1583 );
7daf5226 1584
462129d3
MW
1585 /* use functions depending on algorithm */
1586 switch (algo)
1587 {
1588 case ENCR_DES:
1589 this->key_size = sizeof(des_cblock);
af403caf
MW
1590 this->public.crypter.set_key = _set_key;
1591 this->public.crypter.encrypt = _encrypt;
1592 this->public.crypter.decrypt = _decrypt;
462129d3
MW
1593 break;
1594 case ENCR_3DES:
1595 this->key_size = 3 * sizeof(des_cblock);
af403caf
MW
1596 this->public.crypter.set_key = _set_key3;
1597 this->public.crypter.encrypt = _encrypt3;
1598 this->public.crypter.decrypt = _decrypt3;
462129d3 1599 break;
7b767025
TB
1600 case ENCR_DES_ECB:
1601 this->key_size = sizeof(des_cblock);
af403caf
MW
1602 this->public.crypter.set_key = _set_key;
1603 this->public.crypter.encrypt = _encrypt_ecb;
1604 this->public.crypter.decrypt = _decrypt_ecb;
7b767025 1605 break;
462129d3
MW
1606 default:
1607 free(this);
1608 return NULL;
1609 }
4d181759 1610 return &this->public;
462129d3 1611}