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