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