]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/openswan-2.6.16dr2-2.6.24-kernel.patch
Switch back to Kernel 2.6.23.16 + openswan 2.4.13
[people/pmueller/ipfire-2.x.git] / src / patches / openswan-2.6.16dr2-2.6.24-kernel.patch
1 packaging/utils/kernelpatch 2.6
2 --- /dev/null Tue Mar 11 13:02:56 2003
3 +++ linux/README.openswan-2 Mon Feb 9 13:51:03 2004
4 @@ -0,0 +1,112 @@
5 +*
6 +* RCSID $Id: README.openswan-2,v 1.1 2003/12/10 01:07:49 mcr Exp $
7 +*
8 +
9 + ****************************************
10 + * IPSEC for Linux, Release 2.xx series *
11 + ****************************************
12 +
13 +
14 +
15 +1. Files
16 +
17 +The contents of linux/net/ipsec/ (see below) join the linux kernel source tree.
18 +as provided for higher up.
19 +
20 +The programs/ directory contains the user-level utilities which you need
21 +to run IPSEC. See the top-level top/INSTALL to compile and install them.
22 +
23 +The testing/ directory contains test scripts.
24 +
25 +The doc/ directory contains -- what else -- documentation.
26 +
27 +1.1. Kernel files
28 +
29 +The following are found in net/ipsec/:
30 +
31 +Makefile The Makefile
32 +Config.in The configuration script for make menuconfig
33 +defconfig Configuration defaults for first time.
34 +
35 +radij.c General-purpose radix-tree operations
36 +
37 +ipsec_ipcomp.c IPCOMP encapsulate/decapsulate code.
38 +ipsec_ah.c Authentication Header (AH) encapsulate/decapsulate code.
39 +ipsec_esp.c Encapsulated Security Payload (ESP) encap/decap code.
40 +
41 +pfkey_v2.c PF_KEYv2 socket interface code.
42 +pfkey_v2_parser.c PF_KEYv2 message parsing and processing code.
43 +
44 +ipsec_init.c Initialization code, /proc interface.
45 +ipsec_radij.c Interface with the radix tree code.
46 +ipsec_netlink.c Interface with the netlink code.
47 +ipsec_xform.c Routines and structures common to transforms.
48 +ipsec_tunnel.c The outgoing packet processing code.
49 +ipsec_rcv.c The incoming packet processing code.
50 +ipsec_md5c.c Somewhat modified RSADSI MD5 C code.
51 +ipsec_sha1.c Somewhat modified Steve Reid SHA-1 C code.
52 +
53 +sysctl_net_ipsec.c /proc/sys/net/ipsec/* variable definitions.
54 +
55 +version.c symbolic link to project version.
56 +
57 +radij.h Headers for radij.c
58 +
59 +ipcomp.h Headers used by IPCOMP code.
60 +
61 +ipsec_radij.h Interface with the radix tree code.
62 +ipsec_netlink.h Headers used by the netlink interface.
63 +ipsec_encap.h Headers defining encapsulation structures.
64 +ipsec_xform.h Transform headers.
65 +ipsec_tunnel.h Headers used by tunneling code.
66 +ipsec_ipe4.h Headers for the IP-in-IP code.
67 +ipsec_ah.h Headers common to AH transforms.
68 +ipsec_md5h.h RSADSI MD5 headers.
69 +ipsec_sha1.h SHA-1 headers.
70 +ipsec_esp.h Headers common to ESP transfroms.
71 +ipsec_rcv.h Headers for incoming packet processing code.
72 +
73 +1.2. User-level files.
74 +
75 +The following are found in utils/:
76 +
77 +eroute.c Create an "extended route" source code
78 +spi.c Set up Security Associations source code
79 +spigrp.c Link SPIs together source code.
80 +tncfg.c Configure the tunneling features of the virtual interface
81 + source code
82 +klipsdebug.c Set/reset klips debugging features source code.
83 +version.c symbolic link to project version.
84 +
85 +eroute.8 Create an "extended route" manual page
86 +spi.8 Set up Security Associations manual page
87 +spigrp.8 Link SPIs together manual page
88 +tncfg.8 Configure the tunneling features of the virtual interface
89 + manual page
90 +klipsdebug.8 Set/reset klips debugging features manual page
91 +
92 +eroute.5 /proc/net/ipsec_eroute format manual page
93 +spi.5 /proc/net/ipsec_spi format manual page
94 +spigrp.5 /proc/net/ipsec_spigrp format manual page
95 +tncfg.5 /proc/net/ipsec_tncfg format manual page
96 +klipsdebug.5 /proc/net/ipsec_klipsdebug format manual page
97 +version.5 /proc/net/ipsec_version format manual page
98 +pf_key.5 /proc/net/pf_key format manual page
99 +
100 +Makefile Utilities makefile.
101 +
102 +*.8 Manpages for the respective utils.
103 +
104 +
105 +1.3. Test files
106 +
107 +The test scripts are locate in testing/ and and documentation is found
108 +at doc/src/umltesting.html. Automated testing via "make check" is available
109 +provided that the User-Mode-Linux patches are available.
110 +
111 +*
112 +* $Log: README.openswan-2,v $
113 +* Revision 1.1 2003/12/10 01:07:49 mcr
114 +* documentation for additions.
115 +*
116 +*
117 --- /dev/null Tue Mar 11 13:02:56 2003
118 +++ linux/include/des/des_locl.h Mon Feb 9 13:51:03 2004
119 @@ -0,0 +1,511 @@
120 +/* crypto/des/des_locl.org */
121 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
122 + * All rights reserved.
123 + *
124 + * This package is an SSL implementation written
125 + * by Eric Young (eay@cryptsoft.com).
126 + * The implementation was written so as to conform with Netscapes SSL.
127 + *
128 + * This library is free for commercial and non-commercial use as long as
129 + * the following conditions are aheared to. The following conditions
130 + * apply to all code found in this distribution, be it the RC4, RSA,
131 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
132 + * included with this distribution is covered by the same copyright terms
133 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
134 + *
135 + * Copyright remains Eric Young's, and as such any Copyright notices in
136 + * the code are not to be removed.
137 + * If this package is used in a product, Eric Young should be given attribution
138 + * as the author of the parts of the library used.
139 + * This can be in the form of a textual message at program startup or
140 + * in documentation (online or textual) provided with the package.
141 + *
142 + * Redistribution and use in source and binary forms, with or without
143 + * modification, are permitted provided that the following conditions
144 + * are met:
145 + * 1. Redistributions of source code must retain the copyright
146 + * notice, this list of conditions and the following disclaimer.
147 + * 2. Redistributions in binary form must reproduce the above copyright
148 + * notice, this list of conditions and the following disclaimer in the
149 + * documentation and/or other materials provided with the distribution.
150 + * 3. All advertising materials mentioning features or use of this software
151 + * must display the following acknowledgement:
152 + * "This product includes cryptographic software written by
153 + * Eric Young (eay@cryptsoft.com)"
154 + * The word 'cryptographic' can be left out if the rouines from the library
155 + * being used are not cryptographic related :-).
156 + * 4. If you include any Windows specific code (or a derivative thereof) from
157 + * the apps directory (application code) you must include an acknowledgement:
158 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
159 + *
160 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
161 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
162 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
163 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
164 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
165 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
166 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
167 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
168 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
169 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
170 + * SUCH DAMAGE.
171 + *
172 + * The licence and distribution terms for any publically available version or
173 + * derivative of this code cannot be changed. i.e. this code cannot simply be
174 + * copied and put under another distribution licence
175 + * [including the GNU Public Licence.]
176 + */
177 +
178 +/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
179 + *
180 + * Always modify des_locl.org since des_locl.h is automatically generated from
181 + * it during SSLeay configuration.
182 + *
183 + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
184 + */
185 +
186 +#ifndef HEADER_DES_LOCL_H
187 +#define HEADER_DES_LOCL_H
188 +
189 +#if defined(WIN32) || defined(WIN16)
190 +#ifndef MSDOS
191 +#define MSDOS
192 +#endif
193 +#endif
194 +
195 +#include "klips-crypto/des.h"
196 +#ifdef OCF_ASSIST
197 +#include "klips-crypto/ocf_assist.h"
198 +#endif
199 +
200 +#ifndef DES_DEFAULT_OPTIONS
201 +/* the following is tweaked from a config script, that is why it is a
202 + * protected undef/define */
203 +#ifndef DES_PTR
204 +#define DES_PTR
205 +#endif
206 +
207 +/* This helps C compiler generate the correct code for multiple functional
208 + * units. It reduces register dependancies at the expense of 2 more
209 + * registers */
210 +#ifndef DES_RISC1
211 +#define DES_RISC1
212 +#endif
213 +
214 +#ifndef DES_RISC2
215 +#undef DES_RISC2
216 +#endif
217 +
218 +#if defined(DES_RISC1) && defined(DES_RISC2)
219 +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
220 +#endif
221 +
222 +/* Unroll the inner loop, this sometimes helps, sometimes hinders.
223 + * Very mucy CPU dependant */
224 +#ifndef DES_UNROLL
225 +#define DES_UNROLL
226 +#endif
227 +
228 +/* These default values were supplied by
229 + * Peter Gutman <pgut001@cs.auckland.ac.nz>
230 + * They are only used if nothing else has been defined */
231 +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
232 +/* Special defines which change the way the code is built depending on the
233 + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
234 + even newer MIPS CPU's, but at the moment one size fits all for
235 + optimization options. Older Sparc's work better with only UNROLL, but
236 + there's no way to tell at compile time what it is you're running on */
237 +
238 +#if defined( sun ) /* Newer Sparc's */
239 + #define DES_PTR
240 + #define DES_RISC1
241 + #define DES_UNROLL
242 +#elif defined( __ultrix ) /* Older MIPS */
243 + #define DES_PTR
244 + #define DES_RISC2
245 + #define DES_UNROLL
246 +#elif defined( __osf1__ ) /* Alpha */
247 + #define DES_PTR
248 + #define DES_RISC2
249 +#elif defined ( _AIX ) /* RS6000 */
250 + /* Unknown */
251 +#elif defined( __hpux ) /* HP-PA */
252 + /* Unknown */
253 +#elif defined( __aux ) /* 68K */
254 + /* Unknown */
255 +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
256 + #define DES_UNROLL
257 +#elif defined( __sgi ) /* Newer MIPS */
258 + #define DES_PTR
259 + #define DES_RISC2
260 + #define DES_UNROLL
261 +#elif defined( i386 ) /* x86 boxes, should be gcc */
262 + #define DES_PTR
263 + #define DES_RISC1
264 + #define DES_UNROLL
265 +#endif /* Systems-specific speed defines */
266 +#endif
267 +
268 +#endif /* DES_DEFAULT_OPTIONS */
269 +
270 +#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */
271 +#include <stdlib.h>
272 +#include <errno.h>
273 +#include <time.h>
274 +#include <io.h>
275 +#ifndef RAND
276 +#define RAND
277 +#endif
278 +#undef NOPROTO
279 +#endif
280 +
281 +#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
282 +#ifndef __KERNEL__
283 +#include <string.h>
284 +#else
285 +#include <linux/string.h>
286 +#endif
287 +#endif
288 +
289 +#ifndef RAND
290 +#define RAND
291 +#endif
292 +
293 +#ifdef linux
294 +#undef RAND
295 +#endif
296 +
297 +#ifdef MSDOS
298 +#define getpid() 2
299 +#define RAND
300 +#undef NOPROTO
301 +#endif
302 +
303 +#if defined(NOCONST)
304 +#define const
305 +#endif
306 +
307 +#ifdef __STDC__
308 +#undef NOPROTO
309 +#endif
310 +
311 +#define ITERATIONS 16
312 +#define HALF_ITERATIONS 8
313 +
314 +/* used in des_read and des_write */
315 +#define MAXWRITE (1024*16)
316 +#define BSIZE (MAXWRITE+4)
317 +
318 +#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \
319 + l|=((DES_LONG)(*((c)++)))<< 8L, \
320 + l|=((DES_LONG)(*((c)++)))<<16L, \
321 + l|=((DES_LONG)(*((c)++)))<<24L)
322 +
323 +/* NOTE - c is not incremented as per c2l */
324 +#define c2ln(c,l1,l2,n) { \
325 + c+=n; \
326 + l1=l2=0; \
327 + switch (n) { \
328 + case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
329 + case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
330 + case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
331 + case 5: l2|=((DES_LONG)(*(--(c)))); \
332 + case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
333 + case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
334 + case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
335 + case 1: l1|=((DES_LONG)(*(--(c)))); \
336 + } \
337 + }
338 +
339 +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
340 + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
341 + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
342 + *((c)++)=(unsigned char)(((l)>>24L)&0xff))
343 +
344 +/* replacements for htonl and ntohl since I have no idea what to do
345 + * when faced with machines with 8 byte longs. */
346 +#define HDRSIZE 4
347 +
348 +#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \
349 + l|=((DES_LONG)(*((c)++)))<<16L, \
350 + l|=((DES_LONG)(*((c)++)))<< 8L, \
351 + l|=((DES_LONG)(*((c)++))))
352 +
353 +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
354 + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
355 + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
356 + *((c)++)=(unsigned char)(((l) )&0xff))
357 +
358 +/* NOTE - c is not incremented as per l2c */
359 +#define l2cn(l1,l2,c,n) { \
360 + c+=n; \
361 + switch (n) { \
362 + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
363 + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
364 + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
365 + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
366 + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
367 + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
368 + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
369 + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
370 + } \
371 + }
372 +
373 +#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
374 +
375 +/* Don't worry about the LOAD_DATA() stuff, that is used by
376 + * fcrypt() to add it's little bit to the front */
377 +
378 +#ifdef DES_FCRYPT
379 +
380 +#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
381 + { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
382 +
383 +#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
384 + t=R^(R>>16L); \
385 + u=t&E0; t&=E1; \
386 + tmp=(u<<16); u^=R^s[S ]; u^=tmp; \
387 + tmp=(t<<16); t^=R^s[S+1]; t^=tmp
388 +#else
389 +#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
390 +#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
391 + u=R^s[S ]; \
392 + t=R^s[S+1]
393 +#endif
394 +
395 +/* The changes to this macro may help or hinder, depending on the
396 + * compiler and the achitecture. gcc2 always seems to do well :-).
397 + * Inspired by Dana How <how@isl.stanford.edu>
398 + * DO NOT use the alternative version on machines with 8 byte longs.
399 + * It does not seem to work on the Alpha, even when DES_LONG is 4
400 + * bytes, probably an issue of accessing non-word aligned objects :-( */
401 +#ifdef DES_PTR
402 +
403 +/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there
404 + * is no reason to not xor all the sub items together. This potentially
405 + * saves a register since things can be xored directly into L */
406 +
407 +#if defined(DES_RISC1) || defined(DES_RISC2)
408 +#ifdef DES_RISC1
409 +#define D_ENCRYPT(LL,R,S) { \
410 + unsigned int u1,u2,u3; \
411 + LOAD_DATA(R,S,u,t,E0,E1,u1); \
412 + u2=(int)u>>8L; \
413 + u1=(int)u&0xfc; \
414 + u2&=0xfc; \
415 + t=ROTATE(t,4); \
416 + u>>=16L; \
417 + LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
418 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
419 + u3=(int)(u>>8L); \
420 + u1=(int)u&0xfc; \
421 + u3&=0xfc; \
422 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
423 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
424 + u2=(int)t>>8L; \
425 + u1=(int)t&0xfc; \
426 + u2&=0xfc; \
427 + t>>=16L; \
428 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
429 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
430 + u3=(int)t>>8L; \
431 + u1=(int)t&0xfc; \
432 + u3&=0xfc; \
433 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
434 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }
435 +#endif
436 +#ifdef DES_RISC2
437 +#define D_ENCRYPT(LL,R,S) { \
438 + unsigned int u1,u2,s1,s2; \
439 + LOAD_DATA(R,S,u,t,E0,E1,u1); \
440 + u2=(int)u>>8L; \
441 + u1=(int)u&0xfc; \
442 + u2&=0xfc; \
443 + t=ROTATE(t,4); \
444 + LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
445 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
446 + s1=(int)(u>>16L); \
447 + s2=(int)(u>>24L); \
448 + s1&=0xfc; \
449 + s2&=0xfc; \
450 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
451 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
452 + u2=(int)t>>8L; \
453 + u1=(int)t&0xfc; \
454 + u2&=0xfc; \
455 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
456 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
457 + s1=(int)(t>>16L); \
458 + s2=(int)(t>>24L); \
459 + s1&=0xfc; \
460 + s2&=0xfc; \
461 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
462 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }
463 +#endif
464 +#else
465 +#define D_ENCRYPT(LL,R,S) { \
466 + LOAD_DATA_tmp(R,S,u,t,E0,E1); \
467 + t=ROTATE(t,4); \
468 + LL^= \
469 + *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \
470 + *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
471 + *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
472 + *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
473 + *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \
474 + *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
475 + *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
476 + *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }
477 +#endif
478 +
479 +#else /* original version */
480 +
481 +#if defined(DES_RISC1) || defined(DES_RISC2)
482 +#ifdef DES_RISC1
483 +#define D_ENCRYPT(LL,R,S) {\
484 + unsigned int u1,u2,u3; \
485 + LOAD_DATA(R,S,u,t,E0,E1,u1); \
486 + u>>=2L; \
487 + t=ROTATE(t,6); \
488 + u2=(int)u>>8L; \
489 + u1=(int)u&0x3f; \
490 + u2&=0x3f; \
491 + u>>=16L; \
492 + LL^=des_SPtrans[0][u1]; \
493 + LL^=des_SPtrans[2][u2]; \
494 + u3=(int)u>>8L; \
495 + u1=(int)u&0x3f; \
496 + u3&=0x3f; \
497 + LL^=des_SPtrans[4][u1]; \
498 + LL^=des_SPtrans[6][u3]; \
499 + u2=(int)t>>8L; \
500 + u1=(int)t&0x3f; \
501 + u2&=0x3f; \
502 + t>>=16L; \
503 + LL^=des_SPtrans[1][u1]; \
504 + LL^=des_SPtrans[3][u2]; \
505 + u3=(int)t>>8L; \
506 + u1=(int)t&0x3f; \
507 + u3&=0x3f; \
508 + LL^=des_SPtrans[5][u1]; \
509 + LL^=des_SPtrans[7][u3]; }
510 +#endif
511 +#ifdef DES_RISC2
512 +#define D_ENCRYPT(LL,R,S) {\
513 + unsigned int u1,u2,s1,s2; \
514 + LOAD_DATA(R,S,u,t,E0,E1,u1); \
515 + u>>=2L; \
516 + t=ROTATE(t,6); \
517 + u2=(int)u>>8L; \
518 + u1=(int)u&0x3f; \
519 + u2&=0x3f; \
520 + LL^=des_SPtrans[0][u1]; \
521 + LL^=des_SPtrans[2][u2]; \
522 + s1=(int)u>>16L; \
523 + s2=(int)u>>24L; \
524 + s1&=0x3f; \
525 + s2&=0x3f; \
526 + LL^=des_SPtrans[4][s1]; \
527 + LL^=des_SPtrans[6][s2]; \
528 + u2=(int)t>>8L; \
529 + u1=(int)t&0x3f; \
530 + u2&=0x3f; \
531 + LL^=des_SPtrans[1][u1]; \
532 + LL^=des_SPtrans[3][u2]; \
533 + s1=(int)t>>16; \
534 + s2=(int)t>>24L; \
535 + s1&=0x3f; \
536 + s2&=0x3f; \
537 + LL^=des_SPtrans[5][s1]; \
538 + LL^=des_SPtrans[7][s2]; }
539 +#endif
540 +
541 +#else
542 +
543 +#define D_ENCRYPT(LL,R,S) {\
544 + LOAD_DATA_tmp(R,S,u,t,E0,E1); \
545 + t=ROTATE(t,4); \
546 + LL^=\
547 + des_SPtrans[0][(u>> 2L)&0x3f]^ \
548 + des_SPtrans[2][(u>>10L)&0x3f]^ \
549 + des_SPtrans[4][(u>>18L)&0x3f]^ \
550 + des_SPtrans[6][(u>>26L)&0x3f]^ \
551 + des_SPtrans[1][(t>> 2L)&0x3f]^ \
552 + des_SPtrans[3][(t>>10L)&0x3f]^ \
553 + des_SPtrans[5][(t>>18L)&0x3f]^ \
554 + des_SPtrans[7][(t>>26L)&0x3f]; }
555 +#endif
556 +#endif
557 +
558 + /* IP and FP
559 + * The problem is more of a geometric problem that random bit fiddling.
560 + 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
561 + 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
562 + 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
563 + 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
564 +
565 + 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
566 + 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
567 + 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
568 + 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
569 +
570 + The output has been subject to swaps of the form
571 + 0 1 -> 3 1 but the odd and even bits have been put into
572 + 2 3 2 0
573 + different words. The main trick is to remember that
574 + t=((l>>size)^r)&(mask);
575 + r^=t;
576 + l^=(t<<size);
577 + can be used to swap and move bits between words.
578 +
579 + So l = 0 1 2 3 r = 16 17 18 19
580 + 4 5 6 7 20 21 22 23
581 + 8 9 10 11 24 25 26 27
582 + 12 13 14 15 28 29 30 31
583 + becomes (for size == 2 and mask == 0x3333)
584 + t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
585 + 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
586 + 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
587 + 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
588 +
589 + Thanks for hints from Richard Outerbridge - he told me IP&FP
590 + could be done in 15 xor, 10 shifts and 5 ands.
591 + When I finally started to think of the problem in 2D
592 + I first got ~42 operations without xors. When I remembered
593 + how to use xors :-) I got it to its final state.
594 + */
595 +#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
596 + (b)^=(t),\
597 + (a)^=((t)<<(n)))
598 +
599 +#define IP(l,r) \
600 + { \
601 + register DES_LONG tt; \
602 + PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
603 + PERM_OP(l,r,tt,16,0x0000ffffL); \
604 + PERM_OP(r,l,tt, 2,0x33333333L); \
605 + PERM_OP(l,r,tt, 8,0x00ff00ffL); \
606 + PERM_OP(r,l,tt, 1,0x55555555L); \
607 + }
608 +
609 +#define FP(l,r) \
610 + { \
611 + register DES_LONG tt; \
612 + PERM_OP(l,r,tt, 1,0x55555555L); \
613 + PERM_OP(r,l,tt, 8,0x00ff00ffL); \
614 + PERM_OP(l,r,tt, 2,0x33333333L); \
615 + PERM_OP(r,l,tt,16,0x0000ffffL); \
616 + PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
617 + }
618 +
619 +extern const DES_LONG des_SPtrans[8][64];
620 +
621 +#ifndef NO_FCRYPT
622 +#ifndef NOPROTO
623 +void fcrypt_body(DES_LONG *out,des_key_schedule ks,
624 + DES_LONG Eswap0, DES_LONG Eswap1);
625 +#else
626 +void fcrypt_body();
627 +#endif
628 +#endif /* NO_FCRYPT */
629 +
630 +#endif
631 --- /dev/null Tue Mar 11 13:02:56 2003
632 +++ linux/include/des/des_ver.h Mon Feb 9 13:51:03 2004
633 @@ -0,0 +1,60 @@
634 +/* crypto/des/des_ver.h */
635 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
636 + * All rights reserved.
637 + *
638 + * This package is an SSL implementation written
639 + * by Eric Young (eay@cryptsoft.com).
640 + * The implementation was written so as to conform with Netscapes SSL.
641 + *
642 + * This library is free for commercial and non-commercial use as long as
643 + * the following conditions are aheared to. The following conditions
644 + * apply to all code found in this distribution, be it the RC4, RSA,
645 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
646 + * included with this distribution is covered by the same copyright terms
647 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
648 + *
649 + * Copyright remains Eric Young's, and as such any Copyright notices in
650 + * the code are not to be removed.
651 + * If this package is used in a product, Eric Young should be given attribution
652 + * as the author of the parts of the library used.
653 + * This can be in the form of a textual message at program startup or
654 + * in documentation (online or textual) provided with the package.
655 + *
656 + * Redistribution and use in source and binary forms, with or without
657 + * modification, are permitted provided that the following conditions
658 + * are met:
659 + * 1. Redistributions of source code must retain the copyright
660 + * notice, this list of conditions and the following disclaimer.
661 + * 2. Redistributions in binary form must reproduce the above copyright
662 + * notice, this list of conditions and the following disclaimer in the
663 + * documentation and/or other materials provided with the distribution.
664 + * 3. All advertising materials mentioning features or use of this software
665 + * must display the following acknowledgement:
666 + * "This product includes cryptographic software written by
667 + * Eric Young (eay@cryptsoft.com)"
668 + * The word 'cryptographic' can be left out if the rouines from the library
669 + * being used are not cryptographic related :-).
670 + * 4. If you include any Windows specific code (or a derivative thereof) from
671 + * the apps directory (application code) you must include an acknowledgement:
672 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
673 + *
674 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
675 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
676 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
677 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
678 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
679 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
680 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
681 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
682 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
683 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
684 + * SUCH DAMAGE.
685 + *
686 + * The licence and distribution terms for any publically available version or
687 + * derivative of this code cannot be changed. i.e. this code cannot simply be
688 + * copied and put under another distribution licence
689 + * [including the GNU Public Licence.]
690 + */
691 +
692 +extern char *DES_version; /* SSLeay version string */
693 +extern char *libdes_version; /* old libdes version string */
694 --- /dev/null Tue Mar 11 13:02:56 2003
695 +++ linux/include/des/podd.h Mon Feb 9 13:51:03 2004
696 @@ -0,0 +1,75 @@
697 +/* crypto/des/podd.h */
698 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
699 + * All rights reserved.
700 + *
701 + * This package is an SSL implementation written
702 + * by Eric Young (eay@cryptsoft.com).
703 + * The implementation was written so as to conform with Netscapes SSL.
704 + *
705 + * This library is free for commercial and non-commercial use as long as
706 + * the following conditions are aheared to. The following conditions
707 + * apply to all code found in this distribution, be it the RC4, RSA,
708 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
709 + * included with this distribution is covered by the same copyright terms
710 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
711 + *
712 + * Copyright remains Eric Young's, and as such any Copyright notices in
713 + * the code are not to be removed.
714 + * If this package is used in a product, Eric Young should be given attribution
715 + * as the author of the parts of the library used.
716 + * This can be in the form of a textual message at program startup or
717 + * in documentation (online or textual) provided with the package.
718 + *
719 + * Redistribution and use in source and binary forms, with or without
720 + * modification, are permitted provided that the following conditions
721 + * are met:
722 + * 1. Redistributions of source code must retain the copyright
723 + * notice, this list of conditions and the following disclaimer.
724 + * 2. Redistributions in binary form must reproduce the above copyright
725 + * notice, this list of conditions and the following disclaimer in the
726 + * documentation and/or other materials provided with the distribution.
727 + * 3. All advertising materials mentioning features or use of this software
728 + * must display the following acknowledgement:
729 + * "This product includes cryptographic software written by
730 + * Eric Young (eay@cryptsoft.com)"
731 + * The word 'cryptographic' can be left out if the rouines from the library
732 + * being used are not cryptographic related :-).
733 + * 4. If you include any Windows specific code (or a derivative thereof) from
734 + * the apps directory (application code) you must include an acknowledgement:
735 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
736 + *
737 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
738 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
739 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
740 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
741 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
742 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
743 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
744 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
745 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
746 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
747 + * SUCH DAMAGE.
748 + *
749 + * The licence and distribution terms for any publically available version or
750 + * derivative of this code cannot be changed. i.e. this code cannot simply be
751 + * copied and put under another distribution licence
752 + * [including the GNU Public Licence.]
753 + */
754 +
755 +static const unsigned char odd_parity[256]={
756 + 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
757 + 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
758 + 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
759 + 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
760 + 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
761 + 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
762 + 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
763 +112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
764 +128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
765 +145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
766 +161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
767 +176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
768 +193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
769 +208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
770 +224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
771 +241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
772 --- /dev/null Tue Mar 11 13:02:56 2003
773 +++ linux/include/des/sk.h Mon Feb 9 13:51:03 2004
774 @@ -0,0 +1,204 @@
775 +/* crypto/des/sk.h */
776 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
777 + * All rights reserved.
778 + *
779 + * This package is an SSL implementation written
780 + * by Eric Young (eay@cryptsoft.com).
781 + * The implementation was written so as to conform with Netscapes SSL.
782 + *
783 + * This library is free for commercial and non-commercial use as long as
784 + * the following conditions are aheared to. The following conditions
785 + * apply to all code found in this distribution, be it the RC4, RSA,
786 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
787 + * included with this distribution is covered by the same copyright terms
788 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
789 + *
790 + * Copyright remains Eric Young's, and as such any Copyright notices in
791 + * the code are not to be removed.
792 + * If this package is used in a product, Eric Young should be given attribution
793 + * as the author of the parts of the library used.
794 + * This can be in the form of a textual message at program startup or
795 + * in documentation (online or textual) provided with the package.
796 + *
797 + * Redistribution and use in source and binary forms, with or without
798 + * modification, are permitted provided that the following conditions
799 + * are met:
800 + * 1. Redistributions of source code must retain the copyright
801 + * notice, this list of conditions and the following disclaimer.
802 + * 2. Redistributions in binary form must reproduce the above copyright
803 + * notice, this list of conditions and the following disclaimer in the
804 + * documentation and/or other materials provided with the distribution.
805 + * 3. All advertising materials mentioning features or use of this software
806 + * must display the following acknowledgement:
807 + * "This product includes cryptographic software written by
808 + * Eric Young (eay@cryptsoft.com)"
809 + * The word 'cryptographic' can be left out if the rouines from the library
810 + * being used are not cryptographic related :-).
811 + * 4. If you include any Windows specific code (or a derivative thereof) from
812 + * the apps directory (application code) you must include an acknowledgement:
813 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
814 + *
815 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
816 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
817 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
818 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
819 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
820 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
821 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
822 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
823 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
824 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
825 + * SUCH DAMAGE.
826 + *
827 + * The licence and distribution terms for any publically available version or
828 + * derivative of this code cannot be changed. i.e. this code cannot simply be
829 + * copied and put under another distribution licence
830 + * [including the GNU Public Licence.]
831 + */
832 +
833 +static const DES_LONG des_skb[8][64]={
834 +{
835 +/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
836 +0x00000000L,0x00000010L,0x20000000L,0x20000010L,
837 +0x00010000L,0x00010010L,0x20010000L,0x20010010L,
838 +0x00000800L,0x00000810L,0x20000800L,0x20000810L,
839 +0x00010800L,0x00010810L,0x20010800L,0x20010810L,
840 +0x00000020L,0x00000030L,0x20000020L,0x20000030L,
841 +0x00010020L,0x00010030L,0x20010020L,0x20010030L,
842 +0x00000820L,0x00000830L,0x20000820L,0x20000830L,
843 +0x00010820L,0x00010830L,0x20010820L,0x20010830L,
844 +0x00080000L,0x00080010L,0x20080000L,0x20080010L,
845 +0x00090000L,0x00090010L,0x20090000L,0x20090010L,
846 +0x00080800L,0x00080810L,0x20080800L,0x20080810L,
847 +0x00090800L,0x00090810L,0x20090800L,0x20090810L,
848 +0x00080020L,0x00080030L,0x20080020L,0x20080030L,
849 +0x00090020L,0x00090030L,0x20090020L,0x20090030L,
850 +0x00080820L,0x00080830L,0x20080820L,0x20080830L,
851 +0x00090820L,0x00090830L,0x20090820L,0x20090830L,
852 +},{
853 +/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
854 +0x00000000L,0x02000000L,0x00002000L,0x02002000L,
855 +0x00200000L,0x02200000L,0x00202000L,0x02202000L,
856 +0x00000004L,0x02000004L,0x00002004L,0x02002004L,
857 +0x00200004L,0x02200004L,0x00202004L,0x02202004L,
858 +0x00000400L,0x02000400L,0x00002400L,0x02002400L,
859 +0x00200400L,0x02200400L,0x00202400L,0x02202400L,
860 +0x00000404L,0x02000404L,0x00002404L,0x02002404L,
861 +0x00200404L,0x02200404L,0x00202404L,0x02202404L,
862 +0x10000000L,0x12000000L,0x10002000L,0x12002000L,
863 +0x10200000L,0x12200000L,0x10202000L,0x12202000L,
864 +0x10000004L,0x12000004L,0x10002004L,0x12002004L,
865 +0x10200004L,0x12200004L,0x10202004L,0x12202004L,
866 +0x10000400L,0x12000400L,0x10002400L,0x12002400L,
867 +0x10200400L,0x12200400L,0x10202400L,0x12202400L,
868 +0x10000404L,0x12000404L,0x10002404L,0x12002404L,
869 +0x10200404L,0x12200404L,0x10202404L,0x12202404L,
870 +},{
871 +/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
872 +0x00000000L,0x00000001L,0x00040000L,0x00040001L,
873 +0x01000000L,0x01000001L,0x01040000L,0x01040001L,
874 +0x00000002L,0x00000003L,0x00040002L,0x00040003L,
875 +0x01000002L,0x01000003L,0x01040002L,0x01040003L,
876 +0x00000200L,0x00000201L,0x00040200L,0x00040201L,
877 +0x01000200L,0x01000201L,0x01040200L,0x01040201L,
878 +0x00000202L,0x00000203L,0x00040202L,0x00040203L,
879 +0x01000202L,0x01000203L,0x01040202L,0x01040203L,
880 +0x08000000L,0x08000001L,0x08040000L,0x08040001L,
881 +0x09000000L,0x09000001L,0x09040000L,0x09040001L,
882 +0x08000002L,0x08000003L,0x08040002L,0x08040003L,
883 +0x09000002L,0x09000003L,0x09040002L,0x09040003L,
884 +0x08000200L,0x08000201L,0x08040200L,0x08040201L,
885 +0x09000200L,0x09000201L,0x09040200L,0x09040201L,
886 +0x08000202L,0x08000203L,0x08040202L,0x08040203L,
887 +0x09000202L,0x09000203L,0x09040202L,0x09040203L,
888 +},{
889 +/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
890 +0x00000000L,0x00100000L,0x00000100L,0x00100100L,
891 +0x00000008L,0x00100008L,0x00000108L,0x00100108L,
892 +0x00001000L,0x00101000L,0x00001100L,0x00101100L,
893 +0x00001008L,0x00101008L,0x00001108L,0x00101108L,
894 +0x04000000L,0x04100000L,0x04000100L,0x04100100L,
895 +0x04000008L,0x04100008L,0x04000108L,0x04100108L,
896 +0x04001000L,0x04101000L,0x04001100L,0x04101100L,
897 +0x04001008L,0x04101008L,0x04001108L,0x04101108L,
898 +0x00020000L,0x00120000L,0x00020100L,0x00120100L,
899 +0x00020008L,0x00120008L,0x00020108L,0x00120108L,
900 +0x00021000L,0x00121000L,0x00021100L,0x00121100L,
901 +0x00021008L,0x00121008L,0x00021108L,0x00121108L,
902 +0x04020000L,0x04120000L,0x04020100L,0x04120100L,
903 +0x04020008L,0x04120008L,0x04020108L,0x04120108L,
904 +0x04021000L,0x04121000L,0x04021100L,0x04121100L,
905 +0x04021008L,0x04121008L,0x04021108L,0x04121108L,
906 +},{
907 +/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
908 +0x00000000L,0x10000000L,0x00010000L,0x10010000L,
909 +0x00000004L,0x10000004L,0x00010004L,0x10010004L,
910 +0x20000000L,0x30000000L,0x20010000L,0x30010000L,
911 +0x20000004L,0x30000004L,0x20010004L,0x30010004L,
912 +0x00100000L,0x10100000L,0x00110000L,0x10110000L,
913 +0x00100004L,0x10100004L,0x00110004L,0x10110004L,
914 +0x20100000L,0x30100000L,0x20110000L,0x30110000L,
915 +0x20100004L,0x30100004L,0x20110004L,0x30110004L,
916 +0x00001000L,0x10001000L,0x00011000L,0x10011000L,
917 +0x00001004L,0x10001004L,0x00011004L,0x10011004L,
918 +0x20001000L,0x30001000L,0x20011000L,0x30011000L,
919 +0x20001004L,0x30001004L,0x20011004L,0x30011004L,
920 +0x00101000L,0x10101000L,0x00111000L,0x10111000L,
921 +0x00101004L,0x10101004L,0x00111004L,0x10111004L,
922 +0x20101000L,0x30101000L,0x20111000L,0x30111000L,
923 +0x20101004L,0x30101004L,0x20111004L,0x30111004L,
924 +},{
925 +/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
926 +0x00000000L,0x08000000L,0x00000008L,0x08000008L,
927 +0x00000400L,0x08000400L,0x00000408L,0x08000408L,
928 +0x00020000L,0x08020000L,0x00020008L,0x08020008L,
929 +0x00020400L,0x08020400L,0x00020408L,0x08020408L,
930 +0x00000001L,0x08000001L,0x00000009L,0x08000009L,
931 +0x00000401L,0x08000401L,0x00000409L,0x08000409L,
932 +0x00020001L,0x08020001L,0x00020009L,0x08020009L,
933 +0x00020401L,0x08020401L,0x00020409L,0x08020409L,
934 +0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
935 +0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
936 +0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
937 +0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
938 +0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
939 +0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
940 +0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
941 +0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
942 +},{
943 +/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
944 +0x00000000L,0x00000100L,0x00080000L,0x00080100L,
945 +0x01000000L,0x01000100L,0x01080000L,0x01080100L,
946 +0x00000010L,0x00000110L,0x00080010L,0x00080110L,
947 +0x01000010L,0x01000110L,0x01080010L,0x01080110L,
948 +0x00200000L,0x00200100L,0x00280000L,0x00280100L,
949 +0x01200000L,0x01200100L,0x01280000L,0x01280100L,
950 +0x00200010L,0x00200110L,0x00280010L,0x00280110L,
951 +0x01200010L,0x01200110L,0x01280010L,0x01280110L,
952 +0x00000200L,0x00000300L,0x00080200L,0x00080300L,
953 +0x01000200L,0x01000300L,0x01080200L,0x01080300L,
954 +0x00000210L,0x00000310L,0x00080210L,0x00080310L,
955 +0x01000210L,0x01000310L,0x01080210L,0x01080310L,
956 +0x00200200L,0x00200300L,0x00280200L,0x00280300L,
957 +0x01200200L,0x01200300L,0x01280200L,0x01280300L,
958 +0x00200210L,0x00200310L,0x00280210L,0x00280310L,
959 +0x01200210L,0x01200310L,0x01280210L,0x01280310L,
960 +},{
961 +/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
962 +0x00000000L,0x04000000L,0x00040000L,0x04040000L,
963 +0x00000002L,0x04000002L,0x00040002L,0x04040002L,
964 +0x00002000L,0x04002000L,0x00042000L,0x04042000L,
965 +0x00002002L,0x04002002L,0x00042002L,0x04042002L,
966 +0x00000020L,0x04000020L,0x00040020L,0x04040020L,
967 +0x00000022L,0x04000022L,0x00040022L,0x04040022L,
968 +0x00002020L,0x04002020L,0x00042020L,0x04042020L,
969 +0x00002022L,0x04002022L,0x00042022L,0x04042022L,
970 +0x00000800L,0x04000800L,0x00040800L,0x04040800L,
971 +0x00000802L,0x04000802L,0x00040802L,0x04040802L,
972 +0x00002800L,0x04002800L,0x00042800L,0x04042800L,
973 +0x00002802L,0x04002802L,0x00042802L,0x04042802L,
974 +0x00000820L,0x04000820L,0x00040820L,0x04040820L,
975 +0x00000822L,0x04000822L,0x00040822L,0x04040822L,
976 +0x00002820L,0x04002820L,0x00042820L,0x04042820L,
977 +0x00002822L,0x04002822L,0x00042822L,0x04042822L,
978 +}};
979 --- /dev/null Tue Mar 11 13:02:56 2003
980 +++ linux/include/des/spr.h Mon Feb 9 13:51:03 2004
981 @@ -0,0 +1,204 @@
982 +/* crypto/des/spr.h */
983 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
984 + * All rights reserved.
985 + *
986 + * This package is an SSL implementation written
987 + * by Eric Young (eay@cryptsoft.com).
988 + * The implementation was written so as to conform with Netscapes SSL.
989 + *
990 + * This library is free for commercial and non-commercial use as long as
991 + * the following conditions are aheared to. The following conditions
992 + * apply to all code found in this distribution, be it the RC4, RSA,
993 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
994 + * included with this distribution is covered by the same copyright terms
995 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
996 + *
997 + * Copyright remains Eric Young's, and as such any Copyright notices in
998 + * the code are not to be removed.
999 + * If this package is used in a product, Eric Young should be given attribution
1000 + * as the author of the parts of the library used.
1001 + * This can be in the form of a textual message at program startup or
1002 + * in documentation (online or textual) provided with the package.
1003 + *
1004 + * Redistribution and use in source and binary forms, with or without
1005 + * modification, are permitted provided that the following conditions
1006 + * are met:
1007 + * 1. Redistributions of source code must retain the copyright
1008 + * notice, this list of conditions and the following disclaimer.
1009 + * 2. Redistributions in binary form must reproduce the above copyright
1010 + * notice, this list of conditions and the following disclaimer in the
1011 + * documentation and/or other materials provided with the distribution.
1012 + * 3. All advertising materials mentioning features or use of this software
1013 + * must display the following acknowledgement:
1014 + * "This product includes cryptographic software written by
1015 + * Eric Young (eay@cryptsoft.com)"
1016 + * The word 'cryptographic' can be left out if the rouines from the library
1017 + * being used are not cryptographic related :-).
1018 + * 4. If you include any Windows specific code (or a derivative thereof) from
1019 + * the apps directory (application code) you must include an acknowledgement:
1020 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1021 + *
1022 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1023 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1024 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1025 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1026 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1027 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1028 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1029 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1030 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1031 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1032 + * SUCH DAMAGE.
1033 + *
1034 + * The licence and distribution terms for any publically available version or
1035 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1036 + * copied and put under another distribution licence
1037 + * [including the GNU Public Licence.]
1038 + */
1039 +
1040 +const DES_LONG des_SPtrans[8][64]={
1041 +{
1042 +/* nibble 0 */
1043 +0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
1044 +0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
1045 +0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
1046 +0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
1047 +0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
1048 +0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
1049 +0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
1050 +0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
1051 +0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
1052 +0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
1053 +0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
1054 +0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
1055 +0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
1056 +0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
1057 +0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
1058 +0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
1059 +},{
1060 +/* nibble 1 */
1061 +0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
1062 +0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
1063 +0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
1064 +0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
1065 +0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
1066 +0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
1067 +0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
1068 +0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
1069 +0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
1070 +0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
1071 +0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
1072 +0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
1073 +0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
1074 +0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
1075 +0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
1076 +0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
1077 +},{
1078 +/* nibble 2 */
1079 +0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
1080 +0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
1081 +0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
1082 +0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
1083 +0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
1084 +0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
1085 +0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
1086 +0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
1087 +0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
1088 +0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
1089 +0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
1090 +0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
1091 +0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
1092 +0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
1093 +0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
1094 +0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
1095 +},{
1096 +/* nibble 3 */
1097 +0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
1098 +0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
1099 +0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
1100 +0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
1101 +0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
1102 +0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
1103 +0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
1104 +0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
1105 +0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
1106 +0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
1107 +0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
1108 +0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
1109 +0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
1110 +0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
1111 +0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
1112 +0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
1113 +},{
1114 +/* nibble 4 */
1115 +0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
1116 +0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
1117 +0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
1118 +0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
1119 +0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
1120 +0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
1121 +0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
1122 +0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
1123 +0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
1124 +0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
1125 +0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
1126 +0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
1127 +0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
1128 +0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
1129 +0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
1130 +0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
1131 +},{
1132 +/* nibble 5 */
1133 +0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
1134 +0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
1135 +0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
1136 +0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
1137 +0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
1138 +0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
1139 +0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
1140 +0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
1141 +0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
1142 +0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
1143 +0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
1144 +0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
1145 +0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
1146 +0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
1147 +0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
1148 +0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
1149 +},{
1150 +/* nibble 6 */
1151 +0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
1152 +0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
1153 +0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
1154 +0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
1155 +0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
1156 +0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
1157 +0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
1158 +0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
1159 +0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
1160 +0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
1161 +0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
1162 +0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
1163 +0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
1164 +0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
1165 +0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
1166 +0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
1167 +},{
1168 +/* nibble 7 */
1169 +0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
1170 +0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
1171 +0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
1172 +0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
1173 +0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
1174 +0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
1175 +0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
1176 +0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
1177 +0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
1178 +0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
1179 +0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
1180 +0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
1181 +0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
1182 +0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
1183 +0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
1184 +0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
1185 +}};
1186 --- /dev/null Tue Mar 11 13:02:56 2003
1187 +++ linux/include/klips-crypto/aes.h Mon Feb 9 13:51:03 2004
1188 @@ -0,0 +1,97 @@
1189 +// I retain copyright in this code but I encourage its free use provided
1190 +// that I don't carry any responsibility for the results. I am especially
1191 +// happy to see it used in free and open source software. If you do use
1192 +// it I would appreciate an acknowledgement of its origin in the code or
1193 +// the product that results and I would also appreciate knowing a little
1194 +// about the use to which it is being put. I am grateful to Frank Yellin
1195 +// for some ideas that are used in this implementation.
1196 +//
1197 +// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
1198 +//
1199 +// This is an implementation of the AES encryption algorithm (Rijndael)
1200 +// designed by Joan Daemen and Vincent Rijmen. This version is designed
1201 +// to provide both fixed and dynamic block and key lengths and can also
1202 +// run with either big or little endian internal byte order (see aes.h).
1203 +// It inputs block and key lengths in bytes with the legal values being
1204 +// 16, 24 and 32.
1205 +
1206 +/*
1207 + * Modified by Jari Ruusu, May 1 2001
1208 + * - Fixed some compile warnings, code was ok but gcc warned anyway.
1209 + * - Changed basic types: byte -> unsigned char, word -> u_int32_t
1210 + * - Major name space cleanup: Names visible to outside now begin
1211 + * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
1212 + * - Removed C++ and DLL support as part of name space cleanup.
1213 + * - Eliminated unnecessary recomputation of tables. (actual bug fix)
1214 + * - Merged precomputed constant tables to aes.c file.
1215 + * - Removed data alignment restrictions for portability reasons.
1216 + * - Made block and key lengths accept bit count (128/192/256)
1217 + * as well byte count (16/24/32).
1218 + * - Removed all error checks. This change also eliminated the need
1219 + * to preinitialize the context struct to zero.
1220 + * - Removed some totally unused constants.
1221 + */
1222 +
1223 +#ifndef _AES_H
1224 +#define _AES_H
1225 +
1226 +#if defined(__linux__) && defined(__KERNEL__)
1227 +# include <linux/types.h>
1228 +#else
1229 +# include <sys/types.h>
1230 +#endif
1231 +
1232 +// CONFIGURATION OPTIONS (see also aes.c)
1233 +//
1234 +// Define AES_BLOCK_SIZE to set the cipher block size (16, 24 or 32) or
1235 +// leave this undefined for dynamically variable block size (this will
1236 +// result in much slower code).
1237 +// IMPORTANT NOTE: AES_BLOCK_SIZE is in BYTES (16, 24, 32 or undefined). If
1238 +// left undefined a slower version providing variable block length is compiled
1239 +
1240 +#define AES_BLOCK_SIZE 16
1241 +
1242 +// The number of key schedule words for different block and key lengths
1243 +// allowing for method of computation which requires the length to be a
1244 +// multiple of the key length
1245 +//
1246 +// Nk = 4 6 8
1247 +// -------------
1248 +// Nb = 4 | 60 60 64
1249 +// 6 | 96 90 96
1250 +// 8 | 120 120 120
1251 +
1252 +#if !defined(AES_BLOCK_SIZE) || (AES_BLOCK_SIZE == 32)
1253 +#define AES_KS_LENGTH 120
1254 +#define AES_RC_LENGTH 29
1255 +#else
1256 +#define AES_KS_LENGTH 4 * AES_BLOCK_SIZE
1257 +#define AES_RC_LENGTH (9 * AES_BLOCK_SIZE) / 8 - 8
1258 +#endif
1259 +
1260 +typedef struct
1261 +{
1262 + u_int32_t aes_Nkey; // the number of words in the key input block
1263 + u_int32_t aes_Nrnd; // the number of cipher rounds
1264 + u_int32_t aes_e_key[AES_KS_LENGTH]; // the encryption key schedule
1265 + u_int32_t aes_d_key[AES_KS_LENGTH]; // the decryption key schedule
1266 +#if !defined(AES_BLOCK_SIZE)
1267 + u_int32_t aes_Ncol; // the number of columns in the cipher state
1268 +#endif
1269 +} aes_context;
1270 +
1271 +// THE CIPHER INTERFACE
1272 +
1273 +#if !defined(AES_BLOCK_SIZE)
1274 +extern void aes_set_blk(aes_context *, const int);
1275 +#endif
1276 +extern void aes_set_key(aes_context *, const unsigned char [], const int, const int);
1277 +extern void aes_encrypt(const aes_context *, const unsigned char [], unsigned char []);
1278 +extern void aes_decrypt(const aes_context *, const unsigned char [], unsigned char []);
1279 +
1280 +// The block length inputs to aes_set_block and aes_set_key are in numbers
1281 +// of bytes or bits. The calls to subroutines must be made in the above
1282 +// order but multiple calls can be made without repeating earlier calls
1283 +// if their parameters have not changed.
1284 +
1285 +#endif // _AES_H
1286 --- /dev/null Tue Mar 11 13:02:56 2003
1287 +++ linux/include/klips-crypto/aes_cbc.h Mon Feb 9 13:51:03 2004
1288 @@ -0,0 +1,4 @@
1289 +/* Glue header */
1290 +#include "aes.h"
1291 +int AES_set_key(aes_context *aes_ctx, const u_int8_t * key, int keysize);
1292 +int AES_cbc_encrypt(aes_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt);
1293 --- /dev/null Tue Mar 11 13:02:56 2003
1294 +++ linux/include/klips-crypto/aes_xcbc_mac.h Mon Feb 9 13:51:03 2004
1295 @@ -0,0 +1,12 @@
1296 +#ifndef _AES_XCBC_MAC_H
1297 +#define _AES_XCBC_MAC_H
1298 +
1299 +typedef u_int32_t aes_block[4];
1300 +typedef struct {
1301 + aes_context ctx_k1;
1302 + aes_block k2;
1303 + aes_block k3;
1304 +} aes_context_mac;
1305 +int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen);
1306 +int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]);
1307 +#endif /* _AES_XCBC_MAC_H */
1308 --- /dev/null Tue Mar 11 13:02:56 2003
1309 +++ linux/include/klips-crypto/cbc_generic.h Mon Feb 9 13:51:03 2004
1310 @@ -0,0 +1,110 @@
1311 +#ifndef _CBC_GENERIC_H
1312 +#define _CBC_GENERIC_H
1313 +/*
1314 + * CBC macro helpers
1315 + *
1316 + * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
1317 + *
1318 + * This program is free software; you can redistribute it and/or modify it
1319 + * under the terms of the GNU General Public License as published by the
1320 + * Free Software Foundation; either version 2 of the License, or (at your
1321 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
1322 + *
1323 + * This program is distributed in the hope that it will be useful, but
1324 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1325 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1326 + * for more details.
1327 + *
1328 + */
1329 +
1330 +/*
1331 + * Heavily inspired in loop_AES
1332 + */
1333 +#define CBC_IMPL_BLK16(name, ctx_type, addr_type, enc_func, dec_func) \
1334 +int name(ctx_type *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
1335 + int ret=ilen, pos; \
1336 + const u_int32_t *iv_i; \
1337 + if ((ilen) % 16) return 0; \
1338 + if (encrypt) { \
1339 + pos=0; \
1340 + while(pos<ilen) { \
1341 + if (pos==0) \
1342 + iv_i=(const u_int32_t*) iv; \
1343 + else \
1344 + iv_i=(const u_int32_t*) (out-16); \
1345 + *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
1346 + *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
1347 + *((u_int32_t *)(&out[ 8])) = iv_i[2]^*((const u_int32_t *)(&in[ 8])); \
1348 + *((u_int32_t *)(&out[12])) = iv_i[3]^*((const u_int32_t *)(&in[12])); \
1349 + enc_func(ctx, (addr_type) out, (addr_type) out); \
1350 + in+=16; \
1351 + out+=16; \
1352 + pos+=16; \
1353 + } \
1354 + } else { \
1355 + pos=ilen-16; \
1356 + in+=pos; \
1357 + out+=pos; \
1358 + while(pos>=0) { \
1359 + dec_func(ctx, (const addr_type) in, (addr_type) out); \
1360 + if (pos==0) \
1361 + iv_i=(const u_int32_t*) (iv); \
1362 + else \
1363 + iv_i=(const u_int32_t*) (in-16); \
1364 + *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
1365 + *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
1366 + *((u_int32_t *)(&out[ 8])) ^= iv_i[2]; \
1367 + *((u_int32_t *)(&out[12])) ^= iv_i[3]; \
1368 + in-=16; \
1369 + out-=16; \
1370 + pos-=16; \
1371 + } \
1372 + } \
1373 + return ret; \
1374 +}
1375 +#define CBC_IMPL_BLK8(name, ctx_type, addr_type, enc_func, dec_func) \
1376 +int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
1377 + int ret=ilen, pos; \
1378 + const u_int32_t *iv_i; \
1379 + if ((ilen) % 8) return 0; \
1380 + if (encrypt) { \
1381 + pos=0; \
1382 + while(pos<ilen) { \
1383 + if (pos==0) \
1384 + iv_i=(const u_int32_t*) iv; \
1385 + else \
1386 + iv_i=(const u_int32_t*) (out-8); \
1387 + *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
1388 + *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
1389 + enc_func(ctx, (addr_type)out, (addr_type)out); \
1390 + in+=8; \
1391 + out+=8; \
1392 + pos+=8; \
1393 + } \
1394 + } else { \
1395 + pos=ilen-8; \
1396 + in+=pos; \
1397 + out+=pos; \
1398 + while(pos>=0) { \
1399 + dec_func(ctx, (const addr_type)in, (addr_type)out); \
1400 + if (pos==0) \
1401 + iv_i=(const u_int32_t*) (iv); \
1402 + else \
1403 + iv_i=(const u_int32_t*) (in-8); \
1404 + *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
1405 + *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
1406 + in-=8; \
1407 + out-=8; \
1408 + pos-=8; \
1409 + } \
1410 + } \
1411 + return ret; \
1412 +}
1413 +#define CBC_DECL(name, ctx_type) \
1414 +int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt)
1415 +/*
1416 +Eg.:
1417 +CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
1418 +CBC_DECL(AES_cbc_encrypt, aes_context);
1419 +*/
1420 +#endif /* _CBC_GENERIC_H */
1421 --- /dev/null Tue Mar 11 13:02:56 2003
1422 +++ linux/include/klips-crypto/des.h Mon Feb 9 13:51:03 2004
1423 @@ -0,0 +1,286 @@
1424 +/* crypto/des/des.org */
1425 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
1426 + * All rights reserved.
1427 + *
1428 + * This package is an SSL implementation written
1429 + * by Eric Young (eay@cryptsoft.com).
1430 + * The implementation was written so as to conform with Netscapes SSL.
1431 + *
1432 + * This library is free for commercial and non-commercial use as long as
1433 + * the following conditions are aheared to. The following conditions
1434 + * apply to all code found in this distribution, be it the RC4, RSA,
1435 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1436 + * included with this distribution is covered by the same copyright terms
1437 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1438 + *
1439 + * Copyright remains Eric Young's, and as such any Copyright notices in
1440 + * the code are not to be removed.
1441 + * If this package is used in a product, Eric Young should be given attribution
1442 + * as the author of the parts of the library used.
1443 + * This can be in the form of a textual message at program startup or
1444 + * in documentation (online or textual) provided with the package.
1445 + *
1446 + * Redistribution and use in source and binary forms, with or without
1447 + * modification, are permitted provided that the following conditions
1448 + * are met:
1449 + * 1. Redistributions of source code must retain the copyright
1450 + * notice, this list of conditions and the following disclaimer.
1451 + * 2. Redistributions in binary form must reproduce the above copyright
1452 + * notice, this list of conditions and the following disclaimer in the
1453 + * documentation and/or other materials provided with the distribution.
1454 + * 3. All advertising materials mentioning features or use of this software
1455 + * must display the following acknowledgement:
1456 + * "This product includes cryptographic software written by
1457 + * Eric Young (eay@cryptsoft.com)"
1458 + * The word 'cryptographic' can be left out if the rouines from the library
1459 + * being used are not cryptographic related :-).
1460 + * 4. If you include any Windows specific code (or a derivative thereof) from
1461 + * the apps directory (application code) you must include an acknowledgement:
1462 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1463 + *
1464 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1465 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1466 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1467 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1468 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1469 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1470 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1471 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1472 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1473 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1474 + * SUCH DAMAGE.
1475 + *
1476 + * The licence and distribution terms for any publically available version or
1477 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1478 + * copied and put under another distribution licence
1479 + * [including the GNU Public Licence.]
1480 + */
1481 +
1482 +/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
1483 + *
1484 + * Always modify des.org since des.h is automatically generated from
1485 + * it during SSLeay configuration.
1486 + *
1487 + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
1488 + */
1489 +
1490 +#ifndef HEADER_DES_H
1491 +#define HEADER_DES_H
1492 +
1493 +#ifdef __cplusplus
1494 +extern "C" {
1495 +#endif
1496 +
1497 +
1498 +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
1499 + * %20 speed up (longs are 8 bytes, int's are 4). */
1500 +/* Must be unsigned int on ia64/Itanium or DES breaks badly */
1501 +
1502 +#ifdef __KERNEL__
1503 +#include <linux/types.h>
1504 +#else
1505 +#include <sys/types.h>
1506 +#endif
1507 +
1508 +#ifndef DES_LONG
1509 +#define DES_LONG u_int32_t
1510 +#endif
1511 +
1512 +typedef unsigned char des_cblock[8];
1513 +typedef struct { des_cblock ks; } des_key_schedule[16];
1514 +
1515 +#define DES_KEY_SZ (sizeof(des_cblock))
1516 +#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
1517 +
1518 +#define DES_ENCRYPT 1
1519 +#define DES_DECRYPT 0
1520 +
1521 +#define DES_CBC_MODE 0
1522 +#define DES_PCBC_MODE 1
1523 +
1524 +#define des_ecb2_encrypt(i,o,k1,k2,e) \
1525 + des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
1526 +
1527 +#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
1528 + des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
1529 +
1530 +#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
1531 + des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
1532 +
1533 +#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
1534 + des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
1535 +
1536 +#define C_Block des_cblock
1537 +#define Key_schedule des_key_schedule
1538 +#ifdef KERBEROS
1539 +#define ENCRYPT DES_ENCRYPT
1540 +#define DECRYPT DES_DECRYPT
1541 +#endif
1542 +#define KEY_SZ DES_KEY_SZ
1543 +#define string_to_key des_string_to_key
1544 +#define read_pw_string des_read_pw_string
1545 +#define random_key des_random_key
1546 +#define pcbc_encrypt des_pcbc_encrypt
1547 +#define set_key des_set_key
1548 +#define key_sched des_key_sched
1549 +#define ecb_encrypt des_ecb_encrypt
1550 +#define cbc_encrypt des_cbc_encrypt
1551 +#define ncbc_encrypt des_ncbc_encrypt
1552 +#define xcbc_encrypt des_xcbc_encrypt
1553 +#define cbc_cksum des_cbc_cksum
1554 +#define quad_cksum des_quad_cksum
1555 +
1556 +/* For compatibility with the MIT lib - eay 20/05/92 */
1557 +typedef des_key_schedule bit_64;
1558 +#define des_fixup_key_parity des_set_odd_parity
1559 +#define des_check_key_parity check_parity
1560 +
1561 +extern int des_check_key; /* defaults to false */
1562 +extern int des_rw_mode; /* defaults to DES_PCBC_MODE */
1563 +
1564 +/* The next line is used to disable full ANSI prototypes, if your
1565 + * compiler has problems with the prototypes, make sure this line always
1566 + * evaluates to true :-) */
1567 +#if defined(MSDOS) || defined(__STDC__)
1568 +#undef NOPROTO
1569 +#endif
1570 +#ifndef NOPROTO
1571 +char *des_options(void);
1572 +void des_ecb3_encrypt(des_cblock *input,des_cblock *output,
1573 + des_key_schedule ks1,des_key_schedule ks2,
1574 + des_key_schedule ks3, int enc);
1575 +DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output,
1576 + long length,des_key_schedule schedule,des_cblock *ivec);
1577 +void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
1578 + des_key_schedule schedule,des_cblock *ivec,int enc);
1579 +void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
1580 + des_key_schedule schedule,des_cblock *ivec,int enc);
1581 +void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
1582 + des_key_schedule schedule,des_cblock *ivec,
1583 + des_cblock *inw,des_cblock *outw,int enc);
1584 +void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
1585 + long length,des_key_schedule schedule,des_cblock *ivec,int enc);
1586 +void des_ecb_encrypt(des_cblock *input,des_cblock *output,
1587 + des_key_schedule ks,int enc);
1588 +void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
1589 +void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
1590 +void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
1591 + des_key_schedule ks2, des_key_schedule ks3);
1592 +void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
1593 + des_key_schedule ks2, des_key_schedule ks3);
1594 +void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
1595 + long length, des_key_schedule ks1, des_key_schedule ks2,
1596 + des_key_schedule ks3, des_cblock *ivec, int enc);
1597 +void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
1598 + long length, des_key_schedule ks1, des_key_schedule ks2,
1599 + des_key_schedule ks3, des_cblock *ivec, int *num, int enc);
1600 +void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
1601 + long length, des_key_schedule ks1, des_key_schedule ks2,
1602 + des_key_schedule ks3, des_cblock *ivec, int *num);
1603 +
1604 +void des_xwhite_in2out(des_cblock (*des_key), des_cblock (*in_white),
1605 + des_cblock (*out_white));
1606 +
1607 +int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
1608 + des_cblock *iv);
1609 +int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
1610 + des_cblock *iv);
1611 +char *des_fcrypt(const char *buf,const char *salt, char *ret);
1612 +
1613 +void des_ofb_encrypt(unsigned char *in,unsigned char *out,
1614 + int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
1615 +void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
1616 + des_key_schedule schedule,des_cblock *ivec,int enc);
1617 +DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output,
1618 + long length,int out_count,des_cblock *seed);
1619 +void des_random_seed(des_cblock key);
1620 +void des_random_key(des_cblock ret);
1621 +int des_read_password(des_cblock *key,char *prompt,int verify);
1622 +int des_read_2passwords(des_cblock *key1,des_cblock *key2,
1623 + char *prompt,int verify);
1624 +int des_read_pw_string(char *buf,int length,char *prompt,int verify);
1625 +void des_set_odd_parity(des_cblock *key);
1626 +int des_is_weak_key(des_cblock *key);
1627 +int des_set_key(des_cblock *key,des_key_schedule schedule);
1628 +int des_key_sched(des_cblock *key,des_key_schedule schedule);
1629 +void des_string_to_key(char *str,des_cblock *key);
1630 +void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
1631 +void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
1632 + des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
1633 +void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
1634 + des_key_schedule schedule, des_cblock *ivec, int *num);
1635 +int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify);
1636 +
1637 +/* Extra functions from Mark Murray <mark@grondar.za> */
1638 +/* The following functions are not in the normal unix build or the
1639 + * SSLeay build. When using the SSLeay build, use RAND_seed()
1640 + * and RAND_bytes() instead. */
1641 +int des_new_random_key(des_cblock *key);
1642 +void des_init_random_number_generator(des_cblock *key);
1643 +void des_set_random_generator_seed(des_cblock *key);
1644 +void des_set_sequence_number(des_cblock new_sequence_number);
1645 +void des_generate_random_block(des_cblock *block);
1646 +
1647 +#else
1648 +
1649 +char *des_options();
1650 +void des_ecb3_encrypt();
1651 +DES_LONG des_cbc_cksum();
1652 +void des_cbc_encrypt();
1653 +void des_ncbc_encrypt();
1654 +void des_xcbc_encrypt();
1655 +void des_cfb_encrypt();
1656 +void des_ede3_cfb64_encrypt();
1657 +void des_ede3_ofb64_encrypt();
1658 +void des_ecb_encrypt();
1659 +void des_encrypt();
1660 +void des_encrypt2();
1661 +void des_encrypt3();
1662 +void des_decrypt3();
1663 +void des_ede3_cbc_encrypt();
1664 +int des_enc_read();
1665 +int des_enc_write();
1666 +char *des_fcrypt();
1667 +#ifdef PERL5
1668 +char *des_crypt();
1669 +#else
1670 +char *crypt();
1671 +#endif
1672 +void des_ofb_encrypt();
1673 +void des_pcbc_encrypt();
1674 +DES_LONG des_quad_cksum();
1675 +void des_random_seed();
1676 +void des_random_key();
1677 +int des_read_password();
1678 +int des_read_2passwords();
1679 +int des_read_pw_string();
1680 +void des_set_odd_parity();
1681 +int des_is_weak_key();
1682 +int des_set_key();
1683 +int des_key_sched();
1684 +void des_string_to_key();
1685 +void des_string_to_2keys();
1686 +void des_cfb64_encrypt();
1687 +void des_ofb64_encrypt();
1688 +int des_read_pw();
1689 +void des_xwhite_in2out();
1690 +
1691 +/* Extra functions from Mark Murray <mark@grondar.za> */
1692 +/* The following functions are not in the normal unix build or the
1693 + * SSLeay build. When using the SSLeay build, use RAND_seed()
1694 + * and RAND_bytes() instead. */
1695 +#ifdef FreeBSD
1696 +int des_new_random_key();
1697 +void des_init_random_number_generator();
1698 +void des_set_random_generator_seed();
1699 +void des_set_sequence_number();
1700 +void des_generate_random_block();
1701 +#endif
1702 +
1703 +#endif
1704 +
1705 +#ifdef __cplusplus
1706 +}
1707 +#endif
1708 +
1709 +#endif
1710 --- /dev/null Tue Mar 11 13:02:56 2003
1711 +++ linux/include/klips-crypto/ocf_assist.h Mon Feb 9 13:51:03 2004
1712 @@ -0,0 +1,63 @@
1713 +#ifndef _OCF_ASSIST_H
1714 +#define _OCF_ASSIST_H 1
1715 +/****************************************************************************/
1716 +/* The various hw_assist functions return these bits */
1717 +
1718 +#define OCF_PROVIDES_AES 0x0001
1719 +#define OCF_PROVIDES_DES_3DES 0x0002
1720 +
1721 +/****************************************************************************/
1722 +#if !defined(OCF_ASSIST)
1723 +/****************************************************************************/
1724 +/*
1725 + * stub it all out just in case
1726 + */
1727 +
1728 +#define ocf_aes_assist() (0)
1729 +#define ocf_aes_set_key(a1,a2,a3,a4)
1730 +#define ocf_aes_cbc_encrypt(a1,a2,a3,a4,a5,a6)
1731 +
1732 +#define ocf_des_assist() (0)
1733 +#define ocf_des_set_key(a, b)
1734 +#define ocf_des_cbc_encrypt(a1,a2,a3,a4,a5,a6)
1735 +#define ocf_des_encrypt(a1,a2,a3)
1736 +#define ocf_des_ede3_cbc_encrypt(a1,a2,a3,a4,a5,a6,a7,a8)
1737 +#define ocf_des_ncbc_encrypt(a1,a2,a3,a4,a5,a6)
1738 +#define ocf_des_ecb_encrypt(a1,a2,a3,a4)
1739 +
1740 +/****************************************************************************/
1741 +#else
1742 +/****************************************************************************/
1743 +
1744 +#include <sys/types.h>
1745 +#include "aes.h"
1746 +#include "des.h"
1747 +
1748 +extern int ocf_aes_assist(void);
1749 +extern void ocf_aes_set_key(aes_context *cx, const unsigned char in_key[],
1750 + int n_bytes, const int f);
1751 +extern int ocf_aes_cbc_encrypt(aes_context *ctx, const u_int8_t *input,
1752 + u_int8_t *output,
1753 + long length,
1754 + const u_int8_t *ivec, int enc);
1755 +
1756 +extern int ocf_des_assist(void);
1757 +extern int ocf_des_set_key(des_cblock *key, des_key_schedule schedule);
1758 +extern void ocf_des_cbc_encrypt(des_cblock *input, des_cblock *output,
1759 + long length, des_key_schedule schedule,
1760 + des_cblock *ivec, int enc);
1761 +extern void ocf_des_encrypt(DES_LONG *data, des_key_schedule ks, int enc);
1762 +extern void ocf_des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
1763 + long length, des_key_schedule ks1,
1764 + des_key_schedule ks2, des_key_schedule ks3,
1765 + des_cblock *ivec, int enc);
1766 +extern void ocf_des_ncbc_encrypt(des_cblock *input, des_cblock *output,
1767 + long length, des_key_schedule schedule,
1768 + des_cblock *ivec, int enc);
1769 +extern void ocf_des_ecb_encrypt(des_cblock *input, des_cblock *output,
1770 + des_key_schedule ks, int enc);
1771 +
1772 +/****************************************************************************/
1773 +#endif /* !defined(OCF_ASSIST) */
1774 +/****************************************************************************/
1775 +#endif /* _OCF_ASSIST_H */
1776 --- /dev/null Tue Mar 11 13:02:56 2003
1777 +++ linux/include/openswan.h Mon Feb 9 13:51:03 2004
1778 @@ -0,0 +1,569 @@
1779 +#ifndef _OPENSWAN_H
1780 +/*
1781 + * header file for FreeS/WAN library functions
1782 + * Copyright (C) 1998, 1999, 2000 Henry Spencer.
1783 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
1784 + *
1785 + * This library is free software; you can redistribute it and/or modify it
1786 + * under the terms of the GNU Library General Public License as published by
1787 + * the Free Software Foundation; either version 2 of the License, or (at your
1788 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
1789 + *
1790 + * This library is distributed in the hope that it will be useful, but
1791 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1792 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
1793 + * License for more details.
1794 + *
1795 + * RCSID $Id: openswan.h,v 1.95 2005/08/25 01:24:40 paul Exp $
1796 + */
1797 +#define _OPENSWAN_H /* seen it, no need to see it again */
1798 +
1799 +/* you'd think this should be builtin to compiler... */
1800 +#ifndef TRUE
1801 +#define TRUE 1
1802 +#endif
1803 +
1804 +#ifndef FALSE
1805 +#define FALSE 0
1806 +#endif
1807 +
1808 +/*
1809 + * When using uclibc, malloc(0) returns NULL instead of success. This is
1810 + * to make it use the inbuilt work-around.
1811 + * See: http://osdir.com/ml/network.freeswan.devel/2003-11/msg00009.html
1812 + */
1813 +#ifdef __UCLIBC__
1814 +# if !defined(__MALLOC_GLIBC_COMPAT__) && !defined(MALLOC_GLIBC_COMPAT)
1815 +# warning Please compile uclibc with GLIBC_COMPATIBILITY defined
1816 +# endif
1817 +#endif
1818 +
1819 +
1820 +/*
1821 + * We've just got to have some datatypes defined... And annoyingly, just
1822 + * where we get them depends on whether we're in userland or not.
1823 + */
1824 +/* things that need to come from one place or the other, depending */
1825 +#if defined(linux)
1826 +#if defined(__KERNEL__)
1827 +#include <linux/types.h>
1828 +#include <linux/socket.h>
1829 +#include <linux/in.h>
1830 +#include <linux/in6.h>
1831 +#include <linux/string.h>
1832 +#include <linux/ctype.h>
1833 +#include <openswan/ipsec_kversion.h>
1834 +#include <openswan/ipsec_param.h>
1835 +#define user_assert(foo) /*nothing*/
1836 +
1837 +#else /* NOT in kernel */
1838 +#include <sys/types.h>
1839 +#include <netinet/in.h>
1840 +#include <string.h>
1841 +#include <ctype.h>
1842 +#include <assert.h>
1843 +#define user_assert(foo) assert(foo)
1844 +#include <stdio.h>
1845 +
1846 +# define uint8_t u_int8_t
1847 +# define uint16_t u_int16_t
1848 +# define uint32_t u_int32_t
1849 +# define uint64_t u_int64_t
1850 +
1851 +
1852 +
1853 +#endif /* __KERNEL__ */
1854 +
1855 +#endif /* linux */
1856 +
1857 +#define DEBUG_NO_STATIC static
1858 +
1859 +/*
1860 + * Yes Virginia, we have started a windows port.
1861 + */
1862 +#if defined(__CYGWIN32__)
1863 +#if !defined(WIN32_KERNEL)
1864 +/* get windows equivalents */
1865 +#include <stdio.h>
1866 +#include <string.h>
1867 +#include <win32/types.h>
1868 +#include <netinet/in.h>
1869 +#include <cygwin/socket.h>
1870 +#include <assert.h>
1871 +#define user_assert(foo) assert(foo)
1872 +#endif /* _KERNEL */
1873 +#endif /* WIN32 */
1874 +
1875 +/*
1876 + * Kovacs? A macosx port?
1877 + */
1878 +#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
1879 +#include <TargetConditionals.h>
1880 +#include <AvailabilityMacros.h>
1881 +#include <machine/types.h>
1882 +#include <machine/endian.h>
1883 +#include <stdint.h>
1884 +#include <stddef.h>
1885 +#include <stdio.h>
1886 +#include <time.h>
1887 +#include <sys/time.h>
1888 +#include <string.h>
1889 +#include <netinet/in.h>
1890 +#include <arpa/inet.h>
1891 +#include <tcpd.h>
1892 +#include <assert.h>
1893 +#define user_assert(foo) assert(foo)
1894 +#define __u32 unsigned int
1895 +#define __u8 unsigned char
1896 +#define s6_addr16 __u6_addr.__u6_addr16
1897 +#define DEBUG_NO_STATIC static
1898 +#endif
1899 +
1900 +/*
1901 + * FreeBSD
1902 + */
1903 +#if defined(__FreeBSD__)
1904 +# define DEBUG_NO_STATIC static
1905 +#include <sys/types.h>
1906 +#include <netinet/in.h>
1907 +#include <sys/socket.h>
1908 +#include <arpa/inet.h>
1909 +#include <string.h>
1910 +#include <assert.h>
1911 +#define user_assert(foo) assert(foo)
1912 +/* apparently this way to deal with an IPv6 address is not standard. */
1913 +#define s6_addr16 __u6_addr.__u6_addr16
1914 +#endif
1915 +
1916 +
1917 +#ifndef IPPROTO_COMP
1918 +# define IPPROTO_COMP 108
1919 +#endif /* !IPPROTO_COMP */
1920 +
1921 +#ifndef IPPROTO_INT
1922 +# define IPPROTO_INT 61
1923 +#endif /* !IPPROTO_INT */
1924 +
1925 +#if !defined(ESPINUDP_WITH_NON_IKE)
1926 +#define ESPINUDP_WITH_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
1927 +#define ESPINUDP_WITH_NON_ESP 2 /* draft-ietf-ipsec-nat-t-ike-02 */
1928 +#endif
1929 +
1930 +/*
1931 + * Basic data types for the address-handling functions.
1932 + * ip_address and ip_subnet are supposed to be opaque types; do not
1933 + * use their definitions directly, they are subject to change!
1934 + */
1935 +
1936 +/* first, some quick fakes in case we're on an old system with no IPv6 */
1937 +#if !defined(s6_addr16) && defined(__CYGWIN32__)
1938 +struct in6_addr {
1939 + union
1940 + {
1941 + u_int8_t u6_addr8[16];
1942 + u_int16_t u6_addr16[8];
1943 + u_int32_t u6_addr32[4];
1944 + } in6_u;
1945 +#define s6_addr in6_u.u6_addr8
1946 +#define s6_addr16 in6_u.u6_addr16
1947 +#define s6_addr32 in6_u.u6_addr32
1948 +};
1949 +struct sockaddr_in6 {
1950 + unsigned short int sin6_family; /* AF_INET6 */
1951 + __u16 sin6_port; /* Transport layer port # */
1952 + __u32 sin6_flowinfo; /* IPv6 flow information */
1953 + struct in6_addr sin6_addr; /* IPv6 address */
1954 + __u32 sin6_scope_id; /* scope id (new in RFC2553) */
1955 +};
1956 +#endif /* !s6_addr16 */
1957 +
1958 +/* then the main types */
1959 +typedef struct {
1960 + union {
1961 + struct sockaddr_in v4;
1962 + struct sockaddr_in6 v6;
1963 + } u;
1964 +} ip_address;
1965 +typedef struct {
1966 + ip_address addr;
1967 + int maskbits;
1968 +} ip_subnet;
1969 +
1970 +/* and the SA ID stuff */
1971 +#ifdef __KERNEL__
1972 +typedef __u32 ipsec_spi_t;
1973 +#else
1974 +typedef u_int32_t ipsec_spi_t;
1975 +#endif
1976 +typedef struct { /* to identify an SA, we need: */
1977 + ip_address dst; /* A. destination host */
1978 + ipsec_spi_t spi; /* B. 32-bit SPI, assigned by dest. host */
1979 +# define SPI_PASS 256 /* magic values... */
1980 +# define SPI_DROP 257 /* ...for use... */
1981 +# define SPI_REJECT 258 /* ...with SA_INT */
1982 +# define SPI_HOLD 259
1983 +# define SPI_TRAP 260
1984 +# define SPI_TRAPSUBNET 261
1985 + int proto; /* C. protocol */
1986 +# define SA_ESP 50 /* IPPROTO_ESP */
1987 +# define SA_AH 51 /* IPPROTO_AH */
1988 +# define SA_IPIP 4 /* IPPROTO_IPIP */
1989 +# define SA_COMP 108 /* IPPROTO_COMP */
1990 +# define SA_INT 61 /* IANA reserved for internal use */
1991 +} ip_said;
1992 +
1993 +/* misc */
1994 +typedef const char *err_t; /* error message, or NULL for success */
1995 +struct prng { /* pseudo-random-number-generator guts */
1996 + unsigned char sbox[256];
1997 + int i, j;
1998 + unsigned long count;
1999 +};
2000 +
2001 +
2002 +/*
2003 + * definitions for user space, taken from freeswan/ipsec_sa.h
2004 + */
2005 +typedef uint32_t IPsecSAref_t;
2006 +
2007 +/* Translation to/from nfmark.
2008 + *
2009 + * use bits 16-31. Leave bit 32 as a indicate that IPsec processing
2010 + * has already been done.
2011 + */
2012 +#define IPSEC_SA_REF_TABLE_IDX_WIDTH 15
2013 +#define IPSEC_SA_REF_TABLE_OFFSET 16
2014 +#define IPSEC_SA_REF_MAASK ((1<<IPSEC_SA_REF_TABLE_IDX_WIDTH)-1)
2015 +
2016 +#define IPsecSAref2NFmark(x) (((x)&IPSEC_SA_REF_MASK) << IPSEC_SA_REF_TABLE_OFFSET)
2017 +#define NFmark2IPsecSAref(x) (((x) >> IPSEC_SA_REF_TABLE_OFFSET)&IPSEC_SA_REF_MASK)
2018 +
2019 +#define IPSEC_SAREF_NULL ((IPsecSAref_t)0)
2020 +#define IPSEC_SAREF_NA ((IPsecSAref_t)0xffff0001)
2021 +
2022 +/* GCC magic for use in function definitions! */
2023 +#ifdef GCC_LINT
2024 +# define PRINTF_LIKE(n) __attribute__ ((format(printf, n, n+1)))
2025 +# define NEVER_RETURNS __attribute__ ((noreturn))
2026 +# define UNUSED __attribute__ ((unused))
2027 +# define BLANK_FORMAT " " /* GCC_LINT whines about empty formats */
2028 +#else
2029 +# define PRINTF_LIKE(n) /* ignore */
2030 +# define NEVER_RETURNS /* ignore */
2031 +# define UNUSED /* ignore */
2032 +# define BLANK_FORMAT ""
2033 +#endif
2034 +
2035 +
2036 +/*
2037 + * function to log stuff from libraries that may be used in multiple
2038 + * places.
2039 + */
2040 +typedef int (*openswan_keying_debug_func_t)(const char *message, ...);
2041 +
2042 +
2043 +
2044 +/*
2045 + * new IPv6-compatible functions
2046 + */
2047 +
2048 +/* text conversions */
2049 +err_t ttoul(const char *src, size_t srclen, int format, unsigned long *dst);
2050 +size_t ultot(unsigned long src, int format, char *buf, size_t buflen);
2051 +#define ULTOT_BUF (22+1) /* holds 64 bits in octal */
2052 +
2053 +/* looks up names in DNS */
2054 +err_t ttoaddr(const char *src, size_t srclen, int af, ip_address *dst);
2055 +
2056 +/* does not look up names in DNS */
2057 +err_t ttoaddr_num(const char *src, size_t srclen, int af, ip_address *dst);
2058 +
2059 +err_t tnatoaddr(const char *src, size_t srclen, int af, ip_address *dst);
2060 +size_t addrtot(const ip_address *src, int format, char *buf, size_t buflen);
2061 +/* RFC 1886 old IPv6 reverse-lookup format is the bulkiest */
2062 +#define ADDRTOT_BUF (32*2 + 3 + 1 + 3 + 1 + 1)
2063 +err_t ttosubnet(const char *src, size_t srclen, int af, ip_subnet *dst);
2064 +size_t subnettot(const ip_subnet *src, int format, char *buf, size_t buflen);
2065 +#define SUBNETTOT_BUF (ADDRTOT_BUF + 1 + 3)
2066 +size_t subnetporttot(const ip_subnet *src, int format, char *buf, size_t buflen);
2067 +#define SUBNETPROTOTOT_BUF (SUBNETTOTO_BUF + ULTOT_BUF)
2068 +err_t ttosa(const char *src, size_t srclen, ip_said *dst);
2069 +size_t satot(const ip_said *src, int format, char *bufptr, size_t buflen);
2070 +#define SATOT_BUF (5 + ULTOA_BUF + 1 + ADDRTOT_BUF)
2071 +err_t ttodata(const char *src, size_t srclen, int base, char *buf,
2072 + size_t buflen, size_t *needed);
2073 +err_t ttodatav(const char *src, size_t srclen, int base,
2074 + char *buf, size_t buflen, size_t *needed,
2075 + char *errp, size_t errlen, unsigned int flags);
2076 +#define TTODATAV_BUF 40 /* ttodatav's largest non-literal message */
2077 +#define TTODATAV_IGNORESPACE (1<<1) /* ignore spaces in base64 encodings*/
2078 +#define TTODATAV_SPACECOUNTS 0 /* do not ignore spaces in base64 */
2079 +
2080 +size_t datatot(const unsigned char *src, size_t srclen, int format
2081 + , char *buf, size_t buflen);
2082 +size_t keyblobtoid(const unsigned char *src, size_t srclen, char *dst,
2083 + size_t dstlen);
2084 +size_t splitkeytoid(const unsigned char *e, size_t elen, const unsigned char *m,
2085 + size_t mlen, char *dst, size_t dstlen);
2086 +#define KEYID_BUF 10 /* up to 9 text digits plus NUL */
2087 +err_t ttoprotoport(char *src, size_t src_len, u_int8_t *proto, u_int16_t *port,
2088 + int *has_port_wildcard);
2089 +
2090 +/* initializations */
2091 +void initsaid(const ip_address *addr, ipsec_spi_t spi, int proto, ip_said *dst);
2092 +err_t loopbackaddr(int af, ip_address *dst);
2093 +err_t unspecaddr(int af, ip_address *dst);
2094 +err_t anyaddr(int af, ip_address *dst);
2095 +err_t initaddr(const unsigned char *src, size_t srclen, int af, ip_address *dst);
2096 +err_t add_port(int af, ip_address *addr, unsigned short port);
2097 +err_t initsubnet(const ip_address *addr, int maskbits, int clash, ip_subnet *dst);
2098 +err_t addrtosubnet(const ip_address *addr, ip_subnet *dst);
2099 +
2100 +/* misc. conversions and related */
2101 +err_t rangetosubnet(const ip_address *from, const ip_address *to, ip_subnet *dst);
2102 +int addrtypeof(const ip_address *src);
2103 +int subnettypeof(const ip_subnet *src);
2104 +size_t addrlenof(const ip_address *src);
2105 +size_t addrbytesptr(const ip_address *src, const unsigned char **dst);
2106 +size_t addrbytesptr_write(ip_address *src, unsigned char **dst);
2107 +size_t addrbytesof(const ip_address *src, unsigned char *dst, size_t dstlen);
2108 +int masktocount(const ip_address *src);
2109 +void networkof(const ip_subnet *src, ip_address *dst);
2110 +void maskof(const ip_subnet *src, ip_address *dst);
2111 +
2112 +/* tests */
2113 +int sameaddr(const ip_address *a, const ip_address *b);
2114 +int addrcmp(const ip_address *a, const ip_address *b);
2115 +int samesubnet(const ip_subnet *a, const ip_subnet *b);
2116 +int addrinsubnet(const ip_address *a, const ip_subnet *s);
2117 +int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);
2118 +int subnetishost(const ip_subnet *s);
2119 +int samesaid(const ip_said *a, const ip_said *b);
2120 +int sameaddrtype(const ip_address *a, const ip_address *b);
2121 +int samesubnettype(const ip_subnet *a, const ip_subnet *b);
2122 +int isvalidsubnet(const ip_subnet *a);
2123 +int isanyaddr(const ip_address *src);
2124 +int isunspecaddr(const ip_address *src);
2125 +int isloopbackaddr(const ip_address *src);
2126 +
2127 +/* low-level grot */
2128 +int portof(const ip_address *src);
2129 +void setportof(int port, ip_address *dst);
2130 +struct sockaddr *sockaddrof(ip_address *src);
2131 +size_t sockaddrlenof(const ip_address *src);
2132 +
2133 +/* PRNG */
2134 +void prng_init(struct prng *prng, const unsigned char *key, size_t keylen);
2135 +void prng_bytes(struct prng *prng, unsigned char *dst, size_t dstlen);
2136 +unsigned long prng_count(struct prng *prng);
2137 +void prng_final(struct prng *prng);
2138 +
2139 +/* odds and ends */
2140 +const char *ipsec_version_code(void);
2141 +const char *ipsec_version_string(void);
2142 +const char **ipsec_copyright_notice(void);
2143 +
2144 +const char *dns_string_rr(int rr, char *buf, int bufsize);
2145 +const char *dns_string_datetime(time_t seconds,
2146 + char *buf,
2147 + int bufsize);
2148 +
2149 +
2150 +/*
2151 + * old functions, to be deleted eventually
2152 + */
2153 +
2154 +/* unsigned long */
2155 +const char * /* NULL for success, else string literal */
2156 +atoul(
2157 + const char *src,
2158 + size_t srclen, /* 0 means strlen(src) */
2159 + int base, /* 0 means figure it out */
2160 + unsigned long *resultp
2161 +);
2162 +size_t /* space needed for full conversion */
2163 +ultoa(
2164 + unsigned long n,
2165 + int base,
2166 + char *dst,
2167 + size_t dstlen
2168 +);
2169 +#define ULTOA_BUF 21 /* just large enough for largest result, */
2170 + /* assuming 64-bit unsigned long! */
2171 +
2172 +/* Internet addresses */
2173 +const char * /* NULL for success, else string literal */
2174 +atoaddr(
2175 + const char *src,
2176 + size_t srclen, /* 0 means strlen(src) */
2177 + struct in_addr *addr
2178 +);
2179 +size_t /* space needed for full conversion */
2180 +addrtoa(
2181 + struct in_addr addr,
2182 + int format, /* character; 0 means default */
2183 + char *dst,
2184 + size_t dstlen
2185 +);
2186 +#define ADDRTOA_BUF 16 /* just large enough for largest result */
2187 +
2188 +/* subnets */
2189 +const char * /* NULL for success, else string literal */
2190 +atosubnet(
2191 + const char *src,
2192 + size_t srclen, /* 0 means strlen(src) */
2193 + struct in_addr *addr,
2194 + struct in_addr *mask
2195 +);
2196 +size_t /* space needed for full conversion */
2197 +subnettoa(
2198 + struct in_addr addr,
2199 + struct in_addr mask,
2200 + int format, /* character; 0 means default */
2201 + char *dst,
2202 + size_t dstlen
2203 +);
2204 +#define SUBNETTOA_BUF 32 /* large enough for worst case result */
2205 +
2206 +/* ranges */
2207 +const char * /* NULL for success, else string literal */
2208 +atoasr(
2209 + const char *src,
2210 + size_t srclen, /* 0 means strlen(src) */
2211 + char *type, /* 'a', 's', 'r' */
2212 + struct in_addr *addrs /* two-element array */
2213 +);
2214 +size_t /* space needed for full conversion */
2215 +rangetoa(
2216 + struct in_addr *addrs, /* two-element array */
2217 + int format, /* character; 0 means default */
2218 + char *dst,
2219 + size_t dstlen
2220 +);
2221 +#define RANGETOA_BUF 34 /* large enough for worst case result */
2222 +
2223 +/* data types for SA conversion functions */
2224 +
2225 +/* generic data, e.g. keys */
2226 +const char * /* NULL for success, else string literal */
2227 +atobytes(
2228 + const char *src,
2229 + size_t srclen, /* 0 means strlen(src) */
2230 + char *dst,
2231 + size_t dstlen,
2232 + size_t *lenp /* NULL means don't bother telling me */
2233 +);
2234 +size_t /* 0 failure, else true size */
2235 +bytestoa(
2236 + const unsigned char *src,
2237 + size_t srclen,
2238 + int format, /* character; 0 means default */
2239 + char *dst,
2240 + size_t dstlen
2241 +);
2242 +
2243 +/* old versions of generic-data functions; deprecated */
2244 +size_t /* 0 failure, else true size */
2245 +atodata(
2246 + const char *src,
2247 + size_t srclen, /* 0 means strlen(src) */
2248 + char *dst,
2249 + size_t dstlen
2250 +);
2251 +size_t /* 0 failure, else true size */
2252 +datatoa(
2253 + const unsigned char *src,
2254 + size_t srclen,
2255 + int format, /* character; 0 means default */
2256 + char *dst,
2257 + size_t dstlen
2258 +);
2259 +
2260 +/* part extraction and special addresses */
2261 +struct in_addr
2262 +subnetof(
2263 + struct in_addr addr,
2264 + struct in_addr mask
2265 +);
2266 +struct in_addr
2267 +hostof(
2268 + struct in_addr addr,
2269 + struct in_addr mask
2270 +);
2271 +struct in_addr
2272 +broadcastof(
2273 + struct in_addr addr,
2274 + struct in_addr mask
2275 +);
2276 +
2277 +/* mask handling */
2278 +int
2279 +goodmask(
2280 + struct in_addr mask
2281 +);
2282 +extern int masktobits(struct in_addr mask);
2283 +extern struct in_addr bitstomask(int n);
2284 +extern struct in6_addr bitstomask6(int n);
2285 +
2286 +
2287 +
2288 +/*
2289 + * ENUM of klips debugging values. Not currently used in klips.
2290 + * debug flag is actually 32 -bits, but only one bit is ever used,
2291 + * so we can actually pack it all into a single 32-bit word.
2292 + */
2293 +enum klips_debug_flags {
2294 + KDF_VERBOSE = 0,
2295 + KDF_XMIT = 1,
2296 + KDF_NETLINK = 2, /* obsolete */
2297 + KDF_XFORM = 3,
2298 + KDF_EROUTE = 4,
2299 + KDF_SPI = 5,
2300 + KDF_RADIJ = 6,
2301 + KDF_ESP = 7,
2302 + KDF_AH = 8, /* obsolete */
2303 + KDF_RCV = 9,
2304 + KDF_TUNNEL = 10,
2305 + KDF_PFKEY = 11,
2306 + KDF_COMP = 12,
2307 + KDF_NATT = 13,
2308 +};
2309 +
2310 +
2311 +/*
2312 + * Debugging levels for pfkey_lib_debug
2313 + */
2314 +#define PF_KEY_DEBUG_PARSE_NONE 0
2315 +#define PF_KEY_DEBUG_PARSE_PROBLEM 1
2316 +#define PF_KEY_DEBUG_PARSE_STRUCT 2
2317 +#define PF_KEY_DEBUG_PARSE_FLOW 4
2318 +#define PF_KEY_DEBUG_BUILD 8
2319 +#define PF_KEY_DEBUG_PARSE_MAX 15
2320 +
2321 +extern unsigned int pfkey_lib_debug; /* bits selecting what to report */
2322 +
2323 +/*
2324 + * pluto and lwdnsq need to know the maximum size of the commands to,
2325 + * and replies from lwdnsq.
2326 + */
2327 +
2328 +#define LWDNSQ_CMDBUF_LEN 1024
2329 +#define LWDNSQ_RESULT_LEN_MAX 4096
2330 +
2331 +
2332 +/* syntax for passthrough SA */
2333 +#ifndef PASSTHROUGHNAME
2334 +#define PASSTHROUGHNAME "%passthrough"
2335 +#define PASSTHROUGH4NAME "%passthrough4"
2336 +#define PASSTHROUGH6NAME "%passthrough6"
2337 +#define PASSTHROUGHIS "tun0@0.0.0.0"
2338 +#define PASSTHROUGH4IS "tun0@0.0.0.0"
2339 +#define PASSTHROUGH6IS "tun0@::"
2340 +#define PASSTHROUGHTYPE "tun"
2341 +#define PASSTHROUGHSPI 0
2342 +#define PASSTHROUGHDST 0
2343 +#endif
2344 +
2345 +
2346 +
2347 +#endif /* _OPENSWAN_H */
2348 --- /dev/null Tue Mar 11 13:02:56 2003
2349 +++ linux/include/openswan/ipcomp.h Mon Feb 9 13:51:03 2004
2350 @@ -0,0 +1,58 @@
2351 +/*
2352 + * IPCOMP zlib interface code.
2353 + * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
2354 + * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
2355 + *
2356 + * This program is free software; you can redistribute it and/or modify it
2357 + * under the terms of the GNU General Public License as published by the
2358 + * Free Software Foundation; either version 2 of the License, or (at your
2359 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2360 + *
2361 + * This program is distributed in the hope that it will be useful, but
2362 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2363 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2364 + * for more details.
2365 +
2366 + RCSID $Id: ipcomp.h,v 1.14 2004/07/10 19:08:41 mcr Exp $
2367 +
2368 + */
2369 +
2370 +/* SSS */
2371 +
2372 +#ifndef _IPCOMP_H
2373 +#define _IPCOMP_H
2374 +
2375 +/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
2376 +#ifndef IPCOMP_PREFIX
2377 +#define IPCOMP_PREFIX
2378 +#endif /* IPCOMP_PREFIX */
2379 +
2380 +#ifndef IPPROTO_COMP
2381 +#define IPPROTO_COMP 108
2382 +#endif /* IPPROTO_COMP */
2383 +
2384 +#include "openswan/ipsec_sysctl.h"
2385 +
2386 +struct ipcomphdr { /* IPCOMP header */
2387 + __u8 ipcomp_nh; /* Next header (protocol) */
2388 + __u8 ipcomp_flags; /* Reserved, must be 0 */
2389 + __u16 ipcomp_cpi; /* Compression Parameter Index */
2390 +};
2391 +
2392 +extern struct inet_protocol comp_protocol;
2393 +
2394 +#define IPCOMP_UNCOMPRESSABLE 0x000000001
2395 +#define IPCOMP_COMPRESSIONERROR 0x000000002
2396 +#define IPCOMP_PARMERROR 0x000000004
2397 +#define IPCOMP_DECOMPRESSIONERROR 0x000000008
2398 +
2399 +#define IPCOMP_ADAPT_INITIAL_TRIES 8
2400 +#define IPCOMP_ADAPT_INITIAL_SKIP 4
2401 +#define IPCOMP_ADAPT_SUBSEQ_TRIES 2
2402 +#define IPCOMP_ADAPT_SUBSEQ_SKIP 8
2403 +
2404 +/* Function prototypes */
2405 +struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
2406 +struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
2407 +
2408 +#endif /* _IPCOMP_H */
2409 --- /dev/null Tue Mar 11 13:02:56 2003
2410 +++ linux/include/openswan/ipsec_ah.h Mon Feb 9 13:51:03 2004
2411 @@ -0,0 +1,201 @@
2412 +/*
2413 + * Authentication Header declarations
2414 + * Copyright (C) 1996, 1997 John Ioannidis.
2415 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
2416 + *
2417 + * This program is free software; you can redistribute it and/or modify it
2418 + * under the terms of the GNU General Public License as published by the
2419 + * Free Software Foundation; either version 2 of the License, or (at your
2420 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2421 + *
2422 + * This program is distributed in the hope that it will be useful, but
2423 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2424 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2425 + * for more details.
2426 + *
2427 + * RCSID $Id: ipsec_ah.h,v 1.26 2004/09/13 02:22:10 mcr Exp $
2428 + */
2429 +
2430 +#include "ipsec_md5h.h"
2431 +#include "ipsec_sha1.h"
2432 +
2433 +#ifndef IPPROTO_AH
2434 +#define IPPROTO_AH 51
2435 +#endif /* IPPROTO_AH */
2436 +
2437 +#include "ipsec_auth.h"
2438 +
2439 +#ifdef __KERNEL__
2440 +
2441 +#ifndef CONFIG_XFRM_ALTERNATE_STACK
2442 +extern struct inet_protocol ah_protocol;
2443 +#endif /* CONFIG_XFRM_ALTERNATE_STACK */
2444 +
2445 +struct options;
2446 +
2447 +struct ahhdr /* Generic AH header */
2448 +{
2449 + __u8 ah_nh; /* Next header (protocol) */
2450 + __u8 ah_hl; /* AH length, in 32-bit words */
2451 + __u16 ah_rv; /* reserved, must be 0 */
2452 + __u32 ah_spi; /* Security Parameters Index */
2453 + __u32 ah_rpl; /* Replay prevention */
2454 + __u8 ah_data[AHHMAC_HASHLEN];/* Authentication hash */
2455 +};
2456 +#define AH_BASIC_LEN 8 /* basic AH header is 8 bytes, nh,hl,rv,spi
2457 + * and the ah_hl, says how many bytes after that
2458 + * to cover. */
2459 +
2460 +extern struct xform_functions ah_xform_funcs[];
2461 +
2462 +#include "openswan/ipsec_sysctl.h"
2463 +
2464 +#endif /* __KERNEL__ */
2465 +
2466 +/*
2467 + * $Log: ipsec_ah.h,v $
2468 + * Revision 1.26 2004/09/13 02:22:10 mcr
2469 + * #define inet_protocol if necessary.
2470 + *
2471 + * Revision 1.25 2004/09/06 18:35:41 mcr
2472 + * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
2473 + * so adjust for that.
2474 + *
2475 + * Revision 1.24 2004/07/10 19:08:41 mcr
2476 + * CONFIG_IPSEC -> CONFIG_KLIPS.
2477 + *
2478 + * Revision 1.23 2004/04/05 19:55:04 mcr
2479 + * Moved from linux/include/freeswan/ipsec_ah.h,v
2480 + *
2481 + * Revision 1.22 2004/04/05 19:41:05 mcr
2482 + * merged alg-branch code.
2483 + *
2484 + * Revision 1.21 2003/12/13 19:10:16 mcr
2485 + * refactored rcv and xmit code - same as FS 2.05.
2486 + *
2487 + * Revision 1.22 2003/12/11 20:14:58 mcr
2488 + * refactored the xmit code, to move all encapsulation
2489 + * code into protocol functions. Note that all functions
2490 + * are essentially done by a single function, which is probably
2491 + * wrong.
2492 + * the rcv_functions structures are renamed xform_functions.
2493 + *
2494 + * Revision 1.21 2003/12/06 21:21:19 mcr
2495 + * split up receive path into per-transform files, for
2496 + * easier later removal.
2497 + *
2498 + * Revision 1.20.8.1 2003/12/22 15:25:52 jjo
2499 + * Merged algo-0.8.1-rc11-test1 into alg-branch
2500 + *
2501 + * Revision 1.20 2003/02/06 02:21:34 rgb
2502 + *
2503 + * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
2504 + * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
2505 + * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
2506 + *
2507 + * Revision 1.19 2002/09/16 21:19:13 mcr
2508 + * fixes for west-ah-icmp-01 - length of AH header must be
2509 + * calculated properly, and next_header field properly copied.
2510 + *
2511 + * Revision 1.18 2002/05/14 02:37:02 rgb
2512 + * Change reference from _TDB to _IPSA.
2513 + *
2514 + * Revision 1.17 2002/04/24 07:36:46 mcr
2515 + * Moved from ./klips/net/ipsec/ipsec_ah.h,v
2516 + *
2517 + * Revision 1.16 2002/02/20 01:27:06 rgb
2518 + * Ditched a pile of structs only used by the old Netlink interface.
2519 + *
2520 + * Revision 1.15 2001/12/11 02:35:57 rgb
2521 + * Change "struct net_device" to "struct device" for 2.2 compatibility.
2522 + *
2523 + * Revision 1.14 2001/11/26 09:23:47 rgb
2524 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
2525 + *
2526 + * Revision 1.13.2.1 2001/09/25 02:18:24 mcr
2527 + * replace "struct device" with "struct netdevice"
2528 + *
2529 + * Revision 1.13 2001/06/14 19:35:08 rgb
2530 + * Update copyright date.
2531 + *
2532 + * Revision 1.12 2000/09/12 03:21:20 rgb
2533 + * Cleared out unused htonq.
2534 + *
2535 + * Revision 1.11 2000/09/08 19:12:55 rgb
2536 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
2537 + *
2538 + * Revision 1.10 2000/01/21 06:13:10 rgb
2539 + * Tidied up spacing.
2540 + * Added macros for HMAC padding magic numbers.(kravietz)
2541 + *
2542 + * Revision 1.9 1999/12/07 18:16:23 rgb
2543 + * Fixed comments at end of #endif lines.
2544 + *
2545 + * Revision 1.8 1999/04/11 00:28:56 henry
2546 + * GPL boilerplate
2547 + *
2548 + * Revision 1.7 1999/04/06 04:54:25 rgb
2549 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
2550 + * patch shell fixes.
2551 + *
2552 + * Revision 1.6 1999/01/26 02:06:01 rgb
2553 + * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
2554 + *
2555 + * Revision 1.5 1999/01/22 06:17:49 rgb
2556 + * Updated macro comments.
2557 + * Added context types to support algorithm switch code.
2558 + * 64-bit clean-up -- converting 'u long long' to __u64.
2559 + *
2560 + * Revision 1.4 1998/07/14 15:54:56 rgb
2561 + * Add #ifdef __KERNEL__ to protect kernel-only structures.
2562 + *
2563 + * Revision 1.3 1998/06/30 18:05:16 rgb
2564 + * Comment out references to htonq.
2565 + *
2566 + * Revision 1.2 1998/06/25 19:33:46 rgb
2567 + * Add prototype for protocol receive function.
2568 + * Rearrange for more logical layout.
2569 + *
2570 + * Revision 1.1 1998/06/18 21:27:43 henry
2571 + * move sources from klips/src to klips/net/ipsec, to keep stupid
2572 + * kernel-build scripts happier in the presence of symlinks
2573 + *
2574 + * Revision 1.4 1998/05/18 22:28:43 rgb
2575 + * Disable key printing facilities from /proc/net/ipsec_*.
2576 + *
2577 + * Revision 1.3 1998/04/21 21:29:07 rgb
2578 + * Rearrange debug switches to change on the fly debug output from user
2579 + * space. Only kernel changes checked in at this time. radij.c was also
2580 + * changed to temporarily remove buggy debugging code in rj_delete causing
2581 + * an OOPS and hence, netlink device open errors.
2582 + *
2583 + * Revision 1.2 1998/04/12 22:03:17 rgb
2584 + * Updated ESP-3DES-HMAC-MD5-96,
2585 + * ESP-DES-HMAC-MD5-96,
2586 + * AH-HMAC-MD5-96,
2587 + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
2588 + * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
2589 + *
2590 + * Fixed eroute references in /proc/net/ipsec*.
2591 + *
2592 + * Started to patch module unloading memory leaks in ipsec_netlink and
2593 + * radij tree unloading.
2594 + *
2595 + * Revision 1.1 1998/04/09 03:05:55 henry
2596 + * sources moved up from linux/net/ipsec
2597 + *
2598 + * Revision 1.1.1.1 1998/04/08 05:35:02 henry
2599 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
2600 + *
2601 + * Revision 0.4 1997/01/15 01:28:15 ji
2602 + * Added definitions for new AH transforms.
2603 + *
2604 + * Revision 0.3 1996/11/20 14:35:48 ji
2605 + * Minor Cleanup.
2606 + * Rationalized debugging code.
2607 + *
2608 + * Revision 0.2 1996/11/02 00:18:33 ji
2609 + * First limited release.
2610 + *
2611 + *
2612 + */
2613 --- /dev/null Tue Mar 11 13:02:56 2003
2614 +++ linux/include/openswan/ipsec_alg.h Mon Feb 9 13:51:03 2004
2615 @@ -0,0 +1,248 @@
2616 +/*
2617 + * Modular extensions service and registration functions interface
2618 + *
2619 + * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
2620 + *
2621 + * ipsec_alg.h,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
2622 + *
2623 + */
2624 +/*
2625 + * This program is free software; you can redistribute it and/or modify it
2626 + * under the terms of the GNU General Public License as published by the
2627 + * Free Software Foundation; either version 2 of the License, or (at your
2628 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2629 + *
2630 + * This program is distributed in the hope that it will be useful, but
2631 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2632 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2633 + * for more details.
2634 + *
2635 + */
2636 +#ifndef IPSEC_ALG_H
2637 +#define IPSEC_ALG_H
2638 +
2639 +/*
2640 + * gcc >= 3.2 has removed __FUNCTION__, replaced by C99 __func__
2641 + * *BUT* its a compiler variable.
2642 + */
2643 +#if (__GNUC__ >= 3)
2644 +#ifndef __FUNCTION__
2645 +#define __FUNCTION__ __func__
2646 +#endif
2647 +#endif
2648 +
2649 +/* Version 0.8.1-0 */
2650 +#define IPSEC_ALG_VERSION 0x00080100
2651 +
2652 +#include <linux/types.h>
2653 +#include <linux/list.h>
2654 +#include <asm/atomic.h>
2655 +#include <openswan/pfkey.h>
2656 +
2657 +/*
2658 + * The following structs are used via pointers in ipsec_alg object to
2659 + * avoid ipsec_alg.h coupling with freeswan headers, thus simplifying
2660 + * module development
2661 + */
2662 +struct ipsec_sa;
2663 +struct esp;
2664 +
2665 +/**************************************
2666 + *
2667 + * Main registration object
2668 + *
2669 + *************************************/
2670 +#define IPSEC_ALG_VERSION_QUAD(v) \
2671 + (v>>24),((v>>16)&0xff),((v>>8)&0xff),(v&0xff)
2672 +/*
2673 + * Main ipsec_alg objects: "OOPrograming wannabe"
2674 + * Hierachy (carefully handled with _minimal_ cast'ing):
2675 + *
2676 + * ipsec_alg+
2677 + * +->ipsec_alg_enc (ixt_alg_type=SADB_EXT_SUPPORTED_ENCRYPT)
2678 + * +->ipsec_alg_auth (ixt_alg_type=SADB_EXT_SUPPORTED_AUTH)
2679 + */
2680 +
2681 +/***************************************************************
2682 + *
2683 + * INTERFACE object: struct ipsec_alg
2684 + *
2685 + ***************************************************************/
2686 +
2687 +#define ixt_alg_type ixt_support.ias_exttype
2688 +#define ixt_alg_id ixt_support.ias_id
2689 +
2690 +#define IPSEC_ALG_ST_SUPP 0x01
2691 +#define IPSEC_ALG_ST_REGISTERED 0x02
2692 +#define IPSEC_ALG_ST_EXCL 0x04
2693 +struct ipsec_alg {
2694 + unsigned ixt_version; /* only allow this version (or 'near')*/ \
2695 + struct list_head ixt_list; /* dlinked list */ \
2696 + struct module *ixt_module; /* THIS_MODULE */ \
2697 + unsigned ixt_state; /* state flags */ \
2698 + atomic_t ixt_refcnt; /* ref. count when pointed from ipsec_sa */ \
2699 + char ixt_name[16]; /* descriptive short name, eg. "3des" */ \
2700 + void *ixt_data; /* private for algo implementation */ \
2701 + uint8_t ixt_blocksize; /* blocksize in bytes */ \
2702 +
2703 + struct ipsec_alg_supported ixt_support;
2704 +};
2705 +/*
2706 + * Note the const in cbc_encrypt IV arg:
2707 + * some ciphers like to toast passed IV (eg. 3DES): make a local IV copy
2708 + */
2709 +struct ipsec_alg_enc {
2710 + struct ipsec_alg ixt_common;
2711 + unsigned ixt_e_keylen; /* raw key length in bytes */
2712 + unsigned ixt_e_ctx_size; /* sa_p->key_e_size */
2713 + int (*ixt_e_set_key)(struct ipsec_alg_enc *alg, __u8 *key_e, const __u8 *key, size_t keysize);
2714 + __u8 *(*ixt_e_new_key)(struct ipsec_alg_enc *alg, const __u8 *key, size_t keysize);
2715 + void (*ixt_e_destroy_key)(struct ipsec_alg_enc *alg, __u8 *key_e);
2716 + int (*ixt_e_cbc_encrypt)(struct ipsec_alg_enc *alg, __u8 *key_e, __u8 *in, int ilen, __u8 *iv, int encrypt);
2717 +};
2718 +struct ipsec_alg_auth {
2719 + struct ipsec_alg ixt_common;
2720 + unsigned ixt_a_keylen; /* raw key length in bytes */
2721 + unsigned ixt_a_ctx_size; /* sa_p->key_a_size */
2722 + unsigned ixt_a_authlen; /* 'natural' auth. hash len (bytes) */
2723 + int (*ixt_a_hmac_set_key)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *key, int keylen);
2724 + int (*ixt_a_hmac_hash)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *dat, int len, __u8 *hash, int hashlen);
2725 +};
2726 +/*
2727 + * These are _copies_ of SADB_EXT_SUPPORTED_{AUTH,ENCRYPT},
2728 + * to avoid header coupling for true constants
2729 + * about headers ... "cp is your friend" --Linus
2730 + */
2731 +#define IPSEC_ALG_TYPE_AUTH 14
2732 +#define IPSEC_ALG_TYPE_ENCRYPT 15
2733 +
2734 +/***************************************************************
2735 + *
2736 + * INTERFACE for module loading,testing, and unloading
2737 + *
2738 + ***************************************************************/
2739 +/* - registration calls */
2740 +int register_ipsec_alg(struct ipsec_alg *);
2741 +int unregister_ipsec_alg(struct ipsec_alg *);
2742 +/* - optional (simple test) for algos */
2743 +int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int testparm);
2744 +/* inline wrappers (usefull for type validation */
2745 +static inline int register_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
2746 + return register_ipsec_alg((struct ipsec_alg*)ixt);
2747 +}
2748 +static inline int unregister_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
2749 + return unregister_ipsec_alg((struct ipsec_alg*)ixt);
2750 +}
2751 +static inline int register_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
2752 + return register_ipsec_alg((struct ipsec_alg*)ixt);
2753 +}
2754 +static inline int unregister_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
2755 + return unregister_ipsec_alg((struct ipsec_alg*)ixt);
2756 +}
2757 +
2758 +/*****************************************************************
2759 + *
2760 + * INTERFACE for ENC services: key creation, encrypt function
2761 + *
2762 + *****************************************************************/
2763 +
2764 +#define IPSEC_ALG_ENCRYPT 1
2765 +#define IPSEC_ALG_DECRYPT 0
2766 +
2767 +/* encryption key context creation function */
2768 +int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p);
2769 +/*
2770 + * ipsec_alg_esp_encrypt(): encrypt ilen bytes in idat returns
2771 + * 0 or ERR<0
2772 + */
2773 +int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 *idat, int ilen, __u8 *iv, int action);
2774 +
2775 +/***************************************************************
2776 + *
2777 + * INTERFACE for AUTH services: key creation, hash functions
2778 + *
2779 + ***************************************************************/
2780 +int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p);
2781 +int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) ;
2782 +#define ipsec_alg_sa_esp_update(c,k,l) ipsec_alg_sa_esp_hash(c,k,l,NULL,0)
2783 +
2784 +/* only called from ipsec_init.c */
2785 +int ipsec_alg_init(void);
2786 +
2787 +/* algo module glue for static algos */
2788 +void ipsec_alg_static_init(void);
2789 +typedef int (*ipsec_alg_init_func_t) (void);
2790 +
2791 +/**********************************************
2792 + *
2793 + * INTERFACE for ipsec_sa init and wipe
2794 + *
2795 + **********************************************/
2796 +
2797 +/* returns true if ipsec_sa has ipsec_alg obj attached */
2798 +/*
2799 + * Initializes ipsec_sa's ipsec_alg object, using already loaded
2800 + * proto, authalg, encalg.; links ipsec_alg objects (enc, auth)
2801 + */
2802 +int ipsec_alg_sa_init(struct ipsec_sa *sa_p);
2803 +/*
2804 + * Destroys ipsec_sa's ipsec_alg object
2805 + * unlinking ipsec_alg objects
2806 + */
2807 +int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p);
2808 +
2809 +#define IPSEC_ALG_MODULE_INIT_MOD( func_name ) \
2810 + static int func_name(void); \
2811 + module_init(func_name); \
2812 + static int __init func_name(void)
2813 +#define IPSEC_ALG_MODULE_EXIT_MOD( func_name ) \
2814 + static void func_name(void); \
2815 + module_exit(func_name); \
2816 + static void __exit func_name(void)
2817 +
2818 +#define IPSEC_ALG_MODULE_INIT_STATIC( func_name ) \
2819 + extern int func_name(void); \
2820 + int func_name(void)
2821 +#define IPSEC_ALG_MODULE_EXIT_STATIC( func_name ) \
2822 + extern void func_name(void); \
2823 + void func_name(void)
2824 +
2825 +/**********************************************
2826 + *
2827 + * 2.2 backport for some 2.4 useful module stuff
2828 + *
2829 + **********************************************/
2830 +#ifdef MODULE
2831 +#ifndef THIS_MODULE
2832 +#define THIS_MODULE (&__this_module)
2833 +#endif
2834 +#ifndef module_init
2835 +typedef int (*__init_module_func_t)(void);
2836 +typedef void (*__cleanup_module_func_t)(void);
2837 +
2838 +#define module_init(x) \
2839 + int init_module(void) __attribute__((alias(#x))); \
2840 + static inline __init_module_func_t __init_module_inline(void) \
2841 + { return x; }
2842 +#define module_exit(x) \
2843 + void cleanup_module(void) __attribute__((alias(#x))); \
2844 + static inline __cleanup_module_func_t __cleanup_module_inline(void) \
2845 + { return x; }
2846 +#endif
2847 +#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_MOD( func_name )
2848 +#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_MOD( func_name )
2849 +
2850 +#else /* not MODULE */
2851 +#ifndef THIS_MODULE
2852 +#define THIS_MODULE NULL
2853 +#endif
2854 +/*
2855 + * I only want module_init() magic
2856 + * when algo.c file *is THE MODULE*, in all other
2857 + * cases, initialization is called explicitely from ipsec_alg_init()
2858 + */
2859 +#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_STATIC(func_name)
2860 +#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_STATIC(func_name)
2861 +#endif
2862 +
2863 +#endif /* IPSEC_ALG_H */
2864 --- /dev/null Tue Mar 11 13:02:56 2003
2865 +++ linux/include/openswan/ipsec_alg_3des.h Mon Feb 9 13:51:03 2004
2866 @@ -0,0 +1,12 @@
2867 +struct TripleDES_context {
2868 + des_key_schedule s1;
2869 + des_key_schedule s2;
2870 + des_key_schedule s3;
2871 +};
2872 +typedef struct TripleDES_context TripleDES_context;
2873 +
2874 +#define ESP_3DES_KEY_SZ 3*(sizeof(des_cblock))
2875 +#define ESP_3DES_CBC_BLK_LEN 8
2876 +
2877 +
2878 +
2879 --- /dev/null Tue Mar 11 13:02:56 2003
2880 +++ linux/include/openswan/ipsec_auth.h Mon Feb 9 13:51:03 2004
2881 @@ -0,0 +1,100 @@
2882 +/*
2883 + * Authentication Header declarations
2884 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
2885 + *
2886 + * This program is free software; you can redistribute it and/or modify it
2887 + * under the terms of the GNU General Public License as published by the
2888 + * Free Software Foundation; either version 2 of the License, or (at your
2889 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2890 + *
2891 + * This program is distributed in the hope that it will be useful, but
2892 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2893 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2894 + * for more details.
2895 + *
2896 + * RCSID $Id: ipsec_auth.h,v 1.3 2004/04/06 02:49:08 mcr Exp $
2897 + */
2898 +
2899 +#include "ipsec_md5h.h"
2900 +#include "ipsec_sha1.h"
2901 +
2902 +#ifndef IPSEC_AUTH_H
2903 +#define IPSEC_AUTH_H
2904 +
2905 +#define AH_FLENGTH 12 /* size of fixed part */
2906 +#define AHMD5_KMAX 64 /* MD5 max 512 bits key */
2907 +#define AHMD5_AMAX 12 /* MD5 96 bits of authenticator */
2908 +
2909 +#define AHMD596_KLEN 16 /* MD5 128 bits key */
2910 +#define AHSHA196_KLEN 20 /* SHA1 160 bits key */
2911 +
2912 +#define AHMD596_ALEN 16 /* MD5 128 bits authentication length */
2913 +#define AHSHA196_ALEN 20 /* SHA1 160 bits authentication length */
2914 +
2915 +#define AHMD596_BLKLEN 64 /* MD5 block length */
2916 +#define AHSHA196_BLKLEN 64 /* SHA1 block length */
2917 +#define AHSHA2_256_BLKLEN 64 /* SHA2-256 block length */
2918 +#define AHSHA2_384_BLKLEN 128 /* SHA2-384 block length (?) */
2919 +#define AHSHA2_512_BLKLEN 128 /* SHA2-512 block length */
2920 +
2921 +#define AH_BLKLEN_MAX 128 /* keep up to date! */
2922 +
2923 +
2924 +#define AH_AMAX AHSHA196_ALEN /* keep up to date! */
2925 +#define AHHMAC_HASHLEN 12 /* authenticator length of 96bits */
2926 +#define AHHMAC_RPLLEN 4 /* 32 bit replay counter */
2927 +
2928 +#define DB_AH_PKTRX 0x0001
2929 +#define DB_AH_PKTRX2 0x0002
2930 +#define DB_AH_DMP 0x0004
2931 +#define DB_AH_IPSA 0x0010
2932 +#define DB_AH_XF 0x0020
2933 +#define DB_AH_INAU 0x0040
2934 +#define DB_AH_REPLAY 0x0100
2935 +
2936 +#ifdef __KERNEL__
2937 +
2938 +/* General HMAC algorithm is described in RFC 2104 */
2939 +
2940 +#define HMAC_IPAD 0x36
2941 +#define HMAC_OPAD 0x5C
2942 +
2943 +struct md5_ctx {
2944 + MD5_CTX ictx; /* context after H(K XOR ipad) */
2945 + MD5_CTX octx; /* context after H(K XOR opad) */
2946 +};
2947 +
2948 +struct sha1_ctx {
2949 + SHA1_CTX ictx; /* context after H(K XOR ipad) */
2950 + SHA1_CTX octx; /* context after H(K XOR opad) */
2951 +};
2952 +
2953 +struct auth_alg {
2954 + void (*init)(void *ctx);
2955 + void (*update)(void *ctx, unsigned char *bytes, __u32 len);
2956 + void (*final)(unsigned char *hash, void *ctx);
2957 + int hashlen;
2958 +};
2959 +
2960 +struct options;
2961 +
2962 +#endif /* __KERNEL__ */
2963 +#endif /* IPSEC_AUTH_H */
2964 +
2965 +/*
2966 + * $Log: ipsec_auth.h,v $
2967 + * Revision 1.3 2004/04/06 02:49:08 mcr
2968 + * pullup of algo code from alg-branch.
2969 + *
2970 + * Revision 1.2 2004/04/05 19:55:04 mcr
2971 + * Moved from linux/include/freeswan/ipsec_auth.h,v
2972 + *
2973 + * Revision 1.1 2003/12/13 19:10:16 mcr
2974 + * refactored rcv and xmit code - same as FS 2.05.
2975 + *
2976 + * Revision 1.1 2003/12/06 21:21:19 mcr
2977 + * split up receive path into per-transform files, for
2978 + * easier later removal.
2979 + *
2980 + *
2981 + */
2982 --- /dev/null Tue Mar 11 13:02:56 2003
2983 +++ linux/include/openswan/ipsec_encap.h Mon Feb 9 13:51:03 2004
2984 @@ -0,0 +1,149 @@
2985 +/*
2986 + * declarations relevant to encapsulation-like operations
2987 + * Copyright (C) 1996, 1997 John Ioannidis.
2988 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
2989 + *
2990 + * This program is free software; you can redistribute it and/or modify it
2991 + * under the terms of the GNU General Public License as published by the
2992 + * Free Software Foundation; either version 2 of the License, or (at your
2993 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2994 + *
2995 + * This program is distributed in the hope that it will be useful, but
2996 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2997 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2998 + * for more details.
2999 + *
3000 + * RCSID $Id: ipsec_encap.h,v 1.19 2004/04/05 19:55:04 mcr Exp $
3001 + */
3002 +
3003 +#ifndef _IPSEC_ENCAP_H_
3004 +
3005 +#define SENT_IP4 16 /* data is two struct in_addr + proto + ports*/
3006 + /* (2 * sizeof(struct in_addr)) */
3007 + /* sizeof(struct sockaddr_encap)
3008 + - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */
3009 +
3010 +struct sockaddr_encap
3011 +{
3012 + __u8 sen_len; /* length */
3013 + __u8 sen_family; /* AF_ENCAP */
3014 + __u16 sen_type; /* see SENT_* */
3015 + union
3016 + {
3017 + struct /* SENT_IP4 */
3018 + {
3019 + struct in_addr Src;
3020 + struct in_addr Dst;
3021 + __u8 Proto;
3022 + __u16 Sport;
3023 + __u16 Dport;
3024 + } Sip4;
3025 + } Sen;
3026 +};
3027 +
3028 +#define sen_ip_src Sen.Sip4.Src
3029 +#define sen_ip_dst Sen.Sip4.Dst
3030 +#define sen_proto Sen.Sip4.Proto
3031 +#define sen_sport Sen.Sip4.Sport
3032 +#define sen_dport Sen.Sip4.Dport
3033 +
3034 +#ifndef AF_ENCAP
3035 +#define AF_ENCAP 26
3036 +#endif /* AF_ENCAP */
3037 +
3038 +#define _IPSEC_ENCAP_H_
3039 +#endif /* _IPSEC_ENCAP_H_ */
3040 +
3041 +/*
3042 + * $Log: ipsec_encap.h,v $
3043 + * Revision 1.19 2004/04/05 19:55:04 mcr
3044 + * Moved from linux/include/freeswan/ipsec_encap.h,v
3045 + *
3046 + * Revision 1.18 2003/10/31 02:27:05 mcr
3047 + * pulled up port-selector patches and sa_id elimination.
3048 + *
3049 + * Revision 1.17.30.1 2003/09/21 13:59:38 mcr
3050 + * pre-liminary X.509 patch - does not yet pass tests.
3051 + *
3052 + * Revision 1.17 2002/04/24 07:36:46 mcr
3053 + * Moved from ./klips/net/ipsec/ipsec_encap.h,v
3054 + *
3055 + * Revision 1.16 2001/11/26 09:23:47 rgb
3056 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3057 + *
3058 + * Revision 1.15.2.1 2001/09/25 02:18:54 mcr
3059 + * struct eroute moved to ipsec_eroute.h
3060 + *
3061 + * Revision 1.15 2001/09/14 16:58:36 rgb
3062 + * Added support for storing the first and last packets through a HOLD.
3063 + *
3064 + * Revision 1.14 2001/09/08 21:13:31 rgb
3065 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
3066 + *
3067 + * Revision 1.13 2001/06/14 19:35:08 rgb
3068 + * Update copyright date.
3069 + *
3070 + * Revision 1.12 2001/05/27 06:12:10 rgb
3071 + * Added structures for pid, packet count and last access time to eroute.
3072 + * Added packet count to beginning of /proc/net/ipsec_eroute.
3073 + *
3074 + * Revision 1.11 2000/09/08 19:12:56 rgb
3075 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
3076 + *
3077 + * Revision 1.10 2000/03/22 16:15:36 rgb
3078 + * Fixed renaming of dev_get (MB).
3079 + *
3080 + * Revision 1.9 2000/01/21 06:13:26 rgb
3081 + * Added a macro for AF_ENCAP
3082 + *
3083 + * Revision 1.8 1999/12/31 14:56:55 rgb
3084 + * MB fix for 2.3 dev-use-count.
3085 + *
3086 + * Revision 1.7 1999/11/18 04:09:18 rgb
3087 + * Replaced all kernel version macros to shorter, readable form.
3088 + *
3089 + * Revision 1.6 1999/09/24 00:34:13 rgb
3090 + * Add Marc Boucher's support for 2.3.xx+.
3091 + *
3092 + * Revision 1.5 1999/04/11 00:28:57 henry
3093 + * GPL boilerplate
3094 + *
3095 + * Revision 1.4 1999/04/06 04:54:25 rgb
3096 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
3097 + * patch shell fixes.
3098 + *
3099 + * Revision 1.3 1998/10/19 14:44:28 rgb
3100 + * Added inclusion of freeswan.h.
3101 + * sa_id structure implemented and used: now includes protocol.
3102 + *
3103 + * Revision 1.2 1998/07/14 18:19:33 rgb
3104 + * Added #ifdef __KERNEL__ directives to restrict scope of header.
3105 + *
3106 + * Revision 1.1 1998/06/18 21:27:44 henry
3107 + * move sources from klips/src to klips/net/ipsec, to keep stupid
3108 + * kernel-build scripts happier in the presence of symlinks
3109 + *
3110 + * Revision 1.2 1998/04/21 21:29:10 rgb
3111 + * Rearrange debug switches to change on the fly debug output from user
3112 + * space. Only kernel changes checked in at this time. radij.c was also
3113 + * changed to temporarily remove buggy debugging code in rj_delete causing
3114 + * an OOPS and hence, netlink device open errors.
3115 + *
3116 + * Revision 1.1 1998/04/09 03:05:58 henry
3117 + * sources moved up from linux/net/ipsec
3118 + *
3119 + * Revision 1.1.1.1 1998/04/08 05:35:02 henry
3120 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
3121 + *
3122 + * Revision 0.4 1997/01/15 01:28:15 ji
3123 + * Minor cosmetic changes.
3124 + *
3125 + * Revision 0.3 1996/11/20 14:35:48 ji
3126 + * Minor Cleanup.
3127 + * Rationalized debugging code.
3128 + *
3129 + * Revision 0.2 1996/11/02 00:18:33 ji
3130 + * First limited release.
3131 + *
3132 + *
3133 + */
3134 --- /dev/null Tue Mar 11 13:02:56 2003
3135 +++ linux/include/openswan/ipsec_eroute.h Mon Feb 9 13:51:03 2004
3136 @@ -0,0 +1,112 @@
3137 +/*
3138 + * @(#) declarations of eroute structures
3139 + *
3140 + * Copyright (C) 1996, 1997 John Ioannidis.
3141 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
3142 + * Copyright (C) 2001 Michael Richardson <mcr@freeswan.org>
3143 + *
3144 + * This program is free software; you can redistribute it and/or modify it
3145 + * under the terms of the GNU General Public License as published by the
3146 + * Free Software Foundation; either version 2 of the License, or (at your
3147 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3148 + *
3149 + * This program is distributed in the hope that it will be useful, but
3150 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3151 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3152 + * for more details.
3153 + *
3154 + * RCSID $Id: ipsec_eroute.h,v 1.5 2004/04/05 19:55:05 mcr Exp $
3155 + *
3156 + * derived from ipsec_encap.h 1.15 on 2001/9/18 by mcr.
3157 + *
3158 + */
3159 +
3160 +#ifndef _IPSEC_EROUTE_H_
3161 +
3162 +#include "radij.h"
3163 +#include "ipsec_encap.h"
3164 +#include "ipsec_radij.h"
3165 +
3166 +/*
3167 + * The "type" is really part of the address as far as the routing
3168 + * system is concerned. By using only one bit in the type field
3169 + * for each type, we sort-of make sure that different types of
3170 + * encapsulation addresses won't be matched against the wrong type.
3171 + */
3172 +
3173 +/*
3174 + * An entry in the radix tree
3175 + */
3176 +
3177 +struct rjtentry
3178 +{
3179 + struct radij_node rd_nodes[2]; /* tree glue, and other values */
3180 +#define rd_key(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_key))
3181 +#define rd_mask(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_mask))
3182 + short rd_flags;
3183 + short rd_count;
3184 +};
3185 +
3186 +struct ident
3187 +{
3188 + __u16 type; /* identity type */
3189 + __u64 id; /* identity id */
3190 + __u8 len; /* identity len */
3191 + caddr_t data; /* identity data */
3192 +};
3193 +
3194 +/*
3195 + * An encapsulation route consists of a pointer to a
3196 + * radix tree entry and a SAID (a destination_address/SPI/protocol triple).
3197 + */
3198 +
3199 +struct eroute
3200 +{
3201 + struct rjtentry er_rjt;
3202 + ip_said er_said;
3203 + uint32_t er_pid;
3204 + uint32_t er_count;
3205 + uint64_t er_lasttime;
3206 + struct sockaddr_encap er_eaddr; /* MCR get rid of _encap, it is silly*/
3207 + struct sockaddr_encap er_emask;
3208 + struct ident er_ident_s;
3209 + struct ident er_ident_d;
3210 + struct sk_buff* er_first;
3211 + struct sk_buff* er_last;
3212 +};
3213 +
3214 +#define er_dst er_said.dst
3215 +#define er_spi er_said.spi
3216 +
3217 +#define _IPSEC_EROUTE_H_
3218 +#endif /* _IPSEC_EROUTE_H_ */
3219 +
3220 +/*
3221 + * $Log: ipsec_eroute.h,v $
3222 + * Revision 1.5 2004/04/05 19:55:05 mcr
3223 + * Moved from linux/include/freeswan/ipsec_eroute.h,v
3224 + *
3225 + * Revision 1.4 2003/10/31 02:27:05 mcr
3226 + * pulled up port-selector patches and sa_id elimination.
3227 + *
3228 + * Revision 1.3.30.2 2003/10/29 01:10:19 mcr
3229 + * elimited "struct sa_id"
3230 + *
3231 + * Revision 1.3.30.1 2003/09/21 13:59:38 mcr
3232 + * pre-liminary X.509 patch - does not yet pass tests.
3233 + *
3234 + * Revision 1.3 2002/04/24 07:36:46 mcr
3235 + * Moved from ./klips/net/ipsec/ipsec_eroute.h,v
3236 + *
3237 + * Revision 1.2 2001/11/26 09:16:13 rgb
3238 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3239 + *
3240 + * Revision 1.1.2.1 2001/09/25 02:18:54 mcr
3241 + * struct eroute moved to ipsec_eroute.h
3242 + *
3243 + *
3244 + * Local variables:
3245 + * c-file-style: "linux"
3246 + * End:
3247 + *
3248 + */
3249 --- /dev/null Tue Mar 11 13:02:56 2003
3250 +++ linux/include/openswan/ipsec_errs.h Mon Feb 9 13:51:03 2004
3251 @@ -0,0 +1,53 @@
3252 +/*
3253 + * @(#) definition of ipsec_errs structure
3254 + *
3255 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
3256 + * and Michael Richardson <mcr@freeswan.org>
3257 + *
3258 + * This program is free software; you can redistribute it and/or modify it
3259 + * under the terms of the GNU General Public License as published by the
3260 + * Free Software Foundation; either version 2 of the License, or (at your
3261 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3262 + *
3263 + * This program is distributed in the hope that it will be useful, but
3264 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3265 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3266 + * for more details.
3267 + *
3268 + * RCSID $Id: ipsec_errs.h,v 1.4 2004/04/05 19:55:05 mcr Exp $
3269 + *
3270 + */
3271 +
3272 +/*
3273 + * This file describes the errors/statistics that FreeSWAN collects.
3274 + *
3275 + */
3276 +
3277 +struct ipsec_errs {
3278 + __u32 ips_alg_errs; /* number of algorithm errors */
3279 + __u32 ips_auth_errs; /* # of authentication errors */
3280 + __u32 ips_encsize_errs; /* # of encryption size errors*/
3281 + __u32 ips_encpad_errs; /* # of encryption pad errors*/
3282 + __u32 ips_replaywin_errs; /* # of pkt sequence errors */
3283 +};
3284 +
3285 +/*
3286 + * $Log: ipsec_errs.h,v $
3287 + * Revision 1.4 2004/04/05 19:55:05 mcr
3288 + * Moved from linux/include/freeswan/ipsec_errs.h,v
3289 + *
3290 + * Revision 1.3 2002/04/24 07:36:46 mcr
3291 + * Moved from ./klips/net/ipsec/ipsec_errs.h,v
3292 + *
3293 + * Revision 1.2 2001/11/26 09:16:13 rgb
3294 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3295 + *
3296 + * Revision 1.1.2.1 2001/09/25 02:25:57 mcr
3297 + * lifetime structure created and common functions created.
3298 + *
3299 + *
3300 + * Local variables:
3301 + * c-file-style: "linux"
3302 + * End:
3303 + *
3304 + */
3305 --- /dev/null Tue Mar 11 13:02:56 2003
3306 +++ linux/include/openswan/ipsec_esp.h Mon Feb 9 13:51:03 2004
3307 @@ -0,0 +1,161 @@
3308 +/*
3309 + * Copyright (C) 1996, 1997 John Ioannidis.
3310 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
3311 + *
3312 + * This program is free software; you can redistribute it and/or modify it
3313 + * under the terms of the GNU General Public License as published by the
3314 + * Free Software Foundation; either version 2 of the License, or (at your
3315 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3316 + *
3317 + * This program is distributed in the hope that it will be useful, but
3318 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3319 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3320 + * for more details.
3321 + *
3322 + * RCSID $Id: ipsec_esp.h,v 1.28 2004/09/13 02:22:10 mcr Exp $
3323 + */
3324 +
3325 +#include "openswan/ipsec_md5h.h"
3326 +#include "openswan/ipsec_sha1.h"
3327 +
3328 +#include "klips-crypto/des.h"
3329 +
3330 +#ifndef IPPROTO_ESP
3331 +#define IPPROTO_ESP 50
3332 +#endif /* IPPROTO_ESP */
3333 +
3334 +#define ESP_HEADER_LEN 8 /* 64 bits header (spi+rpl)*/
3335 +
3336 +#define EMT_ESPDESCBC_ULEN 20 /* coming from user mode */
3337 +#define EMT_ESPDES_KMAX 64 /* 512 bit secret key enough? */
3338 +#define EMT_ESPDES_KEY_SZ 8 /* 56 bit secret key with parity = 64 bits */
3339 +#define EMT_ESP3DES_KEY_SZ 24 /* 168 bit secret key with parity = 192 bits */
3340 +#define EMT_ESPDES_IV_SZ 8 /* IV size */
3341 +#define ESP_DESCBC_BLKLEN 8 /* DES-CBC block size */
3342 +
3343 +#define ESP_IV_MAXSZ 16 /* This is _critical_ */
3344 +#define ESP_IV_MAXSZ_INT (ESP_IV_MAXSZ/sizeof(int))
3345 +
3346 +#define DB_ES_PKTRX 0x0001
3347 +#define DB_ES_PKTRX2 0x0002
3348 +#define DB_ES_IPSA 0x0010
3349 +#define DB_ES_XF 0x0020
3350 +#define DB_ES_IPAD 0x0040
3351 +#define DB_ES_INAU 0x0080
3352 +#define DB_ES_OINFO 0x0100
3353 +#define DB_ES_OINFO2 0x0200
3354 +#define DB_ES_OH 0x0400
3355 +#define DB_ES_REPLAY 0x0800
3356 +
3357 +#ifdef __KERNEL__
3358 +struct des_eks {
3359 + des_key_schedule ks;
3360 +};
3361 +
3362 +#ifndef CONFIG_XFRM_ALTERNATE_STACK
3363 +extern struct inet_protocol esp_protocol;
3364 +#endif /* CONFIG_XFRM_ALTERNATE_STACK */
3365 +
3366 +struct options;
3367 +
3368 +struct esphdr
3369 +{
3370 + __u32 esp_spi; /* Security Parameters Index */
3371 + __u32 esp_rpl; /* Replay counter */
3372 + __u8 esp_iv[8]; /* iv */
3373 +};
3374 +
3375 +extern struct xform_functions esp_xform_funcs[];
3376 +
3377 +extern enum ipsec_rcv_value ipsec_rcv_esp_post_decrypt(struct ipsec_rcv_state *irs);
3378 +
3379 +#ifdef CONFIG_KLIPS_DEBUG
3380 +extern int debug_esp;
3381 +#endif /* CONFIG_KLIPS_DEBUG */
3382 +#endif /* __KERNEL__ */
3383 +
3384 +/*
3385 + * $Log: ipsec_esp.h,v $
3386 + * Revision 1.28 2004/09/13 02:22:10 mcr
3387 + * #define inet_protocol if necessary.
3388 + *
3389 + * Revision 1.27 2004/09/06 18:35:41 mcr
3390 + * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
3391 + * so adjust for that.
3392 + *
3393 + * Revision 1.26 2004/07/10 19:08:41 mcr
3394 + * CONFIG_IPSEC -> CONFIG_KLIPS.
3395 + *
3396 + * Revision 1.25 2004/04/06 02:49:08 mcr
3397 + * pullup of algo code from alg-branch.
3398 + *
3399 + * Revision 1.24 2004/04/05 19:55:05 mcr
3400 + * Moved from linux/include/freeswan/ipsec_esp.h,v
3401 + *
3402 + * Revision 1.23 2004/04/05 19:41:05 mcr
3403 + * merged alg-branch code.
3404 + *
3405 + * Revision 1.22 2003/12/13 19:10:16 mcr
3406 + * refactored rcv and xmit code - same as FS 2.05.
3407 + *
3408 + * Revision 1.23 2003/12/11 20:14:58 mcr
3409 + * refactored the xmit code, to move all encapsulation
3410 + * code into protocol functions. Note that all functions
3411 + * are essentially done by a single function, which is probably
3412 + * wrong.
3413 + * the rcv_functions structures are renamed xform_functions.
3414 + *
3415 + * Revision 1.22 2003/12/06 21:21:19 mcr
3416 + * split up receive path into per-transform files, for
3417 + * easier later removal.
3418 + *
3419 + * Revision 1.21.8.1 2003/12/22 15:25:52 jjo
3420 + * Merged algo-0.8.1-rc11-test1 into alg-branch
3421 + *
3422 + * Revision 1.21 2003/02/06 02:21:34 rgb
3423 + *
3424 + * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
3425 + * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
3426 + * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
3427 + *
3428 + * Revision 1.20 2002/05/14 02:37:02 rgb
3429 + * Change reference from _TDB to _IPSA.
3430 + *
3431 + * Revision 1.19 2002/04/24 07:55:32 mcr
3432 + * #include patches and Makefiles for post-reorg compilation.
3433 + *
3434 + * Revision 1.18 2002/04/24 07:36:46 mcr
3435 + * Moved from ./klips/net/ipsec/ipsec_esp.h,v
3436 + *
3437 + * Revision 1.17 2002/02/20 01:27:07 rgb
3438 + * Ditched a pile of structs only used by the old Netlink interface.
3439 + *
3440 + * Revision 1.16 2001/12/11 02:35:57 rgb
3441 + * Change "struct net_device" to "struct device" for 2.2 compatibility.
3442 + *
3443 + * Revision 1.15 2001/11/26 09:23:48 rgb
3444 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3445 + *
3446 + * Revision 1.14.2.3 2001/10/23 04:16:42 mcr
3447 + * get definition of des_key_schedule from des.h
3448 + *
3449 + * Revision 1.14.2.2 2001/10/22 20:33:13 mcr
3450 + * use "des_key_schedule" structure instead of cooking our own.
3451 + *
3452 + * Revision 1.14.2.1 2001/09/25 02:18:25 mcr
3453 + * replace "struct device" with "struct netdevice"
3454 + *
3455 + * Revision 1.14 2001/06/14 19:35:08 rgb
3456 + * Update copyright date.
3457 + *
3458 + * Revision 1.13 2000/09/08 19:12:56 rgb
3459 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
3460 + *
3461 + * Revision 1.12 2000/08/01 14:51:50 rgb
3462 + * Removed _all_ remaining traces of DES.
3463 + *
3464 + * Revision 1.11 2000/01/10 16:36:20 rgb
3465 + * Ditch last of EME option flags, including initiator.
3466 + *
3467 + *
3468 + */
3469 --- /dev/null Tue Mar 11 13:02:56 2003
3470 +++ linux/include/openswan/ipsec_ipcomp.h Mon Feb 9 13:51:03 2004
3471 @@ -0,0 +1,97 @@
3472 +/*
3473 + * IP compression header declations
3474 + *
3475 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
3476 + *
3477 + * This program is free software; you can redistribute it and/or modify it
3478 + * under the terms of the GNU General Public License as published by the
3479 + * Free Software Foundation; either version 2 of the License, or (at your
3480 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3481 + *
3482 + * This program is distributed in the hope that it will be useful, but
3483 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3484 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3485 + * for more details.
3486 + *
3487 + * RCSID $Id: ipsec_ipcomp.h,v 1.4 2004/07/10 19:08:41 mcr Exp $
3488 + */
3489 +
3490 +#ifndef IPSEC_IPCOMP_H
3491 +#define IPSEC_IPCOMP_H
3492 +
3493 +#include "openswan/ipsec_auth.h"
3494 +
3495 +/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
3496 +#ifndef IPCOMP_PREFIX
3497 +#define IPCOMP_PREFIX
3498 +#endif /* IPCOMP_PREFIX */
3499 +
3500 +#ifndef IPPROTO_COMP
3501 +#define IPPROTO_COMP 108
3502 +#endif /* IPPROTO_COMP */
3503 +
3504 +#ifdef CONFIG_KLIPS_DEBUG
3505 +extern int sysctl_ipsec_debug_ipcomp;
3506 +#endif /* CONFIG_KLIPS_DEBUG */
3507 +
3508 +struct ipcomphdr { /* IPCOMP header */
3509 + __u8 ipcomp_nh; /* Next header (protocol) */
3510 + __u8 ipcomp_flags; /* Reserved, must be 0 */
3511 + __u16 ipcomp_cpi; /* Compression Parameter Index */
3512 +};
3513 +
3514 +#ifndef CONFIG_XFRM_ALTERNATE_STACK
3515 +extern struct inet_protocol comp_protocol;
3516 +#endif /* CONFIG_XFRM_ALTERNATE_STACK */
3517 +
3518 +extern int sysctl_ipsec_debug_ipcomp;
3519 +
3520 +#define IPCOMP_UNCOMPRESSABLE 0x000000001
3521 +#define IPCOMP_COMPRESSIONERROR 0x000000002
3522 +#define IPCOMP_PARMERROR 0x000000004
3523 +#define IPCOMP_DECOMPRESSIONERROR 0x000000008
3524 +
3525 +#define IPCOMP_ADAPT_INITIAL_TRIES 8
3526 +#define IPCOMP_ADAPT_INITIAL_SKIP 4
3527 +#define IPCOMP_ADAPT_SUBSEQ_TRIES 2
3528 +#define IPCOMP_ADAPT_SUBSEQ_SKIP 8
3529 +
3530 +/* Function prototypes */
3531 +struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
3532 +struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
3533 +
3534 +extern struct xform_functions ipcomp_xform_funcs[];
3535 +
3536 +#endif /* IPSEC_IPCOMP_H */
3537 +
3538 +/*
3539 + * $Log: ipsec_ipcomp.h,v $
3540 + * Revision 1.4 2004/07/10 19:08:41 mcr
3541 + * CONFIG_IPSEC -> CONFIG_KLIPS.
3542 + *
3543 + * Revision 1.3 2004/04/06 02:49:08 mcr
3544 + * pullup of algo code from alg-branch.
3545 + *
3546 + * Revision 1.2 2004/04/05 19:55:05 mcr
3547 + * Moved from linux/include/freeswan/ipsec_ipcomp.h,v
3548 + *
3549 + * Revision 1.1 2003/12/13 19:10:16 mcr
3550 + * refactored rcv and xmit code - same as FS 2.05.
3551 + *
3552 + * Revision 1.2 2003/12/11 20:14:58 mcr
3553 + * refactored the xmit code, to move all encapsulation
3554 + * code into protocol functions. Note that all functions
3555 + * are essentially done by a single function, which is probably
3556 + * wrong.
3557 + * the rcv_functions structures are renamed xform_functions.
3558 + *
3559 + * Revision 1.1 2003/12/06 21:21:19 mcr
3560 + * split up receive path into per-transform files, for
3561 + * easier later removal.
3562 + *
3563 + *
3564 + *
3565 + */
3566 +
3567 +
3568 +
3569 --- /dev/null Tue Mar 11 13:02:56 2003
3570 +++ linux/include/openswan/ipsec_ipe4.h Mon Feb 9 13:51:03 2004
3571 @@ -0,0 +1,68 @@
3572 +/*
3573 + * IP-in-IP Header declarations
3574 + * Copyright (C) 1996, 1997 John Ioannidis.
3575 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
3576 + *
3577 + * This program is free software; you can redistribute it and/or modify it
3578 + * under the terms of the GNU General Public License as published by the
3579 + * Free Software Foundation; either version 2 of the License, or (at your
3580 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3581 + *
3582 + * This program is distributed in the hope that it will be useful, but
3583 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3584 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3585 + * for more details.
3586 + *
3587 + * RCSID $Id: ipsec_ipe4.h,v 1.6 2004/04/05 19:55:05 mcr Exp $
3588 + */
3589 +
3590 +/* The packet header is an IP header! */
3591 +
3592 +struct ipe4_xdata /* transform table data */
3593 +{
3594 + struct in_addr i4_src;
3595 + struct in_addr i4_dst;
3596 +};
3597 +
3598 +#define EMT_IPE4_ULEN 8 /* coming from user mode */
3599 +
3600 +
3601 +/*
3602 + * $Log: ipsec_ipe4.h,v $
3603 + * Revision 1.6 2004/04/05 19:55:05 mcr
3604 + * Moved from linux/include/freeswan/ipsec_ipe4.h,v
3605 + *
3606 + * Revision 1.5 2002/04/24 07:36:46 mcr
3607 + * Moved from ./klips/net/ipsec/ipsec_ipe4.h,v
3608 + *
3609 + * Revision 1.4 2001/06/14 19:35:08 rgb
3610 + * Update copyright date.
3611 + *
3612 + * Revision 1.3 1999/04/11 00:28:57 henry
3613 + * GPL boilerplate
3614 + *
3615 + * Revision 1.2 1999/04/06 04:54:25 rgb
3616 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
3617 + * patch shell fixes.
3618 + *
3619 + * Revision 1.1 1998/06/18 21:27:47 henry
3620 + * move sources from klips/src to klips/net/ipsec, to keep stupid
3621 + * kernel-build scripts happier in the presence of symlinks
3622 + *
3623 + * Revision 1.1 1998/04/09 03:06:07 henry
3624 + * sources moved up from linux/net/ipsec
3625 + *
3626 + * Revision 1.1.1.1 1998/04/08 05:35:03 henry
3627 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
3628 + *
3629 + * Revision 0.4 1997/01/15 01:28:15 ji
3630 + * No changes.
3631 + *
3632 + * Revision 0.3 1996/11/20 14:48:53 ji
3633 + * Release update only.
3634 + *
3635 + * Revision 0.2 1996/11/02 00:18:33 ji
3636 + * First limited release.
3637 + *
3638 + *
3639 + */
3640 --- /dev/null Tue Mar 11 13:02:56 2003
3641 +++ linux/include/openswan/ipsec_ipip.h Mon Feb 9 13:51:03 2004
3642 @@ -0,0 +1,45 @@
3643 +/*
3644 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
3645 + *
3646 + * This program is free software; you can redistribute it and/or modify it
3647 + * under the terms of the GNU General Public License as published by the
3648 + * Free Software Foundation; either version 2 of the License, or (at your
3649 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3650 + *
3651 + * This program is distributed in the hope that it will be useful, but
3652 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3653 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3654 + * for more details.
3655 + *
3656 + * RCSID $Id: ipsec_ipip.h,v 1.2 2004/04/05 19:55:05 mcr Exp $
3657 + */
3658 +
3659 +#ifndef _IPSEC_IPIP_H_
3660 +
3661 +#ifndef IPPROTO_IPIP
3662 +#define IPPROTO_IPIP 4
3663 +#endif /* IPPROTO_ESP */
3664 +
3665 +extern struct xform_functions ipip_xform_funcs[];
3666 +
3667 +#define _IPSEC_IPIP_H_
3668 +
3669 +#endif /* _IPSEC_IPIP_H_ */
3670 +
3671 +/*
3672 + * $Log: ipsec_ipip.h,v $
3673 + * Revision 1.2 2004/04/05 19:55:05 mcr
3674 + * Moved from linux/include/freeswan/ipsec_ipip.h,v
3675 + *
3676 + * Revision 1.1 2003/12/13 19:10:16 mcr
3677 + * refactored rcv and xmit code - same as FS 2.05.
3678 + *
3679 + * Revision 1.1 2003/12/11 20:14:58 mcr
3680 + * refactored the xmit code, to move all encapsulation
3681 + * code into protocol functions. Note that all functions
3682 + * are essentially done by a single function, which is probably
3683 + * wrong.
3684 + * the rcv_functions structures are renamed xform_functions.
3685 + *
3686 + *
3687 + */
3688 --- /dev/null Tue Mar 11 13:02:56 2003
3689 +++ linux/include/openswan/ipsec_kern24.h Mon Feb 9 13:51:03 2004
3690 @@ -0,0 +1,92 @@
3691 +/*
3692 + * @(#) routines to makes kernel 2.4 compatible with 2.6 usage.
3693 + *
3694 + * Copyright (C) 2004 Michael Richardson <mcr@sandelman.ottawa.on.ca>
3695 + * Copyright (C) 2005 - 2008 Paul Wouters <paul@xelerance.com>
3696 + *
3697 + * This program is free software; you can redistribute it and/or modify it
3698 + * under the terms of the GNU General Public License as published by the
3699 + * Free Software Foundation; either version 2 of the License, or (at your
3700 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3701 + *
3702 + * This program is distributed in the hope that it will be useful, but
3703 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3704 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3705 + * for more details.
3706 + *
3707 + */
3708 +
3709 +#ifndef _IPSEC_KERN24_H
3710 +
3711 +
3712 +#ifdef NETDEV_23
3713 +#if 0
3714 +#ifndef NETDEV_25
3715 +#define device net_device
3716 +#endif
3717 +#endif
3718 +
3719 +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
3720 +# define __ipsec_dev_get(x) __dev_get_by_name(&init_net, x)
3721 +# define ipsec_dev_get(x) dev_get_by_name(&init_net, x)
3722 +# else
3723 +# define ipsec_dev_get(x) __dev_get_by_name(x)
3724 +# define __ipsec_dev_get(x) __dev_get_by_name(x)
3725 +# endif
3726 +
3727 +# define ipsec_dev_put(x) dev_put(x)
3728 +# define __ipsec_dev_put(x) __dev_put(x)
3729 +# define ipsec_dev_hold(x) dev_hold(x)
3730 +#else /* NETDEV_23 */
3731 +# define ipsec_dev_get dev_get
3732 +# define __ipsec_dev_put(x)
3733 +# define ipsec_dev_put(x)
3734 +# define ipsec_dev_hold(x)
3735 +#endif /* NETDEV_23 */
3736 +
3737 +#ifndef HAVE_NETDEV_PRINTK
3738 +#define netdev_printk(sevlevel, netdev, msglevel, format, arg...) \
3739 + printk(sevlevel "%s: " format , netdev->name , ## arg)
3740 +#endif
3741 +
3742 +#ifndef NET_26
3743 +#define sk_receive_queue receive_queue
3744 +#define sk_destruct destruct
3745 +#define sk_reuse reuse
3746 +#define sk_zapped zapped
3747 +#define sk_family family
3748 +#define sk_protocol protocol
3749 +#define sk_protinfo protinfo
3750 +#define sk_sleep sleep
3751 +#define sk_state_change state_change
3752 +#define sk_shutdown shutdown
3753 +#define sk_err err
3754 +#define sk_stamp stamp
3755 +#define sk_socket socket
3756 +#define sk_sndbuf sndbuf
3757 +#define sock_flag(sk, flag) sk->dead
3758 +#define sk_for_each(sk, node, plist) for(sk=*plist; sk!=NULL; sk = sk->next)
3759 +#endif
3760 +
3761 +/* deal with 2.4 vs 2.6 issues with module counts */
3762 +
3763 +/* in 2.6, all refcounts are maintained *outside* of the
3764 + * module to deal with race conditions.
3765 + */
3766 +
3767 +#ifdef NET_26
3768 +#define KLIPS_INC_USE /* nothing */
3769 +#define KLIPS_DEC_USE /* nothing */
3770 +
3771 +#else
3772 +#define KLIPS_INC_USE MOD_INC_USE_COUNT
3773 +#define KLIPS_DEC_USE MOD_DEC_USE_COUNT
3774 +#endif
3775 +
3776 +extern int printk_ratelimit(void);
3777 +
3778 +
3779 +#define _IPSEC_KERN24_H 1
3780 +
3781 +#endif /* _IPSEC_KERN24_H */
3782 +
3783 --- /dev/null Tue Mar 11 13:02:56 2003
3784 +++ linux/include/openswan/ipsec_kversion.h Mon Feb 9 13:51:03 2004
3785 @@ -0,0 +1,441 @@
3786 +#ifndef _OPENSWAN_KVERSIONS_H
3787 +/*
3788 + * header file for Openswan library functions
3789 + * Copyright (C) 1998, 1999, 2000 Henry Spencer.
3790 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
3791 + * Copyright (C) 2003 - 2008 Paul Wouters <paul@xelerance.com>
3792 + *
3793 + * This library is free software; you can redistribute it and/or modify it
3794 + * under the terms of the GNU Library General Public License as published by
3795 + * the Free Software Foundation; either version 2 of the License, or (at your
3796 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
3797 + *
3798 + * This library is distributed in the hope that it will be useful, but
3799 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3800 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
3801 + * License for more details.
3802 + *
3803 + */
3804 +#define _OPENSWAN_KVERSIONS_H /* seen it, no need to see it again */
3805 +
3806 +/*
3807 + * this file contains a series of atomic defines that depend upon
3808 + * kernel version numbers. The kernel versions are arranged
3809 + * in version-order number (which is often not chronological)
3810 + * and each clause enables or disables a feature.
3811 + */
3812 +
3813 +/*
3814 + * First, assorted kernel-version-dependent trickery.
3815 + */
3816 +#include <linux/version.h>
3817 +#ifndef KERNEL_VERSION
3818 +# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
3819 +#endif
3820 +
3821 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
3822 +# define HEADER_CACHE_BIND_21
3823 +# error "KLIPS is no longer supported on Linux 2.0. Sorry"
3824 +#endif
3825 +
3826 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
3827 +# define SPINLOCK
3828 +# define PROC_FS_21
3829 +# define NETLINK_SOCK
3830 +# define NET_21
3831 +#endif
3832 +
3833 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,19)
3834 +# define net_device_stats enet_statistics
3835 +#endif
3836 +
3837 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3838 +# define SPINLOCK_23
3839 +# define NETDEV_23
3840 +# ifndef CONFIG_IP_ALIAS
3841 +# define CONFIG_IP_ALIAS
3842 +# endif
3843 +#endif
3844 +
3845 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,25)
3846 +# define PROC_FS_2325
3847 +# undef PROC_FS_21
3848 +#endif
3849 +
3850 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
3851 +# define PROC_NO_DUMMY
3852 +#endif
3853 +
3854 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,35)
3855 +# define SKB_COPY_EXPAND
3856 +#endif
3857 +
3858 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,37)
3859 +# define IP_SELECT_IDENT
3860 +#endif
3861 +
3862 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2)
3863 +# define IP_SELECT_IDENT_NEW
3864 +#endif
3865 +
3866 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
3867 +# define IPH_is_SKB_PULLED
3868 +# define SKB_COW_NEW
3869 +# define PROTO_HANDLER_SINGLE_PARM
3870 +# define IP_FRAGMENT_LINEARIZE 1
3871 +#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
3872 +# ifdef REDHAT_BOGOSITY
3873 +# define IP_SELECT_IDENT_NEW
3874 +# define IPH_is_SKB_PULLED
3875 +# define SKB_COW_NEW
3876 +# define PROTO_HANDLER_SINGLE_PARM
3877 +# endif /* REDHAT_BOGOSITY */
3878 +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
3879 +
3880 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
3881 +# define MALLOC_SLAB
3882 +# define LINUX_KERNEL_HAS_SNPRINTF
3883 +#endif
3884 +
3885 +/* API changes are documented at: http://lwn.net/Articles/2.6-kernel-api/ */
3886 +
3887 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
3888 +# define HAVE_NETDEV_PRINTK 1
3889 +# define NET_26
3890 +# define NETDEV_25
3891 +# define NEED_SPINLOCK_TYPES
3892 +#endif
3893 +
3894 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)
3895 +# define NEED_INET_PROTOCOL
3896 +#endif
3897 +
3898 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
3899 +# define HAVE_SOCK_ZAPPED
3900 +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
3901 +# define NET_26_24_SKALLOC
3902 +# else
3903 +# define NET_26_12_SKALLOC
3904 +# endif
3905 +#endif
3906 +#endif
3907 +
3908 +/* see <linux/security.h> */
3909 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
3910 +# define HAVE_SOCK_SECURITY
3911 +/* skb->nf_debug disappared completely in 2.6.13 */
3912 +# define ipsec_nf_debug_reset(skb) ((skb)->nf_debug = 0)
3913 +#else
3914 +# define ipsec_nf_debug_reset(skb)
3915 +#endif
3916 +
3917 +/* how to reset an skb we are reusing after encrpytion/decryption etc */
3918 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
3919 +# define ipsec_nf_reset(skb) nf_reset((skb))
3920 +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,50) && defined(CONFIG_NETFILTER)
3921 +# define ipsec_nf_reset(skb) do { \
3922 + nf_conntrack_put((skb)->nfct); \
3923 + (skb)->nfct=NULL; \
3924 + ipsec_nf_debug_reset(skb); \
3925 + } while(0)
3926 +#else
3927 +# define ipsec_nf_reset(skb) /**/
3928 +#endif
3929 +
3930 +/* skb->stamp changed to skb->tstamp in 2.6.14 */
3931 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
3932 +# define HAVE_TSTAMP
3933 +# define HAVE_INET_SK_SPORT
3934 +#else
3935 +# define HAVE_SKB_LIST
3936 +#endif
3937 +
3938 +/* it seems 2.6.14 accidentally removed sysctl_ip_default_ttl */
3939 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
3940 +# define SYSCTL_IPSEC_DEFAULT_TTL IPSEC_DEFAULT_TTL
3941 +#else
3942 +# define SYSCTL_IPSEC_DEFAULT_TTL sysctl_ip_default_ttl
3943 +#endif
3944 +
3945 +/*
3946 + The obsolete MODULE_PARM() macro is gone forevermore [in 2.6.17+]
3947 + It was introduced in 2.6.0
3948 + Zero-filled memory can now be allocated from slab caches with
3949 + kmem_cache_zalloc(). There is also a new slab debugging option
3950 + to produce a /proc/slab_allocators file with detailed allocation
3951 + information.
3952 + */
3953 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
3954 +# define module_param(a,b,c) MODULE_PARM(#a,"i")
3955 +/* note below is only true for our current calls to module_param_array */
3956 +# define module_param_array(a,b,c,d) MODULE_PARM(#a,"1-2i")
3957 +#endif
3958 +
3959 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
3960 +/*
3961 + The skb_linearize() function has been reworked, and no longer has a
3962 + GFP flags argument. There is also a new skb_linearize_cow() function
3963 + which ensures that the resulting SKB is writable.
3964 + Network drivers should no longer manipulate the xmit_lock spinlock
3965 + in the net_device structure; instead, the following new functions
3966 + should be used:
3967 + int netif_tx_lock(struct net_device *dev);
3968 + int netif_tx_lock_bh(struct net_device *dev);
3969 + void netif_tx_unlock(struct net_device *dev);
3970 + void netif_tx_unlock_bh(struct net_device *dev);
3971 + int netif_tx_trylock(struct net_device *dev);
3972 + A number of crypto API changes have been merged, the biggest being
3973 + a change to most algorithm-specific functions to take a pointer to
3974 + the crypto_tfm structure, rather than the old "context" pointer. This
3975 + change was necessary to support parameterized algorithms.
3976 +*/
3977 +
3978 +# define HAVE_NEW_SKB_LINEARIZE
3979 +#endif
3980 +
3981 +/* this is the best we can do to detect XEN, which makes
3982 + * patches to linux/skbuff.h, making it look like 2.6.18 version
3983 + */
3984 +#ifdef CONFIG_XEN
3985 +# define HAVE_NEW_SKB_LINEARIZE
3986 +#endif
3987 +
3988 +/* And the same for SuSe kernels who have it before it got into the
3989 + * linus kernel.
3990 + */
3991 +#ifdef SLE_VERSION_CODE
3992 +# if SLE_VERSION_CODE >= 655616
3993 +# define HAVE_NEW_SKB_LINEARIZE
3994 +# else
3995 +# warning "A Suse kernel was detected, but we are unsure if it requires HAVE_NEW_SKB_LINEARIZE"
3996 +# endif
3997 +#endif
3998 +
3999 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
4000 +# define VOID_SOCK_UNREGISTER
4001 +#endif
4002 +
4003 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
4004 +/* skb->nfmark changed to skb->mark in 2.6.20 */
4005 +# define nfmark mark
4006 +#else
4007 +# define HAVE_KMEM_CACHE_T
4008 +#endif
4009 +
4010 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
4011 +/*
4012 + Significant changes have been made to the crypto support interface.
4013 + The sysctl code has been heavily reworked, leading to a number of
4014 + internal API changes.
4015 +*/
4016 +# define ipsec_register_sysctl_table(a,b) register_sysctl_table(a)
4017 +# define CTL_TABLE_PARENT
4018 +#else
4019 +# define ipsec_register_sysctl_table(a,b) register_sysctl_table(a,b)
4020 +#endif
4021 +
4022 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
4023 +/*
4024 + The eth_type_trans() function now sets the skb->dev field, consistent
4025 + with how similar functions for other link types operate. As a result,
4026 + many Ethernet drivers have been changed to remove the (now) redundant
4027 + assignment.
4028 + The header fields in the sk_buff structure have been renamed
4029 + and are no longer unions. Networking code and drivers can
4030 + now just use skb->transport_header, skb->network_header, and
4031 + skb->skb_mac_header. There are new functions for finding specific
4032 + headers within packets: tcp_hdr(), udp_hdr(), ipip_hdr(), and
4033 + ipipv6_hdr().
4034 + The crypto API has a new set of functions for use with asynchronous
4035 + block ciphers. There is also a new cryptd kernel thread which can
4036 + run any synchronous cipher in an asynchronous mode.
4037 + A new macro has been added to make the creation of slab caches easier:
4038 + struct kmem_cache KMEM_CACHE(struct-type, flags);
4039 + The result is the creation of a cache holding objects of the given
4040 + struct_type, named after that type, and with the additional slab
4041 + flags (if any).
4042 +*/
4043 +
4044 +/* need to include ip.h early, no longer pick it up in skbuff.h */
4045 +# include <linux/ip.h>
4046 +# define HAVE_KERNEL_TSTAMP
4047 +/* type of sock.sk_stamp changed from timeval to ktime */
4048 +# define grab_socket_timeval(tv, sock) { (tv) = ktime_to_timeval((sock).sk_stamp); }
4049 +#else
4050 +# define grab_socket_timeval(tv, sock) { (tv) = (sock).sk_stamp; }
4051 +/* internals of struct skbuff changed */
4052 +# define HAVE_DEV_NEXT
4053 +# define ip_hdr(skb) ((skb)->nh.iph)
4054 +# define skb_tail_pointer(skb) ((skb)->tail)
4055 +# define skb_end_pointer(skb) ((skb)->end)
4056 +# define skb_network_header(skb) ((skb)->nh.raw)
4057 +# define skb_set_network_header(skb,off) ((skb)->nh.raw = (skb)->data + (off))
4058 +# define tcp_hdr(skb) ((skb)->h.th)
4059 +# define udp_hdr(skb) ((skb)->h.uh)
4060 +# define skb_transport_header(skb) ((skb)->h.raw)
4061 +# define skb_set_transport_header(skb,off) ((skb)->h.raw = (skb)->data + (off))
4062 +# define skb_mac_header(skb) ((skb)->mac.raw)
4063 +# define skb_set_mac_header(skb,off) ((skb)->mac.raw = (skb)->data + (off))
4064 +#endif
4065 +/* turn a pointer into an offset for above macros */
4066 +#define ipsec_skb_offset(skb, ptr) (((unsigned char *)(ptr)) - (skb)->data)
4067 +
4068 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
4069 +/*
4070 + * The macro got introduced in 2,6,22 but it does not work properly, and
4071 + * still uses the old number of arguments.
4072 + */
4073 + /*
4074 + The destructor argument has been removed from kmem_cache_create(), as
4075 + destructors are no longer supported. All in-kernel callers have been
4076 + updated
4077 + */
4078 +# define HAVE_KMEM_CACHE_MACRO
4079 +
4080 +/* Try using the new kernel encaps hook for nat-t, instead of udp.c */
4081 +# ifdef NOT_YET_FINISHED
4082 +# define HAVE_UDP_ENCAP_CONVERT
4083 +# endif
4084 +
4085 +#endif
4086 +
4087 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4088 +/*
4089 + * We can switch on earlier kernels, but from here on we have no choice
4090 + * but to abandon the old style proc_net and use seq_file
4091 + * The hard_header() method has been removed from struct net_device;
4092 + it has been replaced by a per-protocol header_ops structure pointer.
4093 +
4094 + The prototype for slab constructor callbacks has changed to:
4095 + void (*ctor)(struct kmem_cache *cache, void *object);
4096 + The unused flags argument has been removed and the order of the other
4097 + two arguments has been reversed to match other slab functions.
4098 + */
4099 +# define HAVE_PROC_DIR_ENTRY
4100 +# define PROC_NET init_net.proc_net
4101 +
4102 +# define __ipsec_dev_get(x) __dev_get_by_name(&init_net, x)
4103 +# define ipsec_dev_get(x) dev_get_by_name(&init_net, x)
4104 +#else
4105 +
4106 +# define PROC_NET proc_net
4107 +
4108 +# define ipsec_dev_get(x) __dev_get_by_name(x)
4109 +# define __ipsec_dev_get(x) __dev_get_by_name(x)
4110 +#endif
4111 +
4112 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
4113 +# define ip_chk_addr(a) inet_addr_type(&init_net, a)
4114 +
4115 +# define l_inet_addr_type(a) inet_addr_type(&init_net, a)
4116 +
4117 +#else
4118 +# define ip_chk_addr inet_addr_type
4119 +
4120 +#define l_inet_addr_type inet_addr_type
4121 +
4122 +#endif
4123 +
4124 +#ifndef NETDEV_TX_BUSY
4125 +# ifdef NETDEV_XMIT_CN
4126 +# define NETDEV_TX_BUSY NETDEV_XMIT_CN
4127 +# else
4128 +# define NETDEV_TX_BUSY 1
4129 +# endif
4130 +#endif
4131 +
4132 +
4133 +#ifdef NET_21
4134 +# define ipsec_kfree_skb(a) kfree_skb(a)
4135 +#else /* NET_21 */
4136 +# define ipsec_kfree_skb(a) kfree_skb(a, FREE_WRITE)
4137 +#endif /* NET_21 */
4138 +
4139 +#ifdef NETDEV_23
4140 +
4141 +#ifndef SPINLOCK
4142 +# include <linux/bios32.h>
4143 + /* simulate spin locks and read/write locks */
4144 + typedef struct {
4145 + volatile char lock;
4146 + } spinlock_t;
4147 +
4148 + typedef struct {
4149 + volatile unsigned int lock;
4150 + } rwlock_t;
4151 +
4152 +# define spin_lock_init(x) { (x)->lock = 0;}
4153 +# define rw_lock_init(x) { (x)->lock = 0; }
4154 +
4155 +# define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;}
4156 +# define spin_lock_irq(x) { cli(); spin_lock(x);}
4157 +# define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);}
4158 +
4159 +# define spin_unlock(x) { (x)->lock=0;}
4160 +# define spin_unlock_irq(x) { spin_unlock(x); sti();}
4161 +# define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);}
4162 +
4163 +# define read_lock(x) spin_lock(x)
4164 +# define read_lock_irq(x) spin_lock_irq(x)
4165 +# define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
4166 +
4167 +# define read_unlock(x) spin_unlock(x)
4168 +# define read_unlock_irq(x) spin_unlock_irq(x)
4169 +# define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
4170 +
4171 +# define write_lock(x) spin_lock(x)
4172 +# define write_lock_irq(x) spin_lock_irq(x)
4173 +# define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
4174 +
4175 +# define write_unlock(x) spin_unlock(x)
4176 +# define write_unlock_irq(x) spin_unlock_irq(x)
4177 +# define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
4178 +#endif /* !SPINLOCK */
4179 +
4180 +#ifndef SPINLOCK_23
4181 +# define spin_lock_bh(x) spin_lock_irq(x)
4182 +# define spin_unlock_bh(x) spin_unlock_irq(x)
4183 +
4184 +# define read_lock_bh(x) read_lock_irq(x)
4185 +# define read_unlock_bh(x) read_unlock_irq(x)
4186 +
4187 +# define write_lock_bh(x) write_lock_irq(x)
4188 +# define write_unlock_bh(x) write_unlock_irq(x)
4189 +#endif /* !SPINLOCK_23 */
4190 +
4191 +#ifndef HAVE_NETDEV_PRINTK
4192 +#define netdev_printk(sevlevel, netdev, msglevel, format, arg...) \
4193 + printk(sevlevel "%s: " format , netdev->name , ## arg)
4194 +#endif
4195 +
4196 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
4197 +#define PROC_NET init_net.proc_net
4198 +#define PROC_EOF_DATA
4199 +#else
4200 +#define PROC_NET proc_net
4201 +#endif
4202 +
4203 +#ifdef NET_21
4204 +# include <linux/in6.h>
4205 +#else
4206 + /* old kernel in.h has some IPv6 stuff, but not quite enough */
4207 +# define s6_addr16 s6_addr
4208 +# define AF_INET6 10
4209 +# define uint8_t __u8
4210 +# define uint16_t __u16
4211 +# define uint32_t __u32
4212 +# define uint64_t __u64
4213 +#endif
4214 +
4215 +#if __KERNEL__
4216 +# if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0)
4217 +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4218 +# include "openswan/ipsec_kern24.h"
4219 +# else
4220 +# error "kernels before 2.4 are not supported at this time"
4221 +# endif
4222 +# endif
4223 +#endif
4224 +
4225 +#endif /* _OPENSWAN_KVERSIONS_H */
4226 +
4227 --- /dev/null Tue Mar 11 13:02:56 2003
4228 +++ linux/include/openswan/ipsec_life.h Mon Feb 9 13:51:03 2004
4229 @@ -0,0 +1,112 @@
4230 +/*
4231 + * Definitions relevant to IPSEC lifetimes
4232 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
4233 + * and Michael Richardson <mcr@freeswan.org>
4234 + *
4235 + * This program is free software; you can redistribute it and/or modify it
4236 + * under the terms of the GNU General Public License as published by the
4237 + * Free Software Foundation; either version 2 of the License, or (at your
4238 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4239 + *
4240 + * This program is distributed in the hope that it will be useful, but
4241 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4242 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4243 + * for more details.
4244 + *
4245 + * RCSID $Id: ipsec_life.h,v 1.4 2004/04/05 19:55:05 mcr Exp $
4246 + *
4247 + * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
4248 + *
4249 + */
4250 +
4251 +/*
4252 + * This file describes the book keeping fields for the
4253 + * IPsec Security Association Structure. ("ipsec_sa")
4254 + *
4255 + * This structure is never allocated directly by kernel code,
4256 + * (it is always a static/auto or is part of a structure)
4257 + * so it does not have a reference count.
4258 + *
4259 + */
4260 +
4261 +#ifndef _IPSEC_LIFE_H_
4262 +
4263 +/*
4264 + * _count is total count.
4265 + * _hard is hard limit (kill SA after this number)
4266 + * _soft is soft limit (try to renew SA after this number)
4267 + * _last is used in some special cases.
4268 + *
4269 + */
4270 +
4271 +struct ipsec_lifetime64
4272 +{
4273 + __u64 ipl_count;
4274 + __u64 ipl_soft;
4275 + __u64 ipl_hard;
4276 + __u64 ipl_last;
4277 +};
4278 +
4279 +struct ipsec_lifetimes
4280 +{
4281 + /* number of bytes processed */
4282 + struct ipsec_lifetime64 ipl_bytes;
4283 +
4284 + /* number of packets processed */
4285 + struct ipsec_lifetime64 ipl_packets;
4286 +
4287 + /* time since SA was added */
4288 + struct ipsec_lifetime64 ipl_addtime;
4289 +
4290 + /* time since SA was first used */
4291 + struct ipsec_lifetime64 ipl_usetime;
4292 +
4293 + /* from rfc2367:
4294 + * For CURRENT, the number of different connections,
4295 + * endpoints, or flows that the association has been
4296 + * allocated towards. For HARD and SOFT, the number of
4297 + * these the association may be allocated towards
4298 + * before it expires. The concept of a connection,
4299 + * flow, or endpoint is system specific.
4300 + *
4301 + * mcr(2001-9-18) it is unclear what purpose these serve for FreeSWAN.
4302 + * They are maintained for PF_KEY compatibility.
4303 + */
4304 + struct ipsec_lifetime64 ipl_allocations;
4305 +};
4306 +
4307 +enum ipsec_life_alive {
4308 + ipsec_life_harddied = -1,
4309 + ipsec_life_softdied = 0,
4310 + ipsec_life_okay = 1
4311 +};
4312 +
4313 +enum ipsec_life_type {
4314 + ipsec_life_timebased = 1,
4315 + ipsec_life_countbased= 0
4316 +};
4317 +
4318 +#define _IPSEC_LIFE_H_
4319 +#endif /* _IPSEC_LIFE_H_ */
4320 +
4321 +
4322 +/*
4323 + * $Log: ipsec_life.h,v $
4324 + * Revision 1.4 2004/04/05 19:55:05 mcr
4325 + * Moved from linux/include/freeswan/ipsec_life.h,v
4326 + *
4327 + * Revision 1.3 2002/04/24 07:36:46 mcr
4328 + * Moved from ./klips/net/ipsec/ipsec_life.h,v
4329 + *
4330 + * Revision 1.2 2001/11/26 09:16:14 rgb
4331 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
4332 + *
4333 + * Revision 1.1.2.1 2001/09/25 02:25:58 mcr
4334 + * lifetime structure created and common functions created.
4335 + *
4336 + *
4337 + * Local variables:
4338 + * c-file-style: "linux"
4339 + * End:
4340 + *
4341 + */
4342 --- /dev/null Tue Mar 11 13:02:56 2003
4343 +++ linux/include/openswan/ipsec_mast.h Mon Feb 9 13:51:03 2004
4344 @@ -0,0 +1,59 @@
4345 +#ifndef _IPSEC_MAST_H
4346 +#define _IPSEC_MAST_H
4347 +
4348 +#ifdef CONFIG_KLIPS_DEBUG
4349 +#define DB_MAST_INIT 0x0001
4350 +#define DB_MAST_PROCFS 0x0002
4351 +#define DB_MAST_XMIT 0x0010
4352 +#define DB_MAST_OHDR 0x0020
4353 +#define DB_MAST_CROUT 0x0040
4354 +#define DB_MAST_OXFS 0x0080
4355 +#define DB_MAST_REVEC 0x0100
4356 +#define DB_MAST_ENCAP 0x0200
4357 +#endif /* CONFIG_KLIPS_DEBUG */
4358 +
4359 +struct ipsecmastconf {
4360 + __u32 cf_cmd;
4361 + union
4362 + {
4363 + char cfu_name[12];
4364 + } cf_u;
4365 +#define cf_name cf_u.cfu_name
4366 +};
4367 +
4368 +struct mastpriv
4369 +{
4370 + struct sk_buff_head sendq;
4371 + struct wait_queue *wait_queue;
4372 + int (*hard_header) (struct sk_buff *skb,
4373 + struct net_device *dev,
4374 + unsigned short type,
4375 + void *daddr,
4376 + void *saddr,
4377 + unsigned len);
4378 +#if 0
4379 + char locked;
4380 + int (*hard_start_xmit) (struct sk_buff *skb,
4381 + struct net_device *dev);
4382 + int (*rebuild_header)(struct sk_buff *skb);
4383 + int (*set_mac_address)(struct net_device *dev, void *addr);
4384 + void (*header_cache_bind)(struct hh_cache **hhp, struct net_device *dev,
4385 + unsigned short htype, __u32 daddr);
4386 + void (*header_cache_update)(struct hh_cache *hh,
4387 + struct net_device *dev,
4388 + unsigned char * haddr);
4389 + struct net_device_stats *(*get_stats)(struct net_device *dev);
4390 +#endif
4391 + struct net_device_stats mystats;
4392 + int mtu; /* What is the desired MTU? */
4393 +};
4394 +
4395 +extern int ipsec_mast_init_devices(void);
4396 +extern int ipsec_mast_deletenum(int vifnum);
4397 +extern int ipsec_mast_createnum(int vifnum);
4398 +extern struct net_device *ipsec_mast_get_device(int vifnum);
4399 +extern unsigned int ipsec_mast_is_transport(int vifnum);
4400 +
4401 +
4402 +
4403 +#endif
4404 --- /dev/null Tue Mar 11 13:02:56 2003
4405 +++ linux/include/openswan/ipsec_md5h.h Mon Feb 9 13:51:03 2004
4406 @@ -0,0 +1,143 @@
4407 +/*
4408 + * RCSID $Id: ipsec_md5h.h,v 1.10 2004/09/08 17:21:35 ken Exp $
4409 + */
4410 +
4411 +/*
4412 + * The rest of this file is Copyright RSA DSI. See the following comments
4413 + * for the full Copyright notice.
4414 + */
4415 +
4416 +#ifndef _IPSEC_MD5H_H_
4417 +#define _IPSEC_MD5H_H_
4418 +
4419 +/* GLOBAL.H - RSAREF types and constants
4420 + */
4421 +
4422 +/* PROTOTYPES should be set to one if and only if the compiler supports
4423 + function argument prototyping.
4424 + The following makes PROTOTYPES default to 0 if it has not already
4425 + been defined with C compiler flags.
4426 + */
4427 +#ifndef PROTOTYPES
4428 +#define PROTOTYPES 1
4429 +#endif /* !PROTOTYPES */
4430 +
4431 +/* POINTER defines a generic pointer type */
4432 +typedef __u8 *POINTER;
4433 +
4434 +/* UINT2 defines a two byte word */
4435 +typedef __u16 UINT2;
4436 +
4437 +/* UINT4 defines a four byte word */
4438 +typedef __u32 UINT4;
4439 +
4440 +/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
4441 + If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
4442 + returns an empty list.
4443 + */
4444 +
4445 +#if PROTOTYPES
4446 +#define PROTO_LIST(list) list
4447 +#else /* PROTOTYPES */
4448 +#define PROTO_LIST(list) ()
4449 +#endif /* PROTOTYPES */
4450 +
4451 +
4452 +/* MD5.H - header file for MD5C.C
4453 + */
4454 +
4455 +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
4456 +rights reserved.
4457 +
4458 +License to copy and use this software is granted provided that it
4459 +is identified as the "RSA Data Security, Inc. MD5 Message-Digest
4460 +Algorithm" in all material mentioning or referencing this software
4461 +or this function.
4462 +
4463 +License is also granted to make and use derivative works provided
4464 +that such works are identified as "derived from the RSA Data
4465 +Security, Inc. MD5 Message-Digest Algorithm" in all material
4466 +mentioning or referencing the derived work.
4467 +
4468 +RSA Data Security, Inc. makes no representations concerning either
4469 +the merchantability of this software or the suitability of this
4470 +software for any particular purpose. It is provided "as is"
4471 +without express or implied warranty of any kind.
4472 +
4473 +These notices must be retained in any copies of any part of this
4474 +documentation and/or software.
4475 + */
4476 +
4477 +/* MD5 context. */
4478 +typedef struct {
4479 + UINT4 state[4]; /* state (ABCD) */
4480 + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
4481 + unsigned char buffer[64]; /* input buffer */
4482 +} MD5_CTX;
4483 +
4484 +void osMD5Init PROTO_LIST ((void *));
4485 +void osMD5Update PROTO_LIST
4486 + ((void *, unsigned char *, __u32));
4487 +void osMD5Final PROTO_LIST ((unsigned char [16], void *));
4488 +
4489 +#endif /* _IPSEC_MD5H_H_ */
4490 +
4491 +/*
4492 + * $Log: ipsec_md5h.h,v $
4493 + * Revision 1.10 2004/09/08 17:21:35 ken
4494 + * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
4495 + *
4496 + * Revision 1.9 2004/04/05 19:55:05 mcr
4497 + * Moved from linux/include/freeswan/ipsec_md5h.h,v
4498 + *
4499 + * Revision 1.8 2002/09/10 01:45:09 mcr
4500 + * changed type of MD5_CTX and SHA1_CTX to void * so that
4501 + * the function prototypes would match, and could be placed
4502 + * into a pointer to a function.
4503 + *
4504 + * Revision 1.7 2002/04/24 07:36:46 mcr
4505 + * Moved from ./klips/net/ipsec/ipsec_md5h.h,v
4506 + *
4507 + * Revision 1.6 1999/12/13 13:59:13 rgb
4508 + * Quick fix to argument size to Update bugs.
4509 + *
4510 + * Revision 1.5 1999/12/07 18:16:23 rgb
4511 + * Fixed comments at end of #endif lines.
4512 + *
4513 + * Revision 1.4 1999/04/06 04:54:26 rgb
4514 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
4515 + * patch shell fixes.
4516 + *
4517 + * Revision 1.3 1999/01/22 06:19:58 rgb
4518 + * 64-bit clean-up.
4519 + *
4520 + * Revision 1.2 1998/11/30 13:22:54 rgb
4521 + * Rationalised all the klips kernel file headers. They are much shorter
4522 + * now and won't conflict under RH5.2.
4523 + *
4524 + * Revision 1.1 1998/06/18 21:27:48 henry
4525 + * move sources from klips/src to klips/net/ipsec, to keep stupid
4526 + * kernel-build scripts happier in the presence of symlinks
4527 + *
4528 + * Revision 1.2 1998/04/23 20:54:03 rgb
4529 + * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
4530 + * verified.
4531 + *
4532 + * Revision 1.1 1998/04/09 03:04:21 henry
4533 + * sources moved up from linux/net/ipsec
4534 + * these two include files modified not to include others except in kernel
4535 + *
4536 + * Revision 1.1.1.1 1998/04/08 05:35:03 henry
4537 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
4538 + *
4539 + * Revision 0.4 1997/01/15 01:28:15 ji
4540 + * No changes.
4541 + *
4542 + * Revision 0.3 1996/11/20 14:48:53 ji
4543 + * Release update only.
4544 + *
4545 + * Revision 0.2 1996/11/02 00:18:33 ji
4546 + * First limited release.
4547 + *
4548 + *
4549 + */
4550 --- /dev/null Tue Mar 11 13:02:56 2003
4551 +++ linux/include/openswan/ipsec_param.h Mon Feb 9 13:51:03 2004
4552 @@ -0,0 +1,268 @@
4553 +/*
4554 + * @(#) Openswan tunable paramaters
4555 + *
4556 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
4557 + * and Michael Richardson <mcr@freeswan.org>
4558 + * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
4559 + *
4560 + * This program is free software; you can redistribute it and/or modify it
4561 + * under the terms of the GNU General Public License as published by the
4562 + * Free Software Foundation; either version 2 of the License, or (at your
4563 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4564 + *
4565 + * This program is distributed in the hope that it will be useful, but
4566 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4567 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4568 + * for more details.
4569 + *
4570 + *
4571 + */
4572 +
4573 +/*
4574 + * This file provides a set of #define's which may be tuned by various
4575 + * people/configurations. It keeps all compile-time tunables in one place.
4576 + *
4577 + * This file should be included before all other IPsec kernel-only files.
4578 + *
4579 + */
4580 +
4581 +#ifndef _IPSEC_PARAM_H_
4582 +
4583 +#ifdef __KERNEL__
4584 +
4585 +#include "openswan/ipsec_kversion.h"
4586 +
4587 +/* Set number of ipsecX virtual devices here. */
4588 +/* This must be < exp(field width of IPSEC_DEV_FORMAT) */
4589 +/* It must also be reasonable so as not to overload the memory and CPU */
4590 +/* constraints of the host. */
4591 +#ifdef CONFIG_KLIPS_IF_MAX
4592 +#define IPSEC_NUM_IFMAX CONFIG_KLIPS_IF_MAX
4593 +#endif
4594 +#ifndef IPSEC_NUM_IFMAX
4595 +#define IPSEC_NUM_IFMAX 64
4596 +#endif
4597 +
4598 +/* default number of ipsecX devices to create */
4599 +#define IPSEC_NUM_IF 2
4600 +
4601 +/* The field width must be < IF_NAM_SIZ - strlen("ipsec") - 1. */
4602 +/* With "ipsec" being 5 characters, that means 10 is the max field width */
4603 +/* but machine memory and CPU constraints are not likely to tollerate */
4604 +/* more than 3 digits. The default is one digit. */
4605 +/* Update: userland scripts get upset if they can't find "ipsec0", so */
4606 +/* for now, no "0"-padding should be used (which would have been helpful */
4607 +/* to make text-searches work */
4608 +#define IPSEC_DEV_FORMAT "ipsec%d"
4609 +#define MAST_DEV_FORMAT "mast%d"
4610 +
4611 +/* For, say, 500 virtual ipsec devices, I would recommend: */
4612 +/* #define IPSEC_NUM_IF 500 */
4613 +/* #define IPSEC_DEV_FORMAT "ipsec%03d" */
4614 +/* Note that the "interfaces=" line in /etc/ipsec.conf would be, um, challenging. */
4615 +
4616 +/* use dynamic ipsecX device allocation */
4617 +#ifndef CONFIG_KLIPS_DYNDEV
4618 +#define CONFIG_KLIPS_DYNDEV 1
4619 +#endif /* CONFIG_KLIPS_DYNDEV */
4620 +
4621 +
4622 +#ifdef CONFIG_KLIPS_BIGGATE
4623 +# define SADB_HASHMOD 8069
4624 +#else /* CONFIG_KLIPS_BIGGATE */
4625 +# define SADB_HASHMOD 257
4626 +#endif /* CONFIG_KLIPS_BIGGATE */
4627 +
4628 +#endif /* __KERNEL__ */
4629 +
4630 +/*
4631 + * This is for the SA reference table. This number is related to the
4632 + * maximum number of SAs that KLIPS can concurrently deal with, plus enough
4633 + * space for keeping expired SAs around.
4634 + *
4635 + * TABLE_IDX_WIDTH is the number of bits that we will use.
4636 + * MAIN_TABLE_WIDTH is the number of bits used for the primary index table.
4637 + *
4638 + */
4639 +#ifndef IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
4640 +# define IPSEC_SA_REF_MAINTABLE_IDX_WIDTH 4
4641 +#endif
4642 +
4643 +#ifndef IPSEC_SA_REF_FREELIST_NUM_ENTRIES
4644 +# define IPSEC_SA_REF_FREELIST_NUM_ENTRIES 256
4645 +#endif
4646 +
4647 +#ifndef IPSEC_SA_REF_CODE
4648 +# define IPSEC_SA_REF_CODE 1
4649 +#endif
4650 +
4651 +#ifdef __KERNEL__
4652 +/* This is defined for 2.4, but not 2.2.... */
4653 +#ifndef ARPHRD_VOID
4654 +# define ARPHRD_VOID 0xFFFF
4655 +#endif
4656 +
4657 +/* always turn on IPIP mode */
4658 +#ifndef CONFIG_KLIPS_IPIP
4659 +#define CONFIG_KLIPS_IPIP 1
4660 +#endif
4661 +
4662 +/*
4663 + * Worry about PROC_FS stuff
4664 + */
4665 +#if defined(PROC_FS_2325)
4666 +/* kernel 2.4 */
4667 +# define IPSEC_PROC_LAST_ARG ,int *eof,void *data
4668 +# define IPSEC_PROCFS_DEBUG_NO_STATIC
4669 +# define IPSEC_PROC_SUBDIRS
4670 +#else
4671 +/* kernel <2.4 */
4672 +# define IPSEC_PROCFS_DEBUG_NO_STATIC DEBUG_NO_STATIC
4673 +
4674 +# ifndef PROC_NO_DUMMY
4675 +# define IPSEC_PROC_LAST_ARG , int dummy
4676 +# else
4677 +# define IPSEC_PROC_LAST_ARG
4678 +# endif /* !PROC_NO_DUMMY */
4679 +#endif /* PROC_FS_2325 */
4680 +
4681 +#if !defined(LINUX_KERNEL_HAS_SNPRINTF)
4682 +/* GNU CPP specific! */
4683 +# define snprintf(buf, len, fmt...) sprintf(buf, ##fmt)
4684 +#endif /* !LINUX_KERNEL_HAS_SNPRINTF */
4685 +
4686 +#ifdef SPINLOCK
4687 +# ifdef SPINLOCK_23
4688 +# include <linux/spinlock.h> /* *lock* */
4689 +# else /* SPINLOCK_23 */
4690 +# include <asm/spinlock.h> /* *lock* */
4691 +# endif /* SPINLOCK_23 */
4692 +#endif /* SPINLOCK */
4693 +
4694 +#ifndef KLIPS_FIXES_DES_PARITY
4695 +# define KLIPS_FIXES_DES_PARITY 1
4696 +#endif /* !KLIPS_FIXES_DES_PARITY */
4697 +
4698 +/* we don't really want to print these unless there are really big problems */
4699 +#ifndef KLIPS_DIVULGE_CYPHER_KEY
4700 +# define KLIPS_DIVULGE_CYPHER_KEY 0
4701 +#endif /* !KLIPS_DIVULGE_CYPHER_KEY */
4702 +
4703 +#ifndef KLIPS_DIVULGE_HMAC_KEY
4704 +# define KLIPS_DIVULGE_HMAC_KEY 0
4705 +#endif /* !KLIPS_DIVULGE_HMAC_KEY */
4706 +
4707 +#ifndef IPSEC_DISALLOW_IPOPTIONS
4708 +# define IPSEC_DISALLOW_IPOPTIONS 1
4709 +#endif /* !KLIPS_DIVULGE_HMAC_KEY */
4710 +
4711 +/* extra toggles for regression testing */
4712 +#ifdef CONFIG_KLIPS_REGRESS
4713 +
4714 +/*
4715 + * should pfkey_acquire() become 100% lossy?
4716 + *
4717 + */
4718 +extern int sysctl_ipsec_regress_pfkey_lossage;
4719 +#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE
4720 +# ifdef CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE
4721 +# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100
4722 +# else /* CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE */
4723 +/* not by default! */
4724 +# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
4725 +# endif /* CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE */
4726 +#endif /* KLIPS_PFKEY_ACQUIRE_LOSSAGE */
4727 +
4728 +#endif /* CONFIG_KLIPS_REGRESS */
4729 +
4730 +
4731 +/*
4732 + * debugging routines.
4733 + */
4734 +#ifdef CONFIG_KLIPS_DEBUG
4735 + #define KLIPS_ERROR(flag, format, args...) if(printk_ratelimit() || flag) printk(KERN_ERR "KLIPS " format, ## args)
4736 + #define KLIPS_PRINT(flag, format, args...) \
4737 + ((flag) ? printk(KERN_INFO format , ## args) : 0)
4738 + #define KLIPS_PRINTMORE(flag, format, args...) \
4739 + ((flag) ? printk(format , ## args) : 0)
4740 + #define KLIPS_IP_PRINT(flag, ip) \
4741 + ((flag) ? ipsec_print_ip(ip) : 0)
4742 + #define KLIPS_SATOT(flag, sa, format, dst, dstlen) \
4743 + ((flag) ? satot(sa, format, dst, dstlen) : 0)
4744 +#else /* CONFIG_KLIPS_DEBUG */
4745 + #define KLIPS_ERROR(flag, format, args...) if(printk_ratelimit()) printk(KERN_ERR "KLIPS " format, ## args)
4746 + #define KLIPS_PRINT(flag, format, args...) do ; while(0)
4747 + #define KLIPS_PRINTMORE(flag, format, args...) do ; while(0)
4748 + #define KLIPS_IP_PRINT(flag, ip) do ; while(0)
4749 + #define KLIPS_SATOT(flag, sa, format, dst, dstlen) (0)
4750 +#endif /* CONFIG_KLIPS_DEBUG */
4751 +
4752 +
4753 +/*
4754 + * Stupid kernel API differences in APIs. Not only do some
4755 + * kernels not have ip_select_ident, but some have differing APIs,
4756 + * and SuSE has one with one parameter, but no way of checking to
4757 + * see what is really what.
4758 + */
4759 +
4760 +#ifdef SUSE_LINUX_2_4_19_IS_STUPID
4761 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
4762 +#else
4763 +
4764 +/* simplest case, nothing */
4765 +#if !defined(IP_SELECT_IDENT)
4766 +#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
4767 +#endif
4768 +
4769 +/* kernels > 2.3.37-ish */
4770 +#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
4771 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
4772 +#endif
4773 +
4774 +/* kernels > 2.4.2 */
4775 +#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
4776 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
4777 +#endif
4778 +
4779 +#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
4780 +
4781 +/*
4782 + * make klips fail test:east-espiv-01.
4783 + * exploit is at testing/attacks/espiv
4784 + *
4785 + */
4786 +#define KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK 0
4787 +
4788 +
4789 +/* IP_FRAGMENT_LINEARIZE is set in freeswan.h if Kernel > 2.4.4 */
4790 +#ifndef IP_FRAGMENT_LINEARIZE
4791 +# define IP_FRAGMENT_LINEARIZE 0
4792 +#endif /* IP_FRAGMENT_LINEARIZE */
4793 +#endif /* __KERNEL__ */
4794 +
4795 +#ifdef NEED_INET_PROTOCOL
4796 +#define inet_protocol net_protocol
4797 +#endif
4798 +
4799 +#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && CONFIG_IPSEC_NAT_TRAVERSAL
4800 +#define NAT_TRAVERSAL 1
4801 +#else
4802 +/* let people either #undef, or #define = 0 it */
4803 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
4804 +#undef CONFIG_IPSEC_NAT_TRAVERSAL
4805 +#endif
4806 +#endif
4807 +
4808 +#ifndef IPSEC_DEFAULT_TTL
4809 +#define IPSEC_DEFAULT_TTL 64
4810 +#endif
4811 +
4812 +#define _IPSEC_PARAM_H_
4813 +#endif /* _IPSEC_PARAM_H_ */
4814 +
4815 +/*
4816 + * Local variables:
4817 + * c-file-style: "linux"
4818 + * End:
4819 + *
4820 + */
4821 --- /dev/null Tue Mar 11 13:02:56 2003
4822 +++ linux/include/openswan/ipsec_policy.h Mon Feb 9 13:51:03 2004
4823 @@ -0,0 +1,239 @@
4824 +#ifndef _IPSEC_POLICY_H
4825 +/*
4826 + * policy interface file between pluto and applications
4827 + * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
4828 + *
4829 + * This library is free software; you can redistribute it and/or modify it
4830 + * under the terms of the GNU Library General Public License as published by
4831 + * the Free Software Foundation; either version 2 of the License, or (at your
4832 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
4833 + *
4834 + * This library is distributed in the hope that it will be useful, but
4835 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4836 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
4837 + * License for more details.
4838 + *
4839 + * RCSID $Id: ipsec_policy.h,v 1.8 2005/07/26 01:12:38 mcr Exp $
4840 + */
4841 +#define _IPSEC_POLICY_H /* seen it, no need to see it again */
4842 +
4843 +
4844 +/*
4845 + * this file defines an interface between an application (or rather an
4846 + * application library) and a key/policy daemon. It provides for inquiries
4847 + * as to the current state of a connected socket, as well as for general
4848 + * questions.
4849 + *
4850 + * In general, the interface is defined as a series of functional interfaces,
4851 + * and the policy messages should be internal. However, because this is in
4852 + * fact an ABI between pieces of the system that may get compiled and revised
4853 + * seperately, this ABI must be public and revision controlled.
4854 + *
4855 + * It is expected that the daemon will always support previous versions.
4856 + */
4857 +
4858 +#define IPSEC_POLICY_MSG_REVISION (unsigned)200305061
4859 +
4860 +enum ipsec_policy_command {
4861 + IPSEC_CMD_QUERY_FD = 1,
4862 + IPSEC_CMD_QUERY_HOSTPAIR = 2,
4863 + IPSEC_CMD_QUERY_DSTONLY = 3,
4864 +};
4865 +
4866 +struct ipsec_policy_msg_head {
4867 + u_int32_t ipm_version;
4868 + u_int32_t ipm_msg_len;
4869 + u_int32_t ipm_msg_type;
4870 + u_int32_t ipm_msg_seq;
4871 +};
4872 +
4873 +enum ipsec_privacy_quality {
4874 + IPSEC_PRIVACY_NONE = 0,
4875 + IPSEC_PRIVACY_INTEGRAL = 4, /* not private at all. AH-like */
4876 + IPSEC_PRIVACY_UNKNOWN = 8, /* something is claimed, but details unavail */
4877 + IPSEC_PRIVACY_ROT13 = 12, /* trivially breakable, i.e. 1DES */
4878 + IPSEC_PRIVACY_GAK = 16, /* known eavesdroppers */
4879 + IPSEC_PRIVACY_PRIVATE = 32, /* secure for at least a decade */
4880 + IPSEC_PRIVACY_STRONG = 64, /* ridiculously secure */
4881 + IPSEC_PRIVACY_TORTOISE = 192, /* even stronger, but very slow */
4882 + IPSEC_PRIVACY_OTP = 224, /* some kind of *true* one time pad */
4883 +};
4884 +
4885 +enum ipsec_bandwidth_quality {
4886 + IPSEC_QOS_UNKNOWN = 0, /* unknown bandwidth */
4887 + IPSEC_QOS_INTERACTIVE = 16, /* reasonably moderate jitter, moderate fast.
4888 + Good enough for telnet/ssh. */
4889 + IPSEC_QOS_VOIP = 32, /* faster crypto, predicable jitter */
4890 + IPSEC_QOS_FTP = 64, /* higher throughput crypto, perhaps hardware
4891 + offloaded, but latency/jitter may be bad */
4892 + IPSEC_QOS_WIRESPEED = 128, /* expect to be able to fill your pipe */
4893 +};
4894 +
4895 +/* moved from programs/pluto/constants.h */
4896 +/* IPsec AH transform values
4897 + * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.3
4898 + * and in http://www.iana.org/assignments/isakmp-registry
4899 + */
4900 +enum ipsec_authentication_algo {
4901 + AH_NONE=0,
4902 + AH_MD5=2,
4903 + AH_SHA=3,
4904 + AH_DES=4,
4905 + AH_SHA2_256=5,
4906 + AH_SHA2_384=6,
4907 + AH_SHA2_512=7,
4908 + AH_RIPEMD=8,
4909 + AH__AES_XCBC_MAC=9,
4910 + AH_RSA=10
4911 +};
4912 +
4913 +/* IPsec ESP transform values
4914 + * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.4
4915 + * and from http://www.iana.org/assignments/isakmp-registry
4916 + */
4917 +
4918 +enum ipsec_cipher_algo {
4919 + ESP_reserved=0,
4920 + ESP_DES_IV64=1,
4921 + ESP_DES=2,
4922 + ESP_3DES=3,
4923 + ESP_RC5=4,
4924 + ESP_IDEA=5,
4925 + ESP_CAST=6,
4926 + ESP_BLOWFISH=7,
4927 + ESP_3IDEA=8,
4928 + ESP_DES_IV32=9,
4929 + ESP_RC4=10,
4930 + ESP_NULL=11,
4931 + ESP_AES=12, /* 128 bit AES */
4932 + ESP_AES_CTR=13,
4933 + ESP_AES_CCM_8=14,
4934 + ESP_AES_CCM_12=15,
4935 + ESP_AES_CCM_16=16,
4936 + /* unassigned=17 */
4937 + ESP_AES_GCM_8=18,
4938 + ESP_AES_GCM_12=19,
4939 + ESP_AES_GCM_16=20,
4940 + ESP_SEED_CBC=21,
4941 + ESP_CAMELLIA=22,
4942 + /* 249-255 reserved for private use */
4943 +};
4944 +
4945 +/* IPCOMP transform values
4946 + * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.5
4947 + */
4948 +
4949 +enum ipsec_comp_algo {
4950 + IPCOMP_OUI= 1,
4951 + IPCOMP_DEFLATE= 2,
4952 + IPCOMP_LZS= 3,
4953 + IPCOMP_V42BIS= 4
4954 +};
4955 +
4956 +/* Identification type values
4957 + * RFC 2407 The Internet IP security Domain of Interpretation for
4958 + * ISAKMP 4.6.2.1
4959 + *
4960 + * Also for RFC4306.
4961 + *
4962 + * enum ident_names;
4963 + */
4964 +
4965 +enum ipsec_id_type {
4966 + ID_FROMCERT= (-3), /* taken from certificate */
4967 + ID_IMPOSSIBLE= (-2), /* private to Pluto */
4968 + ID_MYID= (-1), /* private to Pluto */
4969 + ID_NONE= 0, /* private to Pluto */
4970 + ID_IPV4_ADDR= 1,
4971 + ID_FQDN= 2,
4972 + ID_USER_FQDN= 3,
4973 + ID_RFC822_ADDR = ID_USER_FQDN, /* RFC4306 */
4974 + ID_IPV4_ADDR_SUBNET= 4,
4975 + ID_IPV6_ADDR= 5,
4976 + ID_IPV6_ADDR_SUBNET= 6,
4977 + ID_IPV4_ADDR_RANGE= 7,
4978 + ID_IPV6_ADDR_RANGE= 8,
4979 + ID_DER_ASN1_DN= 9,
4980 + ID_DER_ASN1_GN= 10,
4981 + ID_KEY_ID= 11
4982 +};
4983 +
4984 +/* Certificate type values
4985 + * RFC 2408 ISAKMP, chapter 3.9
4986 + */
4987 +enum ipsec_cert_type {
4988 + CERT_NONE= 0, /* none, or guess from file contents */
4989 + CERT_PKCS7_WRAPPED_X509= 1, /* self-signed certificate from disk */
4990 + CERT_PGP= 2,
4991 + CERT_DNS_SIGNED_KEY= 3, /* KEY RR from DNS */
4992 + CERT_X509_SIGNATURE= 4,
4993 + CERT_X509_KEY_EXCHANGE= 5,
4994 + CERT_KERBEROS_TOKENS= 6,
4995 + CERT_CRL= 7,
4996 + CERT_ARL= 8,
4997 + CERT_SPKI= 9,
4998 + CERT_X509_ATTRIBUTE= 10,
4999 + CERT_RAW_RSA= 11, /* raw RSA from config file */
5000 +};
5001 +
5002 +/* a SIG record in ASCII */
5003 +struct ipsec_dns_sig {
5004 + char fqdn[256];
5005 + char dns_sig[768]; /* empty string if not signed */
5006 +};
5007 +
5008 +struct ipsec_raw_key {
5009 + char id_name[256];
5010 + char fs_keyid[8];
5011 +};
5012 +
5013 +struct ipsec_identity {
5014 + enum ipsec_id_type ii_type;
5015 + enum ipsec_cert_type ii_format;
5016 + union {
5017 + struct ipsec_dns_sig ipsec_dns_signed;
5018 + /* some thing for PGP */
5019 + /* some thing for PKIX */
5020 + struct ipsec_raw_key ipsec_raw_key;
5021 + } ii_credential;
5022 +};
5023 +
5024 +#define IPSEC_MAX_CREDENTIALS 32
5025 +
5026 +struct ipsec_policy_cmd_query {
5027 + struct ipsec_policy_msg_head head;
5028 +
5029 + /* Query section */
5030 + ip_address query_local; /* us */
5031 + ip_address query_remote; /* them */
5032 + u_int8_t proto; /* TCP, ICMP, etc. */
5033 + u_short src_port, dst_port;
5034 +
5035 + /* Answer section */
5036 + enum ipsec_privacy_quality strength;
5037 + enum ipsec_bandwidth_quality bandwidth;
5038 + enum ipsec_authentication_algo auth_detail;
5039 + enum ipsec_cipher_algo esp_detail;
5040 + enum ipsec_comp_algo comp_detail;
5041 +
5042 + int credential_count;
5043 +
5044 + struct ipsec_identity credentials[IPSEC_MAX_CREDENTIALS];
5045 +};
5046 +
5047 +#define IPSEC_POLICY_SOCKET "/var/run/pluto/pluto.info"
5048 +
5049 +/* prototypes */
5050 +extern err_t ipsec_policy_lookup(int fd, struct ipsec_policy_cmd_query *result);
5051 +extern err_t ipsec_policy_init(void);
5052 +extern err_t ipsec_policy_final(void);
5053 +extern err_t ipsec_policy_readmsg(int policysock,
5054 + unsigned char *buf, size_t buflen);
5055 +extern err_t ipsec_policy_sendrecv(unsigned char *buf, size_t buflen);
5056 +extern err_t ipsec_policy_cgilookup(struct ipsec_policy_cmd_query *result);
5057 +
5058 +
5059 +extern const char *ipsec_policy_version_code(void);
5060 +extern const char *ipsec_policy_version_string(void);
5061 +
5062 +#endif /* _IPSEC_POLICY_H */
5063 --- /dev/null Tue Mar 11 13:02:56 2003
5064 +++ linux/include/openswan/ipsec_proto.h Mon Feb 9 13:51:03 2004
5065 @@ -0,0 +1,195 @@
5066 +/*
5067 + * @(#) prototypes for FreeSWAN functions
5068 + *
5069 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
5070 + * and Michael Richardson <mcr@freeswan.org>
5071 + *
5072 + * This program is free software; you can redistribute it and/or modify it
5073 + * under the terms of the GNU General Public License as published by the
5074 + * Free Software Foundation; either version 2 of the License, or (at your
5075 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5076 + *
5077 + * This program is distributed in the hope that it will be useful, but
5078 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5079 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5080 + * for more details.
5081 + *
5082 + * RCSID $Id: ipsec_proto.h,v 1.14 2005/04/29 04:50:03 mcr Exp $
5083 + *
5084 + */
5085 +
5086 +#ifndef _IPSEC_PROTO_H_
5087 +
5088 +#include "ipsec_param.h"
5089 +
5090 +/*
5091 + * This file is a kernel only file that declares prototypes for
5092 + * all intra-module function calls and global data structures.
5093 + *
5094 + * Include this file last.
5095 + *
5096 + */
5097 +
5098 +/* forward references */
5099 +enum ipsec_direction;
5100 +enum ipsec_life_type;
5101 +struct ipsec_lifetime64;
5102 +struct ident;
5103 +struct sockaddr_encap;
5104 +struct ipsec_sa;
5105 +
5106 +/* ipsec_init.c */
5107 +extern struct prng ipsec_prng;
5108 +
5109 +/* ipsec_sa.c */
5110 +extern struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
5111 +extern spinlock_t tdb_lock;
5112 +extern int ipsec_sadb_init(void);
5113 +extern int ipsec_sadb_cleanup(__u8);
5114 +
5115 +extern struct ipsec_sa *ipsec_sa_alloc(int*error);
5116 +
5117 +
5118 +extern struct ipsec_sa *ipsec_sa_getbyid(ip_said *);
5119 +extern /* void */ int ipsec_sa_add(struct ipsec_sa *);
5120 +
5121 +extern int ipsec_sa_init(struct ipsec_sa *ipsp);
5122 +
5123 +/* debug declarations */
5124 +
5125 +/* ipsec_proc.c */
5126 +extern int ipsec_proc_init(void);
5127 +extern void ipsec_proc_cleanup(void);
5128 +
5129 +/* ipsec_rcv.c */
5130 +extern int ipsec_rcv(struct sk_buff *skb);
5131 +extern int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type);
5132 +
5133 +/* ipsec_xmit.c */
5134 +struct ipsec_xmit_state;
5135 +extern enum ipsec_xmit_value ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
5136 +extern enum ipsec_xmit_value ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
5137 +extern void ipsec_print_ip(struct iphdr *ip);
5138 +
5139 +
5140 +
5141 +/* ipsec_radij.c */
5142 +extern int ipsec_makeroute(struct sockaddr_encap *ea,
5143 + struct sockaddr_encap *em,
5144 + ip_said said,
5145 + uint32_t pid,
5146 + struct sk_buff *skb,
5147 + struct ident *ident_s,
5148 + struct ident *ident_d);
5149 +
5150 +extern int ipsec_breakroute(struct sockaddr_encap *ea,
5151 + struct sockaddr_encap *em,
5152 + struct sk_buff **first,
5153 + struct sk_buff **last);
5154 +
5155 +int ipsec_radijinit(void);
5156 +int ipsec_cleareroutes(void);
5157 +int ipsec_radijcleanup(void);
5158 +
5159 +/* ipsec_life.c */
5160 +extern enum ipsec_life_alive ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
5161 + const char *lifename,
5162 + const char *saname,
5163 + enum ipsec_life_type ilt,
5164 + enum ipsec_direction idir,
5165 + struct ipsec_sa *ips);
5166 +
5167 +
5168 +extern int ipsec_lifetime_format(char *buffer,
5169 + int buflen,
5170 + char *lifename,
5171 + enum ipsec_life_type timebaselife,
5172 + struct ipsec_lifetime64 *lifetime);
5173 +
5174 +extern void ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
5175 + __u64 newvalue);
5176 +
5177 +extern void ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
5178 + __u64 newvalue);
5179 +
5180 +/* ipsec_snprintf.c */
5181 +extern int ipsec_snprintf(char * buf, ssize_t size, const char *fmt, ...);
5182 +extern void ipsec_dmp_block(char *s, caddr_t bb, int len);
5183 +
5184 +
5185 +/* ipsec_alg.c */
5186 +extern int ipsec_alg_init(void);
5187 +
5188 +
5189 +#ifdef CONFIG_KLIPS_DEBUG
5190 +
5191 +extern int debug_xform;
5192 +extern int debug_eroute;
5193 +extern int debug_spi;
5194 +extern int debug_netlink;
5195 +
5196 +#endif /* CONFIG_KLIPS_DEBUG */
5197 +
5198 +
5199 +
5200 +
5201 +#define _IPSEC_PROTO_H
5202 +#endif /* _IPSEC_PROTO_H_ */
5203 +
5204 +/*
5205 + * $Log: ipsec_proto.h,v $
5206 + * Revision 1.14 2005/04/29 04:50:03 mcr
5207 + * prototypes for xmit and alg code.
5208 + *
5209 + * Revision 1.13 2005/04/17 03:46:07 mcr
5210 + * added prototypes for ipsec_rcv() routines.
5211 + *
5212 + * Revision 1.12 2005/04/14 20:28:37 mcr
5213 + * added additional prototypes.
5214 + *
5215 + * Revision 1.11 2005/04/14 01:16:28 mcr
5216 + * add prototypes for snprintf.
5217 + *
5218 + * Revision 1.10 2005/04/13 22:47:28 mcr
5219 + * make sure that forward references are available.
5220 + *
5221 + * Revision 1.9 2004/07/10 19:08:41 mcr
5222 + * CONFIG_IPSEC -> CONFIG_KLIPS.
5223 + *
5224 + * Revision 1.8 2004/04/05 19:55:06 mcr
5225 + * Moved from linux/include/freeswan/ipsec_proto.h,v
5226 + *
5227 + * Revision 1.7 2003/10/31 02:27:05 mcr
5228 + * pulled up port-selector patches and sa_id elimination.
5229 + *
5230 + * Revision 1.6.30.1 2003/10/29 01:10:19 mcr
5231 + * elimited "struct sa_id"
5232 + *
5233 + * Revision 1.6 2002/05/23 07:13:48 rgb
5234 + * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
5235 + *
5236 + * Revision 1.5 2002/05/14 02:36:40 rgb
5237 + * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
5238 + * with "put" usage in the kernel.
5239 + *
5240 + * Revision 1.4 2002/04/24 07:36:47 mcr
5241 + * Moved from ./klips/net/ipsec/ipsec_proto.h,v
5242 + *
5243 + * Revision 1.3 2002/04/20 00:12:25 rgb
5244 + * Added esp IV CBC attack fix, disabled.
5245 + *
5246 + * Revision 1.2 2001/11/26 09:16:15 rgb
5247 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
5248 + *
5249 + * Revision 1.1.2.1 2001/09/25 02:21:01 mcr
5250 + * ipsec_proto.h created to keep prototypes rather than deal with
5251 + * cyclic dependancies of structures and prototypes in .h files.
5252 + *
5253 + *
5254 + *
5255 + * Local variables:
5256 + * c-file-style: "linux"
5257 + * End:
5258 + *
5259 + */
5260 +
5261 --- /dev/null Tue Mar 11 13:02:56 2003
5262 +++ linux/include/openswan/ipsec_radij.h Mon Feb 9 13:51:03 2004
5263 @@ -0,0 +1,179 @@
5264 +/*
5265 + * @(#) Definitions relevant to the IPSEC <> radij tree interfacing
5266 + * Copyright (C) 1996, 1997 John Ioannidis.
5267 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
5268 + *
5269 + * This program is free software; you can redistribute it and/or modify it
5270 + * under the terms of the GNU General Public License as published by the
5271 + * Free Software Foundation; either version 2 of the License, or (at your
5272 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5273 + *
5274 + * This program is distributed in the hope that it will be useful, but
5275 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5276 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5277 + * for more details.
5278 + *
5279 + * RCSID $Id: ipsec_radij.h,v 1.22 2004/07/10 19:08:41 mcr Exp $
5280 + */
5281 +
5282 +#ifndef _IPSEC_RADIJ_H
5283 +
5284 +#include <openswan.h>
5285 +
5286 +int ipsec_walk(char *);
5287 +
5288 +int ipsec_rj_walker_procprint(struct radij_node *, void *);
5289 +int ipsec_rj_walker_delete(struct radij_node *, void *);
5290 +
5291 +/* This structure is used to pass information between
5292 + * ipsec_eroute_get_info and ipsec_rj_walker_procprint
5293 + * (through rj_walktree) and between calls of ipsec_rj_walker_procprint.
5294 + */
5295 +struct wsbuf
5296 +{
5297 + /* from caller of ipsec_eroute_get_info: */
5298 + char *const buffer; /* start of buffer provided */
5299 + const int length; /* length of buffer provided */
5300 + const off_t offset; /* file position of first character of interest */
5301 + /* accumulated by ipsec_rj_walker_procprint: */
5302 + int len; /* number of character filled into buffer */
5303 + off_t begin; /* file position contained in buffer[0] (<=offset) */
5304 +};
5305 +
5306 +extern struct radij_node_head *rnh;
5307 +extern spinlock_t eroute_lock;
5308 +
5309 +struct eroute * ipsec_findroute(struct sockaddr_encap *);
5310 +
5311 +#define O1(x) (int)(((x)>>24)&0xff)
5312 +#define O2(x) (int)(((x)>>16)&0xff)
5313 +#define O3(x) (int)(((x)>>8)&0xff)
5314 +#define O4(x) (int)(((x))&0xff)
5315 +
5316 +#ifdef CONFIG_KLIPS_DEBUG
5317 +extern int debug_radij;
5318 +void rj_dumptrees(void);
5319 +
5320 +#define DB_RJ_DUMPTREES 0x0001
5321 +#define DB_RJ_FINDROUTE 0x0002
5322 +#endif /* CONFIG_KLIPS_DEBUG */
5323 +
5324 +#define _IPSEC_RADIJ_H
5325 +#endif
5326 +
5327 +/*
5328 + * $Log: ipsec_radij.h,v $
5329 + * Revision 1.22 2004/07/10 19:08:41 mcr
5330 + * CONFIG_IPSEC -> CONFIG_KLIPS.
5331 + *
5332 + * Revision 1.21 2004/04/29 11:06:42 ken
5333 + * Last bits from 2.06 procfs updates
5334 + *
5335 + * Revision 1.20 2004/04/06 02:49:08 mcr
5336 + * pullup of algo code from alg-branch.
5337 + *
5338 + * Revision 1.19 2004/04/05 19:55:06 mcr
5339 + * Moved from linux/include/freeswan/ipsec_radij.h,v
5340 + *
5341 + * Revision 1.18 2002/04/24 07:36:47 mcr
5342 + * Moved from ./klips/net/ipsec/ipsec_radij.h,v
5343 + *
5344 + * Revision 1.17 2001/11/26 09:23:49 rgb
5345 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
5346 + *
5347 + * Revision 1.16.2.1 2001/09/25 02:21:17 mcr
5348 + * ipsec_proto.h created to keep prototypes rather than deal with
5349 + * cyclic dependancies of structures and prototypes in .h files.
5350 + *
5351 + * Revision 1.16 2001/09/15 16:24:04 rgb
5352 + * Re-inject first and last HOLD packet when an eroute REPLACE is done.
5353 + *
5354 + * Revision 1.15 2001/09/14 16:58:37 rgb
5355 + * Added support for storing the first and last packets through a HOLD.
5356 + *
5357 + * Revision 1.14 2001/09/08 21:13:32 rgb
5358 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
5359 + *
5360 + * Revision 1.13 2001/06/14 19:35:09 rgb
5361 + * Update copyright date.
5362 + *
5363 + * Revision 1.12 2001/05/27 06:12:11 rgb
5364 + * Added structures for pid, packet count and last access time to eroute.
5365 + * Added packet count to beginning of /proc/net/ipsec_eroute.
5366 + *
5367 + * Revision 1.11 2000/09/08 19:12:56 rgb
5368 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
5369 + *
5370 + * Revision 1.10 1999/11/17 15:53:39 rgb
5371 + * Changed all occurrences of #include "../../../lib/freeswan.h"
5372 + * to #include <freeswan.h> which works due to -Ilibfreeswan in the
5373 + * klips/net/ipsec/Makefile.
5374 + *
5375 + * Revision 1.9 1999/10/01 00:01:23 rgb
5376 + * Added eroute structure locking.
5377 + *
5378 + * Revision 1.8 1999/04/11 00:28:59 henry
5379 + * GPL boilerplate
5380 + *
5381 + * Revision 1.7 1999/04/06 04:54:26 rgb
5382 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
5383 + * patch shell fixes.
5384 + *
5385 + * Revision 1.6 1999/01/22 06:23:26 rgb
5386 + * Cruft clean-out.
5387 + *
5388 + * Revision 1.5 1998/10/25 02:42:08 rgb
5389 + * Change return type on ipsec_breakroute and ipsec_makeroute and add an
5390 + * argument to be able to transmit more infomation about errors.
5391 + *
5392 + * Revision 1.4 1998/10/19 14:44:29 rgb
5393 + * Added inclusion of freeswan.h.
5394 + * sa_id structure implemented and used: now includes protocol.
5395 + *
5396 + * Revision 1.3 1998/07/28 00:03:31 rgb
5397 + * Comment out temporary inet_nto4u() kluge.
5398 + *
5399 + * Revision 1.2 1998/07/14 18:22:00 rgb
5400 + * Add function to clear the eroute table.
5401 + *
5402 + * Revision 1.1 1998/06/18 21:27:49 henry
5403 + * move sources from klips/src to klips/net/ipsec, to keep stupid
5404 + * kernel-build scripts happier in the presence of symlinks
5405 + *
5406 + * Revision 1.5 1998/05/25 20:30:38 rgb
5407 + * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
5408 + *
5409 + * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
5410 + * add ipsec_rj_walker_delete.
5411 + *
5412 + * Revision 1.4 1998/05/21 13:02:56 rgb
5413 + * Imported definitions from ipsec_radij.c and radij.c to support /proc 3k
5414 + * limit fix.
5415 + *
5416 + * Revision 1.3 1998/04/21 21:29:09 rgb
5417 + * Rearrange debug switches to change on the fly debug output from user
5418 + * space. Only kernel changes checked in at this time. radij.c was also
5419 + * changed to temporarily remove buggy debugging code in rj_delete causing
5420 + * an OOPS and hence, netlink device open errors.
5421 + *
5422 + * Revision 1.2 1998/04/14 17:30:39 rgb
5423 + * Fix up compiling errors for radij tree memory reclamation.
5424 + *
5425 + * Revision 1.1 1998/04/09 03:06:10 henry
5426 + * sources moved up from linux/net/ipsec
5427 + *
5428 + * Revision 1.1.1.1 1998/04/08 05:35:04 henry
5429 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
5430 + *
5431 + * Revision 0.4 1997/01/15 01:28:15 ji
5432 + * No changes.
5433 + *
5434 + * Revision 0.3 1996/11/20 14:39:04 ji
5435 + * Minor cleanups.
5436 + * Rationalized debugging code.
5437 + *
5438 + * Revision 0.2 1996/11/02 00:18:33 ji
5439 + * First limited release.
5440 + *
5441 + *
5442 + */
5443 --- /dev/null Tue Mar 11 13:02:56 2003
5444 +++ linux/include/openswan/ipsec_rcv.h Mon Feb 9 13:51:03 2004
5445 @@ -0,0 +1,261 @@
5446 +/*
5447 + *
5448 + * Copyright (C) 1996, 1997 John Ioannidis.
5449 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
5450 + *
5451 + * This program is free software; you can redistribute it and/or modify it
5452 + * under the terms of the GNU General Public License as published by the
5453 + * Free Software Foundation; either version 2 of the License, or (at your
5454 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5455 + *
5456 + * This program is distributed in the hope that it will be useful, but
5457 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5458 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5459 + * for more details.
5460 + *
5461 + * RCSID $Id: ipsec_rcv.h,v 1.28.2.1 2006/07/10 15:52:20 paul Exp $
5462 + */
5463 +
5464 +#ifndef IPSEC_RCV_H
5465 +#define IPSEC_RCV_H
5466 +
5467 +#include "openswan/ipsec_auth.h"
5468 +
5469 +#define DB_RX_PKTRX 0x0001
5470 +#define DB_RX_PKTRX2 0x0002
5471 +#define DB_RX_DMP 0x0004
5472 +#define DB_RX_IPSA 0x0010
5473 +#define DB_RX_XF 0x0020
5474 +#define DB_RX_IPAD 0x0040
5475 +#define DB_RX_INAU 0x0080
5476 +#define DB_RX_OINFO 0x0100
5477 +#define DB_RX_OINFO2 0x0200
5478 +#define DB_RX_OH 0x0400
5479 +#define DB_RX_REPLAY 0x0800
5480 +
5481 +#ifdef __KERNEL__
5482 +/* struct options; */
5483 +
5484 +#define __NO_VERSION__
5485 +#ifndef AUTOCONF_INCLUDED
5486 +#include <linux/config.h>
5487 +#endif /* for CONFIG_IP_FORWARD */
5488 +#ifdef CONFIG_MODULES
5489 +#include <linux/module.h>
5490 +#endif
5491 +#include <linux/version.h>
5492 +#include <openswan.h>
5493 +
5494 +#ifdef CONFIG_KLIPS_OCF
5495 +#include <cryptodev.h>
5496 +#endif
5497 +
5498 +#define IPSEC_BIRTH_TEMPLATE_MAXLEN 256
5499 +
5500 +struct ipsec_birth_reply {
5501 + int packet_template_len;
5502 + unsigned char packet_template[IPSEC_BIRTH_TEMPLATE_MAXLEN];
5503 +};
5504 +
5505 +extern struct ipsec_birth_reply ipsec_ipv4_birth_packet;
5506 +extern struct ipsec_birth_reply ipsec_ipv6_birth_packet;
5507 +
5508 +enum ipsec_rcv_value {
5509 + IPSEC_RCV_PENDING=2,
5510 + IPSEC_RCV_LASTPROTO=1,
5511 + IPSEC_RCV_OK=0,
5512 + IPSEC_RCV_BADPROTO=-1,
5513 + IPSEC_RCV_BADLEN=-2,
5514 + IPSEC_RCV_ESP_BADALG=-3,
5515 + IPSEC_RCV_3DES_BADBLOCKING=-4,
5516 + IPSEC_RCV_ESP_DECAPFAIL=-5,
5517 + IPSEC_RCV_DECAPFAIL=-6,
5518 + IPSEC_RCV_SAIDNOTFOUND=-7,
5519 + IPSEC_RCV_IPCOMPALONE=-8,
5520 + IPSEC_RCV_IPCOMPFAILED=-10,
5521 + IPSEC_RCV_SAIDNOTLIVE=-11,
5522 + IPSEC_RCV_FAILEDINBOUND=-12,
5523 + IPSEC_RCV_LIFETIMEFAILED=-13,
5524 + IPSEC_RCV_BADAUTH=-14,
5525 + IPSEC_RCV_REPLAYFAILED=-15,
5526 + IPSEC_RCV_AUTHFAILED=-16,
5527 + IPSEC_RCV_REPLAYROLLED=-17,
5528 + IPSEC_RCV_BAD_DECRYPT=-18,
5529 + IPSEC_RCV_REALLYBAD=-19
5530 +};
5531 +
5532 +/*
5533 + * state machine states
5534 + */
5535 +
5536 +#define IPSEC_RSM_INIT 0 /* make it easy, starting state is 0 */
5537 +#define IPSEC_RSM_DECAP_INIT 1
5538 +#define IPSEC_RSM_DECAP_LOOKUP 2
5539 +#define IPSEC_RSM_AUTH_INIT 3
5540 +#define IPSEC_RSM_AUTH_DECAP 4
5541 +#define IPSEC_RSM_AUTH_CALC 5
5542 +#define IPSEC_RSM_AUTH_CHK 6
5543 +#define IPSEC_RSM_DECRYPT 7
5544 +#define IPSEC_RSM_DECAP_CONT 8 /* do we restart at IPSEC_RSM_DECAP_INIT */
5545 +#define IPSEC_RSM_CLEANUP 9
5546 +#define IPSEC_RSM_IPCOMP 10
5547 +#define IPSEC_RSM_COMPLETE 11
5548 +#define IPSEC_RSM_DONE 100
5549 +
5550 +struct ipsec_rcv_state {
5551 + struct sk_buff *skb;
5552 + struct net_device_stats *stats;
5553 + struct iphdr *ipp; /* the IP header */
5554 + struct ipsec_sa *ipsp; /* current SA being processed */
5555 + struct ipsec_sa *lastipsp; /* last SA that was processed */
5556 + int len; /* length of packet */
5557 + int ilen; /* length of inner payload (-authlen) */
5558 + int authlen; /* how big is the auth data at end */
5559 + int hard_header_len; /* layer 2 size */
5560 + int iphlen; /* how big is IP header */
5561 + unsigned int transport_direct:1;
5562 + struct auth_alg *authfuncs;
5563 + ip_said said;
5564 + char sa[SATOT_BUF];
5565 + size_t sa_len;
5566 + __u8 next_header;
5567 + __u8 hash[AH_AMAX];
5568 + char ipsaddr_txt[ADDRTOA_BUF];
5569 + char ipdaddr_txt[ADDRTOA_BUF];
5570 + __u8 *octx;
5571 + __u8 *ictx;
5572 + int ictx_len;
5573 + int octx_len;
5574 + union {
5575 + struct {
5576 + struct esphdr *espp;
5577 + } espstuff;
5578 + struct {
5579 + struct ahhdr *ahp;
5580 + } ahstuff;
5581 + struct {
5582 + struct ipcomphdr *compp;
5583 + } ipcompstuff;
5584 + } protostuff;
5585 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
5586 + __u8 natt_type;
5587 + __u16 natt_sport;
5588 + __u16 natt_dport;
5589 + int natt_len;
5590 +#endif
5591 +
5592 + /*
5593 + * rcv state machine use
5594 + */
5595 + int state;
5596 + int next_state;
5597 + int auth_checked;
5598 +
5599 +#ifdef CONFIG_KLIPS_OCF
5600 + struct work_struct workq;
5601 +#ifdef DECLARE_TASKLET
5602 + struct tasklet_struct tasklet;
5603 +#endif
5604 +#endif
5605 +#ifndef NET_21
5606 + struct net_device *devp;
5607 + struct inet_protocol *protop;
5608 +#endif
5609 + struct xform_functions *proto_funcs;
5610 + __u8 proto;
5611 + int replay;
5612 + unsigned char *authenticator;
5613 + int esphlen;
5614 +#ifdef CONFIG_KLIPS_ALG
5615 + struct ipsec_alg_auth *ixt_a;
5616 +#endif
5617 + __u8 ttl, tos;
5618 + __u16 frag_off, check;
5619 +};
5620 +
5621 +extern void ipsec_rsm(struct ipsec_rcv_state *irs);
5622 +#ifdef HAVE_KMEM_CACHE_T
5623 +extern kmem_cache_t *ipsec_irs_cache;
5624 +#else
5625 +extern struct kmem_cache *ipsec_irs_cache;
5626 +#endif
5627 +extern int ipsec_irs_max;
5628 +extern atomic_t ipsec_irs_cnt;
5629 +
5630 +extern int
5631 +#ifdef PROTO_HANDLER_SINGLE_PARM
5632 +ipsec_rcv(struct sk_buff *skb);
5633 +#else /* PROTO_HANDLER_SINGLE_PARM */
5634 +ipsec_rcv(struct sk_buff *skb,
5635 + unsigned short xlen);
5636 +#endif /* PROTO_HANDLER_SINGLE_PARM */
5637 +
5638 +#ifdef CONFIG_KLIPS_DEBUG
5639 +extern int debug_rcv;
5640 +#define ipsec_rcv_dmp(_x,_y, _z) if (debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
5641 +#else
5642 +#define ipsec_rcv_dmp(_x,_y, _z) do {} while(0)
5643 +#endif /* CONFIG_KLIPS_DEBUG */
5644 +
5645 +extern int sysctl_ipsec_inbound_policy_check;
5646 +#endif /* __KERNEL__ */
5647 +
5648 +extern int klips26_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
5649 +extern int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type);
5650 +
5651 +// manage ipsec rcv state objects
5652 +extern int ipsec_rcv_state_cache_init (void);
5653 +extern void ipsec_rcv_state_cache_cleanup (void);
5654 +
5655 +#endif /* IPSEC_RCV_H */
5656 +
5657 +/*
5658 + * $Log: ipsec_rcv.h,v $
5659 + * Revision 1.28.2.1 2006/07/10 15:52:20 paul
5660 + * Fix for bug #642 by Bart Trojanowski
5661 + *
5662 + * Revision 1.28 2005/05/11 00:59:45 mcr
5663 + * do not call debug routines if !defined KLIPS_DEBUG.
5664 + *
5665 + * Revision 1.27 2005/04/29 04:59:46 mcr
5666 + * use ipsec_dmp_block.
5667 + *
5668 + * Revision 1.26 2005/04/13 22:48:35 mcr
5669 + * added comments, and removed some log.
5670 + * removed Linux 2.0 support.
5671 + *
5672 + * Revision 1.25 2005/04/08 18:25:37 mcr
5673 + * prototype klips26 encap receive function
5674 + *
5675 + * Revision 1.24 2004/08/20 21:45:37 mcr
5676 + * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
5677 + * be 26sec compatible. But, some defines where changed.
5678 + *
5679 + * Revision 1.23 2004/08/03 18:17:40 mcr
5680 + * in 2.6, use "net_device" instead of #define device->net_device.
5681 + * this probably breaks 2.0 compiles.
5682 + *
5683 + * Revision 1.22 2004/07/10 19:08:41 mcr
5684 + * CONFIG_IPSEC -> CONFIG_KLIPS.
5685 + *
5686 + * Revision 1.21 2004/04/06 02:49:08 mcr
5687 + * pullup of algo code from alg-branch.
5688 + *
5689 + * Revision 1.20 2004/04/05 19:55:06 mcr
5690 + * Moved from linux/include/freeswan/ipsec_rcv.h,v
5691 + *
5692 + * Revision 1.19 2003/12/15 18:13:09 mcr
5693 + * when compiling with NAT traversal, don't assume that the
5694 + * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
5695 + * is set.
5696 + *
5697 + * history elided 2005-04-12.
5698 + *
5699 + * Local Variables:
5700 + * c-basic-offset:8
5701 + * c-style:linux
5702 + * End:
5703 + *
5704 + */
5705 +
5706 +
5707 --- /dev/null Tue Mar 11 13:02:56 2003
5708 +++ linux/include/openswan/ipsec_sa.h Mon Feb 9 13:51:03 2004
5709 @@ -0,0 +1,280 @@
5710 +/*
5711 + * @(#) Definitions of IPsec Security Association (ipsec_sa)
5712 + *
5713 + * Copyright (C) 2001, 2002, 2003
5714 + * Richard Guy Briggs <rgb@freeswan.org>
5715 + * and Michael Richardson <mcr@freeswan.org>
5716 + *
5717 + * This program is free software; you can redistribute it and/or modify it
5718 + * under the terms of the GNU General Public License as published by the
5719 + * Free Software Foundation; either version 2 of the License, or (at your
5720 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5721 + *
5722 + * This program is distributed in the hope that it will be useful, but
5723 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5724 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5725 + * for more details.
5726 + *
5727 + * RCSID $Id: ipsec_sa.h,v 1.23.2.1 2007/09/05 02:31:15 paul Exp $
5728 + *
5729 + * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
5730 + *
5731 + */
5732 +
5733 +/*
5734 + * This file describes the IPsec Security Association Structure.
5735 + *
5736 + * This structure keeps track of a single transform that may be done
5737 + * to a set of packets. It can describe applying the transform or
5738 + * apply the reverse. (e.g. compression vs expansion). However, it
5739 + * only describes one at a time. To describe both, two structures would
5740 + * be used, but since the sides of the transform are performed
5741 + * on different machines typically it is usual to have only one side
5742 + * of each association.
5743 + *
5744 + */
5745 +
5746 +#ifndef _IPSEC_SA_H_
5747 +
5748 +#ifdef __KERNEL__
5749 +#include "openswan/ipsec_stats.h"
5750 +#include "openswan/ipsec_life.h"
5751 +#include "openswan/ipsec_eroute.h"
5752 +#endif /* __KERNEL__ */
5753 +#include "openswan/ipsec_param.h"
5754 +
5755 +#include "openswan/pfkeyv2.h"
5756 +
5757 +
5758 +/* SAs are held in a table.
5759 + * Entries in this table are referenced by IPsecSAref_t values.
5760 + * IPsecSAref_t values are conceptually subscripts. Because
5761 + * we want to allocate the table piece-meal, the subscripting
5762 + * is implemented with two levels, a bit like paged virtual memory.
5763 + * This representation mechanism is known as an Iliffe Vector.
5764 + *
5765 + * The Main table (AKA the refTable) consists of 2^IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
5766 + * pointers to subtables.
5767 + * Each subtable has 2^IPSEC_SA_REF_SUBTABLE_IDX_WIDTH entries, each of which
5768 + * is a pointer to an SA.
5769 + *
5770 + * An IPsecSAref_t contains either an exceptional value (signified by the
5771 + * high-order bit being on) or a reference to a table entry. A table entry
5772 + * reference has the subtable subscript in the low-order
5773 + * IPSEC_SA_REF_SUBTABLE_IDX_WIDTH bits and the Main table subscript
5774 + * in the next lowest IPSEC_SA_REF_MAINTABLE_IDX_WIDTH bits.
5775 + *
5776 + * The Maintable entry for an IPsecSAref_t x, a pointer to its subtable, is
5777 + * IPsecSAref2table(x). It is of type struct IPsecSArefSubTable *.
5778 + *
5779 + * The pointer to the SA for x is IPsecSAref2SA(x). It is of type
5780 + * struct ipsec_sa*. The macro definition clearly shows the two-level
5781 + * access needed to find the SA pointer.
5782 + *
5783 + * The Maintable is allocated when IPsec is initialized.
5784 + * Each subtable is allocated when needed, but the first is allocated
5785 + * when IPsec is initialized.
5786 + *
5787 + * IPsecSAref_t is designed to be smaller than an NFmark so that
5788 + * they can be stored in NFmarks and still leave a few bits for other
5789 + * purposes. The spare bits are in the low order of the NFmark
5790 + * but in the high order of the IPsecSAref_t, so conversion is required.
5791 + * We pick the upper bits of NFmark on the theory that they are less likely to
5792 + * interfere with more pedestrian uses of nfmark.
5793 + */
5794 +
5795 +
5796 +typedef unsigned short int IPsecRefTableUnusedCount;
5797 +
5798 +#define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH)
5799 +
5800 +#ifdef __KERNEL__
5801 +#if ((IPSEC_SA_REF_TABLE_IDX_WIDTH - (1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) < 0)
5802 +#error "IPSEC_SA_REF_TABLE_IDX_WIDTH("IPSEC_SA_REF_TABLE_IDX_WIDTH") MUST be < 1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH("IPSEC_SA_REF_MAINTABLE_IDX_WIDTH")"
5803 +#endif
5804 +
5805 +#define IPSEC_SA_REF_SUBTABLE_IDX_WIDTH (IPSEC_SA_REF_TABLE_IDX_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
5806 +
5807 +#define IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
5808 +#define IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
5809 +
5810 +#ifdef CONFIG_NETFILTER
5811 +#define IPSEC_SA_REF_HOST_FIELD(x) ((struct sk_buff*)(x))->nfmark
5812 +#define IPSEC_SA_REF_HOST_FIELD_TYPE typeof(IPSEC_SA_REF_HOST_FIELD(NULL))
5813 +#else /* CONFIG_NETFILTER */
5814 +/* just make it work for now, it doesn't matter, since there is no nfmark */
5815 +#define IPSEC_SA_REF_HOST_FIELD_TYPE unsigned long
5816 +#endif /* CONFIG_NETFILTER */
5817 +#define IPSEC_SA_REF_HOST_FIELD_WIDTH (8 * sizeof(IPSEC_SA_REF_HOST_FIELD_TYPE))
5818 +#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
5819 +
5820 +#define IPSEC_SA_REF_MAX (~IPSEC_SAREF_NULL)
5821 +#define IPSEC_SAREF_FIRST 1
5822 +#define IPSEC_SA_REF_MASK (IPSEC_SA_REF_MAX >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
5823 +#define IPSEC_SA_REF_TABLE_MASK ((IPSEC_SA_REF_MAX >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
5824 +#define IPSEC_SA_REF_ENTRY_MASK (IPSEC_SA_REF_MAX >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_SUBTABLE_IDX_WIDTH))
5825 +
5826 +#define IPsecSAref2table(x) (((x) & IPSEC_SA_REF_TABLE_MASK) >> IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
5827 +#define IPsecSAref2entry(x) ((x) & IPSEC_SA_REF_ENTRY_MASK)
5828 +#define IPsecSArefBuild(x,y) (((x) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) + (y))
5829 +
5830 +#define IPsecSAref2SA(x) (ipsec_sadb.refTable[IPsecSAref2table(x)]->entry[IPsecSAref2entry(x)])
5831 +#define IPsecSA2SAref(x) ((x)->ips_ref)
5832 +
5833 +#define EMT_INBOUND 0x01 /* SA direction, 1=inbound */
5834 +
5835 +/* 'struct ipsec_sa' should be 64bit aligned when allocated. */
5836 +struct ipsec_sa
5837 +{
5838 + atomic_t ips_refcount; /* reference count for this struct */
5839 + int ips_marked_deleted; /* used with reference counting */
5840 + IPsecSAref_t ips_ref; /* reference table entry number */
5841 + IPsecSAref_t ips_refhim; /* ref of paired SA, if any */
5842 + struct ipsec_sa *ips_next; /* pointer to next xform */
5843 +
5844 + struct ipsec_sa *ips_hnext; /* next in hash chain */
5845 +
5846 + struct ifnet *ips_rcvif; /* related rcv encap interface */
5847 +
5848 + struct xform_functions *ips_xformfuncs; /* pointer to routines to process this SA */
5849 +
5850 + struct net_device *ips_out; /* what interface to emerge on */
5851 + __u8 ips_transport_direct; /* if true, punt directly to
5852 + * the protocol layer */
5853 + struct socket *ips_sock; /* cache of transport socket */
5854 +
5855 + ip_said ips_said; /* SA ID */
5856 +
5857 + __u32 ips_seq; /* seq num of msg that initiated this SA */
5858 + __u32 ips_pid; /* PID of process that initiated this SA */
5859 + __u8 ips_authalg; /* auth algorithm for this SA */
5860 + __u8 ips_encalg; /* enc algorithm for this SA */
5861 +
5862 + struct ipsec_stats ips_errs;
5863 +
5864 + __u8 ips_replaywin; /* replay window size */
5865 + enum sadb_sastate ips_state; /* state of SA */
5866 + __u32 ips_replaywin_lastseq; /* last pkt sequence num */
5867 + __u64 ips_replaywin_bitmap; /* bitmap of received pkts */
5868 + __u32 ips_replaywin_maxdiff; /* max pkt sequence difference */
5869 +
5870 + __u32 ips_flags; /* generic xform flags */
5871 +
5872 +
5873 + struct ipsec_lifetimes ips_life; /* lifetime records */
5874 +
5875 + /* selector information */
5876 + __u8 ips_transport_protocol; /* protocol for this SA, if ports are involved */
5877 + struct sockaddr*ips_addr_s; /* src sockaddr */
5878 + struct sockaddr*ips_addr_d; /* dst sockaddr */
5879 + struct sockaddr*ips_addr_p; /* proxy sockaddr */
5880 + __u16 ips_addr_s_size;
5881 + __u16 ips_addr_d_size;
5882 + __u16 ips_addr_p_size;
5883 + ip_address ips_flow_s;
5884 + ip_address ips_flow_d;
5885 + ip_address ips_mask_s;
5886 + ip_address ips_mask_d;
5887 +
5888 + __u16 ips_key_bits_a; /* size of authkey in bits */
5889 + __u16 ips_auth_bits; /* size of authenticator in bits */
5890 + __u16 ips_key_bits_e; /* size of enckey in bits */
5891 + __u16 ips_iv_bits; /* size of IV in bits */
5892 + __u8 ips_iv_size;
5893 + __u16 ips_key_a_size;
5894 + __u16 ips_key_e_size;
5895 +
5896 + caddr_t ips_key_a; /* authentication key */
5897 + caddr_t ips_key_e; /* encryption key */
5898 + caddr_t ips_iv; /* Initialisation Vector */
5899 +
5900 + struct ident ips_ident_s; /* identity src */
5901 + struct ident ips_ident_d; /* identity dst */
5902 +
5903 + /* these are included even if CONFIG_KLIPS_IPCOMP is off */
5904 + __u16 ips_comp_adapt_tries; /* ipcomp self-adaption tries */
5905 + __u16 ips_comp_adapt_skip; /* ipcomp self-adaption to-skip */
5906 + __u64 ips_comp_ratio_cbytes; /* compressed bytes */
5907 + __u64 ips_comp_ratio_dbytes; /* decompressed (or uncompressed) bytes */
5908 +
5909 + /* these are included even if CONFIG_IPSEC_NAT_TRAVERSAL is off */
5910 + __u8 ips_natt_type;
5911 + __u8 ips_natt_reserved[3];
5912 + __u16 ips_natt_sport;
5913 + __u16 ips_natt_dport;
5914 +
5915 + struct sockaddr *ips_natt_oa;
5916 + __u16 ips_natt_oa_size;
5917 + __u16 ips_natt_reserved2;
5918 +
5919 +#if 0
5920 + __u32 ips_sens_dpd;
5921 + __u8 ips_sens_sens_level;
5922 + __u8 ips_sens_sens_len;
5923 + __u64* ips_sens_sens_bitmap;
5924 + __u8 ips_sens_integ_level;
5925 + __u8 ips_sens_integ_len;
5926 + __u64* ips_sens_integ_bitmap;
5927 +#endif
5928 + struct ipsec_alg_enc *ips_alg_enc;
5929 + struct ipsec_alg_auth *ips_alg_auth;
5930 +
5931 + int ocf_in_use;
5932 + int64_t ocf_cryptoid;
5933 +};
5934 +
5935 +struct IPsecSArefSubTable
5936 +{
5937 + struct ipsec_sa* entry[IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES];
5938 +};
5939 +
5940 +struct ipsec_sadb {
5941 + struct IPsecSArefSubTable* refTable[IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES];
5942 + IPsecSAref_t refFreeList[IPSEC_SA_REF_FREELIST_NUM_ENTRIES];
5943 + int refFreeListHead;
5944 + int refFreeListTail;
5945 + IPsecSAref_t refFreeListCont;
5946 + IPsecSAref_t said_hash[SADB_HASHMOD];
5947 + spinlock_t sadb_lock;
5948 +};
5949 +
5950 +extern struct ipsec_sadb ipsec_sadb;
5951 +
5952 +extern int ipsec_SAref_recycle(void);
5953 +extern int ipsec_SArefSubTable_alloc(unsigned table);
5954 +extern int ipsec_saref_freelist_init(void);
5955 +extern int ipsec_sadb_init(void);
5956 +extern struct ipsec_sa *ipsec_sa_alloc(int*error); /* pass in error var by pointer */
5957 +extern IPsecSAref_t ipsec_SAref_alloc(int*erorr); /* pass in error var by pointer */
5958 +extern int ipsec_sa_free(struct ipsec_sa* ips);
5959 +
5960 +#define ipsec_sa_get(ips) __ipsec_sa_get(ips, __FUNCTION__, __LINE__)
5961 +extern struct ipsec_sa * __ipsec_sa_get(struct ipsec_sa *ips, const char *func, int line);
5962 +
5963 +#define ipsec_sa_put(ips) __ipsec_sa_put(ips, __FUNCTION__, __LINE__)
5964 +extern void __ipsec_sa_put(struct ipsec_sa *ips, const char *func, int line);
5965 +extern int ipsec_sa_add(struct ipsec_sa *ips);
5966 +extern void ipsec_sa_rm(struct ipsec_sa *ips);
5967 +extern int ipsec_sadb_cleanup(__u8 proto);
5968 +extern int ipsec_sadb_free(void);
5969 +extern int ipsec_sa_wipe(struct ipsec_sa *ips);
5970 +extern int ipsec_sa_intern(struct ipsec_sa *ips);
5971 +extern struct ipsec_sa *ipsec_sa_getbyref(IPsecSAref_t ref);
5972 +
5973 +extern void ipsec_sa_untern(struct ipsec_sa *ips);
5974 +#endif /* __KERNEL__ */
5975 +
5976 +enum ipsec_direction {
5977 + ipsec_incoming = 1,
5978 + ipsec_outgoing = 2
5979 +};
5980 +
5981 +#define _IPSEC_SA_H_
5982 +#endif /* _IPSEC_SA_H_ */
5983 +
5984 +/*
5985 + * Local variables:
5986 + * c-file-style: "linux"
5987 + * End:
5988 + *
5989 + */
5990 --- /dev/null Tue Mar 11 13:02:56 2003
5991 +++ linux/include/openswan/ipsec_sha1.h Mon Feb 9 13:51:03 2004
5992 @@ -0,0 +1,79 @@
5993 +/*
5994 + * RCSID $Id: ipsec_sha1.h,v 1.8 2004/04/05 19:55:07 mcr Exp $
5995 + */
5996 +
5997 +/*
5998 + * Here is the original comment from the distribution:
5999 +
6000 +SHA-1 in C
6001 +By Steve Reid <steve@edmweb.com>
6002 +100% Public Domain
6003 +
6004 + * Adapted for use by the IPSEC code by John Ioannidis
6005 + */
6006 +
6007 +
6008 +#ifndef _IPSEC_SHA1_H_
6009 +#define _IPSEC_SHA1_H_
6010 +
6011 +typedef struct
6012 +{
6013 + __u32 state[5];
6014 + __u32 count[2];
6015 + __u8 buffer[64];
6016 +} SHA1_CTX;
6017 +
6018 +void SHA1Transform(__u32 state[5], __u8 buffer[64]);
6019 +void SHA1Init(void *context);
6020 +void SHA1Update(void *context, unsigned char *data, __u32 len);
6021 +void SHA1Final(unsigned char digest[20], void *context);
6022 +
6023 +
6024 +#endif /* _IPSEC_SHA1_H_ */
6025 +
6026 +/*
6027 + * $Log: ipsec_sha1.h,v $
6028 + * Revision 1.8 2004/04/05 19:55:07 mcr
6029 + * Moved from linux/include/freeswan/ipsec_sha1.h,v
6030 + *
6031 + * Revision 1.7 2002/09/10 01:45:09 mcr
6032 + * changed type of MD5_CTX and SHA1_CTX to void * so that
6033 + * the function prototypes would match, and could be placed
6034 + * into a pointer to a function.
6035 + *
6036 + * Revision 1.6 2002/04/24 07:36:47 mcr
6037 + * Moved from ./klips/net/ipsec/ipsec_sha1.h,v
6038 + *
6039 + * Revision 1.5 1999/12/13 13:59:13 rgb
6040 + * Quick fix to argument size to Update bugs.
6041 + *
6042 + * Revision 1.4 1999/12/07 18:16:23 rgb
6043 + * Fixed comments at end of #endif lines.
6044 + *
6045 + * Revision 1.3 1999/04/06 04:54:27 rgb
6046 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
6047 + * patch shell fixes.
6048 + *
6049 + * Revision 1.2 1998/11/30 13:22:54 rgb
6050 + * Rationalised all the klips kernel file headers. They are much shorter
6051 + * now and won't conflict under RH5.2.
6052 + *
6053 + * Revision 1.1 1998/06/18 21:27:50 henry
6054 + * move sources from klips/src to klips/net/ipsec, to keep stupid
6055 + * kernel-build scripts happier in the presence of symlinks
6056 + *
6057 + * Revision 1.2 1998/04/23 20:54:05 rgb
6058 + * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
6059 + * verified.
6060 + *
6061 + * Revision 1.1 1998/04/09 03:04:21 henry
6062 + * sources moved up from linux/net/ipsec
6063 + * these two include files modified not to include others except in kernel
6064 + *
6065 + * Revision 1.1.1.1 1998/04/08 05:35:04 henry
6066 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
6067 + *
6068 + * Revision 0.4 1997/01/15 01:28:15 ji
6069 + * New transform
6070 + *
6071 + */
6072 --- /dev/null Tue Mar 11 13:02:56 2003
6073 +++ linux/include/openswan/ipsec_stats.h Mon Feb 9 13:51:03 2004
6074 @@ -0,0 +1,76 @@
6075 +/*
6076 + * @(#) definition of ipsec_stats structure
6077 + *
6078 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
6079 + * and Michael Richardson <mcr@freeswan.org>
6080 + *
6081 + * This program is free software; you can redistribute it and/or modify it
6082 + * under the terms of the GNU General Public License as published by the
6083 + * Free Software Foundation; either version 2 of the License, or (at your
6084 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6085 + *
6086 + * This program is distributed in the hope that it will be useful, but
6087 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6088 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6089 + * for more details.
6090 + *
6091 + * RCSID $Id: ipsec_stats.h,v 1.7 2005/04/14 01:17:45 mcr Exp $
6092 + *
6093 + */
6094 +
6095 +/*
6096 + * This file describes the errors/statistics that FreeSWAN collects.
6097 + */
6098 +
6099 +#ifndef _IPSEC_STATS_H_
6100 +
6101 +struct ipsec_stats {
6102 + __u32 ips_alg_errs; /* number of algorithm errors */
6103 + __u32 ips_auth_errs; /* # of authentication errors */
6104 + __u32 ips_encsize_errs; /* # of encryption size errors*/
6105 + __u32 ips_encpad_errs; /* # of encryption pad errors*/
6106 + __u32 ips_replaywin_errs; /* # of pkt sequence errors */
6107 +};
6108 +
6109 +#define _IPSEC_STATS_H_
6110 +#endif /* _IPSEC_STATS_H_ */
6111 +
6112 +/*
6113 + * $Log: ipsec_stats.h,v $
6114 + * Revision 1.7 2005/04/14 01:17:45 mcr
6115 + * add prototypes for snprintf.
6116 + *
6117 + * Revision 1.6 2004/04/05 19:55:07 mcr
6118 + * Moved from linux/include/freeswan/ipsec_stats.h,v
6119 + *
6120 + * Revision 1.5 2004/04/05 19:41:05 mcr
6121 + * merged alg-branch code.
6122 + *
6123 + * Revision 1.4 2004/03/28 20:27:19 paul
6124 + * Included tested and confirmed fixes mcr made and dhr verified for
6125 + * snprint statements. Changed one other snprintf to use ipsec_snprintf
6126 + * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
6127 + * dhr. (thanks dhr!)
6128 + *
6129 + * Revision 1.4 2004/03/24 01:58:31 mcr
6130 + * sprintf->snprintf for formatting into proc buffer.
6131 + *
6132 + * Revision 1.3.34.1 2004/04/05 04:30:46 mcr
6133 + * patches for alg-branch to compile/work with 2.x openswan
6134 + *
6135 + * Revision 1.3 2002/04/24 07:36:47 mcr
6136 + * Moved from ./klips/net/ipsec/ipsec_stats.h,v
6137 + *
6138 + * Revision 1.2 2001/11/26 09:16:16 rgb
6139 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
6140 + *
6141 + * Revision 1.1.2.1 2001/09/25 02:27:00 mcr
6142 + * statistics moved to seperate structure.
6143 + *
6144 + *
6145 + *
6146 + * Local variables:
6147 + * c-file-style: "linux"
6148 + * End:
6149 + *
6150 + */
6151 --- /dev/null Tue Mar 11 13:02:56 2003
6152 +++ linux/include/openswan/ipsec_sysctl.h Mon Feb 9 13:51:03 2004
6153 @@ -0,0 +1,20 @@
6154 +#ifndef OPENSWAN_SYSCTL_H
6155 +#define OPENSWAN_SYSCTL_H
6156 +
6157 +extern int debug_ah;
6158 +extern int debug_esp;
6159 +extern int debug_xform;
6160 +extern int debug_eroute;
6161 +extern int debug_spi;
6162 +extern int debug_netlink;
6163 +extern int debug_radij;
6164 +extern int debug_rcv;
6165 +extern int debug_tunnel;
6166 +extern int debug_xmit;
6167 +extern int debug_mast;
6168 +
6169 +extern int sysctl_ip_default_ttl;
6170 +extern int sysctl_ipsec_inbound_policy_check;
6171 +extern int sysctl_ipsec_debug_ipcomp;
6172 +extern int sysctl_ipsec_debug_verbose;
6173 +#endif
6174 --- /dev/null Tue Mar 11 13:02:56 2003
6175 +++ linux/include/openswan/ipsec_tunnel.h Mon Feb 9 13:51:03 2004
6176 @@ -0,0 +1,286 @@
6177 +/*
6178 + * IPSEC tunneling code
6179 + * Copyright (C) 1996, 1997 John Ioannidis.
6180 + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
6181 + * Copyright (C) 2006 Michael Richardson <mcr@xelerance.com>
6182 + *
6183 + * This program is free software; you can redistribute it and/or modify it
6184 + * under the terms of the GNU General Public License as published by the
6185 + * Free Software Foundation; either version 2 of the License, or (at your
6186 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6187 + *
6188 + * This program is distributed in the hope that it will be useful, but
6189 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6190 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6191 + * for more details.
6192 + *
6193 + */
6194 +
6195 +
6196 +# define DEV_QUEUE_XMIT(skb, device, pri) {\
6197 + skb->dev = device; \
6198 + neigh_compat_output(skb); \
6199 + /* skb->dst->output(skb); */ \
6200 + }
6201 +# define ICMP_SEND(skb_in, type, code, info, dev) \
6202 + icmp_send(skb_in, type, code, htonl(info))
6203 +# define IP_SEND(skb, dev) \
6204 + ip_send(skb);
6205 +
6206 +
6207 +#if defined(KLIPS)
6208 +/*
6209 + * Heavily based on drivers/net/new_tunnel.c. Lots
6210 + * of ideas also taken from the 2.1.x version of drivers/net/shaper.c
6211 + */
6212 +
6213 +struct ipsectunnelconf
6214 +{
6215 + uint32_t cf_cmd;
6216 + union
6217 + {
6218 + char cfu_name[12];
6219 + } cf_u;
6220 +#define cf_name cf_u.cfu_name
6221 +};
6222 +
6223 +#define IPSEC_SET_DEV (SIOCDEVPRIVATE)
6224 +#define IPSEC_DEL_DEV (SIOCDEVPRIVATE + 1)
6225 +#define IPSEC_CLR_DEV (SIOCDEVPRIVATE + 2)
6226 +#define IPSEC_UDP_ENCAP_CONVERT (SIOCDEVPRIVATE + 3)
6227 +#endif
6228 +
6229 +#ifdef __KERNEL__
6230 +#include <linux/version.h>
6231 +#ifndef KERNEL_VERSION
6232 +# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
6233 +#endif
6234 +struct ipsecpriv
6235 +{
6236 + struct sk_buff_head sendq;
6237 + struct net_device *dev;
6238 + struct wait_queue *wait_queue;
6239 + int vifnum;
6240 + char locked;
6241 + int (*hard_start_xmit) (struct sk_buff *skb,
6242 + struct net_device *dev);
6243 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
6244 + const struct header_ops *header_ops;
6245 +#else
6246 +
6247 + int (*hard_header) (struct sk_buff *skb,
6248 + struct net_device *dev,
6249 + unsigned short type,
6250 + void *daddr,
6251 + void *saddr,
6252 + unsigned len);
6253 +#ifdef NET_21
6254 + int (*rebuild_header)(struct sk_buff *skb);
6255 +#else /* NET_21 */
6256 + int (*rebuild_header)(void *buff, struct net_device *dev,
6257 + unsigned long raddr, struct sk_buff *skb);
6258 +#endif /* NET_21 */
6259 +#ifndef NET_21
6260 + void (*header_cache_bind)(struct hh_cache **hhp, struct net_device *dev,
6261 + unsigned short htype, __u32 daddr);
6262 +#endif /* !NET_21 */
6263 + void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr);
6264 +#endif
6265 + int (*set_mac_address)(struct net_device *dev, void *addr);
6266 + struct net_device_stats *(*get_stats)(struct net_device *dev);
6267 + struct net_device_stats mystats;
6268 + int mtu; /* What is the desired MTU? */
6269 +};
6270 +
6271 +extern char ipsec_tunnel_c_version[];
6272 +
6273 +extern struct net_device *ipsecdevices[IPSEC_NUM_IFMAX];
6274 +extern int ipsecdevices_max;
6275 +
6276 +int ipsec_tunnel_init_devices(void);
6277 +
6278 +/* void */ int ipsec_tunnel_cleanup_devices(void);
6279 +
6280 +extern /* void */ int ipsec_init(void);
6281 +
6282 +extern int ipsec_tunnel_start_xmit(struct sk_buff *skb, struct net_device *dev);
6283 +extern struct net_device *ipsec_get_device(int inst);
6284 +
6285 +#ifdef CONFIG_KLIPS_DEBUG
6286 +extern int debug_tunnel;
6287 +extern int sysctl_ipsec_debug_verbose;
6288 +#endif /* CONFIG_KLIPS_DEBUG */
6289 +#endif /* __KERNEL__ */
6290 +
6291 +#ifdef CONFIG_KLIPS_DEBUG
6292 +#define DB_TN_INIT 0x0001
6293 +#define DB_TN_PROCFS 0x0002
6294 +#define DB_TN_XMIT 0x0010
6295 +#define DB_TN_OHDR 0x0020
6296 +#define DB_TN_CROUT 0x0040
6297 +#define DB_TN_OXFS 0x0080
6298 +#define DB_TN_REVEC 0x0100
6299 +#define DB_TN_ENCAP 0x0200
6300 +#endif /* CONFIG_KLIPS_DEBUG */
6301 +
6302 +extern int ipsec_tunnel_deletenum(int vifnum);
6303 +extern int ipsec_tunnel_createnum(int vifnum);
6304 +extern struct net_device *ipsec_tunnel_get_device(int vifnum);
6305 +
6306 +
6307 +/* manage ipsec xmit state objects */
6308 +extern int ipsec_xmit_state_cache_init (void);
6309 +extern void ipsec_xmit_state_cache_cleanup (void);
6310 +struct ipsec_xmit_state *ipsec_xmit_state_new (void);
6311 +void ipsec_xmit_state_delete (struct ipsec_xmit_state *ixs);
6312 +
6313 +/*
6314 + * $Log: ipsec_tunnel.h,v $
6315 + * Revision 1.33 2005/06/04 16:06:05 mcr
6316 + * better patch for nat-t rcv-device code.
6317 + *
6318 + * Revision 1.32 2005/05/21 03:18:35 mcr
6319 + * added additional debug flag tunnelling.
6320 + *
6321 + * Revision 1.31 2004/08/03 18:18:02 mcr
6322 + * in 2.6, use "net_device" instead of #define device->net_device.
6323 + * this probably breaks 2.0 compiles.
6324 + *
6325 + * Revision 1.30 2004/07/10 19:08:41 mcr
6326 + * CONFIG_IPSEC -> CONFIG_KLIPS.
6327 + *
6328 + * Revision 1.29 2004/04/05 19:55:07 mcr
6329 + * Moved from linux/include/freeswan/ipsec_tunnel.h,v
6330 + *
6331 + * Revision 1.28 2003/06/24 20:22:32 mcr
6332 + * added new global: ipsecdevices[] so that we can keep track of
6333 + * the ipsecX devices. They will be referenced with dev_hold(),
6334 + * so 2.2 may need this as well.
6335 + *
6336 + * Revision 1.27 2003/04/03 17:38:09 rgb
6337 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
6338 + *
6339 + * Revision 1.26 2003/02/12 19:32:20 rgb
6340 + * Updated copyright year.
6341 + *
6342 + * Revision 1.25 2002/05/27 18:56:07 rgb
6343 + * Convert to dynamic ipsec device allocation.
6344 + *
6345 + * Revision 1.24 2002/04/24 07:36:48 mcr
6346 + * Moved from ./klips/net/ipsec/ipsec_tunnel.h,v
6347 + *
6348 + * Revision 1.23 2001/11/06 19:50:44 rgb
6349 + * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
6350 + * use also by pfkey_v2_parser.c
6351 + *
6352 + * Revision 1.22 2001/09/15 16:24:05 rgb
6353 + * Re-inject first and last HOLD packet when an eroute REPLACE is done.
6354 + *
6355 + * Revision 1.21 2001/06/14 19:35:10 rgb
6356 + * Update copyright date.
6357 + *
6358 + * Revision 1.20 2000/09/15 11:37:02 rgb
6359 + * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
6360 + * IPCOMP zlib deflate code.
6361 + *
6362 + * Revision 1.19 2000/09/08 19:12:56 rgb
6363 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
6364 + *
6365 + * Revision 1.18 2000/07/28 13:50:54 rgb
6366 + * Changed enet_statistics to net_device_stats and added back compatibility
6367 + * for pre-2.1.19.
6368 + *
6369 + * Revision 1.17 1999/11/19 01:12:15 rgb
6370 + * Purge unneeded proc_info prototypes, now that static linking uses
6371 + * dynamic proc_info registration.
6372 + *
6373 + * Revision 1.16 1999/11/18 18:51:00 rgb
6374 + * Changed all device registrations for static linking to
6375 + * dynamic to reduce the number and size of patches.
6376 + *
6377 + * Revision 1.15 1999/11/18 04:14:21 rgb
6378 + * Replaced all kernel version macros to shorter, readable form.
6379 + * Added CONFIG_PROC_FS compiler directives in case it is shut off.
6380 + * Added Marc Boucher's 2.3.25 proc patches.
6381 + *
6382 + * Revision 1.14 1999/05/25 02:50:10 rgb
6383 + * Fix kernel version macros for 2.0.x static linking.
6384 + *
6385 + * Revision 1.13 1999/05/25 02:41:06 rgb
6386 + * Add ipsec_klipsdebug support for static linking.
6387 + *
6388 + * Revision 1.12 1999/05/05 22:02:32 rgb
6389 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
6390 + *
6391 + * Revision 1.11 1999/04/29 15:19:50 rgb
6392 + * Add return values to init and cleanup functions.
6393 + *
6394 + * Revision 1.10 1999/04/16 16:02:39 rgb
6395 + * Bump up macro to 4 ipsec I/Fs.
6396 + *
6397 + * Revision 1.9 1999/04/15 15:37:25 rgb
6398 + * Forward check changes from POST1_00 branch.
6399 + *
6400 + * Revision 1.5.2.1 1999/04/02 04:26:14 rgb
6401 + * Backcheck from HEAD, pre1.0.
6402 + *
6403 + * Revision 1.8 1999/04/11 00:29:01 henry
6404 + * GPL boilerplate
6405 + *
6406 + * Revision 1.7 1999/04/06 04:54:28 rgb
6407 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
6408 + * patch shell fixes.
6409 + *
6410 + * Revision 1.6 1999/03/31 05:44:48 rgb
6411 + * Keep PMTU reduction private.
6412 + *
6413 + * Revision 1.5 1999/02/10 22:31:20 rgb
6414 + * Change rebuild_header member to reflect generality of link layer.
6415 + *
6416 + * Revision 1.4 1998/12/01 13:22:04 rgb
6417 + * Added support for debug printing of version info.
6418 + *
6419 + * Revision 1.3 1998/07/29 20:42:46 rgb
6420 + * Add a macro for clearing all tunnel devices.
6421 + * Rearrange structures and declarations for sharing with userspace.
6422 + *
6423 + * Revision 1.2 1998/06/25 20:01:45 rgb
6424 + * Make prototypes available for ipsec_init and ipsec proc_dir_entries
6425 + * for static linking.
6426 + *
6427 + * Revision 1.1 1998/06/18 21:27:50 henry
6428 + * move sources from klips/src to klips/net/ipsec, to keep stupid
6429 + * kernel-build scripts happier in the presence of symlinks
6430 + *
6431 + * Revision 1.3 1998/05/18 21:51:50 rgb
6432 + * Added macros for num of I/F's and a procfs debug switch.
6433 + *
6434 + * Revision 1.2 1998/04/21 21:29:09 rgb
6435 + * Rearrange debug switches to change on the fly debug output from user
6436 + * space. Only kernel changes checked in at this time. radij.c was also
6437 + * changed to temporarily remove buggy debugging code in rj_delete causing
6438 + * an OOPS and hence, netlink device open errors.
6439 + *
6440 + * Revision 1.1 1998/04/09 03:06:13 henry
6441 + * sources moved up from linux/net/ipsec
6442 + *
6443 + * Revision 1.1.1.1 1998/04/08 05:35:05 henry
6444 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
6445 + *
6446 + * Revision 0.5 1997/06/03 04:24:48 ji
6447 + * Added transport mode.
6448 + * Changed the way routing is done.
6449 + * Lots of bug fixes.
6450 + *
6451 + * Revision 0.4 1997/01/15 01:28:15 ji
6452 + * No changes.
6453 + *
6454 + * Revision 0.3 1996/11/20 14:39:04 ji
6455 + * Minor cleanups.
6456 + * Rationalized debugging code.
6457 + *
6458 + * Revision 0.2 1996/11/02 00:18:33 ji
6459 + * First limited release.
6460 + *
6461 + *
6462 + */
6463 --- /dev/null Tue Mar 11 13:02:56 2003
6464 +++ linux/include/openswan/ipsec_xform.h Mon Feb 9 13:51:03 2004
6465 @@ -0,0 +1,278 @@
6466 +/*
6467 + * Definitions relevant to IPSEC transformations
6468 + * Copyright (C) 1996, 1997 John Ioannidis.
6469 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
6470 + * COpyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
6471 + *
6472 + * This program is free software; you can redistribute it and/or modify it
6473 + * under the terms of the GNU General Public License as published by the
6474 + * Free Software Foundation; either version 2 of the License, or (at your
6475 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6476 + *
6477 + * This program is distributed in the hope that it will be useful, but
6478 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6479 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6480 + * for more details.
6481 + *
6482 + * RCSID $Id: ipsec_xform.h,v 1.42 2005/08/05 08:50:45 mcr Exp $
6483 + */
6484 +
6485 +#ifndef _IPSEC_XFORM_H_
6486 +
6487 +#include <openswan.h>
6488 +
6489 +#define XF_NONE 0 /* No transform set */
6490 +#define XF_IP4 1 /* IPv4 inside IPv4 */
6491 +#define XF_AHMD5 2 /* AH MD5 */
6492 +#define XF_AHSHA 3 /* AH SHA */
6493 +#define XF_ESP3DES 5 /* ESP DES3-CBC */
6494 +#define XF_AHHMACMD5 6 /* AH-HMAC-MD5 with opt replay prot */
6495 +#define XF_AHHMACSHA1 7 /* AH-HMAC-SHA1 with opt replay prot */
6496 +#define XF_ESP3DESMD5 9 /* triple DES, HMAC-MD-5, 128-bits of authentication */
6497 +#define XF_ESP3DESMD596 10 /* triple DES, HMAC-MD-5, 96-bits of authentication */
6498 +#define XF_ESPNULLMD596 12 /* NULL, HMAC-MD-5 with 96-bits of authentication */
6499 +#define XF_ESPNULLSHA196 13 /* NULL, HMAC-SHA-1 with 96-bits of authentication */
6500 +#define XF_ESP3DESSHA196 14 /* triple DES, HMAC-SHA-1, 96-bits of authentication */
6501 +#define XF_IP6 15 /* IPv6 inside IPv6 */
6502 +#define XF_COMPDEFLATE 16 /* IPCOMP deflate */
6503 +
6504 +#define XF_CLR 126 /* Clear SA table */
6505 +#define XF_DEL 127 /* Delete SA */
6506 +
6507 +/* IPsec AH transform values
6508 + * RFC 2407
6509 + * draft-ietf-ipsec-doi-tc-mib-02.txt
6510 + */
6511 +
6512 +/* why are these hardcoded here? See ipsec_policy.h for their enums -- Paul*/
6513 +/* ---------- These really need to go from here ------------------ */
6514 +#define AH_NONE 0
6515 +#define AH_MD5 2
6516 +#define AH_SHA 3
6517 +/* draft-ietf-ipsec-ciph-aes-cbc-03.txt */
6518 +#define AH_SHA2_256 5
6519 +#define AH_SHA2_384 6
6520 +#define AH_SHA2_512 7
6521 +#define AH_RIPEMD 8
6522 +#define AH_AES 9
6523 +#define AH_NULL 251
6524 +#define AH_MAX 251
6525 +
6526 +/* IPsec ESP transform values */
6527 +
6528 +#define ESP_NONE 0
6529 +#define ESP_DES 2
6530 +#define ESP_3DES 3
6531 +#define ESP_RC5 4
6532 +#define ESP_IDEA 5
6533 +#define ESP_CAST 6
6534 +#define ESP_BLOWFISH 7
6535 +#define ESP_3IDEA 8
6536 +#define ESP_RC4 10
6537 +#define ESP_NULL 11
6538 +#define ESP_AES 12
6539 +#define ESP_AES_CTR 13
6540 +#define ESP_AES_CCM_A 14
6541 +#define ESP_AES_CCM_B 15
6542 +#define ESP_AES_CCM_C 16
6543 +#define ESP_ID17 17
6544 +#define ESP_AES_GCM_A 18
6545 +#define ESP_AES_GCM_B 19
6546 +#define ESP_AES_GCM_C 20
6547 +#define ESP_SEED_CBC 21
6548 +#define ESP_CAMELLIA 22
6549 +
6550 +/* as draft-ietf-ipsec-ciph-aes-cbc-02.txt */
6551 +#define ESP_MARS 249
6552 +#define ESP_RC6 250
6553 +#define ESP_SERPENT 252
6554 +#define ESP_TWOFISH 253
6555 +
6556 +/* IPCOMP transform values */
6557 +
6558 +#define IPCOMP_NONE 0
6559 +#define IPCOMP_OUI 1
6560 +#define IPCOMP_DEFLAT 2
6561 +#define IPCOMP_LZS 3
6562 +#define IPCOMP_V42BIS 4
6563 +
6564 +#define XFT_AUTH 0x0001
6565 +#define XFT_CONF 0x0100
6566 +
6567 +/* available if CONFIG_KLIPS_DEBUG is defined */
6568 +#define DB_XF_INIT 0x0001
6569 +
6570 +#define PROTO2TXT(x) \
6571 + (x) == IPPROTO_AH ? "AH" : \
6572 + (x) == IPPROTO_ESP ? "ESP" : \
6573 + (x) == IPPROTO_IPIP ? "IPIP" : \
6574 + (x) == IPPROTO_COMP ? "COMP" : \
6575 + "UNKNOWN_proto"
6576 +static inline const char *enc_name_id (unsigned id) {
6577 + static char buf[16];
6578 + snprintf(buf, sizeof(buf), "_ID%d", id);
6579 + return buf;
6580 +}
6581 +static inline const char *auth_name_id (unsigned id) {
6582 + static char buf[16];
6583 + snprintf(buf, sizeof(buf), "_ID%d", id);
6584 + return buf;
6585 +}
6586 +#define IPS_XFORM_NAME(x) \
6587 + PROTO2TXT((x)->ips_said.proto), \
6588 + (x)->ips_said.proto == IPPROTO_COMP ? \
6589 + ((x)->ips_encalg == SADB_X_CALG_DEFLATE ? \
6590 + "_DEFLATE" : "_UNKNOWN_comp") : \
6591 + (x)->ips_encalg == ESP_NONE ? "" : \
6592 + (x)->ips_encalg == ESP_3DES ? "_3DES" : \
6593 + (x)->ips_encalg == ESP_AES ? "_AES" : \
6594 + (x)->ips_encalg == ESP_SERPENT ? "_SERPENT" : \
6595 + (x)->ips_encalg == ESP_TWOFISH ? "_TWOFISH" : \
6596 + enc_name_id(x->ips_encalg)/* "_UNKNOWN_encr" */, \
6597 + (x)->ips_authalg == AH_NONE ? "" : \
6598 + (x)->ips_authalg == AH_MD5 ? "_HMAC_MD5" : \
6599 + (x)->ips_authalg == AH_SHA ? "_HMAC_SHA1" : \
6600 + (x)->ips_authalg == AH_SHA2_256 ? "_HMAC_SHA2_256" : \
6601 + (x)->ips_authalg == AH_SHA2_384 ? "_HMAC_SHA2_384" : \
6602 + (x)->ips_authalg == AH_SHA2_512 ? "_HMAC_SHA2_512" : \
6603 + auth_name_id(x->ips_authalg) /* "_UNKNOWN_auth" */ \
6604 +
6605 +#ifdef __KERNEL__
6606 +#include <linux/skbuff.h>
6607 +
6608 +struct ipsec_rcv_state;
6609 +struct ipsec_xmit_state;
6610 +
6611 +struct xform_functions {
6612 + u8 protocol;
6613 + enum ipsec_rcv_value (*rcv_checks)(struct ipsec_rcv_state *irs,
6614 + struct sk_buff *skb);
6615 + enum ipsec_rcv_value (*rcv_decrypt)(struct ipsec_rcv_state *irs);
6616 +
6617 + enum ipsec_rcv_value (*rcv_setup_auth)(struct ipsec_rcv_state *irs,
6618 + struct sk_buff *skb,
6619 + __u32 *replay,
6620 + unsigned char **authenticator);
6621 + enum ipsec_rcv_value (*rcv_calc_auth)(struct ipsec_rcv_state *irs,
6622 + struct sk_buff *skb);
6623 +
6624 + enum ipsec_xmit_value (*xmit_setup)(struct ipsec_xmit_state *ixs);
6625 + enum ipsec_xmit_value (*xmit_encrypt)(struct ipsec_xmit_state *ixs);
6626 +
6627 + enum ipsec_xmit_value (*xmit_setup_auth)(struct ipsec_xmit_state *ixs,
6628 + struct sk_buff *skb,
6629 + __u32 *replay,
6630 + unsigned char **authenticator);
6631 + enum ipsec_xmit_value (*xmit_calc_auth)(struct ipsec_xmit_state *ixs,
6632 + struct sk_buff *skb);
6633 + int xmit_headroom;
6634 + int xmit_needtailroom;
6635 +};
6636 +
6637 +#endif /* __KERNEL__ */
6638 +
6639 +#ifdef CONFIG_KLIPS_DEBUG
6640 +extern void ipsec_dmp(char *s, caddr_t bb, int len);
6641 +#else /* CONFIG_KLIPS_DEBUG */
6642 +#define ipsec_dmp(_x, _y, _z)
6643 +#endif /* CONFIG_KLIPS_DEBUG */
6644 +
6645 +
6646 +#define _IPSEC_XFORM_H_
6647 +#endif /* _IPSEC_XFORM_H_ */
6648 +
6649 +/*
6650 + * $Log: ipsec_xform.h,v $
6651 + * Revision 1.42 2005/08/05 08:50:45 mcr
6652 + * move #include of skbuff.h to a place where
6653 + * we know it will be kernel only code.
6654 + *
6655 + * Revision 1.41 2004/07/10 19:08:41 mcr
6656 + * CONFIG_IPSEC -> CONFIG_KLIPS.
6657 + *
6658 + * Revision 1.40 2004/04/06 02:49:08 mcr
6659 + * pullup of algo code from alg-branch.
6660 + *
6661 + * Revision 1.39 2004/04/05 19:55:07 mcr
6662 + * Moved from linux/include/freeswan/ipsec_xform.h,v
6663 + *
6664 + * Revision 1.38 2004/04/05 19:41:05 mcr
6665 + * merged alg-branch code.
6666 + *
6667 + * Revision 1.37 2003/12/13 19:10:16 mcr
6668 + * refactored rcv and xmit code - same as FS 2.05.
6669 + *
6670 + * Revision 1.36.34.1 2003/12/22 15:25:52 jjo
6671 + * Merged algo-0.8.1-rc11-test1 into alg-branch
6672 + *
6673 + * Revision 1.36 2002/04/24 07:36:48 mcr
6674 + * Moved from ./klips/net/ipsec/ipsec_xform.h,v
6675 + *
6676 + * Revision 1.35 2001/11/26 09:23:51 rgb
6677 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
6678 + *
6679 + * Revision 1.33.2.1 2001/09/25 02:24:58 mcr
6680 + * struct tdb -> struct ipsec_sa.
6681 + * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
6682 + * ipsec_xform.c removed. header file still contains useful things.
6683 + *
6684 + * Revision 1.34 2001/11/06 19:47:17 rgb
6685 + * Changed lifetime_packets to uint32 from uint64.
6686 + *
6687 + * Revision 1.33 2001/09/08 21:13:34 rgb
6688 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
6689 + *
6690 + * Revision 1.32 2001/07/06 07:40:01 rgb
6691 + * Reformatted for readability.
6692 + * Added inbound policy checking fields for use with IPIP SAs.
6693 + *
6694 + * Revision 1.31 2001/06/14 19:35:11 rgb
6695 + * Update copyright date.
6696 + *
6697 + * Revision 1.30 2001/05/30 08:14:03 rgb
6698 + * Removed vestiges of esp-null transforms.
6699 + *
6700 + * Revision 1.29 2001/01/30 23:42:47 rgb
6701 + * Allow pfkey msgs from pid other than user context required for ACQUIRE
6702 + * and subsequent ADD or UDATE.
6703 + *
6704 + * Revision 1.28 2000/11/06 04:30:40 rgb
6705 + * Add Svenning's adaptive content compression.
6706 + *
6707 + * Revision 1.27 2000/09/19 00:38:25 rgb
6708 + * Fixed algorithm name bugs introduced for ipcomp.
6709 + *
6710 + * Revision 1.26 2000/09/17 21:36:48 rgb
6711 + * Added proto2txt macro.
6712 + *
6713 + * Revision 1.25 2000/09/17 18:56:47 rgb
6714 + * Added IPCOMP support.
6715 + *
6716 + * Revision 1.24 2000/09/12 19:34:12 rgb
6717 + * Defined XF_IP6 from Gerhard for ipv6 tunnel support.
6718 + *
6719 + * Revision 1.23 2000/09/12 03:23:14 rgb
6720 + * Cleaned out now unused tdb_xform and tdb_xdata members of struct tdb.
6721 + *
6722 + * Revision 1.22 2000/09/08 19:12:56 rgb
6723 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
6724 + *
6725 + * Revision 1.21 2000/09/01 18:32:43 rgb
6726 + * Added (disabled) sensitivity members to tdb struct.
6727 + *
6728 + * Revision 1.20 2000/08/30 05:31:01 rgb
6729 + * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
6730 + * Kill remainder of tdb_xform, tdb_xdata, xformsw.
6731 + *
6732 + * Revision 1.19 2000/08/01 14:51:52 rgb
6733 + * Removed _all_ remaining traces of DES.
6734 + *
6735 + * Revision 1.18 2000/01/21 06:17:45 rgb
6736 + * Tidied up spacing.
6737 + *
6738 + *
6739 + * Local variables:
6740 + * c-file-style: "linux"
6741 + * End:
6742 + *
6743 + */
6744 --- /dev/null Tue Mar 11 13:02:56 2003
6745 +++ linux/include/openswan/ipsec_xmit.h Mon Feb 9 13:51:03 2004
6746 @@ -0,0 +1,267 @@
6747 +/*
6748 + * IPSEC tunneling code
6749 + * Copyright (C) 1996, 1997 John Ioannidis.
6750 + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
6751 + *
6752 + * This program is free software; you can redistribute it and/or modify it
6753 + * under the terms of the GNU General Public License as published by the
6754 + * Free Software Foundation; either version 2 of the License, or (at your
6755 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6756 + *
6757 + * This program is distributed in the hope that it will be useful, but
6758 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6759 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6760 + * for more details.
6761 + *
6762 + * RCSID $Id: ipsec_xmit.h,v 1.14 2005/05/11 01:00:26 mcr Exp $
6763 + */
6764 +
6765 +#include "openswan/ipsec_sa.h"
6766 +
6767 +#ifdef CONFIG_KLIPS_OCF
6768 +#include <cryptodev.h>
6769 +#endif
6770 +
6771 +enum ipsec_xmit_value
6772 +{
6773 + IPSEC_XMIT_STOLEN=2,
6774 + IPSEC_XMIT_PASS=1,
6775 + IPSEC_XMIT_OK=0,
6776 + IPSEC_XMIT_ERRMEMALLOC=-1,
6777 + IPSEC_XMIT_ESP_BADALG=-2,
6778 + IPSEC_XMIT_BADPROTO=-3,
6779 + IPSEC_XMIT_ESP_PUSHPULLERR=-4,
6780 + IPSEC_XMIT_BADLEN=-5,
6781 + IPSEC_XMIT_AH_BADALG=-6,
6782 + IPSEC_XMIT_SAIDNOTFOUND=-7,
6783 + IPSEC_XMIT_SAIDNOTLIVE=-8,
6784 + IPSEC_XMIT_REPLAYROLLED=-9,
6785 + IPSEC_XMIT_LIFETIMEFAILED=-10,
6786 + IPSEC_XMIT_CANNOTFRAG=-11,
6787 + IPSEC_XMIT_MSSERR=-12,
6788 + IPSEC_XMIT_ERRSKBALLOC=-13,
6789 + IPSEC_XMIT_ENCAPFAIL=-14,
6790 + IPSEC_XMIT_NODEV=-15,
6791 + IPSEC_XMIT_NOPRIVDEV=-16,
6792 + IPSEC_XMIT_NOPHYSDEV=-17,
6793 + IPSEC_XMIT_NOSKB=-18,
6794 + IPSEC_XMIT_NOIPV6=-19,
6795 + IPSEC_XMIT_NOIPOPTIONS=-20,
6796 + IPSEC_XMIT_TTLEXPIRED=-21,
6797 + IPSEC_XMIT_BADHHLEN=-22,
6798 + IPSEC_XMIT_PUSHPULLERR=-23,
6799 + IPSEC_XMIT_ROUTEERR=-24,
6800 + IPSEC_XMIT_RECURSDETECT=-25,
6801 + IPSEC_XMIT_IPSENDFAILURE=-26,
6802 + IPSEC_XMIT_ESPUDP=-27,
6803 + IPSEC_XMIT_ESPUDP_BADTYPE=-28,
6804 + IPSEC_XMIT_PENDING=-29,
6805 +};
6806 +
6807 +
6808 +/*
6809 + * state machine states
6810 + */
6811 +
6812 +#define IPSEC_XSM_INIT1 0 /* make it easy, starting state is 0 */
6813 +#define IPSEC_XSM_INIT2 1
6814 +#define IPSEC_XSM_ENCAP_INIT 2
6815 +#define IPSEC_XSM_ENCAP_SELECT 3
6816 +#define IPSEC_XSM_ESP 4
6817 +#define IPSEC_XSM_ESP_AH 5
6818 +#define IPSEC_XSM_AH 6
6819 +#define IPSEC_XSM_IPIP 7
6820 +#define IPSEC_XSM_IPCOMP 8
6821 +#define IPSEC_XSM_CONT 9
6822 +#define IPSEC_XSM_DONE 100
6823 +
6824 +
6825 +struct ipsec_xmit_state
6826 +{
6827 + struct sk_buff *skb; /* working skb pointer */
6828 + struct net_device *dev; /* working dev pointer */
6829 + struct ipsecpriv *prv; /* Our device' private space */
6830 + struct sk_buff *oskb; /* Original skb pointer */
6831 + struct net_device_stats *stats; /* This device's statistics */
6832 + struct iphdr *iph; /* Our new IP header */
6833 + __u32 newdst; /* The other SG's IP address */
6834 + __u32 orgdst; /* Original IP destination address */
6835 + __u32 orgedst; /* 1st SG's IP address */
6836 + __u32 newsrc; /* The new source SG's IP address */
6837 + __u32 orgsrc; /* Original IP source address */
6838 + __u32 innersrc; /* Innermost IP source address */
6839 + int iphlen; /* IP header length */
6840 + int pyldsz; /* upper protocol payload size */
6841 + int headroom;
6842 + int tailroom;
6843 + int authlen;
6844 + int max_headroom; /* The extra header space needed */
6845 + int max_tailroom; /* The extra stuffing needed */
6846 + int ll_headroom; /* The extra link layer hard_header space needed */
6847 + int tot_headroom; /* The total header space needed */
6848 + int tot_tailroom; /* The totalstuffing needed */
6849 + __u8 *saved_header; /* saved copy of the hard header */
6850 + unsigned short sport, dport;
6851 +
6852 + struct sockaddr_encap matcher; /* eroute search key */
6853 + struct eroute *eroute;
6854 + struct ipsec_sa *ipsp; /* ipsec_sa pointers */
6855 + //struct ipsec_sa *ipsp_outer; /* last SA applied by encap_bundle */
6856 + char sa_txt[SATOT_BUF];
6857 + size_t sa_len;
6858 + int hard_header_stripped; /* has the hard header been removed yet? */
6859 + int hard_header_len;
6860 + struct net_device *physdev;
6861 +/* struct device *virtdev; */
6862 + short physmtu;
6863 + short cur_mtu; /* copy of prv->mtu, cause prv may == NULL */
6864 + short mtudiff;
6865 +#ifdef NET_21
6866 + struct rtable *route;
6867 +#endif /* NET_21 */
6868 + ip_said outgoing_said;
6869 +#ifdef NET_21
6870 + int pass;
6871 +#endif /* NET_21 */
6872 + uint32_t eroute_pid;
6873 + struct ipsec_sa ips;
6874 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
6875 + uint8_t natt_type;
6876 + uint8_t natt_head;
6877 + uint16_t natt_sport;
6878 + uint16_t natt_dport;
6879 +#endif
6880 +
6881 + /*
6882 + * xmit state machine use
6883 + */
6884 + void (*xsm_complete)(struct ipsec_xmit_state *ixs,
6885 + enum ipsec_xmit_value stat);
6886 + int state;
6887 + int next_state;
6888 +#ifdef CONFIG_KLIPS_OCF
6889 + struct work_struct workq;
6890 +#ifdef DECLARE_TASKLET
6891 + struct tasklet_struct tasklet;
6892 +#endif
6893 +#endif
6894 +#ifdef CONFIG_KLIPS_ALG
6895 + struct ipsec_alg_auth *ixt_a;
6896 + struct ipsec_alg_enc *ixt_e;
6897 +#endif
6898 +#ifdef CONFIG_KLIPS_ESP
6899 + struct esphdr *espp;
6900 + unsigned char *idat;
6901 +#endif /* !CONFIG_KLIPS_ESP */
6902 + int blocksize;
6903 + int ilen, len;
6904 + unsigned char *dat;
6905 + __u8 frag_off, tos;
6906 + __u16 ttl, check;
6907 +};
6908 +
6909 +enum ipsec_xmit_value
6910 +ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
6911 +
6912 +enum ipsec_xmit_value
6913 +ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
6914 +
6915 +enum ipsec_xmit_value
6916 +ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs);
6917 +
6918 +extern void ipsec_xsm(struct ipsec_xmit_state *ixs);
6919 +#ifdef HAVE_KMEM_CACHE_T
6920 +extern kmem_cache_t *ipsec_ixs_cache;
6921 +#else
6922 +extern struct kmem_cache *ipsec_ixs_cache;
6923 +#endif
6924 +extern int ipsec_ixs_max;
6925 +extern atomic_t ipsec_ixs_cnt;
6926 +
6927 +extern void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er);
6928 +
6929 +extern enum ipsec_xmit_value
6930 +ipsec_xmit_send(struct ipsec_xmit_state*ixs, struct flowi *fl);
6931 +
6932 +extern enum ipsec_xmit_value
6933 +ipsec_nat_encap(struct ipsec_xmit_state*ixs);
6934 +
6935 +extern enum ipsec_xmit_value
6936 +ipsec_tunnel_send(struct ipsec_xmit_state *ixs);
6937 +
6938 +extern void ipsec_xmit_cleanup(struct ipsec_xmit_state*ixs);
6939 +
6940 +
6941 +extern int ipsec_xmit_trap_count;
6942 +extern int ipsec_xmit_trap_sendcount;
6943 +
6944 +#ifdef CONFIG_KLIPS_DEBUG
6945 +extern int debug_xmit;
6946 +extern int debug_mast;
6947 +
6948 +#define ipsec_xmit_dmp(_x,_y, _z) if (debug_xmit && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
6949 +#else
6950 +#define ipsec_xmit_dmp(_x,_y, _z) do {} while(0)
6951 +
6952 +#endif /* CONFIG_KLIPS_DEBUG */
6953 +
6954 +extern int sysctl_ipsec_debug_verbose;
6955 +extern int sysctl_ipsec_icmp;
6956 +extern int sysctl_ipsec_tos;
6957 +
6958 +
6959 +/*
6960 + * $Log: ipsec_xmit.h,v $
6961 + * Revision 1.14 2005/05/11 01:00:26 mcr
6962 + * do not call debug routines if !defined KLIPS_DEBUG.
6963 + *
6964 + * Revision 1.13 2005/04/29 05:01:38 mcr
6965 + * use ipsec_dmp_block.
6966 + * added cur_mtu to ixs instead of using ixs->dev.
6967 + *
6968 + * Revision 1.12 2004/08/20 21:45:37 mcr
6969 + * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
6970 + * be 26sec compatible. But, some defines where changed.
6971 + *
6972 + * Revision 1.11 2004/08/03 18:18:21 mcr
6973 + * in 2.6, use "net_device" instead of #define device->net_device.
6974 + * this probably breaks 2.0 compiles.
6975 + *
6976 + * Revision 1.10 2004/07/10 19:08:41 mcr
6977 + * CONFIG_IPSEC -> CONFIG_KLIPS.
6978 + *
6979 + * Revision 1.9 2004/04/06 02:49:08 mcr
6980 + * pullup of algo code from alg-branch.
6981 + *
6982 + * Revision 1.8 2004/04/05 19:55:07 mcr
6983 + * Moved from linux/include/freeswan/ipsec_xmit.h,v
6984 + *
6985 + * Revision 1.7 2004/02/03 03:11:40 mcr
6986 + * new xmit type if the UDP encapsulation is wrong.
6987 + *
6988 + * Revision 1.6 2003/12/13 19:10:16 mcr
6989 + * refactored rcv and xmit code - same as FS 2.05.
6990 + *
6991 + * Revision 1.5 2003/12/10 01:20:06 mcr
6992 + * NAT-traversal patches to KLIPS.
6993 + *
6994 + * Revision 1.4 2003/12/06 16:37:04 mcr
6995 + * 1.4.7a X.509 patch applied.
6996 + *
6997 + * Revision 1.3 2003/10/31 02:27:05 mcr
6998 + * pulled up port-selector patches and sa_id elimination.
6999 + *
7000 + * Revision 1.2.4.2 2003/10/29 01:10:19 mcr
7001 + * elimited "struct sa_id"
7002 + *
7003 + * Revision 1.2.4.1 2003/09/21 13:59:38 mcr
7004 + * pre-liminary X.509 patch - does not yet pass tests.
7005 + *
7006 + * Revision 1.2 2003/06/20 01:42:13 mcr
7007 + * added counters to measure how many ACQUIREs we send to pluto,
7008 + * and how many are successfully sent.
7009 + *
7010 + * Revision 1.1 2003/02/12 19:31:03 rgb
7011 + * Refactored from ipsec_tunnel.c
7012 + *
7013 + */
7014 --- /dev/null Tue Mar 11 13:02:56 2003
7015 +++ linux/include/openswan/mast.h Mon Feb 9 13:51:03 2004
7016 @@ -0,0 +1,33 @@
7017 +struct mast_callbacks {
7018 + int (*packet_encap)(struct device *mast, void *context,
7019 + struct sk_buff *skb, int flowref);
7020 + int (*link_inquire)(struct device *mast, void *context);
7021 +};
7022 +
7023 +
7024 +struct device *mast_init (int family,
7025 + struct mast_callbacks *callbacks,
7026 + unsigned int flags,
7027 + unsigned int desired_unit,
7028 + unsigned int max_flowref,
7029 + void *context);
7030 +
7031 +int mast_destroy(struct device *mast);
7032 +
7033 +int mast_recv(struct device *mast, struct sk_buff *skb, int flowref);
7034 +
7035 +/* free this skb as being useless, increment failure count. */
7036 +int mast_toast(struct device *mast, struct sk_buff *skb, int flowref);
7037 +
7038 +int mast_linkstat (struct device *mast, int flowref,
7039 + int status);
7040 +
7041 +int mast_setreference (struct device *mast,
7042 + int defaultSA);
7043 +
7044 +int mast_setneighbor (struct device *mast,
7045 + struct sockaddr *source,
7046 + struct sockaddr *destination,
7047 + int flowref);
7048 +
7049 +
7050 --- /dev/null Tue Mar 11 13:02:56 2003
7051 +++ linux/include/openswan/passert.h Mon Feb 9 13:51:03 2004
7052 @@ -0,0 +1,75 @@
7053 +/*
7054 + * sanitize a string into a printable format.
7055 + *
7056 + * Copyright (C) 1998-2002 D. Hugh Redelmeier.
7057 + * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
7058 + *
7059 + * This library is free software; you can redistribute it and/or modify it
7060 + * under the terms of the GNU Library General Public License as published by
7061 + * the Free Software Foundation; either version 2 of the License, or (at your
7062 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
7063 + *
7064 + * This library is distributed in the hope that it will be useful, but
7065 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
7066 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
7067 + * License for more details.
7068 + *
7069 + * RCSID $Id: passert.h,v 1.7.8.1 2007/09/05 02:32:24 paul Exp $
7070 + */
7071 +
7072 +#include "openswan.h"
7073 +
7074 +#ifndef _OPENSWAN_PASSERT_H
7075 +#define _OPENSWAN_PASSERT_H
7076 +/* our versions of assert: log result */
7077 +
7078 +#ifdef DEBUG
7079 +
7080 +typedef void (*openswan_passert_fail_t)(const char *pred_str,
7081 + const char *file_str,
7082 + unsigned long line_no) NEVER_RETURNS;
7083 +
7084 +extern openswan_passert_fail_t openswan_passert_fail;
7085 +
7086 +extern void pexpect_log(const char *pred_str
7087 + , const char *file_str, unsigned long line_no);
7088 +
7089 +# define impossible() do { \
7090 + if(openswan_passert_fail) { \
7091 + (*openswan_passert_fail)("impossible", __FILE__, __LINE__); \
7092 + }} while(0)
7093 +
7094 +extern void openswan_switch_fail(int n
7095 + , const char *file_str, unsigned long line_no) NEVER_RETURNS;
7096 +
7097 +# define bad_case(n) openswan_switch_fail((int) n, __FILE__, __LINE__)
7098 +
7099 +# define passert(pred) do { \
7100 + if (!(pred)) \
7101 + if(openswan_passert_fail) { \
7102 + (*openswan_passert_fail)(#pred, __FILE__, __LINE__); \
7103 + } \
7104 + } while(0)
7105 +
7106 +# define pexpect(pred) do { \
7107 + if (!(pred)) \
7108 + pexpect_log(#pred, __FILE__, __LINE__); \
7109 + } while(0)
7110 +
7111 +/* assert that an err_t is NULL; evaluate exactly once */
7112 +# define happy(x) { \
7113 + err_t ugh = x; \
7114 + if (ugh != NULL) \
7115 + if(openswan_passert_fail) { (*openswan_passert_fail)(ugh, __FILE__, __LINE__); } \
7116 + }
7117 +
7118 +#else /*!DEBUG*/
7119 +
7120 +# define impossible() abort()
7121 +# define bad_case(n) abort()
7122 +# define passert(pred) { } /* do nothing */
7123 +# define happy(x) { (void) x; } /* evaluate non-judgementally */
7124 +
7125 +#endif /*!DEBUG*/
7126 +
7127 +#endif /* _OPENSWAN_PASSERT_H */
7128 --- /dev/null Tue Mar 11 13:02:56 2003
7129 +++ linux/include/openswan/pfkey.h Mon Feb 9 13:51:03 2004
7130 @@ -0,0 +1,384 @@
7131 +/*
7132 + * Openswan specific PF_KEY headers
7133 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
7134 + * Copyright (C) 2006-2007 Michael Richardson <mcr@xelerance.com>
7135 + *
7136 + * This program is free software; you can redistribute it and/or modify it
7137 + * under the terms of the GNU General Public License as published by the
7138 + * Free Software Foundation; either version 2 of the License, or (at your
7139 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
7140 + *
7141 + * This program is distributed in the hope that it will be useful, but
7142 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
7143 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7144 + * for more details.
7145 + *
7146 + * RCSID $Id: pfkey.h,v 1.52 2005/11/09 00:30:37 mcr Exp $
7147 + */
7148 +
7149 +#ifndef __NET_IPSEC_PF_KEY_H
7150 +#define __NET_IPSEC_PF_KEY_H
7151 +
7152 +#include "pfkeyv2.h"
7153 +#ifdef __KERNEL__
7154 +extern struct proto_ops pfkey_proto_ops;
7155 +typedef struct sock pfkey_sock;
7156 +extern int debug_pfkey;
7157 +
7158 +extern /* void */ int pfkey_init(void);
7159 +extern /* void */ int pfkey_cleanup(void);
7160 +
7161 +struct socket_list
7162 +{
7163 + struct socket *socketp;
7164 + struct socket_list *next;
7165 +};
7166 +extern int pfkey_list_insert_socket(struct socket*, struct socket_list**);
7167 +extern int pfkey_list_remove_socket(struct socket*, struct socket_list**);
7168 +extern struct socket_list *pfkey_open_sockets;
7169 +extern struct socket_list *pfkey_registered_sockets[];
7170 +
7171 +struct ipsec_alg_supported
7172 +{
7173 + uint16_t ias_exttype;
7174 + uint8_t ias_id;
7175 + uint8_t ias_ivlen;
7176 + uint16_t ias_keyminbits;
7177 + uint16_t ias_keymaxbits;
7178 + const char *ias_name;
7179 +};
7180 +
7181 +extern struct supported_list *pfkey_supported_list[];
7182 +struct supported_list
7183 +{
7184 + struct ipsec_alg_supported *supportedp;
7185 + struct supported_list *next;
7186 +};
7187 +extern int pfkey_list_insert_supported(struct ipsec_alg_supported*, struct supported_list**);
7188 +extern int pfkey_list_remove_supported(struct ipsec_alg_supported*, struct supported_list**);
7189 +
7190 +struct sockaddr_key
7191 +{
7192 + uint16_t key_family; /* PF_KEY */
7193 + uint16_t key_pad; /* not used */
7194 + uint32_t key_pid; /* process ID */
7195 +};
7196 +
7197 +struct pfkey_extracted_data
7198 +{
7199 + struct ipsec_sa* ips;
7200 + struct ipsec_sa* ips2;
7201 + struct eroute *eroute;
7202 + int outif;
7203 + IPsecSAref_t sarefme;
7204 + IPsecSAref_t sarefhim;
7205 +};
7206 +
7207 +/* forward reference */
7208 +struct sadb_ext;
7209 +struct sadb_msg;
7210 +struct sockaddr;
7211 +struct sadb_comb;
7212 +struct sadb_sadb;
7213 +struct sadb_alg;
7214 +
7215 +extern int
7216 +pfkey_alloc_eroute(struct eroute** eroute);
7217 +
7218 +extern int
7219 +pfkey_sa_process(struct sadb_ext *pfkey_ext,
7220 + struct pfkey_extracted_data* extr);
7221 +
7222 +extern int
7223 +pfkey_lifetime_process(struct sadb_ext *pfkey_ext,
7224 + struct pfkey_extracted_data* extr);
7225 +
7226 +extern int
7227 +pfkey_address_process(struct sadb_ext *pfkey_ext,
7228 + struct pfkey_extracted_data* extr);
7229 +
7230 +extern int
7231 +pfkey_key_process(struct sadb_ext *pfkey_ext,
7232 + struct pfkey_extracted_data* extr);
7233 +
7234 +extern int
7235 +pfkey_ident_process(struct sadb_ext *pfkey_ext,
7236 + struct pfkey_extracted_data* extr);
7237 +
7238 +extern int
7239 +pfkey_sens_process(struct sadb_ext *pfkey_ext,
7240 + struct pfkey_extracted_data* extr);
7241 +
7242 +extern int
7243 +pfkey_prop_process(struct sadb_ext *pfkey_ext,
7244 + struct pfkey_extracted_data* extr);
7245 +
7246 +extern int
7247 +pfkey_supported_process(struct sadb_ext *pfkey_ext,
7248 + struct pfkey_extracted_data* extr);
7249 +
7250 +extern int
7251 +pfkey_spirange_process(struct sadb_ext *pfkey_ext,
7252 + struct pfkey_extracted_data* extr);
7253 +
7254 +extern int
7255 +pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext,
7256 + struct pfkey_extracted_data* extr);
7257 +
7258 +extern int
7259 +pfkey_x_satype_process(struct sadb_ext *pfkey_ext,
7260 + struct pfkey_extracted_data* extr);
7261 +
7262 +extern int
7263 +pfkey_x_debug_process(struct sadb_ext *pfkey_ext,
7264 + struct pfkey_extracted_data* extr);
7265 +
7266 +extern int pfkey_upmsg(struct socket *, struct sadb_msg *);
7267 +extern int pfkey_upmsgsk(struct sock *, struct sadb_msg *);
7268 +extern int pfkey_expire(struct ipsec_sa *, int);
7269 +extern int pfkey_acquire(struct ipsec_sa *);
7270 +#else /* ! __KERNEL__ */
7271 +
7272 +extern openswan_keying_debug_func_t pfkey_debug_func;
7273 +extern openswan_keying_debug_func_t pfkey_error_func;
7274 +extern void pfkey_print(struct sadb_msg *msg, FILE *out);
7275 +
7276 +
7277 +#endif /* __KERNEL__ */
7278 +
7279 +extern uint8_t satype2proto(uint8_t satype);
7280 +extern uint8_t proto2satype(uint8_t proto);
7281 +extern char* satype2name(uint8_t satype);
7282 +extern char* proto2name(uint8_t proto);
7283 +
7284 +struct key_opt
7285 +{
7286 + uint32_t key_pid; /* process ID */
7287 + struct sock *sk;
7288 +};
7289 +
7290 +#define key_pid(sk) ((struct key_opt*)&((sk)->sk_protinfo))->key_pid
7291 +
7292 +/* XXX-mcr this is not an alignment, this is because the count is in 64-bit
7293 + * words.
7294 + */
7295 +#define IPSEC_PFKEYv2_ALIGN (sizeof(uint64_t)/sizeof(uint8_t))
7296 +#define BITS_PER_OCTET 8
7297 +#define OCTETBITS 8
7298 +#define PFKEYBITS 64
7299 +#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */
7300 +#define ALIGN_N(x,y) (DIVUP(x,y) * y) /* align on y boundary */
7301 +
7302 +#define IPSEC_PFKEYv2_LEN(x) ((x) * IPSEC_PFKEYv2_ALIGN)
7303 +#define IPSEC_PFKEYv2_WORDS(x) (DIVUP(x,IPSEC_PFKEYv2_ALIGN))
7304 +
7305 +
7306 +#define PFKEYv2_MAX_MSGSIZE 4096
7307 +
7308 +/*
7309 + * PF_KEYv2 permitted and required extensions in and out bitmaps
7310 + */
7311 +struct pf_key_ext_parsers_def {
7312 + int (*parser)(struct sadb_ext*);
7313 + char *parser_name;
7314 +};
7315 +
7316 +enum pfkey_ext_required {
7317 + EXT_BITS_IN=0,
7318 + EXT_BITS_OUT=1
7319 +};
7320 +
7321 +enum pfkey_ext_perm {
7322 + EXT_BITS_PERM=0,
7323 + EXT_BITS_REQ=1
7324 +};
7325 +
7326 +
7327 +typedef uint64_t pfkey_ext_track;
7328 +static inline void pfkey_mark_extension(enum sadb_extension_t exttype,
7329 + pfkey_ext_track *exten_track)
7330 +{
7331 + *exten_track |= (1 << exttype);
7332 +}
7333 +
7334 +extern int pfkey_extensions_missing(enum pfkey_ext_required inout,
7335 + enum sadb_msg_t sadb_operation,
7336 + pfkey_ext_track extensions_seen);
7337 +extern int pfkey_required_extension(enum pfkey_ext_required inout,
7338 + enum sadb_msg_t sadb_operation,
7339 + enum sadb_extension_t exttype);
7340 +extern int pfkey_permitted_extension(enum pfkey_ext_required inout,
7341 + enum sadb_msg_t sadb_operation,
7342 + enum sadb_extension_t exttype);
7343 +
7344 +
7345 +extern void pfkey_extensions_init(struct sadb_ext *extensions[]);
7346 +extern void pfkey_extensions_free(struct sadb_ext *extensions[]);
7347 +extern void pfkey_msg_free(struct sadb_msg **pfkey_msg);
7348 +
7349 +extern int pfkey_msg_parse(struct sadb_msg *pfkey_msg,
7350 + struct pf_key_ext_parsers_def *ext_parsers[],
7351 + struct sadb_ext **extensions,
7352 + int dir);
7353 +
7354 +extern int pfkey_register_reply(int satype, struct sadb_msg *sadb_msg);
7355 +
7356 +/*
7357 + * PF_KEYv2 build function prototypes
7358 + */
7359 +
7360 +int
7361 +pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
7362 + uint8_t msg_type,
7363 + uint8_t satype,
7364 + uint8_t msg_errno,
7365 + uint32_t seq,
7366 + uint32_t pid);
7367 +
7368 +int
7369 +pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
7370 + uint16_t exttype,
7371 + uint32_t spi, /* in network order */
7372 + uint8_t replay_window,
7373 + uint8_t sa_state,
7374 + uint8_t auth,
7375 + uint8_t encrypt,
7376 + uint32_t flags,
7377 + uint32_t/*IPsecSAref_t*/ ref);
7378 +
7379 +int
7380 +pfkey_sa_build(struct sadb_ext ** pfkey_ext,
7381 + uint16_t exttype,
7382 + uint32_t spi, /* in network order */
7383 + uint8_t replay_window,
7384 + uint8_t sa_state,
7385 + uint8_t auth,
7386 + uint8_t encrypt,
7387 + uint32_t flags);
7388 +
7389 +extern int
7390 +pfkey_saref_build(struct sadb_ext **pfkey_ext,
7391 + IPsecSAref_t in, IPsecSAref_t out);
7392 +
7393 +int
7394 +pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
7395 + uint16_t exttype,
7396 + uint32_t allocations,
7397 + uint64_t bytes,
7398 + uint64_t addtime,
7399 + uint64_t usetime,
7400 + uint32_t packets);
7401 +
7402 +int
7403 +pfkey_address_build(struct sadb_ext** pfkey_ext,
7404 + uint16_t exttype,
7405 + uint8_t proto,
7406 + uint8_t prefixlen,
7407 + struct sockaddr* address);
7408 +
7409 +int
7410 +pfkey_key_build(struct sadb_ext** pfkey_ext,
7411 + uint16_t exttype,
7412 + uint16_t key_bits,
7413 + unsigned char *key);
7414 +
7415 +int
7416 +pfkey_ident_build(struct sadb_ext** pfkey_ext,
7417 + uint16_t exttype,
7418 + uint16_t ident_type,
7419 + uint64_t ident_id,
7420 + uint8_t ident_len,
7421 + char* ident_string);
7422 +
7423 +#ifdef __KERNEL__
7424 +extern int pfkey_nat_t_new_mapping(struct ipsec_sa *, struct sockaddr *, __u16);
7425 +extern int pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
7426 +extern int pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
7427 +#endif /* __KERNEL__ */
7428 +int
7429 +pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
7430 + uint8_t type);
7431 +int
7432 +pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
7433 + uint16_t exttype,
7434 + uint16_t port);
7435 +
7436 +int
7437 +pfkey_sens_build(struct sadb_ext** pfkey_ext,
7438 + uint32_t dpd,
7439 + uint8_t sens_level,
7440 + uint8_t sens_len,
7441 + uint64_t* sens_bitmap,
7442 + uint8_t integ_level,
7443 + uint8_t integ_len,
7444 + uint64_t* integ_bitmap);
7445 +
7446 +int pfkey_x_protocol_build(struct sadb_ext **, uint8_t);
7447 +
7448 +
7449 +int
7450 +pfkey_prop_build(struct sadb_ext** pfkey_ext,
7451 + uint8_t replay,
7452 + unsigned int comb_num,
7453 + struct sadb_comb* comb);
7454 +
7455 +int
7456 +pfkey_supported_build(struct sadb_ext** pfkey_ext,
7457 + uint16_t exttype,
7458 + unsigned int alg_num,
7459 + struct sadb_alg* alg);
7460 +
7461 +int
7462 +pfkey_spirange_build(struct sadb_ext** pfkey_ext,
7463 + uint16_t exttype,
7464 + uint32_t min,
7465 + uint32_t max);
7466 +
7467 +int
7468 +pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext);
7469 +
7470 +int
7471 +pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
7472 + uint8_t satype);
7473 +
7474 +int
7475 +pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
7476 + uint32_t tunnel,
7477 + uint32_t netlink,
7478 + uint32_t xform,
7479 + uint32_t eroute,
7480 + uint32_t spi,
7481 + uint32_t radij,
7482 + uint32_t esp,
7483 + uint32_t ah,
7484 + uint32_t rcv,
7485 + uint32_t pfkey,
7486 + uint32_t ipcomp,
7487 + uint32_t verbose);
7488 +
7489 +int
7490 +pfkey_msg_build(struct sadb_msg** pfkey_msg,
7491 + struct sadb_ext* extensions[],
7492 + int dir);
7493 +
7494 +/* in pfkey_v2_debug.c - routines to decode numbers -> strings */
7495 +const char *
7496 +pfkey_v2_sadb_ext_string(int extnum);
7497 +
7498 +const char *
7499 +pfkey_v2_sadb_type_string(int sadb_type);
7500 +
7501 +struct sadb_builds {
7502 + struct k_sadb_sa sa_base;
7503 +};
7504 +
7505 +int
7506 +pfkey_sa_builds(struct sadb_ext **pfkey_ext,
7507 + struct sadb_builds sab);
7508 +
7509 +extern int
7510 +pfkey_outif_build(struct sadb_ext **pfkey_ext,
7511 + uint16_t outif);
7512 +
7513 +#endif /* __NET_IPSEC_PF_KEY_H */
7514 +
7515 --- /dev/null Tue Mar 11 13:02:56 2003
7516 +++ linux/include/openswan/pfkey_debug.h Mon Feb 9 13:51:03 2004
7517 @@ -0,0 +1,54 @@
7518 +/*
7519 + * sanitize a string into a printable format.
7520 + *
7521 + * Copyright (C) 1998-2002 D. Hugh Redelmeier.
7522 + * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
7523 + *
7524 + * This library is free software; you can redistribute it and/or modify it
7525 + * under the terms of the GNU Library General Public License as published by
7526 + * the Free Software Foundation; either version 2 of the License, or (at your
7527 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
7528 + *
7529 + * This library is distributed in the hope that it will be useful, but
7530 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
7531 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
7532 + * License for more details.
7533 + *
7534 + * RCSID $Id: pfkey_debug.h,v 1.3 2004/04/05 19:55:07 mcr Exp $
7535 + */
7536 +
7537 +#ifndef _FREESWAN_PFKEY_DEBUG_H
7538 +#define _FREESWAN_PFKEY_DEBUG_H
7539 +
7540 +#ifdef __KERNEL__
7541 +
7542 +/* note, kernel version ignores pfkey levels */
7543 +# define DEBUGGING(level,args...) \
7544 + KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
7545 +
7546 +# define ERROR(args...) printk(KERN_ERR "klips:" args)
7547 +
7548 +#else
7549 +
7550 +extern unsigned int pfkey_lib_debug;
7551 +
7552 +extern int (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
7553 +extern int (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
7554 +
7555 +#define DEBUGGING(level,args...) if(pfkey_lib_debug & level) { \
7556 + if(pfkey_debug_func != NULL) { \
7557 + (*pfkey_debug_func)("pfkey_lib_debug:" args); \
7558 + } else { \
7559 + printf("pfkey_lib_debug:" args); \
7560 + } }
7561 +
7562 +#define ERROR(args...) if(pfkey_error_func != NULL) { \
7563 + (*pfkey_error_func)("pfkey_lib_debug:" args); \
7564 + }
7565 +
7566 +# define MALLOC(size) malloc(size)
7567 +# define FREE(obj) free(obj)
7568 +
7569 +#endif
7570 +
7571 +#endif
7572 --- /dev/null Tue Mar 11 13:02:56 2003
7573 +++ linux/include/openswan/pfkeyv2.h Mon Feb 9 13:51:03 2004
7574 @@ -0,0 +1,347 @@
7575 +/*
7576 + * RCSID $Id: pfkeyv2.h,v 1.31 2005/04/14 01:14:54 mcr Exp $
7577 + */
7578 +
7579 +/*
7580 +RFC 2367 PF_KEY Key Management API July 1998
7581 +
7582 +
7583 +Appendix D: Sample Header File
7584 +
7585 +This file defines structures and symbols for the PF_KEY Version 2
7586 +key management interface. It was written at the U.S. Naval Research
7587 +Laboratory. This file is in the public domain. The authors ask that
7588 +you leave this credit intact on any copies of this file.
7589 +*/
7590 +
7591 +#ifndef __PFKEY_V2_H
7592 +#define __PFKEY_V2_H 1
7593 +
7594 +#include <linux/pfkeyv2.h>
7595 +
7596 +#define PF_KEY_V2 2
7597 +#define PFKEYV2_REVISION 199806L
7598 +
7599 +enum sadb_msg_t {
7600 + K_SADB_RESERVED=SADB_RESERVED,
7601 + K_SADB_GETSPI=SADB_GETSPI,
7602 + K_SADB_UPDATE=SADB_UPDATE,
7603 + K_SADB_ADD=SADB_ADD,
7604 + K_SADB_DELETE=SADB_DELETE,
7605 + K_SADB_GET=SADB_GET,
7606 + K_SADB_ACQUIRE=SADB_ACQUIRE,
7607 + K_SADB_REGISTER=SADB_REGISTER,
7608 + K_SADB_EXPIRE=SADB_EXPIRE,
7609 + K_SADB_FLUSH=SADB_FLUSH,
7610 + K_SADB_DUMP=SADB_DUMP,
7611 + K_SADB_X_PROMISC=SADB_X_PROMISC,
7612 + K_SADB_X_PCHANGE=SADB_X_PCHANGE,
7613 + K_SADB_X_GRPSA=13,
7614 + K_SADB_X_ADDFLOW=14,
7615 + K_SADB_X_DELFLOW=15,
7616 + K_SADB_X_DEBUG=16,
7617 + K_SADB_X_NAT_T_NEW_MAPPING=17,
7618 + K_SADB_X_PLUMBIF=18,
7619 + K_SADB_X_UNPLUMBIF=19,
7620 + K_SADB_MAX=19
7621 +};
7622 +
7623 +#define SADB_X_GRPSA K_SADB_X_GRPSA
7624 +#define SADB_X_ADDFLOW K_SADB_X_ADDFLOW
7625 +#define SADB_X_DELFLOW K_SADB_X_DELFLOW
7626 +#define SADB_X_DEBUG K_SADB_X_DEBUG
7627 +#define SADB_X_PLUMBIF K_SADB_X_PLUMBIF
7628 +#define SADB_X_UNPLUMBIF K_SADB_X_UNPLUMBIF
7629 +
7630 +struct k_sadb_sa {
7631 + uint16_t sadb_sa_len;
7632 + uint16_t sadb_sa_exttype;
7633 + uint32_t sadb_sa_spi;
7634 + uint8_t sadb_sa_replay;
7635 + uint8_t sadb_sa_state;
7636 + uint8_t sadb_sa_auth;
7637 + uint8_t sadb_sa_encrypt;
7638 + uint32_t sadb_sa_flags;
7639 + uint32_t /*IPsecSAref_t*/ sadb_x_sa_ref; /* 32 bits */
7640 + uint8_t sadb_x_reserved[4];
7641 +} __attribute__((packed));
7642 +
7643 +struct sadb_sa_v1 {
7644 + uint16_t sadb_sa_len;
7645 + uint16_t sadb_sa_exttype;
7646 + uint32_t sadb_sa_spi;
7647 + uint8_t sadb_sa_replay;
7648 + uint8_t sadb_sa_state;
7649 + uint8_t sadb_sa_auth;
7650 + uint8_t sadb_sa_encrypt;
7651 + uint32_t sadb_sa_flags;
7652 +} __attribute__((packed));
7653 +
7654 +struct sadb_x_satype {
7655 + uint16_t sadb_x_satype_len;
7656 + uint16_t sadb_x_satype_exttype;
7657 + uint8_t sadb_x_satype_satype;
7658 + uint8_t sadb_x_satype_reserved[3];
7659 +} __attribute__((packed));
7660 +
7661 +struct sadb_x_debug {
7662 + uint16_t sadb_x_debug_len;
7663 + uint16_t sadb_x_debug_exttype;
7664 + uint32_t sadb_x_debug_tunnel;
7665 + uint32_t sadb_x_debug_netlink;
7666 + uint32_t sadb_x_debug_xform;
7667 + uint32_t sadb_x_debug_eroute;
7668 + uint32_t sadb_x_debug_spi;
7669 + uint32_t sadb_x_debug_radij;
7670 + uint32_t sadb_x_debug_esp;
7671 + uint32_t sadb_x_debug_ah;
7672 + uint32_t sadb_x_debug_rcv;
7673 + uint32_t sadb_x_debug_pfkey;
7674 + uint32_t sadb_x_debug_ipcomp;
7675 + uint32_t sadb_x_debug_verbose;
7676 + uint8_t sadb_x_debug_reserved[4];
7677 +} __attribute__((packed));
7678 +
7679 +/*
7680 + * a plumbif extension can appear in
7681 + * - a plumbif message to create the interface.
7682 + * - a unplumbif message to delete the interface.
7683 + * - a sadb add/replace to indicate which interface
7684 + * a decrypted packet should emerge on.
7685 + *
7686 + * the create/delete part could/should be replaced with netlink equivalents,
7687 + * or better yet, FORCES versions of same.
7688 + *
7689 + */
7690 +struct sadb_x_plumbif {
7691 + uint16_t sadb_x_outif_len;
7692 + uint16_t sadb_x_outif_exttype;
7693 + uint16_t sadb_x_outif_ifnum;
7694 +} __attribute__((packed));
7695 +
7696 +/*
7697 + * the ifnum describes a device that you wish to create refer to.
7698 + *
7699 + * devices 0-40959 are mastXXX devices.
7700 + * devices 40960-49141 are mastXXX devices with transport set.
7701 + * devices 49152-65536 are deprecated ipsecXXX devices.
7702 + */
7703 +#define IPSECDEV_OFFSET (48*1024)
7704 +#define MASTTRANSPORT_OFFSET (40*1024)
7705 +
7706 +/*
7707 + * an saref extension sets the SA's reference number, and
7708 + * may also set the paired SA's reference number.
7709 + *
7710 + */
7711 +struct sadb_x_saref {
7712 + uint16_t sadb_x_saref_len;
7713 + uint16_t sadb_x_saref_exttype;
7714 + uint32_t sadb_x_saref_me;
7715 + uint32_t sadb_x_saref_him;
7716 +} __attribute__((packed));
7717 +
7718 +/*
7719 + * A protocol structure for passing through the transport level
7720 + * protocol. It contains more fields than are actually used/needed
7721 + * but it is this way to be compatible with the structure used in
7722 + * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h)
7723 + */
7724 +struct sadb_protocol {
7725 + uint16_t sadb_protocol_len;
7726 + uint16_t sadb_protocol_exttype;
7727 + uint8_t sadb_protocol_proto;
7728 + uint8_t sadb_protocol_direction;
7729 + uint8_t sadb_protocol_flags;
7730 + uint8_t sadb_protocol_reserved2;
7731 +} __attribute__((packed));
7732 +
7733 +/*
7734 + * NOTE that there is a limit of 31 extensions due to current implementation
7735 + * in pfkeyv2_ext_bits.c
7736 + */
7737 +enum sadb_extension_t {
7738 + K_SADB_EXT_RESERVED=SADB_RESERVED,
7739 + K_SADB_EXT_SA= SADB_EXT_SA,
7740 + K_SADB_EXT_LIFETIME_CURRENT=SADB_EXT_LIFETIME_CURRENT,
7741 + K_SADB_EXT_LIFETIME_HARD= SADB_EXT_LIFETIME_HARD,
7742 + K_SADB_EXT_LIFETIME_SOFT= SADB_EXT_LIFETIME_SOFT,
7743 + K_SADB_EXT_ADDRESS_SRC= SADB_EXT_ADDRESS_SRC,
7744 + K_SADB_EXT_ADDRESS_DST= SADB_EXT_ADDRESS_DST,
7745 + K_SADB_EXT_ADDRESS_PROXY= SADB_EXT_ADDRESS_PROXY,
7746 + K_SADB_EXT_KEY_AUTH= SADB_EXT_KEY_AUTH,
7747 + K_SADB_EXT_KEY_ENCRYPT= SADB_EXT_KEY_ENCRYPT,
7748 + K_SADB_EXT_IDENTITY_SRC= SADB_EXT_IDENTITY_SRC,
7749 + K_SADB_EXT_IDENTITY_DST= SADB_EXT_IDENTITY_DST,
7750 + K_SADB_EXT_SENSITIVITY= SADB_EXT_SENSITIVITY,
7751 + K_SADB_EXT_PROPOSAL= SADB_EXT_PROPOSAL,
7752 + K_SADB_EXT_SUPPORTED_AUTH= SADB_EXT_SUPPORTED_AUTH,
7753 + K_SADB_EXT_SUPPORTED_ENCRYPT=SADB_EXT_SUPPORTED_ENCRYPT,
7754 + K_SADB_EXT_SPIRANGE= SADB_EXT_SPIRANGE,
7755 + K_SADB_X_EXT_KMPRIVATE= SADB_X_EXT_KMPRIVATE,
7756 + K_SADB_X_EXT_SATYPE2= 18,
7757 + K_SADB_X_EXT_POLICY= SADB_X_EXT_POLICY,
7758 + K_SADB_X_EXT_SA2= SADB_X_EXT_SA2,
7759 + K_SADB_X_EXT_ADDRESS_DST2= 20,
7760 + K_SADB_X_EXT_ADDRESS_SRC_FLOW=21,
7761 + K_SADB_X_EXT_ADDRESS_DST_FLOW=22,
7762 + K_SADB_X_EXT_ADDRESS_SRC_MASK=23,
7763 + K_SADB_X_EXT_ADDRESS_DST_MASK=24,
7764 + K_SADB_X_EXT_DEBUG= 25,
7765 + K_SADB_X_EXT_PROTOCOL= 26,
7766 + K_SADB_X_EXT_NAT_T_TYPE= 27,
7767 + K_SADB_X_EXT_NAT_T_SPORT= 28,
7768 + K_SADB_X_EXT_NAT_T_DPORT= 29,
7769 + K_SADB_X_EXT_NAT_T_OA= 30,
7770 + K_SADB_X_EXT_PLUMBIF= 31,
7771 + K_SADB_X_EXT_SAREF= 32,
7772 + K_SADB_EXT_MAX= 32,
7773 +};
7774 +
7775 +
7776 +#define SADB_X_EXT_SATYPE2 K_SADB_X_EXT_SATYPE2
7777 +#define SADB_X_EXT_ADDRESS_DST2 K_SADB_X_EXT_ADDRESS_DST2
7778 +#define SADB_X_EXT_ADDRESS_SRC_FLOW K_SADB_X_EXT_ADDRESS_SRC_FLOW
7779 +#define SADB_X_EXT_ADDRESS_DST_FLOW K_SADB_X_EXT_ADDRESS_DST_FLOW
7780 +#define SADB_X_EXT_ADDRESS_SRC_MASK K_SADB_X_EXT_ADDRESS_SRC_MASK
7781 +#define SADB_X_EXT_ADDRESS_DST_MASK K_SADB_X_EXT_ADDRESS_DST_MASK
7782 +#define SADB_X_EXT_DEBUG K_SADB_X_EXT_DEBUG
7783 +#define SADB_X_EXT_PROTOCOL K_SADB_X_EXT_PROTOCOL
7784 +
7785 +#undef SADB_X_EXT_NAT_T_TYPE
7786 +#undef SADB_X_EXT_NAT_T_SPORT
7787 +#undef SADB_X_EXT_NAT_T_DPORT
7788 +#undef SADB_X_EXT_NAT_T_OA
7789 +#define SADB_X_EXT_PLUMBIF K_SADB_X_EXT_PLUMBIF
7790 +
7791 +
7792 +
7793 +/* K_SADB_X_DELFLOW required over and above K_SADB_X_SAFLAGS_CLEARFLOW */
7794 +#define K_SADB_X_EXT_ADDRESS_DELFLOW \
7795 + ( (1<<K_SADB_X_EXT_ADDRESS_SRC_FLOW) \
7796 + | (1<<K_SADB_X_EXT_ADDRESS_DST_FLOW) \
7797 + | (1<<K_SADB_X_EXT_ADDRESS_SRC_MASK) \
7798 + | (1<<K_SADB_X_EXT_ADDRESS_DST_MASK))
7799 +
7800 +enum sadb_satype {
7801 + K_SADB_SATYPE_UNSPEC=SADB_SATYPE_UNSPEC,
7802 + K_SADB_SATYPE_AH=SADB_SATYPE_AH,
7803 + K_SADB_SATYPE_ESP=SADB_SATYPE_ESP,
7804 + K_SADB_SATYPE_RSVP=SADB_SATYPE_RSVP,
7805 + K_SADB_SATYPE_OSPFV2=SADB_SATYPE_OSPFV2,
7806 + K_SADB_SATYPE_RIPV2=SADB_SATYPE_RIPV2,
7807 + K_SADB_SATYPE_MIP=SADB_SATYPE_MIP,
7808 + K_SADB_X_SATYPE_IPIP=9,
7809 + K_SADB_X_SATYPE_COMP=10,
7810 + K_SADB_X_SATYPE_INT=11
7811 +};
7812 +#define K_SADB_SATYPE_MAX 11
7813 +
7814 +enum sadb_sastate {
7815 + K_SADB_SASTATE_LARVAL=0,
7816 + K_SADB_SASTATE_MATURE=1,
7817 + K_SADB_SASTATE_DYING=2,
7818 + K_SADB_SASTATE_DEAD=3
7819 +};
7820 +#undef SADB_SASTATE_LARVAL
7821 +#undef SADB_SASTATE_MATURE
7822 +#undef SADB_SASTATE_DYING
7823 +#undef SADB_SASTATE_DEAD
7824 +#define K_SADB_SASTATE_MAX 3
7825 +
7826 +#define SADB_SAFLAGS_PFS 1
7827 +#define SADB_X_SAFLAGS_REPLACEFLOW 2
7828 +#define SADB_X_SAFLAGS_CLEARFLOW 4
7829 +#define SADB_X_SAFLAGS_INFLOW 8
7830 +
7831 +/* not obvious, but these are the same values as used in isakmp,
7832 + * and in freeswan/ipsec_policy.h. If you need to add any, they
7833 + * should be added as according to
7834 + * http://www.iana.org/assignments/isakmp-registry
7835 + *
7836 + * and if not, then please try to use a private-use value, and
7837 + * consider asking IANA to assign a value.
7838 + */
7839 +#define SADB_AALG_NONE 0
7840 +#define SADB_AALG_MD5HMAC 2
7841 +#define SADB_AALG_SHA1HMAC 3
7842 +#define SADB_X_AALG_SHA2_256HMAC 5
7843 +#define SADB_X_AALG_SHA2_384HMAC 6
7844 +#define SADB_X_AALG_SHA2_512HMAC 7
7845 +#define SADB_X_AALG_RIPEMD160HMAC 8
7846 +#define SADB_X_AALG_NULL 251 /* kame */
7847 +enum sadb_aalg {
7848 + K_SADB_AALG_NONE= SADB_AALG_NONE,
7849 + K_SADB_AALG_MD5HMAC= SADB_AALG_MD5HMAC,
7850 + K_SADB_AALG_SHA1HMAC= SADB_AALG_SHA1HMAC,
7851 + K_SADB_X_AALG_SHA2_256HMAC=SADB_X_AALG_SHA2_256HMAC,
7852 + K_SADB_X_AALG_SHA2_384HMAC=SADB_X_AALG_SHA2_384HMAC,
7853 + K_SADB_X_AALG_SHA2_512HMAC=SADB_X_AALG_SHA2_512HMAC,
7854 + K_SADB_X_AALG_RIPEMD160HMAC=SADB_X_AALG_RIPEMD160HMAC,
7855 +};
7856 +#define K_SADB_AALG_MAX 251
7857 +
7858 +#define SADB_EALG_NONE 0
7859 +#define SADB_EALG_DESCBC 2
7860 +#define SADB_EALG_3DESCBC 3
7861 +#define SADB_X_EALG_CASTCBC 6
7862 +#define SADB_X_EALG_BLOWFISHCBC 7
7863 +#define SADB_EALG_NULL 11
7864 +#define SADB_X_EALG_AESCBC 12
7865 +#define SADB_X_EALG_AESCTR 13
7866 +#define SADB_X_EALG_AES_CCM_ICV8 14
7867 +#define SADB_X_EALG_AES_CCM_ICV12 15
7868 +#define SADB_X_EALG_AES_CCM_ICV16 16
7869 +#define SADB_X_EALG_AES_GCM_ICV8 18
7870 +#define SADB_X_EALG_AES_GCM_ICV12 19
7871 +#define SADB_X_EALG_AES_GCM_ICV16 20
7872 +#define SADB_X_EALG_CAMELLIACBC 22
7873 +
7874 +enum sadb_ealg {
7875 + K_SADB_EALG_NONE=SADB_EALG_NONE,
7876 + K_SADB_EALG_DESCBC=SADB_EALG_DESCBC,
7877 + K_SADB_EALG_3DESCBC=SADB_EALG_3DESCBC,
7878 + K_SADB_X_EALG_CASTCBC=SADB_X_EALG_CASTCBC,
7879 + K_SADB_X_EALG_BLOWFISHCBC=SADB_X_EALG_BLOWFISHCBC,
7880 + K_SADB_EALG_NULL=SADB_EALG_NULL,
7881 + K_SADB_X_EALG_AESCBC=SADB_X_EALG_AESCBC,
7882 + K_SADB_X_EALG_AESCTR=SADB_X_EALG_AESCTR,
7883 + K_SADB_X_EALG_AES_CCM_ICV8=SADB_X_EALG_AES_CCM_ICV8,
7884 + K_SADB_X_EALG_AES_CCM_ICV12=SADB_X_EALG_AES_CCM_ICV12,
7885 + K_SADB_X_EALG_AES_CCM_ICV16=SADB_X_EALG_AES_CCM_ICV16,
7886 + K_SADB_X_EALG_AES_GCM_ICV8=SADB_X_EALG_AES_GCM_ICV8,
7887 + K_SADB_X_EALG_AES_GCM_ICV12=SADB_X_EALG_AES_GCM_ICV12,
7888 + K_SADB_X_EALG_AES_GCM_ICV16=SADB_X_EALG_AES_GCM_ICV16,
7889 + K_SADB_X_EALG_CAMELLIACBC=SADB_X_EALG_CAMELLIACBC
7890 +};
7891 +
7892 +#undef SADB_EALG_MAX
7893 +#define K_SADB_EALG_MAX 255
7894 +
7895 +#define SADB_X_CALG_NONE 0
7896 +#define SADB_X_CALG_OUI 1
7897 +#define SADB_X_CALG_DEFLATE 2
7898 +#define SADB_X_CALG_LZS 3
7899 +#define SADB_X_CALG_LZJH 4
7900 +#define SADB_X_CALG_MAX 4
7901 +
7902 +enum sadb_talg {
7903 + K_SADB_X_TALG_NONE=0,
7904 + K_SADB_X_TALG_IPv4_in_IPv4=1,
7905 + K_SADB_X_TALG_IPv6_in_IPv4=2,
7906 + K_SADB_X_TALG_IPv4_in_IPv6=3,
7907 + K_SADB_X_TALG_IPv6_in_IPv6=4,
7908 +};
7909 +#define SADB_X_TALG_MAX 4
7910 +
7911 +
7912 +#define SADB_IDENTTYPE_RESERVED 0
7913 +#define SADB_IDENTTYPE_PREFIX 1
7914 +#define SADB_IDENTTYPE_FQDN 2
7915 +#define SADB_IDENTTYPE_USERFQDN 3
7916 +#define SADB_X_IDENTTYPE_CONNECTION 4
7917 +#define K_SADB_IDENTTYPE_MAX 4
7918 +
7919 +#define K_SADB_KEY_FLAGS_MAX 0
7920 +#endif /* __PFKEY_V2_H */
7921 +
7922 --- /dev/null Tue Mar 11 13:02:56 2003
7923 +++ linux/include/openswan/radij.h Mon Feb 9 13:51:03 2004
7924 @@ -0,0 +1,280 @@
7925 +/*
7926 + * RCSID $Id: radij.h,v 1.13 2004/04/05 19:55:08 mcr Exp $
7927 + */
7928 +
7929 +/*
7930 + * This file is defived from ${SRC}/sys/net/radix.h of BSD 4.4lite
7931 + *
7932 + * Variable and procedure names have been modified so that they don't
7933 + * conflict with the original BSD code, as a small number of modifications
7934 + * have been introduced and we may want to reuse this code in BSD.
7935 + *
7936 + * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
7937 + * chi or a German ch sound (as `doch', not as in `milch'), or even a
7938 + * spanish j as in Juan. It is not as far back in the throat like
7939 + * the corresponding Hebrew sound, nor is it a soft breath like the English h.
7940 + * It has nothing to do with the Dutch ij sound.
7941 + *
7942 + * Here is the appropriate copyright notice:
7943 + */
7944 +
7945 +/*
7946 + * Copyright (c) 1988, 1989, 1993
7947 + * The Regents of the University of California. All rights reserved.
7948 + *
7949 + * Redistribution and use in source and binary forms, with or without
7950 + * modification, are permitted provided that the following conditions
7951 + * are met:
7952 + * 1. Redistributions of source code must retain the above copyright
7953 + * notice, this list of conditions and the following disclaimer.
7954 + * 2. Redistributions in binary form must reproduce the above copyright
7955 + * notice, this list of conditions and the following disclaimer in the
7956 + * documentation and/or other materials provided with the distribution.
7957 + * 3. All advertising materials mentioning features or use of this software
7958 + * must display the following acknowledgement:
7959 + * This product includes software developed by the University of
7960 + * California, Berkeley and its contributors.
7961 + * 4. Neither the name of the University nor the names of its contributors
7962 + * may be used to endorse or promote products derived from this software
7963 + * without specific prior written permission.
7964 + *
7965 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
7966 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7967 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7968 + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
7969 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
7970 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
7971 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
7972 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
7973 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
7974 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
7975 + * SUCH DAMAGE.
7976 + *
7977 + * @(#)radix.h 8.1 (Berkeley) 6/10/93
7978 + */
7979 +
7980 +#ifndef _RADIJ_H_
7981 +#define _RADIJ_H_
7982 +
7983 +/*
7984 +#define RJ_DEBUG
7985 +*/
7986 +
7987 +#ifdef __KERNEL__
7988 +
7989 +#ifndef __P
7990 +#ifdef __STDC__
7991 +#define __P(x) x
7992 +#else
7993 +#define __P(x) ()
7994 +#endif
7995 +#endif
7996 +
7997 +/*
7998 + * Radix search tree node layout.
7999 + */
8000 +
8001 +struct radij_node
8002 +{
8003 + struct radij_mask *rj_mklist; /* list of masks contained in subtree */
8004 + struct radij_node *rj_p; /* parent */
8005 + short rj_b; /* bit offset; -1-index(netmask) */
8006 + char rj_bmask; /* node: mask for bit test*/
8007 + u_char rj_flags; /* enumerated next */
8008 +#define RJF_NORMAL 1 /* leaf contains normal route */
8009 +#define RJF_ROOT 2 /* leaf is root leaf for tree */
8010 +#define RJF_ACTIVE 4 /* This node is alive (for rtfree) */
8011 + union {
8012 + struct { /* leaf only data: */
8013 + caddr_t rj_Key; /* object of search */
8014 + caddr_t rj_Mask; /* netmask, if present */
8015 + struct radij_node *rj_Dupedkey;
8016 + } rj_leaf;
8017 + struct { /* node only data: */
8018 + int rj_Off; /* where to start compare */
8019 + struct radij_node *rj_L;/* progeny */
8020 + struct radij_node *rj_R;/* progeny */
8021 + }rj_node;
8022 + } rj_u;
8023 +#ifdef RJ_DEBUG
8024 + int rj_info;
8025 + struct radij_node *rj_twin;
8026 + struct radij_node *rj_ybro;
8027 +#endif
8028 +};
8029 +
8030 +#define rj_dupedkey rj_u.rj_leaf.rj_Dupedkey
8031 +#define rj_key rj_u.rj_leaf.rj_Key
8032 +#define rj_mask rj_u.rj_leaf.rj_Mask
8033 +#define rj_off rj_u.rj_node.rj_Off
8034 +#define rj_l rj_u.rj_node.rj_L
8035 +#define rj_r rj_u.rj_node.rj_R
8036 +
8037 +/*
8038 + * Annotations to tree concerning potential routes applying to subtrees.
8039 + */
8040 +
8041 +extern struct radij_mask {
8042 + short rm_b; /* bit offset; -1-index(netmask) */
8043 + char rm_unused; /* cf. rj_bmask */
8044 + u_char rm_flags; /* cf. rj_flags */
8045 + struct radij_mask *rm_mklist; /* more masks to try */
8046 + caddr_t rm_mask; /* the mask */
8047 + int rm_refs; /* # of references to this struct */
8048 +} *rj_mkfreelist;
8049 +
8050 +#define MKGet(m) {\
8051 + if (rj_mkfreelist) {\
8052 + m = rj_mkfreelist; \
8053 + rj_mkfreelist = (m)->rm_mklist; \
8054 + } else \
8055 + R_Malloc(m, struct radij_mask *, sizeof (*(m))); }\
8056 +
8057 +#define MKFree(m) { (m)->rm_mklist = rj_mkfreelist; rj_mkfreelist = (m);}
8058 +
8059 +struct radij_node_head {
8060 + struct radij_node *rnh_treetop;
8061 + int rnh_addrsize; /* permit, but not require fixed keys */
8062 + int rnh_pktsize; /* permit, but not require fixed keys */
8063 +#if 0
8064 + struct radij_node *(*rnh_addaddr) /* add based on sockaddr */
8065 + __P((void *v, void *mask,
8066 + struct radij_node_head *head, struct radij_node nodes[]));
8067 +#endif
8068 + int (*rnh_addaddr) /* add based on sockaddr */
8069 + __P((void *v, void *mask,
8070 + struct radij_node_head *head, struct radij_node nodes[]));
8071 + struct radij_node *(*rnh_addpkt) /* add based on packet hdr */
8072 + __P((void *v, void *mask,
8073 + struct radij_node_head *head, struct radij_node nodes[]));
8074 +#if 0
8075 + struct radij_node *(*rnh_deladdr) /* remove based on sockaddr */
8076 + __P((void *v, void *mask, struct radij_node_head *head));
8077 +#endif
8078 + int (*rnh_deladdr) /* remove based on sockaddr */
8079 + __P((void *v, void *mask, struct radij_node_head *head, struct radij_node **node));
8080 + struct radij_node *(*rnh_delpkt) /* remove based on packet hdr */
8081 + __P((void *v, void *mask, struct radij_node_head *head));
8082 + struct radij_node *(*rnh_matchaddr) /* locate based on sockaddr */
8083 + __P((void *v, struct radij_node_head *head));
8084 + struct radij_node *(*rnh_matchpkt) /* locate based on packet hdr */
8085 + __P((void *v, struct radij_node_head *head));
8086 + int (*rnh_walktree) /* traverse tree */
8087 + __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
8088 + struct radij_node rnh_nodes[3]; /* empty tree for common case */
8089 +};
8090 +
8091 +
8092 +#define Bcmp(a, b, n) memcmp(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
8093 +#define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
8094 +#define Bzero(p, n) memset((caddr_t)(p), 0, (unsigned)(n))
8095 +#define R_Malloc(p, t, n) ((p = (t) kmalloc((size_t)(n), GFP_ATOMIC)), Bzero((p),(n)))
8096 +#define Free(p) kfree((caddr_t)p);
8097 +
8098 +void rj_init __P((void));
8099 +int rj_inithead __P((void **, int));
8100 +int rj_refines __P((void *, void *));
8101 +int rj_walktree __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
8102 +struct radij_node
8103 + *rj_addmask __P((void *, int, int)) /* , rgb */ ;
8104 +int /* * */ rj_addroute __P((void *, void *, struct radij_node_head *,
8105 + struct radij_node [2])) /* , rgb */ ;
8106 +int /* * */ rj_delete __P((void *, void *, struct radij_node_head *, struct radij_node **)) /* , rgb */ ;
8107 +struct radij_node /* rgb */
8108 + *rj_insert __P((void *, struct radij_node_head *, int *,
8109 + struct radij_node [2])),
8110 + *rj_match __P((void *, struct radij_node_head *)),
8111 + *rj_newpair __P((void *, int, struct radij_node[2])),
8112 + *rj_search __P((void *, struct radij_node *)),
8113 + *rj_search_m __P((void *, struct radij_node *, void *));
8114 +
8115 +void rj_deltree(struct radij_node_head *);
8116 +void rj_delnodes(struct radij_node *);
8117 +void rj_free_mkfreelist(void);
8118 +int radijcleartree(void);
8119 +int radijcleanup(void);
8120 +
8121 +extern struct radij_node_head *mask_rjhead;
8122 +extern int maj_keylen;
8123 +#endif /* __KERNEL__ */
8124 +
8125 +#endif /* _RADIJ_H_ */
8126 +
8127 +
8128 +/*
8129 + * $Log: radij.h,v $
8130 + * Revision 1.13 2004/04/05 19:55:08 mcr
8131 + * Moved from linux/include/freeswan/radij.h,v
8132 + *
8133 + * Revision 1.12 2002/04/24 07:36:48 mcr
8134 + * Moved from ./klips/net/ipsec/radij.h,v
8135 + *
8136 + * Revision 1.11 2001/09/20 15:33:00 rgb
8137 + * Min/max cleanup.
8138 + *
8139 + * Revision 1.10 1999/11/18 04:09:20 rgb
8140 + * Replaced all kernel version macros to shorter, readable form.
8141 + *
8142 + * Revision 1.9 1999/05/05 22:02:33 rgb
8143 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
8144 + *
8145 + * Revision 1.8 1999/04/29 15:24:58 rgb
8146 + * Add check for existence of macros min/max.
8147 + *
8148 + * Revision 1.7 1999/04/11 00:29:02 henry
8149 + * GPL boilerplate
8150 + *
8151 + * Revision 1.6 1999/04/06 04:54:29 rgb
8152 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
8153 + * patch shell fixes.
8154 + *
8155 + * Revision 1.5 1999/01/22 06:30:32 rgb
8156 + * 64-bit clean-up.
8157 + *
8158 + * Revision 1.4 1998/11/30 13:22:55 rgb
8159 + * Rationalised all the klips kernel file headers. They are much shorter
8160 + * now and won't conflict under RH5.2.
8161 + *
8162 + * Revision 1.3 1998/10/25 02:43:27 rgb
8163 + * Change return type on rj_addroute and rj_delete and add and argument
8164 + * to the latter to be able to transmit more infomation about errors.
8165 + *
8166 + * Revision 1.2 1998/07/14 18:09:51 rgb
8167 + * Add a routine to clear eroute table.
8168 + * Added #ifdef __KERNEL__ directives to restrict scope of header.
8169 + *
8170 + * Revision 1.1 1998/06/18 21:30:22 henry
8171 + * move sources from klips/src to klips/net/ipsec to keep stupid kernel
8172 + * build scripts happier about symlinks
8173 + *
8174 + * Revision 1.4 1998/05/25 20:34:16 rgb
8175 + * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
8176 + *
8177 + * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
8178 + * add ipsec_rj_walker_delete.
8179 + *
8180 + * Recover memory for eroute table on unload of module.
8181 + *
8182 + * Revision 1.3 1998/04/22 16:51:37 rgb
8183 + * Tidy up radij debug code from recent rash of modifications to debug code.
8184 + *
8185 + * Revision 1.2 1998/04/14 17:30:38 rgb
8186 + * Fix up compiling errors for radij tree memory reclamation.
8187 + *
8188 + * Revision 1.1 1998/04/09 03:06:16 henry
8189 + * sources moved up from linux/net/ipsec
8190 + *
8191 + * Revision 1.1.1.1 1998/04/08 05:35:04 henry
8192 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
8193 + *
8194 + * Revision 0.4 1997/01/15 01:28:15 ji
8195 + * No changes.
8196 + *
8197 + * Revision 0.3 1996/11/20 14:44:45 ji
8198 + * Release update only.
8199 + *
8200 + * Revision 0.2 1996/11/02 00:18:33 ji
8201 + * First limited release.
8202 + *
8203 + *
8204 + */
8205 --- /dev/null Tue Mar 11 13:02:56 2003
8206 +++ linux/include/zlib/zconf.h Mon Feb 9 13:51:03 2004
8207 @@ -0,0 +1,309 @@
8208 +/* zconf.h -- configuration of the zlib compression library
8209 + * Copyright (C) 1995-2002 Jean-loup Gailly.
8210 + * For conditions of distribution and use, see copyright notice in zlib.h
8211 + */
8212 +
8213 +/* @(#) $Id: zconf.h,v 1.4 2004/07/10 07:48:40 mcr Exp $ */
8214 +
8215 +#ifndef _ZCONF_H
8216 +#define _ZCONF_H
8217 +
8218 +/*
8219 + * If you *really* need a unique prefix for all types and library functions,
8220 + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
8221 + */
8222 +#ifdef IPCOMP_PREFIX
8223 +# define deflateInit_ ipcomp_deflateInit_
8224 +# define deflate ipcomp_deflate
8225 +# define deflateEnd ipcomp_deflateEnd
8226 +# define inflateInit_ ipcomp_inflateInit_
8227 +# define inflate ipcomp_inflate
8228 +# define inflateEnd ipcomp_inflateEnd
8229 +# define deflateInit2_ ipcomp_deflateInit2_
8230 +# define deflateSetDictionary ipcomp_deflateSetDictionary
8231 +# define deflateCopy ipcomp_deflateCopy
8232 +# define deflateReset ipcomp_deflateReset
8233 +# define deflateParams ipcomp_deflateParams
8234 +# define inflateInit2_ ipcomp_inflateInit2_
8235 +# define inflateSetDictionary ipcomp_inflateSetDictionary
8236 +# define inflateSync ipcomp_inflateSync
8237 +# define inflateSyncPoint ipcomp_inflateSyncPoint
8238 +# define inflateReset ipcomp_inflateReset
8239 +# define compress ipcomp_compress
8240 +# define compress2 ipcomp_compress2
8241 +# define uncompress ipcomp_uncompress
8242 +# define adler32 ipcomp_adler32
8243 +# define crc32 ipcomp_crc32
8244 +# define get_crc_table ipcomp_get_crc_table
8245 +/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */
8246 +# define inflate_blocks ipcomp_deflate_blocks
8247 +# define inflate_blocks_free ipcomp_deflate_blocks_free
8248 +# define inflate_blocks_new ipcomp_inflate_blocks_new
8249 +# define inflate_blocks_reset ipcomp_inflate_blocks_reset
8250 +# define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point
8251 +# define inflate_set_dictionary ipcomp_inflate_set_dictionary
8252 +# define inflate_codes ipcomp_inflate_codes
8253 +# define inflate_codes_free ipcomp_inflate_codes_free
8254 +# define inflate_codes_new ipcomp_inflate_codes_new
8255 +# define inflate_fast ipcomp_inflate_fast
8256 +# define inflate_trees_bits ipcomp_inflate_trees_bits
8257 +# define inflate_trees_dynamic ipcomp_inflate_trees_dynamic
8258 +# define inflate_trees_fixed ipcomp_inflate_trees_fixed
8259 +# define inflate_flush ipcomp_inflate_flush
8260 +# define inflate_mask ipcomp_inflate_mask
8261 +# define _dist_code _ipcomp_dist_code
8262 +# define _length_code _ipcomp_length_code
8263 +# define _tr_align _ipcomp_tr_align
8264 +# define _tr_flush_block _ipcomp_tr_flush_block
8265 +# define _tr_init _ipcomp_tr_init
8266 +# define _tr_stored_block _ipcomp_tr_stored_block
8267 +# define _tr_tally _ipcomp_tr_tally
8268 +# define zError ipcomp_zError
8269 +# define z_errmsg ipcomp_z_errmsg
8270 +# define zlibVersion ipcomp_zlibVersion
8271 +# define match_init ipcomp_match_init
8272 +# define longest_match ipcomp_longest_match
8273 +#endif
8274 +
8275 +#ifdef Z_PREFIX
8276 +# define Byte z_Byte
8277 +# define uInt z_uInt
8278 +# define uLong z_uLong
8279 +# define Bytef z_Bytef
8280 +# define charf z_charf
8281 +# define intf z_intf
8282 +# define uIntf z_uIntf
8283 +# define uLongf z_uLongf
8284 +# define voidpf z_voidpf
8285 +# define voidp z_voidp
8286 +#endif
8287 +
8288 +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
8289 +# define WIN32
8290 +#endif
8291 +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
8292 +# ifndef __32BIT__
8293 +# define __32BIT__
8294 +# endif
8295 +#endif
8296 +#if defined(__MSDOS__) && !defined(MSDOS)
8297 +# define MSDOS
8298 +#endif
8299 +
8300 +/*
8301 + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
8302 + * than 64k bytes at a time (needed on systems with 16-bit int).
8303 + */
8304 +#if defined(MSDOS) && !defined(__32BIT__)
8305 +# define MAXSEG_64K
8306 +#endif
8307 +#ifdef MSDOS
8308 +# define UNALIGNED_OK
8309 +#endif
8310 +
8311 +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
8312 +# define STDC
8313 +#endif
8314 +#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
8315 +# ifndef STDC
8316 +# define STDC
8317 +# endif
8318 +#endif
8319 +
8320 +#ifndef STDC
8321 +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
8322 +# define const
8323 +# endif
8324 +#endif
8325 +
8326 +/* Some Mac compilers merge all .h files incorrectly: */
8327 +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
8328 +# define NO_DUMMY_DECL
8329 +#endif
8330 +
8331 +/* Old Borland C incorrectly complains about missing returns: */
8332 +#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
8333 +# define NEED_DUMMY_RETURN
8334 +#endif
8335 +
8336 +
8337 +/* Maximum value for memLevel in deflateInit2 */
8338 +#ifndef MAX_MEM_LEVEL
8339 +# ifdef MAXSEG_64K
8340 +# define MAX_MEM_LEVEL 8
8341 +# else
8342 +# define MAX_MEM_LEVEL 9
8343 +# endif
8344 +#endif
8345 +
8346 +/* Maximum value for windowBits in deflateInit2 and inflateInit2.
8347 + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
8348 + * created by gzip. (Files created by minigzip can still be extracted by
8349 + * gzip.)
8350 + */
8351 +#ifndef MAX_WBITS
8352 +# define MAX_WBITS 15 /* 32K LZ77 window */
8353 +#endif
8354 +
8355 +/* The memory requirements for deflate are (in bytes):
8356 + (1 << (windowBits+2)) + (1 << (memLevel+9))
8357 + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
8358 + plus a few kilobytes for small objects. For example, if you want to reduce
8359 + the default memory requirements from 256K to 128K, compile with
8360 + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
8361 + Of course this will generally degrade compression (there's no free lunch).
8362 +
8363 + The memory requirements for inflate are (in bytes) 1 << windowBits
8364 + that is, 32K for windowBits=15 (default value) plus a few kilobytes
8365 + for small objects.
8366 +*/
8367 +
8368 + /* Type declarations */
8369 +
8370 +#ifndef OF /* function prototypes */
8371 +# ifdef STDC
8372 +# define OF(args) args
8373 +# else
8374 +# define OF(args) ()
8375 +# endif
8376 +#endif
8377 +
8378 +/* The following definitions for FAR are needed only for MSDOS mixed
8379 + * model programming (small or medium model with some far allocations).
8380 + * This was tested only with MSC; for other MSDOS compilers you may have
8381 + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
8382 + * just define FAR to be empty.
8383 + */
8384 +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
8385 + /* MSC small or medium model */
8386 +# define SMALL_MEDIUM
8387 +# ifdef _MSC_VER
8388 +# define FAR _far
8389 +# else
8390 +# define FAR far
8391 +# endif
8392 +#endif
8393 +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
8394 +# ifndef __32BIT__
8395 +# define SMALL_MEDIUM
8396 +# define FAR _far
8397 +# endif
8398 +#endif
8399 +
8400 +/* Compile with -DZLIB_DLL for Windows DLL support */
8401 +#if defined(ZLIB_DLL)
8402 +# if defined(_WINDOWS) || defined(WINDOWS)
8403 +# ifdef FAR
8404 +# undef FAR
8405 +# endif
8406 +# include <windows.h>
8407 +# define ZEXPORT WINAPI
8408 +# ifdef WIN32
8409 +# define ZEXPORTVA WINAPIV
8410 +# else
8411 +# define ZEXPORTVA FAR _cdecl _export
8412 +# endif
8413 +# endif
8414 +# if defined (__BORLANDC__)
8415 +# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
8416 +# include <windows.h>
8417 +# define ZEXPORT __declspec(dllexport) WINAPI
8418 +# define ZEXPORTRVA __declspec(dllexport) WINAPIV
8419 +# else
8420 +# if defined (_Windows) && defined (__DLL__)
8421 +# define ZEXPORT _export
8422 +# define ZEXPORTVA _export
8423 +# endif
8424 +# endif
8425 +# endif
8426 +#endif
8427 +
8428 +#if defined (__BEOS__)
8429 +# if defined (ZLIB_DLL)
8430 +# define ZEXTERN extern __declspec(dllexport)
8431 +# else
8432 +# define ZEXTERN extern __declspec(dllimport)
8433 +# endif
8434 +#endif
8435 +
8436 +#ifndef ZEXPORT
8437 +# define ZEXPORT
8438 +#endif
8439 +#ifndef ZEXPORTVA
8440 +# define ZEXPORTVA
8441 +#endif
8442 +#ifndef ZEXTERN
8443 +# define ZEXTERN extern
8444 +#endif
8445 +
8446 +#ifndef FAR
8447 +# define FAR
8448 +#endif
8449 +
8450 +#if !defined(MACOS) && !defined(TARGET_OS_MAC)
8451 +typedef unsigned char Byte; /* 8 bits */
8452 +#endif
8453 +typedef unsigned int uInt; /* 16 bits or more */
8454 +typedef unsigned long uLong; /* 32 bits or more */
8455 +
8456 +#ifdef SMALL_MEDIUM
8457 + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
8458 +# define Bytef Byte FAR
8459 +#else
8460 + typedef Byte FAR Bytef;
8461 +#endif
8462 +typedef char FAR charf;
8463 +typedef int FAR intf;
8464 +typedef uInt FAR uIntf;
8465 +typedef uLong FAR uLongf;
8466 +
8467 +#ifdef STDC
8468 + typedef void FAR *voidpf;
8469 + typedef void *voidp;
8470 +#else
8471 + typedef Byte FAR *voidpf;
8472 + typedef Byte *voidp;
8473 +#endif
8474 +
8475 +#ifdef HAVE_UNISTD_H
8476 +# include <sys/types.h> /* for off_t */
8477 +# include <unistd.h> /* for SEEK_* and off_t */
8478 +# define z_off_t off_t
8479 +#endif
8480 +#ifndef SEEK_SET
8481 +# define SEEK_SET 0 /* Seek from beginning of file. */
8482 +# define SEEK_CUR 1 /* Seek from current position. */
8483 +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
8484 +#endif
8485 +#ifndef z_off_t
8486 +# define z_off_t long
8487 +#endif
8488 +
8489 +/* MVS linker does not support external names larger than 8 bytes */
8490 +#if defined(__MVS__)
8491 +# pragma map(deflateInit_,"DEIN")
8492 +# pragma map(deflateInit2_,"DEIN2")
8493 +# pragma map(deflateEnd,"DEEND")
8494 +# pragma map(inflateInit_,"ININ")
8495 +# pragma map(inflateInit2_,"ININ2")
8496 +# pragma map(inflateEnd,"INEND")
8497 +# pragma map(inflateSync,"INSY")
8498 +# pragma map(inflateSetDictionary,"INSEDI")
8499 +# pragma map(inflate_blocks,"INBL")
8500 +# pragma map(inflate_blocks_new,"INBLNE")
8501 +# pragma map(inflate_blocks_free,"INBLFR")
8502 +# pragma map(inflate_blocks_reset,"INBLRE")
8503 +# pragma map(inflate_codes_free,"INCOFR")
8504 +# pragma map(inflate_codes,"INCO")
8505 +# pragma map(inflate_fast,"INFA")
8506 +# pragma map(inflate_flush,"INFLU")
8507 +# pragma map(inflate_mask,"INMA")
8508 +# pragma map(inflate_set_dictionary,"INSEDI2")
8509 +# pragma map(ipcomp_inflate_copyright,"INCOPY")
8510 +# pragma map(inflate_trees_bits,"INTRBI")
8511 +# pragma map(inflate_trees_dynamic,"INTRDY")
8512 +# pragma map(inflate_trees_fixed,"INTRFI")
8513 +# pragma map(inflate_trees_free,"INTRFR")
8514 +#endif
8515 +
8516 +#endif /* _ZCONF_H */
8517 --- /dev/null Tue Mar 11 13:02:56 2003
8518 +++ linux/include/zlib/zlib.h Mon Feb 9 13:51:03 2004
8519 @@ -0,0 +1,893 @@
8520 +/* zlib.h -- interface of the 'zlib' general purpose compression library
8521 + version 1.1.4, March 11th, 2002
8522 +
8523 + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
8524 +
8525 + This software is provided 'as-is', without any express or implied
8526 + warranty. In no event will the authors be held liable for any damages
8527 + arising from the use of this software.
8528 +
8529 + Permission is granted to anyone to use this software for any purpose,
8530 + including commercial applications, and to alter it and redistribute it
8531 + freely, subject to the following restrictions:
8532 +
8533 + 1. The origin of this software must not be misrepresented; you must not
8534 + claim that you wrote the original software. If you use this software
8535 + in a product, an acknowledgment in the product documentation would be
8536 + appreciated but is not required.
8537 + 2. Altered source versions must be plainly marked as such, and must not be
8538 + misrepresented as being the original software.
8539 + 3. This notice may not be removed or altered from any source distribution.
8540 +
8541 + Jean-loup Gailly Mark Adler
8542 + jloup@gzip.org madler@alumni.caltech.edu
8543 +
8544 +
8545 + The data format used by the zlib library is described by RFCs (Request for
8546 + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
8547 + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
8548 +*/
8549 +
8550 +#ifndef _ZLIB_H
8551 +#define _ZLIB_H
8552 +
8553 +#include "zconf.h"
8554 +
8555 +#ifdef __cplusplus
8556 +extern "C" {
8557 +#endif
8558 +
8559 +#define ZLIB_VERSION "1.1.4"
8560 +
8561 +/*
8562 + The 'zlib' compression library provides in-memory compression and
8563 + decompression functions, including integrity checks of the uncompressed
8564 + data. This version of the library supports only one compression method
8565 + (deflation) but other algorithms will be added later and will have the same
8566 + stream interface.
8567 +
8568 + Compression can be done in a single step if the buffers are large
8569 + enough (for example if an input file is mmap'ed), or can be done by
8570 + repeated calls of the compression function. In the latter case, the
8571 + application must provide more input and/or consume the output
8572 + (providing more output space) before each call.
8573 +
8574 + The library also supports reading and writing files in gzip (.gz) format
8575 + with an interface similar to that of stdio.
8576 +
8577 + The library does not install any signal handler. The decoder checks
8578 + the consistency of the compressed data, so the library should never
8579 + crash even in case of corrupted input.
8580 +*/
8581 +
8582 +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
8583 +typedef void (*free_func) OF((voidpf opaque, voidpf address));
8584 +
8585 +struct internal_state;
8586 +
8587 +typedef struct z_stream_s {
8588 + Bytef *next_in; /* next input byte */
8589 + uInt avail_in; /* number of bytes available at next_in */
8590 + uLong total_in; /* total nb of input bytes read so far */
8591 +
8592 + Bytef *next_out; /* next output byte should be put there */
8593 + uInt avail_out; /* remaining free space at next_out */
8594 + uLong total_out; /* total nb of bytes output so far */
8595 +
8596 + const char *msg; /* last error message, NULL if no error */
8597 + struct internal_state FAR *state; /* not visible by applications */
8598 +
8599 + alloc_func zalloc; /* used to allocate the internal state */
8600 + free_func zfree; /* used to free the internal state */
8601 + voidpf opaque; /* private data object passed to zalloc and zfree */
8602 +
8603 + int data_type; /* best guess about the data type: ascii or binary */
8604 + uLong adler; /* adler32 value of the uncompressed data */
8605 + uLong reserved; /* reserved for future use */
8606 +} z_stream;
8607 +
8608 +typedef z_stream FAR *z_streamp;
8609 +
8610 +/*
8611 + The application must update next_in and avail_in when avail_in has
8612 + dropped to zero. It must update next_out and avail_out when avail_out
8613 + has dropped to zero. The application must initialize zalloc, zfree and
8614 + opaque before calling the init function. All other fields are set by the
8615 + compression library and must not be updated by the application.
8616 +
8617 + The opaque value provided by the application will be passed as the first
8618 + parameter for calls of zalloc and zfree. This can be useful for custom
8619 + memory management. The compression library attaches no meaning to the
8620 + opaque value.
8621 +
8622 + zalloc must return Z_NULL if there is not enough memory for the object.
8623 + If zlib is used in a multi-threaded application, zalloc and zfree must be
8624 + thread safe.
8625 +
8626 + On 16-bit systems, the functions zalloc and zfree must be able to allocate
8627 + exactly 65536 bytes, but will not be required to allocate more than this
8628 + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
8629 + pointers returned by zalloc for objects of exactly 65536 bytes *must*
8630 + have their offset normalized to zero. The default allocation function
8631 + provided by this library ensures this (see zutil.c). To reduce memory
8632 + requirements and avoid any allocation of 64K objects, at the expense of
8633 + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
8634 +
8635 + The fields total_in and total_out can be used for statistics or
8636 + progress reports. After compression, total_in holds the total size of
8637 + the uncompressed data and may be saved for use in the decompressor
8638 + (particularly if the decompressor wants to decompress everything in
8639 + a single step).
8640 +*/
8641 +
8642 + /* constants */
8643 +
8644 +#define Z_NO_FLUSH 0
8645 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
8646 +#define Z_SYNC_FLUSH 2
8647 +#define Z_FULL_FLUSH 3
8648 +#define Z_FINISH 4
8649 +/* Allowed flush values; see deflate() below for details */
8650 +
8651 +#define Z_OK 0
8652 +#define Z_STREAM_END 1
8653 +#define Z_NEED_DICT 2
8654 +#define Z_ERRNO (-1)
8655 +#define Z_STREAM_ERROR (-2)
8656 +#define Z_DATA_ERROR (-3)
8657 +#define Z_MEM_ERROR (-4)
8658 +#define Z_BUF_ERROR (-5)
8659 +#define Z_VERSION_ERROR (-6)
8660 +/* Return codes for the compression/decompression functions. Negative
8661 + * values are errors, positive values are used for special but normal events.
8662 + */
8663 +
8664 +#define Z_NO_COMPRESSION 0
8665 +#define Z_BEST_SPEED 1
8666 +#define Z_BEST_COMPRESSION 9
8667 +#define Z_DEFAULT_COMPRESSION (-1)
8668 +/* compression levels */
8669 +
8670 +#define Z_FILTERED 1
8671 +#define Z_HUFFMAN_ONLY 2
8672 +#define Z_DEFAULT_STRATEGY 0
8673 +/* compression strategy; see deflateInit2() below for details */
8674 +
8675 +#define Z_BINARY 0
8676 +#define Z_ASCII 1
8677 +#define Z_UNKNOWN 2
8678 +/* Possible values of the data_type field */
8679 +
8680 +#define Z_DEFLATED 8
8681 +/* The deflate compression method (the only one supported in this version) */
8682 +
8683 +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
8684 +
8685 +#define zlib_version zlibVersion()
8686 +/* for compatibility with versions < 1.0.2 */
8687 +
8688 + /* basic functions */
8689 +
8690 +ZEXTERN const char * ZEXPORT zlibVersion OF((void));
8691 +/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
8692 + If the first character differs, the library code actually used is
8693 + not compatible with the zlib.h header file used by the application.
8694 + This check is automatically made by deflateInit and inflateInit.
8695 + */
8696 +
8697 +/*
8698 +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
8699 +
8700 + Initializes the internal stream state for compression. The fields
8701 + zalloc, zfree and opaque must be initialized before by the caller.
8702 + If zalloc and zfree are set to Z_NULL, deflateInit updates them to
8703 + use default allocation functions.
8704 +
8705 + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
8706 + 1 gives best speed, 9 gives best compression, 0 gives no compression at
8707 + all (the input data is simply copied a block at a time).
8708 + Z_DEFAULT_COMPRESSION requests a default compromise between speed and
8709 + compression (currently equivalent to level 6).
8710 +
8711 + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
8712 + enough memory, Z_STREAM_ERROR if level is not a valid compression level,
8713 + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
8714 + with the version assumed by the caller (ZLIB_VERSION).
8715 + msg is set to null if there is no error message. deflateInit does not
8716 + perform any compression: this will be done by deflate().
8717 +*/
8718 +
8719 +
8720 +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
8721 +/*
8722 + deflate compresses as much data as possible, and stops when the input
8723 + buffer becomes empty or the output buffer becomes full. It may introduce some
8724 + output latency (reading input without producing any output) except when
8725 + forced to flush.
8726 +
8727 + The detailed semantics are as follows. deflate performs one or both of the
8728 + following actions:
8729 +
8730 + - Compress more input starting at next_in and update next_in and avail_in
8731 + accordingly. If not all input can be processed (because there is not
8732 + enough room in the output buffer), next_in and avail_in are updated and
8733 + processing will resume at this point for the next call of deflate().
8734 +
8735 + - Provide more output starting at next_out and update next_out and avail_out
8736 + accordingly. This action is forced if the parameter flush is non zero.
8737 + Forcing flush frequently degrades the compression ratio, so this parameter
8738 + should be set only when necessary (in interactive applications).
8739 + Some output may be provided even if flush is not set.
8740 +
8741 + Before the call of deflate(), the application should ensure that at least
8742 + one of the actions is possible, by providing more input and/or consuming
8743 + more output, and updating avail_in or avail_out accordingly; avail_out
8744 + should never be zero before the call. The application can consume the
8745 + compressed output when it wants, for example when the output buffer is full
8746 + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
8747 + and with zero avail_out, it must be called again after making room in the
8748 + output buffer because there might be more output pending.
8749 +
8750 + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
8751 + flushed to the output buffer and the output is aligned on a byte boundary, so
8752 + that the decompressor can get all input data available so far. (In particular
8753 + avail_in is zero after the call if enough output space has been provided
8754 + before the call.) Flushing may degrade compression for some compression
8755 + algorithms and so it should be used only when necessary.
8756 +
8757 + If flush is set to Z_FULL_FLUSH, all output is flushed as with
8758 + Z_SYNC_FLUSH, and the compression state is reset so that decompression can
8759 + restart from this point if previous compressed data has been damaged or if
8760 + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
8761 + the compression.
8762 +
8763 + If deflate returns with avail_out == 0, this function must be called again
8764 + with the same value of the flush parameter and more output space (updated
8765 + avail_out), until the flush is complete (deflate returns with non-zero
8766 + avail_out).
8767 +
8768 + If the parameter flush is set to Z_FINISH, pending input is processed,
8769 + pending output is flushed and deflate returns with Z_STREAM_END if there
8770 + was enough output space; if deflate returns with Z_OK, this function must be
8771 + called again with Z_FINISH and more output space (updated avail_out) but no
8772 + more input data, until it returns with Z_STREAM_END or an error. After
8773 + deflate has returned Z_STREAM_END, the only possible operations on the
8774 + stream are deflateReset or deflateEnd.
8775 +
8776 + Z_FINISH can be used immediately after deflateInit if all the compression
8777 + is to be done in a single step. In this case, avail_out must be at least
8778 + 0.1% larger than avail_in plus 12 bytes. If deflate does not return
8779 + Z_STREAM_END, then it must be called again as described above.
8780 +
8781 + deflate() sets strm->adler to the adler32 checksum of all input read
8782 + so far (that is, total_in bytes).
8783 +
8784 + deflate() may update data_type if it can make a good guess about
8785 + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
8786 + binary. This field is only for information purposes and does not affect
8787 + the compression algorithm in any manner.
8788 +
8789 + deflate() returns Z_OK if some progress has been made (more input
8790 + processed or more output produced), Z_STREAM_END if all input has been
8791 + consumed and all output has been produced (only when flush is set to
8792 + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
8793 + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
8794 + (for example avail_in or avail_out was zero).
8795 +*/
8796 +
8797 +
8798 +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
8799 +/*
8800 + All dynamically allocated data structures for this stream are freed.
8801 + This function discards any unprocessed input and does not flush any
8802 + pending output.
8803 +
8804 + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
8805 + stream state was inconsistent, Z_DATA_ERROR if the stream was freed
8806 + prematurely (some input or output was discarded). In the error case,
8807 + msg may be set but then points to a static string (which must not be
8808 + deallocated).
8809 +*/
8810 +
8811 +
8812 +/*
8813 +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
8814 +
8815 + Initializes the internal stream state for decompression. The fields
8816 + next_in, avail_in, zalloc, zfree and opaque must be initialized before by
8817 + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
8818 + value depends on the compression method), inflateInit determines the
8819 + compression method from the zlib header and allocates all data structures
8820 + accordingly; otherwise the allocation will be deferred to the first call of
8821 + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
8822 + use default allocation functions.
8823 +
8824 + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
8825 + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
8826 + version assumed by the caller. msg is set to null if there is no error
8827 + message. inflateInit does not perform any decompression apart from reading
8828 + the zlib header if present: this will be done by inflate(). (So next_in and
8829 + avail_in may be modified, but next_out and avail_out are unchanged.)
8830 +*/
8831 +
8832 +
8833 +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
8834 +/*
8835 + inflate decompresses as much data as possible, and stops when the input
8836 + buffer becomes empty or the output buffer becomes full. It may some
8837 + introduce some output latency (reading input without producing any output)
8838 + except when forced to flush.
8839 +
8840 + The detailed semantics are as follows. inflate performs one or both of the
8841 + following actions:
8842 +
8843 + - Decompress more input starting at next_in and update next_in and avail_in
8844 + accordingly. If not all input can be processed (because there is not
8845 + enough room in the output buffer), next_in is updated and processing
8846 + will resume at this point for the next call of inflate().
8847 +
8848 + - Provide more output starting at next_out and update next_out and avail_out
8849 + accordingly. inflate() provides as much output as possible, until there
8850 + is no more input data or no more space in the output buffer (see below
8851 + about the flush parameter).
8852 +
8853 + Before the call of inflate(), the application should ensure that at least
8854 + one of the actions is possible, by providing more input and/or consuming
8855 + more output, and updating the next_* and avail_* values accordingly.
8856 + The application can consume the uncompressed output when it wants, for
8857 + example when the output buffer is full (avail_out == 0), or after each
8858 + call of inflate(). If inflate returns Z_OK and with zero avail_out, it
8859 + must be called again after making room in the output buffer because there
8860 + might be more output pending.
8861 +
8862 + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
8863 + output as possible to the output buffer. The flushing behavior of inflate is
8864 + not specified for values of the flush parameter other than Z_SYNC_FLUSH
8865 + and Z_FINISH, but the current implementation actually flushes as much output
8866 + as possible anyway.
8867 +
8868 + inflate() should normally be called until it returns Z_STREAM_END or an
8869 + error. However if all decompression is to be performed in a single step
8870 + (a single call of inflate), the parameter flush should be set to
8871 + Z_FINISH. In this case all pending input is processed and all pending
8872 + output is flushed; avail_out must be large enough to hold all the
8873 + uncompressed data. (The size of the uncompressed data may have been saved
8874 + by the compressor for this purpose.) The next operation on this stream must
8875 + be inflateEnd to deallocate the decompression state. The use of Z_FINISH
8876 + is never required, but can be used to inform inflate that a faster routine
8877 + may be used for the single inflate() call.
8878 +
8879 + If a preset dictionary is needed at this point (see inflateSetDictionary
8880 + below), inflate sets strm-adler to the adler32 checksum of the
8881 + dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
8882 + it sets strm->adler to the adler32 checksum of all output produced
8883 + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
8884 + an error code as described below. At the end of the stream, inflate()
8885 + checks that its computed adler32 checksum is equal to that saved by the
8886 + compressor and returns Z_STREAM_END only if the checksum is correct.
8887 +
8888 + inflate() returns Z_OK if some progress has been made (more input processed
8889 + or more output produced), Z_STREAM_END if the end of the compressed data has
8890 + been reached and all uncompressed output has been produced, Z_NEED_DICT if a
8891 + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
8892 + corrupted (input stream not conforming to the zlib format or incorrect
8893 + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
8894 + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
8895 + enough memory, Z_BUF_ERROR if no progress is possible or if there was not
8896 + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
8897 + case, the application may then call inflateSync to look for a good
8898 + compression block.
8899 +*/
8900 +
8901 +
8902 +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
8903 +/*
8904 + All dynamically allocated data structures for this stream are freed.
8905 + This function discards any unprocessed input and does not flush any
8906 + pending output.
8907 +
8908 + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
8909 + was inconsistent. In the error case, msg may be set but then points to a
8910 + static string (which must not be deallocated).
8911 +*/
8912 +
8913 + /* Advanced functions */
8914 +
8915 +/*
8916 + The following functions are needed only in some special applications.
8917 +*/
8918 +
8919 +/*
8920 +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
8921 + int level,
8922 + int method,
8923 + int windowBits,
8924 + int memLevel,
8925 + int strategy));
8926 +
8927 + This is another version of deflateInit with more compression options. The
8928 + fields next_in, zalloc, zfree and opaque must be initialized before by
8929 + the caller.
8930 +
8931 + The method parameter is the compression method. It must be Z_DEFLATED in
8932 + this version of the library.
8933 +
8934 + The windowBits parameter is the base two logarithm of the window size
8935 + (the size of the history buffer). It should be in the range 8..15 for this
8936 + version of the library. Larger values of this parameter result in better
8937 + compression at the expense of memory usage. The default value is 15 if
8938 + deflateInit is used instead.
8939 +
8940 + The memLevel parameter specifies how much memory should be allocated
8941 + for the internal compression state. memLevel=1 uses minimum memory but
8942 + is slow and reduces compression ratio; memLevel=9 uses maximum memory
8943 + for optimal speed. The default value is 8. See zconf.h for total memory
8944 + usage as a function of windowBits and memLevel.
8945 +
8946 + The strategy parameter is used to tune the compression algorithm. Use the
8947 + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
8948 + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
8949 + string match). Filtered data consists mostly of small values with a
8950 + somewhat random distribution. In this case, the compression algorithm is
8951 + tuned to compress them better. The effect of Z_FILTERED is to force more
8952 + Huffman coding and less string matching; it is somewhat intermediate
8953 + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
8954 + the compression ratio but not the correctness of the compressed output even
8955 + if it is not set appropriately.
8956 +
8957 + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
8958 + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
8959 + method). msg is set to null if there is no error message. deflateInit2 does
8960 + not perform any compression: this will be done by deflate().
8961 +*/
8962 +
8963 +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
8964 + const Bytef *dictionary,
8965 + uInt dictLength));
8966 +/*
8967 + Initializes the compression dictionary from the given byte sequence
8968 + without producing any compressed output. This function must be called
8969 + immediately after deflateInit, deflateInit2 or deflateReset, before any
8970 + call of deflate. The compressor and decompressor must use exactly the same
8971 + dictionary (see inflateSetDictionary).
8972 +
8973 + The dictionary should consist of strings (byte sequences) that are likely
8974 + to be encountered later in the data to be compressed, with the most commonly
8975 + used strings preferably put towards the end of the dictionary. Using a
8976 + dictionary is most useful when the data to be compressed is short and can be
8977 + predicted with good accuracy; the data can then be compressed better than
8978 + with the default empty dictionary.
8979 +
8980 + Depending on the size of the compression data structures selected by
8981 + deflateInit or deflateInit2, a part of the dictionary may in effect be
8982 + discarded, for example if the dictionary is larger than the window size in
8983 + deflate or deflate2. Thus the strings most likely to be useful should be
8984 + put at the end of the dictionary, not at the front.
8985 +
8986 + Upon return of this function, strm->adler is set to the Adler32 value
8987 + of the dictionary; the decompressor may later use this value to determine
8988 + which dictionary has been used by the compressor. (The Adler32 value
8989 + applies to the whole dictionary even if only a subset of the dictionary is
8990 + actually used by the compressor.)
8991 +
8992 + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
8993 + parameter is invalid (such as NULL dictionary) or the stream state is
8994 + inconsistent (for example if deflate has already been called for this stream
8995 + or if the compression method is bsort). deflateSetDictionary does not
8996 + perform any compression: this will be done by deflate().
8997 +*/
8998 +
8999 +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
9000 + z_streamp source));
9001 +/*
9002 + Sets the destination stream as a complete copy of the source stream.
9003 +
9004 + This function can be useful when several compression strategies will be
9005 + tried, for example when there are several ways of pre-processing the input
9006 + data with a filter. The streams that will be discarded should then be freed
9007 + by calling deflateEnd. Note that deflateCopy duplicates the internal
9008 + compression state which can be quite large, so this strategy is slow and
9009 + can consume lots of memory.
9010 +
9011 + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
9012 + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
9013 + (such as zalloc being NULL). msg is left unchanged in both source and
9014 + destination.
9015 +*/
9016 +
9017 +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
9018 +/*
9019 + This function is equivalent to deflateEnd followed by deflateInit,
9020 + but does not free and reallocate all the internal compression state.
9021 + The stream will keep the same compression level and any other attributes
9022 + that may have been set by deflateInit2.
9023 +
9024 + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
9025 + stream state was inconsistent (such as zalloc or state being NULL).
9026 +*/
9027 +
9028 +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
9029 + int level,
9030 + int strategy));
9031 +/*
9032 + Dynamically update the compression level and compression strategy. The
9033 + interpretation of level and strategy is as in deflateInit2. This can be
9034 + used to switch between compression and straight copy of the input data, or
9035 + to switch to a different kind of input data requiring a different
9036 + strategy. If the compression level is changed, the input available so far
9037 + is compressed with the old level (and may be flushed); the new level will
9038 + take effect only at the next call of deflate().
9039 +
9040 + Before the call of deflateParams, the stream state must be set as for
9041 + a call of deflate(), since the currently available input may have to
9042 + be compressed and flushed. In particular, strm->avail_out must be non-zero.
9043 +
9044 + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
9045 + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
9046 + if strm->avail_out was zero.
9047 +*/
9048 +
9049 +/*
9050 +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
9051 + int windowBits));
9052 +
9053 + This is another version of inflateInit with an extra parameter. The
9054 + fields next_in, avail_in, zalloc, zfree and opaque must be initialized
9055 + before by the caller.
9056 +
9057 + The windowBits parameter is the base two logarithm of the maximum window
9058 + size (the size of the history buffer). It should be in the range 8..15 for
9059 + this version of the library. The default value is 15 if inflateInit is used
9060 + instead. If a compressed stream with a larger window size is given as
9061 + input, inflate() will return with the error code Z_DATA_ERROR instead of
9062 + trying to allocate a larger window.
9063 +
9064 + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
9065 + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
9066 + memLevel). msg is set to null if there is no error message. inflateInit2
9067 + does not perform any decompression apart from reading the zlib header if
9068 + present: this will be done by inflate(). (So next_in and avail_in may be
9069 + modified, but next_out and avail_out are unchanged.)
9070 +*/
9071 +
9072 +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
9073 + const Bytef *dictionary,
9074 + uInt dictLength));
9075 +/*
9076 + Initializes the decompression dictionary from the given uncompressed byte
9077 + sequence. This function must be called immediately after a call of inflate
9078 + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
9079 + can be determined from the Adler32 value returned by this call of
9080 + inflate. The compressor and decompressor must use exactly the same
9081 + dictionary (see deflateSetDictionary).
9082 +
9083 + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
9084 + parameter is invalid (such as NULL dictionary) or the stream state is
9085 + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
9086 + expected one (incorrect Adler32 value). inflateSetDictionary does not
9087 + perform any decompression: this will be done by subsequent calls of
9088 + inflate().
9089 +*/
9090 +
9091 +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
9092 +/*
9093 + Skips invalid compressed data until a full flush point (see above the
9094 + description of deflate with Z_FULL_FLUSH) can be found, or until all
9095 + available input is skipped. No output is provided.
9096 +
9097 + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
9098 + if no more input was provided, Z_DATA_ERROR if no flush point has been found,
9099 + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
9100 + case, the application may save the current current value of total_in which
9101 + indicates where valid compressed data was found. In the error case, the
9102 + application may repeatedly call inflateSync, providing more input each time,
9103 + until success or end of the input data.
9104 +*/
9105 +
9106 +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
9107 +/*
9108 + This function is equivalent to inflateEnd followed by inflateInit,
9109 + but does not free and reallocate all the internal decompression state.
9110 + The stream will keep attributes that may have been set by inflateInit2.
9111 +
9112 + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
9113 + stream state was inconsistent (such as zalloc or state being NULL).
9114 +*/
9115 +
9116 +
9117 + /* utility functions */
9118 +
9119 +/*
9120 + The following utility functions are implemented on top of the
9121 + basic stream-oriented functions. To simplify the interface, some
9122 + default options are assumed (compression level and memory usage,
9123 + standard memory allocation functions). The source code of these
9124 + utility functions can easily be modified if you need special options.
9125 +*/
9126 +
9127 +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
9128 + const Bytef *source, uLong sourceLen));
9129 +/*
9130 + Compresses the source buffer into the destination buffer. sourceLen is
9131 + the byte length of the source buffer. Upon entry, destLen is the total
9132 + size of the destination buffer, which must be at least 0.1% larger than
9133 + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
9134 + compressed buffer.
9135 + This function can be used to compress a whole file at once if the
9136 + input file is mmap'ed.
9137 + compress returns Z_OK if success, Z_MEM_ERROR if there was not
9138 + enough memory, Z_BUF_ERROR if there was not enough room in the output
9139 + buffer.
9140 +*/
9141 +
9142 +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
9143 + const Bytef *source, uLong sourceLen,
9144 + int level));
9145 +/*
9146 + Compresses the source buffer into the destination buffer. The level
9147 + parameter has the same meaning as in deflateInit. sourceLen is the byte
9148 + length of the source buffer. Upon entry, destLen is the total size of the
9149 + destination buffer, which must be at least 0.1% larger than sourceLen plus
9150 + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
9151 +
9152 + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
9153 + memory, Z_BUF_ERROR if there was not enough room in the output buffer,
9154 + Z_STREAM_ERROR if the level parameter is invalid.
9155 +*/
9156 +
9157 +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
9158 + const Bytef *source, uLong sourceLen));
9159 +/*
9160 + Decompresses the source buffer into the destination buffer. sourceLen is
9161 + the byte length of the source buffer. Upon entry, destLen is the total
9162 + size of the destination buffer, which must be large enough to hold the
9163 + entire uncompressed data. (The size of the uncompressed data must have
9164 + been saved previously by the compressor and transmitted to the decompressor
9165 + by some mechanism outside the scope of this compression library.)
9166 + Upon exit, destLen is the actual size of the compressed buffer.
9167 + This function can be used to decompress a whole file at once if the
9168 + input file is mmap'ed.
9169 +
9170 + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
9171 + enough memory, Z_BUF_ERROR if there was not enough room in the output
9172 + buffer, or Z_DATA_ERROR if the input data was corrupted.
9173 +*/
9174 +
9175 +
9176 +typedef voidp gzFile;
9177 +
9178 +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
9179 +/*
9180 + Opens a gzip (.gz) file for reading or writing. The mode parameter
9181 + is as in fopen ("rb" or "wb") but can also include a compression level
9182 + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
9183 + Huffman only compression as in "wb1h". (See the description
9184 + of deflateInit2 for more information about the strategy parameter.)
9185 +
9186 + gzopen can be used to read a file which is not in gzip format; in this
9187 + case gzread will directly read from the file without decompression.
9188 +
9189 + gzopen returns NULL if the file could not be opened or if there was
9190 + insufficient memory to allocate the (de)compression state; errno
9191 + can be checked to distinguish the two cases (if errno is zero, the
9192 + zlib error is Z_MEM_ERROR). */
9193 +
9194 +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
9195 +/*
9196 + gzdopen() associates a gzFile with the file descriptor fd. File
9197 + descriptors are obtained from calls like open, dup, creat, pipe or
9198 + fileno (in the file has been previously opened with fopen).
9199 + The mode parameter is as in gzopen.
9200 + The next call of gzclose on the returned gzFile will also close the
9201 + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
9202 + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
9203 + gzdopen returns NULL if there was insufficient memory to allocate
9204 + the (de)compression state.
9205 +*/
9206 +
9207 +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
9208 +/*
9209 + Dynamically update the compression level or strategy. See the description
9210 + of deflateInit2 for the meaning of these parameters.
9211 + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
9212 + opened for writing.
9213 +*/
9214 +
9215 +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
9216 +/*
9217 + Reads the given number of uncompressed bytes from the compressed file.
9218 + If the input file was not in gzip format, gzread copies the given number
9219 + of bytes into the buffer.
9220 + gzread returns the number of uncompressed bytes actually read (0 for
9221 + end of file, -1 for error). */
9222 +
9223 +ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
9224 + const voidp buf, unsigned len));
9225 +/*
9226 + Writes the given number of uncompressed bytes into the compressed file.
9227 + gzwrite returns the number of uncompressed bytes actually written
9228 + (0 in case of error).
9229 +*/
9230 +
9231 +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
9232 +/*
9233 + Converts, formats, and writes the args to the compressed file under
9234 + control of the format string, as in fprintf. gzprintf returns the number of
9235 + uncompressed bytes actually written (0 in case of error).
9236 +*/
9237 +
9238 +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
9239 +/*
9240 + Writes the given null-terminated string to the compressed file, excluding
9241 + the terminating null character.
9242 + gzputs returns the number of characters written, or -1 in case of error.
9243 +*/
9244 +
9245 +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
9246 +/*
9247 + Reads bytes from the compressed file until len-1 characters are read, or
9248 + a newline character is read and transferred to buf, or an end-of-file
9249 + condition is encountered. The string is then terminated with a null
9250 + character.
9251 + gzgets returns buf, or Z_NULL in case of error.
9252 +*/
9253 +
9254 +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
9255 +/*
9256 + Writes c, converted to an unsigned char, into the compressed file.
9257 + gzputc returns the value that was written, or -1 in case of error.
9258 +*/
9259 +
9260 +ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
9261 +/*
9262 + Reads one byte from the compressed file. gzgetc returns this byte
9263 + or -1 in case of end of file or error.
9264 +*/
9265 +
9266 +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
9267 +/*
9268 + Flushes all pending output into the compressed file. The parameter
9269 + flush is as in the deflate() function. The return value is the zlib
9270 + error number (see function gzerror below). gzflush returns Z_OK if
9271 + the flush parameter is Z_FINISH and all output could be flushed.
9272 + gzflush should be called only when strictly necessary because it can
9273 + degrade compression.
9274 +*/
9275 +
9276 +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
9277 + z_off_t offset, int whence));
9278 +/*
9279 + Sets the starting position for the next gzread or gzwrite on the
9280 + given compressed file. The offset represents a number of bytes in the
9281 + uncompressed data stream. The whence parameter is defined as in lseek(2);
9282 + the value SEEK_END is not supported.
9283 + If the file is opened for reading, this function is emulated but can be
9284 + extremely slow. If the file is opened for writing, only forward seeks are
9285 + supported; gzseek then compresses a sequence of zeroes up to the new
9286 + starting position.
9287 +
9288 + gzseek returns the resulting offset location as measured in bytes from
9289 + the beginning of the uncompressed stream, or -1 in case of error, in
9290 + particular if the file is opened for writing and the new starting position
9291 + would be before the current position.
9292 +*/
9293 +
9294 +ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
9295 +/*
9296 + Rewinds the given file. This function is supported only for reading.
9297 +
9298 + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
9299 +*/
9300 +
9301 +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
9302 +/*
9303 + Returns the starting position for the next gzread or gzwrite on the
9304 + given compressed file. This position represents a number of bytes in the
9305 + uncompressed data stream.
9306 +
9307 + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
9308 +*/
9309 +
9310 +ZEXTERN int ZEXPORT gzeof OF((gzFile file));
9311 +/*
9312 + Returns 1 when EOF has previously been detected reading the given
9313 + input stream, otherwise zero.
9314 +*/
9315 +
9316 +ZEXTERN int ZEXPORT gzclose OF((gzFile file));
9317 +/*
9318 + Flushes all pending output if necessary, closes the compressed file
9319 + and deallocates all the (de)compression state. The return value is the zlib
9320 + error number (see function gzerror below).
9321 +*/
9322 +
9323 +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
9324 +/*
9325 + Returns the error message for the last error which occurred on the
9326 + given compressed file. errnum is set to zlib error number. If an
9327 + error occurred in the file system and not in the compression library,
9328 + errnum is set to Z_ERRNO and the application may consult errno
9329 + to get the exact error code.
9330 +*/
9331 +
9332 + /* checksum functions */
9333 +
9334 +/*
9335 + These functions are not related to compression but are exported
9336 + anyway because they might be useful in applications using the
9337 + compression library.
9338 +*/
9339 +
9340 +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
9341 +
9342 +/*
9343 + Update a running Adler-32 checksum with the bytes buf[0..len-1] and
9344 + return the updated checksum. If buf is NULL, this function returns
9345 + the required initial value for the checksum.
9346 + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
9347 + much faster. Usage example:
9348 +
9349 + uLong adler = adler32(0L, Z_NULL, 0);
9350 +
9351 + while (read_buffer(buffer, length) != EOF) {
9352 + adler = adler32(adler, buffer, length);
9353 + }
9354 + if (adler != original_adler) error();
9355 +*/
9356 +
9357 +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
9358 +/*
9359 + Update a running crc with the bytes buf[0..len-1] and return the updated
9360 + crc. If buf is NULL, this function returns the required initial value
9361 + for the crc. Pre- and post-conditioning (one's complement) is performed
9362 + within this function so it shouldn't be done by the application.
9363 + Usage example:
9364 +
9365 + uLong crc = crc32(0L, Z_NULL, 0);
9366 +
9367 + while (read_buffer(buffer, length) != EOF) {
9368 + crc = crc32(crc, buffer, length);
9369 + }
9370 + if (crc != original_crc) error();
9371 +*/
9372 +
9373 +
9374 + /* various hacks, don't look :) */
9375 +
9376 +/* deflateInit and inflateInit are macros to allow checking the zlib version
9377 + * and the compiler's view of z_stream:
9378 + */
9379 +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
9380 + const char *version, int stream_size));
9381 +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
9382 + const char *version, int stream_size));
9383 +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
9384 + int windowBits, int memLevel,
9385 + int strategy, const char *version,
9386 + int stream_size));
9387 +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
9388 + const char *version, int stream_size));
9389 +#define deflateInit(strm, level) \
9390 + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
9391 +#define inflateInit(strm) \
9392 + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
9393 +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
9394 + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
9395 + (strategy), ZLIB_VERSION, sizeof(z_stream))
9396 +#define inflateInit2(strm, windowBits) \
9397 + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
9398 +
9399 +
9400 +#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
9401 + struct internal_state {int dummy;}; /* hack for buggy compilers */
9402 +#endif
9403 +
9404 +ZEXTERN const char * ZEXPORT zError OF((int err));
9405 +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
9406 +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
9407 +
9408 +#ifdef __cplusplus
9409 +}
9410 +#endif
9411 +
9412 +#endif /* _ZLIB_H */
9413 --- /dev/null Tue Mar 11 13:02:56 2003
9414 +++ linux/include/zlib/zutil.h Mon Feb 9 13:51:03 2004
9415 @@ -0,0 +1,225 @@
9416 +/* zutil.h -- internal interface and configuration of the compression library
9417 + * Copyright (C) 1995-2002 Jean-loup Gailly.
9418 + * For conditions of distribution and use, see copyright notice in zlib.h
9419 + */
9420 +
9421 +/* WARNING: this file should *not* be used by applications. It is
9422 + part of the implementation of the compression library and is
9423 + subject to change. Applications should only use zlib.h.
9424 + */
9425 +
9426 +/* @(#) $Id: zutil.h,v 1.4 2002/04/24 07:36:48 mcr Exp $ */
9427 +
9428 +#ifndef _Z_UTIL_H
9429 +#define _Z_UTIL_H
9430 +
9431 +#include "zlib.h"
9432 +
9433 +#include <linux/string.h>
9434 +#define HAVE_MEMCPY
9435 +
9436 +#if 0 // #ifdef STDC
9437 +# include <stddef.h>
9438 +# include <string.h>
9439 +# include <stdlib.h>
9440 +#endif
9441 +#ifndef __KERNEL__
9442 +#ifdef NO_ERRNO_H
9443 + extern int errno;
9444 +#else
9445 +# include <errno.h>
9446 +#endif
9447 +#endif
9448 +
9449 +#ifndef local
9450 +# define local static
9451 +#endif
9452 +/* compile with -Dlocal if your debugger can't find static symbols */
9453 +
9454 +typedef unsigned char uch;
9455 +typedef uch FAR uchf;
9456 +typedef unsigned short ush;
9457 +typedef ush FAR ushf;
9458 +typedef unsigned long ulg;
9459 +
9460 +extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
9461 +/* (size given to avoid silly warnings with Visual C++) */
9462 +
9463 +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
9464 +
9465 +#define ERR_RETURN(strm,err) \
9466 + return (strm->msg = ERR_MSG(err), (err))
9467 +/* To be used only when the state is known to be valid */
9468 +
9469 + /* common constants */
9470 +
9471 +#ifndef DEF_WBITS
9472 +# define DEF_WBITS MAX_WBITS
9473 +#endif
9474 +/* default windowBits for decompression. MAX_WBITS is for compression only */
9475 +
9476 +#if MAX_MEM_LEVEL >= 8
9477 +# define DEF_MEM_LEVEL 8
9478 +#else
9479 +# define DEF_MEM_LEVEL MAX_MEM_LEVEL
9480 +#endif
9481 +/* default memLevel */
9482 +
9483 +#define STORED_BLOCK 0
9484 +#define STATIC_TREES 1
9485 +#define DYN_TREES 2
9486 +/* The three kinds of block type */
9487 +
9488 +#define MIN_MATCH 3
9489 +#define MAX_MATCH 258
9490 +/* The minimum and maximum match lengths */
9491 +
9492 +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
9493 +
9494 + /* target dependencies */
9495 +
9496 +#ifdef MSDOS
9497 +# define OS_CODE 0x00
9498 +# if defined(__TURBOC__) || defined(__BORLANDC__)
9499 +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
9500 + /* Allow compilation with ANSI keywords only enabled */
9501 + void _Cdecl farfree( void *block );
9502 + void *_Cdecl farmalloc( unsigned long nbytes );
9503 +# else
9504 +# include <alloc.h>
9505 +# endif
9506 +# else /* MSC or DJGPP */
9507 +# include <malloc.h>
9508 +# endif
9509 +#endif
9510 +
9511 +#ifdef OS2
9512 +# define OS_CODE 0x06
9513 +#endif
9514 +
9515 +#ifdef WIN32 /* Window 95 & Windows NT */
9516 +# define OS_CODE 0x0b
9517 +#endif
9518 +
9519 +#if defined(VAXC) || defined(VMS)
9520 +# define OS_CODE 0x02
9521 +# define F_OPEN(name, mode) \
9522 + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
9523 +#endif
9524 +
9525 +#ifdef AMIGA
9526 +# define OS_CODE 0x01
9527 +#endif
9528 +
9529 +#if defined(ATARI) || defined(atarist)
9530 +# define OS_CODE 0x05
9531 +#endif
9532 +
9533 +#if defined(MACOS) || defined(TARGET_OS_MAC)
9534 +# define OS_CODE 0x07
9535 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
9536 +# include <unix.h> /* for fdopen */
9537 +# else
9538 +# ifndef fdopen
9539 +# define fdopen(fd,mode) NULL /* No fdopen() */
9540 +# endif
9541 +# endif
9542 +#endif
9543 +
9544 +#ifdef __50SERIES /* Prime/PRIMOS */
9545 +# define OS_CODE 0x0F
9546 +#endif
9547 +
9548 +#ifdef TOPS20
9549 +# define OS_CODE 0x0a
9550 +#endif
9551 +
9552 +#if defined(_BEOS_) || defined(RISCOS)
9553 +# define fdopen(fd,mode) NULL /* No fdopen() */
9554 +#endif
9555 +
9556 +#if (defined(_MSC_VER) && (_MSC_VER > 600))
9557 +# define fdopen(fd,type) _fdopen(fd,type)
9558 +#endif
9559 +
9560 +
9561 + /* Common defaults */
9562 +
9563 +#ifndef OS_CODE
9564 +# define OS_CODE 0x03 /* assume Unix */
9565 +#endif
9566 +
9567 +#ifndef F_OPEN
9568 +# define F_OPEN(name, mode) fopen((name), (mode))
9569 +#endif
9570 +
9571 + /* functions */
9572 +
9573 +#ifdef HAVE_STRERROR
9574 + extern char *strerror OF((int));
9575 +# define zstrerror(errnum) strerror(errnum)
9576 +#else
9577 +# define zstrerror(errnum) ""
9578 +#endif
9579 +
9580 +#if defined(pyr)
9581 +# define NO_MEMCPY
9582 +#endif
9583 +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
9584 + /* Use our own functions for small and medium model with MSC <= 5.0.
9585 + * You may have to use the same strategy for Borland C (untested).
9586 + * The __SC__ check is for Symantec.
9587 + */
9588 +# define NO_MEMCPY
9589 +#endif
9590 +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
9591 +# define HAVE_MEMCPY
9592 +#endif
9593 +#ifdef HAVE_MEMCPY
9594 +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
9595 +# define zmemcpy _fmemcpy
9596 +# define zmemcmp _fmemcmp
9597 +# define zmemzero(dest, len) _fmemset(dest, 0, len)
9598 +# else
9599 +# define zmemcpy memcpy
9600 +# define zmemcmp memcmp
9601 +# define zmemzero(dest, len) memset(dest, 0, len)
9602 +# endif
9603 +#else
9604 + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
9605 + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
9606 + extern void zmemzero OF((Bytef* dest, uInt len));
9607 +#endif
9608 +
9609 +/* Diagnostic functions */
9610 +#ifdef DEBUG
9611 +# include <stdio.h>
9612 + extern int z_verbose;
9613 + extern void z_error OF((char *m));
9614 +# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
9615 +# define Trace(x) {if (z_verbose>=0) fprintf x ;}
9616 +# define Tracev(x) {if (z_verbose>0) fprintf x ;}
9617 +# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
9618 +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
9619 +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
9620 +#else
9621 +# define Assert(cond,msg)
9622 +# define Trace(x)
9623 +# define Tracev(x)
9624 +# define Tracevv(x)
9625 +# define Tracec(c,x)
9626 +# define Tracecv(c,x)
9627 +#endif
9628 +
9629 +
9630 +typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
9631 + uInt len));
9632 +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
9633 +void zcfree OF((voidpf opaque, voidpf ptr));
9634 +
9635 +#define ZALLOC(strm, items, size) \
9636 + (*((strm)->zalloc))((strm)->opaque, (items), (size))
9637 +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
9638 +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
9639 +
9640 +#endif /* _Z_UTIL_H */
9641 --- swan26/net/Kconfig.preipsec 2005-09-01 18:15:19.000000000 -0400
9642 +++ swan26/net/Kconfig 2005-09-03 16:51:17.000000000 -0400
9643 @@ -215,2 +215,6 @@
9644
9645 +if INET
9646 +source "net/ipsec/Kconfig"
9647 +endif # if INET
9648 +
9649 endif # if NET
9650 --- /distros/kernel/linux-2.6.3-rc4/net/Makefile Mon Feb 16 21:22:12 2004
9651 +++ ref26/net/Makefile Thu Feb 19 21:02:25 2004
9652 @@ -42,3 +42,6 @@
9653 ifeq ($(CONFIG_NET),y)
9654 obj-$(CONFIG_SYSCTL) += sysctl_net.o
9655 endif
9656 +
9657 +obj-$(CONFIG_KLIPS) += ipsec/
9658 +
9659 --- /dev/null Tue Mar 11 13:02:56 2003
9660 +++ linux/net/ipsec/Kconfig Mon Feb 9 13:51:03 2004
9661 @@ -0,0 +1,143 @@
9662 +#
9663 +# IPSEC configuration
9664 +# Copyright (C) 2004 Michael Richardson <mcr@freeswan.org>
9665 +#
9666 +# This program is free software; you can redistribute it and/or modify it
9667 +# under the terms of the GNU General Public License as published by the
9668 +# Free Software Foundation; either version 2 of the License, or (at your
9669 +# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9670 +#
9671 +# This program is distributed in the hope that it will be useful, but
9672 +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9673 +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9674 +# for more details.
9675 +#
9676 +
9677 +config KLIPS
9678 + tristate "Openswan IPsec (KLIPS)"
9679 + default n
9680 +# depends on NF_CONNTRACK && NETFILTER
9681 + help
9682 + KLIPS is the Openswan (www.openswan.org) Kernel Level IP Security
9683 + system. It is extensively tested, and has interoperated with
9684 + many other systems.
9685 + It provides "ipsecX" devices on which one can do firewalling.
9686 + The Openswan userland, is compatible with both KLIPS and NETKEY
9687 + You cannot build KLIPS and NETKEY inline into the kernel.
9688 +
9689 +menu "KLIPS options"
9690 + depends on KLIPS
9691 +
9692 +config KLIPS_ESP
9693 + bool 'Encapsulating Security Payload - ESP ("VPN")'
9694 + default y
9695 + help
9696 + This option provides support for the IPSEC Encapsulation Security
9697 + Payload (IP protocol 50) which provides packet layer content
9698 + hiding, and content authentication.
9699 + It is recommended to enable this. RFC2406
9700 +
9701 +config KLIPS_AH
9702 + bool 'Authentication Header - AH'
9703 + default n
9704 + help
9705 + This option provides support for the IPSEC Authentication Header
9706 + (IP protocol 51) which provides packet layer sender and content
9707 + authentication. It does not provide for confidentiality.
9708 + It is not recommended to enable this. RFC2402
9709 +
9710 +config KLIPS_AUTH_HMAC_MD5
9711 + bool 'HMAC-MD5 authentication algorithm'
9712 + default y
9713 + help
9714 + The HMAC-MD5 algorithm is used by ESP (and AH) to guarantee packet
9715 + integrity. There is little reason not to include it.
9716 +
9717 +config KLIPS_AUTH_HMAC_SHA1
9718 + bool 'HMAC-SHA1 authentication algorithm'
9719 + default y
9720 + help
9721 + The HMAC-SHA1 algorithm is used by ESP (and AH) to guarantee packet
9722 + integrity. SHA1 is a little slower than MD5, but is said to be
9723 + a bit more secure. There is little reason not to include it.
9724 +
9725 +config KLIPS_ALG
9726 + bool 'KLIPS_ALG software encryption'
9727 + default y
9728 + help
9729 + This option provides support for loading new algorithms into the
9730 + kernel for crypto use. You may disable this if using the
9731 + CONFIG_KLIPS_OCF option for hardware offload.
9732 +
9733 +config KLIPS_ENC_CRYPTOAPI
9734 + bool 'CryptoAPI algorithm interface'
9735 + default n
9736 + depends on KLIPS_ALG
9737 + help
9738 + Enable the algorithm interface to make all CryptoAPI 1.0 algorithms
9739 + available to KLIPS.
9740 +
9741 +config KLIPS_ENC_1DES
9742 + bool 'Include 1DES with CryptoAPI'
9743 + default n
9744 + depends on KLIPS_ENC_CRYPTOAPI
9745 + help
9746 + The CryptoAPI interface does not include support for every algorithm
9747 + yet, and one that it doesn't support by default is the VERY WEAK
9748 + 1DES. Select this if you are terminally stupid.
9749 +
9750 +config KLIPS_ENC_3DES
9751 + bool '3DES encryption algorithm'
9752 + default y
9753 + help
9754 + The 3DES algorithm is used by ESP to provide for packet privacy.
9755 + 3DES is 3-repeats of the DES algorithm. 3DES is widely supported,
9756 + and analyzed and is considered very secure. 1DES is not supported.
9757 +
9758 +config KLIPS_ENC_AES
9759 + bool 'AES encryption algorithm'
9760 + default y
9761 + depends on KLIPS_ALG
9762 + help
9763 + The AES algorithm is used by ESP to provide for packet privacy.
9764 + AES the NIST replacement for DES. AES is being widely analyzed,
9765 + and is very fast.
9766 +
9767 +config KLIPS_IPCOMP
9768 + bool 'IP compression'
9769 + default y
9770 + help
9771 + The IPcomp protocol is used prior to ESP to make the packet
9772 + smaller. Once encrypted, compression will fail, so any link
9773 + layer efforts (e.g. PPP) will not work.
9774 +
9775 +config KLIPS_OCF
9776 + bool 'IPsec OCF Acceleration Support'
9777 + default n
9778 + help
9779 + OCF provides Asynchronous crypto acceleration for kernel and
9780 + user applications. It supports various HW accelerators.
9781 + If you have OCF support enabled and wish IPsec to utilise
9782 + the hardware managed by OCF, then enable this option.
9783 + OCF is a kernel patch, see http://ocf-linux.sourceforge.net/
9784 +
9785 +config KLIPS_DEBUG
9786 + bool 'IPsec debugging'
9787 + default y
9788 + help
9789 + KLIPS includes a lot of debugging code. Unless there is a real
9790 + tangible benefit to removing this code, it should be left in place.
9791 + Debugging connections without access to kernel level debugging is
9792 + essentially impossible. Leave this on.
9793 +
9794 +config KLIPS_IF_MAX
9795 + int 'Maximum number of virtual interfaces'
9796 + default 64
9797 + range 4 256
9798 + help
9799 + KLIPS creates virtual interfaces for tunnel purposes. At present
9800 + it keeps track of certain items in an array (FIX ME), and needs
9801 + to preallocate this array. Only a pointer is used per item.
9802 +
9803 +endmenu
9804 +
9805 --- /dev/null Tue Mar 11 13:02:56 2003
9806 +++ linux/net/ipsec/Makefile Mon Feb 9 13:51:03 2004
9807 @@ -0,0 +1,192 @@
9808 +# Makefile for KLIPS kernel code as a module for 2.6 kernels
9809 +#
9810 +# Makefile for KLIPS kernel code as a module
9811 +# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
9812 +# Copyright (C) 2002-2004 Michael Richardson <mcr@freeswan.org>
9813 +#
9814 +# This program is free software; you can redistribute it and/or modify it
9815 +# under the terms of the GNU General Public License as published by the
9816 +# Free Software Foundation; either version 2 of the License, or (at your
9817 +# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9818 +#
9819 +# This program is distributed in the hope that it will be useful, but
9820 +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9821 +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9822 +# for more details.
9823 +#
9824 +# RCSID $Id: Makefile.fs2_6,v 1.8.2.1 2006/04/20 16:33:06 mcr Exp $
9825 +#
9826 +# Note! Dependencies are done automagically by 'make dep', which also
9827 +# removes any old dependencies. DON'T put your own dependencies here
9828 +# unless it's something special (ie not a .c file).
9829 +#
9830 +
9831 +OPENSWANSRCDIR?=.
9832 +KLIPS_TOP?=.
9833 +
9834 +-include ${OPENSWANSRCDIR}/Makefile.ver
9835 +
9836 +base-klips-objs :=
9837 +
9838 +base-klips-objs+= ipsec_init.o ipsec_sa.o ipsec_radij.o radij.o
9839 +base-klips-objs+= ipsec_life.o ipsec_proc.o
9840 +base-klips-objs+= ipsec_tunnel.o ipsec_xmit.o ipsec_rcv.o ipsec_ipip.o
9841 +base-klips-objs+= ipsec_snprintf.o
9842 +base-klips-objs+= ipsec_mast.o
9843 +base-klips-objs+= sysctl_net_ipsec.o
9844 +base-klips-objs+= pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o
9845 +base-klips-objs+= version.o
9846 +
9847 +base-klips-objs+= satot.o
9848 +base-klips-objs+= addrtot.o
9849 +base-klips-objs+= ultot.o
9850 +base-klips-objs+= addrtypeof.o
9851 +base-klips-objs+= anyaddr.o
9852 +base-klips-objs+= initaddr.o
9853 +base-klips-objs+= ultoa.o
9854 +base-klips-objs+= addrtoa.o
9855 +base-klips-objs+= subnettoa.o
9856 +base-klips-objs+= subnetof.o
9857 +base-klips-objs+= goodmask.o
9858 +base-klips-objs+= datatot.o
9859 +base-klips-objs+= rangetoa.o
9860 +base-klips-objs+= prng.o
9861 +base-klips-objs+= pfkey_v2_parse.o
9862 +base-klips-objs+= pfkey_v2_build.o
9863 +base-klips-objs+= pfkey_v2_debug.o
9864 +base-klips-objs+= pfkey_v2_ext_bits.o
9865 +base-klips-objs+= version.o
9866 +
9867 +obj-${CONFIG_KLIPS} += ipsec.o
9868 +
9869 +ipsec-objs += ${base-klips-objs}
9870 +
9871 +ipsec-$(CONFIG_KLIPS_ESP) += ipsec_esp.o
9872 +ipsec-$(CONFIG_KLIPS_OCF) += ipsec_ocf.o
9873 +ipsec-$(CONFIG_KLIPS_IPCOMP) += ipsec_ipcomp.o
9874 +ipsec-$(CONFIG_KLIPS_AUTH_HMAC_MD5) += ipsec_md5c.o
9875 +ipsec-$(CONFIG_KLIPS_AUTH_HMAC_SHA1) += ipsec_sha1.o
9876 +
9877 +# AH, if you really think you need it.
9878 +ipsec-$(CONFIG_KLIPS_AH) += ipsec_ah.o
9879 +
9880 +ipsec-$(CONFIG_KLIPS_ALG) += ipsec_alg.o
9881 +
9882 +# include code from DES subdir
9883 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/ipsec_alg_3des.o
9884 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/cbc_enc.o
9885 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/ecb_enc.o
9886 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/set_key.o
9887 +
9888 +ifeq ($(strip ${SUBARCH}),)
9889 +SUBARCH:=${ARCH}
9890 +endif
9891 +
9892 +# the assembly version expects frame pointers, which are
9893 +# optional in many kernel builds. If you want speed, you should
9894 +# probably use cryptoapi code instead.
9895 +USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
9896 +ifeq (${USEASSEMBLY},i386y)
9897 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/dx86unix.o
9898 +else
9899 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/des_enc.o
9900 +endif
9901 +
9902 +# include code from AES subdir
9903 +crypto-$(CONFIG_KLIPS_ENC_AES) += aes/ipsec_alg_aes.o
9904 +crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes_xcbc_mac.o
9905 +crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes_cbc.o
9906 +
9907 +ifeq ($(strip ${SUBARCH}),)
9908 +SUBARCH:=${ARCH}
9909 +endif
9910 +
9911 +USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
9912 +ifeq (${USEASSEMBLY},i386y)
9913 +crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes-i586.o
9914 +else
9915 +crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes.o
9916 +endif
9917 +
9918 +ipsec-y += ${crypto-y}
9919 +
9920 +ipsec-$(CONFIG_KLIPS_ENC_CRYPTOAPI) += ipsec_alg_cryptoapi.o
9921 +
9922 +# IPcomp stuff
9923 +base-ipcomp-objs := ipcomp.o
9924 +base-ipcomp-objs += adler32.o
9925 +base-ipcomp-objs += deflate.o
9926 +base-ipcomp-objs += infblock.o
9927 +base-ipcomp-objs += infcodes.o
9928 +base-ipcomp-objs += inffast.o
9929 +base-ipcomp-objs += inflate.o
9930 +base-ipcomp-objs += inftrees.o
9931 +base-ipcomp-objs += infutil.o
9932 +base-ipcomp-objs += trees.o
9933 +base-ipcomp-objs += zutil.o
9934 +asm-ipcomp-obj-$(CONFIG_M586) += match586.o
9935 +asm-ipcomp-obj-$(CONFIG_M586TSC) += match586.o
9936 +asm-ipcomp-obj-$(CONFIG_M586MMX) += match586.o
9937 +asm-ipcomp-obj-$(CONFIG_M686) += match686.o
9938 +asm-ipcomp-obj-$(CONFIG_MPENTIUMIII) += match686.o
9939 +asm-ipcomp-obj-$(CONFIG_MPENTIUM4) += match686.o
9940 +asm-ipcomp-obj-$(CONFIG_MK6) += match586.o
9941 +asm-ipcomp-obj-$(CONFIG_MK7) += match686.o
9942 +asm-ipcomp-obj-$(CONFIG_MCRUSOE) += match586.o
9943 +asm-ipcomp-obj-$(CONFIG_MWINCHIPC6) += match586.o
9944 +asm-ipcomp-obj-$(CONFIG_MWINCHIP2) += match686.o
9945 +asm-ipcomp-obj-$(CONFIG_MWINCHIP3D) += match686.o
9946 +base-ipcomp-objs += ${asm-ipcomp-obj-y}
9947 +
9948 +ipsec-$(CONFIG_KLIPS_IPCOMP) += ${base-ipcomp-objs}
9949 +
9950 +EXTRA_CFLAGS += -DIPCOMP_PREFIX -DKLIPS
9951 +EXTRA_CFLAGS += -Icrypto/ocf
9952 +
9953 +#
9954 +# $Log: Makefile.fs2_6,v $
9955 +# Revision 1.8.2.1 2006/04/20 16:33:06 mcr
9956 +# remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
9957 +# Fix in-kernel module compilation. Sub-makefiles do not work.
9958 +#
9959 +# Revision 1.8 2005/05/11 03:15:42 mcr
9960 +# adjusted makefiles to sanely build modules properly.
9961 +#
9962 +# Revision 1.7 2005/04/13 22:52:12 mcr
9963 +# moved KLIPS specific snprintf() wrapper to seperate file.
9964 +#
9965 +# Revision 1.6 2004/08/22 05:02:03 mcr
9966 +# organized symbols such that it is easier to build modules.
9967 +#
9968 +# Revision 1.5 2004/08/18 01:43:56 mcr
9969 +# adjusted makefile enumation so that it can be used by module
9970 +# wrapper.
9971 +#
9972 +# Revision 1.4 2004/08/17 03:27:23 mcr
9973 +# klips 2.6 edits.
9974 +#
9975 +# Revision 1.3 2004/08/04 16:50:13 mcr
9976 +# removed duplicate definition of dx86unix.o
9977 +#
9978 +# Revision 1.2 2004/08/03 18:21:09 mcr
9979 +# only set KLIPS_TOP and OPENSWANSRCDIR if not already set.
9980 +#
9981 +# Revision 1.1 2004/07/26 15:02:22 mcr
9982 +# makefile for KLIPS module for 2.6.
9983 +#
9984 +# Revision 1.3 2004/02/24 17:17:04 mcr
9985 +# s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
9986 +# turn it on/off as well.
9987 +#
9988 +# Revision 1.2 2004/02/22 06:50:42 mcr
9989 +# kernel 2.6 port - merged with 2.4 code.
9990 +#
9991 +# Revision 1.1.2.1 2004/02/20 02:07:53 mcr
9992 +# module configuration for KLIPS 2.6
9993 +#
9994 +#
9995 +# Local Variables:
9996 +# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
9997 +# End Variables:
9998 +#
9999 +
10000 --- /dev/null Tue Mar 11 13:02:56 2003
10001 +++ linux/net/ipsec/README-zlib Mon Feb 9 13:51:03 2004
10002 @@ -0,0 +1,147 @@
10003 +zlib 1.1.4 is a general purpose data compression library. All the code
10004 +is thread safe. The data format used by the zlib library
10005 +is described by RFCs (Request for Comments) 1950 to 1952 in the files
10006 +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
10007 +format) and rfc1952.txt (gzip format). These documents are also available in
10008 +other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
10009 +
10010 +All functions of the compression library are documented in the file zlib.h
10011 +(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
10012 +example of the library is given in the file example.c which also tests that
10013 +the library is working correctly. Another example is given in the file
10014 +minigzip.c. The compression library itself is composed of all source files
10015 +except example.c and minigzip.c.
10016 +
10017 +To compile all files and run the test program, follow the instructions
10018 +given at the top of Makefile. In short "make test; make install"
10019 +should work for most machines. For Unix: "./configure; make test; make install"
10020 +For MSDOS, use one of the special makefiles such as Makefile.msc.
10021 +For VMS, use Make_vms.com or descrip.mms.
10022 +
10023 +Questions about zlib should be sent to <zlib@gzip.org>, or to
10024 +Gilles Vollant <info@winimage.com> for the Windows DLL version.
10025 +The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
10026 +Before reporting a problem, please check this site to verify that
10027 +you have the latest version of zlib; otherwise get the latest version and
10028 +check whether the problem still exists or not.
10029 +
10030 +PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
10031 +before asking for help.
10032 +
10033 +Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
10034 +issue of Dr. Dobb's Journal; a copy of the article is available in
10035 +http://dogma.net/markn/articles/zlibtool/zlibtool.htm
10036 +
10037 +The changes made in version 1.1.4 are documented in the file ChangeLog.
10038 +The only changes made since 1.1.3 are bug corrections:
10039 +
10040 +- ZFREE was repeated on same allocation on some error conditions.
10041 + This creates a security problem described in
10042 + http://www.zlib.org/advisory-2002-03-11.txt
10043 +- Returned incorrect error (Z_MEM_ERROR) on some invalid data
10044 +- Avoid accesses before window for invalid distances with inflate window
10045 + less than 32K.
10046 +- force windowBits > 8 to avoid a bug in the encoder for a window size
10047 + of 256 bytes. (A complete fix will be available in 1.1.5).
10048 +
10049 +The beta version 1.1.5beta includes many more changes. A new official
10050 +version 1.1.5 will be released as soon as extensive testing has been
10051 +completed on it.
10052 +
10053 +
10054 +Unsupported third party contributions are provided in directory "contrib".
10055 +
10056 +A Java implementation of zlib is available in the Java Development Kit
10057 +http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
10058 +See the zlib home page http://www.zlib.org for details.
10059 +
10060 +A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
10061 +is in the CPAN (Comprehensive Perl Archive Network) sites
10062 +http://www.cpan.org/modules/by-module/Compress/
10063 +
10064 +A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
10065 +is available in Python 1.5 and later versions, see
10066 +http://www.python.org/doc/lib/module-zlib.html
10067 +
10068 +A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
10069 +is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
10070 +
10071 +An experimental package to read and write files in .zip format,
10072 +written on top of zlib by Gilles Vollant <info@winimage.com>, is
10073 +available at http://www.winimage.com/zLibDll/unzip.html
10074 +and also in the contrib/minizip directory of zlib.
10075 +
10076 +
10077 +Notes for some targets:
10078 +
10079 +- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
10080 + and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
10081 + The zlib DLL support was initially done by Alessandro Iacopetti and is
10082 + now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
10083 + home page at http://www.winimage.com/zLibDll
10084 +
10085 + From Visual Basic, you can call the DLL functions which do not take
10086 + a structure as argument: compress, uncompress and all gz* functions.
10087 + See contrib/visual-basic.txt for more information, or get
10088 + http://www.tcfb.com/dowseware/cmp-z-it.zip
10089 +
10090 +- For 64-bit Irix, deflate.c must be compiled without any optimization.
10091 + With -O, one libpng test fails. The test works in 32 bit mode (with
10092 + the -n32 compiler flag). The compiler bug has been reported to SGI.
10093 +
10094 +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1
10095 + it works when compiled with cc.
10096 +
10097 +- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
10098 + is necessary to get gzprintf working correctly. This is done by configure.
10099 +
10100 +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
10101 + with other compilers. Use "make test" to check your compiler.
10102 +
10103 +- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
10104 +
10105 +- For Turbo C the small model is supported only with reduced performance to
10106 + avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
10107 +
10108 +- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
10109 + Per Harald Myrvang <perm@stud.cs.uit.no>
10110 +
10111 +
10112 +Acknowledgments:
10113 +
10114 + The deflate format used by zlib was defined by Phil Katz. The deflate
10115 + and zlib specifications were written by L. Peter Deutsch. Thanks to all the
10116 + people who reported problems and suggested various improvements in zlib;
10117 + they are too numerous to cite here.
10118 +
10119 +Copyright notice:
10120 +
10121 + (C) 1995-2002 Jean-loup Gailly and Mark Adler
10122 +
10123 + This software is provided 'as-is', without any express or implied
10124 + warranty. In no event will the authors be held liable for any damages
10125 + arising from the use of this software.
10126 +
10127 + Permission is granted to anyone to use this software for any purpose,
10128 + including commercial applications, and to alter it and redistribute it
10129 + freely, subject to the following restrictions:
10130 +
10131 + 1. The origin of this software must not be misrepresented; you must not
10132 + claim that you wrote the original software. If you use this software
10133 + in a product, an acknowledgment in the product documentation would be
10134 + appreciated but is not required.
10135 + 2. Altered source versions must be plainly marked as such, and must not be
10136 + misrepresented as being the original software.
10137 + 3. This notice may not be removed or altered from any source distribution.
10138 +
10139 + Jean-loup Gailly Mark Adler
10140 + jloup@gzip.org madler@alumni.caltech.edu
10141 +
10142 +If you use the zlib library in a product, we would appreciate *not*
10143 +receiving lengthy legal documents to sign. The sources are provided
10144 +for free but without warranty of any kind. The library has been
10145 +entirely written by Jean-loup Gailly and Mark Adler; it does not
10146 +include third-party code.
10147 +
10148 +If you redistribute modified sources, we would appreciate that you include
10149 +in the file ChangeLog history information documenting your changes.
10150 --- /dev/null Tue Mar 11 13:02:56 2003
10151 +++ linux/net/ipsec/README-zlib.freeswan Mon Feb 9 13:51:03 2004
10152 @@ -0,0 +1,13 @@
10153 +The only changes made to these files for use in FreeS/WAN are:
10154 +
10155 + - In zconf.h, macros are defined to prefix global symbols with "ipcomp_"
10156 + (or "_ipcomp"), when compiled with -DIPCOMP_PREFIX.
10157 + - The copyright strings are defined local (static)
10158 +
10159 + The above changes are made to avoid name collisions with ppp_deflate
10160 + and ext2compr.
10161 +
10162 + - Files not needed for FreeS/WAN have been removed
10163 +
10164 + See the "README" file for information about where to obtain the complete
10165 + zlib package.
10166 --- /dev/null Tue Mar 11 13:02:56 2003
10167 +++ linux/net/ipsec/addrtoa.c Mon Feb 9 13:51:03 2004
10168 @@ -0,0 +1,67 @@
10169 +/*
10170 + * addresses to ASCII
10171 + * Copyright (C) 1998, 1999 Henry Spencer.
10172 + *
10173 + * This library is free software; you can redistribute it and/or modify it
10174 + * under the terms of the GNU Library General Public License as published by
10175 + * the Free Software Foundation; either version 2 of the License, or (at your
10176 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10177 + *
10178 + * This library is distributed in the hope that it will be useful, but
10179 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10180 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10181 + * License for more details.
10182 + *
10183 + * RCSID $Id: addrtoa.c,v 1.10 2004/07/10 07:43:47 mcr Exp $
10184 + */
10185 +#include "openswan.h"
10186 +
10187 +#define NBYTES 4 /* bytes in an address */
10188 +#define PERBYTE 4 /* three digits plus a dot or NUL */
10189 +#define BUFLEN (NBYTES*PERBYTE)
10190 +
10191 +#if BUFLEN != ADDRTOA_BUF
10192 +#error "ADDRTOA_BUF in openswan.h inconsistent with addrtoa() code"
10193 +#endif
10194 +
10195 +/*
10196 + - addrtoa - convert binary address to ASCII dotted decimal
10197 + */
10198 +size_t /* space needed for full conversion */
10199 +addrtoa(addr, format, dst, dstlen)
10200 +struct in_addr addr;
10201 +int format; /* character */
10202 +char *dst; /* need not be valid if dstlen is 0 */
10203 +size_t dstlen;
10204 +{
10205 + unsigned long a = ntohl(addr.s_addr);
10206 + int i;
10207 + size_t n;
10208 + unsigned long byte;
10209 + char buf[BUFLEN];
10210 + char *p;
10211 +
10212 + switch (format) {
10213 + case 0:
10214 + break;
10215 + default:
10216 + return 0;
10217 + break;
10218 + }
10219 +
10220 + p = buf;
10221 + for (i = NBYTES-1; i >= 0; i--) {
10222 + byte = (a >> (i*8)) & 0xff;
10223 + p += ultoa(byte, 10, p, PERBYTE);
10224 + if (i != 0)
10225 + *(p-1) = '.';
10226 + }
10227 + n = p - buf;
10228 +
10229 + if (dstlen > 0) {
10230 + if (n > dstlen)
10231 + buf[dstlen - 1] = '\0';
10232 + strcpy(dst, buf);
10233 + }
10234 + return n;
10235 +}
10236 --- /dev/null Tue Mar 11 13:02:56 2003
10237 +++ linux/net/ipsec/addrtot.c Mon Feb 9 13:51:03 2004
10238 @@ -0,0 +1,344 @@
10239 +/*
10240 + * addresses to text
10241 + * Copyright (C) 2000 Henry Spencer.
10242 + *
10243 + * This library is free software; you can redistribute it and/or modify it
10244 + * under the terms of the GNU Library General Public License as published by
10245 + * the Free Software Foundation; either version 2 of the License, or (at your
10246 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10247 + *
10248 + * This library is distributed in the hope that it will be useful, but
10249 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10250 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10251 + * License for more details.
10252 + *
10253 + */
10254 +
10255 +#if defined(__KERNEL__) && defined(__HAVE_ARCH_STRSTR)
10256 +#include <linux/string.h>
10257 +#endif
10258 +
10259 +#include "openswan.h"
10260 +
10261 +#define IP4BYTES 4 /* bytes in an IPv4 address */
10262 +#define PERBYTE 4 /* three digits plus a dot or NUL */
10263 +#define IP6BYTES 16 /* bytes in an IPv6 address */
10264 +
10265 +/* forwards */
10266 +static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp);
10267 +static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp, int squish);
10268 +static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp);
10269 +static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp);
10270 +
10271 +#if defined(__KERNEL__) && !defined(__HAVE_ARCH_STRSTR)
10272 +#define strstr ipsec_strstr
10273 +/*
10274 + * Find the first occurrence of find in s.
10275 + * (from NetBSD 1.6's /src/lib/libc/string/strstr.c)
10276 + */
10277 +
10278 +static char *
10279 +ipsec_strstr(s, find)
10280 + const char *s, *find;
10281 +{
10282 + char c, sc;
10283 + size_t len;
10284 +
10285 + if ((c = *find++) != 0) {
10286 + len = strlen(find);
10287 + do {
10288 + do {
10289 + if ((sc = *s++) == 0)
10290 + return (NULL);
10291 + } while (sc != c);
10292 + } while (strncmp(s, find, len) != 0);
10293 + s--;
10294 + }
10295 + /* LINTED interface specification */
10296 + return ((char *)s);
10297 +}
10298 +#endif
10299 +
10300 +/*
10301 + - addrtot - convert binary address to text (dotted decimal or IPv6 string)
10302 + */
10303 +size_t /* space needed for full conversion */
10304 +addrtot(src, format, dst, dstlen)
10305 +const ip_address *src;
10306 +int format; /* character */
10307 +char *dst; /* need not be valid if dstlen is 0 */
10308 +size_t dstlen;
10309 +{
10310 + const unsigned char *b;
10311 + size_t n;
10312 + char buf[1+ADDRTOT_BUF+1]; /* :address: */
10313 + char *p;
10314 + int t = addrtypeof(src);
10315 +# define TF(t, f) (((t)<<8) | (f))
10316 +
10317 + n = addrbytesptr(src, &b);
10318 + if (n == 0) {
10319 + bad:
10320 + dst[0]='\0';
10321 + strncat(dst, "<invalid>", dstlen);
10322 + return sizeof("<invalid>");
10323 + }
10324 +
10325 + switch (TF(t, format)) {
10326 + case TF(AF_INET, 0):
10327 + n = normal4(b, n, buf, &p);
10328 + break;
10329 + case TF(AF_INET6, 0):
10330 + n = normal6(b, n, buf, &p, 1);
10331 + break;
10332 + case TF(AF_INET, 'Q'):
10333 + n = normal4(b, n, buf, &p);
10334 + break;
10335 + case TF(AF_INET6, 'Q'):
10336 + n = normal6(b, n, buf, &p, 0);
10337 + break;
10338 + case TF(AF_INET, 'r'):
10339 + n = reverse4(b, n, buf, &p);
10340 + break;
10341 + case TF(AF_INET6, 'r'):
10342 + n = reverse6(b, n, buf, &p);
10343 + break;
10344 + default: /* including (AF_INET, 'R') */
10345 + goto bad;
10346 + break;
10347 + }
10348 +
10349 + if (dstlen > 0) {
10350 + if (dstlen < n)
10351 + p[dstlen - 1] = '\0';
10352 + strcpy(dst, p);
10353 + }
10354 + return n;
10355 +}
10356 +
10357 +/*
10358 + - normal4 - normal IPv4 address-text conversion
10359 + */
10360 +static size_t /* size of text, including NUL */
10361 +normal4(srcp, srclen, buf, dstp)
10362 +const unsigned char *srcp;
10363 +size_t srclen;
10364 +char *buf; /* guaranteed large enough */
10365 +char **dstp; /* where to put result pointer */
10366 +{
10367 + int i;
10368 + char *p;
10369 +
10370 + if (srclen != IP4BYTES) /* "can't happen" */
10371 + return 0;
10372 + p = buf;
10373 + for (i = 0; i < IP4BYTES; i++) {
10374 + p += ultot(srcp[i], 10, p, PERBYTE);
10375 + if (i != IP4BYTES - 1)
10376 + *(p-1) = '.'; /* overwrites the NUL */
10377 + }
10378 + *dstp = buf;
10379 + return p - buf;
10380 +}
10381 +
10382 +/*
10383 + - normal6 - normal IPv6 address-text conversion
10384 + */
10385 +static size_t /* size of text, including NUL */
10386 +normal6(srcp, srclen, buf, dstp, squish)
10387 +const unsigned char *srcp;
10388 +size_t srclen;
10389 +char *buf; /* guaranteed large enough, plus 2 */
10390 +char **dstp; /* where to put result pointer */
10391 +int squish; /* whether to squish out 0:0 */
10392 +{
10393 + int i;
10394 + unsigned long piece;
10395 + char *p;
10396 + char *q;
10397 +
10398 + if (srclen != IP6BYTES) /* "can't happen" */
10399 + return 0;
10400 + p = buf;
10401 + *p++ = ':';
10402 + for (i = 0; i < IP6BYTES/2; i++) {
10403 + piece = (srcp[2*i] << 8) + srcp[2*i + 1];
10404 + p += ultot(piece, 16, p, 5); /* 5 = abcd + NUL */
10405 + *(p-1) = ':'; /* overwrites the NUL */
10406 + }
10407 + *p = '\0';
10408 + q = strstr(buf, ":0:0:");
10409 + if (squish && q != NULL) { /* zero squishing is possible */
10410 + p = q + 1;
10411 + while (*p == '0' && *(p+1) == ':')
10412 + p += 2;
10413 + q++;
10414 + *q++ = ':'; /* overwrite first 0 */
10415 + while (*p != '\0')
10416 + *q++ = *p++;
10417 + *q = '\0';
10418 + if (!(*(q-1) == ':' && *(q-2) == ':'))
10419 + *--q = '\0'; /* strip final : unless :: */
10420 + p = buf;
10421 + if (!(*p == ':' && *(p+1) == ':'))
10422 + p++; /* skip initial : unless :: */
10423 + } else {
10424 + q = p;
10425 + *--q = '\0'; /* strip final : */
10426 + p = buf + 1; /* skip initial : */
10427 + }
10428 + *dstp = p;
10429 + return q - p + 1;
10430 +}
10431 +
10432 +/*
10433 + - reverse4 - IPv4 reverse-lookup conversion
10434 + */
10435 +static size_t /* size of text, including NUL */
10436 +reverse4(srcp, srclen, buf, dstp)
10437 +const unsigned char *srcp;
10438 +size_t srclen;
10439 +char *buf; /* guaranteed large enough */
10440 +char **dstp; /* where to put result pointer */
10441 +{
10442 + int i;
10443 + char *p;
10444 +
10445 + if (srclen != IP4BYTES) /* "can't happen" */
10446 + return 0;
10447 + p = buf;
10448 + for (i = IP4BYTES-1; i >= 0; i--) {
10449 + p += ultot(srcp[i], 10, p, PERBYTE);
10450 + *(p-1) = '.'; /* overwrites the NUL */
10451 + }
10452 + strcpy(p, "IN-ADDR.ARPA.");
10453 + *dstp = buf;
10454 + return strlen(buf) + 1;
10455 +}
10456 +
10457 +/*
10458 + - reverse6 - IPv6 reverse-lookup conversion (RFC 1886)
10459 + * A trifle inefficient, really shouldn't use ultot...
10460 + */
10461 +static size_t /* size of text, including NUL */
10462 +reverse6(srcp, srclen, buf, dstp)
10463 +const unsigned char *srcp;
10464 +size_t srclen;
10465 +char *buf; /* guaranteed large enough */
10466 +char **dstp; /* where to put result pointer */
10467 +{
10468 + int i;
10469 + unsigned long piece;
10470 + char *p;
10471 +
10472 + if (srclen != IP6BYTES) /* "can't happen" */
10473 + return 0;
10474 + p = buf;
10475 + for (i = IP6BYTES-1; i >= 0; i--) {
10476 + piece = srcp[i];
10477 + p += ultot(piece&0xf, 16, p, 2);
10478 + *(p-1) = '.';
10479 + p += ultot(piece>>4, 16, p, 2);
10480 + *(p-1) = '.';
10481 + }
10482 + strcpy(p, "IP6.ARPA.");
10483 + *dstp = buf;
10484 + return strlen(buf) + 1;
10485 +}
10486 +
10487 +/*
10488 + - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874)
10489 + * this version removed as it was obsoleted in the end.
10490 + */
10491 +
10492 +#ifdef ADDRTOT_MAIN
10493 +
10494 +#include <stdio.h>
10495 +#include <sys/socket.h>
10496 +#include <netinet/in.h>
10497 +#include <arpa/inet.h>
10498 +
10499 +void regress(void);
10500 +
10501 +int
10502 +main(int argc, char *argv[])
10503 +{
10504 + if (argc < 2) {
10505 + fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
10506 + argv[0]);
10507 + exit(2);
10508 + }
10509 +
10510 + if (strcmp(argv[1], "-r") == 0) {
10511 + regress();
10512 + fprintf(stderr, "regress() returned?!?\n");
10513 + exit(1);
10514 + }
10515 + exit(0);
10516 +}
10517 +
10518 +struct rtab {
10519 + char *input;
10520 + char format;
10521 + char *output; /* NULL means error expected */
10522 +} rtab[] = {
10523 + {"1.2.3.0", 0, "1.2.3.0"},
10524 + {"1:2::3:4", 0, "1:2::3:4"},
10525 + {"1:2::3:4", 'Q', "1:2:0:0:0:0:3:4"},
10526 + {"1:2:0:0:3:4:0:0", 0, "1:2::3:4:0:0"},
10527 + {"1.2.3.4", 'r' , "4.3.2.1.IN-ADDR.ARPA."},
10528 + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f */
10529 + {"1:2::3:4", 'r', "4.0.0.0.3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.1.0.0.0.IP6.ARPA."},
10530 + {NULL, 0, NULL}
10531 +};
10532 +
10533 +void
10534 +regress()
10535 +{
10536 + struct rtab *r;
10537 + int status = 0;
10538 + ip_address a;
10539 + char in[100];
10540 + char buf[100];
10541 + const char *oops;
10542 + size_t n;
10543 +
10544 + for (r = rtab; r->input != NULL; r++) {
10545 + strcpy(in, r->input);
10546 +
10547 + /* convert it *to* internal format */
10548 + oops = ttoaddr(in, strlen(in), 0, &a);
10549 +
10550 + /* now convert it back */
10551 +
10552 + n = addrtot(&a, r->format, buf, sizeof(buf));
10553 +
10554 + if (n == 0 && r->output == NULL)
10555 + {} /* okay, error expected */
10556 +
10557 + else if (n == 0) {
10558 + printf("`%s' atoasr failed\n", r->input);
10559 + status = 1;
10560 +
10561 + } else if (r->output == NULL) {
10562 + printf("`%s' atoasr succeeded unexpectedly '%c'\n",
10563 + r->input, r->format);
10564 + status = 1;
10565 + } else {
10566 + if (strcasecmp(r->output, buf) != 0) {
10567 + printf("`%s' '%c' gave `%s', expected `%s'\n",
10568 + r->input, r->format, buf, r->output);
10569 + status = 1;
10570 + }
10571 + }
10572 + }
10573 + exit(status);
10574 +}
10575 +
10576 +#endif /* ADDRTOT_MAIN */
10577 +
10578 +/*
10579 + * Local variables:
10580 + * c-file-style: "linux"
10581 + * End:
10582 + */
10583 --- /dev/null Tue Mar 11 13:02:56 2003
10584 +++ linux/net/ipsec/addrtypeof.c Mon Feb 9 13:51:03 2004
10585 @@ -0,0 +1,123 @@
10586 +/*
10587 + * extract parts of an ip_address
10588 + * Copyright (C) 2000 Henry Spencer.
10589 + *
10590 + * This library is free software; you can redistribute it and/or modify it
10591 + * under the terms of the GNU Library General Public License as published by
10592 + * the Free Software Foundation; either version 2 of the License, or (at your
10593 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10594 + *
10595 + * This library is distributed in the hope that it will be useful, but
10596 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10597 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10598 + * License for more details.
10599 + *
10600 + * RCSID $Id: addrtypeof.c,v 1.10 2004/07/10 07:43:47 mcr Exp $
10601 + */
10602 +#include "openswan.h"
10603 +
10604 +/*
10605 + - addrtypeof - get the type of an ip_address
10606 + */
10607 +int
10608 +addrtypeof(src)
10609 +const ip_address *src;
10610 +{
10611 + return src->u.v4.sin_family;
10612 +}
10613 +
10614 +/*
10615 + - addrbytesptr - get pointer to the address bytes of an ip_address
10616 + */
10617 +size_t /* 0 for error */
10618 +addrbytesptr(src, dstp)
10619 +const ip_address *src;
10620 +const unsigned char **dstp; /* NULL means just a size query */
10621 +{
10622 + const unsigned char *p;
10623 + size_t n;
10624 +
10625 + switch (src->u.v4.sin_family) {
10626 + case AF_INET:
10627 + p = (const unsigned char *)&src->u.v4.sin_addr.s_addr;
10628 + n = 4;
10629 + break;
10630 + case AF_INET6:
10631 + p = (const unsigned char *)&src->u.v6.sin6_addr;
10632 + n = 16;
10633 + break;
10634 + default:
10635 + return 0;
10636 + break;
10637 + }
10638 +
10639 + if (dstp != NULL)
10640 + *dstp = p;
10641 + return n;
10642 +
10643 +}
10644 +/*
10645 + - addrbytesptr - get pointer to the address bytes of an ip_address
10646 + */
10647 +size_t /* 0 for error */
10648 +addrbytesptr_write(src, dstp)
10649 +ip_address *src;
10650 +unsigned char **dstp; /* NULL means just a size query */
10651 +{
10652 + unsigned char *p;
10653 + size_t n;
10654 +
10655 + switch (src->u.v4.sin_family) {
10656 + case AF_INET:
10657 + p = (unsigned char *)&src->u.v4.sin_addr.s_addr;
10658 + n = 4;
10659 + break;
10660 + case AF_INET6:
10661 + p = (unsigned char *)&src->u.v6.sin6_addr;
10662 + n = 16;
10663 + break;
10664 + default:
10665 + return 0;
10666 + break;
10667 + }
10668 +
10669 + if (dstp != NULL)
10670 + *dstp = p;
10671 + return n;
10672 +}
10673 +
10674 +/*
10675 + - addrlenof - get length of the address bytes of an ip_address
10676 + */
10677 +size_t /* 0 for error */
10678 +addrlenof(src)
10679 +const ip_address *src;
10680 +{
10681 + return addrbytesptr(src, NULL);
10682 +}
10683 +
10684 +/*
10685 + - addrbytesof - get the address bytes of an ip_address
10686 + */
10687 +size_t /* 0 for error */
10688 +addrbytesof(src, dst, dstlen)
10689 +const ip_address *src;
10690 +unsigned char *dst;
10691 +size_t dstlen;
10692 +{
10693 + const unsigned char *p;
10694 + size_t n;
10695 + size_t ncopy;
10696 +
10697 + n = addrbytesptr(src, &p);
10698 + if (n == 0)
10699 + return 0;
10700 +
10701 + if (dstlen > 0) {
10702 + ncopy = n;
10703 + if (ncopy > dstlen)
10704 + ncopy = dstlen;
10705 + memcpy(dst, p, ncopy);
10706 + }
10707 + return n;
10708 +}
10709 --- /dev/null Tue Mar 11 13:02:56 2003
10710 +++ linux/net/ipsec/adler32.c Mon Feb 9 13:51:03 2004
10711 @@ -0,0 +1,49 @@
10712 +/* adler32.c -- compute the Adler-32 checksum of a data stream
10713 + * Copyright (C) 1995-2002 Mark Adler
10714 + * For conditions of distribution and use, see copyright notice in zlib.h
10715 + */
10716 +
10717 +/* @(#) $Id: adler32.c,v 1.6 2004/07/10 19:11:18 mcr Exp $ */
10718 +
10719 +#include <zlib/zlib.h>
10720 +#include <zlib/zconf.h>
10721 +
10722 +#define BASE 65521L /* largest prime smaller than 65536 */
10723 +#define NMAX 5552
10724 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
10725 +
10726 +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
10727 +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
10728 +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
10729 +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
10730 +#define DO16(buf) DO8(buf,0); DO8(buf,8);
10731 +
10732 +/* ========================================================================= */
10733 +uLong ZEXPORT adler32(adler, buf, len)
10734 + uLong adler;
10735 + const Bytef *buf;
10736 + uInt len;
10737 +{
10738 + unsigned long s1 = adler & 0xffff;
10739 + unsigned long s2 = (adler >> 16) & 0xffff;
10740 + int k;
10741 +
10742 + if (buf == Z_NULL) return 1L;
10743 +
10744 + while (len > 0) {
10745 + k = len < NMAX ? len : NMAX;
10746 + len -= k;
10747 + while (k >= 16) {
10748 + DO16(buf);
10749 + buf += 16;
10750 + k -= 16;
10751 + }
10752 + if (k != 0) do {
10753 + s1 += *buf++;
10754 + s2 += s1;
10755 + } while (--k);
10756 + s1 %= BASE;
10757 + s2 %= BASE;
10758 + }
10759 + return (s2 << 16) | s1;
10760 +}
10761 --- /dev/null Tue Mar 11 13:02:56 2003
10762 +++ linux/net/ipsec/aes/Makefile Mon Feb 9 13:51:03 2004
10763 @@ -0,0 +1,56 @@
10764 +# Makefile for KLIPS 3DES kernel code as a module for 2.6 kernels
10765 +#
10766 +# Makefile for KLIPS kernel code as a module
10767 +# Copyright (C) 2002-2004 Michael Richardson <mcr@xelerance.com>
10768 +#
10769 +# This program is free software; you can redistribute it and/or modify it
10770 +# under the terms of the GNU General Public License as published by the
10771 +# Free Software Foundation; either version 2 of the License, or (at your
10772 +# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10773 +#
10774 +# This program is distributed in the hope that it will be useful, but
10775 +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10776 +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10777 +# for more details.
10778 +#
10779 +# RCSID $Id: Makefile.fs2_6,v 1.2 2005/08/12 14:13:58 mcr Exp $
10780 +#
10781 +# Note! Dependencies are done automagically by 'make dep', which also
10782 +# removes any old dependencies. DON'T put your own dependencies here
10783 +# unless it's something special (ie not a .c file).
10784 +#
10785 +
10786 +obj-$(CONFIG_KLIPS_ENC_AES) += ipsec_alg_aes.o
10787 +obj-$(CONFIG_KLIPS_ENC_AES) += aes_xcbc_mac.o
10788 +obj-$(CONFIG_KLIPS_ENC_AES) += aes_cbc.o
10789 +
10790 +ifeq ($(strip ${SUBARCH}),)
10791 +SUBARCH:=${ARCH}
10792 +endif
10793 +
10794 +# the assembly version expects frame pointers, which are
10795 +# optional in many kernel builds. If you want speed, you should
10796 +# probably use cryptoapi code instead.
10797 +USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
10798 +ifeq (${USEASSEMBLY},i386y)
10799 +obj-$(CONFIG_KLIPS_ENC_AES) += aes-i586.o
10800 +else
10801 +obj-$(CONFIG_KLIPS_ENC_AES) += aes.o
10802 +endif
10803 +
10804 +
10805 +#
10806 +# $Log: Makefile.fs2_6,v $
10807 +# Revision 1.2 2005/08/12 14:13:58 mcr
10808 +# do not use assembly code with there are no frame pointers,
10809 +# as it does not have the right linkages.
10810 +#
10811 +# Revision 1.1 2004/08/17 03:31:34 mcr
10812 +# klips 2.6 edits.
10813 +#
10814 +#
10815 +# Local Variables:
10816 +# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
10817 +# End Variables:
10818 +#
10819 +
10820 --- /dev/null Tue Mar 11 13:02:56 2003
10821 +++ linux/net/ipsec/aes/aes-i586.S Mon Feb 9 13:51:03 2004
10822 @@ -0,0 +1,892 @@
10823 +//
10824 +// Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
10825 +// All rights reserved.
10826 +//
10827 +// TERMS
10828 +//
10829 +// Redistribution and use in source and binary forms, with or without
10830 +// modification, are permitted subject to the following conditions:
10831 +//
10832 +// 1. Redistributions of source code must retain the above copyright
10833 +// notice, this list of conditions and the following disclaimer.
10834 +//
10835 +// 2. Redistributions in binary form must reproduce the above copyright
10836 +// notice, this list of conditions and the following disclaimer in the
10837 +// documentation and/or other materials provided with the distribution.
10838 +//
10839 +// 3. The copyright holder's name must not be used to endorse or promote
10840 +// any products derived from this software without his specific prior
10841 +// written permission.
10842 +//
10843 +// This software is provided 'as is' with no express or implied warranties
10844 +// of correctness or fitness for purpose.
10845 +
10846 +// Modified by Jari Ruusu, December 24 2001
10847 +// - Converted syntax to GNU CPP/assembler syntax
10848 +// - C programming interface converted back to "old" API
10849 +// - Minor portability cleanups and speed optimizations
10850 +
10851 +// An AES (Rijndael) implementation for the Pentium. This version only
10852 +// implements the standard AES block length (128 bits, 16 bytes). This code
10853 +// does not preserve the eax, ecx or edx registers or the artihmetic status
10854 +// flags. However, the ebx, esi, edi, and ebp registers are preserved across
10855 +// calls.
10856 +
10857 +// void aes_set_key(aes_context *cx, const unsigned char key[], const int key_len, const int f)
10858 +// void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
10859 +// void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
10860 +
10861 +#if defined(USE_UNDERLINE)
10862 +# define aes_set_key _aes_set_key
10863 +# define aes_encrypt _aes_encrypt
10864 +# define aes_decrypt _aes_decrypt
10865 +#endif
10866 +#if !defined(ALIGN32BYTES)
10867 +# define ALIGN32BYTES 32
10868 +#endif
10869 +
10870 + .file "aes-i586.S"
10871 + .globl aes_set_key
10872 + .globl aes_encrypt
10873 + .globl aes_decrypt
10874 +
10875 +#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words)
10876 +
10877 +// offsets to parameters with one register pushed onto stack
10878 +
10879 +#define ctx 8 // AES context structure
10880 +#define in_blk 12 // input byte array address parameter
10881 +#define out_blk 16 // output byte array address parameter
10882 +
10883 +// offsets in context structure
10884 +
10885 +#define nkey 0 // key length, size 4
10886 +#define nrnd 4 // number of rounds, size 4
10887 +#define ekey 8 // encryption key schedule base address, size 256
10888 +#define dkey 264 // decryption key schedule base address, size 256
10889 +
10890 +// This macro performs a forward encryption cycle. It is entered with
10891 +// the first previous round column values in %eax, %ebx, %esi and %edi and
10892 +// exits with the final values in the same registers.
10893 +
10894 +#define fwd_rnd(p1,p2) \
10895 + mov %ebx,(%esp) ;\
10896 + movzbl %al,%edx ;\
10897 + mov %eax,%ecx ;\
10898 + mov p2(%ebp),%eax ;\
10899 + mov %edi,4(%esp) ;\
10900 + mov p2+12(%ebp),%edi ;\
10901 + xor p1(,%edx,4),%eax ;\
10902 + movzbl %ch,%edx ;\
10903 + shr $16,%ecx ;\
10904 + mov p2+4(%ebp),%ebx ;\
10905 + xor p1+tlen(,%edx,4),%edi ;\
10906 + movzbl %cl,%edx ;\
10907 + movzbl %ch,%ecx ;\
10908 + xor p1+3*tlen(,%ecx,4),%ebx ;\
10909 + mov %esi,%ecx ;\
10910 + mov p1+2*tlen(,%edx,4),%esi ;\
10911 + movzbl %cl,%edx ;\
10912 + xor p1(,%edx,4),%esi ;\
10913 + movzbl %ch,%edx ;\
10914 + shr $16,%ecx ;\
10915 + xor p1+tlen(,%edx,4),%ebx ;\
10916 + movzbl %cl,%edx ;\
10917 + movzbl %ch,%ecx ;\
10918 + xor p1+2*tlen(,%edx,4),%eax ;\
10919 + mov (%esp),%edx ;\
10920 + xor p1+3*tlen(,%ecx,4),%edi ;\
10921 + movzbl %dl,%ecx ;\
10922 + xor p2+8(%ebp),%esi ;\
10923 + xor p1(,%ecx,4),%ebx ;\
10924 + movzbl %dh,%ecx ;\
10925 + shr $16,%edx ;\
10926 + xor p1+tlen(,%ecx,4),%eax ;\
10927 + movzbl %dl,%ecx ;\
10928 + movzbl %dh,%edx ;\
10929 + xor p1+2*tlen(,%ecx,4),%edi ;\
10930 + mov 4(%esp),%ecx ;\
10931 + xor p1+3*tlen(,%edx,4),%esi ;\
10932 + movzbl %cl,%edx ;\
10933 + xor p1(,%edx,4),%edi ;\
10934 + movzbl %ch,%edx ;\
10935 + shr $16,%ecx ;\
10936 + xor p1+tlen(,%edx,4),%esi ;\
10937 + movzbl %cl,%edx ;\
10938 + movzbl %ch,%ecx ;\
10939 + xor p1+2*tlen(,%edx,4),%ebx ;\
10940 + xor p1+3*tlen(,%ecx,4),%eax
10941 +
10942 +// This macro performs an inverse encryption cycle. It is entered with
10943 +// the first previous round column values in %eax, %ebx, %esi and %edi and
10944 +// exits with the final values in the same registers.
10945 +
10946 +#define inv_rnd(p1,p2) \
10947 + movzbl %al,%edx ;\
10948 + mov %ebx,(%esp) ;\
10949 + mov %eax,%ecx ;\
10950 + mov p2(%ebp),%eax ;\
10951 + mov %edi,4(%esp) ;\
10952 + mov p2+4(%ebp),%ebx ;\
10953 + xor p1(,%edx,4),%eax ;\
10954 + movzbl %ch,%edx ;\
10955 + shr $16,%ecx ;\
10956 + mov p2+12(%ebp),%edi ;\
10957 + xor p1+tlen(,%edx,4),%ebx ;\
10958 + movzbl %cl,%edx ;\
10959 + movzbl %ch,%ecx ;\
10960 + xor p1+3*tlen(,%ecx,4),%edi ;\
10961 + mov %esi,%ecx ;\
10962 + mov p1+2*tlen(,%edx,4),%esi ;\
10963 + movzbl %cl,%edx ;\
10964 + xor p1(,%edx,4),%esi ;\
10965 + movzbl %ch,%edx ;\
10966 + shr $16,%ecx ;\
10967 + xor p1+tlen(,%edx,4),%edi ;\
10968 + movzbl %cl,%edx ;\
10969 + movzbl %ch,%ecx ;\
10970 + xor p1+2*tlen(,%edx,4),%eax ;\
10971 + mov (%esp),%edx ;\
10972 + xor p1+3*tlen(,%ecx,4),%ebx ;\
10973 + movzbl %dl,%ecx ;\
10974 + xor p2+8(%ebp),%esi ;\
10975 + xor p1(,%ecx,4),%ebx ;\
10976 + movzbl %dh,%ecx ;\
10977 + shr $16,%edx ;\
10978 + xor p1+tlen(,%ecx,4),%esi ;\
10979 + movzbl %dl,%ecx ;\
10980 + movzbl %dh,%edx ;\
10981 + xor p1+2*tlen(,%ecx,4),%edi ;\
10982 + mov 4(%esp),%ecx ;\
10983 + xor p1+3*tlen(,%edx,4),%eax ;\
10984 + movzbl %cl,%edx ;\
10985 + xor p1(,%edx,4),%edi ;\
10986 + movzbl %ch,%edx ;\
10987 + shr $16,%ecx ;\
10988 + xor p1+tlen(,%edx,4),%eax ;\
10989 + movzbl %cl,%edx ;\
10990 + movzbl %ch,%ecx ;\
10991 + xor p1+2*tlen(,%edx,4),%ebx ;\
10992 + xor p1+3*tlen(,%ecx,4),%esi
10993 +
10994 +// AES (Rijndael) Encryption Subroutine
10995 +
10996 + .text
10997 + .align ALIGN32BYTES
10998 +aes_encrypt:
10999 + push %ebp
11000 + mov ctx(%esp),%ebp // pointer to context
11001 + mov in_blk(%esp),%ecx
11002 + push %ebx
11003 + push %esi
11004 + push %edi
11005 + mov nrnd(%ebp),%edx // number of rounds
11006 + lea ekey+16(%ebp),%ebp // key pointer
11007 +
11008 +// input four columns and xor in first round key
11009 +
11010 + mov (%ecx),%eax
11011 + mov 4(%ecx),%ebx
11012 + mov 8(%ecx),%esi
11013 + mov 12(%ecx),%edi
11014 + xor -16(%ebp),%eax
11015 + xor -12(%ebp),%ebx
11016 + xor -8(%ebp),%esi
11017 + xor -4(%ebp),%edi
11018 +
11019 + sub $8,%esp // space for register saves on stack
11020 +
11021 + sub $10,%edx
11022 + je aes_15
11023 + add $32,%ebp
11024 + sub $2,%edx
11025 + je aes_13
11026 + add $32,%ebp
11027 +
11028 + fwd_rnd(aes_ft_tab,-64) // 14 rounds for 256-bit key
11029 + fwd_rnd(aes_ft_tab,-48)
11030 +aes_13: fwd_rnd(aes_ft_tab,-32) // 12 rounds for 192-bit key
11031 + fwd_rnd(aes_ft_tab,-16)
11032 +aes_15: fwd_rnd(aes_ft_tab,0) // 10 rounds for 128-bit key
11033 + fwd_rnd(aes_ft_tab,16)
11034 + fwd_rnd(aes_ft_tab,32)
11035 + fwd_rnd(aes_ft_tab,48)
11036 + fwd_rnd(aes_ft_tab,64)
11037 + fwd_rnd(aes_ft_tab,80)
11038 + fwd_rnd(aes_ft_tab,96)
11039 + fwd_rnd(aes_ft_tab,112)
11040 + fwd_rnd(aes_ft_tab,128)
11041 + fwd_rnd(aes_fl_tab,144) // last round uses a different table
11042 +
11043 +// move final values to the output array.
11044 +
11045 + mov out_blk+20(%esp),%ebp
11046 + add $8,%esp
11047 + mov %eax,(%ebp)
11048 + mov %ebx,4(%ebp)
11049 + mov %esi,8(%ebp)
11050 + mov %edi,12(%ebp)
11051 + pop %edi
11052 + pop %esi
11053 + pop %ebx
11054 + pop %ebp
11055 + ret
11056 +
11057 +
11058 +// AES (Rijndael) Decryption Subroutine
11059 +
11060 + .align ALIGN32BYTES
11061 +aes_decrypt:
11062 + push %ebp
11063 + mov ctx(%esp),%ebp // pointer to context
11064 + mov in_blk(%esp),%ecx
11065 + push %ebx
11066 + push %esi
11067 + push %edi
11068 + mov nrnd(%ebp),%edx // number of rounds
11069 + lea dkey+16(%ebp),%ebp // key pointer
11070 +
11071 +// input four columns and xor in first round key
11072 +
11073 + mov (%ecx),%eax
11074 + mov 4(%ecx),%ebx
11075 + mov 8(%ecx),%esi
11076 + mov 12(%ecx),%edi
11077 + xor -16(%ebp),%eax
11078 + xor -12(%ebp),%ebx
11079 + xor -8(%ebp),%esi
11080 + xor -4(%ebp),%edi
11081 +
11082 + sub $8,%esp // space for register saves on stack
11083 +
11084 + sub $10,%edx
11085 + je aes_25
11086 + add $32,%ebp
11087 + sub $2,%edx
11088 + je aes_23
11089 + add $32,%ebp
11090 +
11091 + inv_rnd(aes_it_tab,-64) // 14 rounds for 256-bit key
11092 + inv_rnd(aes_it_tab,-48)
11093 +aes_23: inv_rnd(aes_it_tab,-32) // 12 rounds for 192-bit key
11094 + inv_rnd(aes_it_tab,-16)
11095 +aes_25: inv_rnd(aes_it_tab,0) // 10 rounds for 128-bit key
11096 + inv_rnd(aes_it_tab,16)
11097 + inv_rnd(aes_it_tab,32)
11098 + inv_rnd(aes_it_tab,48)
11099 + inv_rnd(aes_it_tab,64)
11100 + inv_rnd(aes_it_tab,80)
11101 + inv_rnd(aes_it_tab,96)
11102 + inv_rnd(aes_it_tab,112)
11103 + inv_rnd(aes_it_tab,128)
11104 + inv_rnd(aes_il_tab,144) // last round uses a different table
11105 +
11106 +// move final values to the output array.
11107 +
11108 + mov out_blk+20(%esp),%ebp
11109 + add $8,%esp
11110 + mov %eax,(%ebp)
11111 + mov %ebx,4(%ebp)
11112 + mov %esi,8(%ebp)
11113 + mov %edi,12(%ebp)
11114 + pop %edi
11115 + pop %esi
11116 + pop %ebx
11117 + pop %ebp
11118 + ret
11119 +
11120 +// AES (Rijndael) Key Schedule Subroutine
11121 +
11122 +// input/output parameters
11123 +
11124 +#define aes_cx 12 // AES context
11125 +#define in_key 16 // key input array address
11126 +#define key_ln 20 // key length, bytes (16,24,32) or bits (128,192,256)
11127 +#define ed_flg 24 // 0=create both encr/decr keys, 1=create encr key only
11128 +
11129 +// offsets for locals
11130 +
11131 +#define cnt -4
11132 +#define kpf -8
11133 +#define slen 8
11134 +
11135 +// This macro performs a column mixing operation on an input 32-bit
11136 +// word to give a 32-bit result. It uses each of the 4 bytes in the
11137 +// the input column to index 4 different tables of 256 32-bit words
11138 +// that are xored together to form the output value.
11139 +
11140 +#define mix_col(p1) \
11141 + movzbl %bl,%ecx ;\
11142 + mov p1(,%ecx,4),%eax ;\
11143 + movzbl %bh,%ecx ;\
11144 + ror $16,%ebx ;\
11145 + xor p1+tlen(,%ecx,4),%eax ;\
11146 + movzbl %bl,%ecx ;\
11147 + xor p1+2*tlen(,%ecx,4),%eax ;\
11148 + movzbl %bh,%ecx ;\
11149 + xor p1+3*tlen(,%ecx,4),%eax
11150 +
11151 +// Key Schedule Macros
11152 +
11153 +#define ksc4(p1) \
11154 + rol $24,%ebx ;\
11155 + mix_col(aes_fl_tab) ;\
11156 + ror $8,%ebx ;\
11157 + xor 4*p1+aes_rcon_tab,%eax ;\
11158 + xor %eax,%esi ;\
11159 + xor %esi,%ebp ;\
11160 + mov %esi,16*p1(%edi) ;\
11161 + mov %ebp,16*p1+4(%edi) ;\
11162 + xor %ebp,%edx ;\
11163 + xor %edx,%ebx ;\
11164 + mov %edx,16*p1+8(%edi) ;\
11165 + mov %ebx,16*p1+12(%edi)
11166 +
11167 +#define ksc6(p1) \
11168 + rol $24,%ebx ;\
11169 + mix_col(aes_fl_tab) ;\
11170 + ror $8,%ebx ;\
11171 + xor 4*p1+aes_rcon_tab,%eax ;\
11172 + xor 24*p1-24(%edi),%eax ;\
11173 + mov %eax,24*p1(%edi) ;\
11174 + xor 24*p1-20(%edi),%eax ;\
11175 + mov %eax,24*p1+4(%edi) ;\
11176 + xor %eax,%esi ;\
11177 + xor %esi,%ebp ;\
11178 + mov %esi,24*p1+8(%edi) ;\
11179 + mov %ebp,24*p1+12(%edi) ;\
11180 + xor %ebp,%edx ;\
11181 + xor %edx,%ebx ;\
11182 + mov %edx,24*p1+16(%edi) ;\
11183 + mov %ebx,24*p1+20(%edi)
11184 +
11185 +#define ksc8(p1) \
11186 + rol $24,%ebx ;\
11187 + mix_col(aes_fl_tab) ;\
11188 + ror $8,%ebx ;\
11189 + xor 4*p1+aes_rcon_tab,%eax ;\
11190 + xor 32*p1-32(%edi),%eax ;\
11191 + mov %eax,32*p1(%edi) ;\
11192 + xor 32*p1-28(%edi),%eax ;\
11193 + mov %eax,32*p1+4(%edi) ;\
11194 + xor 32*p1-24(%edi),%eax ;\
11195 + mov %eax,32*p1+8(%edi) ;\
11196 + xor 32*p1-20(%edi),%eax ;\
11197 + mov %eax,32*p1+12(%edi) ;\
11198 + push %ebx ;\
11199 + mov %eax,%ebx ;\
11200 + mix_col(aes_fl_tab) ;\
11201 + pop %ebx ;\
11202 + xor %eax,%esi ;\
11203 + xor %esi,%ebp ;\
11204 + mov %esi,32*p1+16(%edi) ;\
11205 + mov %ebp,32*p1+20(%edi) ;\
11206 + xor %ebp,%edx ;\
11207 + xor %edx,%ebx ;\
11208 + mov %edx,32*p1+24(%edi) ;\
11209 + mov %ebx,32*p1+28(%edi)
11210 +
11211 + .align ALIGN32BYTES
11212 +aes_set_key:
11213 + pushfl
11214 + push %ebp
11215 + mov %esp,%ebp
11216 + sub $slen,%esp
11217 + push %ebx
11218 + push %esi
11219 + push %edi
11220 +
11221 + mov aes_cx(%ebp),%edx // edx -> AES context
11222 +
11223 + mov key_ln(%ebp),%ecx // key length
11224 + cmpl $128,%ecx
11225 + jb aes_30
11226 + shr $3,%ecx
11227 +aes_30: cmpl $32,%ecx
11228 + je aes_32
11229 + cmpl $24,%ecx
11230 + je aes_32
11231 + mov $16,%ecx
11232 +aes_32: shr $2,%ecx
11233 + mov %ecx,nkey(%edx)
11234 +
11235 + lea 6(%ecx),%eax // 10/12/14 for 4/6/8 32-bit key length
11236 + mov %eax,nrnd(%edx)
11237 +
11238 + mov in_key(%ebp),%esi // key input array
11239 + lea ekey(%edx),%edi // key position in AES context
11240 + cld
11241 + push %ebp
11242 + mov %ecx,%eax // save key length in eax
11243 + rep ; movsl // words in the key schedule
11244 + mov -4(%esi),%ebx // put some values in registers
11245 + mov -8(%esi),%edx // to allow faster code
11246 + mov -12(%esi),%ebp
11247 + mov -16(%esi),%esi
11248 +
11249 + cmpl $4,%eax // jump on key size
11250 + je aes_36
11251 + cmpl $6,%eax
11252 + je aes_35
11253 +
11254 + ksc8(0)
11255 + ksc8(1)
11256 + ksc8(2)
11257 + ksc8(3)
11258 + ksc8(4)
11259 + ksc8(5)
11260 + ksc8(6)
11261 + jmp aes_37
11262 +aes_35: ksc6(0)
11263 + ksc6(1)
11264 + ksc6(2)
11265 + ksc6(3)
11266 + ksc6(4)
11267 + ksc6(5)
11268 + ksc6(6)
11269 + ksc6(7)
11270 + jmp aes_37
11271 +aes_36: ksc4(0)
11272 + ksc4(1)
11273 + ksc4(2)
11274 + ksc4(3)
11275 + ksc4(4)
11276 + ksc4(5)
11277 + ksc4(6)
11278 + ksc4(7)
11279 + ksc4(8)
11280 + ksc4(9)
11281 +aes_37: pop %ebp
11282 + mov aes_cx(%ebp),%edx // edx -> AES context
11283 + cmpl $0,ed_flg(%ebp)
11284 + jne aes_39
11285 +
11286 +// compile decryption key schedule from encryption schedule - reverse
11287 +// order and do mix_column operation on round keys except first and last
11288 +
11289 + mov nrnd(%edx),%eax // kt = cx->d_key + nc * cx->Nrnd
11290 + shl $2,%eax
11291 + lea dkey(%edx,%eax,4),%edi
11292 + lea ekey(%edx),%esi // kf = cx->e_key
11293 +
11294 + movsl // copy first round key (unmodified)
11295 + movsl
11296 + movsl
11297 + movsl
11298 + sub $32,%edi
11299 + movl $1,cnt(%ebp)
11300 +aes_38: // do mix column on each column of
11301 + lodsl // each round key
11302 + mov %eax,%ebx
11303 + mix_col(aes_im_tab)
11304 + stosl
11305 + lodsl
11306 + mov %eax,%ebx
11307 + mix_col(aes_im_tab)
11308 + stosl
11309 + lodsl
11310 + mov %eax,%ebx
11311 + mix_col(aes_im_tab)
11312 + stosl
11313 + lodsl
11314 + mov %eax,%ebx
11315 + mix_col(aes_im_tab)
11316 + stosl
11317 + sub $32,%edi
11318 +
11319 + incl cnt(%ebp)
11320 + mov cnt(%ebp),%eax
11321 + cmp nrnd(%edx),%eax
11322 + jb aes_38
11323 +
11324 + movsl // copy last round key (unmodified)
11325 + movsl
11326 + movsl
11327 + movsl
11328 +aes_39: pop %edi
11329 + pop %esi
11330 + pop %ebx
11331 + mov %ebp,%esp
11332 + pop %ebp
11333 + popfl
11334 + ret
11335 +
11336 +
11337 +// finite field multiplies by {02}, {04} and {08}
11338 +
11339 +#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b))
11340 +#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b))
11341 +#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b))
11342 +
11343 +// finite field multiplies required in table generation
11344 +
11345 +#define f3(x) (f2(x) ^ x)
11346 +#define f9(x) (f8(x) ^ x)
11347 +#define fb(x) (f8(x) ^ f2(x) ^ x)
11348 +#define fd(x) (f8(x) ^ f4(x) ^ x)
11349 +#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
11350 +
11351 +// These defines generate the forward table entries
11352 +
11353 +#define u0(x) ((f3(x) << 24) | (x << 16) | (x << 8) | f2(x))
11354 +#define u1(x) ((x << 24) | (x << 16) | (f2(x) << 8) | f3(x))
11355 +#define u2(x) ((x << 24) | (f2(x) << 16) | (f3(x) << 8) | x)
11356 +#define u3(x) ((f2(x) << 24) | (f3(x) << 16) | (x << 8) | x)
11357 +
11358 +// These defines generate the inverse table entries
11359 +
11360 +#define v0(x) ((fb(x) << 24) | (fd(x) << 16) | (f9(x) << 8) | fe(x))
11361 +#define v1(x) ((fd(x) << 24) | (f9(x) << 16) | (fe(x) << 8) | fb(x))
11362 +#define v2(x) ((f9(x) << 24) | (fe(x) << 16) | (fb(x) << 8) | fd(x))
11363 +#define v3(x) ((fe(x) << 24) | (fb(x) << 16) | (fd(x) << 8) | f9(x))
11364 +
11365 +// These defines generate entries for the last round tables
11366 +
11367 +#define w0(x) (x)
11368 +#define w1(x) (x << 8)
11369 +#define w2(x) (x << 16)
11370 +#define w3(x) (x << 24)
11371 +
11372 +// macro to generate inverse mix column tables (needed for the key schedule)
11373 +
11374 +#define im_data0(p1) \
11375 + .long p1(0x00),p1(0x01),p1(0x02),p1(0x03),p1(0x04),p1(0x05),p1(0x06),p1(0x07) ;\
11376 + .long p1(0x08),p1(0x09),p1(0x0a),p1(0x0b),p1(0x0c),p1(0x0d),p1(0x0e),p1(0x0f) ;\
11377 + .long p1(0x10),p1(0x11),p1(0x12),p1(0x13),p1(0x14),p1(0x15),p1(0x16),p1(0x17) ;\
11378 + .long p1(0x18),p1(0x19),p1(0x1a),p1(0x1b),p1(0x1c),p1(0x1d),p1(0x1e),p1(0x1f)
11379 +#define im_data1(p1) \
11380 + .long p1(0x20),p1(0x21),p1(0x22),p1(0x23),p1(0x24),p1(0x25),p1(0x26),p1(0x27) ;\
11381 + .long p1(0x28),p1(0x29),p1(0x2a),p1(0x2b),p1(0x2c),p1(0x2d),p1(0x2e),p1(0x2f) ;\
11382 + .long p1(0x30),p1(0x31),p1(0x32),p1(0x33),p1(0x34),p1(0x35),p1(0x36),p1(0x37) ;\
11383 + .long p1(0x38),p1(0x39),p1(0x3a),p1(0x3b),p1(0x3c),p1(0x3d),p1(0x3e),p1(0x3f)
11384 +#define im_data2(p1) \
11385 + .long p1(0x40),p1(0x41),p1(0x42),p1(0x43),p1(0x44),p1(0x45),p1(0x46),p1(0x47) ;\
11386 + .long p1(0x48),p1(0x49),p1(0x4a),p1(0x4b),p1(0x4c),p1(0x4d),p1(0x4e),p1(0x4f) ;\
11387 + .long p1(0x50),p1(0x51),p1(0x52),p1(0x53),p1(0x54),p1(0x55),p1(0x56),p1(0x57) ;\
11388 + .long p1(0x58),p1(0x59),p1(0x5a),p1(0x5b),p1(0x5c),p1(0x5d),p1(0x5e),p1(0x5f)
11389 +#define im_data3(p1) \
11390 + .long p1(0x60),p1(0x61),p1(0x62),p1(0x63),p1(0x64),p1(0x65),p1(0x66),p1(0x67) ;\
11391 + .long p1(0x68),p1(0x69),p1(0x6a),p1(0x6b),p1(0x6c),p1(0x6d),p1(0x6e),p1(0x6f) ;\
11392 + .long p1(0x70),p1(0x71),p1(0x72),p1(0x73),p1(0x74),p1(0x75),p1(0x76),p1(0x77) ;\
11393 + .long p1(0x78),p1(0x79),p1(0x7a),p1(0x7b),p1(0x7c),p1(0x7d),p1(0x7e),p1(0x7f)
11394 +#define im_data4(p1) \
11395 + .long p1(0x80),p1(0x81),p1(0x82),p1(0x83),p1(0x84),p1(0x85),p1(0x86),p1(0x87) ;\
11396 + .long p1(0x88),p1(0x89),p1(0x8a),p1(0x8b),p1(0x8c),p1(0x8d),p1(0x8e),p1(0x8f) ;\
11397 + .long p1(0x90),p1(0x91),p1(0x92),p1(0x93),p1(0x94),p1(0x95),p1(0x96),p1(0x97) ;\
11398 + .long p1(0x98),p1(0x99),p1(0x9a),p1(0x9b),p1(0x9c),p1(0x9d),p1(0x9e),p1(0x9f)
11399 +#define im_data5(p1) \
11400 + .long p1(0xa0),p1(0xa1),p1(0xa2),p1(0xa3),p1(0xa4),p1(0xa5),p1(0xa6),p1(0xa7) ;\
11401 + .long p1(0xa8),p1(0xa9),p1(0xaa),p1(0xab),p1(0xac),p1(0xad),p1(0xae),p1(0xaf) ;\
11402 + .long p1(0xb0),p1(0xb1),p1(0xb2),p1(0xb3),p1(0xb4),p1(0xb5),p1(0xb6),p1(0xb7) ;\
11403 + .long p1(0xb8),p1(0xb9),p1(0xba),p1(0xbb),p1(0xbc),p1(0xbd),p1(0xbe),p1(0xbf)
11404 +#define im_data6(p1) \
11405 + .long p1(0xc0),p1(0xc1),p1(0xc2),p1(0xc3),p1(0xc4),p1(0xc5),p1(0xc6),p1(0xc7) ;\
11406 + .long p1(0xc8),p1(0xc9),p1(0xca),p1(0xcb),p1(0xcc),p1(0xcd),p1(0xce),p1(0xcf) ;\
11407 + .long p1(0xd0),p1(0xd1),p1(0xd2),p1(0xd3),p1(0xd4),p1(0xd5),p1(0xd6),p1(0xd7) ;\
11408 + .long p1(0xd8),p1(0xd9),p1(0xda),p1(0xdb),p1(0xdc),p1(0xdd),p1(0xde),p1(0xdf)
11409 +#define im_data7(p1) \
11410 + .long p1(0xe0),p1(0xe1),p1(0xe2),p1(0xe3),p1(0xe4),p1(0xe5),p1(0xe6),p1(0xe7) ;\
11411 + .long p1(0xe8),p1(0xe9),p1(0xea),p1(0xeb),p1(0xec),p1(0xed),p1(0xee),p1(0xef) ;\
11412 + .long p1(0xf0),p1(0xf1),p1(0xf2),p1(0xf3),p1(0xf4),p1(0xf5),p1(0xf6),p1(0xf7) ;\
11413 + .long p1(0xf8),p1(0xf9),p1(0xfa),p1(0xfb),p1(0xfc),p1(0xfd),p1(0xfe),p1(0xff)
11414 +
11415 +// S-box data - 256 entries
11416 +
11417 +#define sb_data0(p1) \
11418 + .long p1(0x63),p1(0x7c),p1(0x77),p1(0x7b),p1(0xf2),p1(0x6b),p1(0x6f),p1(0xc5) ;\
11419 + .long p1(0x30),p1(0x01),p1(0x67),p1(0x2b),p1(0xfe),p1(0xd7),p1(0xab),p1(0x76) ;\
11420 + .long p1(0xca),p1(0x82),p1(0xc9),p1(0x7d),p1(0xfa),p1(0x59),p1(0x47),p1(0xf0) ;\
11421 + .long p1(0xad),p1(0xd4),p1(0xa2),p1(0xaf),p1(0x9c),p1(0xa4),p1(0x72),p1(0xc0)
11422 +#define sb_data1(p1) \
11423 + .long p1(0xb7),p1(0xfd),p1(0x93),p1(0x26),p1(0x36),p1(0x3f),p1(0xf7),p1(0xcc) ;\
11424 + .long p1(0x34),p1(0xa5),p1(0xe5),p1(0xf1),p1(0x71),p1(0xd8),p1(0x31),p1(0x15) ;\
11425 + .long p1(0x04),p1(0xc7),p1(0x23),p1(0xc3),p1(0x18),p1(0x96),p1(0x05),p1(0x9a) ;\
11426 + .long p1(0x07),p1(0x12),p1(0x80),p1(0xe2),p1(0xeb),p1(0x27),p1(0xb2),p1(0x75)
11427 +#define sb_data2(p1) \
11428 + .long p1(0x09),p1(0x83),p1(0x2c),p1(0x1a),p1(0x1b),p1(0x6e),p1(0x5a),p1(0xa0) ;\
11429 + .long p1(0x52),p1(0x3b),p1(0xd6),p1(0xb3),p1(0x29),p1(0xe3),p1(0x2f),p1(0x84) ;\
11430 + .long p1(0x53),p1(0xd1),p1(0x00),p1(0xed),p1(0x20),p1(0xfc),p1(0xb1),p1(0x5b) ;\
11431 + .long p1(0x6a),p1(0xcb),p1(0xbe),p1(0x39),p1(0x4a),p1(0x4c),p1(0x58),p1(0xcf)
11432 +#define sb_data3(p1) \
11433 + .long p1(0xd0),p1(0xef),p1(0xaa),p1(0xfb),p1(0x43),p1(0x4d),p1(0x33),p1(0x85) ;\
11434 + .long p1(0x45),p1(0xf9),p1(0x02),p1(0x7f),p1(0x50),p1(0x3c),p1(0x9f),p1(0xa8) ;\
11435 + .long p1(0x51),p1(0xa3),p1(0x40),p1(0x8f),p1(0x92),p1(0x9d),p1(0x38),p1(0xf5) ;\
11436 + .long p1(0xbc),p1(0xb6),p1(0xda),p1(0x21),p1(0x10),p1(0xff),p1(0xf3),p1(0xd2)
11437 +#define sb_data4(p1) \
11438 + .long p1(0xcd),p1(0x0c),p1(0x13),p1(0xec),p1(0x5f),p1(0x97),p1(0x44),p1(0x17) ;\
11439 + .long p1(0xc4),p1(0xa7),p1(0x7e),p1(0x3d),p1(0x64),p1(0x5d),p1(0x19),p1(0x73) ;\
11440 + .long p1(0x60),p1(0x81),p1(0x4f),p1(0xdc),p1(0x22),p1(0x2a),p1(0x90),p1(0x88) ;\
11441 + .long p1(0x46),p1(0xee),p1(0xb8),p1(0x14),p1(0xde),p1(0x5e),p1(0x0b),p1(0xdb)
11442 +#define sb_data5(p1) \
11443 + .long p1(0xe0),p1(0x32),p1(0x3a),p1(0x0a),p1(0x49),p1(0x06),p1(0x24),p1(0x5c) ;\
11444 + .long p1(0xc2),p1(0xd3),p1(0xac),p1(0x62),p1(0x91),p1(0x95),p1(0xe4),p1(0x79) ;\
11445 + .long p1(0xe7),p1(0xc8),p1(0x37),p1(0x6d),p1(0x8d),p1(0xd5),p1(0x4e),p1(0xa9) ;\
11446 + .long p1(0x6c),p1(0x56),p1(0xf4),p1(0xea),p1(0x65),p1(0x7a),p1(0xae),p1(0x08)
11447 +#define sb_data6(p1) \
11448 + .long p1(0xba),p1(0x78),p1(0x25),p1(0x2e),p1(0x1c),p1(0xa6),p1(0xb4),p1(0xc6) ;\
11449 + .long p1(0xe8),p1(0xdd),p1(0x74),p1(0x1f),p1(0x4b),p1(0xbd),p1(0x8b),p1(0x8a) ;\
11450 + .long p1(0x70),p1(0x3e),p1(0xb5),p1(0x66),p1(0x48),p1(0x03),p1(0xf6),p1(0x0e) ;\
11451 + .long p1(0x61),p1(0x35),p1(0x57),p1(0xb9),p1(0x86),p1(0xc1),p1(0x1d),p1(0x9e)
11452 +#define sb_data7(p1) \
11453 + .long p1(0xe1),p1(0xf8),p1(0x98),p1(0x11),p1(0x69),p1(0xd9),p1(0x8e),p1(0x94) ;\
11454 + .long p1(0x9b),p1(0x1e),p1(0x87),p1(0xe9),p1(0xce),p1(0x55),p1(0x28),p1(0xdf) ;\
11455 + .long p1(0x8c),p1(0xa1),p1(0x89),p1(0x0d),p1(0xbf),p1(0xe6),p1(0x42),p1(0x68) ;\
11456 + .long p1(0x41),p1(0x99),p1(0x2d),p1(0x0f),p1(0xb0),p1(0x54),p1(0xbb),p1(0x16)
11457 +
11458 +// Inverse S-box data - 256 entries
11459 +
11460 +#define ib_data0(p1) \
11461 + .long p1(0x52),p1(0x09),p1(0x6a),p1(0xd5),p1(0x30),p1(0x36),p1(0xa5),p1(0x38) ;\
11462 + .long p1(0xbf),p1(0x40),p1(0xa3),p1(0x9e),p1(0x81),p1(0xf3),p1(0xd7),p1(0xfb) ;\
11463 + .long p1(0x7c),p1(0xe3),p1(0x39),p1(0x82),p1(0x9b),p1(0x2f),p1(0xff),p1(0x87) ;\
11464 + .long p1(0x34),p1(0x8e),p1(0x43),p1(0x44),p1(0xc4),p1(0xde),p1(0xe9),p1(0xcb)
11465 +#define ib_data1(p1) \
11466 + .long p1(0x54),p1(0x7b),p1(0x94),p1(0x32),p1(0xa6),p1(0xc2),p1(0x23),p1(0x3d) ;\
11467 + .long p1(0xee),p1(0x4c),p1(0x95),p1(0x0b),p1(0x42),p1(0xfa),p1(0xc3),p1(0x4e) ;\
11468 + .long p1(0x08),p1(0x2e),p1(0xa1),p1(0x66),p1(0x28),p1(0xd9),p1(0x24),p1(0xb2) ;\
11469 + .long p1(0x76),p1(0x5b),p1(0xa2),p1(0x49),p1(0x6d),p1(0x8b),p1(0xd1),p1(0x25)
11470 +#define ib_data2(p1) \
11471 + .long p1(0x72),p1(0xf8),p1(0xf6),p1(0x64),p1(0x86),p1(0x68),p1(0x98),p1(0x16) ;\
11472 + .long p1(0xd4),p1(0xa4),p1(0x5c),p1(0xcc),p1(0x5d),p1(0x65),p1(0xb6),p1(0x92) ;\
11473 + .long p1(0x6c),p1(0x70),p1(0x48),p1(0x50),p1(0xfd),p1(0xed),p1(0xb9),p1(0xda) ;\
11474 + .long p1(0x5e),p1(0x15),p1(0x46),p1(0x57),p1(0xa7),p1(0x8d),p1(0x9d),p1(0x84)
11475 +#define ib_data3(p1) \
11476 + .long p1(0x90),p1(0xd8),p1(0xab),p1(0x00),p1(0x8c),p1(0xbc),p1(0xd3),p1(0x0a) ;\
11477 + .long p1(0xf7),p1(0xe4),p1(0x58),p1(0x05),p1(0xb8),p1(0xb3),p1(0x45),p1(0x06) ;\
11478 + .long p1(0xd0),p1(0x2c),p1(0x1e),p1(0x8f),p1(0xca),p1(0x3f),p1(0x0f),p1(0x02) ;\
11479 + .long p1(0xc1),p1(0xaf),p1(0xbd),p1(0x03),p1(0x01),p1(0x13),p1(0x8a),p1(0x6b)
11480 +#define ib_data4(p1) \
11481 + .long p1(0x3a),p1(0x91),p1(0x11),p1(0x41),p1(0x4f),p1(0x67),p1(0xdc),p1(0xea) ;\
11482 + .long p1(0x97),p1(0xf2),p1(0xcf),p1(0xce),p1(0xf0),p1(0xb4),p1(0xe6),p1(0x73) ;\
11483 + .long p1(0x96),p1(0xac),p1(0x74),p1(0x22),p1(0xe7),p1(0xad),p1(0x35),p1(0x85) ;\
11484 + .long p1(0xe2),p1(0xf9),p1(0x37),p1(0xe8),p1(0x1c),p1(0x75),p1(0xdf),p1(0x6e)
11485 +#define ib_data5(p1) \
11486 + .long p1(0x47),p1(0xf1),p1(0x1a),p1(0x71),p1(0x1d),p1(0x29),p1(0xc5),p1(0x89) ;\
11487 + .long p1(0x6f),p1(0xb7),p1(0x62),p1(0x0e),p1(0xaa),p1(0x18),p1(0xbe),p1(0x1b) ;\
11488 + .long p1(0xfc),p1(0x56),p1(0x3e),p1(0x4b),p1(0xc6),p1(0xd2),p1(0x79),p1(0x20) ;\
11489 + .long p1(0x9a),p1(0xdb),p1(0xc0),p1(0xfe),p1(0x78),p1(0xcd),p1(0x5a),p1(0xf4)
11490 +#define ib_data6(p1) \
11491 + .long p1(0x1f),p1(0xdd),p1(0xa8),p1(0x33),p1(0x88),p1(0x07),p1(0xc7),p1(0x31) ;\
11492 + .long p1(0xb1),p1(0x12),p1(0x10),p1(0x59),p1(0x27),p1(0x80),p1(0xec),p1(0x5f) ;\
11493 + .long p1(0x60),p1(0x51),p1(0x7f),p1(0xa9),p1(0x19),p1(0xb5),p1(0x4a),p1(0x0d) ;\
11494 + .long p1(0x2d),p1(0xe5),p1(0x7a),p1(0x9f),p1(0x93),p1(0xc9),p1(0x9c),p1(0xef)
11495 +#define ib_data7(p1) \
11496 + .long p1(0xa0),p1(0xe0),p1(0x3b),p1(0x4d),p1(0xae),p1(0x2a),p1(0xf5),p1(0xb0) ;\
11497 + .long p1(0xc8),p1(0xeb),p1(0xbb),p1(0x3c),p1(0x83),p1(0x53),p1(0x99),p1(0x61) ;\
11498 + .long p1(0x17),p1(0x2b),p1(0x04),p1(0x7e),p1(0xba),p1(0x77),p1(0xd6),p1(0x26) ;\
11499 + .long p1(0xe1),p1(0x69),p1(0x14),p1(0x63),p1(0x55),p1(0x21),p1(0x0c),p1(0x7d)
11500 +
11501 +// The rcon_table (needed for the key schedule)
11502 +//
11503 +// Here is original Dr Brian Gladman's source code:
11504 +// _rcon_tab:
11505 +// %assign x 1
11506 +// %rep 29
11507 +// dd x
11508 +// %assign x f2(x)
11509 +// %endrep
11510 +//
11511 +// Here is precomputed output (it's more portable this way):
11512 +
11513 + .align ALIGN32BYTES
11514 +aes_rcon_tab:
11515 + .long 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
11516 + .long 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f
11517 + .long 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4
11518 + .long 0xb3,0x7d,0xfa,0xef,0xc5
11519 +
11520 +// The forward xor tables
11521 +
11522 + .align ALIGN32BYTES
11523 +aes_ft_tab:
11524 + sb_data0(u0)
11525 + sb_data1(u0)
11526 + sb_data2(u0)
11527 + sb_data3(u0)
11528 + sb_data4(u0)
11529 + sb_data5(u0)
11530 + sb_data6(u0)
11531 + sb_data7(u0)
11532 +
11533 + sb_data0(u1)
11534 + sb_data1(u1)
11535 + sb_data2(u1)
11536 + sb_data3(u1)
11537 + sb_data4(u1)
11538 + sb_data5(u1)
11539 + sb_data6(u1)
11540 + sb_data7(u1)
11541 +
11542 + sb_data0(u2)
11543 + sb_data1(u2)
11544 + sb_data2(u2)
11545 + sb_data3(u2)
11546 + sb_data4(u2)
11547 + sb_data5(u2)
11548 + sb_data6(u2)
11549 + sb_data7(u2)
11550 +
11551 + sb_data0(u3)
11552 + sb_data1(u3)
11553 + sb_data2(u3)
11554 + sb_data3(u3)
11555 + sb_data4(u3)
11556 + sb_data5(u3)
11557 + sb_data6(u3)
11558 + sb_data7(u3)
11559 +
11560 + .align ALIGN32BYTES
11561 +aes_fl_tab:
11562 + sb_data0(w0)
11563 + sb_data1(w0)
11564 + sb_data2(w0)
11565 + sb_data3(w0)
11566 + sb_data4(w0)
11567 + sb_data5(w0)
11568 + sb_data6(w0)
11569 + sb_data7(w0)
11570 +
11571 + sb_data0(w1)
11572 + sb_data1(w1)
11573 + sb_data2(w1)
11574 + sb_data3(w1)
11575 + sb_data4(w1)
11576 + sb_data5(w1)
11577 + sb_data6(w1)
11578 + sb_data7(w1)
11579 +
11580 + sb_data0(w2)
11581 + sb_data1(w2)
11582 + sb_data2(w2)
11583 + sb_data3(w2)
11584 + sb_data4(w2)
11585 + sb_data5(w2)
11586 + sb_data6(w2)
11587 + sb_data7(w2)
11588 +
11589 + sb_data0(w3)
11590 + sb_data1(w3)
11591 + sb_data2(w3)
11592 + sb_data3(w3)
11593 + sb_data4(w3)
11594 + sb_data5(w3)
11595 + sb_data6(w3)
11596 + sb_data7(w3)
11597 +
11598 +// The inverse xor tables
11599 +
11600 + .align ALIGN32BYTES
11601 +aes_it_tab:
11602 + ib_data0(v0)
11603 + ib_data1(v0)
11604 + ib_data2(v0)
11605 + ib_data3(v0)
11606 + ib_data4(v0)
11607 + ib_data5(v0)
11608 + ib_data6(v0)
11609 + ib_data7(v0)
11610 +
11611 + ib_data0(v1)
11612 + ib_data1(v1)
11613 + ib_data2(v1)
11614 + ib_data3(v1)
11615 + ib_data4(v1)
11616 + ib_data5(v1)
11617 + ib_data6(v1)
11618 + ib_data7(v1)
11619 +
11620 + ib_data0(v2)
11621 + ib_data1(v2)
11622 + ib_data2(v2)
11623 + ib_data3(v2)
11624 + ib_data4(v2)
11625 + ib_data5(v2)
11626 + ib_data6(v2)
11627 + ib_data7(v2)
11628 +
11629 + ib_data0(v3)
11630 + ib_data1(v3)
11631 + ib_data2(v3)
11632 + ib_data3(v3)
11633 + ib_data4(v3)
11634 + ib_data5(v3)
11635 + ib_data6(v3)
11636 + ib_data7(v3)
11637 +
11638 + .align ALIGN32BYTES
11639 +aes_il_tab:
11640 + ib_data0(w0)
11641 + ib_data1(w0)
11642 + ib_data2(w0)
11643 + ib_data3(w0)
11644 + ib_data4(w0)
11645 + ib_data5(w0)
11646 + ib_data6(w0)
11647 + ib_data7(w0)
11648 +
11649 + ib_data0(w1)
11650 + ib_data1(w1)
11651 + ib_data2(w1)
11652 + ib_data3(w1)
11653 + ib_data4(w1)
11654 + ib_data5(w1)
11655 + ib_data6(w1)
11656 + ib_data7(w1)
11657 +
11658 + ib_data0(w2)
11659 + ib_data1(w2)
11660 + ib_data2(w2)
11661 + ib_data3(w2)
11662 + ib_data4(w2)
11663 + ib_data5(w2)
11664 + ib_data6(w2)
11665 + ib_data7(w2)
11666 +
11667 + ib_data0(w3)
11668 + ib_data1(w3)
11669 + ib_data2(w3)
11670 + ib_data3(w3)
11671 + ib_data4(w3)
11672 + ib_data5(w3)
11673 + ib_data6(w3)
11674 + ib_data7(w3)
11675 +
11676 +// The inverse mix column tables
11677 +
11678 + .align ALIGN32BYTES
11679 +aes_im_tab:
11680 + im_data0(v0)
11681 + im_data1(v0)
11682 + im_data2(v0)
11683 + im_data3(v0)
11684 + im_data4(v0)
11685 + im_data5(v0)
11686 + im_data6(v0)
11687 + im_data7(v0)
11688 +
11689 + im_data0(v1)
11690 + im_data1(v1)
11691 + im_data2(v1)
11692 + im_data3(v1)
11693 + im_data4(v1)
11694 + im_data5(v1)
11695 + im_data6(v1)
11696 + im_data7(v1)
11697 +
11698 + im_data0(v2)
11699 + im_data1(v2)
11700 + im_data2(v2)
11701 + im_data3(v2)
11702 + im_data4(v2)
11703 + im_data5(v2)
11704 + im_data6(v2)
11705 + im_data7(v2)
11706 +
11707 + im_data0(v3)
11708 + im_data1(v3)
11709 + im_data2(v3)
11710 + im_data3(v3)
11711 + im_data4(v3)
11712 + im_data5(v3)
11713 + im_data6(v3)
11714 + im_data7(v3)
11715 --- /dev/null Tue Mar 11 13:02:56 2003
11716 +++ linux/net/ipsec/aes/aes.c Mon Feb 9 13:51:03 2004
11717 @@ -0,0 +1,1427 @@
11718 +// I retain copyright in this code but I encourage its free use provided
11719 +// that I don't carry any responsibility for the results. I am especially
11720 +// happy to see it used in free and open source software. If you do use
11721 +// it I would appreciate an acknowledgement of its origin in the code or
11722 +// the product that results and I would also appreciate knowing a little
11723 +// about the use to which it is being put. I am grateful to Frank Yellin
11724 +// for some ideas that are used in this implementation.
11725 +//
11726 +// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
11727 +//
11728 +// This is an implementation of the AES encryption algorithm (Rijndael)
11729 +// designed by Joan Daemen and Vincent Rijmen. This version is designed
11730 +// to provide both fixed and dynamic block and key lengths and can also
11731 +// run with either big or little endian internal byte order (see aes.h).
11732 +// It inputs block and key lengths in bytes with the legal values being
11733 +// 16, 24 and 32.
11734 +
11735 +/*
11736 + * Modified by Jari Ruusu, May 1 2001
11737 + * - Fixed some compile warnings, code was ok but gcc warned anyway.
11738 + * - Changed basic types: byte -> unsigned char, word -> u_int32_t
11739 + * - Major name space cleanup: Names visible to outside now begin
11740 + * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
11741 + * - Removed C++ and DLL support as part of name space cleanup.
11742 + * - Eliminated unnecessary recomputation of tables. (actual bug fix)
11743 + * - Merged precomputed constant tables to aes.c file.
11744 + * - Removed data alignment restrictions for portability reasons.
11745 + * - Made block and key lengths accept bit count (128/192/256)
11746 + * as well byte count (16/24/32).
11747 + * - Removed all error checks. This change also eliminated the need
11748 + * to preinitialize the context struct to zero.
11749 + * - Removed some totally unused constants.
11750 + */
11751 +
11752 +#include "klips-crypto/aes.h"
11753 +
11754 +#ifdef OCF_ASSIST
11755 +#include "klips-crypto/ocf_assist.h"
11756 +#endif
11757 +
11758 +// CONFIGURATION OPTIONS (see also aes.h)
11759 +//
11760 +// 1. Define UNROLL for full loop unrolling in encryption and decryption.
11761 +// 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption.
11762 +// 3. Define FIXED_TABLES for compiled rather than dynamic tables.
11763 +// 4. Define FF_TABLES to use tables for field multiplies and inverses.
11764 +// Do not enable this without understanding stack space requirements.
11765 +// 5. Define ARRAYS to use arrays to hold the local state block. If this
11766 +// is not defined, individually declared 32-bit words are used.
11767 +// 6. Define FAST_VARIABLE if a high speed variable block implementation
11768 +// is needed (essentially three separate fixed block size code sequences)
11769 +// 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven
11770 +// version using 1 table (2 kbytes of table space) or 4 tables (8
11771 +// kbytes of table space) for higher speed.
11772 +// 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed
11773 +// increase by using tables for the last rounds but with more table
11774 +// space (2 or 8 kbytes extra).
11775 +// 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but
11776 +// slower version is provided.
11777 +// 10. If fast decryption key scheduling is needed define ONE_IM_TABLE
11778 +// or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra).
11779 +
11780 +#define UNROLL
11781 +//#define PARTIAL_UNROLL
11782 +
11783 +#define FIXED_TABLES
11784 +//#define FF_TABLES
11785 +//#define ARRAYS
11786 +#define FAST_VARIABLE
11787 +
11788 +//#define ONE_TABLE
11789 +#define FOUR_TABLES
11790 +
11791 +//#define ONE_LR_TABLE
11792 +#define FOUR_LR_TABLES
11793 +
11794 +//#define ONE_IM_TABLE
11795 +#define FOUR_IM_TABLES
11796 +
11797 +#if defined(UNROLL) && defined (PARTIAL_UNROLL)
11798 +#error both UNROLL and PARTIAL_UNROLL are defined
11799 +#endif
11800 +
11801 +#if defined(ONE_TABLE) && defined (FOUR_TABLES)
11802 +#error both ONE_TABLE and FOUR_TABLES are defined
11803 +#endif
11804 +
11805 +#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES)
11806 +#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined
11807 +#endif
11808 +
11809 +#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES)
11810 +#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined
11811 +#endif
11812 +
11813 +#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32
11814 +#error an illegal block size has been specified
11815 +#endif
11816 +
11817 +// upr(x,n): rotates bytes within words by n positions, moving bytes
11818 +// to higher index positions with wrap around into low positions
11819 +// ups(x,n): moves bytes by n positions to higher index positions in
11820 +// words but without wrap around
11821 +// bval(x,n): extracts a byte from a word
11822 +
11823 +#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n))))
11824 +#define ups(x,n) ((x) << 8 * (n))
11825 +#define bval(x,n) ((unsigned char)((x) >> 8 * (n)))
11826 +#define bytes2word(b0, b1, b2, b3) \
11827 + ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0))
11828 +
11829 +
11830 +/* little endian processor without data alignment restrictions: AES_LE_OK */
11831 +/* original code: i386 */
11832 +#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386)
11833 +#define AES_LE_OK 1
11834 +/* added (tested): alpha --jjo */
11835 +#elif defined(__alpha__)|| defined (__alpha)
11836 +#define AES_LE_OK 1
11837 +/* added (tested): ia64 --jjo */
11838 +#elif defined(__ia64__)|| defined (__ia64)
11839 +#define AES_LE_OK 1
11840 +#endif
11841 +
11842 +#ifdef AES_LE_OK
11843 +/* little endian processor without data alignment restrictions */
11844 +#define word_in(x) *(u_int32_t*)(x)
11845 +#define const_word_in(x) *(const u_int32_t*)(x)
11846 +#define word_out(x,v) *(u_int32_t*)(x) = (v)
11847 +#define const_word_out(x,v) *(const u_int32_t*)(x) = (v)
11848 +#else
11849 +/* slower but generic big endian or with data alignment restrictions */
11850 +/* some additional "const" touches to stop "gcc -Wcast-qual" complains --jjo */
11851 +#define word_in(x) ((u_int32_t)(((unsigned char *)(x))[0])|((u_int32_t)(((unsigned char *)(x))[1])<<8)|((u_int32_t)(((unsigned char *)(x))[2])<<16)|((u_int32_t)(((unsigned char *)(x))[3])<<24))
11852 +#define const_word_in(x) ((const u_int32_t)(((const unsigned char *)(x))[0])|((const u_int32_t)(((const unsigned char *)(x))[1])<<8)|((const u_int32_t)(((const unsigned char *)(x))[2])<<16)|((const u_int32_t)(((const unsigned char *)(x))[3])<<24))
11853 +#define word_out(x,v) ((unsigned char *)(x))[0]=(v),((unsigned char *)(x))[1]=((v)>>8),((unsigned char *)(x))[2]=((v)>>16),((unsigned char *)(x))[3]=((v)>>24)
11854 +#define const_word_out(x,v) ((const unsigned char *)(x))[0]=(v),((const unsigned char *)(x))[1]=((v)>>8),((const unsigned char *)(x))[2]=((v)>>16),((const unsigned char *)(x))[3]=((v)>>24)
11855 +#endif
11856 +
11857 +// Disable at least some poor combinations of options
11858 +
11859 +#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
11860 +#define FIXED_TABLES
11861 +#undef UNROLL
11862 +#undef ONE_LR_TABLE
11863 +#undef FOUR_LR_TABLES
11864 +#undef ONE_IM_TABLE
11865 +#undef FOUR_IM_TABLES
11866 +#elif !defined(FOUR_TABLES)
11867 +#ifdef FOUR_LR_TABLES
11868 +#undef FOUR_LR_TABLES
11869 +#define ONE_LR_TABLE
11870 +#endif
11871 +#ifdef FOUR_IM_TABLES
11872 +#undef FOUR_IM_TABLES
11873 +#define ONE_IM_TABLE
11874 +#endif
11875 +#elif !defined(AES_BLOCK_SIZE)
11876 +#if defined(UNROLL)
11877 +#define PARTIAL_UNROLL
11878 +#undef UNROLL
11879 +#endif
11880 +#endif
11881 +
11882 +// the finite field modular polynomial and elements
11883 +
11884 +#define ff_poly 0x011b
11885 +#define ff_hi 0x80
11886 +
11887 +// multiply four bytes in GF(2^8) by 'x' {02} in parallel
11888 +
11889 +#define m1 0x80808080
11890 +#define m2 0x7f7f7f7f
11891 +#define m3 0x0000001b
11892 +#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3))
11893 +
11894 +// The following defines provide alternative definitions of FFmulX that might
11895 +// give improved performance if a fast 32-bit multiply is not available. Note
11896 +// that a temporary variable u needs to be defined where FFmulX is used.
11897 +
11898 +// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
11899 +// #define m4 0x1b1b1b1b
11900 +// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
11901 +
11902 +// perform column mix operation on four bytes in parallel
11903 +
11904 +#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1))
11905 +
11906 +#if defined(FIXED_TABLES)
11907 +
11908 +// the S-Box table
11909 +
11910 +static const unsigned char s_box[256] =
11911 +{
11912 + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
11913 + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
11914 + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
11915 + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
11916 + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
11917 + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
11918 + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
11919 + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
11920 + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
11921 + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
11922 + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
11923 + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
11924 + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
11925 + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
11926 + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
11927 + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
11928 + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
11929 + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
11930 + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
11931 + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
11932 + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
11933 + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
11934 + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
11935 + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
11936 + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
11937 + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
11938 + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
11939 + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
11940 + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
11941 + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
11942 + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
11943 + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
11944 +};
11945 +
11946 +// the inverse S-Box table
11947 +
11948 +static const unsigned char inv_s_box[256] =
11949 +{
11950 + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
11951 + 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
11952 + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
11953 + 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
11954 + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
11955 + 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
11956 + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
11957 + 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
11958 + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
11959 + 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
11960 + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
11961 + 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
11962 + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
11963 + 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
11964 + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
11965 + 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
11966 + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
11967 + 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
11968 + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
11969 + 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
11970 + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
11971 + 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
11972 + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
11973 + 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
11974 + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
11975 + 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
11976 + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
11977 + 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
11978 + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
11979 + 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
11980 + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
11981 + 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
11982 +};
11983 +
11984 +#define w0(p) 0x000000##p
11985 +
11986 +// Number of elements required in this table for different
11987 +// block and key lengths is:
11988 +//
11989 +// Nk = 4 6 8
11990 +// ----------
11991 +// Nb = 4 | 10 8 7
11992 +// 6 | 19 12 11
11993 +// 8 | 29 19 14
11994 +//
11995 +// this table can be a table of bytes if the key schedule
11996 +// code is adjusted accordingly
11997 +
11998 +static const u_int32_t rcon_tab[29] =
11999 +{
12000 + w0(01), w0(02), w0(04), w0(08),
12001 + w0(10), w0(20), w0(40), w0(80),
12002 + w0(1b), w0(36), w0(6c), w0(d8),
12003 + w0(ab), w0(4d), w0(9a), w0(2f),
12004 + w0(5e), w0(bc), w0(63), w0(c6),
12005 + w0(97), w0(35), w0(6a), w0(d4),
12006 + w0(b3), w0(7d), w0(fa), w0(ef),
12007 + w0(c5)
12008 +};
12009 +
12010 +#undef w0
12011 +
12012 +#define r0(p,q,r,s) 0x##p##q##r##s
12013 +#define r1(p,q,r,s) 0x##q##r##s##p
12014 +#define r2(p,q,r,s) 0x##r##s##p##q
12015 +#define r3(p,q,r,s) 0x##s##p##q##r
12016 +#define w0(p) 0x000000##p
12017 +#define w1(p) 0x0000##p##00
12018 +#define w2(p) 0x00##p##0000
12019 +#define w3(p) 0x##p##000000
12020 +
12021 +#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES))
12022 +
12023 +// data for forward tables (other than last round)
12024 +
12025 +#define f_table \
12026 + r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\
12027 + r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\
12028 + r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\
12029 + r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\
12030 + r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\
12031 + r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\
12032 + r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\
12033 + r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\
12034 + r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\
12035 + r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\
12036 + r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\
12037 + r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\
12038 + r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\
12039 + r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\
12040 + r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\
12041 + r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\
12042 + r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\
12043 + r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\
12044 + r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\
12045 + r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\
12046 + r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\
12047 + r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\
12048 + r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\
12049 + r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\
12050 + r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\
12051 + r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\
12052 + r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\
12053 + r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\
12054 + r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\
12055 + r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\
12056 + r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\
12057 + r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\
12058 + r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\
12059 + r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\
12060 + r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\
12061 + r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\
12062 + r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\
12063 + r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\
12064 + r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\
12065 + r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\
12066 + r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\
12067 + r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\
12068 + r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\
12069 + r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\
12070 + r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\
12071 + r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\
12072 + r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\
12073 + r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\
12074 + r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\
12075 + r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\
12076 + r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\
12077 + r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\
12078 + r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\
12079 + r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\
12080 + r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\
12081 + r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\
12082 + r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\
12083 + r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\
12084 + r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\
12085 + r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\
12086 + r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\
12087 + r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\
12088 + r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\
12089 + r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c)
12090 +
12091 +// data for inverse tables (other than last round)
12092 +
12093 +#define i_table \
12094 + r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\
12095 + r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\
12096 + r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\
12097 + r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\
12098 + r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\
12099 + r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\
12100 + r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\
12101 + r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\
12102 + r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\
12103 + r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\
12104 + r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\
12105 + r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\
12106 + r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\
12107 + r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\
12108 + r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\
12109 + r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\
12110 + r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\
12111 + r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\
12112 + r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\
12113 + r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\
12114 + r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\
12115 + r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\
12116 + r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\
12117 + r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\
12118 + r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\
12119 + r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\
12120 + r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\
12121 + r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\
12122 + r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\
12123 + r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\
12124 + r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\
12125 + r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\
12126 + r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\
12127 + r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\
12128 + r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\
12129 + r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\
12130 + r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\
12131 + r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\
12132 + r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\
12133 + r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\
12134 + r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\
12135 + r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\
12136 + r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\
12137 + r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\
12138 + r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\
12139 + r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\
12140 + r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\
12141 + r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\
12142 + r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\
12143 + r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\
12144 + r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\
12145 + r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\
12146 + r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\
12147 + r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\
12148 + r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\
12149 + r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\
12150 + r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\
12151 + r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\
12152 + r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\
12153 + r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\
12154 + r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\
12155 + r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\
12156 + r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\
12157 + r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0)
12158 +
12159 +// generate the required tables in the desired endian format
12160 +
12161 +#undef r
12162 +#define r r0
12163 +
12164 +#if defined(ONE_TABLE)
12165 +static const u_int32_t ft_tab[256] =
12166 + { f_table };
12167 +#elif defined(FOUR_TABLES)
12168 +static const u_int32_t ft_tab[4][256] =
12169 +{ { f_table },
12170 +#undef r
12171 +#define r r1
12172 + { f_table },
12173 +#undef r
12174 +#define r r2
12175 + { f_table },
12176 +#undef r
12177 +#define r r3
12178 + { f_table }
12179 +};
12180 +#endif
12181 +
12182 +#undef r
12183 +#define r r0
12184 +#if defined(ONE_TABLE)
12185 +static const u_int32_t it_tab[256] =
12186 + { i_table };
12187 +#elif defined(FOUR_TABLES)
12188 +static const u_int32_t it_tab[4][256] =
12189 +{ { i_table },
12190 +#undef r
12191 +#define r r1
12192 + { i_table },
12193 +#undef r
12194 +#define r r2
12195 + { i_table },
12196 +#undef r
12197 +#define r r3
12198 + { i_table }
12199 +};
12200 +#endif
12201 +
12202 +#endif
12203 +
12204 +#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES))
12205 +
12206 +// data for inverse tables (last round)
12207 +
12208 +#define li_table \
12209 + w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\
12210 + w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\
12211 + w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\
12212 + w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\
12213 + w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\
12214 + w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\
12215 + w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\
12216 + w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\
12217 + w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\
12218 + w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\
12219 + w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\
12220 + w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\
12221 + w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\
12222 + w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\
12223 + w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\
12224 + w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\
12225 + w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\
12226 + w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\
12227 + w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\
12228 + w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\
12229 + w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\
12230 + w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\
12231 + w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\
12232 + w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\
12233 + w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\
12234 + w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\
12235 + w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\
12236 + w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\
12237 + w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\
12238 + w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\
12239 + w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\
12240 + w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d),
12241 +
12242 +// generate the required tables in the desired endian format
12243 +
12244 +#undef r
12245 +#define r(p,q,r,s) w0(q)
12246 +#if defined(ONE_LR_TABLE)
12247 +static const u_int32_t fl_tab[256] =
12248 + { f_table };
12249 +#elif defined(FOUR_LR_TABLES)
12250 +static const u_int32_t fl_tab[4][256] =
12251 +{ { f_table },
12252 +#undef r
12253 +#define r(p,q,r,s) w1(q)
12254 + { f_table },
12255 +#undef r
12256 +#define r(p,q,r,s) w2(q)
12257 + { f_table },
12258 +#undef r
12259 +#define r(p,q,r,s) w3(q)
12260 + { f_table }
12261 +};
12262 +#endif
12263 +
12264 +#undef w
12265 +#define w w0
12266 +#if defined(ONE_LR_TABLE)
12267 +static const u_int32_t il_tab[256] =
12268 + { li_table };
12269 +#elif defined(FOUR_LR_TABLES)
12270 +static const u_int32_t il_tab[4][256] =
12271 +{ { li_table },
12272 +#undef w
12273 +#define w w1
12274 + { li_table },
12275 +#undef w
12276 +#define w w2
12277 + { li_table },
12278 +#undef w
12279 +#define w w3
12280 + { li_table }
12281 +};
12282 +#endif
12283 +
12284 +#endif
12285 +
12286 +#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES))
12287 +
12288 +#define m_table \
12289 + r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\
12290 + r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\
12291 + r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\
12292 + r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\
12293 + r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\
12294 + r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\
12295 + r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\
12296 + r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\
12297 + r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\
12298 + r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\
12299 + r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\
12300 + r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\
12301 + r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\
12302 + r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\
12303 + r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\
12304 + r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\
12305 + r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\
12306 + r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\
12307 + r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\
12308 + r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\
12309 + r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\
12310 + r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\
12311 + r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\
12312 + r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\
12313 + r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\
12314 + r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\
12315 + r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\
12316 + r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\
12317 + r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\
12318 + r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\
12319 + r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\
12320 + r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\
12321 + r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\
12322 + r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\
12323 + r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\
12324 + r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\
12325 + r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\
12326 + r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\
12327 + r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\
12328 + r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\
12329 + r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\
12330 + r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\
12331 + r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\
12332 + r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\
12333 + r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\
12334 + r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\
12335 + r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\
12336 + r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\
12337 + r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\
12338 + r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\
12339 + r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\
12340 + r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\
12341 + r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\
12342 + r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\
12343 + r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\
12344 + r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\
12345 + r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\
12346 + r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\
12347 + r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\
12348 + r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\
12349 + r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\
12350 + r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\
12351 + r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\
12352 + r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d)
12353 +
12354 +#undef r
12355 +#define r r0
12356 +
12357 +#if defined(ONE_IM_TABLE)
12358 +static const u_int32_t im_tab[256] =
12359 + { m_table };
12360 +#elif defined(FOUR_IM_TABLES)
12361 +static const u_int32_t im_tab[4][256] =
12362 +{ { m_table },
12363 +#undef r
12364 +#define r r1
12365 + { m_table },
12366 +#undef r
12367 +#define r r2
12368 + { m_table },
12369 +#undef r
12370 +#define r r3
12371 + { m_table }
12372 +};
12373 +#endif
12374 +
12375 +#endif
12376 +
12377 +#else
12378 +
12379 +static int tab_gen = 0;
12380 +
12381 +static unsigned char s_box[256]; // the S box
12382 +static unsigned char inv_s_box[256]; // the inverse S box
12383 +static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants
12384 +
12385 +#if defined(ONE_TABLE)
12386 +static u_int32_t ft_tab[256];
12387 +static u_int32_t it_tab[256];
12388 +#elif defined(FOUR_TABLES)
12389 +static u_int32_t ft_tab[4][256];
12390 +static u_int32_t it_tab[4][256];
12391 +#endif
12392 +
12393 +#if defined(ONE_LR_TABLE)
12394 +static u_int32_t fl_tab[256];
12395 +static u_int32_t il_tab[256];
12396 +#elif defined(FOUR_LR_TABLES)
12397 +static u_int32_t fl_tab[4][256];
12398 +static u_int32_t il_tab[4][256];
12399 +#endif
12400 +
12401 +#if defined(ONE_IM_TABLE)
12402 +static u_int32_t im_tab[256];
12403 +#elif defined(FOUR_IM_TABLES)
12404 +static u_int32_t im_tab[4][256];
12405 +#endif
12406 +
12407 +// Generate the tables for the dynamic table option
12408 +
12409 +#if !defined(FF_TABLES)
12410 +
12411 +// It will generally be sensible to use tables to compute finite
12412 +// field multiplies and inverses but where memory is scarse this
12413 +// code might sometimes be better.
12414 +
12415 +// return 2 ^ (n - 1) where n is the bit number of the highest bit
12416 +// set in x with x in the range 1 < x < 0x00000200. This form is
12417 +// used so that locals within FFinv can be bytes rather than words
12418 +
12419 +static unsigned char hibit(const u_int32_t x)
12420 +{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2));
12421 +
12422 + r |= (r >> 2);
12423 + r |= (r >> 4);
12424 + return (r + 1) >> 1;
12425 +}
12426 +
12427 +// return the inverse of the finite field element x
12428 +
12429 +static unsigned char FFinv(const unsigned char x)
12430 +{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
12431 +
12432 + if(x < 2) return x;
12433 +
12434 + for(;;)
12435 + {
12436 + if(!n1) return v1;
12437 +
12438 + while(n2 >= n1)
12439 + {
12440 + n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
12441 + }
12442 +
12443 + if(!n2) return v2;
12444 +
12445 + while(n1 >= n2)
12446 + {
12447 + n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
12448 + }
12449 + }
12450 +}
12451 +
12452 +// define the finite field multiplies required for Rijndael
12453 +
12454 +#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0))
12455 +#define FFmul03(x) ((x) ^ FFmul02(x))
12456 +#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x))))
12457 +#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x))))
12458 +#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x))))
12459 +#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x)))
12460 +
12461 +#else
12462 +
12463 +#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
12464 +
12465 +#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
12466 +#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
12467 +#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
12468 +#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
12469 +#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
12470 +#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
12471 +
12472 +#endif
12473 +
12474 +// The forward and inverse affine transformations used in the S-box
12475 +
12476 +#define fwd_affine(x) \
12477 + (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8)))
12478 +
12479 +#define inv_affine(x) \
12480 + (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8)))
12481 +
12482 +static void gen_tabs(void)
12483 +{ u_int32_t i, w;
12484 +
12485 +#if defined(FF_TABLES)
12486 +
12487 + unsigned char pow[512], log[256];
12488 +
12489 + // log and power tables for GF(2^8) finite field with
12490 + // 0x011b as modular polynomial - the simplest primitive
12491 + // root is 0x03, used here to generate the tables
12492 +
12493 + i = 0; w = 1;
12494 + do
12495 + {
12496 + pow[i] = (unsigned char)w;
12497 + pow[i + 255] = (unsigned char)w;
12498 + log[w] = (unsigned char)i++;
12499 + w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
12500 + }
12501 + while (w != 1);
12502 +
12503 +#endif
12504 +
12505 + for(i = 0, w = 1; i < AES_RC_LENGTH; ++i)
12506 + {
12507 + rcon_tab[i] = bytes2word(w, 0, 0, 0);
12508 + w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
12509 + }
12510 +
12511 + for(i = 0; i < 256; ++i)
12512 + { unsigned char b;
12513 +
12514 + s_box[i] = b = fwd_affine(FFinv((unsigned char)i));
12515 +
12516 + w = bytes2word(b, 0, 0, 0);
12517 +#if defined(ONE_LR_TABLE)
12518 + fl_tab[i] = w;
12519 +#elif defined(FOUR_LR_TABLES)
12520 + fl_tab[0][i] = w;
12521 + fl_tab[1][i] = upr(w,1);
12522 + fl_tab[2][i] = upr(w,2);
12523 + fl_tab[3][i] = upr(w,3);
12524 +#endif
12525 + w = bytes2word(FFmul02(b), b, b, FFmul03(b));
12526 +#if defined(ONE_TABLE)
12527 + ft_tab[i] = w;
12528 +#elif defined(FOUR_TABLES)
12529 + ft_tab[0][i] = w;
12530 + ft_tab[1][i] = upr(w,1);
12531 + ft_tab[2][i] = upr(w,2);
12532 + ft_tab[3][i] = upr(w,3);
12533 +#endif
12534 + inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i));
12535 +
12536 + w = bytes2word(b, 0, 0, 0);
12537 +#if defined(ONE_LR_TABLE)
12538 + il_tab[i] = w;
12539 +#elif defined(FOUR_LR_TABLES)
12540 + il_tab[0][i] = w;
12541 + il_tab[1][i] = upr(w,1);
12542 + il_tab[2][i] = upr(w,2);
12543 + il_tab[3][i] = upr(w,3);
12544 +#endif
12545 + w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b));
12546 +#if defined(ONE_TABLE)
12547 + it_tab[i] = w;
12548 +#elif defined(FOUR_TABLES)
12549 + it_tab[0][i] = w;
12550 + it_tab[1][i] = upr(w,1);
12551 + it_tab[2][i] = upr(w,2);
12552 + it_tab[3][i] = upr(w,3);
12553 +#endif
12554 +#if defined(ONE_IM_TABLE)
12555 + im_tab[b] = w;
12556 +#elif defined(FOUR_IM_TABLES)
12557 + im_tab[0][b] = w;
12558 + im_tab[1][b] = upr(w,1);
12559 + im_tab[2][b] = upr(w,2);
12560 + im_tab[3][b] = upr(w,3);
12561 +#endif
12562 +
12563 + }
12564 +}
12565 +
12566 +#endif
12567 +
12568 +#define no_table(x,box,vf,rf,c) bytes2word( \
12569 + box[bval(vf(x,0,c),rf(0,c))], \
12570 + box[bval(vf(x,1,c),rf(1,c))], \
12571 + box[bval(vf(x,2,c),rf(2,c))], \
12572 + box[bval(vf(x,3,c),rf(3,c))])
12573 +
12574 +#define one_table(x,op,tab,vf,rf,c) \
12575 + ( tab[bval(vf(x,0,c),rf(0,c))] \
12576 + ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
12577 + ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
12578 + ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
12579 +
12580 +#define four_tables(x,tab,vf,rf,c) \
12581 + ( tab[0][bval(vf(x,0,c),rf(0,c))] \
12582 + ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
12583 + ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
12584 + ^ tab[3][bval(vf(x,3,c),rf(3,c))])
12585 +
12586 +#define vf1(x,r,c) (x)
12587 +#define rf1(r,c) (r)
12588 +#define rf2(r,c) ((r-c)&3)
12589 +
12590 +#if defined(FOUR_LR_TABLES)
12591 +#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
12592 +#elif defined(ONE_LR_TABLE)
12593 +#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
12594 +#else
12595 +#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
12596 +#endif
12597 +
12598 +#if defined(FOUR_IM_TABLES)
12599 +#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
12600 +#elif defined(ONE_IM_TABLE)
12601 +#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
12602 +#else
12603 +#define inv_mcol(x) \
12604 + (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
12605 + f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
12606 +#endif
12607 +
12608 +// Subroutine to set the block size (if variable) in bytes, legal
12609 +// values being 16, 24 and 32.
12610 +
12611 +#if defined(AES_BLOCK_SIZE)
12612 +#define nc (AES_BLOCK_SIZE / 4)
12613 +#else
12614 +#define nc (cx->aes_Ncol)
12615 +
12616 +void aes_set_blk(aes_context *cx, int n_bytes)
12617 +{
12618 +#if !defined(FIXED_TABLES)
12619 + if(!tab_gen) { gen_tabs(); tab_gen = 1; }
12620 +#endif
12621 +
12622 + switch(n_bytes) {
12623 + case 32: /* bytes */
12624 + case 256: /* bits */
12625 + nc = 8;
12626 + break;
12627 + case 24: /* bytes */
12628 + case 192: /* bits */
12629 + nc = 6;
12630 + break;
12631 + case 16: /* bytes */
12632 + case 128: /* bits */
12633 + default:
12634 + nc = 4;
12635 + break;
12636 + }
12637 +}
12638 +
12639 +#endif
12640 +
12641 +// Initialise the key schedule from the user supplied key. The key
12642 +// length is now specified in bytes - 16, 24 or 32 as appropriate.
12643 +// This corresponds to bit lengths of 128, 192 and 256 bits, and
12644 +// to Nk values of 4, 6 and 8 respectively.
12645 +
12646 +#define mx(t,f) (*t++ = inv_mcol(*f),f++)
12647 +#define cp(t,f) *t++ = *f++
12648 +
12649 +#if AES_BLOCK_SIZE == 16
12650 +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s)
12651 +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s)
12652 +#elif AES_BLOCK_SIZE == 24
12653 +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
12654 + cp(d,s); cp(d,s)
12655 +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
12656 + mx(d,s); mx(d,s)
12657 +#elif AES_BLOCK_SIZE == 32
12658 +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
12659 + cp(d,s); cp(d,s); cp(d,s); cp(d,s)
12660 +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
12661 + mx(d,s); mx(d,s); mx(d,s); mx(d,s)
12662 +#else
12663 +
12664 +#define cpy(d,s) \
12665 +switch(nc) \
12666 +{ case 8: cp(d,s); cp(d,s); \
12667 + case 6: cp(d,s); cp(d,s); \
12668 + case 4: cp(d,s); cp(d,s); \
12669 + cp(d,s); cp(d,s); \
12670 +}
12671 +
12672 +#define mix(d,s) \
12673 +switch(nc) \
12674 +{ case 8: mx(d,s); mx(d,s); \
12675 + case 6: mx(d,s); mx(d,s); \
12676 + case 4: mx(d,s); mx(d,s); \
12677 + mx(d,s); mx(d,s); \
12678 +}
12679 +
12680 +#endif
12681 +
12682 +void aes_set_key(aes_context *cx, const unsigned char in_key[], int n_bytes, const int f)
12683 +{ u_int32_t *kf, *kt, rci;
12684 +
12685 +#if !defined(FIXED_TABLES)
12686 + if(!tab_gen) { gen_tabs(); tab_gen = 1; }
12687 +#endif
12688 +
12689 +/* only need to do a special set_key for the cryptodev hw acceleration */
12690 +#ifdef OCF_ASSIST
12691 + if (ocf_aes_assist() & OCF_PROVIDES_AES) {
12692 + ocf_aes_set_key(cx, in_key, n_bytes, f);
12693 + return;
12694 + }
12695 +#endif
12696 +
12697 + switch(n_bytes) {
12698 + case 32: /* bytes */
12699 + case 256: /* bits */
12700 + cx->aes_Nkey = 8;
12701 + break;
12702 + case 24: /* bytes */
12703 + case 192: /* bits */
12704 + cx->aes_Nkey = 6;
12705 + break;
12706 + case 16: /* bytes */
12707 + case 128: /* bits */
12708 + default:
12709 + cx->aes_Nkey = 4;
12710 + break;
12711 + }
12712 +
12713 + cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6;
12714 +
12715 + cx->aes_e_key[0] = const_word_in(in_key );
12716 + cx->aes_e_key[1] = const_word_in(in_key + 4);
12717 + cx->aes_e_key[2] = const_word_in(in_key + 8);
12718 + cx->aes_e_key[3] = const_word_in(in_key + 12);
12719 +
12720 + kf = cx->aes_e_key;
12721 + kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey;
12722 + rci = 0;
12723 +
12724 + switch(cx->aes_Nkey)
12725 + {
12726 + case 4: do
12727 + { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++];
12728 + kf[5] = kf[1] ^ kf[4];
12729 + kf[6] = kf[2] ^ kf[5];
12730 + kf[7] = kf[3] ^ kf[6];
12731 + kf += 4;
12732 + }
12733 + while(kf < kt);
12734 + break;
12735 +
12736 + case 6: cx->aes_e_key[4] = const_word_in(in_key + 16);
12737 + cx->aes_e_key[5] = const_word_in(in_key + 20);
12738 + do
12739 + { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++];
12740 + kf[ 7] = kf[1] ^ kf[ 6];
12741 + kf[ 8] = kf[2] ^ kf[ 7];
12742 + kf[ 9] = kf[3] ^ kf[ 8];
12743 + kf[10] = kf[4] ^ kf[ 9];
12744 + kf[11] = kf[5] ^ kf[10];
12745 + kf += 6;
12746 + }
12747 + while(kf < kt);
12748 + break;
12749 +
12750 + case 8: cx->aes_e_key[4] = const_word_in(in_key + 16);
12751 + cx->aes_e_key[5] = const_word_in(in_key + 20);
12752 + cx->aes_e_key[6] = const_word_in(in_key + 24);
12753 + cx->aes_e_key[7] = const_word_in(in_key + 28);
12754 + do
12755 + { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++];
12756 + kf[ 9] = kf[1] ^ kf[ 8];
12757 + kf[10] = kf[2] ^ kf[ 9];
12758 + kf[11] = kf[3] ^ kf[10];
12759 + kf[12] = kf[4] ^ ls_box(kf[11],0);
12760 + kf[13] = kf[5] ^ kf[12];
12761 + kf[14] = kf[6] ^ kf[13];
12762 + kf[15] = kf[7] ^ kf[14];
12763 + kf += 8;
12764 + }
12765 + while (kf < kt);
12766 + break;
12767 + }
12768 +
12769 + if(!f)
12770 + { u_int32_t i;
12771 +
12772 + kt = cx->aes_d_key + nc * cx->aes_Nrnd;
12773 + kf = cx->aes_e_key;
12774 +
12775 + cpy(kt, kf); kt -= 2 * nc;
12776 +
12777 + for(i = 1; i < cx->aes_Nrnd; ++i)
12778 + {
12779 +#if defined(ONE_TABLE) || defined(FOUR_TABLES)
12780 +#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES)
12781 + u_int32_t f2, f4, f8, f9;
12782 +#endif
12783 + mix(kt, kf);
12784 +#else
12785 + cpy(kt, kf);
12786 +#endif
12787 + kt -= 2 * nc;
12788 + }
12789 +
12790 + cpy(kt, kf);
12791 + }
12792 +}
12793 +
12794 +// y = output word, x = input word, r = row, c = column
12795 +// for r = 0, 1, 2 and 3 = column accessed for row r
12796 +
12797 +#if defined(ARRAYS)
12798 +#define s(x,c) x[c]
12799 +#else
12800 +#define s(x,c) x##c
12801 +#endif
12802 +
12803 +// I am grateful to Frank Yellin for the following constructions
12804 +// which, given the column (c) of the output state variable that
12805 +// is being computed, return the input state variables which are
12806 +// needed for each row (r) of the state
12807 +
12808 +// For the fixed block size options, compilers reduce these two
12809 +// expressions to fixed variable references. For variable block
12810 +// size code conditional clauses will sometimes be returned
12811 +
12812 +#define unused 77 // Sunset Strip
12813 +
12814 +#define fwd_var(x,r,c) \
12815 + ( r==0 ? \
12816 + ( c==0 ? s(x,0) \
12817 + : c==1 ? s(x,1) \
12818 + : c==2 ? s(x,2) \
12819 + : c==3 ? s(x,3) \
12820 + : c==4 ? s(x,4) \
12821 + : c==5 ? s(x,5) \
12822 + : c==6 ? s(x,6) \
12823 + : s(x,7)) \
12824 + : r==1 ? \
12825 + ( c==0 ? s(x,1) \
12826 + : c==1 ? s(x,2) \
12827 + : c==2 ? s(x,3) \
12828 + : c==3 ? nc==4 ? s(x,0) : s(x,4) \
12829 + : c==4 ? s(x,5) \
12830 + : c==5 ? nc==8 ? s(x,6) : s(x,0) \
12831 + : c==6 ? s(x,7) \
12832 + : s(x,0)) \
12833 + : r==2 ? \
12834 + ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
12835 + : c==1 ? nc==8 ? s(x,4) : s(x,3) \
12836 + : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
12837 + : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
12838 + : c==4 ? nc==8 ? s(x,7) : s(x,0) \
12839 + : c==5 ? nc==8 ? s(x,0) : s(x,1) \
12840 + : c==6 ? s(x,1) \
12841 + : s(x,2)) \
12842 + : \
12843 + ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
12844 + : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
12845 + : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
12846 + : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
12847 + : c==4 ? nc==8 ? s(x,0) : s(x,1) \
12848 + : c==5 ? nc==8 ? s(x,1) : s(x,2) \
12849 + : c==6 ? s(x,2) \
12850 + : s(x,3)))
12851 +
12852 +#define inv_var(x,r,c) \
12853 + ( r==0 ? \
12854 + ( c==0 ? s(x,0) \
12855 + : c==1 ? s(x,1) \
12856 + : c==2 ? s(x,2) \
12857 + : c==3 ? s(x,3) \
12858 + : c==4 ? s(x,4) \
12859 + : c==5 ? s(x,5) \
12860 + : c==6 ? s(x,6) \
12861 + : s(x,7)) \
12862 + : r==1 ? \
12863 + ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \
12864 + : c==1 ? s(x,0) \
12865 + : c==2 ? s(x,1) \
12866 + : c==3 ? s(x,2) \
12867 + : c==4 ? s(x,3) \
12868 + : c==5 ? s(x,4) \
12869 + : c==6 ? s(x,5) \
12870 + : s(x,6)) \
12871 + : r==2 ? \
12872 + ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
12873 + : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
12874 + : c==2 ? nc==8 ? s(x,7) : s(x,0) \
12875 + : c==3 ? nc==8 ? s(x,0) : s(x,1) \
12876 + : c==4 ? nc==8 ? s(x,1) : s(x,2) \
12877 + : c==5 ? nc==8 ? s(x,2) : s(x,3) \
12878 + : c==6 ? s(x,3) \
12879 + : s(x,4)) \
12880 + : \
12881 + ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \
12882 + : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
12883 + : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
12884 + : c==3 ? nc==8 ? s(x,7) : s(x,0) \
12885 + : c==4 ? nc==8 ? s(x,0) : s(x,1) \
12886 + : c==5 ? nc==8 ? s(x,1) : s(x,2) \
12887 + : c==6 ? s(x,2) \
12888 + : s(x,3)))
12889 +
12890 +#define si(y,x,k,c) s(y,c) = const_word_in(x + 4 * c) ^ k[c]
12891 +#define so(y,x,c) word_out(y + 4 * c, s(x,c))
12892 +
12893 +#if defined(FOUR_TABLES)
12894 +#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
12895 +#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
12896 +#elif defined(ONE_TABLE)
12897 +#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
12898 +#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
12899 +#else
12900 +#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
12901 +#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
12902 +#endif
12903 +
12904 +#if defined(FOUR_LR_TABLES)
12905 +#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
12906 +#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
12907 +#elif defined(ONE_LR_TABLE)
12908 +#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
12909 +#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
12910 +#else
12911 +#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
12912 +#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
12913 +#endif
12914 +
12915 +#if AES_BLOCK_SIZE == 16
12916 +
12917 +#if defined(ARRAYS)
12918 +#define locals(y,x) x[4],y[4]
12919 +#else
12920 +#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
12921 +// the following defines prevent the compiler requiring the declaration
12922 +// of generated but unused variables in the fwd_var and inv_var macros
12923 +#define b04 unused
12924 +#define b05 unused
12925 +#define b06 unused
12926 +#define b07 unused
12927 +#define b14 unused
12928 +#define b15 unused
12929 +#define b16 unused
12930 +#define b17 unused
12931 +#endif
12932 +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
12933 + s(y,2) = s(x,2); s(y,3) = s(x,3);
12934 +#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
12935 +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
12936 +#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
12937 +
12938 +#elif AES_BLOCK_SIZE == 24
12939 +
12940 +#if defined(ARRAYS)
12941 +#define locals(y,x) x[6],y[6]
12942 +#else
12943 +#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
12944 + y##0,y##1,y##2,y##3,y##4,y##5
12945 +#define b06 unused
12946 +#define b07 unused
12947 +#define b16 unused
12948 +#define b17 unused
12949 +#endif
12950 +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
12951 + s(y,2) = s(x,2); s(y,3) = s(x,3); \
12952 + s(y,4) = s(x,4); s(y,5) = s(x,5);
12953 +#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
12954 + si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
12955 +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
12956 + so(y,x,3); so(y,x,4); so(y,x,5)
12957 +#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
12958 + rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
12959 +#else
12960 +
12961 +#if defined(ARRAYS)
12962 +#define locals(y,x) x[8],y[8]
12963 +#else
12964 +#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
12965 + y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
12966 +#endif
12967 +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
12968 + s(y,2) = s(x,2); s(y,3) = s(x,3); \
12969 + s(y,4) = s(x,4); s(y,5) = s(x,5); \
12970 + s(y,6) = s(x,6); s(y,7) = s(x,7);
12971 +
12972 +#if AES_BLOCK_SIZE == 32
12973 +
12974 +#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
12975 + si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
12976 +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
12977 + so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
12978 +#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
12979 + rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
12980 +#else
12981 +
12982 +#define state_in(y,x,k) \
12983 +switch(nc) \
12984 +{ case 8: si(y,x,k,7); si(y,x,k,6); \
12985 + case 6: si(y,x,k,5); si(y,x,k,4); \
12986 + case 4: si(y,x,k,3); si(y,x,k,2); \
12987 + si(y,x,k,1); si(y,x,k,0); \
12988 +}
12989 +
12990 +#define state_out(y,x) \
12991 +switch(nc) \
12992 +{ case 8: so(y,x,7); so(y,x,6); \
12993 + case 6: so(y,x,5); so(y,x,4); \
12994 + case 4: so(y,x,3); so(y,x,2); \
12995 + so(y,x,1); so(y,x,0); \
12996 +}
12997 +
12998 +#if defined(FAST_VARIABLE)
12999 +
13000 +#define round(rm,y,x,k) \
13001 +switch(nc) \
13002 +{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
13003 + rm(y,x,k,5); rm(y,x,k,4); \
13004 + rm(y,x,k,3); rm(y,x,k,2); \
13005 + rm(y,x,k,1); rm(y,x,k,0); \
13006 + break; \
13007 + case 6: rm(y,x,k,5); rm(y,x,k,4); \
13008 + rm(y,x,k,3); rm(y,x,k,2); \
13009 + rm(y,x,k,1); rm(y,x,k,0); \
13010 + break; \
13011 + case 4: rm(y,x,k,3); rm(y,x,k,2); \
13012 + rm(y,x,k,1); rm(y,x,k,0); \
13013 + break; \
13014 +}
13015 +#else
13016 +
13017 +#define round(rm,y,x,k) \
13018 +switch(nc) \
13019 +{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
13020 + case 6: rm(y,x,k,5); rm(y,x,k,4); \
13021 + case 4: rm(y,x,k,3); rm(y,x,k,2); \
13022 + rm(y,x,k,1); rm(y,x,k,0); \
13023 +}
13024 +
13025 +#endif
13026 +
13027 +#endif
13028 +#endif
13029 +
13030 +void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
13031 +{ u_int32_t locals(b0, b1);
13032 + const u_int32_t *kp = cx->aes_e_key;
13033 +
13034 +#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
13035 + u_int32_t f2;
13036 +#endif
13037 +
13038 + state_in(b0, in_blk, kp); kp += nc;
13039 +
13040 +#if defined(UNROLL)
13041 +
13042 + switch(cx->aes_Nrnd)
13043 + {
13044 + case 14: round(fwd_rnd, b1, b0, kp );
13045 + round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13046 + case 12: round(fwd_rnd, b1, b0, kp );
13047 + round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13048 + case 10: round(fwd_rnd, b1, b0, kp );
13049 + round(fwd_rnd, b0, b1, kp + nc);
13050 + round(fwd_rnd, b1, b0, kp + 2 * nc);
13051 + round(fwd_rnd, b0, b1, kp + 3 * nc);
13052 + round(fwd_rnd, b1, b0, kp + 4 * nc);
13053 + round(fwd_rnd, b0, b1, kp + 5 * nc);
13054 + round(fwd_rnd, b1, b0, kp + 6 * nc);
13055 + round(fwd_rnd, b0, b1, kp + 7 * nc);
13056 + round(fwd_rnd, b1, b0, kp + 8 * nc);
13057 + round(fwd_lrnd, b0, b1, kp + 9 * nc);
13058 + }
13059 +
13060 +#elif defined(PARTIAL_UNROLL)
13061 + { u_int32_t rnd;
13062 +
13063 + for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
13064 + {
13065 + round(fwd_rnd, b1, b0, kp);
13066 + round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc;
13067 + }
13068 +
13069 + round(fwd_rnd, b1, b0, kp);
13070 + round(fwd_lrnd, b0, b1, kp + nc);
13071 + }
13072 +#else
13073 + { u_int32_t rnd;
13074 +
13075 + for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
13076 + {
13077 + round(fwd_rnd, b1, b0, kp);
13078 + l_copy(b0, b1); kp += nc;
13079 + }
13080 +
13081 + round(fwd_lrnd, b0, b1, kp);
13082 + }
13083 +#endif
13084 +
13085 + state_out(out_blk, b0);
13086 +}
13087 +
13088 +void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
13089 +{ u_int32_t locals(b0, b1);
13090 + const u_int32_t *kp = cx->aes_d_key;
13091 +
13092 +#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
13093 + u_int32_t f2, f4, f8, f9;
13094 +#endif
13095 +
13096 + state_in(b0, in_blk, kp); kp += nc;
13097 +
13098 +#if defined(UNROLL)
13099 +
13100 + switch(cx->aes_Nrnd)
13101 + {
13102 + case 14: round(inv_rnd, b1, b0, kp );
13103 + round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13104 + case 12: round(inv_rnd, b1, b0, kp );
13105 + round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13106 + case 10: round(inv_rnd, b1, b0, kp );
13107 + round(inv_rnd, b0, b1, kp + nc);
13108 + round(inv_rnd, b1, b0, kp + 2 * nc);
13109 + round(inv_rnd, b0, b1, kp + 3 * nc);
13110 + round(inv_rnd, b1, b0, kp + 4 * nc);
13111 + round(inv_rnd, b0, b1, kp + 5 * nc);
13112 + round(inv_rnd, b1, b0, kp + 6 * nc);
13113 + round(inv_rnd, b0, b1, kp + 7 * nc);
13114 + round(inv_rnd, b1, b0, kp + 8 * nc);
13115 + round(inv_lrnd, b0, b1, kp + 9 * nc);
13116 + }
13117 +
13118 +#elif defined(PARTIAL_UNROLL)
13119 + { u_int32_t rnd;
13120 +
13121 + for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
13122 + {
13123 + round(inv_rnd, b1, b0, kp);
13124 + round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc;
13125 + }
13126 +
13127 + round(inv_rnd, b1, b0, kp);
13128 + round(inv_lrnd, b0, b1, kp + nc);
13129 + }
13130 +#else
13131 + { u_int32_t rnd;
13132 +
13133 + for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
13134 + {
13135 + round(inv_rnd, b1, b0, kp);
13136 + l_copy(b0, b1); kp += nc;
13137 + }
13138 +
13139 + round(inv_lrnd, b0, b1, kp);
13140 + }
13141 +#endif
13142 +
13143 + state_out(out_blk, b0);
13144 +}
13145 --- /dev/null Tue Mar 11 13:02:56 2003
13146 +++ linux/net/ipsec/aes/aes_cbc.c Mon Feb 9 13:51:03 2004
13147 @@ -0,0 +1,67 @@
13148 +/*
13149 +// I retain copyright in this code but I encourage its free use provided
13150 +// that I don't carry any responsibility for the results. I am especially
13151 +// happy to see it used in free and open source software. If you do use
13152 +// it I would appreciate an acknowledgement of its origin in the code or
13153 +// the product that results and I would also appreciate knowing a little
13154 +// about the use to which it is being put. I am grateful to Frank Yellin
13155 +// for some ideas that are used in this implementation.
13156 +//
13157 +// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
13158 +//
13159 +// This is an implementation of the AES encryption algorithm (Rijndael)
13160 +// designed by Joan Daemen and Vincent Rijmen. This version is designed
13161 +// to provide both fixed and dynamic block and key lengths and can also
13162 +// run with either big or little endian internal byte order (see aes.h).
13163 +// It inputs block and key lengths in bytes with the legal values being
13164 +// 16, 24 and 32.
13165 +*
13166 +*/
13167 +
13168 +#ifdef __KERNEL__
13169 +#include <linux/types.h>
13170 +#else
13171 +#include <sys/types.h>
13172 +#endif
13173 +#include "klips-crypto/aes_cbc.h"
13174 +#include "klips-crypto/cbc_generic.h"
13175 +#ifdef OCF_ASSIST
13176 +#include "klips-crypto/ocf_assist.h"
13177 +#endif
13178 +
13179 +/* returns bool success */
13180 +int AES_set_key(aes_context *aes_ctx, const u_int8_t *key, int keysize) {
13181 + aes_set_key(aes_ctx, key, keysize, 0);
13182 + return 1;
13183 +}
13184 +
13185 +#ifdef OCF_ASSIST
13186 +
13187 +CBC_IMPL_BLK16(_AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
13188 +
13189 +int
13190 +AES_cbc_encrypt(aes_context *ctx, const u_int8_t *in, u_int8_t *out, int ilen,
13191 + const u_int8_t *iv, int encrypt)
13192 +{
13193 + if (ocf_aes_assist() & OCF_PROVIDES_AES) {
13194 + return ocf_aes_cbc_encrypt(ctx, in, out, ilen, iv, encrypt);
13195 + } else {
13196 + return _AES_cbc_encrypt(ctx, in, out, ilen, iv, encrypt);
13197 + }
13198 +}
13199 +
13200 +#else
13201 +CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
13202 +#endif
13203 +
13204 +
13205 +/*
13206 + * $Log: aes_cbc.c,v $
13207 + * Revision 1.2 2004/07/10 07:48:40 mcr
13208 + * Moved from linux/crypto/ciphers/aes/aes_cbc.c,v
13209 + *
13210 + * Revision 1.1 2004/04/06 02:48:12 mcr
13211 + * pullup of AES cipher from alg-branch.
13212 + *
13213 + *
13214 + */
13215 --- /dev/null Tue Mar 11 13:02:56 2003
13216 +++ linux/net/ipsec/aes/aes_xcbc_mac.c Mon Feb 9 13:51:03 2004
13217 @@ -0,0 +1,67 @@
13218 +#ifdef __KERNEL__
13219 +#include <linux/types.h>
13220 +#include <linux/kernel.h>
13221 +#define AES_DEBUG(x)
13222 +#else
13223 +#include <stdio.h>
13224 +#include <sys/types.h>
13225 +#define AES_DEBUG(x) x
13226 +#endif
13227 +
13228 +#include "klips-crypto/aes.h"
13229 +#include "klips-crypto/aes_xcbc_mac.h"
13230 +
13231 +int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen)
13232 +{
13233 + int ret=1;
13234 + aes_block kn[3] = {
13235 + { 0x01010101, 0x01010101, 0x01010101, 0x01010101 },
13236 + { 0x02020202, 0x02020202, 0x02020202, 0x02020202 },
13237 + { 0x03030303, 0x03030303, 0x03030303, 0x03030303 },
13238 + };
13239 + aes_set_key(&ctxm->ctx_k1, key, keylen, 0);
13240 + aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[0], (u_int8_t *) kn[0]);
13241 + aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[1], (u_int8_t *) ctxm->k2);
13242 + aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[2], (u_int8_t *) ctxm->k3);
13243 + aes_set_key(&ctxm->ctx_k1, (u_int8_t *) kn[0], 16, 0);
13244 + return ret;
13245 +}
13246 +static void do_pad_xor(u_int8_t *out, const u_int8_t *in, int len) {
13247 + int pos=0;
13248 + for (pos=1; pos <= 16; pos++, in++, out++) {
13249 + if (pos <= len)
13250 + *out ^= *in;
13251 + if (pos > len) {
13252 + AES_DEBUG(printf("put 0x80 at pos=%d\n", pos));
13253 + *out ^= 0x80;
13254 + break;
13255 + }
13256 + }
13257 +}
13258 +static void xor_block(aes_block res, const aes_block op) {
13259 + res[0] ^= op[0];
13260 + res[1] ^= op[1];
13261 + res[2] ^= op[2];
13262 + res[3] ^= op[3];
13263 +}
13264 +int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]) {
13265 + int ret=ilen;
13266 + u_int32_t out[4] = { 0, 0, 0, 0 };
13267 + for (; ilen > 16 ; ilen-=16) {
13268 + xor_block(out, (const u_int32_t*) &in[0]);
13269 + aes_encrypt(&ctxm->ctx_k1, in, (u_int8_t *)&out[0]);
13270 + in+=16;
13271 + }
13272 + do_pad_xor((u_int8_t *)&out, in, ilen);
13273 + if (ilen==16) {
13274 + AES_DEBUG(printf("using k3\n"));
13275 + xor_block(out, ctxm->k3);
13276 + }
13277 + else
13278 + {
13279 + AES_DEBUG(printf("using k2\n"));
13280 + xor_block(out, ctxm->k2);
13281 + }
13282 + aes_encrypt(&ctxm->ctx_k1, (u_int8_t *)out, hash);
13283 + return ret;
13284 +}
13285 --- /dev/null Tue Mar 11 13:02:56 2003
13286 +++ linux/net/ipsec/aes/ipsec_alg_aes.c Mon Feb 9 13:51:03 2004
13287 @@ -0,0 +1,300 @@
13288 +/*
13289 + * ipsec_alg AES cipher stubs
13290 + *
13291 + * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
13292 + *
13293 + * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
13294 + *
13295 + * This program is free software; you can redistribute it and/or modify it
13296 + * under the terms of the GNU General Public License as published by the
13297 + * Free Software Foundation; either version 2 of the License, or (at your
13298 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13299 + *
13300 + * This program is distributed in the hope that it will be useful, but
13301 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13302 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13303 + * for more details.
13304 + *
13305 + * Fixes by:
13306 + * PK: Pawel Krawczyk <kravietz@aba.krakow.pl>
13307 + * Fixes list:
13308 + * PK: make XCBC comply with latest draft (keylength)
13309 + *
13310 + */
13311 +#ifndef AUTOCONF_INCLUDED
13312 +#include <linux/config.h>
13313 +#endif
13314 +#include <linux/version.h>
13315 +
13316 +/*
13317 + * special case: ipsec core modular with this static algo inside:
13318 + * must avoid MODULE magic for this file
13319 + */
13320 +#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_AES)
13321 +#undef MODULE
13322 +#endif
13323 +
13324 +#include <linux/module.h>
13325 +#include <linux/init.h>
13326 +
13327 +#include <linux/kernel.h> /* printk() */
13328 +#include <linux/errno.h> /* error codes */
13329 +#include <linux/types.h> /* size_t */
13330 +#include <linux/string.h>
13331 +
13332 +/* Check if __exit is defined, if not null it */
13333 +#ifndef __exit
13334 +#define __exit
13335 +#endif
13336 +
13337 +/* Low freeswan header coupling */
13338 +#include <openswan.h>
13339 +#include "openswan/ipsec_alg.h"
13340 +#include "klips-crypto/aes_cbc.h"
13341 +
13342 +#define CONFIG_KLIPS_ENC_AES_MAC 1
13343 +
13344 +#define AES_CONTEXT_T aes_context
13345 +static int debug_aes=0;
13346 +static int test_aes=0;
13347 +static int excl_aes=0;
13348 +static int keyminbits=0;
13349 +static int keymaxbits=0;
13350 +#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13351 +MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
13352 +#ifdef module_param
13353 +module_param(debug_aes,int,0664);
13354 +module_param(test_aes,int,0664);
13355 +module_param(excl_aes,int,0664);
13356 +module_param(keyminbits,int,0664);
13357 +module_param(keymaxbits,int,0664);
13358 +#else
13359 +MODULE_PARM(debug_aes, "i");
13360 +MODULE_PARM(test_aes, "i");
13361 +MODULE_PARM(excl_aes, "i");
13362 +MODULE_PARM(keyminbits, "i");
13363 +MODULE_PARM(keymaxbits, "i");
13364 +#endif
13365 +#endif
13366 +
13367 +#if CONFIG_KLIPS_ENC_AES_MAC
13368 +#include "klips-crypto/aes_xcbc_mac.h"
13369 +
13370 +/*
13371 + * Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt).
13372 + * We use 9 for non-modular algorithm and none for modular, thus
13373 + * forcing user to specify one on module load. -kravietz
13374 + */
13375 +#ifdef MODULE
13376 +static int auth_id=0;
13377 +#else
13378 +static int auth_id=9;
13379 +#endif
13380 +#if 0
13381 +#ifdef MODULE_PARM
13382 +MODULE_PARM(auth_id, "i");
13383 +#else
13384 +module_param(auth_id,int,0664);
13385 +#endif
13386 +#endif
13387 +#endif
13388 +
13389 +#define ESP_AES 12 /* truely _constant_ :) */
13390 +
13391 +/* 128, 192 or 256 */
13392 +#define ESP_AES_KEY_SZ_MIN 16 /* 128 bit secret key */
13393 +#define ESP_AES_KEY_SZ_MAX 32 /* 256 bit secret key */
13394 +#define ESP_AES_CBC_BLK_LEN 16 /* AES-CBC block size */
13395 +
13396 +/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt
13397 + * -kravietz
13398 + */
13399 +#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
13400 +#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
13401 +
13402 +static int _aes_set_key(struct ipsec_alg_enc *alg,
13403 + __u8 * key_e, const __u8 * key,
13404 + size_t keysize)
13405 +{
13406 + int ret;
13407 + AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
13408 + ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL;
13409 + if (debug_aes > 0)
13410 + printk(KERN_DEBUG "klips_debug:_aes_set_key:"
13411 + "ret=%d key_e=%p key=%p keysize=%ld\n",
13412 + ret, key_e, key, (unsigned long int) keysize);
13413 + return ret;
13414 +}
13415 +
13416 +static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e,
13417 + const __u8 * in, int ilen, const __u8 * iv,
13418 + int encrypt)
13419 +{
13420 + AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
13421 + if (debug_aes > 0)
13422 + printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
13423 + "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
13424 + key_e, in, ilen, iv, encrypt);
13425 + return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt);
13426 +}
13427 +#if CONFIG_KLIPS_ENC_AES_MAC
13428 +static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
13429 + aes_context_mac *ctxm=(aes_context_mac *)key_a;
13430 + return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL;
13431 +}
13432 +static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
13433 + int ret;
13434 + char hash_buf[16];
13435 + aes_context_mac *ctxm=(aes_context_mac *)key_a;
13436 + ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf);
13437 + memcpy(hash, hash_buf, hashlen);
13438 + return ret;
13439 +}
13440 +static struct ipsec_alg_auth ipsec_alg_AES_MAC = {
13441 + ixt_common: { ixt_version: IPSEC_ALG_VERSION,
13442 + ixt_refcnt: ATOMIC_INIT(0),
13443 + ixt_name: "aes_mac",
13444 + ixt_blocksize: ESP_AES_MAC_BLK_LEN,
13445 + ixt_support: {
13446 + ias_exttype: IPSEC_ALG_TYPE_AUTH,
13447 + ias_id: 0,
13448 + ias_keyminbits: ESP_AES_MAC_KEY_SZ*8,
13449 + ias_keymaxbits: ESP_AES_MAC_KEY_SZ*8,
13450 + },
13451 + },
13452 +#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13453 + ixt_module: THIS_MODULE,
13454 +#endif
13455 + ixt_a_keylen: ESP_AES_MAC_KEY_SZ,
13456 + ixt_a_ctx_size: sizeof(aes_context_mac),
13457 + ixt_a_hmac_set_key: _aes_mac_set_key,
13458 + ixt_a_hmac_hash:_aes_mac_hash,
13459 +};
13460 +#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13461 +static struct ipsec_alg_enc ipsec_alg_AES = {
13462 + ixt_common: { ixt_version: IPSEC_ALG_VERSION,
13463 + ixt_refcnt: ATOMIC_INIT(0),
13464 + ixt_name: "aes",
13465 + ixt_blocksize: ESP_AES_CBC_BLK_LEN,
13466 + ixt_support: {
13467 + ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
13468 + //ias_ivlen: 128,
13469 + ias_id: ESP_AES,
13470 + ias_keyminbits: ESP_AES_KEY_SZ_MIN*8,
13471 + ias_keymaxbits: ESP_AES_KEY_SZ_MAX*8,
13472 + },
13473 + },
13474 +#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13475 + ixt_module: THIS_MODULE,
13476 +#endif
13477 + ixt_e_keylen: ESP_AES_KEY_SZ_MAX,
13478 + ixt_e_ctx_size: sizeof(AES_CONTEXT_T),
13479 + ixt_e_set_key: _aes_set_key,
13480 + ixt_e_cbc_encrypt:_aes_cbc_encrypt,
13481 +};
13482 +
13483 +#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13484 +IPSEC_ALG_MODULE_INIT_MOD( ipsec_aes_init )
13485 +#else
13486 +IPSEC_ALG_MODULE_INIT_STATIC( ipsec_aes_init )
13487 +#endif
13488 +{
13489 + int ret, test_ret;
13490 +
13491 + if (keyminbits)
13492 + ipsec_alg_AES.ixt_common.ixt_support.ias_keyminbits=keyminbits;
13493 + if (keymaxbits) {
13494 + ipsec_alg_AES.ixt_common.ixt_support.ias_keymaxbits=keymaxbits;
13495 + if (keymaxbits*8>ipsec_alg_AES.ixt_common.ixt_support.ias_keymaxbits)
13496 + ipsec_alg_AES.ixt_e_keylen=keymaxbits*8;
13497 + }
13498 + if (excl_aes) ipsec_alg_AES.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
13499 + ret=register_ipsec_alg_enc(&ipsec_alg_AES);
13500 + printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
13501 + ipsec_alg_AES.ixt_common.ixt_support.ias_exttype,
13502 + ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13503 + ipsec_alg_AES.ixt_common.ixt_name,
13504 + ret);
13505 + if (ret==0 && test_aes) {
13506 + test_ret=ipsec_alg_test(
13507 + ipsec_alg_AES.ixt_common.ixt_support.ias_exttype ,
13508 + ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13509 + test_aes);
13510 + printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
13511 + ipsec_alg_AES.ixt_common.ixt_support.ias_exttype ,
13512 + ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13513 + test_ret);
13514 + }
13515 +#if CONFIG_KLIPS_ENC_AES_MAC
13516 + if (auth_id!=0){
13517 + int ret;
13518 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id=auth_id;
13519 + ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC);
13520 + printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
13521 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13522 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13523 + ipsec_alg_AES_MAC.ixt_common.ixt_name,
13524 + ret);
13525 + if (ret==0 && test_aes) {
13526 + test_ret=ipsec_alg_test(
13527 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13528 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13529 + test_aes);
13530 + printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
13531 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13532 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13533 + test_ret);
13534 + }
13535 + } else {
13536 + printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id);
13537 + }
13538 +#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13539 + return ret;
13540 +}
13541 +
13542 +#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13543 +IPSEC_ALG_MODULE_EXIT_MOD( ipsec_aes_fini )
13544 +#else
13545 +IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_aes_fini )
13546 +#endif
13547 +{
13548 +#if CONFIG_KLIPS_ENC_AES_MAC
13549 + if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC);
13550 +#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13551 + unregister_ipsec_alg_enc(&ipsec_alg_AES);
13552 + return;
13553 +}
13554 +#ifdef MODULE_LICENSE
13555 +MODULE_LICENSE("GPL");
13556 +#endif
13557 +
13558 +#if 0 /* +NOT_YET */
13559 +#ifndef MODULE
13560 +/*
13561 + * This is intended for static module setups, currently
13562 + * doesn't work for modular ipsec.o with static algos inside
13563 + */
13564 +static int setup_keybits(const char *str)
13565 +{
13566 + unsigned aux;
13567 + char *end;
13568 +
13569 + aux = simple_strtoul(str,&end,0);
13570 + if (aux != 128 && aux != 192 && aux != 256)
13571 + return 0;
13572 + keyminbits = aux;
13573 +
13574 + if (*end == 0 || *end != ',')
13575 + return 1;
13576 + str=end+1;
13577 + aux = simple_strtoul(str, NULL, 0);
13578 + if (aux != 128 && aux != 192 && aux != 256)
13579 + return 0;
13580 + if (aux >= keyminbits)
13581 + keymaxbits = aux;
13582 + return 1;
13583 +}
13584 +__setup("ipsec_aes_keybits=", setup_keybits);
13585 +#endif
13586 +#endif
13587 +
13588 --- /dev/null Tue Mar 11 13:02:56 2003
13589 +++ linux/net/ipsec/alg/Config.alg_aes.in Mon Feb 9 13:51:03 2004
13590 @@ -0,0 +1,3 @@
13591 +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
13592 + tristate ' AES encryption algorithm' CONFIG_IPSEC_ENC_AES
13593 +fi
13594 --- /dev/null Tue Mar 11 13:02:56 2003
13595 +++ linux/net/ipsec/alg/Config.alg_cryptoapi.in Mon Feb 9 13:51:03 2004
13596 @@ -0,0 +1,6 @@
13597 +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
13598 + dep_tristate ' CRYPTOAPI ciphers support (needs cryptoapi patch)' CONFIG_IPSEC_ALG_CRYPTOAPI $CONFIG_CRYPTO
13599 + if [ "$CONFIG_IPSEC_ALG_CRYPTOAPI" != "n" ]; then
13600 + bool ' CRYPTOAPI proprietary ciphers ' CONFIG_IPSEC_ALG_NON_LIBRE
13601 + fi
13602 +fi
13603 --- /dev/null Tue Mar 11 13:02:56 2003
13604 +++ linux/net/ipsec/alg/Config.in Mon Feb 9 13:51:03 2004
13605 @@ -0,0 +1,3 @@
13606 +#Placeholder
13607 +source net/ipsec/alg/Config.alg_aes.in
13608 +source net/ipsec/alg/Config.alg_cryptoapi.in
13609 --- /dev/null Tue Mar 11 13:02:56 2003
13610 +++ linux/net/ipsec/alg/Makefile.alg_aes Mon Feb 9 13:51:03 2004
13611 @@ -0,0 +1,18 @@
13612 +MOD_AES := ipsec_aes.o
13613 +
13614 +ALG_MODULES += $(MOD_AES)
13615 +ALG_SUBDIRS += libaes
13616 +
13617 +obj-$(CONFIG_IPSEC_ALG_AES) += $(MOD_AES)
13618 +static_init-func-$(CONFIG_IPSEC_ALG_AES)+= ipsec_aes_init
13619 +alg_obj-$(CONFIG_IPSEC_ALG_AES) += ipsec_alg_aes.o
13620 +
13621 +AES_OBJS := ipsec_alg_aes.o $(LIBCRYPTO)/libaes/libaes.a
13622 +
13623 +
13624 +$(MOD_AES): $(AES_OBJS)
13625 + $(LD) $(EXTRA_LDFLAGS) -r $(AES_OBJS) -o $@
13626 +
13627 +$(LIBCRYPTO)/libaes/libaes.a:
13628 + $(MAKE) -C $(LIBCRYPTO)/libaes CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' libaes.a
13629 +
13630 --- /dev/null Tue Mar 11 13:02:56 2003
13631 +++ linux/net/ipsec/alg/Makefile.alg_cryptoapi Mon Feb 9 13:51:03 2004
13632 @@ -0,0 +1,14 @@
13633 +MOD_CRYPTOAPI := ipsec_cryptoapi.o
13634 +
13635 +ifneq ($(wildcard $(TOPDIR)/include/linux/crypto.h),)
13636 +ALG_MODULES += $(MOD_CRYPTOAPI)
13637 +obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += $(MOD_CRYPTOAPI)
13638 +static_init-func-$(CONFIG_IPSEC_ALG_CRYPTOAPI)+= ipsec_cryptoapi_init
13639 +alg_obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += ipsec_alg_cryptoapi.o
13640 +else
13641 +$(warning "Linux CryptoAPI (2.4.22+ or 2.6.x) not found, not building ipsec_cryptoapi.o")
13642 +endif
13643 +
13644 +CRYPTOAPI_OBJS := ipsec_alg_cryptoapi.o
13645 +$(MOD_CRYPTOAPI): $(CRYPTOAPI_OBJS)
13646 + $(LD) -r $(CRYPTOAPI_OBJS) -o $@
13647 --- /dev/null Tue Mar 11 13:02:56 2003
13648 +++ linux/net/ipsec/alg/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
13649 @@ -0,0 +1,442 @@
13650 +/*
13651 + * ipsec_alg to linux cryptoapi GLUE
13652 + *
13653 + * Authors: CODE.ar TEAM
13654 + * Harpo MAxx <harpo@linuxmendoza.org.ar>
13655 + * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
13656 + * Luciano Ruete <docemeses@softhome.net>
13657 + *
13658 + * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
13659 + *
13660 + * This program is free software; you can redistribute it and/or modify it
13661 + * under the terms of the GNU General Public License as published by the
13662 + * Free Software Foundation; either version 2 of the License, or (at your
13663 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13664 + *
13665 + * This program is distributed in the hope that it will be useful, but
13666 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13667 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13668 + * for more details.
13669 + *
13670 + * Example usage:
13671 + * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
13672 + * modprobe ipsec_cryptoapi
13673 + * modprobe ipsec_cryptoapi test=1
13674 + * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
13675 + * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
13676 + * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
13677 + * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
13678 + */
13679 +#ifndef AUTOCONF_INCLUDED
13680 +#include <linux/config.h>
13681 +#endif
13682 +#include <linux/version.h>
13683 +
13684 +/*
13685 + * special case: ipsec core modular with this static algo inside:
13686 + * must avoid MODULE magic for this file
13687 + */
13688 +#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI
13689 +#undef MODULE
13690 +#endif
13691 +
13692 +#include <linux/module.h>
13693 +#include <linux/init.h>
13694 +
13695 +#include <linux/kernel.h> /* printk() */
13696 +#include <linux/errno.h> /* error codes */
13697 +#include <linux/types.h> /* size_t */
13698 +#include <linux/string.h>
13699 +
13700 +/* Check if __exit is defined, if not null it */
13701 +#ifndef __exit
13702 +#define __exit
13703 +#endif
13704 +
13705 +/* warn the innocent */
13706 +#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
13707 +#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
13708 +#define NO_CRYPTOAPI_SUPPORT
13709 +#endif
13710 +/* Low freeswan header coupling */
13711 +#include "openswan/ipsec_alg.h"
13712 +
13713 +#include <linux/crypto.h>
13714 +#ifdef CRYPTO_API_VERSION_CODE
13715 +#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
13716 +#define NO_CRYPTOAPI_SUPPORT
13717 +#endif
13718 +
13719 +#ifdef NO_CRYPTOAPI_SUPPORT
13720 +#warning "Building an unusable module :P"
13721 +/* Catch old CryptoAPI by not allowing module to load */
13722 +IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
13723 +{
13724 + printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
13725 + return -EINVAL;
13726 +}
13727 +#else
13728 +#include <asm/scatterlist.h>
13729 +#include <asm/pgtable.h>
13730 +#include <linux/mm.h>
13731 +
13732 +#define CIPHERNAME_AES "aes"
13733 +#define CIPHERNAME_3DES "des3_ede"
13734 +#define CIPHERNAME_BLOWFISH "blowfish"
13735 +#define CIPHERNAME_CAST "cast5"
13736 +#define CIPHERNAME_SERPENT "serpent"
13737 +#define CIPHERNAME_TWOFISH "twofish"
13738 +
13739 +#define ESP_3DES 3
13740 +#define ESP_AES 12
13741 +#define ESP_BLOWFISH 7 /* truely _constant_ :) */
13742 +#define ESP_CAST 6 /* quite constant :) */
13743 +#define ESP_SERPENT 252 /* from ipsec drafts */
13744 +#define ESP_TWOFISH 253 /* from ipsec drafts */
13745 +
13746 +#define AH_MD5 2
13747 +#define AH_SHA 3
13748 +#define DIGESTNAME_MD5 "md5"
13749 +#define DIGESTNAME_SHA1 "sha1"
13750 +
13751 +MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
13752 +static int debug=0;
13753 +static int test=0;
13754 +static int excl=0;
13755 +#ifdef module_param
13756 +module_param(debug, int, 0664);
13757 +module_param(test, int, 0664);
13758 +module_param(excl, int, 0664);
13759 +#else
13760 +MODULE_PARM(debug, "i");
13761 +MODULE_PARM(test, "i");
13762 +MODULE_PARM(excl, "i");
13763 +#endif
13764 +
13765 +static int noauto = 0;
13766 +#ifdef module_param
13767 +module_param(noauto,int, 0664);
13768 +#else
13769 +MODULE_PARM(noauto,"i");
13770 +#endif
13771 +MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
13772 +
13773 +static int des_ede3[] = {-1, -1};
13774 +static int aes[] = {-1, -1};
13775 +static int blowfish[] = {-1, -1};
13776 +static int cast[] = {-1, -1};
13777 +static int serpent[] = {-1, -1};
13778 +static int twofish[] = {-1, -1};
13779 +
13780 +#ifdef module_param_array
13781 +module_param_array(des_ede3,int,NULL,0);
13782 +module_param_array(aes,int,NULL,0);
13783 +module_param_array(blowfish,int,NULL,0);
13784 +module_param_array(cast,int,NULL,0);
13785 +module_param_array(serpent,int,NULL,0);
13786 +module_param_array(twofish,int,NULL,0);
13787 +#else
13788 +MODULE_PARM(des_ede3,"1-2i");
13789 +MODULE_PARM(aes,"1-2i");
13790 +MODULE_PARM(blowfish,"1-2i");
13791 +MODULE_PARM(cast,"1-2i");
13792 +MODULE_PARM(serpent,"1-2i");
13793 +MODULE_PARM(twofish,"1-2i");
13794 +#endif
13795 +MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
13796 +MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
13797 +MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
13798 +MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
13799 +MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
13800 +MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
13801 +
13802 +struct ipsec_alg_capi_cipher {
13803 + const char *ciphername; /* cryptoapi's ciphername */
13804 + unsigned blocksize;
13805 + unsigned short minbits;
13806 + unsigned short maxbits;
13807 + int *parm; /* lkm param for this cipher */
13808 + struct ipsec_alg_enc alg; /* note it's not a pointer */
13809 +};
13810 +static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
13811 + { CIPHERNAME_AES , 16, 128, 256, aes , { ixt_alg_id: ESP_AES, }},
13812 + { CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }},
13813 + { CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }},
13814 + { CIPHERNAME_CAST , 8, 128, 128, cast , { ixt_alg_id: ESP_CAST, }},
13815 + { CIPHERNAME_BLOWFISH , 8, 96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }},
13816 + { CIPHERNAME_3DES , 8, 192, 192, des_ede3,{ ixt_alg_id: ESP_3DES, }},
13817 + { NULL, 0, 0, 0, NULL, {} }
13818 +};
13819 +#ifdef NOT_YET
13820 +struct ipsec_alg_capi_digest {
13821 + const char *digestname; /* cryptoapi's digestname */
13822 + struct digest_implementation *di;
13823 + struct ipsec_alg_auth alg; /* note it's not a pointer */
13824 +};
13825 +static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
13826 + { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
13827 + { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
13828 + { NULL, NULL, {} }
13829 +};
13830 +#endif
13831 +/*
13832 + * "generic" linux cryptoapi setup_cipher() function
13833 + */
13834 +int setup_cipher(const char *ciphername)
13835 +{
13836 + return crypto_alg_available(ciphername, 0);
13837 +}
13838 +
13839 +/*
13840 + * setups ipsec_alg_capi_cipher "hyper" struct components, calling
13841 + * register_ipsec_alg for cointaned ipsec_alg object
13842 + */
13843 +static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
13844 +static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
13845 +static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
13846 +
13847 +static int
13848 +setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
13849 +{
13850 + int ret;
13851 + cptr->alg.ixt_version = IPSEC_ALG_VERSION;
13852 + cptr->alg.ixt_module = THIS_MODULE;
13853 + atomic_set (& cptr->alg.ixt_refcnt, 0);
13854 + strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name));
13855 +
13856 + cptr->alg.ixt_blocksize=cptr->blocksize;
13857 + cptr->alg.ixt_keyminbits=cptr->minbits;
13858 + cptr->alg.ixt_keymaxbits=cptr->maxbits;
13859 + cptr->alg.ixt_state = 0;
13860 + if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL;
13861 + cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8;
13862 + cptr->alg.ixt_e_ctx_size = 0;
13863 + cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT;
13864 + cptr->alg.ixt_e_new_key = _capi_new_key;
13865 + cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
13866 + cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
13867 + cptr->alg.ixt_data = cptr;
13868 +
13869 + ret=register_ipsec_alg_enc(&cptr->alg);
13870 + printk("setup_ipsec_alg_capi_cipher(): "
13871 + "alg_type=%d alg_id=%d name=%s "
13872 + "keyminbits=%d keymaxbits=%d, ret=%d\n",
13873 + cptr->alg.ixt_alg_type,
13874 + cptr->alg.ixt_alg_id,
13875 + cptr->alg.ixt_name,
13876 + cptr->alg.ixt_keyminbits,
13877 + cptr->alg.ixt_keymaxbits,
13878 + ret);
13879 + return ret;
13880 +}
13881 +/*
13882 + * called in ipsec_sa_wipe() time, will destroy key contexts
13883 + * and do 1 unbind()
13884 + */
13885 +static void
13886 +_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
13887 +{
13888 + struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
13889 +
13890 + if (debug > 0)
13891 + printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
13892 + "name=%s key_e=%p \n",
13893 + alg->ixt_name, key_e);
13894 + if (!key_e) {
13895 + printk(KERN_ERR "klips_debug: _capi_destroy_key:"
13896 + "name=%s NULL key_e!\n",
13897 + alg->ixt_name);
13898 + return;
13899 + }
13900 + crypto_free_tfm(tfm);
13901 +}
13902 +
13903 +/*
13904 + * create new key context, need alg->ixt_data to know which
13905 + * (of many) cipher inside this module is the target
13906 + */
13907 +static __u8 *
13908 +_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
13909 +{
13910 + struct ipsec_alg_capi_cipher *cptr;
13911 + struct crypto_tfm *tfm=NULL;
13912 +
13913 + cptr = alg->ixt_data;
13914 + if (!cptr) {
13915 + printk(KERN_ERR "_capi_new_key(): "
13916 + "NULL ixt_data (?!) for \"%s\" algo\n"
13917 + , alg->ixt_name);
13918 + goto err;
13919 + }
13920 + if (debug > 0)
13921 + printk(KERN_DEBUG "klips_debug:_capi_new_key:"
13922 + "name=%s cptr=%p key=%p keysize=%d\n",
13923 + alg->ixt_name, cptr, key, keylen);
13924 +
13925 + /*
13926 + * alloc tfm
13927 + */
13928 + tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
13929 + if (!tfm) {
13930 + printk(KERN_ERR "_capi_new_key(): "
13931 + "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
13932 + , alg->ixt_name, cptr->ciphername);
13933 + goto err;
13934 + }
13935 + if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
13936 + printk(KERN_ERR "_capi_new_key(): "
13937 + "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
13938 + , alg->ixt_name, keylen);
13939 + crypto_free_tfm(tfm);
13940 + tfm=NULL;
13941 + }
13942 +err:
13943 + if (debug > 0)
13944 + printk(KERN_DEBUG "klips_debug:_capi_new_key:"
13945 + "name=%s key=%p keylen=%d tfm=%p\n",
13946 + alg->ixt_name, key, keylen, tfm);
13947 + return (__u8 *) tfm;
13948 +}
13949 +/*
13950 + * core encryption function: will use cx->ci to call actual cipher's
13951 + * cbc function
13952 + */
13953 +static int
13954 +_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
13955 + int error =0;
13956 + struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
13957 + struct scatterlist sg = {
13958 + .page = virt_to_page(in),
13959 + .offset = (unsigned long)(in) % PAGE_SIZE,
13960 + .length=ilen,
13961 + };
13962 + if (debug > 1)
13963 + printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
13964 + "key_e=%p "
13965 + "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
13966 + , key_e
13967 + , in, in, ilen, iv, encrypt);
13968 + crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
13969 + if (encrypt)
13970 + error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
13971 + else
13972 + error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
13973 + if (debug > 1)
13974 + printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
13975 + "error=%d\n"
13976 + , error);
13977 + return (error<0)? error : ilen;
13978 +}
13979 +/*
13980 + * main initialization loop: for each cipher in list, do
13981 + * 1) setup cryptoapi cipher else continue
13982 + * 2) register ipsec_alg object
13983 + */
13984 +static int
13985 +setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
13986 +{
13987 + struct ipsec_alg_capi_cipher *cptr;
13988 + /* foreach cipher in list ... */
13989 + for (cptr=clist;cptr->ciphername;cptr++) {
13990 + /*
13991 + * see if cipher has been disabled (0) or
13992 + * if noauto set and not enabled (1)
13993 + */
13994 + if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
13995 + if (debug>0)
13996 + printk(KERN_INFO "setup_cipher_list(): "
13997 + "ciphername=%s skipped at user request: "
13998 + "noauto=%d parm[0]=%d parm[1]=%d\n"
13999 + , cptr->ciphername
14000 + , noauto
14001 + , cptr->parm[0]
14002 + , cptr->parm[1]);
14003 + continue;
14004 + }
14005 + /*
14006 + * use a local ci to avoid touching cptr->ci,
14007 + * if register ipsec_alg success then bind cipher
14008 + */
14009 + if( setup_cipher(cptr->ciphername) ) {
14010 + if (debug > 0)
14011 + printk(KERN_DEBUG "klips_debug:"
14012 + "setup_cipher_list():"
14013 + "ciphername=%s found\n"
14014 + , cptr->ciphername);
14015 + if (setup_ipsec_alg_capi_cipher(cptr) == 0) {
14016 +
14017 +
14018 + } else {
14019 + printk(KERN_ERR "klips_debug:"
14020 + "setup_cipher_list():"
14021 + "ciphername=%s failed ipsec_alg_register\n"
14022 + , cptr->ciphername);
14023 + }
14024 + } else {
14025 + if (debug>0)
14026 + printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n",
14027 + cptr->ciphername);
14028 + }
14029 + }
14030 + return 0;
14031 +}
14032 +/*
14033 + * deregister ipsec_alg objects and unbind ciphers
14034 + */
14035 +static int
14036 +unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
14037 +{
14038 + struct ipsec_alg_capi_cipher *cptr;
14039 + /* foreach cipher in list ... */
14040 + for (cptr=clist;cptr->ciphername;cptr++) {
14041 + if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
14042 + unregister_ipsec_alg_enc(&cptr->alg);
14043 + }
14044 + }
14045 + return 0;
14046 +}
14047 +/*
14048 + * test loop for registered algos
14049 + */
14050 +static int
14051 +test_cipher_list (struct ipsec_alg_capi_cipher* clist)
14052 +{
14053 + int test_ret;
14054 + struct ipsec_alg_capi_cipher *cptr;
14055 + /* foreach cipher in list ... */
14056 + for (cptr=clist;cptr->ciphername;cptr++) {
14057 + if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
14058 + test_ret=ipsec_alg_test(
14059 + cptr->alg.ixt_alg_type,
14060 + cptr->alg.ixt_alg_id,
14061 + test);
14062 + printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
14063 + cptr->alg.ixt_alg_type,
14064 + cptr->alg.ixt_alg_id,
14065 + test_ret);
14066 + }
14067 + }
14068 + return 0;
14069 +}
14070 +
14071 +IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
14072 +{
14073 + int ret, test_ret;
14074 + if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
14075 + return -EPROTONOSUPPORT;
14076 + if (ret==0 && test) {
14077 + test_ret=test_cipher_list(alg_capi_carray);
14078 + }
14079 + return ret;
14080 +}
14081 +IPSEC_ALG_MODULE_EXIT( ipsec_cryptoapi_fini )
14082 +{
14083 + unsetup_cipher_list(alg_capi_carray);
14084 + return;
14085 +}
14086 +#ifdef MODULE_LICENSE
14087 +MODULE_LICENSE("GPL");
14088 +#endif
14089 +
14090 +EXPORT_NO_SYMBOLS;
14091 +#endif /* NO_CRYPTOAPI_SUPPORT */
14092 --- /dev/null Tue Mar 11 13:02:56 2003
14093 +++ linux/net/ipsec/alg/scripts/mk-static_init.c.sh Mon Feb 9 13:51:03 2004
14094 @@ -0,0 +1,18 @@
14095 +#!/bin/sh
14096 +cat << EOF
14097 +#include <linux/kernel.h>
14098 +#include <linux/list.h>
14099 +#include "freeswan/ipsec_alg.h"
14100 +$(for i in $*; do
14101 + test -z "$i" && continue
14102 + echo "extern int $i(void);"
14103 +done)
14104 +void ipsec_alg_static_init(void){
14105 + int __attribute__ ((unused)) err=0;
14106 +$(for i in $*; do
14107 + test -z "$i" && continue
14108 + echo " if ((err=$i()) < 0)"
14109 + echo " printk(KERN_WARNING \"$i() returned %d\", err);"
14110 +done)
14111 +}
14112 +EOF
14113 --- /dev/null Tue Mar 11 13:02:56 2003
14114 +++ linux/net/ipsec/anyaddr.c Mon Feb 9 13:51:03 2004
14115 @@ -0,0 +1,150 @@
14116 +/*
14117 + * special addresses
14118 + * Copyright (C) 2000 Henry Spencer.
14119 + *
14120 + * This library is free software; you can redistribute it and/or modify it
14121 + * under the terms of the GNU Library General Public License as published by
14122 + * the Free Software Foundation; either version 2 of the License, or (at your
14123 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
14124 + *
14125 + * This library is distributed in the hope that it will be useful, but
14126 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14127 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14128 + * License for more details.
14129 + *
14130 + * RCSID $Id: anyaddr.c,v 1.10 2004/07/10 07:43:47 mcr Exp $
14131 + */
14132 +#include "openswan.h"
14133 +
14134 +/* these are mostly fallbacks for the no-IPv6-support-in-library case */
14135 +#ifndef IN6ADDR_ANY_INIT
14136 +#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
14137 +#endif
14138 +#ifndef IN6ADDR_LOOPBACK_INIT
14139 +#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}
14140 +#endif
14141 +
14142 +static struct in6_addr v6any = IN6ADDR_ANY_INIT;
14143 +static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT;
14144 +
14145 +/*
14146 + - anyaddr - initialize to the any-address value
14147 + */
14148 +err_t /* NULL for success, else string literal */
14149 +anyaddr(af, dst)
14150 +int af; /* address family */
14151 +ip_address *dst;
14152 +{
14153 + uint32_t v4any = htonl(INADDR_ANY);
14154 +
14155 + switch (af) {
14156 + case AF_INET:
14157 + return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst);
14158 + break;
14159 + case AF_INET6:
14160 + return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst);
14161 + break;
14162 + default:
14163 + return "unknown address family in anyaddr/unspecaddr";
14164 + break;
14165 + }
14166 +}
14167 +
14168 +/*
14169 + - unspecaddr - initialize to the unspecified-address value
14170 + */
14171 +err_t /* NULL for success, else string literal */
14172 +unspecaddr(af, dst)
14173 +int af; /* address family */
14174 +ip_address *dst;
14175 +{
14176 + return anyaddr(af, dst);
14177 +}
14178 +
14179 +/*
14180 + - loopbackaddr - initialize to the loopback-address value
14181 + */
14182 +err_t /* NULL for success, else string literal */
14183 +loopbackaddr(af, dst)
14184 +int af; /* address family */
14185 +ip_address *dst;
14186 +{
14187 + uint32_t v4loop = htonl(INADDR_LOOPBACK);
14188 +
14189 + switch (af) {
14190 + case AF_INET:
14191 + return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst);
14192 + break;
14193 + case AF_INET6:
14194 + return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst);
14195 + break;
14196 + default:
14197 + return "unknown address family in loopbackaddr";
14198 + break;
14199 + }
14200 +}
14201 +
14202 +/*
14203 + - isanyaddr - test for the any-address value
14204 + */
14205 +int
14206 +isanyaddr(src)
14207 +const ip_address *src;
14208 +{
14209 + uint32_t v4any = htonl(INADDR_ANY);
14210 + int cmp;
14211 +
14212 + switch (src->u.v4.sin_family) {
14213 + case AF_INET:
14214 + cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any));
14215 + break;
14216 + case AF_INET6:
14217 + cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any));
14218 + break;
14219 +
14220 + case 0:
14221 + /* a zeroed structure is considered any address */
14222 + return 1;
14223 +
14224 + default:
14225 + return 0;
14226 + break;
14227 + }
14228 +
14229 + return (cmp == 0) ? 1 : 0;
14230 +}
14231 +
14232 +/*
14233 + - isunspecaddr - test for the unspecified-address value
14234 + */
14235 +int
14236 +isunspecaddr(src)
14237 +const ip_address *src;
14238 +{
14239 + return isanyaddr(src);
14240 +}
14241 +
14242 +/*
14243 + - isloopbackaddr - test for the loopback-address value
14244 + */
14245 +int
14246 +isloopbackaddr(src)
14247 +const ip_address *src;
14248 +{
14249 + uint32_t v4loop = htonl(INADDR_LOOPBACK);
14250 + int cmp;
14251 +
14252 + switch (src->u.v4.sin_family) {
14253 + case AF_INET:
14254 + cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop));
14255 + break;
14256 + case AF_INET6:
14257 + cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop));
14258 + break;
14259 + default:
14260 + return 0;
14261 + break;
14262 + }
14263 +
14264 + return (cmp == 0) ? 1 : 0;
14265 +}
14266 --- /dev/null Tue Mar 11 13:02:56 2003
14267 +++ linux/net/ipsec/datatot.c Mon Feb 9 13:51:03 2004
14268 @@ -0,0 +1,234 @@
14269 +/*
14270 + * convert from binary data (e.g. key) to text form
14271 + * Copyright (C) 2000 Henry Spencer.
14272 + *
14273 + * This library is free software; you can redistribute it and/or modify it
14274 + * under the terms of the GNU Library General Public License as published by
14275 + * the Free Software Foundation; either version 2 of the License, or (at your
14276 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
14277 + *
14278 + * This library is distributed in the hope that it will be useful, but
14279 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14280 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14281 + * License for more details.
14282 + *
14283 + * RCSID $Id: datatot.c,v 1.9 2005/08/30 21:15:26 mcr Exp $
14284 + */
14285 +#include "openswan.h"
14286 +
14287 +static void convert(const char *src, size_t nreal, int format, char *out);
14288 +
14289 +/*
14290 + - datatot - convert data bytes to text
14291 + */
14292 +size_t /* true length (with NUL) for success */
14293 +datatot(src, srclen, format, dst, dstlen)
14294 +const unsigned char *src;
14295 +size_t srclen;
14296 +int format; /* character indicating what format */
14297 +char *dst; /* need not be valid if dstlen is 0 */
14298 +size_t dstlen;
14299 +{
14300 + size_t inblocksize; /* process this many bytes at a time */
14301 + size_t outblocksize; /* producing this many */
14302 + size_t breakevery; /* add a _ every this many (0 means don't) */
14303 + size_t sincebreak; /* output bytes since last _ */
14304 + char breakchar; /* character used to break between groups */
14305 + unsigned char inblock[10]; /* enough for any format */
14306 + char outblock[10]; /* enough for any format */
14307 + char fake[1]; /* fake output area for dstlen == 0 */
14308 + size_t needed; /* return value */
14309 + char *stop; /* where the terminating NUL will go */
14310 + size_t ntodo; /* remaining input */
14311 + size_t nreal;
14312 + char *out;
14313 + char *prefix;
14314 +
14315 + breakevery = 0;
14316 + breakchar = '_';
14317 +
14318 + switch (format) {
14319 + case 0:
14320 + case 'h':
14321 + format = 'x';
14322 + breakevery = 8;
14323 + /* FALLTHROUGH */
14324 + case 'x':
14325 + inblocksize = 1;
14326 + outblocksize = 2;
14327 + prefix = "0x";
14328 + break;
14329 + case ':':
14330 + format = 'x';
14331 + breakevery = 2;
14332 + breakchar = ':';
14333 + /* FALLTHROUGH */
14334 + case 16:
14335 + inblocksize = 1;
14336 + outblocksize = 2;
14337 + prefix = "";
14338 + format = 'x';
14339 + break;
14340 + case 's':
14341 + inblocksize = 3;
14342 + outblocksize = 4;
14343 + prefix = "0s";
14344 + break;
14345 + case 64: /* beware, equals ' ' */
14346 + inblocksize = 3;
14347 + outblocksize = 4;
14348 + prefix = "";
14349 + format = 's';
14350 + break;
14351 + default:
14352 + return 0;
14353 + break;
14354 + }
14355 +
14356 + user_assert(inblocksize < sizeof(inblock));
14357 + user_assert(outblocksize < sizeof(outblock));
14358 + user_assert(breakevery % outblocksize == 0);
14359 +
14360 + if (srclen == 0)
14361 + return 0;
14362 + ntodo = srclen;
14363 +
14364 + if (dstlen == 0) { /* dispose of awkward special case */
14365 + dst = fake;
14366 + dstlen = 1;
14367 + }
14368 + stop = dst + dstlen - 1;
14369 +
14370 + nreal = strlen(prefix);
14371 + needed = nreal; /* for starters */
14372 + if (dstlen <= nreal) { /* prefix won't fit */
14373 + strncpy(dst, prefix, dstlen - 1);
14374 + dst += dstlen - 1;
14375 + } else {
14376 + strcpy(dst, prefix);
14377 + dst += nreal;
14378 + }
14379 +
14380 + user_assert(dst <= stop);
14381 + sincebreak = 0;
14382 +
14383 + while (ntodo > 0) {
14384 + if (ntodo < inblocksize) { /* incomplete input */
14385 + memset(inblock, 0, sizeof(inblock));
14386 + memcpy(inblock, src, ntodo);
14387 + src = inblock;
14388 + nreal = ntodo;
14389 + ntodo = inblocksize;
14390 + } else
14391 + nreal = inblocksize;
14392 + out = (outblocksize > stop - dst) ? outblock : dst;
14393 +
14394 + convert((const char *)src, nreal, format, out);
14395 + needed += outblocksize;
14396 + sincebreak += outblocksize;
14397 + if (dst < stop) {
14398 + if (out != dst) {
14399 + user_assert(outblocksize > stop - dst);
14400 + memcpy(dst, out, stop - dst);
14401 + dst = stop;
14402 + } else
14403 + dst += outblocksize;
14404 + }
14405 +
14406 + src += inblocksize;
14407 + ntodo -= inblocksize;
14408 + if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) {
14409 + if (dst < stop)
14410 + *dst++ = breakchar;
14411 + needed++;
14412 + sincebreak = 0;
14413 + }
14414 + }
14415 +
14416 + user_assert(dst <= stop);
14417 + *dst++ = '\0';
14418 + needed++;
14419 +
14420 + return needed;
14421 +}
14422 +
14423 +/*
14424 + - convert - convert one input block to one output block
14425 + */
14426 +static void
14427 +convert(src, nreal, format, out)
14428 +const char *src;
14429 +size_t nreal; /* how much of the input block is real */
14430 +int format;
14431 +char *out;
14432 +{
14433 + static char hex[] = "0123456789abcdef";
14434 + static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
14435 + "abcdefghijklmnopqrstuvwxyz"
14436 + "0123456789+/";
14437 + unsigned char c;
14438 + unsigned char c1, c2, c3;
14439 +
14440 + user_assert(nreal > 0);
14441 + switch (format) {
14442 + case 'x':
14443 + user_assert(nreal == 1);
14444 + c = (unsigned char)*src;
14445 + *out++ = hex[c >> 4];
14446 + *out++ = hex[c & 0xf];
14447 + break;
14448 + case 's':
14449 + c1 = (unsigned char)*src++;
14450 + c2 = (unsigned char)*src++;
14451 + c3 = (unsigned char)*src++;
14452 + *out++ = base64[c1 >> 2]; /* top 6 bits of c1 */
14453 + c = (c1 & 0x3) << 4; /* bottom 2 of c1... */
14454 + c |= c2 >> 4; /* ...top 4 of c2 */
14455 + *out++ = base64[c];
14456 + if (nreal == 1)
14457 + *out++ = '=';
14458 + else {
14459 + c = (c2 & 0xf) << 2; /* bottom 4 of c2... */
14460 + c |= c3 >> 6; /* ...top 2 of c3 */
14461 + *out++ = base64[c];
14462 + }
14463 + if (nreal <= 2)
14464 + *out++ = '=';
14465 + else
14466 + *out++ = base64[c3 & 0x3f]; /* bottom 6 of c3 */
14467 + break;
14468 + default:
14469 + user_assert(nreal == 0); /* unknown format */
14470 + break;
14471 + }
14472 +}
14473 +
14474 +/*
14475 + - datatoa - convert data to ASCII
14476 + * backward-compatibility synonym for datatot
14477 + */
14478 +size_t /* true length (with NUL) for success */
14479 +datatoa(src, srclen, format, dst, dstlen)
14480 +const unsigned char *src;
14481 +size_t srclen;
14482 +int format; /* character indicating what format */
14483 +char *dst; /* need not be valid if dstlen is 0 */
14484 +size_t dstlen;
14485 +{
14486 + return datatot(src, srclen, format, dst, dstlen);
14487 +}
14488 +
14489 +/*
14490 + - bytestoa - convert data bytes to ASCII
14491 + * backward-compatibility synonym for datatot
14492 + */
14493 +size_t /* true length (with NUL) for success */
14494 +bytestoa(src, srclen, format, dst, dstlen)
14495 +const unsigned char *src;
14496 +size_t srclen;
14497 +int format; /* character indicating what format */
14498 +char *dst; /* need not be valid if dstlen is 0 */
14499 +size_t dstlen;
14500 +{
14501 + return datatot(src, srclen, format, dst, dstlen);
14502 +}
14503 --- /dev/null Tue Mar 11 13:02:56 2003
14504 +++ linux/net/ipsec/defconfig Mon Feb 9 13:51:03 2004
14505 @@ -0,0 +1,63 @@
14506 +
14507 +#
14508 +# RCSID $Id: defconfig,v 1.30 2005/09/15 02:31:12 paul Exp $
14509 +#
14510 +
14511 +#
14512 +# Openswan IPSec implementation, KLIPS kernel config defaults
14513 +#
14514 +
14515 +#
14516 +# First, lets override stuff already set or not in the kernel config.
14517 +#
14518 +# We can't even think about leaving this off...
14519 +CONFIG_INET=y
14520 +
14521 +#
14522 +# This must be on for subnet protection.
14523 +CONFIG_IP_FORWARD=y
14524 +
14525 +# Shut off IPSEC masquerading if it has been enabled, since it will
14526 +# break the compile. IPPROTO_ESP and IPPROTO_AH were included in
14527 +# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h.
14528 +CONFIG_IP_MASQUERADE_IPSEC=n
14529 +
14530 +#
14531 +# Next, lets set the recommended FreeS/WAN configuration.
14532 +#
14533 +
14534 +# To config as static (preferred), 'y'. To config as module, 'm'.
14535 +CONFIG_KLIPS=m
14536 +
14537 +# To do tunnel mode IPSec, this must be enabled.
14538 +CONFIG_KLIPS_IPIP=y
14539 +
14540 +# To enable authentication, say 'y'. (Highly recommended)
14541 +CONFIG_KLIPS_AH=y
14542 +
14543 +# Authentication algorithm(s):
14544 +CONFIG_KLIPS_AUTH_HMAC_MD5=y
14545 +CONFIG_KLIPS_AUTH_HMAC_SHA1=y
14546 +
14547 +# To enable encryption, say 'y'. (Highly recommended)
14548 +CONFIG_KLIPS_ESP=y
14549 +
14550 +# modular algo extensions (and new ALGOs)
14551 +CONFIG_KLIPS_ALG=y
14552 +
14553 +# Encryption algorithm(s):
14554 +CONFIG_KLIPS_ENC_3DES=y
14555 +CONFIG_KLIPS_ENC_AES=y
14556 +
14557 +# Use CryptoAPI for ALG? - by default, no.
14558 +CONFIG_KLIPS_ENC_CRYPTOAPI=n
14559 +
14560 +# IP Compression: new, probably still has minor bugs.
14561 +CONFIG_KLIPS_IPCOMP=y
14562 +
14563 +# To enable userspace-switchable KLIPS debugging, say 'y'.
14564 +CONFIG_KLIPS_DEBUG=y
14565 +
14566 +# OCF HW offloading, requires kernel patch
14567 +# CONFIG_KLIPS_OCF is not set
14568 +
14569 --- /dev/null Tue Mar 11 13:02:56 2003
14570 +++ linux/net/ipsec/deflate.c Mon Feb 9 13:51:03 2004
14571 @@ -0,0 +1,1351 @@
14572 +/* deflate.c -- compress data using the deflation algorithm
14573 + * Copyright (C) 1995-2002 Jean-loup Gailly.
14574 + * For conditions of distribution and use, see copyright notice in zlib.h
14575 + */
14576 +
14577 +/*
14578 + * ALGORITHM
14579 + *
14580 + * The "deflation" process depends on being able to identify portions
14581 + * of the input text which are identical to earlier input (within a
14582 + * sliding window trailing behind the input currently being processed).
14583 + *
14584 + * The most straightforward technique turns out to be the fastest for
14585 + * most input files: try all possible matches and select the longest.
14586 + * The key feature of this algorithm is that insertions into the string
14587 + * dictionary are very simple and thus fast, and deletions are avoided
14588 + * completely. Insertions are performed at each input character, whereas
14589 + * string matches are performed only when the previous match ends. So it
14590 + * is preferable to spend more time in matches to allow very fast string
14591 + * insertions and avoid deletions. The matching algorithm for small
14592 + * strings is inspired from that of Rabin & Karp. A brute force approach
14593 + * is used to find longer strings when a small match has been found.
14594 + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
14595 + * (by Leonid Broukhis).
14596 + * A previous version of this file used a more sophisticated algorithm
14597 + * (by Fiala and Greene) which is guaranteed to run in linear amortized
14598 + * time, but has a larger average cost, uses more memory and is patented.
14599 + * However the F&G algorithm may be faster for some highly redundant
14600 + * files if the parameter max_chain_length (described below) is too large.
14601 + *
14602 + * ACKNOWLEDGEMENTS
14603 + *
14604 + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
14605 + * I found it in 'freeze' written by Leonid Broukhis.
14606 + * Thanks to many people for bug reports and testing.
14607 + *
14608 + * REFERENCES
14609 + *
14610 + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
14611 + * Available in ftp://ds.internic.net/rfc/rfc1951.txt
14612 + *
14613 + * A description of the Rabin and Karp algorithm is given in the book
14614 + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
14615 + *
14616 + * Fiala,E.R., and Greene,D.H.
14617 + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
14618 + *
14619 + */
14620 +
14621 +/* @(#) $Id: deflate.c,v 1.4 2004/07/10 07:48:37 mcr Exp $ */
14622 +
14623 +#include "deflate.h"
14624 +
14625 +local const char deflate_copyright[] =
14626 + " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly ";
14627 +/*
14628 + If you use the zlib library in a product, an acknowledgment is welcome
14629 + in the documentation of your product. If for some reason you cannot
14630 + include such an acknowledgment, I would appreciate that you keep this
14631 + copyright string in the executable of your product.
14632 + */
14633 +
14634 +/* ===========================================================================
14635 + * Function prototypes.
14636 + */
14637 +typedef enum {
14638 + need_more, /* block not completed, need more input or more output */
14639 + block_done, /* block flush performed */
14640 + finish_started, /* finish started, need only more output at next deflate */
14641 + finish_done /* finish done, accept no more input or output */
14642 +} block_state;
14643 +
14644 +typedef block_state (*compress_func) OF((deflate_state *s, int flush));
14645 +/* Compression function. Returns the block state after the call. */
14646 +
14647 +local void fill_window OF((deflate_state *s));
14648 +local block_state deflate_stored OF((deflate_state *s, int flush));
14649 +local block_state deflate_fast OF((deflate_state *s, int flush));
14650 +local block_state deflate_slow OF((deflate_state *s, int flush));
14651 +local void lm_init OF((deflate_state *s));
14652 +local void putShortMSB OF((deflate_state *s, uInt b));
14653 +local void flush_pending OF((z_streamp strm));
14654 +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
14655 +#ifdef ASMV
14656 + void match_init OF((void)); /* asm code initialization */
14657 + uInt longest_match OF((deflate_state *s, IPos cur_match));
14658 +#else
14659 +local uInt longest_match OF((deflate_state *s, IPos cur_match));
14660 +#endif
14661 +
14662 +#ifdef DEBUG
14663 +local void check_match OF((deflate_state *s, IPos start, IPos match,
14664 + int length));
14665 +#endif
14666 +
14667 +/* ===========================================================================
14668 + * Local data
14669 + */
14670 +
14671 +#define NIL 0
14672 +/* Tail of hash chains */
14673 +
14674 +#ifndef TOO_FAR
14675 +# define TOO_FAR 4096
14676 +#endif
14677 +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
14678 +
14679 +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
14680 +/* Minimum amount of lookahead, except at the end of the input file.
14681 + * See deflate.c for comments about the MIN_MATCH+1.
14682 + */
14683 +
14684 +/* Values for max_lazy_match, good_match and max_chain_length, depending on
14685 + * the desired pack level (0..9). The values given below have been tuned to
14686 + * exclude worst case performance for pathological files. Better values may be
14687 + * found for specific files.
14688 + */
14689 +typedef struct config_s {
14690 + ush good_length; /* reduce lazy search above this match length */
14691 + ush max_lazy; /* do not perform lazy search above this match length */
14692 + ush nice_length; /* quit search above this match length */
14693 + ush max_chain;
14694 + compress_func func;
14695 +} config;
14696 +
14697 +local const config configuration_table[10] = {
14698 +/* good lazy nice chain */
14699 +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
14700 +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
14701 +/* 2 */ {4, 5, 16, 8, deflate_fast},
14702 +/* 3 */ {4, 6, 32, 32, deflate_fast},
14703 +
14704 +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
14705 +/* 5 */ {8, 16, 32, 32, deflate_slow},
14706 +/* 6 */ {8, 16, 128, 128, deflate_slow},
14707 +/* 7 */ {8, 32, 128, 256, deflate_slow},
14708 +/* 8 */ {32, 128, 258, 1024, deflate_slow},
14709 +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
14710 +
14711 +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
14712 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
14713 + * meaning.
14714 + */
14715 +
14716 +#define EQUAL 0
14717 +/* result of memcmp for equal strings */
14718 +
14719 +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
14720 +
14721 +/* ===========================================================================
14722 + * Update a hash value with the given input byte
14723 + * IN assertion: all calls to to UPDATE_HASH are made with consecutive
14724 + * input characters, so that a running hash key can be computed from the
14725 + * previous key instead of complete recalculation each time.
14726 + */
14727 +#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
14728 +
14729 +
14730 +/* ===========================================================================
14731 + * Insert string str in the dictionary and set match_head to the previous head
14732 + * of the hash chain (the most recent string with same hash key). Return
14733 + * the previous length of the hash chain.
14734 + * If this file is compiled with -DFASTEST, the compression level is forced
14735 + * to 1, and no hash chains are maintained.
14736 + * IN assertion: all calls to to INSERT_STRING are made with consecutive
14737 + * input characters and the first MIN_MATCH bytes of str are valid
14738 + * (except for the last MIN_MATCH-1 bytes of the input file).
14739 + */
14740 +#ifdef FASTEST
14741 +#define INSERT_STRING(s, str, match_head) \
14742 + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
14743 + match_head = s->head[s->ins_h], \
14744 + s->head[s->ins_h] = (Pos)(str))
14745 +#else
14746 +#define INSERT_STRING(s, str, match_head) \
14747 + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
14748 + s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
14749 + s->head[s->ins_h] = (Pos)(str))
14750 +#endif
14751 +
14752 +/* ===========================================================================
14753 + * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
14754 + * prev[] will be initialized on the fly.
14755 + */
14756 +#define CLEAR_HASH(s) \
14757 + s->head[s->hash_size-1] = NIL; \
14758 + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
14759 +
14760 +/* ========================================================================= */
14761 +int ZEXPORT deflateInit_(strm, level, version, stream_size)
14762 + z_streamp strm;
14763 + int level;
14764 + const char *version;
14765 + int stream_size;
14766 +{
14767 + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
14768 + Z_DEFAULT_STRATEGY, version, stream_size);
14769 + /* To do: ignore strm->next_in if we use it as window */
14770 +}
14771 +
14772 +/* ========================================================================= */
14773 +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
14774 + version, stream_size)
14775 + z_streamp strm;
14776 + int level;
14777 + int method;
14778 + int windowBits;
14779 + int memLevel;
14780 + int strategy;
14781 + const char *version;
14782 + int stream_size;
14783 +{
14784 + deflate_state *s;
14785 + int noheader = 0;
14786 + static const char* my_version = ZLIB_VERSION;
14787 +
14788 + ushf *overlay;
14789 + /* We overlay pending_buf and d_buf+l_buf. This works since the average
14790 + * output size for (length,distance) codes is <= 24 bits.
14791 + */
14792 +
14793 + if (version == Z_NULL || version[0] != my_version[0] ||
14794 + stream_size != sizeof(z_stream)) {
14795 + return Z_VERSION_ERROR;
14796 + }
14797 + if (strm == Z_NULL) return Z_STREAM_ERROR;
14798 +
14799 + strm->msg = Z_NULL;
14800 + if (strm->zalloc == Z_NULL) {
14801 + return Z_STREAM_ERROR;
14802 +/* strm->zalloc = zcalloc;
14803 + strm->opaque = (voidpf)0;*/
14804 + }
14805 + if (strm->zfree == Z_NULL) return Z_STREAM_ERROR; /* strm->zfree = zcfree; */
14806 +
14807 + if (level == Z_DEFAULT_COMPRESSION) level = 6;
14808 +#ifdef FASTEST
14809 + level = 1;
14810 +#endif
14811 +
14812 + if (windowBits < 0) { /* undocumented feature: suppress zlib header */
14813 + noheader = 1;
14814 + windowBits = -windowBits;
14815 + }
14816 + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
14817 + windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
14818 + strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
14819 + return Z_STREAM_ERROR;
14820 + }
14821 + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
14822 + if (s == Z_NULL) return Z_MEM_ERROR;
14823 + strm->state = (struct internal_state FAR *)s;
14824 + s->strm = strm;
14825 +
14826 + s->noheader = noheader;
14827 + s->w_bits = windowBits;
14828 + s->w_size = 1 << s->w_bits;
14829 + s->w_mask = s->w_size - 1;
14830 +
14831 + s->hash_bits = memLevel + 7;
14832 + s->hash_size = 1 << s->hash_bits;
14833 + s->hash_mask = s->hash_size - 1;
14834 + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
14835 +
14836 + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
14837 + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
14838 + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
14839 +
14840 + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
14841 +
14842 + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
14843 + s->pending_buf = (uchf *) overlay;
14844 + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
14845 +
14846 + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
14847 + s->pending_buf == Z_NULL) {
14848 + strm->msg = ERR_MSG(Z_MEM_ERROR);
14849 + deflateEnd (strm);
14850 + return Z_MEM_ERROR;
14851 + }
14852 + s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
14853 + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
14854 +
14855 + s->level = level;
14856 + s->strategy = strategy;
14857 + s->method = (Byte)method;
14858 +
14859 + return deflateReset(strm);
14860 +}
14861 +
14862 +/* ========================================================================= */
14863 +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
14864 + z_streamp strm;
14865 + const Bytef *dictionary;
14866 + uInt dictLength;
14867 +{
14868 + deflate_state *s;
14869 + uInt length = dictLength;
14870 + uInt n;
14871 + IPos hash_head = 0;
14872 +
14873 + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
14874 + strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
14875 +
14876 + s = strm->state;
14877 + strm->adler = adler32(strm->adler, dictionary, dictLength);
14878 +
14879 + if (length < MIN_MATCH) return Z_OK;
14880 + if (length > MAX_DIST(s)) {
14881 + length = MAX_DIST(s);
14882 +#ifndef USE_DICT_HEAD
14883 + dictionary += dictLength - length; /* use the tail of the dictionary */
14884 +#endif
14885 + }
14886 + zmemcpy(s->window, dictionary, length);
14887 + s->strstart = length;
14888 + s->block_start = (long)length;
14889 +
14890 + /* Insert all strings in the hash table (except for the last two bytes).
14891 + * s->lookahead stays null, so s->ins_h will be recomputed at the next
14892 + * call of fill_window.
14893 + */
14894 + s->ins_h = s->window[0];
14895 + UPDATE_HASH(s, s->ins_h, s->window[1]);
14896 + for (n = 0; n <= length - MIN_MATCH; n++) {
14897 + INSERT_STRING(s, n, hash_head);
14898 + }
14899 + if (hash_head) hash_head = 0; /* to make compiler happy */
14900 + return Z_OK;
14901 +}
14902 +
14903 +/* ========================================================================= */
14904 +int ZEXPORT deflateReset (strm)
14905 + z_streamp strm;
14906 +{
14907 + deflate_state *s;
14908 +
14909 + if (strm == Z_NULL || strm->state == Z_NULL ||
14910 + strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
14911 +
14912 + strm->total_in = strm->total_out = 0;
14913 + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
14914 + strm->data_type = Z_UNKNOWN;
14915 +
14916 + s = (deflate_state *)strm->state;
14917 + s->pending = 0;
14918 + s->pending_out = s->pending_buf;
14919 +
14920 + if (s->noheader < 0) {
14921 + s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
14922 + }
14923 + s->status = s->noheader ? BUSY_STATE : INIT_STATE;
14924 + strm->adler = 1;
14925 + s->last_flush = Z_NO_FLUSH;
14926 +
14927 + _tr_init(s);
14928 + lm_init(s);
14929 +
14930 + return Z_OK;
14931 +}
14932 +
14933 +/* ========================================================================= */
14934 +int ZEXPORT deflateParams(strm, level, strategy)
14935 + z_streamp strm;
14936 + int level;
14937 + int strategy;
14938 +{
14939 + deflate_state *s;
14940 + compress_func func;
14941 + int err = Z_OK;
14942 +
14943 + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
14944 + s = strm->state;
14945 +
14946 + if (level == Z_DEFAULT_COMPRESSION) {
14947 + level = 6;
14948 + }
14949 + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
14950 + return Z_STREAM_ERROR;
14951 + }
14952 + func = configuration_table[s->level].func;
14953 +
14954 + if (func != configuration_table[level].func && strm->total_in != 0) {
14955 + /* Flush the last buffer: */
14956 + err = deflate(strm, Z_PARTIAL_FLUSH);
14957 + }
14958 + if (s->level != level) {
14959 + s->level = level;
14960 + s->max_lazy_match = configuration_table[level].max_lazy;
14961 + s->good_match = configuration_table[level].good_length;
14962 + s->nice_match = configuration_table[level].nice_length;
14963 + s->max_chain_length = configuration_table[level].max_chain;
14964 + }
14965 + s->strategy = strategy;
14966 + return err;
14967 +}
14968 +
14969 +/* =========================================================================
14970 + * Put a short in the pending buffer. The 16-bit value is put in MSB order.
14971 + * IN assertion: the stream state is correct and there is enough room in
14972 + * pending_buf.
14973 + */
14974 +local void putShortMSB (s, b)
14975 + deflate_state *s;
14976 + uInt b;
14977 +{
14978 + put_byte(s, (Byte)(b >> 8));
14979 + put_byte(s, (Byte)(b & 0xff));
14980 +}
14981 +
14982 +/* =========================================================================
14983 + * Flush as much pending output as possible. All deflate() output goes
14984 + * through this function so some applications may wish to modify it
14985 + * to avoid allocating a large strm->next_out buffer and copying into it.
14986 + * (See also read_buf()).
14987 + */
14988 +local void flush_pending(strm)
14989 + z_streamp strm;
14990 +{
14991 + unsigned len = strm->state->pending;
14992 +
14993 + if (len > strm->avail_out) len = strm->avail_out;
14994 + if (len == 0) return;
14995 +
14996 + zmemcpy(strm->next_out, strm->state->pending_out, len);
14997 + strm->next_out += len;
14998 + strm->state->pending_out += len;
14999 + strm->total_out += len;
15000 + strm->avail_out -= len;
15001 + strm->state->pending -= len;
15002 + if (strm->state->pending == 0) {
15003 + strm->state->pending_out = strm->state->pending_buf;
15004 + }
15005 +}
15006 +
15007 +/* ========================================================================= */
15008 +int ZEXPORT deflate (strm, flush)
15009 + z_streamp strm;
15010 + int flush;
15011 +{
15012 + int old_flush; /* value of flush param for previous deflate call */
15013 + deflate_state *s;
15014 +
15015 + if (strm == Z_NULL || strm->state == Z_NULL ||
15016 + flush > Z_FINISH || flush < 0) {
15017 + return Z_STREAM_ERROR;
15018 + }
15019 + s = strm->state;
15020 +
15021 + if (strm->next_out == Z_NULL ||
15022 + (strm->next_in == Z_NULL && strm->avail_in != 0) ||
15023 + (s->status == FINISH_STATE && flush != Z_FINISH)) {
15024 + ERR_RETURN(strm, Z_STREAM_ERROR);
15025 + }
15026 + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
15027 +
15028 + s->strm = strm; /* just in case */
15029 + old_flush = s->last_flush;
15030 + s->last_flush = flush;
15031 +
15032 + /* Write the zlib header */
15033 + if (s->status == INIT_STATE) {
15034 +
15035 + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
15036 + uInt level_flags = (s->level-1) >> 1;
15037 +
15038 + if (level_flags > 3) level_flags = 3;
15039 + header |= (level_flags << 6);
15040 + if (s->strstart != 0) header |= PRESET_DICT;
15041 + header += 31 - (header % 31);
15042 +
15043 + s->status = BUSY_STATE;
15044 + putShortMSB(s, header);
15045 +
15046 + /* Save the adler32 of the preset dictionary: */
15047 + if (s->strstart != 0) {
15048 + putShortMSB(s, (uInt)(strm->adler >> 16));
15049 + putShortMSB(s, (uInt)(strm->adler & 0xffff));
15050 + }
15051 + strm->adler = 1L;
15052 + }
15053 +
15054 + /* Flush as much pending output as possible */
15055 + if (s->pending != 0) {
15056 + flush_pending(strm);
15057 + if (strm->avail_out == 0) {
15058 + /* Since avail_out is 0, deflate will be called again with
15059 + * more output space, but possibly with both pending and
15060 + * avail_in equal to zero. There won't be anything to do,
15061 + * but this is not an error situation so make sure we
15062 + * return OK instead of BUF_ERROR at next call of deflate:
15063 + */
15064 + s->last_flush = -1;
15065 + return Z_OK;
15066 + }
15067 +
15068 + /* Make sure there is something to do and avoid duplicate consecutive
15069 + * flushes. For repeated and useless calls with Z_FINISH, we keep
15070 + * returning Z_STREAM_END instead of Z_BUFF_ERROR.
15071 + */
15072 + } else if (strm->avail_in == 0 && flush <= old_flush &&
15073 + flush != Z_FINISH) {
15074 + ERR_RETURN(strm, Z_BUF_ERROR);
15075 + }
15076 +
15077 + /* User must not provide more input after the first FINISH: */
15078 + if (s->status == FINISH_STATE && strm->avail_in != 0) {
15079 + ERR_RETURN(strm, Z_BUF_ERROR);
15080 + }
15081 +
15082 + /* Start a new block or continue the current one.
15083 + */
15084 + if (strm->avail_in != 0 || s->lookahead != 0 ||
15085 + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
15086 + block_state bstate;
15087 +
15088 + bstate = (*(configuration_table[s->level].func))(s, flush);
15089 +
15090 + if (bstate == finish_started || bstate == finish_done) {
15091 + s->status = FINISH_STATE;
15092 + }
15093 + if (bstate == need_more || bstate == finish_started) {
15094 + if (strm->avail_out == 0) {
15095 + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
15096 + }
15097 + return Z_OK;
15098 + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
15099 + * of deflate should use the same flush parameter to make sure
15100 + * that the flush is complete. So we don't have to output an
15101 + * empty block here, this will be done at next call. This also
15102 + * ensures that for a very small output buffer, we emit at most
15103 + * one empty block.
15104 + */
15105 + }
15106 + if (bstate == block_done) {
15107 + if (flush == Z_PARTIAL_FLUSH) {
15108 + _tr_align(s);
15109 + } else { /* FULL_FLUSH or SYNC_FLUSH */
15110 + _tr_stored_block(s, (char*)0, 0L, 0);
15111 + /* For a full flush, this empty block will be recognized
15112 + * as a special marker by inflate_sync().
15113 + */
15114 + if (flush == Z_FULL_FLUSH) {
15115 + CLEAR_HASH(s); /* forget history */
15116 + }
15117 + }
15118 + flush_pending(strm);
15119 + if (strm->avail_out == 0) {
15120 + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
15121 + return Z_OK;
15122 + }
15123 + }
15124 + }
15125 + Assert(strm->avail_out > 0, "bug2");
15126 +
15127 + if (flush != Z_FINISH) return Z_OK;
15128 + if (s->noheader) return Z_STREAM_END;
15129 +
15130 + /* Write the zlib trailer (adler32) */
15131 + putShortMSB(s, (uInt)(strm->adler >> 16));
15132 + putShortMSB(s, (uInt)(strm->adler & 0xffff));
15133 + flush_pending(strm);
15134 + /* If avail_out is zero, the application will call deflate again
15135 + * to flush the rest.
15136 + */
15137 + s->noheader = -1; /* write the trailer only once! */
15138 + return s->pending != 0 ? Z_OK : Z_STREAM_END;
15139 +}
15140 +
15141 +/* ========================================================================= */
15142 +int ZEXPORT deflateEnd (strm)
15143 + z_streamp strm;
15144 +{
15145 + int status;
15146 +
15147 + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
15148 +
15149 + status = strm->state->status;
15150 + if (status != INIT_STATE && status != BUSY_STATE &&
15151 + status != FINISH_STATE) {
15152 + return Z_STREAM_ERROR;
15153 + }
15154 +
15155 + /* Deallocate in reverse order of allocations: */
15156 + TRY_FREE(strm, strm->state->pending_buf);
15157 + TRY_FREE(strm, strm->state->head);
15158 + TRY_FREE(strm, strm->state->prev);
15159 + TRY_FREE(strm, strm->state->window);
15160 +
15161 + ZFREE(strm, strm->state);
15162 + strm->state = Z_NULL;
15163 +
15164 + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
15165 +}
15166 +
15167 +/* =========================================================================
15168 + * Copy the source state to the destination state.
15169 + * To simplify the source, this is not supported for 16-bit MSDOS (which
15170 + * doesn't have enough memory anyway to duplicate compression states).
15171 + */
15172 +int ZEXPORT deflateCopy (dest, source)
15173 + z_streamp dest;
15174 + z_streamp source;
15175 +{
15176 +#ifdef MAXSEG_64K
15177 + return Z_STREAM_ERROR;
15178 +#else
15179 + deflate_state *ds;
15180 + deflate_state *ss;
15181 + ushf *overlay;
15182 +
15183 +
15184 + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
15185 + return Z_STREAM_ERROR;
15186 + }
15187 +
15188 + ss = source->state;
15189 +
15190 + *dest = *source;
15191 +
15192 + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
15193 + if (ds == Z_NULL) return Z_MEM_ERROR;
15194 + dest->state = (struct internal_state FAR *) ds;
15195 + *ds = *ss;
15196 + ds->strm = dest;
15197 +
15198 + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
15199 + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
15200 + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
15201 + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
15202 + ds->pending_buf = (uchf *) overlay;
15203 +
15204 + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
15205 + ds->pending_buf == Z_NULL) {
15206 + deflateEnd (dest);
15207 + return Z_MEM_ERROR;
15208 + }
15209 + /* following zmemcpy do not work for 16-bit MSDOS */
15210 + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
15211 + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
15212 + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
15213 + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
15214 +
15215 + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
15216 + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
15217 + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
15218 +
15219 + ds->l_desc.dyn_tree = ds->dyn_ltree;
15220 + ds->d_desc.dyn_tree = ds->dyn_dtree;
15221 + ds->bl_desc.dyn_tree = ds->bl_tree;
15222 +
15223 + return Z_OK;
15224 +#endif
15225 +}
15226 +
15227 +/* ===========================================================================
15228 + * Read a new buffer from the current input stream, update the adler32
15229 + * and total number of bytes read. All deflate() input goes through
15230 + * this function so some applications may wish to modify it to avoid
15231 + * allocating a large strm->next_in buffer and copying from it.
15232 + * (See also flush_pending()).
15233 + */
15234 +local int read_buf(strm, buf, size)
15235 + z_streamp strm;
15236 + Bytef *buf;
15237 + unsigned size;
15238 +{
15239 + unsigned len = strm->avail_in;
15240 +
15241 + if (len > size) len = size;
15242 + if (len == 0) return 0;
15243 +
15244 + strm->avail_in -= len;
15245 +
15246 + if (!strm->state->noheader) {
15247 + strm->adler = adler32(strm->adler, strm->next_in, len);
15248 + }
15249 + zmemcpy(buf, strm->next_in, len);
15250 + strm->next_in += len;
15251 + strm->total_in += len;
15252 +
15253 + return (int)len;
15254 +}
15255 +
15256 +/* ===========================================================================
15257 + * Initialize the "longest match" routines for a new zlib stream
15258 + */
15259 +local void lm_init (s)
15260 + deflate_state *s;
15261 +{
15262 + s->window_size = (ulg)2L*s->w_size;
15263 +
15264 + CLEAR_HASH(s);
15265 +
15266 + /* Set the default configuration parameters:
15267 + */
15268 + s->max_lazy_match = configuration_table[s->level].max_lazy;
15269 + s->good_match = configuration_table[s->level].good_length;
15270 + s->nice_match = configuration_table[s->level].nice_length;
15271 + s->max_chain_length = configuration_table[s->level].max_chain;
15272 +
15273 + s->strstart = 0;
15274 + s->block_start = 0L;
15275 + s->lookahead = 0;
15276 + s->match_length = s->prev_length = MIN_MATCH-1;
15277 + s->match_available = 0;
15278 + s->ins_h = 0;
15279 +#ifdef ASMV
15280 + match_init(); /* initialize the asm code */
15281 +#endif
15282 +}
15283 +
15284 +/* ===========================================================================
15285 + * Set match_start to the longest match starting at the given string and
15286 + * return its length. Matches shorter or equal to prev_length are discarded,
15287 + * in which case the result is equal to prev_length and match_start is
15288 + * garbage.
15289 + * IN assertions: cur_match is the head of the hash chain for the current
15290 + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
15291 + * OUT assertion: the match length is not greater than s->lookahead.
15292 + */
15293 +#ifndef ASMV
15294 +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
15295 + * match.S. The code will be functionally equivalent.
15296 + */
15297 +#ifndef FASTEST
15298 +local uInt longest_match(s, cur_match)
15299 + deflate_state *s;
15300 + IPos cur_match; /* current match */
15301 +{
15302 + unsigned chain_length = s->max_chain_length;/* max hash chain length */
15303 + register Bytef *scan = s->window + s->strstart; /* current string */
15304 + register Bytef *match; /* matched string */
15305 + register int len; /* length of current match */
15306 + int best_len = s->prev_length; /* best match length so far */
15307 + int nice_match = s->nice_match; /* stop if match long enough */
15308 + IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
15309 + s->strstart - (IPos)MAX_DIST(s) : NIL;
15310 + /* Stop when cur_match becomes <= limit. To simplify the code,
15311 + * we prevent matches with the string of window index 0.
15312 + */
15313 + Posf *prev = s->prev;
15314 + uInt wmask = s->w_mask;
15315 +
15316 +#ifdef UNALIGNED_OK
15317 + /* Compare two bytes at a time. Note: this is not always beneficial.
15318 + * Try with and without -DUNALIGNED_OK to check.
15319 + */
15320 + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
15321 + register ush scan_start = *(ushf*)scan;
15322 + register ush scan_end = *(ushf*)(scan+best_len-1);
15323 +#else
15324 + register Bytef *strend = s->window + s->strstart + MAX_MATCH;
15325 + register Byte scan_end1 = scan[best_len-1];
15326 + register Byte scan_end = scan[best_len];
15327 +#endif
15328 +
15329 + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
15330 + * It is easy to get rid of this optimization if necessary.
15331 + */
15332 + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
15333 +
15334 + /* Do not waste too much time if we already have a good match: */
15335 + if (s->prev_length >= s->good_match) {
15336 + chain_length >>= 2;
15337 + }
15338 + /* Do not look for matches beyond the end of the input. This is necessary
15339 + * to make deflate deterministic.
15340 + */
15341 + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
15342 +
15343 + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
15344 +
15345 + do {
15346 + Assert(cur_match < s->strstart, "no future");
15347 + match = s->window + cur_match;
15348 +
15349 + /* Skip to next match if the match length cannot increase
15350 + * or if the match length is less than 2:
15351 + */
15352 +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
15353 + /* This code assumes sizeof(unsigned short) == 2. Do not use
15354 + * UNALIGNED_OK if your compiler uses a different size.
15355 + */
15356 + if (*(ushf*)(match+best_len-1) != scan_end ||
15357 + *(ushf*)match != scan_start) continue;
15358 +
15359 + /* It is not necessary to compare scan[2] and match[2] since they are
15360 + * always equal when the other bytes match, given that the hash keys
15361 + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
15362 + * strstart+3, +5, ... up to strstart+257. We check for insufficient
15363 + * lookahead only every 4th comparison; the 128th check will be made
15364 + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
15365 + * necessary to put more guard bytes at the end of the window, or
15366 + * to check more often for insufficient lookahead.
15367 + */
15368 + Assert(scan[2] == match[2], "scan[2]?");
15369 + scan++, match++;
15370 + do {
15371 + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15372 + *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15373 + *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15374 + *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15375 + scan < strend);
15376 + /* The funny "do {}" generates better code on most compilers */
15377 +
15378 + /* Here, scan <= window+strstart+257 */
15379 + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15380 + if (*scan == *match) scan++;
15381 +
15382 + len = (MAX_MATCH - 1) - (int)(strend-scan);
15383 + scan = strend - (MAX_MATCH-1);
15384 +
15385 +#else /* UNALIGNED_OK */
15386 +
15387 + if (match[best_len] != scan_end ||
15388 + match[best_len-1] != scan_end1 ||
15389 + *match != *scan ||
15390 + *++match != scan[1]) continue;
15391 +
15392 + /* The check at best_len-1 can be removed because it will be made
15393 + * again later. (This heuristic is not always a win.)
15394 + * It is not necessary to compare scan[2] and match[2] since they
15395 + * are always equal when the other bytes match, given that
15396 + * the hash keys are equal and that HASH_BITS >= 8.
15397 + */
15398 + scan += 2, match++;
15399 + Assert(*scan == *match, "match[2]?");
15400 +
15401 + /* We check for insufficient lookahead only every 8th comparison;
15402 + * the 256th check will be made at strstart+258.
15403 + */
15404 + do {
15405 + } while (*++scan == *++match && *++scan == *++match &&
15406 + *++scan == *++match && *++scan == *++match &&
15407 + *++scan == *++match && *++scan == *++match &&
15408 + *++scan == *++match && *++scan == *++match &&
15409 + scan < strend);
15410 +
15411 + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15412 +
15413 + len = MAX_MATCH - (int)(strend - scan);
15414 + scan = strend - MAX_MATCH;
15415 +
15416 +#endif /* UNALIGNED_OK */
15417 +
15418 + if (len > best_len) {
15419 + s->match_start = cur_match;
15420 + best_len = len;
15421 + if (len >= nice_match) break;
15422 +#ifdef UNALIGNED_OK
15423 + scan_end = *(ushf*)(scan+best_len-1);
15424 +#else
15425 + scan_end1 = scan[best_len-1];
15426 + scan_end = scan[best_len];
15427 +#endif
15428 + }
15429 + } while ((cur_match = prev[cur_match & wmask]) > limit
15430 + && --chain_length != 0);
15431 +
15432 + if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
15433 + return s->lookahead;
15434 +}
15435 +
15436 +#else /* FASTEST */
15437 +/* ---------------------------------------------------------------------------
15438 + * Optimized version for level == 1 only
15439 + */
15440 +local uInt longest_match(s, cur_match)
15441 + deflate_state *s;
15442 + IPos cur_match; /* current match */
15443 +{
15444 + register Bytef *scan = s->window + s->strstart; /* current string */
15445 + register Bytef *match; /* matched string */
15446 + register int len; /* length of current match */
15447 + register Bytef *strend = s->window + s->strstart + MAX_MATCH;
15448 +
15449 + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
15450 + * It is easy to get rid of this optimization if necessary.
15451 + */
15452 + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
15453 +
15454 + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
15455 +
15456 + Assert(cur_match < s->strstart, "no future");
15457 +
15458 + match = s->window + cur_match;
15459 +
15460 + /* Return failure if the match length is less than 2:
15461 + */
15462 + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
15463 +
15464 + /* The check at best_len-1 can be removed because it will be made
15465 + * again later. (This heuristic is not always a win.)
15466 + * It is not necessary to compare scan[2] and match[2] since they
15467 + * are always equal when the other bytes match, given that
15468 + * the hash keys are equal and that HASH_BITS >= 8.
15469 + */
15470 + scan += 2, match += 2;
15471 + Assert(*scan == *match, "match[2]?");
15472 +
15473 + /* We check for insufficient lookahead only every 8th comparison;
15474 + * the 256th check will be made at strstart+258.
15475 + */
15476 + do {
15477 + } while (*++scan == *++match && *++scan == *++match &&
15478 + *++scan == *++match && *++scan == *++match &&
15479 + *++scan == *++match && *++scan == *++match &&
15480 + *++scan == *++match && *++scan == *++match &&
15481 + scan < strend);
15482 +
15483 + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15484 +
15485 + len = MAX_MATCH - (int)(strend - scan);
15486 +
15487 + if (len < MIN_MATCH) return MIN_MATCH - 1;
15488 +
15489 + s->match_start = cur_match;
15490 + return len <= s->lookahead ? len : s->lookahead;
15491 +}
15492 +#endif /* FASTEST */
15493 +#endif /* ASMV */
15494 +
15495 +#ifdef DEBUG
15496 +/* ===========================================================================
15497 + * Check that the match at match_start is indeed a match.
15498 + */
15499 +local void check_match(s, start, match, length)
15500 + deflate_state *s;
15501 + IPos start, match;
15502 + int length;
15503 +{
15504 + /* check that the match is indeed a match */
15505 + if (zmemcmp(s->window + match,
15506 + s->window + start, length) != EQUAL) {
15507 + fprintf(stderr, " start %u, match %u, length %d\n",
15508 + start, match, length);
15509 + do {
15510 + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
15511 + } while (--length != 0);
15512 + z_error("invalid match");
15513 + }
15514 + if (z_verbose > 1) {
15515 + fprintf(stderr,"\\[%d,%d]", start-match, length);
15516 + do { putc(s->window[start++], stderr); } while (--length != 0);
15517 + }
15518 +}
15519 +#else
15520 +# define check_match(s, start, match, length)
15521 +#endif
15522 +
15523 +/* ===========================================================================
15524 + * Fill the window when the lookahead becomes insufficient.
15525 + * Updates strstart and lookahead.
15526 + *
15527 + * IN assertion: lookahead < MIN_LOOKAHEAD
15528 + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
15529 + * At least one byte has been read, or avail_in == 0; reads are
15530 + * performed for at least two bytes (required for the zip translate_eol
15531 + * option -- not supported here).
15532 + */
15533 +local void fill_window(s)
15534 + deflate_state *s;
15535 +{
15536 + register unsigned n, m;
15537 + register Posf *p;
15538 + unsigned more; /* Amount of free space at the end of the window. */
15539 + uInt wsize = s->w_size;
15540 +
15541 + do {
15542 + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
15543 +
15544 + /* Deal with !@#$% 64K limit: */
15545 + if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
15546 + more = wsize;
15547 +
15548 + } else if (more == (unsigned)(-1)) {
15549 + /* Very unlikely, but possible on 16 bit machine if strstart == 0
15550 + * and lookahead == 1 (input done one byte at time)
15551 + */
15552 + more--;
15553 +
15554 + /* If the window is almost full and there is insufficient lookahead,
15555 + * move the upper half to the lower one to make room in the upper half.
15556 + */
15557 + } else if (s->strstart >= wsize+MAX_DIST(s)) {
15558 +
15559 + zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
15560 + s->match_start -= wsize;
15561 + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
15562 + s->block_start -= (long) wsize;
15563 +
15564 + /* Slide the hash table (could be avoided with 32 bit values
15565 + at the expense of memory usage). We slide even when level == 0
15566 + to keep the hash table consistent if we switch back to level > 0
15567 + later. (Using level 0 permanently is not an optimal usage of
15568 + zlib, so we don't care about this pathological case.)
15569 + */
15570 + n = s->hash_size;
15571 + p = &s->head[n];
15572 + do {
15573 + m = *--p;
15574 + *p = (Pos)(m >= wsize ? m-wsize : NIL);
15575 + } while (--n);
15576 +
15577 + n = wsize;
15578 +#ifndef FASTEST
15579 + p = &s->prev[n];
15580 + do {
15581 + m = *--p;
15582 + *p = (Pos)(m >= wsize ? m-wsize : NIL);
15583 + /* If n is not on any hash chain, prev[n] is garbage but
15584 + * its value will never be used.
15585 + */
15586 + } while (--n);
15587 +#endif
15588 + more += wsize;
15589 + }
15590 + if (s->strm->avail_in == 0) return;
15591 +
15592 + /* If there was no sliding:
15593 + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
15594 + * more == window_size - lookahead - strstart
15595 + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
15596 + * => more >= window_size - 2*WSIZE + 2
15597 + * In the BIG_MEM or MMAP case (not yet supported),
15598 + * window_size == input_size + MIN_LOOKAHEAD &&
15599 + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
15600 + * Otherwise, window_size == 2*WSIZE so more >= 2.
15601 + * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
15602 + */
15603 + Assert(more >= 2, "more < 2");
15604 +
15605 + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
15606 + s->lookahead += n;
15607 +
15608 + /* Initialize the hash value now that we have some input: */
15609 + if (s->lookahead >= MIN_MATCH) {
15610 + s->ins_h = s->window[s->strstart];
15611 + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
15612 +#if MIN_MATCH != 3
15613 + Call UPDATE_HASH() MIN_MATCH-3 more times
15614 +#endif
15615 + }
15616 + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
15617 + * but this is not important since only literal bytes will be emitted.
15618 + */
15619 +
15620 + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
15621 +}
15622 +
15623 +/* ===========================================================================
15624 + * Flush the current block, with given end-of-file flag.
15625 + * IN assertion: strstart is set to the end of the current match.
15626 + */
15627 +#define FLUSH_BLOCK_ONLY(s, eof) { \
15628 + _tr_flush_block(s, (s->block_start >= 0L ? \
15629 + (charf *)&s->window[(unsigned)s->block_start] : \
15630 + (charf *)Z_NULL), \
15631 + (ulg)((long)s->strstart - s->block_start), \
15632 + (eof)); \
15633 + s->block_start = s->strstart; \
15634 + flush_pending(s->strm); \
15635 + Tracev((stderr,"[FLUSH]")); \
15636 +}
15637 +
15638 +/* Same but force premature exit if necessary. */
15639 +#define FLUSH_BLOCK(s, eof) { \
15640 + FLUSH_BLOCK_ONLY(s, eof); \
15641 + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
15642 +}
15643 +
15644 +/* ===========================================================================
15645 + * Copy without compression as much as possible from the input stream, return
15646 + * the current block state.
15647 + * This function does not insert new strings in the dictionary since
15648 + * uncompressible data is probably not useful. This function is used
15649 + * only for the level=0 compression option.
15650 + * NOTE: this function should be optimized to avoid extra copying from
15651 + * window to pending_buf.
15652 + */
15653 +local block_state deflate_stored(s, flush)
15654 + deflate_state *s;
15655 + int flush;
15656 +{
15657 + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
15658 + * to pending_buf_size, and each stored block has a 5 byte header:
15659 + */
15660 + ulg max_block_size = 0xffff;
15661 + ulg max_start;
15662 +
15663 + if (max_block_size > s->pending_buf_size - 5) {
15664 + max_block_size = s->pending_buf_size - 5;
15665 + }
15666 +
15667 + /* Copy as much as possible from input to output: */
15668 + for (;;) {
15669 + /* Fill the window as much as possible: */
15670 + if (s->lookahead <= 1) {
15671 +
15672 + Assert(s->strstart < s->w_size+MAX_DIST(s) ||
15673 + s->block_start >= (long)s->w_size, "slide too late");
15674 +
15675 + fill_window(s);
15676 + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
15677 +
15678 + if (s->lookahead == 0) break; /* flush the current block */
15679 + }
15680 + Assert(s->block_start >= 0L, "block gone");
15681 +
15682 + s->strstart += s->lookahead;
15683 + s->lookahead = 0;
15684 +
15685 + /* Emit a stored block if pending_buf will be full: */
15686 + max_start = s->block_start + max_block_size;
15687 + if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
15688 + /* strstart == 0 is possible when wraparound on 16-bit machine */
15689 + s->lookahead = (uInt)(s->strstart - max_start);
15690 + s->strstart = (uInt)max_start;
15691 + FLUSH_BLOCK(s, 0);
15692 + }
15693 + /* Flush if we may have to slide, otherwise block_start may become
15694 + * negative and the data will be gone:
15695 + */
15696 + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
15697 + FLUSH_BLOCK(s, 0);
15698 + }
15699 + }
15700 + FLUSH_BLOCK(s, flush == Z_FINISH);
15701 + return flush == Z_FINISH ? finish_done : block_done;
15702 +}
15703 +
15704 +/* ===========================================================================
15705 + * Compress as much as possible from the input stream, return the current
15706 + * block state.
15707 + * This function does not perform lazy evaluation of matches and inserts
15708 + * new strings in the dictionary only for unmatched strings or for short
15709 + * matches. It is used only for the fast compression options.
15710 + */
15711 +local block_state deflate_fast(s, flush)
15712 + deflate_state *s;
15713 + int flush;
15714 +{
15715 + IPos hash_head = NIL; /* head of the hash chain */
15716 + int bflush; /* set if current block must be flushed */
15717 +
15718 + for (;;) {
15719 + /* Make sure that we always have enough lookahead, except
15720 + * at the end of the input file. We need MAX_MATCH bytes
15721 + * for the next match, plus MIN_MATCH bytes to insert the
15722 + * string following the next match.
15723 + */
15724 + if (s->lookahead < MIN_LOOKAHEAD) {
15725 + fill_window(s);
15726 + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
15727 + return need_more;
15728 + }
15729 + if (s->lookahead == 0) break; /* flush the current block */
15730 + }
15731 +
15732 + /* Insert the string window[strstart .. strstart+2] in the
15733 + * dictionary, and set hash_head to the head of the hash chain:
15734 + */
15735 + if (s->lookahead >= MIN_MATCH) {
15736 + INSERT_STRING(s, s->strstart, hash_head);
15737 + }
15738 +
15739 + /* Find the longest match, discarding those <= prev_length.
15740 + * At this point we have always match_length < MIN_MATCH
15741 + */
15742 + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
15743 + /* To simplify the code, we prevent matches with the string
15744 + * of window index 0 (in particular we have to avoid a match
15745 + * of the string with itself at the start of the input file).
15746 + */
15747 + if (s->strategy != Z_HUFFMAN_ONLY) {
15748 + s->match_length = longest_match (s, hash_head);
15749 + }
15750 + /* longest_match() sets match_start */
15751 + }
15752 + if (s->match_length >= MIN_MATCH) {
15753 + check_match(s, s->strstart, s->match_start, s->match_length);
15754 +
15755 + _tr_tally_dist(s, s->strstart - s->match_start,
15756 + s->match_length - MIN_MATCH, bflush);
15757 +
15758 + s->lookahead -= s->match_length;
15759 +
15760 + /* Insert new strings in the hash table only if the match length
15761 + * is not too large. This saves time but degrades compression.
15762 + */
15763 +#ifndef FASTEST
15764 + if (s->match_length <= s->max_insert_length &&
15765 + s->lookahead >= MIN_MATCH) {
15766 + s->match_length--; /* string at strstart already in hash table */
15767 + do {
15768 + s->strstart++;
15769 + INSERT_STRING(s, s->strstart, hash_head);
15770 + /* strstart never exceeds WSIZE-MAX_MATCH, so there are
15771 + * always MIN_MATCH bytes ahead.
15772 + */
15773 + } while (--s->match_length != 0);
15774 + s->strstart++;
15775 + } else
15776 +#endif
15777 + {
15778 + s->strstart += s->match_length;
15779 + s->match_length = 0;
15780 + s->ins_h = s->window[s->strstart];
15781 + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
15782 +#if MIN_MATCH != 3
15783 + Call UPDATE_HASH() MIN_MATCH-3 more times
15784 +#endif
15785 + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
15786 + * matter since it will be recomputed at next deflate call.
15787 + */
15788 + }
15789 + } else {
15790 + /* No match, output a literal byte */
15791 + Tracevv((stderr,"%c", s->window[s->strstart]));
15792 + _tr_tally_lit (s, s->window[s->strstart], bflush);
15793 + s->lookahead--;
15794 + s->strstart++;
15795 + }
15796 + if (bflush) FLUSH_BLOCK(s, 0);
15797 + }
15798 + FLUSH_BLOCK(s, flush == Z_FINISH);
15799 + return flush == Z_FINISH ? finish_done : block_done;
15800 +}
15801 +
15802 +/* ===========================================================================
15803 + * Same as above, but achieves better compression. We use a lazy
15804 + * evaluation for matches: a match is finally adopted only if there is
15805 + * no better match at the next window position.
15806 + */
15807 +local block_state deflate_slow(s, flush)
15808 + deflate_state *s;
15809 + int flush;
15810 +{
15811 + IPos hash_head = NIL; /* head of hash chain */
15812 + int bflush; /* set if current block must be flushed */
15813 +
15814 + /* Process the input block. */
15815 + for (;;) {
15816 + /* Make sure that we always have enough lookahead, except
15817 + * at the end of the input file. We need MAX_MATCH bytes
15818 + * for the next match, plus MIN_MATCH bytes to insert the
15819 + * string following the next match.
15820 + */
15821 + if (s->lookahead < MIN_LOOKAHEAD) {
15822 + fill_window(s);
15823 + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
15824 + return need_more;
15825 + }
15826 + if (s->lookahead == 0) break; /* flush the current block */
15827 + }
15828 +
15829 + /* Insert the string window[strstart .. strstart+2] in the
15830 + * dictionary, and set hash_head to the head of the hash chain:
15831 + */
15832 + if (s->lookahead >= MIN_MATCH) {
15833 + INSERT_STRING(s, s->strstart, hash_head);
15834 + }
15835 +
15836 + /* Find the longest match, discarding those <= prev_length.
15837 + */
15838 + s->prev_length = s->match_length, s->prev_match = s->match_start;
15839 + s->match_length = MIN_MATCH-1;
15840 +
15841 + if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
15842 + s->strstart - hash_head <= MAX_DIST(s)) {
15843 + /* To simplify the code, we prevent matches with the string
15844 + * of window index 0 (in particular we have to avoid a match
15845 + * of the string with itself at the start of the input file).
15846 + */
15847 + if (s->strategy != Z_HUFFMAN_ONLY) {
15848 + s->match_length = longest_match (s, hash_head);
15849 + }
15850 + /* longest_match() sets match_start */
15851 +
15852 + if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
15853 + (s->match_length == MIN_MATCH &&
15854 + s->strstart - s->match_start > TOO_FAR))) {
15855 +
15856 + /* If prev_match is also MIN_MATCH, match_start is garbage
15857 + * but we will ignore the current match anyway.
15858 + */
15859 + s->match_length = MIN_MATCH-1;
15860 + }
15861 + }
15862 + /* If there was a match at the previous step and the current
15863 + * match is not better, output the previous match:
15864 + */
15865 + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
15866 + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
15867 + /* Do not insert strings in hash table beyond this. */
15868 +
15869 + check_match(s, s->strstart-1, s->prev_match, s->prev_length);
15870 +
15871 + _tr_tally_dist(s, s->strstart -1 - s->prev_match,
15872 + s->prev_length - MIN_MATCH, bflush);
15873 +
15874 + /* Insert in hash table all strings up to the end of the match.
15875 + * strstart-1 and strstart are already inserted. If there is not
15876 + * enough lookahead, the last two strings are not inserted in
15877 + * the hash table.
15878 + */
15879 + s->lookahead -= s->prev_length-1;
15880 + s->prev_length -= 2;
15881 + do {
15882 + if (++s->strstart <= max_insert) {
15883 + INSERT_STRING(s, s->strstart, hash_head);
15884 + }
15885 + } while (--s->prev_length != 0);
15886 + s->match_available = 0;
15887 + s->match_length = MIN_MATCH-1;
15888 + s->strstart++;
15889 +
15890 + if (bflush) FLUSH_BLOCK(s, 0);
15891 +
15892 + } else if (s->match_available) {
15893 + /* If there was no match at the previous position, output a
15894 + * single literal. If there was a match but the current match
15895 + * is longer, truncate the previous match to a single literal.
15896 + */
15897 + Tracevv((stderr,"%c", s->window[s->strstart-1]));
15898 + _tr_tally_lit(s, s->window[s->strstart-1], bflush);
15899 + if (bflush) {
15900 + FLUSH_BLOCK_ONLY(s, 0);
15901 + }
15902 + s->strstart++;
15903 + s->lookahead--;
15904 + if (s->strm->avail_out == 0) return need_more;
15905 + } else {
15906 + /* There is no previous match to compare with, wait for
15907 + * the next step to decide.
15908 + */
15909 + s->match_available = 1;
15910 + s->strstart++;
15911 + s->lookahead--;
15912 + }
15913 + }
15914 + Assert (flush != Z_NO_FLUSH, "no flush?");
15915 + if (s->match_available) {
15916 + Tracevv((stderr,"%c", s->window[s->strstart-1]));
15917 + _tr_tally_lit(s, s->window[s->strstart-1], bflush);
15918 + s->match_available = 0;
15919 + }
15920 + FLUSH_BLOCK(s, flush == Z_FINISH);
15921 + return flush == Z_FINISH ? finish_done : block_done;
15922 +}
15923 --- /dev/null Tue Mar 11 13:02:56 2003
15924 +++ linux/net/ipsec/deflate.h Mon Feb 9 13:51:03 2004
15925 @@ -0,0 +1,318 @@
15926 +/* deflate.h -- internal compression state
15927 + * Copyright (C) 1995-2002 Jean-loup Gailly
15928 + * For conditions of distribution and use, see copyright notice in zlib.h
15929 + */
15930 +
15931 +/* WARNING: this file should *not* be used by applications. It is
15932 + part of the implementation of the compression library and is
15933 + subject to change. Applications should only use zlib.h.
15934 + */
15935 +
15936 +/* @(#) $Id: deflate.h,v 1.5 2004/07/10 07:48:38 mcr Exp $ */
15937 +
15938 +#ifndef _DEFLATE_H
15939 +#define _DEFLATE_H
15940 +
15941 +#include "zlib/zutil.h"
15942 +
15943 +/* ===========================================================================
15944 + * Internal compression state.
15945 + */
15946 +
15947 +#define LENGTH_CODES 29
15948 +/* number of length codes, not counting the special END_BLOCK code */
15949 +
15950 +#define LITERALS 256
15951 +/* number of literal bytes 0..255 */
15952 +
15953 +#define L_CODES (LITERALS+1+LENGTH_CODES)
15954 +/* number of Literal or Length codes, including the END_BLOCK code */
15955 +
15956 +#define D_CODES 30
15957 +/* number of distance codes */
15958 +
15959 +#define BL_CODES 19
15960 +/* number of codes used to transfer the bit lengths */
15961 +
15962 +#define HEAP_SIZE (2*L_CODES+1)
15963 +/* maximum heap size */
15964 +
15965 +#define MAX_BITS 15
15966 +/* All codes must not exceed MAX_BITS bits */
15967 +
15968 +#define INIT_STATE 42
15969 +#define BUSY_STATE 113
15970 +#define FINISH_STATE 666
15971 +/* Stream status */
15972 +
15973 +
15974 +/* Data structure describing a single value and its code string. */
15975 +typedef struct ct_data_s {
15976 + union {
15977 + ush freq; /* frequency count */
15978 + ush code; /* bit string */
15979 + } fc;
15980 + union {
15981 + ush dad; /* father node in Huffman tree */
15982 + ush len; /* length of bit string */
15983 + } dl;
15984 +} FAR ct_data;
15985 +
15986 +#define Freq fc.freq
15987 +#define Code fc.code
15988 +#define Dad dl.dad
15989 +#define Len dl.len
15990 +
15991 +typedef struct static_tree_desc_s static_tree_desc;
15992 +
15993 +typedef struct tree_desc_s {
15994 + ct_data *dyn_tree; /* the dynamic tree */
15995 + int max_code; /* largest code with non zero frequency */
15996 + static_tree_desc *stat_desc; /* the corresponding static tree */
15997 +} FAR tree_desc;
15998 +
15999 +typedef ush Pos;
16000 +typedef Pos FAR Posf;
16001 +typedef unsigned IPos;
16002 +
16003 +/* A Pos is an index in the character window. We use short instead of int to
16004 + * save space in the various tables. IPos is used only for parameter passing.
16005 + */
16006 +
16007 +typedef struct internal_state {
16008 + z_streamp strm; /* pointer back to this zlib stream */
16009 + int status; /* as the name implies */
16010 + Bytef *pending_buf; /* output still pending */
16011 + ulg pending_buf_size; /* size of pending_buf */
16012 + Bytef *pending_out; /* next pending byte to output to the stream */
16013 + int pending; /* nb of bytes in the pending buffer */
16014 + int noheader; /* suppress zlib header and adler32 */
16015 + Byte data_type; /* UNKNOWN, BINARY or ASCII */
16016 + Byte method; /* STORED (for zip only) or DEFLATED */
16017 + int last_flush; /* value of flush param for previous deflate call */
16018 +
16019 + /* used by deflate.c: */
16020 +
16021 + uInt w_size; /* LZ77 window size (32K by default) */
16022 + uInt w_bits; /* log2(w_size) (8..16) */
16023 + uInt w_mask; /* w_size - 1 */
16024 +
16025 + Bytef *window;
16026 + /* Sliding window. Input bytes are read into the second half of the window,
16027 + * and move to the first half later to keep a dictionary of at least wSize
16028 + * bytes. With this organization, matches are limited to a distance of
16029 + * wSize-MAX_MATCH bytes, but this ensures that IO is always
16030 + * performed with a length multiple of the block size. Also, it limits
16031 + * the window size to 64K, which is quite useful on MSDOS.
16032 + * To do: use the user input buffer as sliding window.
16033 + */
16034 +
16035 + ulg window_size;
16036 + /* Actual size of window: 2*wSize, except when the user input buffer
16037 + * is directly used as sliding window.
16038 + */
16039 +
16040 + Posf *prev;
16041 + /* Link to older string with same hash index. To limit the size of this
16042 + * array to 64K, this link is maintained only for the last 32K strings.
16043 + * An index in this array is thus a window index modulo 32K.
16044 + */
16045 +
16046 + Posf *head; /* Heads of the hash chains or NIL. */
16047 +
16048 + uInt ins_h; /* hash index of string to be inserted */
16049 + uInt hash_size; /* number of elements in hash table */
16050 + uInt hash_bits; /* log2(hash_size) */
16051 + uInt hash_mask; /* hash_size-1 */
16052 +
16053 + uInt hash_shift;
16054 + /* Number of bits by which ins_h must be shifted at each input
16055 + * step. It must be such that after MIN_MATCH steps, the oldest
16056 + * byte no longer takes part in the hash key, that is:
16057 + * hash_shift * MIN_MATCH >= hash_bits
16058 + */
16059 +
16060 + long block_start;
16061 + /* Window position at the beginning of the current output block. Gets
16062 + * negative when the window is moved backwards.
16063 + */
16064 +
16065 + uInt match_length; /* length of best match */
16066 + IPos prev_match; /* previous match */
16067 + int match_available; /* set if previous match exists */
16068 + uInt strstart; /* start of string to insert */
16069 + uInt match_start; /* start of matching string */
16070 + uInt lookahead; /* number of valid bytes ahead in window */
16071 +
16072 + uInt prev_length;
16073 + /* Length of the best match at previous step. Matches not greater than this
16074 + * are discarded. This is used in the lazy match evaluation.
16075 + */
16076 +
16077 + uInt max_chain_length;
16078 + /* To speed up deflation, hash chains are never searched beyond this
16079 + * length. A higher limit improves compression ratio but degrades the
16080 + * speed.
16081 + */
16082 +
16083 + uInt max_lazy_match;
16084 + /* Attempt to find a better match only when the current match is strictly
16085 + * smaller than this value. This mechanism is used only for compression
16086 + * levels >= 4.
16087 + */
16088 +# define max_insert_length max_lazy_match
16089 + /* Insert new strings in the hash table only if the match length is not
16090 + * greater than this length. This saves time but degrades compression.
16091 + * max_insert_length is used only for compression levels <= 3.
16092 + */
16093 +
16094 + int level; /* compression level (1..9) */
16095 + int strategy; /* favor or force Huffman coding*/
16096 +
16097 + uInt good_match;
16098 + /* Use a faster search when the previous match is longer than this */
16099 +
16100 + int nice_match; /* Stop searching when current match exceeds this */
16101 +
16102 + /* used by trees.c: */
16103 + /* Didn't use ct_data typedef below to supress compiler warning */
16104 + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
16105 + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
16106 + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
16107 +
16108 + struct tree_desc_s l_desc; /* desc. for literal tree */
16109 + struct tree_desc_s d_desc; /* desc. for distance tree */
16110 + struct tree_desc_s bl_desc; /* desc. for bit length tree */
16111 +
16112 + ush bl_count[MAX_BITS+1];
16113 + /* number of codes at each bit length for an optimal tree */
16114 +
16115 + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
16116 + int heap_len; /* number of elements in the heap */
16117 + int heap_max; /* element of largest frequency */
16118 + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
16119 + * The same heap array is used to build all trees.
16120 + */
16121 +
16122 + uch depth[2*L_CODES+1];
16123 + /* Depth of each subtree used as tie breaker for trees of equal frequency
16124 + */
16125 +
16126 + uchf *l_buf; /* buffer for literals or lengths */
16127 +
16128 + uInt lit_bufsize;
16129 + /* Size of match buffer for literals/lengths. There are 4 reasons for
16130 + * limiting lit_bufsize to 64K:
16131 + * - frequencies can be kept in 16 bit counters
16132 + * - if compression is not successful for the first block, all input
16133 + * data is still in the window so we can still emit a stored block even
16134 + * when input comes from standard input. (This can also be done for
16135 + * all blocks if lit_bufsize is not greater than 32K.)
16136 + * - if compression is not successful for a file smaller than 64K, we can
16137 + * even emit a stored file instead of a stored block (saving 5 bytes).
16138 + * This is applicable only for zip (not gzip or zlib).
16139 + * - creating new Huffman trees less frequently may not provide fast
16140 + * adaptation to changes in the input data statistics. (Take for
16141 + * example a binary file with poorly compressible code followed by
16142 + * a highly compressible string table.) Smaller buffer sizes give
16143 + * fast adaptation but have of course the overhead of transmitting
16144 + * trees more frequently.
16145 + * - I can't count above 4
16146 + */
16147 +
16148 + uInt last_lit; /* running index in l_buf */
16149 +
16150 + ushf *d_buf;
16151 + /* Buffer for distances. To simplify the code, d_buf and l_buf have
16152 + * the same number of elements. To use different lengths, an extra flag
16153 + * array would be necessary.
16154 + */
16155 +
16156 + ulg opt_len; /* bit length of current block with optimal trees */
16157 + ulg static_len; /* bit length of current block with static trees */
16158 + uInt matches; /* number of string matches in current block */
16159 + int last_eob_len; /* bit length of EOB code for last block */
16160 +
16161 +#ifdef DEBUG
16162 + ulg compressed_len; /* total bit length of compressed file mod 2^32 */
16163 + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
16164 +#endif
16165 +
16166 + ush bi_buf;
16167 + /* Output buffer. bits are inserted starting at the bottom (least
16168 + * significant bits).
16169 + */
16170 + int bi_valid;
16171 + /* Number of valid bits in bi_buf. All bits above the last valid bit
16172 + * are always zero.
16173 + */
16174 +
16175 +} FAR deflate_state;
16176 +
16177 +/* Output a byte on the stream.
16178 + * IN assertion: there is enough room in pending_buf.
16179 + */
16180 +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
16181 +
16182 +
16183 +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
16184 +/* Minimum amount of lookahead, except at the end of the input file.
16185 + * See deflate.c for comments about the MIN_MATCH+1.
16186 + */
16187 +
16188 +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
16189 +/* In order to simplify the code, particularly on 16 bit machines, match
16190 + * distances are limited to MAX_DIST instead of WSIZE.
16191 + */
16192 +
16193 + /* in trees.c */
16194 +void _tr_init OF((deflate_state *s));
16195 +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
16196 +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
16197 + int eof));
16198 +void _tr_align OF((deflate_state *s));
16199 +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
16200 + int eof));
16201 +
16202 +#define d_code(dist) \
16203 + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
16204 +/* Mapping from a distance to a distance code. dist is the distance - 1 and
16205 + * must not have side effects. _dist_code[256] and _dist_code[257] are never
16206 + * used.
16207 + */
16208 +
16209 +#ifndef DEBUG
16210 +/* Inline versions of _tr_tally for speed: */
16211 +
16212 +#if defined(GEN_TREES_H) || !defined(STDC)
16213 + extern uch _length_code[];
16214 + extern uch _dist_code[];
16215 +#else
16216 + extern const uch _length_code[];
16217 + extern const uch _dist_code[];
16218 +#endif
16219 +
16220 +# define _tr_tally_lit(s, c, flush) \
16221 + { uch cc = (c); \
16222 + s->d_buf[s->last_lit] = 0; \
16223 + s->l_buf[s->last_lit++] = cc; \
16224 + s->dyn_ltree[cc].Freq++; \
16225 + flush = (s->last_lit == s->lit_bufsize-1); \
16226 + }
16227 +# define _tr_tally_dist(s, distance, length, flush) \
16228 + { uch len = (length); \
16229 + ush dist = (distance); \
16230 + s->d_buf[s->last_lit] = dist; \
16231 + s->l_buf[s->last_lit++] = len; \
16232 + dist--; \
16233 + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
16234 + s->dyn_dtree[d_code(dist)].Freq++; \
16235 + flush = (s->last_lit == s->lit_bufsize-1); \
16236 + }
16237 +#else
16238 +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
16239 +# define _tr_tally_dist(s, distance, length, flush) \
16240 + flush = _tr_tally(s, distance, length)
16241 +#endif
16242 +
16243 +#endif /* _DEFLATE_H */
16244 --- /dev/null Tue Mar 11 13:02:56 2003
16245 +++ linux/net/ipsec/des/COPYRIGHT Mon Feb 9 13:51:03 2004
16246 @@ -0,0 +1,50 @@
16247 +Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
16248 +All rights reserved.
16249 +
16250 +This package is an DES implementation written by Eric Young (eay@cryptsoft.com).
16251 +The implementation was written so as to conform with MIT's libdes.
16252 +
16253 +This library is free for commercial and non-commercial use as long as
16254 +the following conditions are aheared to. The following conditions
16255 +apply to all code found in this distribution.
16256 +
16257 +Copyright remains Eric Young's, and as such any Copyright notices in
16258 +the code are not to be removed.
16259 +If this package is used in a product, Eric Young should be given attribution
16260 +as the author of that the SSL library. This can be in the form of a textual
16261 +message at program startup or in documentation (online or textual) provided
16262 +with the package.
16263 +
16264 +Redistribution and use in source and binary forms, with or without
16265 +modification, are permitted provided that the following conditions
16266 +are met:
16267 +1. Redistributions of source code must retain the copyright
16268 + notice, this list of conditions and the following disclaimer.
16269 +2. Redistributions in binary form must reproduce the above copyright
16270 + notice, this list of conditions and the following disclaimer in the
16271 + documentation and/or other materials provided with the distribution.
16272 +3. All advertising materials mentioning features or use of this software
16273 + must display the following acknowledgement:
16274 + This product includes software developed by Eric Young (eay@cryptsoft.com)
16275 +
16276 +THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
16277 +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16278 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16279 +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16280 +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
16281 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
16282 +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
16283 +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
16284 +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
16285 +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
16286 +SUCH DAMAGE.
16287 +
16288 +The license and distribution terms for any publically available version or
16289 +derivative of this code cannot be changed. i.e. this code cannot simply be
16290 +copied and put under another distrubution license
16291 +[including the GNU Public License.]
16292 +
16293 +The reason behind this being stated in this direct manner is past
16294 +experience in code simply being copied and the attribution removed
16295 +from it and then being distributed as part of other packages. This
16296 +implementation was a non-trivial and unpaid effort.
16297 --- /dev/null Tue Mar 11 13:02:56 2003
16298 +++ linux/net/ipsec/des/INSTALL Mon Feb 9 13:51:03 2004
16299 @@ -0,0 +1,69 @@
16300 +Check the CC and CFLAGS lines in the makefile
16301 +
16302 +If your C library does not support the times(3) function, change the
16303 +#define TIMES to
16304 +#undef TIMES in speed.c
16305 +If it does, check the HZ value for the times(3) function.
16306 +If your system does not define CLK_TCK it will be assumed to
16307 +be 100.0.
16308 +
16309 +If possible use gcc v 2.7.?
16310 +Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc)
16311 +In recent times, some system compilers give better performace.
16312 +
16313 +type 'make'
16314 +
16315 +run './destest' to check things are ok.
16316 +run './rpw' to check the tty code for reading passwords works.
16317 +run './speed' to see how fast those optimisations make the library run :-)
16318 +run './des_opts' to determin the best compile time options.
16319 +
16320 +The output from des_opts should be put in the makefile options and des_enc.c
16321 +should be rebuilt. For 64 bit computers, do not use the DES_PTR option.
16322 +For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int'
16323 +and then you can use the 'DES_PTR' option.
16324 +
16325 +The file options.txt has the options listed for best speed on quite a
16326 +few systems. Look and the options (UNROLL, PTR, RISC2 etc) and then
16327 +turn on the relevent option in the Makefile
16328 +
16329 +There are some special Makefile targets that make life easier.
16330 +make cc - standard cc build
16331 +make gcc - standard gcc build
16332 +make x86-elf - x86 assembler (elf), linux-elf.
16333 +make x86-out - x86 assembler (a.out), FreeBSD
16334 +make x86-solaris- x86 assembler
16335 +make x86-bsdi - x86 assembler (a.out with primative assembler).
16336 +
16337 +If at all possible use the assembler (for Windows NT/95, use
16338 +asm/win32.obj to link with). The x86 assembler is very very fast.
16339 +
16340 +A make install will by default install
16341 +libdes.a in /usr/local/lib/libdes.a
16342 +des in /usr/local/bin/des
16343 +des_crypt.man in /usr/local/man/man3/des_crypt.3
16344 +des.man in /usr/local/man/man1/des.1
16345 +des.h in /usr/include/des.h
16346 +
16347 +des(1) should be compatible with sunOS's but I have been unable to
16348 +test it.
16349 +
16350 +These routines should compile on MSDOS, most 32bit and 64bit version
16351 +of Unix (BSD and SYSV) and VMS, without modification.
16352 +The only problems should be #include files that are in the wrong places.
16353 +
16354 +These routines can be compiled under MSDOS.
16355 +I have successfully encrypted files using des(1) under MSDOS and then
16356 +decrypted the files on a SparcStation.
16357 +I have been able to compile and test the routines with
16358 +Microsoft C v 5.1 and Turbo C v 2.0.
16359 +The code in this library is in no way optimised for the 16bit
16360 +operation of MSDOS.
16361 +
16362 +When building for glibc, ignore all of the above and just unpack into
16363 +glibc-1.??/des and then gmake as per normal.
16364 +
16365 +As a final note on performace. Certain CPUs like sparcs and Alpha often give
16366 +a %10 speed difference depending on the link order. It is rather anoying
16367 +when one program reports 'x' DES encrypts a second and another reports
16368 +'x*0.9' the speed.
16369 --- /dev/null Tue Mar 11 13:02:56 2003
16370 +++ linux/net/ipsec/des/Makefile Mon Feb 9 13:51:03 2004
16371 @@ -0,0 +1,60 @@
16372 +# Makefile for KLIPS kernel code as a module for 2.6 kernels
16373 +#
16374 +# Makefile for KLIPS kernel code as a module
16375 +# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
16376 +# Copyright (C) 2002-2004 Michael Richardson <mcr@freeswan.org>
16377 +#
16378 +# This program is free software; you can redistribute it and/or modify it
16379 +# under the terms of the GNU General Public License as published by the
16380 +# Free Software Foundation; either version 2 of the License, or (at your
16381 +# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16382 +#
16383 +# This program is distributed in the hope that it will be useful, but
16384 +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16385 +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16386 +# for more details.
16387 +#
16388 +# RCSID $Id: Makefile.fs2_6,v 1.3 2005/08/12 14:13:59 mcr Exp $
16389 +#
16390 +# Note! Dependencies are done automagically by 'make dep', which also
16391 +# removes any old dependencies. DON'T put your own dependencies here
16392 +# unless it's something special (ie not a .c file).
16393 +#
16394 +
16395 +obj-$(CONFIG_KLIPS_ENC_3DES) += ipsec_alg_3des.o
16396 +obj-$(CONFIG_KLIPS_ENC_3DES) += cbc_enc.o
16397 +obj-$(CONFIG_KLIPS_ENC_3DES) += ecb_enc.o
16398 +obj-$(CONFIG_KLIPS_ENC_3DES) += set_key.o
16399 +
16400 +ifeq ($(strip ${SUBARCH}),)
16401 +SUBARCH:=${ARCH}
16402 +endif
16403 +
16404 +# the assembly version expects frame pointers, which are
16405 +# optional in many kernel builds. If you want speed, you should
16406 +# probably use cryptoapi code instead.
16407 +USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
16408 +ifeq (${USEASSEMBLY},i386y)
16409 +obj-$(CONFIG_KLIPS_ENC_3DES) += dx86unix.o
16410 +else
16411 +obj-$(CONFIG_KLIPS_ENC_3DES) += des_enc.o
16412 +endif
16413 +
16414 +#
16415 +# $Log: Makefile.fs2_6,v $
16416 +# Revision 1.3 2005/08/12 14:13:59 mcr
16417 +# do not use assembly code with there are no frame pointers,
16418 +# as it does not have the right linkages.
16419 +#
16420 +# Revision 1.2 2005/04/29 05:13:07 mcr
16421 +# 3DES algorithm code.
16422 +#
16423 +# Revision 1.1 2004/08/17 03:27:30 mcr
16424 +# klips 2.6 edits.
16425 +#
16426 +#
16427 +# Local Variables:
16428 +# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
16429 +# End Variables:
16430 +#
16431 +
16432 --- /dev/null Tue Mar 11 13:02:56 2003
16433 +++ linux/net/ipsec/des/README Mon Feb 9 13:51:03 2004
16434 @@ -0,0 +1,54 @@
16435 +
16436 + libdes, Version 4.01 10-Jan-97
16437 +
16438 + Copyright (c) 1997, Eric Young
16439 + All rights reserved.
16440 +
16441 + This program is free software; you can redistribute it and/or modify
16442 + it under the terms specified in COPYRIGHT.
16443 +
16444 +--
16445 +The primary ftp site for this library is
16446 +ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz
16447 +libdes is now also shipped with SSLeay. Primary ftp site of
16448 +ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz
16449 +
16450 +The best way to build this library is to build it as part of SSLeay.
16451 +
16452 +This kit builds a DES encryption library and a DES encryption program.
16453 +It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb,
16454 +triple cfb, desx, and MIT's pcbc encryption modes and also has a fast
16455 +implementation of crypt(3).
16456 +It contains support routines to read keys from a terminal,
16457 +generate a random key, generate a key from an arbitrary length string,
16458 +read/write encrypted data from/to a file descriptor.
16459 +
16460 +The implementation was written so as to conform with the manual entry
16461 +for the des_crypt(3) library routines from MIT's project Athena.
16462 +
16463 +destest should be run after compilation to test the des routines.
16464 +rpw should be run after compilation to test the read password routines.
16465 +The des program is a replacement for the sun des command. I believe it
16466 +conforms to the sun version.
16467 +
16468 +The Imakefile is setup for use in the kerberos distribution.
16469 +
16470 +These routines are best compiled with gcc or any other good
16471 +optimising compiler.
16472 +Just turn you optimiser up to the highest settings and run destest
16473 +after the build to make sure everything works.
16474 +
16475 +I believe these routines are close to the fastest and most portable DES
16476 +routines that use small lookup tables (4.5k) that are publicly available.
16477 +The fcrypt routine is faster than ufc's fcrypt (when compiling with
16478 +gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines
16479 +(on a sun3/260 168 vs 336). It is a function of CPU on chip cache size.
16480 +[ 10-Jan-97 and a function of an incorrect speed testing program in
16481 + ufc which gave much better test figures that reality ].
16482 +
16483 +It is worth noting that on sparc and Alpha CPUs, performance of the DES
16484 +library can vary by upto %10 due to the positioning of files after application
16485 +linkage.
16486 +
16487 +Eric Young (eay@cryptsoft.com)
16488 +
16489 --- /dev/null Tue Mar 11 13:02:56 2003
16490 +++ linux/net/ipsec/des/README.freeswan Mon Feb 9 13:51:03 2004
16491 @@ -0,0 +1,33 @@
16492 +The only changes the FreeS/WAN project has made to libdes-lite 4.04b are:
16493 +
16494 +We #ifdef-ed the declaration of DES_LONG in des.h, so it's more efficient
16495 +on the Alpha, instead of just noting the issue in a comment.
16496 +
16497 +We #ifdef-ed out the des_options() function in ecb_enc.c, because we don't
16498 +use it, and its call to sprintf() can cause subtle difficulties when KLIPS
16499 +is built as a module (depending on details of Linux configuration options).
16500 +
16501 +We changed some instances of CC=$(CC) in the Makefile to CC='$(CC)' to make
16502 +it cope better with Linux kernel Makefile stupidities, and took out an
16503 +explicit CC=gcc (unwise on systems with strange compilers).
16504 +
16505 +We deleted some references to <stdio.h> and <stdlib.h>, and a declaration
16506 +of one function found only in the full libdes (not in libdes-lite), to
16507 +avoid dragging in bits of stdio/stdlib unnecessarily. (Our thanks to Hans
16508 +Schultz for spotting this and pointing out the fixes.)
16509 +
16510 +We deleted a couple of .obj files in the asm subdirectory, which appear to
16511 +have been included in the original library by accident.
16512 +
16513 +We have added an include of our Makefile.inc file, to permit overriding
16514 +things like choice of compiler (although the libdes Makefile would
16515 +probably need some work to make this effective).
16516 +
16517 +
16518 +
16519 +Note that Eric Young is no longer at the email address listed in these
16520 +files, and is (alas) no longer working on free crypto software.
16521 +
16522 +
16523 +
16524 +This file is RCSID $Id: README.freeswan,v 1.12 2004/07/10 08:06:51 mcr Exp $
16525 --- /dev/null Tue Mar 11 13:02:56 2003
16526 +++ linux/net/ipsec/des/VERSION Mon Feb 9 13:51:03 2004
16527 @@ -0,0 +1,406 @@
16528 +Version 4.04
16529 + Fixed a few tests in destest. Also added x86 assember for
16530 + des_ncbc_encrypt() which is the standard cbc mode function.
16531 + This makes a very very large performace difference.
16532 + Ariel Glenn ariel@columbia.edu reports that the terminal
16533 + 'turn echo off' can return (errno == EINVAL) under solaris
16534 + when redirection is used. So I now catch that as well as ENOTTY.
16535 +
16536 +
16537 +Version 4.03
16538 + Left a static out of enc_write.c, which caused to buffer to be
16539 + continiously malloc()ed. Does anyone use these functions? I keep
16540 + on feeling like removing them since I only had these in there
16541 + for a version of kerberised login. Anyway, this was pointed out
16542 + by Theo de Raadt <deraadt@cvs.openbsd.org>
16543 + The 'n' bit ofb code was wrong, it was not shifting the shift
16544 + register. It worked correctly for n == 64. Thanks to
16545 + Gigi Ankeny <Gigi.Ankeny@Eng.Sun.COM> for pointing this one out.
16546 +
16547 +Version 4.02
16548 + I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)'
16549 + when checking for weak keys which is wrong :-(, pointed out by
16550 + Markus F.X.J. Oberhumer <markus.oberhumer@jk.uni-linz.ac.at>.
16551 +
16552 +Version 4.01
16553 + Even faster inner loop in the DES assembler for x86 and a modification
16554 + for IP/FP which is faster on x86. Both of these changes are
16555 + from Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>. His
16556 + changes make the assembler run %40 faster on a pentium. This is just
16557 + a case of getting the instruction sequence 'just right'.
16558 + All credit to 'Svend' :-)
16559 + Quite a few special x86 'make' targets.
16560 + A libdes-l (lite) distribution.
16561 +
16562 +Version 4.00
16563 + After a bit of a pause, I'll up the major version number since this
16564 + is mostly a performace release. I've added x86 assembler and
16565 + added more options for performance. A %28 speedup for gcc
16566 + on a pentium and the assembler is a %50 speedup.
16567 + MIPS CPU's, sparc and Alpha are the main CPU's with speedups.
16568 + Run des_opts to work out which options should be used.
16569 + DES_RISC1/DES_RISC2 use alternative inner loops which use
16570 + more registers but should give speedups on any CPU that does
16571 + dual issue (pentium). DES_UNROLL unrolls the inner loop,
16572 + which costs in code size.
16573 +
16574 +Version 3.26
16575 + I've finally removed one of the shifts in D_ENCRYPT. This
16576 + meant I've changed the des_SPtrans table (spr.h), the set_key()
16577 + function and some things in des_enc.c. This has definitly
16578 + made things faster :-). I've known about this one for some
16579 + time but I've been too lazy to follow it up :-).
16580 + Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^..
16581 + instead of L^=((..)|(..)|(..).. This should save a register at
16582 + least.
16583 + Assember for x86. The file to replace is des_enc.c, which is replaced
16584 + by one of the assembler files found in asm. Look at des/asm/readme
16585 + for more info.
16586 +
16587 + /* Modification to fcrypt so it can be compiled to support
16588 + HPUX 10.x's long password format, define -DLONGCRYPT to use this.
16589 + Thanks to Jens Kupferschmidt <bt1cu@hpboot.rz.uni-leipzig.de>. */
16590 +
16591 + SIGWINCH case put in des_read_passwd() so the function does not
16592 + 'exit' if this function is recieved.
16593 +
16594 +Version 3.25 17/07/96
16595 + Modified read_pwd.c so that stdin can be read if not a tty.
16596 + Thanks to Jeff Barber <jeffb@issl.atl.hp.com> for the patches.
16597 + des_init_random_number_generator() shortened due to VMS linker
16598 + limits.
16599 + Added RSA's DESX cbc mode. It is a form of cbc encryption, with 2
16600 + 8 byte quantites xored before and after encryption.
16601 + des_xcbc_encryption() - the name is funny to preserve the des_
16602 + prefix on all functions.
16603 +
16604 +Version 3.24 20/04/96
16605 + The DES_PTR macro option checked and used by SSLeay configuration
16606 +
16607 +Version 3.23 11/04/96
16608 + Added DES_LONG. If defined to 'unsigned int' on the DEC Alpha,
16609 + it gives a %20 speedup :-)
16610 + Fixed the problem with des.pl under perl5. The patches were
16611 + sent by Ed Kubaitis (ejk@uiuc.edu).
16612 + if fcrypt.c, changed values to handle illegal salt values the way
16613 + normal crypt() implementations do. Some programs apparently use
16614 + them :-(. The patch was sent by Bjorn Gronvall <bg@sics.se>
16615 +
16616 +Version 3.22 29/11/95
16617 + Bug in des(1), an error with the uuencoding stuff when the
16618 + 'data' is small, thanks to Geoff Keating <keagchon@mehta.anu.edu.au>
16619 + for the patch.
16620 +
16621 +Version 3.21 22/11/95
16622 + After some emailing back and forth with
16623 + Colin Plumb <colin@nyx10.cs.du.edu>, I've tweaked a few things
16624 + and in a future version I will probably put in some of the
16625 + optimisation he suggested for use with the DES_USE_PTR option.
16626 + Extra routines from Mark Murray <mark@grondar.za> for use in
16627 + freeBSD. They mostly involve random number generation for use
16628 + with kerberos. They involve evil machine specific system calls
16629 + etc so I would normally suggest pushing this stuff into the
16630 + application and/or using RAND_seed()/RAND_bytes() if you are
16631 + using this DES library as part of SSLeay.
16632 + Redone the read_pw() function so that it is cleaner and
16633 + supports termios, thanks to Sameer Parekh <sameer@c2.org>
16634 + for the initial patches for this.
16635 + Renamed 3ecb_encrypt() to ecb3_encrypt(). This has been
16636 + done just to make things more consistent.
16637 + I have also now added triple DES versions of cfb and ofb.
16638 +
16639 +Version 3.20
16640 + Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com,
16641 + my des_random_seed() function was only copying 4 bytes of the
16642 + passed seed into the init structure. It is now fixed to copy 8.
16643 + My own suggestion is to used something like MD5 :-)
16644 +
16645 +Version 3.19
16646 + While looking at my code one day, I though, why do I keep on
16647 + calling des_encrypt(in,out,ks,enc) when every function that
16648 + calls it has in and out the same. So I dropped the 'out'
16649 + parameter, people should not be using this function.
16650 +
16651 +Version 3.18 30/08/95
16652 + Fixed a few bit with the distribution and the filenames.
16653 + 3.17 had been munged via a move to DOS and back again.
16654 + NO CODE CHANGES
16655 +
16656 +Version 3.17 14/07/95
16657 + Fixed ede3 cbc which I had broken in 3.16. I have also
16658 + removed some unneeded variables in 7-8 of the routines.
16659 +
16660 +Version 3.16 26/06/95
16661 + Added des_encrypt2() which does not use IP/FP, used by triple
16662 + des routines. Tweaked things a bit elsewhere. %13 speedup on
16663 + sparc and %6 on a R4400 for ede3 cbc mode.
16664 +
16665 +Version 3.15 06/06/95
16666 + Added des_ncbc_encrypt(), it is des_cbc mode except that it is
16667 + 'normal' and copies the new iv value back over the top of the
16668 + passed parameter.
16669 + CHANGED des_ede3_cbc_encrypt() so that it too now overwrites
16670 + the iv. THIS WILL BREAK EXISTING CODE, but since this function
16671 + only new, I feel I can change it, not so with des_cbc_encrypt :-(.
16672 + I need to update the documentation.
16673 +
16674 +Version 3.14 31/05/95
16675 + New release upon the world, as part of my SSL implementation.
16676 + New copyright and usage stuff. Basically free for all to use
16677 + as long as you say it came from me :-)
16678 +
16679 +Version 3.13 31/05/95
16680 + A fix in speed.c, if HZ is not defined, I set it to 100.0
16681 + which is reasonable for most unixes except SunOS 4.x.
16682 + I now have a #ifdef sun but timing for SunOS 4.x looked very
16683 + good :-(. At my last job where I used SunOS 4.x, it was
16684 + defined to be 60.0 (look at the old INSTALL documentation), at
16685 + the last release had it changed to 100.0 since I now work with
16686 + Solaris2 and SVR4 boxes.
16687 + Thanks to Rory Chisholm <rchishol@math.ethz.ch> for pointing this
16688 + one out.
16689 +
16690 +Version 3.12 08/05/95
16691 + As pointed out by The Crypt Keeper <tck@bend.UCSD.EDU>,
16692 + my D_ENCRYPT macro in crypt() had an un-necessary variable.
16693 + It has been removed.
16694 +
16695 +Version 3.11 03/05/95
16696 + Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys
16697 + and one iv. It is a standard and I needed it for my SSL code.
16698 + It makes more sense to use this for triple DES than
16699 + 3cbc_encrypt(). I have also added (or should I say tested :-)
16700 + cfb64_encrypt() which is cfb64 but it will encrypt a partial
16701 + number of bytes - 3 bytes in 3 bytes out. Again this is for
16702 + my SSL library, as a form of encryption to use with SSL
16703 + telnet.
16704 +
16705 +Version 3.10 22/03/95
16706 + Fixed a bug in 3cbc_encrypt() :-(. When making repeated calls
16707 + to cbc3_encrypt, the 2 iv values that were being returned to
16708 + be used in the next call were reversed :-(.
16709 + Many thanks to Bill Wade <wade@Stoner.COM> for pointing out
16710 + this error.
16711 +
16712 +Version 3.09 01/02/95
16713 + Fixed des_random_key to far more random, it was rather feeble
16714 + with regards to picking the initial seed. The problem was
16715 + pointed out by Olaf Kirch <okir@monad.swb.de>.
16716 +
16717 +Version 3.08 14/12/94
16718 + Added Makefile.PL so libdes can be built into perl5.
16719 + Changed des_locl.h so RAND is always defined.
16720 +
16721 +Version 3.07 05/12/94
16722 + Added GNUmake and stuff so the library can be build with
16723 + glibc.
16724 +
16725 +Version 3.06 30/08/94
16726 + Added rpc_enc.c which contains _des_crypt. This is for use in
16727 + secure_rpc v 4.0
16728 + Finally fixed the cfb_enc problems.
16729 + Fixed a few parameter parsing bugs in des (-3 and -b), thanks
16730 + to Rob McMillan <R.McMillan@its.gu.edu.au>
16731 +
16732 +Version 3.05 21/04/94
16733 + for unsigned long l; gcc does not produce ((l>>34) == 0)
16734 + This causes bugs in cfb_enc.
16735 + Thanks to Hadmut Danisch <danisch@ira.uka.de>
16736 +
16737 +Version 3.04 20/04/94
16738 + Added a version number to des.c and libdes.a
16739 +
16740 +Version 3.03 12/01/94
16741 + Fixed a bug in non zero iv in 3cbc_enc.
16742 +
16743 +Version 3.02 29/10/93
16744 + I now work in a place where there are 6+ architectures and 14+
16745 + OS versions :-).
16746 + Fixed TERMIO definition so the most sys V boxes will work :-)
16747 +
16748 +Release upon comp.sources.misc
16749 +Version 3.01 08/10/93
16750 + Added des_3cbc_encrypt()
16751 +
16752 +Version 3.00 07/10/93
16753 + Fixed up documentation.
16754 + quad_cksum definitely compatible with MIT's now.
16755 +
16756 +Version 2.30 24/08/93
16757 + Triple DES now defaults to triple cbc but can do triple ecb
16758 + with the -b flag.
16759 + Fixed some MSDOS uuen/uudecoding problems, thanks to
16760 + Added prototypes.
16761 +
16762 +Version 2.22 29/06/93
16763 + Fixed a bug in des_is_weak_key() which stopped it working :-(
16764 + thanks to engineering@MorningStar.Com.
16765 +
16766 +Version 2.21 03/06/93
16767 + des(1) with no arguments gives quite a bit of help.
16768 + Added -c (generate ckecksum) flag to des(1).
16769 + Added -3 (triple DES) flag to des(1).
16770 + Added cfb and ofb routines to the library.
16771 +
16772 +Version 2.20 11/03/93
16773 + Added -u (uuencode) flag to des(1).
16774 + I have been playing with byte order in quad_cksum to make it
16775 + compatible with MIT's version. All I can say is avid this
16776 + function if possible since MIT's output is endian dependent.
16777 +
16778 +Version 2.12 14/10/92
16779 + Added MSDOS specific macro in ecb_encrypt which gives a %70
16780 + speed up when the code is compiled with turbo C.
16781 +
16782 +Version 2.11 12/10/92
16783 + Speedup in set_key (recoding of PC-1)
16784 + I now do it in 47 simple operations, down from 60.
16785 + Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
16786 + for motivating me to look for a faster system :-)
16787 + The speedup is probably less that 1% but it is still 13
16788 + instructions less :-).
16789 +
16790 +Version 2.10 06/10/92
16791 + The code now works on the 64bit ETA10 and CRAY without modifications or
16792 + #defines. I believe the code should work on any machine that
16793 + defines long, int or short to be 8 bytes long.
16794 + Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu)
16795 + for helping me fix the code to run on 64bit machines (he had
16796 + access to an ETA10).
16797 + Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov>
16798 + for testing the routines on a CRAY.
16799 + read_password.c has been renamed to read_passwd.c
16800 + string_to_key.c has been renamed to string2key.c
16801 +
16802 +Version 2.00 14/09/92
16803 + Made mods so that the library should work on 64bit CPU's.
16804 + Removed all my uchar and ulong defs. To many different
16805 + versions of unix define them in their header files in too many
16806 + different combinations :-)
16807 + IRIX - Sillicon Graphics mods (mostly in read_password.c).
16808 + Thanks to Andrew Daviel (advax@erich.triumf.ca)
16809 +
16810 +Version 1.99 26/08/92
16811 + Fixed a bug or 2 in enc_read.c
16812 + Fixed a bug in enc_write.c
16813 + Fixed a pseudo bug in fcrypt.c (very obscure).
16814 +
16815 +Version 1.98 31/07/92
16816 + Support for the ETA10. This is a strange machine that defines
16817 + longs and ints as 8 bytes and shorts as 4 bytes.
16818 + Since I do evil things with long * that assume that they are 4
16819 + bytes. Look in the Makefile for the option to compile for
16820 + this machine. quad_cksum appears to have problems but I
16821 + will don't have the time to fix it right now, and this is not
16822 + a function that uses DES and so will not effect the main uses
16823 + of the library.
16824 +
16825 +Version 1.97 20/05/92 eay
16826 + Fixed the Imakefile and made some changes to des.h to fix some
16827 + problems when building this package with Kerberos v 4.
16828 +
16829 +Version 1.96 18/05/92 eay
16830 + Fixed a small bug in string_to_key() where problems could
16831 + occur if des_check_key was set to true and the string
16832 + generated a weak key.
16833 +
16834 +Patch2 posted to comp.sources.misc
16835 +Version 1.95 13/05/92 eay
16836 + Added an alternative version of the D_ENCRYPT macro in
16837 + ecb_encrypt and fcrypt. Depending on the compiler, one version or the
16838 + other will be faster. This was inspired by
16839 + Dana How <how@isl.stanford.edu>, and her pointers about doing the
16840 + *(ulong *)((uchar *)ptr+(value&0xfc))
16841 + vs
16842 + ptr[value&0x3f]
16843 + to stop the C compiler doing a <<2 to convert the long array index.
16844 +
16845 +Version 1.94 05/05/92 eay
16846 + Fixed an incompatibility between my string_to_key and the MIT
16847 + version. When the key is longer than 8 chars, I was wrapping
16848 + with a different method. To use the old version, define
16849 + OLD_STR_TO_KEY in the makefile. Thanks to
16850 + viktor@newsu.shearson.com (Viktor Dukhovni).
16851 +
16852 +Version 1.93 28/04/92 eay
16853 + Fixed the VMS mods so that echo is now turned off in
16854 + read_password. Thanks again to brennan@coco.cchs.su.oz.AU.
16855 + MSDOS support added. The routines can be compiled with
16856 + Turbo C (v2.0) and MSC (v5.1). Make sure MSDOS is defined.
16857 +
16858 +Patch1 posted to comp.sources.misc
16859 +Version 1.92 13/04/92 eay
16860 + Changed D_ENCRYPT so that the rotation of R occurs outside of
16861 + the loop. This required rotating all the longs in sp.h (now
16862 + called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
16863 + speed.c has been changed so it will work without SIGALRM. If
16864 + times(3) is not present it will try to use ftime() instead.
16865 +
16866 +Version 1.91 08/04/92 eay
16867 + Added -E/-D options to des(1) so it can use string_to_key.
16868 + Added SVR4 mods suggested by witr@rwwa.COM
16869 + Added VMS mods suggested by brennan@coco.cchs.su.oz.AU. If
16870 + anyone knows how to turn of tty echo in VMS please tell me or
16871 + implement it yourself :-).
16872 + Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS
16873 + does not like IN/OUT being used.
16874 +
16875 +Libdes posted to comp.sources.misc
16876 +Version 1.9 24/03/92 eay
16877 + Now contains a fast small crypt replacement.
16878 + Added des(1) command.
16879 + Added des_rw_mode so people can use cbc encryption with
16880 + enc_read and enc_write.
16881 +
16882 +Version 1.8 15/10/91 eay
16883 + Bug in cbc_cksum.
16884 + Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this
16885 + one out.
16886 +
16887 +Version 1.7 24/09/91 eay
16888 + Fixed set_key :-)
16889 + set_key is 4 times faster and takes less space.
16890 + There are a few minor changes that could be made.
16891 +
16892 +Version 1.6 19/09/1991 eay
16893 + Finally go IP and FP finished.
16894 + Now I need to fix set_key.
16895 + This version is quite a bit faster that 1.51
16896 +
16897 +Version 1.52 15/06/1991 eay
16898 + 20% speedup in ecb_encrypt by changing the E bit selection
16899 + to use 2 32bit words. This also required modification of the
16900 + sp table. There is still a way to speedup the IP and IP-1
16901 + (hints from outer@sq.com) still working on this one :-(.
16902 +
16903 +Version 1.51 07/06/1991 eay
16904 + Faster des_encrypt by loop unrolling
16905 + Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu)
16906 +
16907 +Version 1.50 28/05/1991 eay
16908 + Optimised the code a bit more for the sparc. I have improved the
16909 + speed of the inner des_encrypt by speeding up the initial and
16910 + final permutations.
16911 +
16912 +Version 1.40 23/10/1990 eay
16913 + Fixed des_random_key, it did not produce a random key :-(
16914 +
16915 +Version 1.30 2/10/1990 eay
16916 + Have made des_quad_cksum the same as MIT's, the full package
16917 + should be compatible with MIT's
16918 + Have tested on a DECstation 3100
16919 + Still need to fix des_set_key (make it faster).
16920 + Does des_cbc_encrypts at 70.5k/sec on a 3100.
16921 +
16922 +Version 1.20 18/09/1990 eay
16923 + Fixed byte order dependencies.
16924 + Fixed (I hope) all the word alignment problems.
16925 + Speedup in des_ecb_encrypt.
16926 +
16927 +Version 1.10 11/09/1990 eay
16928 + Added des_enc_read and des_enc_write.
16929 + Still need to fix des_quad_cksum.
16930 + Still need to document des_enc_read and des_enc_write.
16931 +
16932 +Version 1.00 27/08/1990 eay
16933 +
16934 --- /dev/null Tue Mar 11 13:02:56 2003
16935 +++ linux/net/ipsec/des/asm/des-586.pl Mon Feb 9 13:51:03 2004
16936 @@ -0,0 +1,251 @@
16937 +#!/usr/local/bin/perl
16938 +#
16939 +# The inner loop instruction sequence and the IP/FP modifications are from
16940 +# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
16941 +#
16942 +
16943 +push(@INC,"perlasm","../../perlasm");
16944 +require "x86asm.pl";
16945 +require "cbc.pl";
16946 +require "desboth.pl";
16947 +
16948 +# base code is in microsft
16949 +# op dest, source
16950 +# format.
16951 +#
16952 +
16953 +&asm_init($ARGV[0],"des-586.pl");
16954 +
16955 +$L="edi";
16956 +$R="esi";
16957 +
16958 +&external_label("des_SPtrans");
16959 +&des_encrypt("des_encrypt",1);
16960 +&des_encrypt("des_encrypt2",0);
16961 +&des_encrypt3("des_encrypt3",1);
16962 +&des_encrypt3("des_decrypt3",0);
16963 +&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
16964 +&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
16965 +
16966 +&asm_finish();
16967 +
16968 +sub des_encrypt
16969 + {
16970 + local($name,$do_ip)=@_;
16971 +
16972 + &function_begin_B($name,"EXTRN _des_SPtrans:DWORD");
16973 +
16974 + &push("esi");
16975 + &push("edi");
16976 +
16977 + &comment("");
16978 + &comment("Load the 2 words");
16979 + $ks="ebp";
16980 +
16981 + if ($do_ip)
16982 + {
16983 + &mov($R,&wparam(0));
16984 + &xor( "ecx", "ecx" );
16985 +
16986 + &push("ebx");
16987 + &push("ebp");
16988 +
16989 + &mov("eax",&DWP(0,$R,"",0));
16990 + &mov("ebx",&wparam(2)); # get encrypt flag
16991 + &mov($L,&DWP(4,$R,"",0));
16992 + &comment("");
16993 + &comment("IP");
16994 + &IP_new("eax",$L,$R,3);
16995 + }
16996 + else
16997 + {
16998 + &mov("eax",&wparam(0));
16999 + &xor( "ecx", "ecx" );
17000 +
17001 + &push("ebx");
17002 + &push("ebp");
17003 +
17004 + &mov($R,&DWP(0,"eax","",0));
17005 + &mov("ebx",&wparam(2)); # get encrypt flag
17006 + &rotl($R,3);
17007 + &mov($L,&DWP(4,"eax","",0));
17008 + &rotl($L,3);
17009 + }
17010 +
17011 + &mov( $ks, &wparam(1) );
17012 + &cmp("ebx","0");
17013 + &je(&label("start_decrypt"));
17014 +
17015 + for ($i=0; $i<16; $i+=2)
17016 + {
17017 + &comment("");
17018 + &comment("Round $i");
17019 + &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17020 +
17021 + &comment("");
17022 + &comment("Round ".sprintf("%d",$i+1));
17023 + &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17024 + }
17025 + &jmp(&label("end"));
17026 +
17027 + &set_label("start_decrypt");
17028 +
17029 + for ($i=15; $i>0; $i-=2)
17030 + {
17031 + &comment("");
17032 + &comment("Round $i");
17033 + &D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17034 + &comment("");
17035 + &comment("Round ".sprintf("%d",$i-1));
17036 + &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17037 + }
17038 +
17039 + &set_label("end");
17040 +
17041 + if ($do_ip)
17042 + {
17043 + &comment("");
17044 + &comment("FP");
17045 + &mov("edx",&wparam(0));
17046 + &FP_new($L,$R,"eax",3);
17047 +
17048 + &mov(&DWP(0,"edx","",0),"eax");
17049 + &mov(&DWP(4,"edx","",0),$R);
17050 + }
17051 + else
17052 + {
17053 + &comment("");
17054 + &comment("Fixup");
17055 + &rotr($L,3); # r
17056 + &mov("eax",&wparam(0));
17057 + &rotr($R,3); # l
17058 + &mov(&DWP(0,"eax","",0),$L);
17059 + &mov(&DWP(4,"eax","",0),$R);
17060 + }
17061 +
17062 + &pop("ebp");
17063 + &pop("ebx");
17064 + &pop("edi");
17065 + &pop("esi");
17066 + &ret();
17067 +
17068 + &function_end_B($name);
17069 + }
17070 +
17071 +sub D_ENCRYPT
17072 + {
17073 + local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
17074 +
17075 + &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
17076 + &xor( $tmp1, $tmp1);
17077 + &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
17078 + &xor( $u, $R);
17079 + &xor( $t, $R);
17080 + &and( $u, "0xfcfcfcfc" );
17081 + &and( $t, "0xcfcfcfcf" );
17082 + &movb( &LB($tmp1), &LB($u) );
17083 + &movb( &LB($tmp2), &HB($u) );
17084 + &rotr( $t, 4 );
17085 + &mov( $ks, &DWP(" $desSP",$tmp1,"",0));
17086 + &movb( &LB($tmp1), &LB($t) );
17087 + &xor( $L, $ks);
17088 + &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
17089 + &xor( $L, $ks); ######
17090 + &movb( &LB($tmp2), &HB($t) );
17091 + &shr( $u, 16);
17092 + &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
17093 + &xor( $L, $ks); ######
17094 + &movb( &LB($tmp1), &HB($u) );
17095 + &shr( $t, 16);
17096 + &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
17097 + &xor( $L, $ks);
17098 + &mov( $ks, &wparam(1) );
17099 + &movb( &LB($tmp2), &HB($t) );
17100 + &and( $u, "0xff" );
17101 + &and( $t, "0xff" );
17102 + &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
17103 + &xor( $L, $tmp1);
17104 + &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
17105 + &xor( $L, $tmp1);
17106 + &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
17107 + &xor( $L, $tmp1);
17108 + &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
17109 + &xor( $L, $tmp1);
17110 + }
17111 +
17112 +sub n2a
17113 + {
17114 + sprintf("%d",$_[0]);
17115 + }
17116 +
17117 +# now has a side affect of rotating $a by $shift
17118 +sub R_PERM_OP
17119 + {
17120 + local($a,$b,$tt,$shift,$mask,$last)=@_;
17121 +
17122 + &rotl( $a, $shift ) if ($shift != 0);
17123 + &mov( $tt, $a );
17124 + &xor( $a, $b );
17125 + &and( $a, $mask );
17126 + if (!$last eq $b)
17127 + {
17128 + &xor( $b, $a );
17129 + &xor( $tt, $a );
17130 + }
17131 + else
17132 + {
17133 + &xor( $tt, $a );
17134 + &xor( $b, $a );
17135 + }
17136 + &comment("");
17137 + }
17138 +
17139 +sub IP_new
17140 + {
17141 + local($l,$r,$tt,$lr)=@_;
17142 +
17143 + &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
17144 + &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
17145 + &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
17146 + &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
17147 + &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
17148 +
17149 + if ($lr != 3)
17150 + {
17151 + if (($lr-3) < 0)
17152 + { &rotr($tt, 3-$lr); }
17153 + else { &rotl($tt, $lr-3); }
17154 + }
17155 + if ($lr != 2)
17156 + {
17157 + if (($lr-2) < 0)
17158 + { &rotr($r, 2-$lr); }
17159 + else { &rotl($r, $lr-2); }
17160 + }
17161 + }
17162 +
17163 +sub FP_new
17164 + {
17165 + local($l,$r,$tt,$lr)=@_;
17166 +
17167 + if ($lr != 2)
17168 + {
17169 + if (($lr-2) < 0)
17170 + { &rotl($r, 2-$lr); }
17171 + else { &rotr($r, $lr-2); }
17172 + }
17173 + if ($lr != 3)
17174 + {
17175 + if (($lr-3) < 0)
17176 + { &rotl($l, 3-$lr); }
17177 + else { &rotr($l, $lr-3); }
17178 + }
17179 +
17180 + &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
17181 + &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
17182 + &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
17183 + &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
17184 + &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
17185 + &rotr($tt , 4);
17186 + }
17187 +
17188 --- /dev/null Tue Mar 11 13:02:56 2003
17189 +++ linux/net/ipsec/des/asm/des686.pl Mon Feb 9 13:51:03 2004
17190 @@ -0,0 +1,230 @@
17191 +#!/usr/local/bin/perl
17192 +
17193 +$prog="des686.pl";
17194 +
17195 +# base code is in microsft
17196 +# op dest, source
17197 +# format.
17198 +#
17199 +
17200 +# WILL NOT WORK ANYMORE WITH desboth.pl
17201 +require "desboth.pl";
17202 +
17203 +if ( ($ARGV[0] eq "elf"))
17204 + { require "x86unix.pl"; }
17205 +elsif ( ($ARGV[0] eq "a.out"))
17206 + { $aout=1; require "x86unix.pl"; }
17207 +elsif ( ($ARGV[0] eq "sol"))
17208 + { $sol=1; require "x86unix.pl"; }
17209 +elsif ( ($ARGV[0] eq "cpp"))
17210 + { $cpp=1; require "x86unix.pl"; }
17211 +elsif ( ($ARGV[0] eq "win32"))
17212 + { require "x86ms.pl"; }
17213 +else
17214 + {
17215 + print STDERR <<"EOF";
17216 +Pick one target type from
17217 + elf - linux, FreeBSD etc
17218 + a.out - old linux
17219 + sol - x86 solaris
17220 + cpp - format so x86unix.cpp can be used
17221 + win32 - Windows 95/Windows NT
17222 +EOF
17223 + exit(1);
17224 + }
17225 +
17226 +&comment("Don't even think of reading this code");
17227 +&comment("It was automatically generated by $prog");
17228 +&comment("Which is a perl program used to generate the x86 assember for");
17229 +&comment("any of elf, a.out, Win32, or Solaris");
17230 +&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
17231 +&comment("eric <eay\@cryptsoft.com>");
17232 +&comment("");
17233 +
17234 +&file("dx86xxxx");
17235 +
17236 +$L="edi";
17237 +$R="esi";
17238 +
17239 +&des_encrypt("des_encrypt",1);
17240 +&des_encrypt("des_encrypt2",0);
17241 +
17242 +&des_encrypt3("des_encrypt3",1);
17243 +&des_encrypt3("des_decrypt3",0);
17244 +
17245 +&file_end();
17246 +
17247 +sub des_encrypt
17248 + {
17249 + local($name,$do_ip)=@_;
17250 +
17251 + &function_begin($name,"EXTRN _des_SPtrans:DWORD");
17252 +
17253 + &comment("");
17254 + &comment("Load the 2 words");
17255 + &mov("eax",&wparam(0));
17256 + &mov($L,&DWP(0,"eax","",0));
17257 + &mov($R,&DWP(4,"eax","",0));
17258 +
17259 + $ksp=&wparam(1);
17260 +
17261 + if ($do_ip)
17262 + {
17263 + &comment("");
17264 + &comment("IP");
17265 + &IP_new($L,$R,"eax");
17266 + }
17267 +
17268 + &comment("");
17269 + &comment("fixup rotate");
17270 + &rotl($R,3);
17271 + &rotl($L,3);
17272 + &exch($L,$R);
17273 +
17274 + &comment("");
17275 + &comment("load counter, key_schedule and enc flag");
17276 + &mov("eax",&wparam(2)); # get encrypt flag
17277 + &mov("ebp",&wparam(1)); # get ks
17278 + &cmp("eax","0");
17279 + &je(&label("start_decrypt"));
17280 +
17281 + # encrypting part
17282 +
17283 + for ($i=0; $i<16; $i+=2)
17284 + {
17285 + &comment("");
17286 + &comment("Round $i");
17287 + &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17288 +
17289 + &comment("");
17290 + &comment("Round ".sprintf("%d",$i+1));
17291 + &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17292 + }
17293 + &jmp(&label("end"));
17294 +
17295 + &set_label("start_decrypt");
17296 +
17297 + for ($i=15; $i>0; $i-=2)
17298 + {
17299 + &comment("");
17300 + &comment("Round $i");
17301 + &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17302 + &comment("");
17303 + &comment("Round ".sprintf("%d",$i-1));
17304 + &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17305 + }
17306 +
17307 + &set_label("end");
17308 +
17309 + &comment("");
17310 + &comment("Fixup");
17311 + &rotr($L,3); # r
17312 + &rotr($R,3); # l
17313 +
17314 + if ($do_ip)
17315 + {
17316 + &comment("");
17317 + &comment("FP");
17318 + &FP_new($R,$L,"eax");
17319 + }
17320 +
17321 + &mov("eax",&wparam(0));
17322 + &mov(&DWP(0,"eax","",0),$L);
17323 + &mov(&DWP(4,"eax","",0),$R);
17324 +
17325 + &function_end($name);
17326 + }
17327 +
17328 +
17329 +# The logic is to load R into 2 registers and operate on both at the same time.
17330 +# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'
17331 +# while also masking the other copy and doing a lookup. We then also accumulate the
17332 +# L value in 2 registers then combine them at the end.
17333 +sub D_ENCRYPT
17334 + {
17335 + local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;
17336 +
17337 + &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
17338 + &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
17339 + &xor( $u, $R );
17340 + &xor( $t, $R );
17341 + &rotr( $t, 4 );
17342 +
17343 + # the numbers at the end of the line are origional instruction order
17344 + &mov( $tmp2, $u ); # 1 2
17345 + &mov( $tmp1, $t ); # 1 1
17346 + &and( $tmp2, "0xfc" ); # 1 4
17347 + &and( $tmp1, "0xfc" ); # 1 3
17348 + &shr( $t, 8 ); # 1 5
17349 + &xor( $L, &DWP("0x100+$desSP",$tmp1,"",0)); # 1 7
17350 + &shr( $u, 8 ); # 1 6
17351 + &mov( $tmp1, &DWP(" $desSP",$tmp2,"",0)); # 1 8
17352 +
17353 + &mov( $tmp2, $u ); # 2 2
17354 + &xor( $L, $tmp1 ); # 1 9
17355 + &and( $tmp2, "0xfc" ); # 2 4
17356 + &mov( $tmp1, $t ); # 2 1
17357 + &and( $tmp1, "0xfc" ); # 2 3
17358 + &shr( $t, 8 ); # 2 5
17359 + &xor( $L, &DWP("0x300+$desSP",$tmp1,"",0)); # 2 7
17360 + &shr( $u, 8 ); # 2 6
17361 + &mov( $tmp1, &DWP("0x200+$desSP",$tmp2,"",0)); # 2 8
17362 + &mov( $tmp2, $u ); # 3 2
17363 +
17364 + &xor( $L, $tmp1 ); # 2 9
17365 + &and( $tmp2, "0xfc" ); # 3 4
17366 +
17367 + &mov( $tmp1, $t ); # 3 1
17368 + &shr( $u, 8 ); # 3 6
17369 + &and( $tmp1, "0xfc" ); # 3 3
17370 + &shr( $t, 8 ); # 3 5
17371 + &xor( $L, &DWP("0x500+$desSP",$tmp1,"",0)); # 3 7
17372 + &mov( $tmp1, &DWP("0x400+$desSP",$tmp2,"",0)); # 3 8
17373 +
17374 + &and( $t, "0xfc" ); # 4 1
17375 + &xor( $L, $tmp1 ); # 3 9
17376 +
17377 + &and( $u, "0xfc" ); # 4 2
17378 + &xor( $L, &DWP("0x700+$desSP",$t,"",0)); # 4 3
17379 + &xor( $L, &DWP("0x600+$desSP",$u,"",0)); # 4 4
17380 + }
17381 +
17382 +sub PERM_OP
17383 + {
17384 + local($a,$b,$tt,$shift,$mask)=@_;
17385 +
17386 + &mov( $tt, $a );
17387 + &shr( $tt, $shift );
17388 + &xor( $tt, $b );
17389 + &and( $tt, $mask );
17390 + &xor( $b, $tt );
17391 + &shl( $tt, $shift );
17392 + &xor( $a, $tt );
17393 + }
17394 +
17395 +sub IP_new
17396 + {
17397 + local($l,$r,$tt)=@_;
17398 +
17399 + &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
17400 + &PERM_OP($l,$r,$tt,16,"0x0000ffff");
17401 + &PERM_OP($r,$l,$tt, 2,"0x33333333");
17402 + &PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
17403 + &PERM_OP($r,$l,$tt, 1,"0x55555555");
17404 + }
17405 +
17406 +sub FP_new
17407 + {
17408 + local($l,$r,$tt)=@_;
17409 +
17410 + &PERM_OP($l,$r,$tt, 1,"0x55555555");
17411 + &PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
17412 + &PERM_OP($l,$r,$tt, 2,"0x33333333");
17413 + &PERM_OP($r,$l,$tt,16,"0x0000ffff");
17414 + &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
17415 + }
17416 +
17417 +sub n2a
17418 + {
17419 + sprintf("%d",$_[0]);
17420 + }
17421 --- /dev/null Tue Mar 11 13:02:56 2003
17422 +++ linux/net/ipsec/des/asm/desboth.pl Mon Feb 9 13:51:03 2004
17423 @@ -0,0 +1,79 @@
17424 +#!/usr/local/bin/perl
17425 +
17426 +$L="edi";
17427 +$R="esi";
17428 +
17429 +sub des_encrypt3
17430 + {
17431 + local($name,$enc)=@_;
17432 +
17433 + &function_begin_B($name,"");
17434 + &push("ebx");
17435 + &mov("ebx",&wparam(0));
17436 +
17437 + &push("ebp");
17438 + &push("esi");
17439 +
17440 + &push("edi");
17441 +
17442 + &comment("");
17443 + &comment("Load the data words");
17444 + &mov($L,&DWP(0,"ebx","",0));
17445 + &mov($R,&DWP(4,"ebx","",0));
17446 + &stack_push(3);
17447 +
17448 + &comment("");
17449 + &comment("IP");
17450 + &IP_new($L,$R,"edx",0);
17451 +
17452 + # put them back
17453 +
17454 + if ($enc)
17455 + {
17456 + &mov(&DWP(4,"ebx","",0),$R);
17457 + &mov("eax",&wparam(1));
17458 + &mov(&DWP(0,"ebx","",0),"edx");
17459 + &mov("edi",&wparam(2));
17460 + &mov("esi",&wparam(3));
17461 + }
17462 + else
17463 + {
17464 + &mov(&DWP(4,"ebx","",0),$R);
17465 + &mov("esi",&wparam(1));
17466 + &mov(&DWP(0,"ebx","",0),"edx");
17467 + &mov("edi",&wparam(2));
17468 + &mov("eax",&wparam(3));
17469 + }
17470 + &mov(&swtmp(2), (($enc)?"1":"0"));
17471 + &mov(&swtmp(1), "eax");
17472 + &mov(&swtmp(0), "ebx");
17473 + &call("des_encrypt2");
17474 + &mov(&swtmp(2), (($enc)?"0":"1"));
17475 + &mov(&swtmp(1), "edi");
17476 + &mov(&swtmp(0), "ebx");
17477 + &call("des_encrypt2");
17478 + &mov(&swtmp(2), (($enc)?"1":"0"));
17479 + &mov(&swtmp(1), "esi");
17480 + &mov(&swtmp(0), "ebx");
17481 + &call("des_encrypt2");
17482 +
17483 + &stack_pop(3);
17484 + &mov($L,&DWP(0,"ebx","",0));
17485 + &mov($R,&DWP(4,"ebx","",0));
17486 +
17487 + &comment("");
17488 + &comment("FP");
17489 + &FP_new($L,$R,"eax",0);
17490 +
17491 + &mov(&DWP(0,"ebx","",0),"eax");
17492 + &mov(&DWP(4,"ebx","",0),$R);
17493 +
17494 + &pop("edi");
17495 + &pop("esi");
17496 + &pop("ebp");
17497 + &pop("ebx");
17498 + &ret();
17499 + &function_end_B($name);
17500 + }
17501 +
17502 +
17503 --- /dev/null Tue Mar 11 13:02:56 2003
17504 +++ linux/net/ipsec/des/asm/readme Mon Feb 9 13:51:03 2004
17505 @@ -0,0 +1,131 @@
17506 +First up, let me say I don't like writing in assembler. It is not portable,
17507 +dependant on the particular CPU architecture release and is generally a pig
17508 +to debug and get right. Having said that, the x86 architecture is probably
17509 +the most important for speed due to number of boxes and since
17510 +it appears to be the worst architecture to to get
17511 +good C compilers for. So due to this, I have lowered myself to do
17512 +assembler for the inner DES routines in libdes :-).
17513 +
17514 +The file to implement in assembler is des_enc.c. Replace the following
17515 +4 functions
17516 +des_encrypt(DES_LONG data[2],des_key_schedule ks, int encrypt);
17517 +des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt);
17518 +des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
17519 +des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
17520 +
17521 +They encrypt/decrypt the 64 bits held in 'data' using
17522 +the 'ks' key schedules. The only difference between the 4 functions is that
17523 +des_encrypt2() does not perform IP() or FP() on the data (this is an
17524 +optimization for when doing triple DES and des_encrypt3() and des_decrypt3()
17525 +perform triple des. The triple DES routines are in here because it does
17526 +make a big difference to have them located near the des_encrypt2 function
17527 +at link time..
17528 +
17529 +Now as we all know, there are lots of different operating systems running on
17530 +x86 boxes, and unfortunately they normally try to make sure their assembler
17531 +formating is not the same as the other peoples.
17532 +The 4 main formats I know of are
17533 +Microsoft Windows 95/Windows NT
17534 +Elf Includes Linux and FreeBSD(?).
17535 +a.out The older Linux.
17536 +Solaris Same as Elf but different comments :-(.
17537 +
17538 +Now I was not overly keen to write 4 different copies of the same code,
17539 +so I wrote a few perl routines to output the correct assembler, given
17540 +a target assembler type. This code is ugly and is just a hack.
17541 +The libraries are x86unix.pl and x86ms.pl.
17542 +des586.pl, des686.pl and des-som[23].pl are the programs to actually
17543 +generate the assembler.
17544 +
17545 +So to generate elf assembler
17546 +perl des-som3.pl elf >dx86-elf.s
17547 +For Windows 95/NT
17548 +perl des-som2.pl win32 >win32.asm
17549 +
17550 +[ update 4 Jan 1996 ]
17551 +I have added another way to do things.
17552 +perl des-som3.pl cpp >dx86-cpp.s
17553 +generates a file that will be included by dx86unix.cpp when it is compiled.
17554 +To build for elf, a.out, solaris, bsdi etc,
17555 +cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o
17556 +cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o
17557 +cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o
17558 +cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o
17559 +This was done to cut down the number of files in the distribution.
17560 +
17561 +Now the ugly part. I acquired my copy of Intels
17562 +"Optimization's For Intel's 32-Bit Processors" and found a few interesting
17563 +things. First, the aim of the exersize is to 'extract' one byte at a time
17564 +from a word and do an array lookup. This involves getting the byte from
17565 +the 4 locations in the word and moving it to a new word and doing the lookup.
17566 +The most obvious way to do this is
17567 +xor eax, eax # clear word
17568 +movb al, cl # get low byte
17569 +xor edi DWORD PTR 0x100+des_SP[eax] # xor in word
17570 +movb al, ch # get next byte
17571 +xor edi DWORD PTR 0x300+des_SP[eax] # xor in word
17572 +shr ecx 16
17573 +which seems ok. For the pentium, this system appears to be the best.
17574 +One has to do instruction interleaving to keep both functional units
17575 +operating, but it is basically very efficient.
17576 +
17577 +Now the crunch. When a full register is used after a partial write, eg.
17578 +mov al, cl
17579 +xor edi, DWORD PTR 0x100+des_SP[eax]
17580 +386 - 1 cycle stall
17581 +486 - 1 cycle stall
17582 +586 - 0 cycle stall
17583 +686 - at least 7 cycle stall (page 22 of the above mentioned document).
17584 +
17585 +So the technique that produces the best results on a pentium, according to
17586 +the documentation, will produce hideous results on a pentium pro.
17587 +
17588 +To get around this, des686.pl will generate code that is not as fast on
17589 +a pentium, should be very good on a pentium pro.
17590 +mov eax, ecx # copy word
17591 +shr ecx, 8 # line up next byte
17592 +and eax, 0fch # mask byte
17593 +xor edi DWORD PTR 0x100+des_SP[eax] # xor in array lookup
17594 +mov eax, ecx # get word
17595 +shr ecx 8 # line up next byte
17596 +and eax, 0fch # mask byte
17597 +xor edi DWORD PTR 0x300+des_SP[eax] # xor in array lookup
17598 +
17599 +Due to the execution units in the pentium, this actually works quite well.
17600 +For a pentium pro it should be very good. This is the type of output
17601 +Visual C++ generates.
17602 +
17603 +There is a third option. instead of using
17604 +mov al, ch
17605 +which is bad on the pentium pro, one may be able to use
17606 +movzx eax, ch
17607 +which may not incur the partial write penalty. On the pentium,
17608 +this instruction takes 4 cycles so is not worth using but on the
17609 +pentium pro it appears it may be worth while. I need access to one to
17610 +experiment :-).
17611 +
17612 +eric (20 Oct 1996)
17613 +
17614 +22 Nov 1996 - I have asked people to run the 2 different version on pentium
17615 +pros and it appears that the intel documentation is wrong. The
17616 +mov al,bh is still faster on a pentium pro, so just use the des586.pl
17617 +install des686.pl
17618 +
17619 +3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these
17620 +functions into des_enc.c because it does make a massive performance
17621 +difference on some boxes to have the functions code located close to
17622 +the des_encrypt2() function.
17623 +
17624 +9 Jan 1997 - des-som2.pl is now the correct perl script to use for
17625 +pentiums. It contains an inner loop from
17626 +Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at
17627 +273,000 per second. He had a previous version at 250,000 and the best
17628 +I was able to get was 203,000. The content has not changed, this is all
17629 +due to instruction sequencing (and actual instructions choice) which is able
17630 +to keep both functional units of the pentium going.
17631 +We may have lost the ugly register usage restrictions when x86 went 32 bit
17632 +but for the pentium it has been replaced by evil instruction ordering tricks.
17633 +
17634 +13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf.
17635 +raw DES at 281,000 per second on a pentium 100.
17636 +
17637 --- /dev/null Tue Mar 11 13:02:56 2003
17638 +++ linux/net/ipsec/des/cbc_enc.c Mon Feb 9 13:51:03 2004
17639 @@ -0,0 +1,142 @@
17640 +/* crypto/des/cbc_enc.c */
17641 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
17642 + * All rights reserved.
17643 + *
17644 + * This package is an SSL implementation written
17645 + * by Eric Young (eay@cryptsoft.com).
17646 + * The implementation was written so as to conform with Netscapes SSL.
17647 + *
17648 + * This library is free for commercial and non-commercial use as long as
17649 + * the following conditions are aheared to. The following conditions
17650 + * apply to all code found in this distribution, be it the RC4, RSA,
17651 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
17652 + * included with this distribution is covered by the same copyright terms
17653 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
17654 + *
17655 + * Copyright remains Eric Young's, and as such any Copyright notices in
17656 + * the code are not to be removed.
17657 + * If this package is used in a product, Eric Young should be given attribution
17658 + * as the author of the parts of the library used.
17659 + * This can be in the form of a textual message at program startup or
17660 + * in documentation (online or textual) provided with the package.
17661 + *
17662 + * Redistribution and use in source and binary forms, with or without
17663 + * modification, are permitted provided that the following conditions
17664 + * are met:
17665 + * 1. Redistributions of source code must retain the copyright
17666 + * notice, this list of conditions and the following disclaimer.
17667 + * 2. Redistributions in binary form must reproduce the above copyright
17668 + * notice, this list of conditions and the following disclaimer in the
17669 + * documentation and/or other materials provided with the distribution.
17670 + * 3. All advertising materials mentioning features or use of this software
17671 + * must display the following acknowledgement:
17672 + * "This product includes cryptographic software written by
17673 + * Eric Young (eay@cryptsoft.com)"
17674 + * The word 'cryptographic' can be left out if the rouines from the library
17675 + * being used are not cryptographic related :-).
17676 + * 4. If you include any Windows specific code (or a derivative thereof) from
17677 + * the apps directory (application code) you must include an acknowledgement:
17678 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
17679 + *
17680 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
17681 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17682 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17683 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17684 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17685 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
17686 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
17687 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
17688 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
17689 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
17690 + * SUCH DAMAGE.
17691 + *
17692 + * The licence and distribution terms for any publically available version or
17693 + * derivative of this code cannot be changed. i.e. this code cannot simply be
17694 + * copied and put under another distribution licence
17695 + * [including the GNU Public Licence.]
17696 + */
17697 +
17698 +#include "des/des_locl.h"
17699 +
17700 +void des_cbc_encrypt(input, output, length, schedule, ivec, enc)
17701 +des_cblock (*input);
17702 +des_cblock (*output);
17703 +long length;
17704 +des_key_schedule schedule;
17705 +des_cblock (*ivec);
17706 +int enc;
17707 + {
17708 + register DES_LONG tin0,tin1;
17709 + register DES_LONG tout0,tout1,xor0,xor1;
17710 + register unsigned char *in,*out;
17711 + register long l=length;
17712 + DES_LONG tin[2];
17713 + unsigned char *iv;
17714 +
17715 +#ifdef OCF_ASSIST
17716 + if (ocf_des_assist() & OCF_PROVIDES_DES_3DES) {
17717 + ocf_des_cbc_encrypt(input, output, length, schedule, ivec, enc);
17718 + return;
17719 + }
17720 +#endif
17721 +
17722 + in=(unsigned char *)input;
17723 + out=(unsigned char *)output;
17724 + iv=(unsigned char *)ivec;
17725 +
17726 + if (enc)
17727 + {
17728 + c2l(iv,tout0);
17729 + c2l(iv,tout1);
17730 + for (l-=8; l>=0; l-=8)
17731 + {
17732 + c2l(in,tin0);
17733 + c2l(in,tin1);
17734 + tin0^=tout0; tin[0]=tin0;
17735 + tin1^=tout1; tin[1]=tin1;
17736 + des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
17737 + tout0=tin[0]; l2c(tout0,out);
17738 + tout1=tin[1]; l2c(tout1,out);
17739 + }
17740 + if (l != -8)
17741 + {
17742 + c2ln(in,tin0,tin1,l+8);
17743 + tin0^=tout0; tin[0]=tin0;
17744 + tin1^=tout1; tin[1]=tin1;
17745 + des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
17746 + tout0=tin[0]; l2c(tout0,out);
17747 + tout1=tin[1]; l2c(tout1,out);
17748 + }
17749 + }
17750 + else
17751 + {
17752 + c2l(iv,xor0);
17753 + c2l(iv,xor1);
17754 + for (l-=8; l>=0; l-=8)
17755 + {
17756 + c2l(in,tin0); tin[0]=tin0;
17757 + c2l(in,tin1); tin[1]=tin1;
17758 + des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
17759 + tout0=tin[0]^xor0;
17760 + tout1=tin[1]^xor1;
17761 + l2c(tout0,out);
17762 + l2c(tout1,out);
17763 + xor0=tin0;
17764 + xor1=tin1;
17765 + }
17766 + if (l != -8)
17767 + {
17768 + c2l(in,tin0); tin[0]=tin0;
17769 + c2l(in,tin1); tin[1]=tin1;
17770 + des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
17771 + tout0=tin[0]^xor0;
17772 + tout1=tin[1]^xor1;
17773 + l2cn(tout0,tout1,out,l+8);
17774 + /* xor0=tin0;
17775 + xor1=tin1; */
17776 + }
17777 + }
17778 + tin0=tin1=tout0=tout1=xor0=xor1=0;
17779 + tin[0]=tin[1]=0;
17780 + }
17781 +
17782 --- /dev/null Tue Mar 11 13:02:56 2003
17783 +++ linux/net/ipsec/des/des.doc Mon Feb 9 13:51:03 2004
17784 @@ -0,0 +1,505 @@
17785 +The DES library.
17786 +
17787 +Please note that this library was originally written to operate with
17788 +eBones, a version of Kerberos that had had encryption removed when it left
17789 +the USA and then put back in. As such there are some routines that I will
17790 +advise not using but they are still in the library for historical reasons.
17791 +For all calls that have an 'input' and 'output' variables, they can be the
17792 +same.
17793 +
17794 +This library requires the inclusion of 'des.h'.
17795 +
17796 +All of the encryption functions take what is called a des_key_schedule as an
17797 +argument. A des_key_schedule is an expanded form of the des key.
17798 +A des_key is 8 bytes of odd parity, the type used to hold the key is a
17799 +des_cblock. A des_cblock is an array of 8 bytes, often in this library
17800 +description I will refer to input bytes when the function specifies
17801 +des_cblock's as input or output, this just means that the variable should
17802 +be a multiple of 8 bytes.
17803 +
17804 +The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to
17805 +specify decryption. The functions and global variable are as follows:
17806 +
17807 +int des_check_key;
17808 + DES keys are supposed to be odd parity. If this variable is set to
17809 + a non-zero value, des_set_key() will check that the key has odd
17810 + parity and is not one of the known weak DES keys. By default this
17811 + variable is turned off;
17812 +
17813 +void des_set_odd_parity(
17814 +des_cblock *key );
17815 + This function takes a DES key (8 bytes) and sets the parity to odd.
17816 +
17817 +int des_is_weak_key(
17818 +des_cblock *key );
17819 + This function returns a non-zero value if the DES key passed is a
17820 + weak, DES key. If it is a weak key, don't use it, try a different
17821 + one. If you are using 'random' keys, the chances of hitting a weak
17822 + key are 1/2^52 so it is probably not worth checking for them.
17823 +
17824 +int des_set_key(
17825 +des_cblock *key,
17826 +des_key_schedule schedule);
17827 + Des_set_key converts an 8 byte DES key into a des_key_schedule.
17828 + A des_key_schedule is an expanded form of the key which is used to
17829 + perform actual encryption. It can be regenerated from the DES key
17830 + so it only needs to be kept when encryption or decryption is about
17831 + to occur. Don't save or pass around des_key_schedule's since they
17832 + are CPU architecture dependent, DES keys are not. If des_check_key
17833 + is non zero, zero is returned if the key has the wrong parity or
17834 + the key is a weak key, else 1 is returned.
17835 +
17836 +int des_key_sched(
17837 +des_cblock *key,
17838 +des_key_schedule schedule);
17839 + An alternative name for des_set_key().
17840 +
17841 +int des_rw_mode; /* defaults to DES_PCBC_MODE */
17842 + This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default).
17843 + This specifies the function to use in the enc_read() and enc_write()
17844 + functions.
17845 +
17846 +void des_encrypt(
17847 +unsigned long *data,
17848 +des_key_schedule ks,
17849 +int enc);
17850 + This is the DES encryption function that gets called by just about
17851 + every other DES routine in the library. You should not use this
17852 + function except to implement 'modes' of DES. I say this because the
17853 + functions that call this routine do the conversion from 'char *' to
17854 + long, and this needs to be done to make sure 'non-aligned' memory
17855 + access do not occur. The characters are loaded 'little endian',
17856 + have a look at my source code for more details on how I use this
17857 + function.
17858 + Data is a pointer to 2 unsigned long's and ks is the
17859 + des_key_schedule to use. enc, is non zero specifies encryption,
17860 + zero if decryption.
17861 +
17862 +void des_encrypt2(
17863 +unsigned long *data,
17864 +des_key_schedule ks,
17865 +int enc);
17866 + This functions is the same as des_encrypt() except that the DES
17867 + initial permutation (IP) and final permutation (FP) have been left
17868 + out. As for des_encrypt(), you should not use this function.
17869 + It is used by the routines in my library that implement triple DES.
17870 + IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same
17871 + as des_encrypt() des_encrypt() des_encrypt() except faster :-).
17872 +
17873 +void des_ecb_encrypt(
17874 +des_cblock *input,
17875 +des_cblock *output,
17876 +des_key_schedule ks,
17877 +int enc);
17878 + This is the basic Electronic Code Book form of DES, the most basic
17879 + form. Input is encrypted into output using the key represented by
17880 + ks. If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise
17881 + decryption occurs. Input is 8 bytes long and output is 8 bytes.
17882 + (the des_cblock structure is 8 chars).
17883 +
17884 +void des_ecb3_encrypt(
17885 +des_cblock *input,
17886 +des_cblock *output,
17887 +des_key_schedule ks1,
17888 +des_key_schedule ks2,
17889 +des_key_schedule ks3,
17890 +int enc);
17891 + This is the 3 key EDE mode of ECB DES. What this means is that
17892 + the 8 bytes of input is encrypted with ks1, decrypted with ks2 and
17893 + then encrypted again with ks3, before being put into output;
17894 + C=E(ks3,D(ks2,E(ks1,M))). There is a macro, des_ecb2_encrypt()
17895 + that only takes 2 des_key_schedules that implements,
17896 + C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1.
17897 +
17898 +void des_cbc_encrypt(
17899 +des_cblock *input,
17900 +des_cblock *output,
17901 +long length,
17902 +des_key_schedule ks,
17903 +des_cblock *ivec,
17904 +int enc);
17905 + This routine implements DES in Cipher Block Chaining mode.
17906 + Input, which should be a multiple of 8 bytes is encrypted
17907 + (or decrypted) to output which will also be a multiple of 8 bytes.
17908 + The number of bytes is in length (and from what I've said above,
17909 + should be a multiple of 8). If length is not a multiple of 8, I'm
17910 + not being held responsible :-). ivec is the initialisation vector.
17911 + This function does not modify this variable. To correctly implement
17912 + cbc mode, you need to do one of 2 things; copy the last 8 bytes of
17913 + cipher text for use as the next ivec in your application,
17914 + or use des_ncbc_encrypt().
17915 + Only this routine has this problem with updating the ivec, all
17916 + other routines that are implementing cbc mode update ivec.
17917 +
17918 +void des_ncbc_encrypt(
17919 +des_cblock *input,
17920 +des_cblock *output,
17921 +long length,
17922 +des_key_schedule sk,
17923 +des_cblock *ivec,
17924 +int enc);
17925 + For historical reasons, des_cbc_encrypt() did not update the
17926 + ivec with the value requires so that subsequent calls to
17927 + des_cbc_encrypt() would 'chain'. This was needed so that the same
17928 + 'length' values would not need to be used when decrypting.
17929 + des_ncbc_encrypt() does the right thing. It is the same as
17930 + des_cbc_encrypt accept that ivec is updates with the correct value
17931 + to pass in subsequent calls to des_ncbc_encrypt(). I advise using
17932 + des_ncbc_encrypt() instead of des_cbc_encrypt();
17933 +
17934 +void des_xcbc_encrypt(
17935 +des_cblock *input,
17936 +des_cblock *output,
17937 +long length,
17938 +des_key_schedule sk,
17939 +des_cblock *ivec,
17940 +des_cblock *inw,
17941 +des_cblock *outw,
17942 +int enc);
17943 + This is RSA's DESX mode of DES. It uses inw and outw to
17944 + 'whiten' the encryption. inw and outw are secret (unlike the iv)
17945 + and are as such, part of the key. So the key is sort of 24 bytes.
17946 + This is much better than cbc des.
17947 +
17948 +void des_3cbc_encrypt(
17949 +des_cblock *input,
17950 +des_cblock *output,
17951 +long length,
17952 +des_key_schedule sk1,
17953 +des_key_schedule sk2,
17954 +des_cblock *ivec1,
17955 +des_cblock *ivec2,
17956 +int enc);
17957 + This function is flawed, do not use it. I have left it in the
17958 + library because it is used in my des(1) program and will function
17959 + correctly when used by des(1). If I removed the function, people
17960 + could end up unable to decrypt files.
17961 + This routine implements outer triple cbc encryption using 2 ks and
17962 + 2 ivec's. Use des_ede2_cbc_encrypt() instead.
17963 +
17964 +void des_ede3_cbc_encrypt(
17965 +des_cblock *input,
17966 +des_cblock *output,
17967 +long length,
17968 +des_key_schedule ks1,
17969 +des_key_schedule ks2,
17970 +des_key_schedule ks3,
17971 +des_cblock *ivec,
17972 +int enc);
17973 + This function implements inner triple CBC DES encryption with 3
17974 + keys. What this means is that each 'DES' operation
17975 + inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))).
17976 + Again, this is cbc mode so an ivec is requires.
17977 + This mode is used by SSL.
17978 + There is also a des_ede2_cbc_encrypt() that only uses 2
17979 + des_key_schedule's, the first being reused for the final
17980 + encryption. C=E(ks1,D(ks2,E(ks1,M))). This form of triple DES
17981 + is used by the RSAref library.
17982 +
17983 +void des_pcbc_encrypt(
17984 +des_cblock *input,
17985 +des_cblock *output,
17986 +long length,
17987 +des_key_schedule ks,
17988 +des_cblock *ivec,
17989 +int enc);
17990 + This is Propagating Cipher Block Chaining mode of DES. It is used
17991 + by Kerberos v4. It's parameters are the same as des_ncbc_encrypt().
17992 +
17993 +void des_cfb_encrypt(
17994 +unsigned char *in,
17995 +unsigned char *out,
17996 +int numbits,
17997 +long length,
17998 +des_key_schedule ks,
17999 +des_cblock *ivec,
18000 +int enc);
18001 + Cipher Feedback Back mode of DES. This implementation 'feeds back'
18002 + in numbit blocks. The input (and output) is in multiples of numbits
18003 + bits. numbits should to be a multiple of 8 bits. Length is the
18004 + number of bytes input. If numbits is not a multiple of 8 bits,
18005 + the extra bits in the bytes will be considered padding. So if
18006 + numbits is 12, for each 2 input bytes, the 4 high bits of the
18007 + second byte will be ignored. So to encode 72 bits when using
18008 + a numbits of 12 take 12 bytes. To encode 72 bits when using
18009 + numbits of 9 will take 16 bytes. To encode 80 bits when using
18010 + numbits of 16 will take 10 bytes. etc, etc. This padding will
18011 + apply to both input and output.
18012 +
18013 +
18014 +void des_cfb64_encrypt(
18015 +unsigned char *in,
18016 +unsigned char *out,
18017 +long length,
18018 +des_key_schedule ks,
18019 +des_cblock *ivec,
18020 +int *num,
18021 +int enc);
18022 + This is one of the more useful functions in this DES library, it
18023 + implements CFB mode of DES with 64bit feedback. Why is this
18024 + useful you ask? Because this routine will allow you to encrypt an
18025 + arbitrary number of bytes, no 8 byte padding. Each call to this
18026 + routine will encrypt the input bytes to output and then update ivec
18027 + and num. num contains 'how far' we are though ivec. If this does
18028 + not make much sense, read more about cfb mode of DES :-).
18029 +
18030 +void des_ede3_cfb64_encrypt(
18031 +unsigned char *in,
18032 +unsigned char *out,
18033 +long length,
18034 +des_key_schedule ks1,
18035 +des_key_schedule ks2,
18036 +des_key_schedule ks3,
18037 +des_cblock *ivec,
18038 +int *num,
18039 +int enc);
18040 + Same as des_cfb64_encrypt() accept that the DES operation is
18041 + triple DES. As usual, there is a macro for
18042 + des_ede2_cfb64_encrypt() which reuses ks1.
18043 +
18044 +void des_ofb_encrypt(
18045 +unsigned char *in,
18046 +unsigned char *out,
18047 +int numbits,
18048 +long length,
18049 +des_key_schedule ks,
18050 +des_cblock *ivec);
18051 + This is a implementation of Output Feed Back mode of DES. It is
18052 + the same as des_cfb_encrypt() in that numbits is the size of the
18053 + units dealt with during input and output (in bits).
18054 +
18055 +void des_ofb64_encrypt(
18056 +unsigned char *in,
18057 +unsigned char *out,
18058 +long length,
18059 +des_key_schedule ks,
18060 +des_cblock *ivec,
18061 +int *num);
18062 + The same as des_cfb64_encrypt() except that it is Output Feed Back
18063 + mode.
18064 +
18065 +void des_ede3_ofb64_encrypt(
18066 +unsigned char *in,
18067 +unsigned char *out,
18068 +long length,
18069 +des_key_schedule ks1,
18070 +des_key_schedule ks2,
18071 +des_key_schedule ks3,
18072 +des_cblock *ivec,
18073 +int *num);
18074 + Same as des_ofb64_encrypt() accept that the DES operation is
18075 + triple DES. As usual, there is a macro for
18076 + des_ede2_ofb64_encrypt() which reuses ks1.
18077 +
18078 +int des_read_pw_string(
18079 +char *buf,
18080 +int length,
18081 +char *prompt,
18082 +int verify);
18083 + This routine is used to get a password from the terminal with echo
18084 + turned off. Buf is where the string will end up and length is the
18085 + size of buf. Prompt is a string presented to the 'user' and if
18086 + verify is set, the key is asked for twice and unless the 2 copies
18087 + match, an error is returned. A return code of -1 indicates a
18088 + system error, 1 failure due to use interaction, and 0 is success.
18089 +
18090 +unsigned long des_cbc_cksum(
18091 +des_cblock *input,
18092 +des_cblock *output,
18093 +long length,
18094 +des_key_schedule ks,
18095 +des_cblock *ivec);
18096 + This function produces an 8 byte checksum from input that it puts in
18097 + output and returns the last 4 bytes as a long. The checksum is
18098 + generated via cbc mode of DES in which only the last 8 byes are
18099 + kept. I would recommend not using this function but instead using
18100 + the EVP_Digest routines, or at least using MD5 or SHA. This
18101 + function is used by Kerberos v4 so that is why it stays in the
18102 + library.
18103 +
18104 +char *des_fcrypt(
18105 +const char *buf,
18106 +const char *salt
18107 +char *ret);
18108 + This is my fast version of the unix crypt(3) function. This version
18109 + takes only a small amount of space relative to other fast
18110 + crypt() implementations. This is different to the normal crypt
18111 + in that the third parameter is the buffer that the return value
18112 + is written into. It needs to be at least 14 bytes long. This
18113 + function is thread safe, unlike the normal crypt.
18114 +
18115 +char *crypt(
18116 +const char *buf,
18117 +const char *salt);
18118 + This function calls des_fcrypt() with a static array passed as the
18119 + third parameter. This emulates the normal non-thread safe semantics
18120 + of crypt(3).
18121 +
18122 +void des_string_to_key(
18123 +char *str,
18124 +des_cblock *key);
18125 + This function takes str and converts it into a DES key. I would
18126 + recommend using MD5 instead and use the first 8 bytes of output.
18127 + When I wrote the first version of these routines back in 1990, MD5
18128 + did not exist but I feel these routines are still sound. This
18129 + routines is compatible with the one in MIT's libdes.
18130 +
18131 +void des_string_to_2keys(
18132 +char *str,
18133 +des_cblock *key1,
18134 +des_cblock *key2);
18135 + This function takes str and converts it into 2 DES keys.
18136 + I would recommend using MD5 and using the 16 bytes as the 2 keys.
18137 + I have nothing against these 2 'string_to_key' routines, it's just
18138 + that if you say that your encryption key is generated by using the
18139 + 16 bytes of an MD5 hash, every-one knows how you generated your
18140 + keys.
18141 +
18142 +int des_read_password(
18143 +des_cblock *key,
18144 +char *prompt,
18145 +int verify);
18146 + This routine combines des_read_pw_string() with des_string_to_key().
18147 +
18148 +int des_read_2passwords(
18149 +des_cblock *key1,
18150 +des_cblock *key2,
18151 +char *prompt,
18152 +int verify);
18153 + This routine combines des_read_pw_string() with des_string_to_2key().
18154 +
18155 +void des_random_seed(
18156 +des_cblock key);
18157 + This routine sets a starting point for des_random_key().
18158 +
18159 +void des_random_key(
18160 +des_cblock ret);
18161 + This function return a random key. Make sure to 'seed' the random
18162 + number generator (with des_random_seed()) before using this function.
18163 + I personally now use a MD5 based random number system.
18164 +
18165 +int des_enc_read(
18166 +int fd,
18167 +char *buf,
18168 +int len,
18169 +des_key_schedule ks,
18170 +des_cblock *iv);
18171 + This function will write to a file descriptor the encrypted data
18172 + from buf. This data will be preceded by a 4 byte 'byte count' and
18173 + will be padded out to 8 bytes. The encryption is either CBC of
18174 + PCBC depending on the value of des_rw_mode. If it is DES_PCBC_MODE,
18175 + pcbc is used, if DES_CBC_MODE, cbc is used. The default is to use
18176 + DES_PCBC_MODE.
18177 +
18178 +int des_enc_write(
18179 +int fd,
18180 +char *buf,
18181 +int len,
18182 +des_key_schedule ks,
18183 +des_cblock *iv);
18184 + This routines read stuff written by des_enc_read() and decrypts it.
18185 + I have used these routines quite a lot but I don't believe they are
18186 + suitable for non-blocking io. If you are after a full
18187 + authentication/encryption over networks, have a look at SSL instead.
18188 +
18189 +unsigned long des_quad_cksum(
18190 +des_cblock *input,
18191 +des_cblock *output,
18192 +long length,
18193 +int out_count,
18194 +des_cblock *seed);
18195 + This is a function from Kerberos v4 that is not anything to do with
18196 + DES but was needed. It is a cksum that is quicker to generate than
18197 + des_cbc_cksum(); I personally would use MD5 routines now.
18198 +=====
18199 +Modes of DES
18200 +Quite a bit of the following information has been taken from
18201 + AS 2805.5.2
18202 + Australian Standard
18203 + Electronic funds transfer - Requirements for interfaces,
18204 + Part 5.2: Modes of operation for an n-bit block cipher algorithm
18205 + Appendix A
18206 +
18207 +There are several different modes in which DES can be used, they are
18208 +as follows.
18209 +
18210 +Electronic Codebook Mode (ECB) (des_ecb_encrypt())
18211 +- 64 bits are enciphered at a time.
18212 +- The order of the blocks can be rearranged without detection.
18213 +- The same plaintext block always produces the same ciphertext block
18214 + (for the same key) making it vulnerable to a 'dictionary attack'.
18215 +- An error will only affect one ciphertext block.
18216 +
18217 +Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
18218 +- a multiple of 64 bits are enciphered at a time.
18219 +- The CBC mode produces the same ciphertext whenever the same
18220 + plaintext is encrypted using the same key and starting variable.
18221 +- The chaining operation makes the ciphertext blocks dependent on the
18222 + current and all preceding plaintext blocks and therefore blocks can not
18223 + be rearranged.
18224 +- The use of different starting variables prevents the same plaintext
18225 + enciphering to the same ciphertext.
18226 +- An error will affect the current and the following ciphertext blocks.
18227 +
18228 +Cipher Feedback Mode (CFB) (des_cfb_encrypt())
18229 +- a number of bits (j) <= 64 are enciphered at a time.
18230 +- The CFB mode produces the same ciphertext whenever the same
18231 + plaintext is encrypted using the same key and starting variable.
18232 +- The chaining operation makes the ciphertext variables dependent on the
18233 + current and all preceding variables and therefore j-bit variables are
18234 + chained together and can not be rearranged.
18235 +- The use of different starting variables prevents the same plaintext
18236 + enciphering to the same ciphertext.
18237 +- The strength of the CFB mode depends on the size of k (maximal if
18238 + j == k). In my implementation this is always the case.
18239 +- Selection of a small value for j will require more cycles through
18240 + the encipherment algorithm per unit of plaintext and thus cause
18241 + greater processing overheads.
18242 +- Only multiples of j bits can be enciphered.
18243 +- An error will affect the current and the following ciphertext variables.
18244 +
18245 +Output Feedback Mode (OFB) (des_ofb_encrypt())
18246 +- a number of bits (j) <= 64 are enciphered at a time.
18247 +- The OFB mode produces the same ciphertext whenever the same
18248 + plaintext enciphered using the same key and starting variable. More
18249 + over, in the OFB mode the same key stream is produced when the same
18250 + key and start variable are used. Consequently, for security reasons
18251 + a specific start variable should be used only once for a given key.
18252 +- The absence of chaining makes the OFB more vulnerable to specific attacks.
18253 +- The use of different start variables values prevents the same
18254 + plaintext enciphering to the same ciphertext, by producing different
18255 + key streams.
18256 +- Selection of a small value for j will require more cycles through
18257 + the encipherment algorithm per unit of plaintext and thus cause
18258 + greater processing overheads.
18259 +- Only multiples of j bits can be enciphered.
18260 +- OFB mode of operation does not extend ciphertext errors in the
18261 + resultant plaintext output. Every bit error in the ciphertext causes
18262 + only one bit to be in error in the deciphered plaintext.
18263 +- OFB mode is not self-synchronising. If the two operation of
18264 + encipherment and decipherment get out of synchronism, the system needs
18265 + to be re-initialised.
18266 +- Each re-initialisation should use a value of the start variable
18267 + different from the start variable values used before with the same
18268 + key. The reason for this is that an identical bit stream would be
18269 + produced each time from the same parameters. This would be
18270 + susceptible to a ' known plaintext' attack.
18271 +
18272 +Triple ECB Mode (des_ecb3_encrypt())
18273 +- Encrypt with key1, decrypt with key2 and encrypt with key3 again.
18274 +- As for ECB encryption but increases the key length to 168 bits.
18275 + There are theoretic attacks that can be used that make the effective
18276 + key length 112 bits, but this attack also requires 2^56 blocks of
18277 + memory, not very likely, even for the NSA.
18278 +- If both keys are the same it is equivalent to encrypting once with
18279 + just one key.
18280 +- If the first and last key are the same, the key length is 112 bits.
18281 + There are attacks that could reduce the key space to 55 bit's but it
18282 + requires 2^56 blocks of memory.
18283 +- If all 3 keys are the same, this is effectively the same as normal
18284 + ecb mode.
18285 +
18286 +Triple CBC Mode (des_ede3_cbc_encrypt())
18287 +- Encrypt with key1, decrypt with key2 and then encrypt with key3.
18288 +- As for CBC encryption but increases the key length to 168 bits with
18289 + the same restrictions as for triple ecb mode.
18290 --- /dev/null Tue Mar 11 13:02:56 2003
18291 +++ linux/net/ipsec/des/des_enc.c Mon Feb 9 13:51:03 2004
18292 @@ -0,0 +1,524 @@
18293 +/* crypto/des/des_enc.c */
18294 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18295 + * All rights reserved.
18296 + *
18297 + * This package is an SSL implementation written
18298 + * by Eric Young (eay@cryptsoft.com).
18299 + * The implementation was written so as to conform with Netscapes SSL.
18300 + *
18301 + * This library is free for commercial and non-commercial use as long as
18302 + * the following conditions are aheared to. The following conditions
18303 + * apply to all code found in this distribution, be it the RC4, RSA,
18304 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18305 + * included with this distribution is covered by the same copyright terms
18306 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18307 + *
18308 + * Copyright remains Eric Young's, and as such any Copyright notices in
18309 + * the code are not to be removed.
18310 + * If this package is used in a product, Eric Young should be given attribution
18311 + * as the author of the parts of the library used.
18312 + * This can be in the form of a textual message at program startup or
18313 + * in documentation (online or textual) provided with the package.
18314 + *
18315 + * Redistribution and use in source and binary forms, with or without
18316 + * modification, are permitted provided that the following conditions
18317 + * are met:
18318 + * 1. Redistributions of source code must retain the copyright
18319 + * notice, this list of conditions and the following disclaimer.
18320 + * 2. Redistributions in binary form must reproduce the above copyright
18321 + * notice, this list of conditions and the following disclaimer in the
18322 + * documentation and/or other materials provided with the distribution.
18323 + * 3. All advertising materials mentioning features or use of this software
18324 + * must display the following acknowledgement:
18325 + * "This product includes cryptographic software written by
18326 + * Eric Young (eay@cryptsoft.com)"
18327 + * The word 'cryptographic' can be left out if the rouines from the library
18328 + * being used are not cryptographic related :-).
18329 + * 4. If you include any Windows specific code (or a derivative thereof) from
18330 + * the apps directory (application code) you must include an acknowledgement:
18331 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18332 + *
18333 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18334 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18335 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18336 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18337 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18338 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18339 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18340 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18341 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18342 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18343 + * SUCH DAMAGE.
18344 + *
18345 + * The licence and distribution terms for any publically available version or
18346 + * derivative of this code cannot be changed. i.e. this code cannot simply be
18347 + * copied and put under another distribution licence
18348 + * [including the GNU Public Licence.]
18349 + */
18350 +
18351 +#include "des/des_locl.h"
18352 +
18353 +void des_encrypt(data, ks, enc)
18354 +DES_LONG *data;
18355 +des_key_schedule ks;
18356 +int enc;
18357 + {
18358 + register DES_LONG l,r,t,u;
18359 +#ifdef DES_PTR
18360 + register unsigned char *des_SP=(unsigned char *)des_SPtrans;
18361 +#endif
18362 +#ifndef DES_UNROLL
18363 + register int i;
18364 +#endif
18365 + register DES_LONG *s;
18366 +
18367 +#ifdef OCF_ASSIST
18368 + if (ocf_des_assist() & OCF_PROVIDES_DES_3DES) {
18369 + ocf_des_encrypt(data, ks, enc);
18370 + return;
18371 + }
18372 +#endif
18373 +
18374 + r=data[0];
18375 + l=data[1];
18376 +
18377 + IP(r,l);
18378 + /* Things have been modified so that the initial rotate is
18379 + * done outside the loop. This required the
18380 + * des_SPtrans values in sp.h to be rotated 1 bit to the right.
18381 + * One perl script later and things have a 5% speed up on a sparc2.
18382 + * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
18383 + * for pointing this out. */
18384 + /* clear the top bits on machines with 8byte longs */
18385 + /* shift left by 2 */
18386 + r=ROTATE(r,29)&0xffffffffL;
18387 + l=ROTATE(l,29)&0xffffffffL;
18388 +
18389 + s=(DES_LONG *)ks;
18390 + /* I don't know if it is worth the effort of loop unrolling the
18391 + * inner loop */
18392 + if (enc)
18393 + {
18394 +#ifdef DES_UNROLL
18395 + D_ENCRYPT(l,r, 0); /* 1 */
18396 + D_ENCRYPT(r,l, 2); /* 2 */
18397 + D_ENCRYPT(l,r, 4); /* 3 */
18398 + D_ENCRYPT(r,l, 6); /* 4 */
18399 + D_ENCRYPT(l,r, 8); /* 5 */
18400 + D_ENCRYPT(r,l,10); /* 6 */
18401 + D_ENCRYPT(l,r,12); /* 7 */
18402 + D_ENCRYPT(r,l,14); /* 8 */
18403 + D_ENCRYPT(l,r,16); /* 9 */
18404 + D_ENCRYPT(r,l,18); /* 10 */
18405 + D_ENCRYPT(l,r,20); /* 11 */
18406 + D_ENCRYPT(r,l,22); /* 12 */
18407 + D_ENCRYPT(l,r,24); /* 13 */
18408 + D_ENCRYPT(r,l,26); /* 14 */
18409 + D_ENCRYPT(l,r,28); /* 15 */
18410 + D_ENCRYPT(r,l,30); /* 16 */
18411 +#else
18412 + for (i=0; i<32; i+=8)
18413 + {
18414 + D_ENCRYPT(l,r,i+0); /* 1 */
18415 + D_ENCRYPT(r,l,i+2); /* 2 */
18416 + D_ENCRYPT(l,r,i+4); /* 3 */
18417 + D_ENCRYPT(r,l,i+6); /* 4 */
18418 + }
18419 +#endif
18420 + }
18421 + else
18422 + {
18423 +#ifdef DES_UNROLL
18424 + D_ENCRYPT(l,r,30); /* 16 */
18425 + D_ENCRYPT(r,l,28); /* 15 */
18426 + D_ENCRYPT(l,r,26); /* 14 */
18427 + D_ENCRYPT(r,l,24); /* 13 */
18428 + D_ENCRYPT(l,r,22); /* 12 */
18429 + D_ENCRYPT(r,l,20); /* 11 */
18430 + D_ENCRYPT(l,r,18); /* 10 */
18431 + D_ENCRYPT(r,l,16); /* 9 */
18432 + D_ENCRYPT(l,r,14); /* 8 */
18433 + D_ENCRYPT(r,l,12); /* 7 */
18434 + D_ENCRYPT(l,r,10); /* 6 */
18435 + D_ENCRYPT(r,l, 8); /* 5 */
18436 + D_ENCRYPT(l,r, 6); /* 4 */
18437 + D_ENCRYPT(r,l, 4); /* 3 */
18438 + D_ENCRYPT(l,r, 2); /* 2 */
18439 + D_ENCRYPT(r,l, 0); /* 1 */
18440 +#else
18441 + for (i=30; i>0; i-=8)
18442 + {
18443 + D_ENCRYPT(l,r,i-0); /* 16 */
18444 + D_ENCRYPT(r,l,i-2); /* 15 */
18445 + D_ENCRYPT(l,r,i-4); /* 14 */
18446 + D_ENCRYPT(r,l,i-6); /* 13 */
18447 + }
18448 +#endif
18449 + }
18450 +
18451 + /* rotate and clear the top bits on machines with 8byte longs */
18452 + l=ROTATE(l,3)&0xffffffffL;
18453 + r=ROTATE(r,3)&0xffffffffL;
18454 +
18455 + FP(r,l);
18456 + data[0]=l;
18457 + data[1]=r;
18458 + l=r=t=u=0;
18459 + }
18460 +
18461 +void des_encrypt2(data, ks, enc)
18462 +DES_LONG *data;
18463 +des_key_schedule ks;
18464 +int enc;
18465 + {
18466 + register DES_LONG l,r,t,u;
18467 +#ifdef DES_PTR
18468 + register unsigned char *des_SP=(unsigned char *)des_SPtrans;
18469 +#endif
18470 +#ifndef DES_UNROLL
18471 + register int i;
18472 +#endif
18473 + register DES_LONG *s;
18474 +
18475 + r=data[0];
18476 + l=data[1];
18477 +
18478 + /* Things have been modified so that the initial rotate is
18479 + * done outside the loop. This required the
18480 + * des_SPtrans values in sp.h to be rotated 1 bit to the right.
18481 + * One perl script later and things have a 5% speed up on a sparc2.
18482 + * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
18483 + * for pointing this out. */
18484 + /* clear the top bits on machines with 8byte longs */
18485 + r=ROTATE(r,29)&0xffffffffL;
18486 + l=ROTATE(l,29)&0xffffffffL;
18487 +
18488 + s=(DES_LONG *)ks;
18489 + /* I don't know if it is worth the effort of loop unrolling the
18490 + * inner loop */
18491 + if (enc)
18492 + {
18493 +#ifdef DES_UNROLL
18494 + D_ENCRYPT(l,r, 0); /* 1 */
18495 + D_ENCRYPT(r,l, 2); /* 2 */
18496 + D_ENCRYPT(l,r, 4); /* 3 */
18497 + D_ENCRYPT(r,l, 6); /* 4 */
18498 + D_ENCRYPT(l,r, 8); /* 5 */
18499 + D_ENCRYPT(r,l,10); /* 6 */
18500 + D_ENCRYPT(l,r,12); /* 7 */
18501 + D_ENCRYPT(r,l,14); /* 8 */
18502 + D_ENCRYPT(l,r,16); /* 9 */
18503 + D_ENCRYPT(r,l,18); /* 10 */
18504 + D_ENCRYPT(l,r,20); /* 11 */
18505 + D_ENCRYPT(r,l,22); /* 12 */
18506 + D_ENCRYPT(l,r,24); /* 13 */
18507 + D_ENCRYPT(r,l,26); /* 14 */
18508 + D_ENCRYPT(l,r,28); /* 15 */
18509 + D_ENCRYPT(r,l,30); /* 16 */
18510 +#else
18511 + for (i=0; i<32; i+=8)
18512 + {
18513 + D_ENCRYPT(l,r,i+0); /* 1 */
18514 + D_ENCRYPT(r,l,i+2); /* 2 */
18515 + D_ENCRYPT(l,r,i+4); /* 3 */
18516 + D_ENCRYPT(r,l,i+6); /* 4 */
18517 + }
18518 +#endif
18519 + }
18520 + else
18521 + {
18522 +#ifdef DES_UNROLL
18523 + D_ENCRYPT(l,r,30); /* 16 */
18524 + D_ENCRYPT(r,l,28); /* 15 */
18525 + D_ENCRYPT(l,r,26); /* 14 */
18526 + D_ENCRYPT(r,l,24); /* 13 */
18527 + D_ENCRYPT(l,r,22); /* 12 */
18528 + D_ENCRYPT(r,l,20); /* 11 */
18529 + D_ENCRYPT(l,r,18); /* 10 */
18530 + D_ENCRYPT(r,l,16); /* 9 */
18531 + D_ENCRYPT(l,r,14); /* 8 */
18532 + D_ENCRYPT(r,l,12); /* 7 */
18533 + D_ENCRYPT(l,r,10); /* 6 */
18534 + D_ENCRYPT(r,l, 8); /* 5 */
18535 + D_ENCRYPT(l,r, 6); /* 4 */
18536 + D_ENCRYPT(r,l, 4); /* 3 */
18537 + D_ENCRYPT(l,r, 2); /* 2 */
18538 + D_ENCRYPT(r,l, 0); /* 1 */
18539 +#else
18540 + for (i=30; i>0; i-=8)
18541 + {
18542 + D_ENCRYPT(l,r,i-0); /* 16 */
18543 + D_ENCRYPT(r,l,i-2); /* 15 */
18544 + D_ENCRYPT(l,r,i-4); /* 14 */
18545 + D_ENCRYPT(r,l,i-6); /* 13 */
18546 + }
18547 +#endif
18548 + }
18549 + /* rotate and clear the top bits on machines with 8byte longs */
18550 + data[0]=ROTATE(l,3)&0xffffffffL;
18551 + data[1]=ROTATE(r,3)&0xffffffffL;
18552 + l=r=t=u=0;
18553 + }
18554 +
18555 +void des_encrypt3(data,ks1,ks2,ks3)
18556 +DES_LONG *data;
18557 +des_key_schedule ks1;
18558 +des_key_schedule ks2;
18559 +des_key_schedule ks3;
18560 + {
18561 + register DES_LONG l,r;
18562 +
18563 + l=data[0];
18564 + r=data[1];
18565 + IP(l,r);
18566 + data[0]=l;
18567 + data[1]=r;
18568 + des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
18569 + des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
18570 + des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
18571 + l=data[0];
18572 + r=data[1];
18573 + FP(r,l);
18574 + data[0]=l;
18575 + data[1]=r;
18576 + }
18577 +
18578 +void des_decrypt3(data,ks1,ks2,ks3)
18579 +DES_LONG *data;
18580 +des_key_schedule ks1;
18581 +des_key_schedule ks2;
18582 +des_key_schedule ks3;
18583 + {
18584 + register DES_LONG l,r;
18585 +
18586 + l=data[0];
18587 + r=data[1];
18588 + IP(l,r);
18589 + data[0]=l;
18590 + data[1]=r;
18591 + des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
18592 + des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
18593 + des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
18594 + l=data[0];
18595 + r=data[1];
18596 + FP(r,l);
18597 + data[0]=l;
18598 + data[1]=r;
18599 + }
18600 +
18601 +#ifndef DES_DEFAULT_OPTIONS
18602 +
18603 +void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
18604 +des_cblock (*input);
18605 +des_cblock (*output);
18606 +long length;
18607 +des_key_schedule schedule;
18608 +des_cblock (*ivec);
18609 +int enc;
18610 + {
18611 + register DES_LONG tin0,tin1;
18612 + register DES_LONG tout0,tout1,xor0,xor1;
18613 + register unsigned char *in,*out;
18614 + register long l=length;
18615 + DES_LONG tin[2];
18616 + unsigned char *iv;
18617 +
18618 +#ifdef OCF_ASSIST
18619 + if (ocf_des_assist() & OCF_PROVIDES_DES_3DES) {
18620 + ocf_des_ncbc_encrypt(input, output, length, schedule, ivec, enc);
18621 + return;
18622 + }
18623 +#endif
18624 +
18625 + in=(unsigned char *)input;
18626 + out=(unsigned char *)output;
18627 + iv=(unsigned char *)ivec;
18628 +
18629 + if (enc)
18630 + {
18631 + c2l(iv,tout0);
18632 + c2l(iv,tout1);
18633 + for (l-=8; l>=0; l-=8)
18634 + {
18635 + c2l(in,tin0);
18636 + c2l(in,tin1);
18637 + tin0^=tout0; tin[0]=tin0;
18638 + tin1^=tout1; tin[1]=tin1;
18639 + des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
18640 + tout0=tin[0]; l2c(tout0,out);
18641 + tout1=tin[1]; l2c(tout1,out);
18642 + }
18643 + if (l != -8)
18644 + {
18645 + c2ln(in,tin0,tin1,l+8);
18646 + tin0^=tout0; tin[0]=tin0;
18647 + tin1^=tout1; tin[1]=tin1;
18648 + des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
18649 + tout0=tin[0]; l2c(tout0,out);
18650 + tout1=tin[1]; l2c(tout1,out);
18651 + }
18652 + iv=(unsigned char *)ivec;
18653 + l2c(tout0,iv);
18654 + l2c(tout1,iv);
18655 + }
18656 + else
18657 + {
18658 + c2l(iv,xor0);
18659 + c2l(iv,xor1);
18660 + for (l-=8; l>=0; l-=8)
18661 + {
18662 + c2l(in,tin0); tin[0]=tin0;
18663 + c2l(in,tin1); tin[1]=tin1;
18664 + des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
18665 + tout0=tin[0]^xor0;
18666 + tout1=tin[1]^xor1;
18667 + l2c(tout0,out);
18668 + l2c(tout1,out);
18669 + xor0=tin0;
18670 + xor1=tin1;
18671 + }
18672 + if (l != -8)
18673 + {
18674 + c2l(in,tin0); tin[0]=tin0;
18675 + c2l(in,tin1); tin[1]=tin1;
18676 + des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
18677 + tout0=tin[0]^xor0;
18678 + tout1=tin[1]^xor1;
18679 + l2cn(tout0,tout1,out,l+8);
18680 + xor0=tin0;
18681 + xor1=tin1;
18682 + }
18683 +
18684 + iv=(unsigned char *)ivec;
18685 + l2c(xor0,iv);
18686 + l2c(xor1,iv);
18687 + }
18688 + tin0=tin1=tout0=tout1=xor0=xor1=0;
18689 + tin[0]=tin[1]=0;
18690 + }
18691 +
18692 +void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc)
18693 +des_cblock (*input);
18694 +des_cblock (*output);
18695 +long length;
18696 +des_key_schedule ks1;
18697 +des_key_schedule ks2;
18698 +des_key_schedule ks3;
18699 +des_cblock (*ivec);
18700 +int enc;
18701 + {
18702 + register DES_LONG tin0,tin1;
18703 + register DES_LONG tout0,tout1,xor0,xor1;
18704 + register unsigned char *in,*out;
18705 + register long l=length;
18706 + DES_LONG tin[2];
18707 + unsigned char *iv;
18708 +
18709 +#ifdef OCF_ASSIST
18710 + if (ocf_des_assist() & OCF_PROVIDES_DES_3DES) {
18711 + ocf_des_ede3_cbc_encrypt(input,output,length,ks1,ks2,ks3,ivec,enc);
18712 + return;
18713 + }
18714 +#endif
18715 +
18716 +
18717 + in=(unsigned char *)input;
18718 + out=(unsigned char *)output;
18719 + iv=(unsigned char *)ivec;
18720 +
18721 + if (enc)
18722 + {
18723 + c2l(iv,tout0);
18724 + c2l(iv,tout1);
18725 + for (l-=8; l>=0; l-=8)
18726 + {
18727 + c2l(in,tin0);
18728 + c2l(in,tin1);
18729 + tin0^=tout0;
18730 + tin1^=tout1;
18731 +
18732 + tin[0]=tin0;
18733 + tin[1]=tin1;
18734 + des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
18735 + tout0=tin[0];
18736 + tout1=tin[1];
18737 +
18738 + l2c(tout0,out);
18739 + l2c(tout1,out);
18740 + }
18741 + if (l != -8)
18742 + {
18743 + c2ln(in,tin0,tin1,l+8);
18744 + tin0^=tout0;
18745 + tin1^=tout1;
18746 +
18747 + tin[0]=tin0;
18748 + tin[1]=tin1;
18749 + des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
18750 + tout0=tin[0];
18751 + tout1=tin[1];
18752 +
18753 + l2c(tout0,out);
18754 + l2c(tout1,out);
18755 + }
18756 + iv=(unsigned char *)ivec;
18757 + l2c(tout0,iv);
18758 + l2c(tout1,iv);
18759 + }
18760 + else
18761 + {
18762 + register DES_LONG t0,t1;
18763 +
18764 + c2l(iv,xor0);
18765 + c2l(iv,xor1);
18766 + for (l-=8; l>=0; l-=8)
18767 + {
18768 + c2l(in,tin0);
18769 + c2l(in,tin1);
18770 +
18771 + t0=tin0;
18772 + t1=tin1;
18773 +
18774 + tin[0]=tin0;
18775 + tin[1]=tin1;
18776 + des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
18777 + tout0=tin[0];
18778 + tout1=tin[1];
18779 +
18780 + tout0^=xor0;
18781 + tout1^=xor1;
18782 + l2c(tout0,out);
18783 + l2c(tout1,out);
18784 + xor0=t0;
18785 + xor1=t1;
18786 + }
18787 + if (l != -8)
18788 + {
18789 + c2l(in,tin0);
18790 + c2l(in,tin1);
18791 +
18792 + t0=tin0;
18793 + t1=tin1;
18794 +
18795 + tin[0]=tin0;
18796 + tin[1]=tin1;
18797 + des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
18798 + tout0=tin[0];
18799 + tout1=tin[1];
18800 +
18801 + tout0^=xor0;
18802 + tout1^=xor1;
18803 + l2cn(tout0,tout1,out,l+8);
18804 + xor0=t0;
18805 + xor1=t1;
18806 + }
18807 +
18808 + iv=(unsigned char *)ivec;
18809 + l2c(xor0,iv);
18810 + l2c(xor1,iv);
18811 + }
18812 + tin0=tin1=tout0=tout1=xor0=xor1=0;
18813 + tin[0]=tin[1]=0;
18814 + }
18815 +
18816 +#endif /* DES_DEFAULT_OPTIONS */
18817 --- /dev/null Tue Mar 11 13:02:56 2003
18818 +++ linux/net/ipsec/des/des_opts.c Mon Feb 9 13:51:03 2004
18819 @@ -0,0 +1,620 @@
18820 +/* crypto/des/des_opts.c */
18821 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18822 + * All rights reserved.
18823 + *
18824 + * This package is an SSL implementation written
18825 + * by Eric Young (eay@cryptsoft.com).
18826 + * The implementation was written so as to conform with Netscapes SSL.
18827 + *
18828 + * This library is free for commercial and non-commercial use as long as
18829 + * the following conditions are aheared to. The following conditions
18830 + * apply to all code found in this distribution, be it the RC4, RSA,
18831 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18832 + * included with this distribution is covered by the same copyright terms
18833 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18834 + *
18835 + * Copyright remains Eric Young's, and as such any Copyright notices in
18836 + * the code are not to be removed.
18837 + * If this package is used in a product, Eric Young should be given attribution
18838 + * as the author of the parts of the library used.
18839 + * This can be in the form of a textual message at program startup or
18840 + * in documentation (online or textual) provided with the package.
18841 + *
18842 + * Redistribution and use in source and binary forms, with or without
18843 + * modification, are permitted provided that the following conditions
18844 + * are met:
18845 + * 1. Redistributions of source code must retain the copyright
18846 + * notice, this list of conditions and the following disclaimer.
18847 + * 2. Redistributions in binary form must reproduce the above copyright
18848 + * notice, this list of conditions and the following disclaimer in the
18849 + * documentation and/or other materials provided with the distribution.
18850 + * 3. All advertising materials mentioning features or use of this software
18851 + * must display the following acknowledgement:
18852 + * "This product includes cryptographic software written by
18853 + * Eric Young (eay@cryptsoft.com)"
18854 + * The word 'cryptographic' can be left out if the rouines from the library
18855 + * being used are not cryptographic related :-).
18856 + * 4. If you include any Windows specific code (or a derivative thereof) from
18857 + * the apps directory (application code) you must include an acknowledgement:
18858 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18859 + *
18860 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18861 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18862 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18863 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18864 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18865 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18866 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18867 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18868 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18869 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18870 + * SUCH DAMAGE.
18871 + *
18872 + * The licence and distribution terms for any publically available version or
18873 + * derivative of this code cannot be changed. i.e. this code cannot simply be
18874 + * copied and put under another distribution licence
18875 + * [including the GNU Public Licence.]
18876 + */
18877 +
18878 +/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
18879 + * This is for machines with 64k code segment size restrictions. */
18880 +
18881 +#ifndef MSDOS
18882 +#define TIMES
18883 +#endif
18884 +
18885 +#include <stdio.h>
18886 +#ifndef MSDOS
18887 +#include <unistd.h>
18888 +#else
18889 +#include <io.h>
18890 +extern void exit();
18891 +#endif
18892 +#include <signal.h>
18893 +#ifndef VMS
18894 +#ifndef _IRIX
18895 +#include <time.h>
18896 +#endif
18897 +#ifdef TIMES
18898 +#include <sys/types.h>
18899 +#include <sys/times.h>
18900 +#endif
18901 +#else /* VMS */
18902 +#include <types.h>
18903 +struct tms {
18904 + time_t tms_utime;
18905 + time_t tms_stime;
18906 + time_t tms_uchild; /* I dunno... */
18907 + time_t tms_uchildsys; /* so these names are a guess :-) */
18908 + }
18909 +#endif
18910 +#ifndef TIMES
18911 +#include <sys/timeb.h>
18912 +#endif
18913 +
18914 +#ifdef sun
18915 +#include <limits.h>
18916 +#include <sys/param.h>
18917 +#endif
18918 +
18919 +#include "des/des_locl.h"
18920 +#include "des/spr.h"
18921 +
18922 +#define DES_DEFAULT_OPTIONS
18923 +
18924 +#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4)
18925 +#define PART1
18926 +#define PART2
18927 +#define PART3
18928 +#define PART4
18929 +#endif
18930 +
18931 +#ifdef PART1
18932 +
18933 +#undef DES_UNROLL
18934 +#undef DES_RISC1
18935 +#undef DES_RISC2
18936 +#undef DES_PTR
18937 +#undef D_ENCRYPT
18938 +#define des_encrypt des_encrypt_u4_cisc_idx
18939 +#define des_encrypt2 des_encrypt2_u4_cisc_idx
18940 +#define des_encrypt3 des_encrypt3_u4_cisc_idx
18941 +#define des_decrypt3 des_decrypt3_u4_cisc_idx
18942 +#undef HEADER_DES_LOCL_H
18943 +#include "des_enc.c"
18944 +
18945 +#define DES_UNROLL
18946 +#undef DES_RISC1
18947 +#undef DES_RISC2
18948 +#undef DES_PTR
18949 +#undef D_ENCRYPT
18950 +#undef des_encrypt
18951 +#undef des_encrypt2
18952 +#undef des_encrypt3
18953 +#undef des_decrypt3
18954 +#define des_encrypt des_encrypt_u16_cisc_idx
18955 +#define des_encrypt2 des_encrypt2_u16_cisc_idx
18956 +#define des_encrypt3 des_encrypt3_u16_cisc_idx
18957 +#define des_decrypt3 des_decrypt3_u16_cisc_idx
18958 +#undef HEADER_DES_LOCL_H
18959 +#include "des_enc.c"
18960 +
18961 +#undef DES_UNROLL
18962 +#define DES_RISC1
18963 +#undef DES_RISC2
18964 +#undef DES_PTR
18965 +#undef D_ENCRYPT
18966 +#undef des_encrypt
18967 +#undef des_encrypt2
18968 +#undef des_encrypt3
18969 +#undef des_decrypt3
18970 +#define des_encrypt des_encrypt_u4_risc1_idx
18971 +#define des_encrypt2 des_encrypt2_u4_risc1_idx
18972 +#define des_encrypt3 des_encrypt3_u4_risc1_idx
18973 +#define des_decrypt3 des_decrypt3_u4_risc1_idx
18974 +#undef HEADER_DES_LOCL_H
18975 +#include "des_enc.c"
18976 +
18977 +#endif
18978 +
18979 +#ifdef PART2
18980 +
18981 +#undef DES_UNROLL
18982 +#undef DES_RISC1
18983 +#define DES_RISC2
18984 +#undef DES_PTR
18985 +#undef D_ENCRYPT
18986 +#undef des_encrypt
18987 +#undef des_encrypt2
18988 +#undef des_encrypt3
18989 +#undef des_decrypt3
18990 +#define des_encrypt des_encrypt_u4_risc2_idx
18991 +#define des_encrypt2 des_encrypt2_u4_risc2_idx
18992 +#define des_encrypt3 des_encrypt3_u4_risc2_idx
18993 +#define des_decrypt3 des_decrypt3_u4_risc2_idx
18994 +#undef HEADER_DES_LOCL_H
18995 +#include "des_enc.c"
18996 +
18997 +#define DES_UNROLL
18998 +#define DES_RISC1
18999 +#undef DES_RISC2
19000 +#undef DES_PTR
19001 +#undef D_ENCRYPT
19002 +#undef des_encrypt
19003 +#undef des_encrypt2
19004 +#undef des_encrypt3
19005 +#undef des_decrypt3
19006 +#define des_encrypt des_encrypt_u16_risc1_idx
19007 +#define des_encrypt2 des_encrypt2_u16_risc1_idx
19008 +#define des_encrypt3 des_encrypt3_u16_risc1_idx
19009 +#define des_decrypt3 des_decrypt3_u16_risc1_idx
19010 +#undef HEADER_DES_LOCL_H
19011 +#include "des_enc.c"
19012 +
19013 +#define DES_UNROLL
19014 +#undef DES_RISC1
19015 +#define DES_RISC2
19016 +#undef DES_PTR
19017 +#undef D_ENCRYPT
19018 +#undef des_encrypt
19019 +#undef des_encrypt2
19020 +#undef des_encrypt3
19021 +#undef des_decrypt3
19022 +#define des_encrypt des_encrypt_u16_risc2_idx
19023 +#define des_encrypt2 des_encrypt2_u16_risc2_idx
19024 +#define des_encrypt3 des_encrypt3_u16_risc2_idx
19025 +#define des_decrypt3 des_decrypt3_u16_risc2_idx
19026 +#undef HEADER_DES_LOCL_H
19027 +#include "des_enc.c"
19028 +
19029 +#endif
19030 +
19031 +#ifdef PART3
19032 +
19033 +#undef DES_UNROLL
19034 +#undef DES_RISC1
19035 +#undef DES_RISC2
19036 +#define DES_PTR
19037 +#undef D_ENCRYPT
19038 +#undef des_encrypt
19039 +#undef des_encrypt2
19040 +#undef des_encrypt3
19041 +#undef des_decrypt3
19042 +#define des_encrypt des_encrypt_u4_cisc_ptr
19043 +#define des_encrypt2 des_encrypt2_u4_cisc_ptr
19044 +#define des_encrypt3 des_encrypt3_u4_cisc_ptr
19045 +#define des_decrypt3 des_decrypt3_u4_cisc_ptr
19046 +#undef HEADER_DES_LOCL_H
19047 +#include "des_enc.c"
19048 +
19049 +#define DES_UNROLL
19050 +#undef DES_RISC1
19051 +#undef DES_RISC2
19052 +#define DES_PTR
19053 +#undef D_ENCRYPT
19054 +#undef des_encrypt
19055 +#undef des_encrypt2
19056 +#undef des_encrypt3
19057 +#undef des_decrypt3
19058 +#define des_encrypt des_encrypt_u16_cisc_ptr
19059 +#define des_encrypt2 des_encrypt2_u16_cisc_ptr
19060 +#define des_encrypt3 des_encrypt3_u16_cisc_ptr
19061 +#define des_decrypt3 des_decrypt3_u16_cisc_ptr
19062 +#undef HEADER_DES_LOCL_H
19063 +#include "des_enc.c"
19064 +
19065 +#undef DES_UNROLL
19066 +#define DES_RISC1
19067 +#undef DES_RISC2
19068 +#define DES_PTR
19069 +#undef D_ENCRYPT
19070 +#undef des_encrypt
19071 +#undef des_encrypt2
19072 +#undef des_encrypt3
19073 +#undef des_decrypt3
19074 +#define des_encrypt des_encrypt_u4_risc1_ptr
19075 +#define des_encrypt2 des_encrypt2_u4_risc1_ptr
19076 +#define des_encrypt3 des_encrypt3_u4_risc1_ptr
19077 +#define des_decrypt3 des_decrypt3_u4_risc1_ptr
19078 +#undef HEADER_DES_LOCL_H
19079 +#include "des_enc.c"
19080 +
19081 +#endif
19082 +
19083 +#ifdef PART4
19084 +
19085 +#undef DES_UNROLL
19086 +#undef DES_RISC1
19087 +#define DES_RISC2
19088 +#define DES_PTR
19089 +#undef D_ENCRYPT
19090 +#undef des_encrypt
19091 +#undef des_encrypt2
19092 +#undef des_encrypt3
19093 +#undef des_decrypt3
19094 +#define des_encrypt des_encrypt_u4_risc2_ptr
19095 +#define des_encrypt2 des_encrypt2_u4_risc2_ptr
19096 +#define des_encrypt3 des_encrypt3_u4_risc2_ptr
19097 +#define des_decrypt3 des_decrypt3_u4_risc2_ptr
19098 +#undef HEADER_DES_LOCL_H
19099 +#include "des_enc.c"
19100 +
19101 +#define DES_UNROLL
19102 +#define DES_RISC1
19103 +#undef DES_RISC2
19104 +#define DES_PTR
19105 +#undef D_ENCRYPT
19106 +#undef des_encrypt
19107 +#undef des_encrypt2
19108 +#undef des_encrypt3
19109 +#undef des_decrypt3
19110 +#define des_encrypt des_encrypt_u16_risc1_ptr
19111 +#define des_encrypt2 des_encrypt2_u16_risc1_ptr
19112 +#define des_encrypt3 des_encrypt3_u16_risc1_ptr
19113 +#define des_decrypt3 des_decrypt3_u16_risc1_ptr
19114 +#undef HEADER_DES_LOCL_H
19115 +#include "des_enc.c"
19116 +
19117 +#define DES_UNROLL
19118 +#undef DES_RISC1
19119 +#define DES_RISC2
19120 +#define DES_PTR
19121 +#undef D_ENCRYPT
19122 +#undef des_encrypt
19123 +#undef des_encrypt2
19124 +#undef des_encrypt3
19125 +#undef des_decrypt3
19126 +#define des_encrypt des_encrypt_u16_risc2_ptr
19127 +#define des_encrypt2 des_encrypt2_u16_risc2_ptr
19128 +#define des_encrypt3 des_encrypt3_u16_risc2_ptr
19129 +#define des_decrypt3 des_decrypt3_u16_risc2_ptr
19130 +#undef HEADER_DES_LOCL_H
19131 +#include "des_enc.c"
19132 +
19133 +#endif
19134 +
19135 +/* The following if from times(3) man page. It may need to be changed */
19136 +#ifndef HZ
19137 +# ifndef CLK_TCK
19138 +# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
19139 +# ifndef VMS
19140 +# define HZ 100.0
19141 +# else /* VMS */
19142 +# define HZ 100.0
19143 +# endif
19144 +# else /* _BSD_CLK_TCK_ */
19145 +# define HZ ((double)_BSD_CLK_TCK_)
19146 +# endif
19147 +# else /* CLK_TCK */
19148 +# define HZ ((double)CLK_TCK)
19149 +# endif
19150 +#endif
19151 +
19152 +#define BUFSIZE ((long)1024)
19153 +long run=0;
19154 +
19155 +#ifndef NOPROTO
19156 +double Time_F(int s);
19157 +#else
19158 +double Time_F();
19159 +#endif
19160 +
19161 +#ifdef SIGALRM
19162 +#if defined(__STDC__) || defined(sgi)
19163 +#define SIGRETTYPE void
19164 +#else
19165 +#define SIGRETTYPE int
19166 +#endif
19167 +
19168 +#ifndef NOPROTO
19169 +SIGRETTYPE sig_done(int sig);
19170 +#else
19171 +SIGRETTYPE sig_done();
19172 +#endif
19173 +
19174 +SIGRETTYPE sig_done(sig)
19175 +int sig;
19176 + {
19177 + signal(SIGALRM,sig_done);
19178 + run=0;
19179 +#ifdef LINT
19180 + sig=sig;
19181 +#endif
19182 + }
19183 +#endif
19184 +
19185 +#define START 0
19186 +#define STOP 1
19187 +
19188 +double Time_F(s)
19189 +int s;
19190 + {
19191 + double ret;
19192 +#ifdef TIMES
19193 + static struct tms tstart,tend;
19194 +
19195 + if (s == START)
19196 + {
19197 + times(&tstart);
19198 + return(0);
19199 + }
19200 + else
19201 + {
19202 + times(&tend);
19203 + ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
19204 + return((ret == 0.0)?1e-6:ret);
19205 + }
19206 +#else /* !times() */
19207 + static struct timeb tstart,tend;
19208 + long i;
19209 +
19210 + if (s == START)
19211 + {
19212 + ftime(&tstart);
19213 + return(0);
19214 + }
19215 + else
19216 + {
19217 + ftime(&tend);
19218 + i=(long)tend.millitm-(long)tstart.millitm;
19219 + ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
19220 + return((ret == 0.0)?1e-6:ret);
19221 + }
19222 +#endif
19223 + }
19224 +
19225 +#ifdef SIGALRM
19226 +#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
19227 +#else
19228 +#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
19229 +#endif
19230 +
19231 +#define time_it(func,name,index) \
19232 + print_name(name); \
19233 + Time_F(START); \
19234 + for (count=0,run=1; COND(cb); count++) \
19235 + { \
19236 + unsigned long d[2]; \
19237 + func(d,&(sch[0]),DES_ENCRYPT); \
19238 + } \
19239 + tm[index]=Time_F(STOP); \
19240 + fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
19241 + tm[index]=((double)COUNT(cb))/tm[index];
19242 +
19243 +#define print_it(name,index) \
19244 + fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
19245 + tm[index]*8,1.0e6/tm[index]);
19246 +
19247 +int main(argc,argv)
19248 +int argc;
19249 +char **argv;
19250 + {
19251 + long count;
19252 + static unsigned char buf[BUFSIZE];
19253 + static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
19254 + static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
19255 + static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
19256 + des_key_schedule sch,sch2,sch3;
19257 + double d,tm[16],max=0;
19258 + int rank[16];
19259 + char *str[16];
19260 + int max_idx=0,i,num=0,j;
19261 +#ifndef SIGALARM
19262 + long ca,cb,cc,cd,ce;
19263 +#endif
19264 +
19265 + for (i=0; i<12; i++)
19266 + {
19267 + tm[i]=0.0;
19268 + rank[i]=0;
19269 + }
19270 +
19271 +#ifndef TIMES
19272 + fprintf(stderr,"To get the most acurate results, try to run this\n");
19273 + fprintf(stderr,"program when this computer is idle.\n");
19274 +#endif
19275 +
19276 + des_set_key((C_Block *)key,sch);
19277 + des_set_key((C_Block *)key2,sch2);
19278 + des_set_key((C_Block *)key3,sch3);
19279 +
19280 +#ifndef SIGALRM
19281 + fprintf(stderr,"First we calculate the approximate speed ...\n");
19282 + des_set_key((C_Block *)key,sch);
19283 + count=10;
19284 + do {
19285 + long i;
19286 + unsigned long data[2];
19287 +
19288 + count*=2;
19289 + Time_F(START);
19290 + for (i=count; i; i--)
19291 + des_encrypt(data,&(sch[0]),DES_ENCRYPT);
19292 + d=Time_F(STOP);
19293 + } while (d < 3.0);
19294 + ca=count;
19295 + cb=count*3;
19296 + cc=count*3*8/BUFSIZE+1;
19297 + cd=count*8/BUFSIZE+1;
19298 +
19299 + ce=count/20+1;
19300 +#define COND(d) (count != (d))
19301 +#define COUNT(d) (d)
19302 +#else
19303 +#define COND(c) (run)
19304 +#define COUNT(d) (count)
19305 + signal(SIGALRM,sig_done);
19306 + alarm(10);
19307 +#endif
19308 +
19309 +#ifdef PART1
19310 + time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0);
19311 + time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1);
19312 + time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2);
19313 + num+=3;
19314 +#endif
19315 +#ifdef PART2
19316 + time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3);
19317 + time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4);
19318 + time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5);
19319 + num+=3;
19320 +#endif
19321 +#ifdef PART3
19322 + time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6);
19323 + time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7);
19324 + time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8);
19325 + num+=3;
19326 +#endif
19327 +#ifdef PART4
19328 + time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9);
19329 + time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10);
19330 + time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11);
19331 + num+=3;
19332 +#endif
19333 +
19334 +#ifdef PART1
19335 + str[0]=" 4 c i";
19336 + print_it("des_encrypt_u4_cisc_idx ",0);
19337 + max=tm[0];
19338 + max_idx=0;
19339 + str[1]="16 c i";
19340 + print_it("des_encrypt_u16_cisc_idx ",1);
19341 + if (max < tm[1]) { max=tm[1]; max_idx=1; }
19342 + str[2]=" 4 r1 i";
19343 + print_it("des_encrypt_u4_risc1_idx ",2);
19344 + if (max < tm[2]) { max=tm[2]; max_idx=2; }
19345 +#endif
19346 +#ifdef PART2
19347 + str[3]="16 r1 i";
19348 + print_it("des_encrypt_u16_risc1_idx",3);
19349 + if (max < tm[3]) { max=tm[3]; max_idx=3; }
19350 + str[4]=" 4 r2 i";
19351 + print_it("des_encrypt_u4_risc2_idx ",4);
19352 + if (max < tm[4]) { max=tm[4]; max_idx=4; }
19353 + str[5]="16 r2 i";
19354 + print_it("des_encrypt_u16_risc2_idx",5);
19355 + if (max < tm[5]) { max=tm[5]; max_idx=5; }
19356 +#endif
19357 +#ifdef PART3
19358 + str[6]=" 4 c p";
19359 + print_it("des_encrypt_u4_cisc_ptr ",6);
19360 + if (max < tm[6]) { max=tm[6]; max_idx=6; }
19361 + str[7]="16 c p";
19362 + print_it("des_encrypt_u16_cisc_ptr ",7);
19363 + if (max < tm[7]) { max=tm[7]; max_idx=7; }
19364 + str[8]=" 4 r1 p";
19365 + print_it("des_encrypt_u4_risc1_ptr ",8);
19366 + if (max < tm[8]) { max=tm[8]; max_idx=8; }
19367 +#endif
19368 +#ifdef PART4
19369 + str[9]="16 r1 p";
19370 + print_it("des_encrypt_u16_risc1_ptr",9);
19371 + if (max < tm[9]) { max=tm[9]; max_idx=9; }
19372 + str[10]=" 4 r2 p";
19373 + print_it("des_encrypt_u4_risc2_ptr ",10);
19374 + if (max < tm[10]) { max=tm[10]; max_idx=10; }
19375 + str[11]="16 r2 p";
19376 + print_it("des_encrypt_u16_risc2_ptr",11);
19377 + if (max < tm[11]) { max=tm[11]; max_idx=11; }
19378 +#endif
19379 + printf("options des ecb/s\n");
19380 + printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
19381 + d=tm[max_idx];
19382 + tm[max_idx]= -2.0;
19383 + max= -1.0;
19384 + for (;;)
19385 + {
19386 + for (i=0; i<12; i++)
19387 + {
19388 + if (max < tm[i]) { max=tm[i]; j=i; }
19389 + }
19390 + if (max < 0.0) break;
19391 + printf("%s %12.2f %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
19392 + tm[j]= -2.0;
19393 + max= -1.0;
19394 + }
19395 +
19396 + switch (max_idx)
19397 + {
19398 + case 0:
19399 + printf("-DDES_DEFAULT_OPTIONS\n");
19400 + break;
19401 + case 1:
19402 + printf("-DDES_UNROLL\n");
19403 + break;
19404 + case 2:
19405 + printf("-DDES_RISC1\n");
19406 + break;
19407 + case 3:
19408 + printf("-DDES_UNROLL -DDES_RISC1\n");
19409 + break;
19410 + case 4:
19411 + printf("-DDES_RISC2\n");
19412 + break;
19413 + case 5:
19414 + printf("-DDES_UNROLL -DDES_RISC2\n");
19415 + break;
19416 + case 6:
19417 + printf("-DDES_PTR\n");
19418 + break;
19419 + case 7:
19420 + printf("-DDES_UNROLL -DDES_PTR\n");
19421 + break;
19422 + case 8:
19423 + printf("-DDES_RISC1 -DDES_PTR\n");
19424 + break;
19425 + case 9:
19426 + printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n");
19427 + break;
19428 + case 10:
19429 + printf("-DDES_RISC2 -DDES_PTR\n");
19430 + break;
19431 + case 11:
19432 + printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n");
19433 + break;
19434 + }
19435 + exit(0);
19436 +#if defined(LINT) || defined(MSDOS)
19437 + return(0);
19438 +#endif
19439 + }
19440 --- /dev/null Tue Mar 11 13:02:56 2003
19441 +++ linux/net/ipsec/des/dx86unix.S Mon Feb 9 13:51:03 2004
19442 @@ -0,0 +1,3160 @@
19443 +/*
19444 + * This file was originally generated by Michael Richardson <mcr@freeswan.org>
19445 + * via the perl scripts found in the ASM subdir. It remains copyright of
19446 + * Eric Young, see the file COPYRIGHT.
19447 + *
19448 + * This was last done on October 9, 2002.
19449 + *
19450 + * While this file does not need to go through cpp, we pass it through
19451 + * CPP by naming it dx86unix.S instead of dx86unix.s because there is
19452 + * a bug in Rules.make for .s builds - specifically it references EXTRA_CFLAGS
19453 + * which may contain stuff that AS doesn't understand instead of
19454 + * referencing EXTRA_AFLAGS.
19455 + */
19456 +
19457 + .file "dx86unix.S"
19458 + .version "01.01"
19459 +.text
19460 + .align 16
19461 +.globl des_encrypt
19462 + .type des_encrypt , @function
19463 +des_encrypt:
19464 + pushl %esi
19465 + pushl %edi
19466 +
19467 +
19468 + movl 12(%esp), %esi
19469 + xorl %ecx, %ecx
19470 + pushl %ebx
19471 + pushl %ebp
19472 + movl (%esi), %eax
19473 + movl 28(%esp), %ebx
19474 + movl 4(%esi), %edi
19475 +
19476 +
19477 + roll $4, %eax
19478 + movl %eax, %esi
19479 + xorl %edi, %eax
19480 + andl $0xf0f0f0f0, %eax
19481 + xorl %eax, %esi
19482 + xorl %eax, %edi
19483 +
19484 + roll $20, %edi
19485 + movl %edi, %eax
19486 + xorl %esi, %edi
19487 + andl $0xfff0000f, %edi
19488 + xorl %edi, %eax
19489 + xorl %edi, %esi
19490 +
19491 + roll $14, %eax
19492 + movl %eax, %edi
19493 + xorl %esi, %eax
19494 + andl $0x33333333, %eax
19495 + xorl %eax, %edi
19496 + xorl %eax, %esi
19497 +
19498 + roll $22, %esi
19499 + movl %esi, %eax
19500 + xorl %edi, %esi
19501 + andl $0x03fc03fc, %esi
19502 + xorl %esi, %eax
19503 + xorl %esi, %edi
19504 +
19505 + roll $9, %eax
19506 + movl %eax, %esi
19507 + xorl %edi, %eax
19508 + andl $0xaaaaaaaa, %eax
19509 + xorl %eax, %esi
19510 + xorl %eax, %edi
19511 +
19512 +.byte 209
19513 +.byte 199
19514 + movl 24(%esp), %ebp
19515 + cmpl $0, %ebx
19516 + je .L000start_decrypt
19517 +
19518 +
19519 + movl (%ebp), %eax
19520 + xorl %ebx, %ebx
19521 + movl 4(%ebp), %edx
19522 + xorl %esi, %eax
19523 + xorl %esi, %edx
19524 + andl $0xfcfcfcfc, %eax
19525 + andl $0xcfcfcfcf, %edx
19526 + movb %al, %bl
19527 + movb %ah, %cl
19528 + rorl $4, %edx
19529 + movl des_SPtrans(%ebx),%ebp
19530 + movb %dl, %bl
19531 + xorl %ebp, %edi
19532 + movl 0x200+des_SPtrans(%ecx),%ebp
19533 + xorl %ebp, %edi
19534 + movb %dh, %cl
19535 + shrl $16, %eax
19536 + movl 0x100+des_SPtrans(%ebx),%ebp
19537 + xorl %ebp, %edi
19538 + movb %ah, %bl
19539 + shrl $16, %edx
19540 + movl 0x300+des_SPtrans(%ecx),%ebp
19541 + xorl %ebp, %edi
19542 + movl 24(%esp), %ebp
19543 + movb %dh, %cl
19544 + andl $0xff, %eax
19545 + andl $0xff, %edx
19546 + movl 0x600+des_SPtrans(%ebx),%ebx
19547 + xorl %ebx, %edi
19548 + movl 0x700+des_SPtrans(%ecx),%ebx
19549 + xorl %ebx, %edi
19550 + movl 0x400+des_SPtrans(%eax),%ebx
19551 + xorl %ebx, %edi
19552 + movl 0x500+des_SPtrans(%edx),%ebx
19553 + xorl %ebx, %edi
19554 +
19555 +
19556 + movl 8(%ebp), %eax
19557 + xorl %ebx, %ebx
19558 + movl 12(%ebp), %edx
19559 + xorl %edi, %eax
19560 + xorl %edi, %edx
19561 + andl $0xfcfcfcfc, %eax
19562 + andl $0xcfcfcfcf, %edx
19563 + movb %al, %bl
19564 + movb %ah, %cl
19565 + rorl $4, %edx
19566 + movl des_SPtrans(%ebx),%ebp
19567 + movb %dl, %bl
19568 + xorl %ebp, %esi
19569 + movl 0x200+des_SPtrans(%ecx),%ebp
19570 + xorl %ebp, %esi
19571 + movb %dh, %cl
19572 + shrl $16, %eax
19573 + movl 0x100+des_SPtrans(%ebx),%ebp
19574 + xorl %ebp, %esi
19575 + movb %ah, %bl
19576 + shrl $16, %edx
19577 + movl 0x300+des_SPtrans(%ecx),%ebp
19578 + xorl %ebp, %esi
19579 + movl 24(%esp), %ebp
19580 + movb %dh, %cl
19581 + andl $0xff, %eax
19582 + andl $0xff, %edx
19583 + movl 0x600+des_SPtrans(%ebx),%ebx
19584 + xorl %ebx, %esi
19585 + movl 0x700+des_SPtrans(%ecx),%ebx
19586 + xorl %ebx, %esi
19587 + movl 0x400+des_SPtrans(%eax),%ebx
19588 + xorl %ebx, %esi
19589 + movl 0x500+des_SPtrans(%edx),%ebx
19590 + xorl %ebx, %esi
19591 +
19592 +
19593 + movl 16(%ebp), %eax
19594 + xorl %ebx, %ebx
19595 + movl 20(%ebp), %edx
19596 + xorl %esi, %eax
19597 + xorl %esi, %edx
19598 + andl $0xfcfcfcfc, %eax
19599 + andl $0xcfcfcfcf, %edx
19600 + movb %al, %bl
19601 + movb %ah, %cl
19602 + rorl $4, %edx
19603 + movl des_SPtrans(%ebx),%ebp
19604 + movb %dl, %bl
19605 + xorl %ebp, %edi
19606 + movl 0x200+des_SPtrans(%ecx),%ebp
19607 + xorl %ebp, %edi
19608 + movb %dh, %cl
19609 + shrl $16, %eax
19610 + movl 0x100+des_SPtrans(%ebx),%ebp
19611 + xorl %ebp, %edi
19612 + movb %ah, %bl
19613 + shrl $16, %edx
19614 + movl 0x300+des_SPtrans(%ecx),%ebp
19615 + xorl %ebp, %edi
19616 + movl 24(%esp), %ebp
19617 + movb %dh, %cl
19618 + andl $0xff, %eax
19619 + andl $0xff, %edx
19620 + movl 0x600+des_SPtrans(%ebx),%ebx
19621 + xorl %ebx, %edi
19622 + movl 0x700+des_SPtrans(%ecx),%ebx
19623 + xorl %ebx, %edi
19624 + movl 0x400+des_SPtrans(%eax),%ebx
19625 + xorl %ebx, %edi
19626 + movl 0x500+des_SPtrans(%edx),%ebx
19627 + xorl %ebx, %edi
19628 +
19629 +
19630 + movl 24(%ebp), %eax
19631 + xorl %ebx, %ebx
19632 + movl 28(%ebp), %edx
19633 + xorl %edi, %eax
19634 + xorl %edi, %edx
19635 + andl $0xfcfcfcfc, %eax
19636 + andl $0xcfcfcfcf, %edx
19637 + movb %al, %bl
19638 + movb %ah, %cl
19639 + rorl $4, %edx
19640 + movl des_SPtrans(%ebx),%ebp
19641 + movb %dl, %bl
19642 + xorl %ebp, %esi
19643 + movl 0x200+des_SPtrans(%ecx),%ebp
19644 + xorl %ebp, %esi
19645 + movb %dh, %cl
19646 + shrl $16, %eax
19647 + movl 0x100+des_SPtrans(%ebx),%ebp
19648 + xorl %ebp, %esi
19649 + movb %ah, %bl
19650 + shrl $16, %edx
19651 + movl 0x300+des_SPtrans(%ecx),%ebp
19652 + xorl %ebp, %esi
19653 + movl 24(%esp), %ebp
19654 + movb %dh, %cl
19655 + andl $0xff, %eax
19656 + andl $0xff, %edx
19657 + movl 0x600+des_SPtrans(%ebx),%ebx
19658 + xorl %ebx, %esi
19659 + movl 0x700+des_SPtrans(%ecx),%ebx
19660 + xorl %ebx, %esi
19661 + movl 0x400+des_SPtrans(%eax),%ebx
19662 + xorl %ebx, %esi
19663 + movl 0x500+des_SPtrans(%edx),%ebx
19664 + xorl %ebx, %esi
19665 +
19666 +
19667 + movl 32(%ebp), %eax
19668 + xorl %ebx, %ebx
19669 + movl 36(%ebp), %edx
19670 + xorl %esi, %eax
19671 + xorl %esi, %edx
19672 + andl $0xfcfcfcfc, %eax
19673 + andl $0xcfcfcfcf, %edx
19674 + movb %al, %bl
19675 + movb %ah, %cl
19676 + rorl $4, %edx
19677 + movl des_SPtrans(%ebx),%ebp
19678 + movb %dl, %bl
19679 + xorl %ebp, %edi
19680 + movl 0x200+des_SPtrans(%ecx),%ebp
19681 + xorl %ebp, %edi
19682 + movb %dh, %cl
19683 + shrl $16, %eax
19684 + movl 0x100+des_SPtrans(%ebx),%ebp
19685 + xorl %ebp, %edi
19686 + movb %ah, %bl
19687 + shrl $16, %edx
19688 + movl 0x300+des_SPtrans(%ecx),%ebp
19689 + xorl %ebp, %edi
19690 + movl 24(%esp), %ebp
19691 + movb %dh, %cl
19692 + andl $0xff, %eax
19693 + andl $0xff, %edx
19694 + movl 0x600+des_SPtrans(%ebx),%ebx
19695 + xorl %ebx, %edi
19696 + movl 0x700+des_SPtrans(%ecx),%ebx
19697 + xorl %ebx, %edi
19698 + movl 0x400+des_SPtrans(%eax),%ebx
19699 + xorl %ebx, %edi
19700 + movl 0x500+des_SPtrans(%edx),%ebx
19701 + xorl %ebx, %edi
19702 +
19703 +
19704 + movl 40(%ebp), %eax
19705 + xorl %ebx, %ebx
19706 + movl 44(%ebp), %edx
19707 + xorl %edi, %eax
19708 + xorl %edi, %edx
19709 + andl $0xfcfcfcfc, %eax
19710 + andl $0xcfcfcfcf, %edx
19711 + movb %al, %bl
19712 + movb %ah, %cl
19713 + rorl $4, %edx
19714 + movl des_SPtrans(%ebx),%ebp
19715 + movb %dl, %bl
19716 + xorl %ebp, %esi
19717 + movl 0x200+des_SPtrans(%ecx),%ebp
19718 + xorl %ebp, %esi
19719 + movb %dh, %cl
19720 + shrl $16, %eax
19721 + movl 0x100+des_SPtrans(%ebx),%ebp
19722 + xorl %ebp, %esi
19723 + movb %ah, %bl
19724 + shrl $16, %edx
19725 + movl 0x300+des_SPtrans(%ecx),%ebp
19726 + xorl %ebp, %esi
19727 + movl 24(%esp), %ebp
19728 + movb %dh, %cl
19729 + andl $0xff, %eax
19730 + andl $0xff, %edx
19731 + movl 0x600+des_SPtrans(%ebx),%ebx
19732 + xorl %ebx, %esi
19733 + movl 0x700+des_SPtrans(%ecx),%ebx
19734 + xorl %ebx, %esi
19735 + movl 0x400+des_SPtrans(%eax),%ebx
19736 + xorl %ebx, %esi
19737 + movl 0x500+des_SPtrans(%edx),%ebx
19738 + xorl %ebx, %esi
19739 +
19740 +
19741 + movl 48(%ebp), %eax
19742 + xorl %ebx, %ebx
19743 + movl 52(%ebp), %edx
19744 + xorl %esi, %eax
19745 + xorl %esi, %edx
19746 + andl $0xfcfcfcfc, %eax
19747 + andl $0xcfcfcfcf, %edx
19748 + movb %al, %bl
19749 + movb %ah, %cl
19750 + rorl $4, %edx
19751 + movl des_SPtrans(%ebx),%ebp
19752 + movb %dl, %bl
19753 + xorl %ebp, %edi
19754 + movl 0x200+des_SPtrans(%ecx),%ebp
19755 + xorl %ebp, %edi
19756 + movb %dh, %cl
19757 + shrl $16, %eax
19758 + movl 0x100+des_SPtrans(%ebx),%ebp
19759 + xorl %ebp, %edi
19760 + movb %ah, %bl
19761 + shrl $16, %edx
19762 + movl 0x300+des_SPtrans(%ecx),%ebp
19763 + xorl %ebp, %edi
19764 + movl 24(%esp), %ebp
19765 + movb %dh, %cl
19766 + andl $0xff, %eax
19767 + andl $0xff, %edx
19768 + movl 0x600+des_SPtrans(%ebx),%ebx
19769 + xorl %ebx, %edi
19770 + movl 0x700+des_SPtrans(%ecx),%ebx
19771 + xorl %ebx, %edi
19772 + movl 0x400+des_SPtrans(%eax),%ebx
19773 + xorl %ebx, %edi
19774 + movl 0x500+des_SPtrans(%edx),%ebx
19775 + xorl %ebx, %edi
19776 +
19777 +
19778 + movl 56(%ebp), %eax
19779 + xorl %ebx, %ebx
19780 + movl 60(%ebp), %edx
19781 + xorl %edi, %eax
19782 + xorl %edi, %edx
19783 + andl $0xfcfcfcfc, %eax
19784 + andl $0xcfcfcfcf, %edx
19785 + movb %al, %bl
19786 + movb %ah, %cl
19787 + rorl $4, %edx
19788 + movl des_SPtrans(%ebx),%ebp
19789 + movb %dl, %bl
19790 + xorl %ebp, %esi
19791 + movl 0x200+des_SPtrans(%ecx),%ebp
19792 + xorl %ebp, %esi
19793 + movb %dh, %cl
19794 + shrl $16, %eax
19795 + movl 0x100+des_SPtrans(%ebx),%ebp
19796 + xorl %ebp, %esi
19797 + movb %ah, %bl
19798 + shrl $16, %edx
19799 + movl 0x300+des_SPtrans(%ecx),%ebp
19800 + xorl %ebp, %esi
19801 + movl 24(%esp), %ebp
19802 + movb %dh, %cl
19803 + andl $0xff, %eax
19804 + andl $0xff, %edx
19805 + movl 0x600+des_SPtrans(%ebx),%ebx
19806 + xorl %ebx, %esi
19807 + movl 0x700+des_SPtrans(%ecx),%ebx
19808 + xorl %ebx, %esi
19809 + movl 0x400+des_SPtrans(%eax),%ebx
19810 + xorl %ebx, %esi
19811 + movl 0x500+des_SPtrans(%edx),%ebx
19812 + xorl %ebx, %esi
19813 +
19814 +
19815 + movl 64(%ebp), %eax
19816 + xorl %ebx, %ebx
19817 + movl 68(%ebp), %edx
19818 + xorl %esi, %eax
19819 + xorl %esi, %edx
19820 + andl $0xfcfcfcfc, %eax
19821 + andl $0xcfcfcfcf, %edx
19822 + movb %al, %bl
19823 + movb %ah, %cl
19824 + rorl $4, %edx
19825 + movl des_SPtrans(%ebx),%ebp
19826 + movb %dl, %bl
19827 + xorl %ebp, %edi
19828 + movl 0x200+des_SPtrans(%ecx),%ebp
19829 + xorl %ebp, %edi
19830 + movb %dh, %cl
19831 + shrl $16, %eax
19832 + movl 0x100+des_SPtrans(%ebx),%ebp
19833 + xorl %ebp, %edi
19834 + movb %ah, %bl
19835 + shrl $16, %edx
19836 + movl 0x300+des_SPtrans(%ecx),%ebp
19837 + xorl %ebp, %edi
19838 + movl 24(%esp), %ebp
19839 + movb %dh, %cl
19840 + andl $0xff, %eax
19841 + andl $0xff, %edx
19842 + movl 0x600+des_SPtrans(%ebx),%ebx
19843 + xorl %ebx, %edi
19844 + movl 0x700+des_SPtrans(%ecx),%ebx
19845 + xorl %ebx, %edi
19846 + movl 0x400+des_SPtrans(%eax),%ebx
19847 + xorl %ebx, %edi
19848 + movl 0x500+des_SPtrans(%edx),%ebx
19849 + xorl %ebx, %edi
19850 +
19851 +
19852 + movl 72(%ebp), %eax
19853 + xorl %ebx, %ebx
19854 + movl 76(%ebp), %edx
19855 + xorl %edi, %eax
19856 + xorl %edi, %edx
19857 + andl $0xfcfcfcfc, %eax
19858 + andl $0xcfcfcfcf, %edx
19859 + movb %al, %bl
19860 + movb %ah, %cl
19861 + rorl $4, %edx
19862 + movl des_SPtrans(%ebx),%ebp
19863 + movb %dl, %bl
19864 + xorl %ebp, %esi
19865 + movl 0x200+des_SPtrans(%ecx),%ebp
19866 + xorl %ebp, %esi
19867 + movb %dh, %cl
19868 + shrl $16, %eax
19869 + movl 0x100+des_SPtrans(%ebx),%ebp
19870 + xorl %ebp, %esi
19871 + movb %ah, %bl
19872 + shrl $16, %edx
19873 + movl 0x300+des_SPtrans(%ecx),%ebp
19874 + xorl %ebp, %esi
19875 + movl 24(%esp), %ebp
19876 + movb %dh, %cl
19877 + andl $0xff, %eax
19878 + andl $0xff, %edx
19879 + movl 0x600+des_SPtrans(%ebx),%ebx
19880 + xorl %ebx, %esi
19881 + movl 0x700+des_SPtrans(%ecx),%ebx
19882 + xorl %ebx, %esi
19883 + movl 0x400+des_SPtrans(%eax),%ebx
19884 + xorl %ebx, %esi
19885 + movl 0x500+des_SPtrans(%edx),%ebx
19886 + xorl %ebx, %esi
19887 +
19888 +
19889 + movl 80(%ebp), %eax
19890 + xorl %ebx, %ebx
19891 + movl 84(%ebp), %edx
19892 + xorl %esi, %eax
19893 + xorl %esi, %edx
19894 + andl $0xfcfcfcfc, %eax
19895 + andl $0xcfcfcfcf, %edx
19896 + movb %al, %bl
19897 + movb %ah, %cl
19898 + rorl $4, %edx
19899 + movl des_SPtrans(%ebx),%ebp
19900 + movb %dl, %bl
19901 + xorl %ebp, %edi
19902 + movl 0x200+des_SPtrans(%ecx),%ebp
19903 + xorl %ebp, %edi
19904 + movb %dh, %cl
19905 + shrl $16, %eax
19906 + movl 0x100+des_SPtrans(%ebx),%ebp
19907 + xorl %ebp, %edi
19908 + movb %ah, %bl
19909 + shrl $16, %edx
19910 + movl 0x300+des_SPtrans(%ecx),%ebp
19911 + xorl %ebp, %edi
19912 + movl 24(%esp), %ebp
19913 + movb %dh, %cl
19914 + andl $0xff, %eax
19915 + andl $0xff, %edx
19916 + movl 0x600+des_SPtrans(%ebx),%ebx
19917 + xorl %ebx, %edi
19918 + movl 0x700+des_SPtrans(%ecx),%ebx
19919 + xorl %ebx, %edi
19920 + movl 0x400+des_SPtrans(%eax),%ebx
19921 + xorl %ebx, %edi
19922 + movl 0x500+des_SPtrans(%edx),%ebx
19923 + xorl %ebx, %edi
19924 +
19925 +
19926 + movl 88(%ebp), %eax
19927 + xorl %ebx, %ebx
19928 + movl 92(%ebp), %edx
19929 + xorl %edi, %eax
19930 + xorl %edi, %edx
19931 + andl $0xfcfcfcfc, %eax
19932 + andl $0xcfcfcfcf, %edx
19933 + movb %al, %bl
19934 + movb %ah, %cl
19935 + rorl $4, %edx
19936 + movl des_SPtrans(%ebx),%ebp
19937 + movb %dl, %bl
19938 + xorl %ebp, %esi
19939 + movl 0x200+des_SPtrans(%ecx),%ebp
19940 + xorl %ebp, %esi
19941 + movb %dh, %cl
19942 + shrl $16, %eax
19943 + movl 0x100+des_SPtrans(%ebx),%ebp
19944 + xorl %ebp, %esi
19945 + movb %ah, %bl
19946 + shrl $16, %edx
19947 + movl 0x300+des_SPtrans(%ecx),%ebp
19948 + xorl %ebp, %esi
19949 + movl 24(%esp), %ebp
19950 + movb %dh, %cl
19951 + andl $0xff, %eax
19952 + andl $0xff, %edx
19953 + movl 0x600+des_SPtrans(%ebx),%ebx
19954 + xorl %ebx, %esi
19955 + movl 0x700+des_SPtrans(%ecx),%ebx
19956 + xorl %ebx, %esi
19957 + movl 0x400+des_SPtrans(%eax),%ebx
19958 + xorl %ebx, %esi
19959 + movl 0x500+des_SPtrans(%edx),%ebx
19960 + xorl %ebx, %esi
19961 +
19962 +
19963 + movl 96(%ebp), %eax
19964 + xorl %ebx, %ebx
19965 + movl 100(%ebp), %edx
19966 + xorl %esi, %eax
19967 + xorl %esi, %edx
19968 + andl $0xfcfcfcfc, %eax
19969 + andl $0xcfcfcfcf, %edx
19970 + movb %al, %bl
19971 + movb %ah, %cl
19972 + rorl $4, %edx
19973 + movl des_SPtrans(%ebx),%ebp
19974 + movb %dl, %bl
19975 + xorl %ebp, %edi
19976 + movl 0x200+des_SPtrans(%ecx),%ebp
19977 + xorl %ebp, %edi
19978 + movb %dh, %cl
19979 + shrl $16, %eax
19980 + movl 0x100+des_SPtrans(%ebx),%ebp
19981 + xorl %ebp, %edi
19982 + movb %ah, %bl
19983 + shrl $16, %edx
19984 + movl 0x300+des_SPtrans(%ecx),%ebp
19985 + xorl %ebp, %edi
19986 + movl 24(%esp), %ebp
19987 + movb %dh, %cl
19988 + andl $0xff, %eax
19989 + andl $0xff, %edx
19990 + movl 0x600+des_SPtrans(%ebx),%ebx
19991 + xorl %ebx, %edi
19992 + movl 0x700+des_SPtrans(%ecx),%ebx
19993 + xorl %ebx, %edi
19994 + movl 0x400+des_SPtrans(%eax),%ebx
19995 + xorl %ebx, %edi
19996 + movl 0x500+des_SPtrans(%edx),%ebx
19997 + xorl %ebx, %edi
19998 +
19999 +
20000 + movl 104(%ebp), %eax
20001 + xorl %ebx, %ebx
20002 + movl 108(%ebp), %edx
20003 + xorl %edi, %eax
20004 + xorl %edi, %edx
20005 + andl $0xfcfcfcfc, %eax
20006 + andl $0xcfcfcfcf, %edx
20007 + movb %al, %bl
20008 + movb %ah, %cl
20009 + rorl $4, %edx
20010 + movl des_SPtrans(%ebx),%ebp
20011 + movb %dl, %bl
20012 + xorl %ebp, %esi
20013 + movl 0x200+des_SPtrans(%ecx),%ebp
20014 + xorl %ebp, %esi
20015 + movb %dh, %cl
20016 + shrl $16, %eax
20017 + movl 0x100+des_SPtrans(%ebx),%ebp
20018 + xorl %ebp, %esi
20019 + movb %ah, %bl
20020 + shrl $16, %edx
20021 + movl 0x300+des_SPtrans(%ecx),%ebp
20022 + xorl %ebp, %esi
20023 + movl 24(%esp), %ebp
20024 + movb %dh, %cl
20025 + andl $0xff, %eax
20026 + andl $0xff, %edx
20027 + movl 0x600+des_SPtrans(%ebx),%ebx
20028 + xorl %ebx, %esi
20029 + movl 0x700+des_SPtrans(%ecx),%ebx
20030 + xorl %ebx, %esi
20031 + movl 0x400+des_SPtrans(%eax),%ebx
20032 + xorl %ebx, %esi
20033 + movl 0x500+des_SPtrans(%edx),%ebx
20034 + xorl %ebx, %esi
20035 +
20036 +
20037 + movl 112(%ebp), %eax
20038 + xorl %ebx, %ebx
20039 + movl 116(%ebp), %edx
20040 + xorl %esi, %eax
20041 + xorl %esi, %edx
20042 + andl $0xfcfcfcfc, %eax
20043 + andl $0xcfcfcfcf, %edx
20044 + movb %al, %bl
20045 + movb %ah, %cl
20046 + rorl $4, %edx
20047 + movl des_SPtrans(%ebx),%ebp
20048 + movb %dl, %bl
20049 + xorl %ebp, %edi
20050 + movl 0x200+des_SPtrans(%ecx),%ebp
20051 + xorl %ebp, %edi
20052 + movb %dh, %cl
20053 + shrl $16, %eax
20054 + movl 0x100+des_SPtrans(%ebx),%ebp
20055 + xorl %ebp, %edi
20056 + movb %ah, %bl
20057 + shrl $16, %edx
20058 + movl 0x300+des_SPtrans(%ecx),%ebp
20059 + xorl %ebp, %edi
20060 + movl 24(%esp), %ebp
20061 + movb %dh, %cl
20062 + andl $0xff, %eax
20063 + andl $0xff, %edx
20064 + movl 0x600+des_SPtrans(%ebx),%ebx
20065 + xorl %ebx, %edi
20066 + movl 0x700+des_SPtrans(%ecx),%ebx
20067 + xorl %ebx, %edi
20068 + movl 0x400+des_SPtrans(%eax),%ebx
20069 + xorl %ebx, %edi
20070 + movl 0x500+des_SPtrans(%edx),%ebx
20071 + xorl %ebx, %edi
20072 +
20073 +
20074 + movl 120(%ebp), %eax
20075 + xorl %ebx, %ebx
20076 + movl 124(%ebp), %edx
20077 + xorl %edi, %eax
20078 + xorl %edi, %edx
20079 + andl $0xfcfcfcfc, %eax
20080 + andl $0xcfcfcfcf, %edx
20081 + movb %al, %bl
20082 + movb %ah, %cl
20083 + rorl $4, %edx
20084 + movl des_SPtrans(%ebx),%ebp
20085 + movb %dl, %bl
20086 + xorl %ebp, %esi
20087 + movl 0x200+des_SPtrans(%ecx),%ebp
20088 + xorl %ebp, %esi
20089 + movb %dh, %cl
20090 + shrl $16, %eax
20091 + movl 0x100+des_SPtrans(%ebx),%ebp
20092 + xorl %ebp, %esi
20093 + movb %ah, %bl
20094 + shrl $16, %edx
20095 + movl 0x300+des_SPtrans(%ecx),%ebp
20096 + xorl %ebp, %esi
20097 + movl 24(%esp), %ebp
20098 + movb %dh, %cl
20099 + andl $0xff, %eax
20100 + andl $0xff, %edx
20101 + movl 0x600+des_SPtrans(%ebx),%ebx
20102 + xorl %ebx, %esi
20103 + movl 0x700+des_SPtrans(%ecx),%ebx
20104 + xorl %ebx, %esi
20105 + movl 0x400+des_SPtrans(%eax),%ebx
20106 + xorl %ebx, %esi
20107 + movl 0x500+des_SPtrans(%edx),%ebx
20108 + xorl %ebx, %esi
20109 + jmp .L001end
20110 +.L000start_decrypt:
20111 +
20112 +
20113 + movl 120(%ebp), %eax
20114 + xorl %ebx, %ebx
20115 + movl 124(%ebp), %edx
20116 + xorl %esi, %eax
20117 + xorl %esi, %edx
20118 + andl $0xfcfcfcfc, %eax
20119 + andl $0xcfcfcfcf, %edx
20120 + movb %al, %bl
20121 + movb %ah, %cl
20122 + rorl $4, %edx
20123 + movl des_SPtrans(%ebx),%ebp
20124 + movb %dl, %bl
20125 + xorl %ebp, %edi
20126 + movl 0x200+des_SPtrans(%ecx),%ebp
20127 + xorl %ebp, %edi
20128 + movb %dh, %cl
20129 + shrl $16, %eax
20130 + movl 0x100+des_SPtrans(%ebx),%ebp
20131 + xorl %ebp, %edi
20132 + movb %ah, %bl
20133 + shrl $16, %edx
20134 + movl 0x300+des_SPtrans(%ecx),%ebp
20135 + xorl %ebp, %edi
20136 + movl 24(%esp), %ebp
20137 + movb %dh, %cl
20138 + andl $0xff, %eax
20139 + andl $0xff, %edx
20140 + movl 0x600+des_SPtrans(%ebx),%ebx
20141 + xorl %ebx, %edi
20142 + movl 0x700+des_SPtrans(%ecx),%ebx
20143 + xorl %ebx, %edi
20144 + movl 0x400+des_SPtrans(%eax),%ebx
20145 + xorl %ebx, %edi
20146 + movl 0x500+des_SPtrans(%edx),%ebx
20147 + xorl %ebx, %edi
20148 +
20149 +
20150 + movl 112(%ebp), %eax
20151 + xorl %ebx, %ebx
20152 + movl 116(%ebp), %edx
20153 + xorl %edi, %eax
20154 + xorl %edi, %edx
20155 + andl $0xfcfcfcfc, %eax
20156 + andl $0xcfcfcfcf, %edx
20157 + movb %al, %bl
20158 + movb %ah, %cl
20159 + rorl $4, %edx
20160 + movl des_SPtrans(%ebx),%ebp
20161 + movb %dl, %bl
20162 + xorl %ebp, %esi
20163 + movl 0x200+des_SPtrans(%ecx),%ebp
20164 + xorl %ebp, %esi
20165 + movb %dh, %cl
20166 + shrl $16, %eax
20167 + movl 0x100+des_SPtrans(%ebx),%ebp
20168 + xorl %ebp, %esi
20169 + movb %ah, %bl
20170 + shrl $16, %edx
20171 + movl 0x300+des_SPtrans(%ecx),%ebp
20172 + xorl %ebp, %esi
20173 + movl 24(%esp), %ebp
20174 + movb %dh, %cl
20175 + andl $0xff, %eax
20176 + andl $0xff, %edx
20177 + movl 0x600+des_SPtrans(%ebx),%ebx
20178 + xorl %ebx, %esi
20179 + movl 0x700+des_SPtrans(%ecx),%ebx
20180 + xorl %ebx, %esi
20181 + movl 0x400+des_SPtrans(%eax),%ebx
20182 + xorl %ebx, %esi
20183 + movl 0x500+des_SPtrans(%edx),%ebx
20184 + xorl %ebx, %esi
20185 +
20186 +
20187 + movl 104(%ebp), %eax
20188 + xorl %ebx, %ebx
20189 + movl 108(%ebp), %edx
20190 + xorl %esi, %eax
20191 + xorl %esi, %edx
20192 + andl $0xfcfcfcfc, %eax
20193 + andl $0xcfcfcfcf, %edx
20194 + movb %al, %bl
20195 + movb %ah, %cl
20196 + rorl $4, %edx
20197 + movl des_SPtrans(%ebx),%ebp
20198 + movb %dl, %bl
20199 + xorl %ebp, %edi
20200 + movl 0x200+des_SPtrans(%ecx),%ebp
20201 + xorl %ebp, %edi
20202 + movb %dh, %cl
20203 + shrl $16, %eax
20204 + movl 0x100+des_SPtrans(%ebx),%ebp
20205 + xorl %ebp, %edi
20206 + movb %ah, %bl
20207 + shrl $16, %edx
20208 + movl 0x300+des_SPtrans(%ecx),%ebp
20209 + xorl %ebp, %edi
20210 + movl 24(%esp), %ebp
20211 + movb %dh, %cl
20212 + andl $0xff, %eax
20213 + andl $0xff, %edx
20214 + movl 0x600+des_SPtrans(%ebx),%ebx
20215 + xorl %ebx, %edi
20216 + movl 0x700+des_SPtrans(%ecx),%ebx
20217 + xorl %ebx, %edi
20218 + movl 0x400+des_SPtrans(%eax),%ebx
20219 + xorl %ebx, %edi
20220 + movl 0x500+des_SPtrans(%edx),%ebx
20221 + xorl %ebx, %edi
20222 +
20223 +
20224 + movl 96(%ebp), %eax
20225 + xorl %ebx, %ebx
20226 + movl 100(%ebp), %edx
20227 + xorl %edi, %eax
20228 + xorl %edi, %edx
20229 + andl $0xfcfcfcfc, %eax
20230 + andl $0xcfcfcfcf, %edx
20231 + movb %al, %bl
20232 + movb %ah, %cl
20233 + rorl $4, %edx
20234 + movl des_SPtrans(%ebx),%ebp
20235 + movb %dl, %bl
20236 + xorl %ebp, %esi
20237 + movl 0x200+des_SPtrans(%ecx),%ebp
20238 + xorl %ebp, %esi
20239 + movb %dh, %cl
20240 + shrl $16, %eax
20241 + movl 0x100+des_SPtrans(%ebx),%ebp
20242 + xorl %ebp, %esi
20243 + movb %ah, %bl
20244 + shrl $16, %edx
20245 + movl 0x300+des_SPtrans(%ecx),%ebp
20246 + xorl %ebp, %esi
20247 + movl 24(%esp), %ebp
20248 + movb %dh, %cl
20249 + andl $0xff, %eax
20250 + andl $0xff, %edx
20251 + movl 0x600+des_SPtrans(%ebx),%ebx
20252 + xorl %ebx, %esi
20253 + movl 0x700+des_SPtrans(%ecx),%ebx
20254 + xorl %ebx, %esi
20255 + movl 0x400+des_SPtrans(%eax),%ebx
20256 + xorl %ebx, %esi
20257 + movl 0x500+des_SPtrans(%edx),%ebx
20258 + xorl %ebx, %esi
20259 +
20260 +
20261 + movl 88(%ebp), %eax
20262 + xorl %ebx, %ebx
20263 + movl 92(%ebp), %edx
20264 + xorl %esi, %eax
20265 + xorl %esi, %edx
20266 + andl $0xfcfcfcfc, %eax
20267 + andl $0xcfcfcfcf, %edx
20268 + movb %al, %bl
20269 + movb %ah, %cl
20270 + rorl $4, %edx
20271 + movl des_SPtrans(%ebx),%ebp
20272 + movb %dl, %bl
20273 + xorl %ebp, %edi
20274 + movl 0x200+des_SPtrans(%ecx),%ebp
20275 + xorl %ebp, %edi
20276 + movb %dh, %cl
20277 + shrl $16, %eax
20278 + movl 0x100+des_SPtrans(%ebx),%ebp
20279 + xorl %ebp, %edi
20280 + movb %ah, %bl
20281 + shrl $16, %edx
20282 + movl 0x300+des_SPtrans(%ecx),%ebp
20283 + xorl %ebp, %edi
20284 + movl 24(%esp), %ebp
20285 + movb %dh, %cl
20286 + andl $0xff, %eax
20287 + andl $0xff, %edx
20288 + movl 0x600+des_SPtrans(%ebx),%ebx
20289 + xorl %ebx, %edi
20290 + movl 0x700+des_SPtrans(%ecx),%ebx
20291 + xorl %ebx, %edi
20292 + movl 0x400+des_SPtrans(%eax),%ebx
20293 + xorl %ebx, %edi
20294 + movl 0x500+des_SPtrans(%edx),%ebx
20295 + xorl %ebx, %edi
20296 +
20297 +
20298 + movl 80(%ebp), %eax
20299 + xorl %ebx, %ebx
20300 + movl 84(%ebp), %edx
20301 + xorl %edi, %eax
20302 + xorl %edi, %edx
20303 + andl $0xfcfcfcfc, %eax
20304 + andl $0xcfcfcfcf, %edx
20305 + movb %al, %bl
20306 + movb %ah, %cl
20307 + rorl $4, %edx
20308 + movl des_SPtrans(%ebx),%ebp
20309 + movb %dl, %bl
20310 + xorl %ebp, %esi
20311 + movl 0x200+des_SPtrans(%ecx),%ebp
20312 + xorl %ebp, %esi
20313 + movb %dh, %cl
20314 + shrl $16, %eax
20315 + movl 0x100+des_SPtrans(%ebx),%ebp
20316 + xorl %ebp, %esi
20317 + movb %ah, %bl
20318 + shrl $16, %edx
20319 + movl 0x300+des_SPtrans(%ecx),%ebp
20320 + xorl %ebp, %esi
20321 + movl 24(%esp), %ebp
20322 + movb %dh, %cl
20323 + andl $0xff, %eax
20324 + andl $0xff, %edx
20325 + movl 0x600+des_SPtrans(%ebx),%ebx
20326 + xorl %ebx, %esi
20327 + movl 0x700+des_SPtrans(%ecx),%ebx
20328 + xorl %ebx, %esi
20329 + movl 0x400+des_SPtrans(%eax),%ebx
20330 + xorl %ebx, %esi
20331 + movl 0x500+des_SPtrans(%edx),%ebx
20332 + xorl %ebx, %esi
20333 +
20334 +
20335 + movl 72(%ebp), %eax
20336 + xorl %ebx, %ebx
20337 + movl 76(%ebp), %edx
20338 + xorl %esi, %eax
20339 + xorl %esi, %edx
20340 + andl $0xfcfcfcfc, %eax
20341 + andl $0xcfcfcfcf, %edx
20342 + movb %al, %bl
20343 + movb %ah, %cl
20344 + rorl $4, %edx
20345 + movl des_SPtrans(%ebx),%ebp
20346 + movb %dl, %bl
20347 + xorl %ebp, %edi
20348 + movl 0x200+des_SPtrans(%ecx),%ebp
20349 + xorl %ebp, %edi
20350 + movb %dh, %cl
20351 + shrl $16, %eax
20352 + movl 0x100+des_SPtrans(%ebx),%ebp
20353 + xorl %ebp, %edi
20354 + movb %ah, %bl
20355 + shrl $16, %edx
20356 + movl 0x300+des_SPtrans(%ecx),%ebp
20357 + xorl %ebp, %edi
20358 + movl 24(%esp), %ebp
20359 + movb %dh, %cl
20360 + andl $0xff, %eax
20361 + andl $0xff, %edx
20362 + movl 0x600+des_SPtrans(%ebx),%ebx
20363 + xorl %ebx, %edi
20364 + movl 0x700+des_SPtrans(%ecx),%ebx
20365 + xorl %ebx, %edi
20366 + movl 0x400+des_SPtrans(%eax),%ebx
20367 + xorl %ebx, %edi
20368 + movl 0x500+des_SPtrans(%edx),%ebx
20369 + xorl %ebx, %edi
20370 +
20371 +
20372 + movl 64(%ebp), %eax
20373 + xorl %ebx, %ebx
20374 + movl 68(%ebp), %edx
20375 + xorl %edi, %eax
20376 + xorl %edi, %edx
20377 + andl $0xfcfcfcfc, %eax
20378 + andl $0xcfcfcfcf, %edx
20379 + movb %al, %bl
20380 + movb %ah, %cl
20381 + rorl $4, %edx
20382 + movl des_SPtrans(%ebx),%ebp
20383 + movb %dl, %bl
20384 + xorl %ebp, %esi
20385 + movl 0x200+des_SPtrans(%ecx),%ebp
20386 + xorl %ebp, %esi
20387 + movb %dh, %cl
20388 + shrl $16, %eax
20389 + movl 0x100+des_SPtrans(%ebx),%ebp
20390 + xorl %ebp, %esi
20391 + movb %ah, %bl
20392 + shrl $16, %edx
20393 + movl 0x300+des_SPtrans(%ecx),%ebp
20394 + xorl %ebp, %esi
20395 + movl 24(%esp), %ebp
20396 + movb %dh, %cl
20397 + andl $0xff, %eax
20398 + andl $0xff, %edx
20399 + movl 0x600+des_SPtrans(%ebx),%ebx
20400 + xorl %ebx, %esi
20401 + movl 0x700+des_SPtrans(%ecx),%ebx
20402 + xorl %ebx, %esi
20403 + movl 0x400+des_SPtrans(%eax),%ebx
20404 + xorl %ebx, %esi
20405 + movl 0x500+des_SPtrans(%edx),%ebx
20406 + xorl %ebx, %esi
20407 +
20408 +
20409 + movl 56(%ebp), %eax
20410 + xorl %ebx, %ebx
20411 + movl 60(%ebp), %edx
20412 + xorl %esi, %eax
20413 + xorl %esi, %edx
20414 + andl $0xfcfcfcfc, %eax
20415 + andl $0xcfcfcfcf, %edx
20416 + movb %al, %bl
20417 + movb %ah, %cl
20418 + rorl $4, %edx
20419 + movl des_SPtrans(%ebx),%ebp
20420 + movb %dl, %bl
20421 + xorl %ebp, %edi
20422 + movl 0x200+des_SPtrans(%ecx),%ebp
20423 + xorl %ebp, %edi
20424 + movb %dh, %cl
20425 + shrl $16, %eax
20426 + movl 0x100+des_SPtrans(%ebx),%ebp
20427 + xorl %ebp, %edi
20428 + movb %ah, %bl
20429 + shrl $16, %edx
20430 + movl 0x300+des_SPtrans(%ecx),%ebp
20431 + xorl %ebp, %edi
20432 + movl 24(%esp), %ebp
20433 + movb %dh, %cl
20434 + andl $0xff, %eax
20435 + andl $0xff, %edx
20436 + movl 0x600+des_SPtrans(%ebx),%ebx
20437 + xorl %ebx, %edi
20438 + movl 0x700+des_SPtrans(%ecx),%ebx
20439 + xorl %ebx, %edi
20440 + movl 0x400+des_SPtrans(%eax),%ebx
20441 + xorl %ebx, %edi
20442 + movl 0x500+des_SPtrans(%edx),%ebx
20443 + xorl %ebx, %edi
20444 +
20445 +
20446 + movl 48(%ebp), %eax
20447 + xorl %ebx, %ebx
20448 + movl 52(%ebp), %edx
20449 + xorl %edi, %eax
20450 + xorl %edi, %edx
20451 + andl $0xfcfcfcfc, %eax
20452 + andl $0xcfcfcfcf, %edx
20453 + movb %al, %bl
20454 + movb %ah, %cl
20455 + rorl $4, %edx
20456 + movl des_SPtrans(%ebx),%ebp
20457 + movb %dl, %bl
20458 + xorl %ebp, %esi
20459 + movl 0x200+des_SPtrans(%ecx),%ebp
20460 + xorl %ebp, %esi
20461 + movb %dh, %cl
20462 + shrl $16, %eax
20463 + movl 0x100+des_SPtrans(%ebx),%ebp
20464 + xorl %ebp, %esi
20465 + movb %ah, %bl
20466 + shrl $16, %edx
20467 + movl 0x300+des_SPtrans(%ecx),%ebp
20468 + xorl %ebp, %esi
20469 + movl 24(%esp), %ebp
20470 + movb %dh, %cl
20471 + andl $0xff, %eax
20472 + andl $0xff, %edx
20473 + movl 0x600+des_SPtrans(%ebx),%ebx
20474 + xorl %ebx, %esi
20475 + movl 0x700+des_SPtrans(%ecx),%ebx
20476 + xorl %ebx, %esi
20477 + movl 0x400+des_SPtrans(%eax),%ebx
20478 + xorl %ebx, %esi
20479 + movl 0x500+des_SPtrans(%edx),%ebx
20480 + xorl %ebx, %esi
20481 +
20482 +
20483 + movl 40(%ebp), %eax
20484 + xorl %ebx, %ebx
20485 + movl 44(%ebp), %edx
20486 + xorl %esi, %eax
20487 + xorl %esi, %edx
20488 + andl $0xfcfcfcfc, %eax
20489 + andl $0xcfcfcfcf, %edx
20490 + movb %al, %bl
20491 + movb %ah, %cl
20492 + rorl $4, %edx
20493 + movl des_SPtrans(%ebx),%ebp
20494 + movb %dl, %bl
20495 + xorl %ebp, %edi
20496 + movl 0x200+des_SPtrans(%ecx),%ebp
20497 + xorl %ebp, %edi
20498 + movb %dh, %cl
20499 + shrl $16, %eax
20500 + movl 0x100+des_SPtrans(%ebx),%ebp
20501 + xorl %ebp, %edi
20502 + movb %ah, %bl
20503 + shrl $16, %edx
20504 + movl 0x300+des_SPtrans(%ecx),%ebp
20505 + xorl %ebp, %edi
20506 + movl 24(%esp), %ebp
20507 + movb %dh, %cl
20508 + andl $0xff, %eax
20509 + andl $0xff, %edx
20510 + movl 0x600+des_SPtrans(%ebx),%ebx
20511 + xorl %ebx, %edi
20512 + movl 0x700+des_SPtrans(%ecx),%ebx
20513 + xorl %ebx, %edi
20514 + movl 0x400+des_SPtrans(%eax),%ebx
20515 + xorl %ebx, %edi
20516 + movl 0x500+des_SPtrans(%edx),%ebx
20517 + xorl %ebx, %edi
20518 +
20519 +
20520 + movl 32(%ebp), %eax
20521 + xorl %ebx, %ebx
20522 + movl 36(%ebp), %edx
20523 + xorl %edi, %eax
20524 + xorl %edi, %edx
20525 + andl $0xfcfcfcfc, %eax
20526 + andl $0xcfcfcfcf, %edx
20527 + movb %al, %bl
20528 + movb %ah, %cl
20529 + rorl $4, %edx
20530 + movl des_SPtrans(%ebx),%ebp
20531 + movb %dl, %bl
20532 + xorl %ebp, %esi
20533 + movl 0x200+des_SPtrans(%ecx),%ebp
20534 + xorl %ebp, %esi
20535 + movb %dh, %cl
20536 + shrl $16, %eax
20537 + movl 0x100+des_SPtrans(%ebx),%ebp
20538 + xorl %ebp, %esi
20539 + movb %ah, %bl
20540 + shrl $16, %edx
20541 + movl 0x300+des_SPtrans(%ecx),%ebp
20542 + xorl %ebp, %esi
20543 + movl 24(%esp), %ebp
20544 + movb %dh, %cl
20545 + andl $0xff, %eax
20546 + andl $0xff, %edx
20547 + movl 0x600+des_SPtrans(%ebx),%ebx
20548 + xorl %ebx, %esi
20549 + movl 0x700+des_SPtrans(%ecx),%ebx
20550 + xorl %ebx, %esi
20551 + movl 0x400+des_SPtrans(%eax),%ebx
20552 + xorl %ebx, %esi
20553 + movl 0x500+des_SPtrans(%edx),%ebx
20554 + xorl %ebx, %esi
20555 +
20556 +
20557 + movl 24(%ebp), %eax
20558 + xorl %ebx, %ebx
20559 + movl 28(%ebp), %edx
20560 + xorl %esi, %eax
20561 + xorl %esi, %edx
20562 + andl $0xfcfcfcfc, %eax
20563 + andl $0xcfcfcfcf, %edx
20564 + movb %al, %bl
20565 + movb %ah, %cl
20566 + rorl $4, %edx
20567 + movl des_SPtrans(%ebx),%ebp
20568 + movb %dl, %bl
20569 + xorl %ebp, %edi
20570 + movl 0x200+des_SPtrans(%ecx),%ebp
20571 + xorl %ebp, %edi
20572 + movb %dh, %cl
20573 + shrl $16, %eax
20574 + movl 0x100+des_SPtrans(%ebx),%ebp
20575 + xorl %ebp, %edi
20576 + movb %ah, %bl
20577 + shrl $16, %edx
20578 + movl 0x300+des_SPtrans(%ecx),%ebp
20579 + xorl %ebp, %edi
20580 + movl 24(%esp), %ebp
20581 + movb %dh, %cl
20582 + andl $0xff, %eax
20583 + andl $0xff, %edx
20584 + movl 0x600+des_SPtrans(%ebx),%ebx
20585 + xorl %ebx, %edi
20586 + movl 0x700+des_SPtrans(%ecx),%ebx
20587 + xorl %ebx, %edi
20588 + movl 0x400+des_SPtrans(%eax),%ebx
20589 + xorl %ebx, %edi
20590 + movl 0x500+des_SPtrans(%edx),%ebx
20591 + xorl %ebx, %edi
20592 +
20593 +
20594 + movl 16(%ebp), %eax
20595 + xorl %ebx, %ebx
20596 + movl 20(%ebp), %edx
20597 + xorl %edi, %eax
20598 + xorl %edi, %edx
20599 + andl $0xfcfcfcfc, %eax
20600 + andl $0xcfcfcfcf, %edx
20601 + movb %al, %bl
20602 + movb %ah, %cl
20603 + rorl $4, %edx
20604 + movl des_SPtrans(%ebx),%ebp
20605 + movb %dl, %bl
20606 + xorl %ebp, %esi
20607 + movl 0x200+des_SPtrans(%ecx),%ebp
20608 + xorl %ebp, %esi
20609 + movb %dh, %cl
20610 + shrl $16, %eax
20611 + movl 0x100+des_SPtrans(%ebx),%ebp
20612 + xorl %ebp, %esi
20613 + movb %ah, %bl
20614 + shrl $16, %edx
20615 + movl 0x300+des_SPtrans(%ecx),%ebp
20616 + xorl %ebp, %esi
20617 + movl 24(%esp), %ebp
20618 + movb %dh, %cl
20619 + andl $0xff, %eax
20620 + andl $0xff, %edx
20621 + movl 0x600+des_SPtrans(%ebx),%ebx
20622 + xorl %ebx, %esi
20623 + movl 0x700+des_SPtrans(%ecx),%ebx
20624 + xorl %ebx, %esi
20625 + movl 0x400+des_SPtrans(%eax),%ebx
20626 + xorl %ebx, %esi
20627 + movl 0x500+des_SPtrans(%edx),%ebx
20628 + xorl %ebx, %esi
20629 +
20630 +
20631 + movl 8(%ebp), %eax
20632 + xorl %ebx, %ebx
20633 + movl 12(%ebp), %edx
20634 + xorl %esi, %eax
20635 + xorl %esi, %edx
20636 + andl $0xfcfcfcfc, %eax
20637 + andl $0xcfcfcfcf, %edx
20638 + movb %al, %bl
20639 + movb %ah, %cl
20640 + rorl $4, %edx
20641 + movl des_SPtrans(%ebx),%ebp
20642 + movb %dl, %bl
20643 + xorl %ebp, %edi
20644 + movl 0x200+des_SPtrans(%ecx),%ebp
20645 + xorl %ebp, %edi
20646 + movb %dh, %cl
20647 + shrl $16, %eax
20648 + movl 0x100+des_SPtrans(%ebx),%ebp
20649 + xorl %ebp, %edi
20650 + movb %ah, %bl
20651 + shrl $16, %edx
20652 + movl 0x300+des_SPtrans(%ecx),%ebp
20653 + xorl %ebp, %edi
20654 + movl 24(%esp), %ebp
20655 + movb %dh, %cl
20656 + andl $0xff, %eax
20657 + andl $0xff, %edx
20658 + movl 0x600+des_SPtrans(%ebx),%ebx
20659 + xorl %ebx, %edi
20660 + movl 0x700+des_SPtrans(%ecx),%ebx
20661 + xorl %ebx, %edi
20662 + movl 0x400+des_SPtrans(%eax),%ebx
20663 + xorl %ebx, %edi
20664 + movl 0x500+des_SPtrans(%edx),%ebx
20665 + xorl %ebx, %edi
20666 +
20667 +
20668 + movl (%ebp), %eax
20669 + xorl %ebx, %ebx
20670 + movl 4(%ebp), %edx
20671 + xorl %edi, %eax
20672 + xorl %edi, %edx
20673 + andl $0xfcfcfcfc, %eax
20674 + andl $0xcfcfcfcf, %edx
20675 + movb %al, %bl
20676 + movb %ah, %cl
20677 + rorl $4, %edx
20678 + movl des_SPtrans(%ebx),%ebp
20679 + movb %dl, %bl
20680 + xorl %ebp, %esi
20681 + movl 0x200+des_SPtrans(%ecx),%ebp
20682 + xorl %ebp, %esi
20683 + movb %dh, %cl
20684 + shrl $16, %eax
20685 + movl 0x100+des_SPtrans(%ebx),%ebp
20686 + xorl %ebp, %esi
20687 + movb %ah, %bl
20688 + shrl $16, %edx
20689 + movl 0x300+des_SPtrans(%ecx),%ebp
20690 + xorl %ebp, %esi
20691 + movl 24(%esp), %ebp
20692 + movb %dh, %cl
20693 + andl $0xff, %eax
20694 + andl $0xff, %edx
20695 + movl 0x600+des_SPtrans(%ebx),%ebx
20696 + xorl %ebx, %esi
20697 + movl 0x700+des_SPtrans(%ecx),%ebx
20698 + xorl %ebx, %esi
20699 + movl 0x400+des_SPtrans(%eax),%ebx
20700 + xorl %ebx, %esi
20701 + movl 0x500+des_SPtrans(%edx),%ebx
20702 + xorl %ebx, %esi
20703 +.L001end:
20704 +
20705 +
20706 + movl 20(%esp), %edx
20707 +.byte 209
20708 +.byte 206
20709 + movl %edi, %eax
20710 + xorl %esi, %edi
20711 + andl $0xaaaaaaaa, %edi
20712 + xorl %edi, %eax
20713 + xorl %edi, %esi
20714 +
20715 + roll $23, %eax
20716 + movl %eax, %edi
20717 + xorl %esi, %eax
20718 + andl $0x03fc03fc, %eax
20719 + xorl %eax, %edi
20720 + xorl %eax, %esi
20721 +
20722 + roll $10, %edi
20723 + movl %edi, %eax
20724 + xorl %esi, %edi
20725 + andl $0x33333333, %edi
20726 + xorl %edi, %eax
20727 + xorl %edi, %esi
20728 +
20729 + roll $18, %esi
20730 + movl %esi, %edi
20731 + xorl %eax, %esi
20732 + andl $0xfff0000f, %esi
20733 + xorl %esi, %edi
20734 + xorl %esi, %eax
20735 +
20736 + roll $12, %edi
20737 + movl %edi, %esi
20738 + xorl %eax, %edi
20739 + andl $0xf0f0f0f0, %edi
20740 + xorl %edi, %esi
20741 + xorl %edi, %eax
20742 +
20743 + rorl $4, %eax
20744 + movl %eax, (%edx)
20745 + movl %esi, 4(%edx)
20746 + popl %ebp
20747 + popl %ebx
20748 + popl %edi
20749 + popl %esi
20750 + ret
20751 +.des_encrypt_end:
20752 + .size des_encrypt , .des_encrypt_end-des_encrypt
20753 +.ident "desasm.pl"
20754 +.text
20755 + .align 16
20756 +.globl des_encrypt2
20757 + .type des_encrypt2 , @function
20758 +des_encrypt2:
20759 + pushl %esi
20760 + pushl %edi
20761 +
20762 +
20763 + movl 12(%esp), %eax
20764 + xorl %ecx, %ecx
20765 + pushl %ebx
20766 + pushl %ebp
20767 + movl (%eax), %esi
20768 + movl 28(%esp), %ebx
20769 + roll $3, %esi
20770 + movl 4(%eax), %edi
20771 + roll $3, %edi
20772 + movl 24(%esp), %ebp
20773 + cmpl $0, %ebx
20774 + je .L002start_decrypt
20775 +
20776 +
20777 + movl (%ebp), %eax
20778 + xorl %ebx, %ebx
20779 + movl 4(%ebp), %edx
20780 + xorl %esi, %eax
20781 + xorl %esi, %edx
20782 + andl $0xfcfcfcfc, %eax
20783 + andl $0xcfcfcfcf, %edx
20784 + movb %al, %bl
20785 + movb %ah, %cl
20786 + rorl $4, %edx
20787 + movl des_SPtrans(%ebx),%ebp
20788 + movb %dl, %bl
20789 + xorl %ebp, %edi
20790 + movl 0x200+des_SPtrans(%ecx),%ebp
20791 + xorl %ebp, %edi
20792 + movb %dh, %cl
20793 + shrl $16, %eax
20794 + movl 0x100+des_SPtrans(%ebx),%ebp
20795 + xorl %ebp, %edi
20796 + movb %ah, %bl
20797 + shrl $16, %edx
20798 + movl 0x300+des_SPtrans(%ecx),%ebp
20799 + xorl %ebp, %edi
20800 + movl 24(%esp), %ebp
20801 + movb %dh, %cl
20802 + andl $0xff, %eax
20803 + andl $0xff, %edx
20804 + movl 0x600+des_SPtrans(%ebx),%ebx
20805 + xorl %ebx, %edi
20806 + movl 0x700+des_SPtrans(%ecx),%ebx
20807 + xorl %ebx, %edi
20808 + movl 0x400+des_SPtrans(%eax),%ebx
20809 + xorl %ebx, %edi
20810 + movl 0x500+des_SPtrans(%edx),%ebx
20811 + xorl %ebx, %edi
20812 +
20813 +
20814 + movl 8(%ebp), %eax
20815 + xorl %ebx, %ebx
20816 + movl 12(%ebp), %edx
20817 + xorl %edi, %eax
20818 + xorl %edi, %edx
20819 + andl $0xfcfcfcfc, %eax
20820 + andl $0xcfcfcfcf, %edx
20821 + movb %al, %bl
20822 + movb %ah, %cl
20823 + rorl $4, %edx
20824 + movl des_SPtrans(%ebx),%ebp
20825 + movb %dl, %bl
20826 + xorl %ebp, %esi
20827 + movl 0x200+des_SPtrans(%ecx),%ebp
20828 + xorl %ebp, %esi
20829 + movb %dh, %cl
20830 + shrl $16, %eax
20831 + movl 0x100+des_SPtrans(%ebx),%ebp
20832 + xorl %ebp, %esi
20833 + movb %ah, %bl
20834 + shrl $16, %edx
20835 + movl 0x300+des_SPtrans(%ecx),%ebp
20836 + xorl %ebp, %esi
20837 + movl 24(%esp), %ebp
20838 + movb %dh, %cl
20839 + andl $0xff, %eax
20840 + andl $0xff, %edx
20841 + movl 0x600+des_SPtrans(%ebx),%ebx
20842 + xorl %ebx, %esi
20843 + movl 0x700+des_SPtrans(%ecx),%ebx
20844 + xorl %ebx, %esi
20845 + movl 0x400+des_SPtrans(%eax),%ebx
20846 + xorl %ebx, %esi
20847 + movl 0x500+des_SPtrans(%edx),%ebx
20848 + xorl %ebx, %esi
20849 +
20850 +
20851 + movl 16(%ebp), %eax
20852 + xorl %ebx, %ebx
20853 + movl 20(%ebp), %edx
20854 + xorl %esi, %eax
20855 + xorl %esi, %edx
20856 + andl $0xfcfcfcfc, %eax
20857 + andl $0xcfcfcfcf, %edx
20858 + movb %al, %bl
20859 + movb %ah, %cl
20860 + rorl $4, %edx
20861 + movl des_SPtrans(%ebx),%ebp
20862 + movb %dl, %bl
20863 + xorl %ebp, %edi
20864 + movl 0x200+des_SPtrans(%ecx),%ebp
20865 + xorl %ebp, %edi
20866 + movb %dh, %cl
20867 + shrl $16, %eax
20868 + movl 0x100+des_SPtrans(%ebx),%ebp
20869 + xorl %ebp, %edi
20870 + movb %ah, %bl
20871 + shrl $16, %edx
20872 + movl 0x300+des_SPtrans(%ecx),%ebp
20873 + xorl %ebp, %edi
20874 + movl 24(%esp), %ebp
20875 + movb %dh, %cl
20876 + andl $0xff, %eax
20877 + andl $0xff, %edx
20878 + movl 0x600+des_SPtrans(%ebx),%ebx
20879 + xorl %ebx, %edi
20880 + movl 0x700+des_SPtrans(%ecx),%ebx
20881 + xorl %ebx, %edi
20882 + movl 0x400+des_SPtrans(%eax),%ebx
20883 + xorl %ebx, %edi
20884 + movl 0x500+des_SPtrans(%edx),%ebx
20885 + xorl %ebx, %edi
20886 +
20887 +
20888 + movl 24(%ebp), %eax
20889 + xorl %ebx, %ebx
20890 + movl 28(%ebp), %edx
20891 + xorl %edi, %eax
20892 + xorl %edi, %edx
20893 + andl $0xfcfcfcfc, %eax
20894 + andl $0xcfcfcfcf, %edx
20895 + movb %al, %bl
20896 + movb %ah, %cl
20897 + rorl $4, %edx
20898 + movl des_SPtrans(%ebx),%ebp
20899 + movb %dl, %bl
20900 + xorl %ebp, %esi
20901 + movl 0x200+des_SPtrans(%ecx),%ebp
20902 + xorl %ebp, %esi
20903 + movb %dh, %cl
20904 + shrl $16, %eax
20905 + movl 0x100+des_SPtrans(%ebx),%ebp
20906 + xorl %ebp, %esi
20907 + movb %ah, %bl
20908 + shrl $16, %edx
20909 + movl 0x300+des_SPtrans(%ecx),%ebp
20910 + xorl %ebp, %esi
20911 + movl 24(%esp), %ebp
20912 + movb %dh, %cl
20913 + andl $0xff, %eax
20914 + andl $0xff, %edx
20915 + movl 0x600+des_SPtrans(%ebx),%ebx
20916 + xorl %ebx, %esi
20917 + movl 0x700+des_SPtrans(%ecx),%ebx
20918 + xorl %ebx, %esi
20919 + movl 0x400+des_SPtrans(%eax),%ebx
20920 + xorl %ebx, %esi
20921 + movl 0x500+des_SPtrans(%edx),%ebx
20922 + xorl %ebx, %esi
20923 +
20924 +
20925 + movl 32(%ebp), %eax
20926 + xorl %ebx, %ebx
20927 + movl 36(%ebp), %edx
20928 + xorl %esi, %eax
20929 + xorl %esi, %edx
20930 + andl $0xfcfcfcfc, %eax
20931 + andl $0xcfcfcfcf, %edx
20932 + movb %al, %bl
20933 + movb %ah, %cl
20934 + rorl $4, %edx
20935 + movl des_SPtrans(%ebx),%ebp
20936 + movb %dl, %bl
20937 + xorl %ebp, %edi
20938 + movl 0x200+des_SPtrans(%ecx),%ebp
20939 + xorl %ebp, %edi
20940 + movb %dh, %cl
20941 + shrl $16, %eax
20942 + movl 0x100+des_SPtrans(%ebx),%ebp
20943 + xorl %ebp, %edi
20944 + movb %ah, %bl
20945 + shrl $16, %edx
20946 + movl 0x300+des_SPtrans(%ecx),%ebp
20947 + xorl %ebp, %edi
20948 + movl 24(%esp), %ebp
20949 + movb %dh, %cl
20950 + andl $0xff, %eax
20951 + andl $0xff, %edx
20952 + movl 0x600+des_SPtrans(%ebx),%ebx
20953 + xorl %ebx, %edi
20954 + movl 0x700+des_SPtrans(%ecx),%ebx
20955 + xorl %ebx, %edi
20956 + movl 0x400+des_SPtrans(%eax),%ebx
20957 + xorl %ebx, %edi
20958 + movl 0x500+des_SPtrans(%edx),%ebx
20959 + xorl %ebx, %edi
20960 +
20961 +
20962 + movl 40(%ebp), %eax
20963 + xorl %ebx, %ebx
20964 + movl 44(%ebp), %edx
20965 + xorl %edi, %eax
20966 + xorl %edi, %edx
20967 + andl $0xfcfcfcfc, %eax
20968 + andl $0xcfcfcfcf, %edx
20969 + movb %al, %bl
20970 + movb %ah, %cl
20971 + rorl $4, %edx
20972 + movl des_SPtrans(%ebx),%ebp
20973 + movb %dl, %bl
20974 + xorl %ebp, %esi
20975 + movl 0x200+des_SPtrans(%ecx),%ebp
20976 + xorl %ebp, %esi
20977 + movb %dh, %cl
20978 + shrl $16, %eax
20979 + movl 0x100+des_SPtrans(%ebx),%ebp
20980 + xorl %ebp, %esi
20981 + movb %ah, %bl
20982 + shrl $16, %edx
20983 + movl 0x300+des_SPtrans(%ecx),%ebp
20984 + xorl %ebp, %esi
20985 + movl 24(%esp), %ebp
20986 + movb %dh, %cl
20987 + andl $0xff, %eax
20988 + andl $0xff, %edx
20989 + movl 0x600+des_SPtrans(%ebx),%ebx
20990 + xorl %ebx, %esi
20991 + movl 0x700+des_SPtrans(%ecx),%ebx
20992 + xorl %ebx, %esi
20993 + movl 0x400+des_SPtrans(%eax),%ebx
20994 + xorl %ebx, %esi
20995 + movl 0x500+des_SPtrans(%edx),%ebx
20996 + xorl %ebx, %esi
20997 +
20998 +
20999 + movl 48(%ebp), %eax
21000 + xorl %ebx, %ebx
21001 + movl 52(%ebp), %edx
21002 + xorl %esi, %eax
21003 + xorl %esi, %edx
21004 + andl $0xfcfcfcfc, %eax
21005 + andl $0xcfcfcfcf, %edx
21006 + movb %al, %bl
21007 + movb %ah, %cl
21008 + rorl $4, %edx
21009 + movl des_SPtrans(%ebx),%ebp
21010 + movb %dl, %bl
21011 + xorl %ebp, %edi
21012 + movl 0x200+des_SPtrans(%ecx),%ebp
21013 + xorl %ebp, %edi
21014 + movb %dh, %cl
21015 + shrl $16, %eax
21016 + movl 0x100+des_SPtrans(%ebx),%ebp
21017 + xorl %ebp, %edi
21018 + movb %ah, %bl
21019 + shrl $16, %edx
21020 + movl 0x300+des_SPtrans(%ecx),%ebp
21021 + xorl %ebp, %edi
21022 + movl 24(%esp), %ebp
21023 + movb %dh, %cl
21024 + andl $0xff, %eax
21025 + andl $0xff, %edx
21026 + movl 0x600+des_SPtrans(%ebx),%ebx
21027 + xorl %ebx, %edi
21028 + movl 0x700+des_SPtrans(%ecx),%ebx
21029 + xorl %ebx, %edi
21030 + movl 0x400+des_SPtrans(%eax),%ebx
21031 + xorl %ebx, %edi
21032 + movl 0x500+des_SPtrans(%edx),%ebx
21033 + xorl %ebx, %edi
21034 +
21035 +
21036 + movl 56(%ebp), %eax
21037 + xorl %ebx, %ebx
21038 + movl 60(%ebp), %edx
21039 + xorl %edi, %eax
21040 + xorl %edi, %edx
21041 + andl $0xfcfcfcfc, %eax
21042 + andl $0xcfcfcfcf, %edx
21043 + movb %al, %bl
21044 + movb %ah, %cl
21045 + rorl $4, %edx
21046 + movl des_SPtrans(%ebx),%ebp
21047 + movb %dl, %bl
21048 + xorl %ebp, %esi
21049 + movl 0x200+des_SPtrans(%ecx),%ebp
21050 + xorl %ebp, %esi
21051 + movb %dh, %cl
21052 + shrl $16, %eax
21053 + movl 0x100+des_SPtrans(%ebx),%ebp
21054 + xorl %ebp, %esi
21055 + movb %ah, %bl
21056 + shrl $16, %edx
21057 + movl 0x300+des_SPtrans(%ecx),%ebp
21058 + xorl %ebp, %esi
21059 + movl 24(%esp), %ebp
21060 + movb %dh, %cl
21061 + andl $0xff, %eax
21062 + andl $0xff, %edx
21063 + movl 0x600+des_SPtrans(%ebx),%ebx
21064 + xorl %ebx, %esi
21065 + movl 0x700+des_SPtrans(%ecx),%ebx
21066 + xorl %ebx, %esi
21067 + movl 0x400+des_SPtrans(%eax),%ebx
21068 + xorl %ebx, %esi
21069 + movl 0x500+des_SPtrans(%edx),%ebx
21070 + xorl %ebx, %esi
21071 +
21072 +
21073 + movl 64(%ebp), %eax
21074 + xorl %ebx, %ebx
21075 + movl 68(%ebp), %edx
21076 + xorl %esi, %eax
21077 + xorl %esi, %edx
21078 + andl $0xfcfcfcfc, %eax
21079 + andl $0xcfcfcfcf, %edx
21080 + movb %al, %bl
21081 + movb %ah, %cl
21082 + rorl $4, %edx
21083 + movl des_SPtrans(%ebx),%ebp
21084 + movb %dl, %bl
21085 + xorl %ebp, %edi
21086 + movl 0x200+des_SPtrans(%ecx),%ebp
21087 + xorl %ebp, %edi
21088 + movb %dh, %cl
21089 + shrl $16, %eax
21090 + movl 0x100+des_SPtrans(%ebx),%ebp
21091 + xorl %ebp, %edi
21092 + movb %ah, %bl
21093 + shrl $16, %edx
21094 + movl 0x300+des_SPtrans(%ecx),%ebp
21095 + xorl %ebp, %edi
21096 + movl 24(%esp), %ebp
21097 + movb %dh, %cl
21098 + andl $0xff, %eax
21099 + andl $0xff, %edx
21100 + movl 0x600+des_SPtrans(%ebx),%ebx
21101 + xorl %ebx, %edi
21102 + movl 0x700+des_SPtrans(%ecx),%ebx
21103 + xorl %ebx, %edi
21104 + movl 0x400+des_SPtrans(%eax),%ebx
21105 + xorl %ebx, %edi
21106 + movl 0x500+des_SPtrans(%edx),%ebx
21107 + xorl %ebx, %edi
21108 +
21109 +
21110 + movl 72(%ebp), %eax
21111 + xorl %ebx, %ebx
21112 + movl 76(%ebp), %edx
21113 + xorl %edi, %eax
21114 + xorl %edi, %edx
21115 + andl $0xfcfcfcfc, %eax
21116 + andl $0xcfcfcfcf, %edx
21117 + movb %al, %bl
21118 + movb %ah, %cl
21119 + rorl $4, %edx
21120 + movl des_SPtrans(%ebx),%ebp
21121 + movb %dl, %bl
21122 + xorl %ebp, %esi
21123 + movl 0x200+des_SPtrans(%ecx),%ebp
21124 + xorl %ebp, %esi
21125 + movb %dh, %cl
21126 + shrl $16, %eax
21127 + movl 0x100+des_SPtrans(%ebx),%ebp
21128 + xorl %ebp, %esi
21129 + movb %ah, %bl
21130 + shrl $16, %edx
21131 + movl 0x300+des_SPtrans(%ecx),%ebp
21132 + xorl %ebp, %esi
21133 + movl 24(%esp), %ebp
21134 + movb %dh, %cl
21135 + andl $0xff, %eax
21136 + andl $0xff, %edx
21137 + movl 0x600+des_SPtrans(%ebx),%ebx
21138 + xorl %ebx, %esi
21139 + movl 0x700+des_SPtrans(%ecx),%ebx
21140 + xorl %ebx, %esi
21141 + movl 0x400+des_SPtrans(%eax),%ebx
21142 + xorl %ebx, %esi
21143 + movl 0x500+des_SPtrans(%edx),%ebx
21144 + xorl %ebx, %esi
21145 +
21146 +
21147 + movl 80(%ebp), %eax
21148 + xorl %ebx, %ebx
21149 + movl 84(%ebp), %edx
21150 + xorl %esi, %eax
21151 + xorl %esi, %edx
21152 + andl $0xfcfcfcfc, %eax
21153 + andl $0xcfcfcfcf, %edx
21154 + movb %al, %bl
21155 + movb %ah, %cl
21156 + rorl $4, %edx
21157 + movl des_SPtrans(%ebx),%ebp
21158 + movb %dl, %bl
21159 + xorl %ebp, %edi
21160 + movl 0x200+des_SPtrans(%ecx),%ebp
21161 + xorl %ebp, %edi
21162 + movb %dh, %cl
21163 + shrl $16, %eax
21164 + movl 0x100+des_SPtrans(%ebx),%ebp
21165 + xorl %ebp, %edi
21166 + movb %ah, %bl
21167 + shrl $16, %edx
21168 + movl 0x300+des_SPtrans(%ecx),%ebp
21169 + xorl %ebp, %edi
21170 + movl 24(%esp), %ebp
21171 + movb %dh, %cl
21172 + andl $0xff, %eax
21173 + andl $0xff, %edx
21174 + movl 0x600+des_SPtrans(%ebx),%ebx
21175 + xorl %ebx, %edi
21176 + movl 0x700+des_SPtrans(%ecx),%ebx
21177 + xorl %ebx, %edi
21178 + movl 0x400+des_SPtrans(%eax),%ebx
21179 + xorl %ebx, %edi
21180 + movl 0x500+des_SPtrans(%edx),%ebx
21181 + xorl %ebx, %edi
21182 +
21183 +
21184 + movl 88(%ebp), %eax
21185 + xorl %ebx, %ebx
21186 + movl 92(%ebp), %edx
21187 + xorl %edi, %eax
21188 + xorl %edi, %edx
21189 + andl $0xfcfcfcfc, %eax
21190 + andl $0xcfcfcfcf, %edx
21191 + movb %al, %bl
21192 + movb %ah, %cl
21193 + rorl $4, %edx
21194 + movl des_SPtrans(%ebx),%ebp
21195 + movb %dl, %bl
21196 + xorl %ebp, %esi
21197 + movl 0x200+des_SPtrans(%ecx),%ebp
21198 + xorl %ebp, %esi
21199 + movb %dh, %cl
21200 + shrl $16, %eax
21201 + movl 0x100+des_SPtrans(%ebx),%ebp
21202 + xorl %ebp, %esi
21203 + movb %ah, %bl
21204 + shrl $16, %edx
21205 + movl 0x300+des_SPtrans(%ecx),%ebp
21206 + xorl %ebp, %esi
21207 + movl 24(%esp), %ebp
21208 + movb %dh, %cl
21209 + andl $0xff, %eax
21210 + andl $0xff, %edx
21211 + movl 0x600+des_SPtrans(%ebx),%ebx
21212 + xorl %ebx, %esi
21213 + movl 0x700+des_SPtrans(%ecx),%ebx
21214 + xorl %ebx, %esi
21215 + movl 0x400+des_SPtrans(%eax),%ebx
21216 + xorl %ebx, %esi
21217 + movl 0x500+des_SPtrans(%edx),%ebx
21218 + xorl %ebx, %esi
21219 +
21220 +
21221 + movl 96(%ebp), %eax
21222 + xorl %ebx, %ebx
21223 + movl 100(%ebp), %edx
21224 + xorl %esi, %eax
21225 + xorl %esi, %edx
21226 + andl $0xfcfcfcfc, %eax
21227 + andl $0xcfcfcfcf, %edx
21228 + movb %al, %bl
21229 + movb %ah, %cl
21230 + rorl $4, %edx
21231 + movl des_SPtrans(%ebx),%ebp
21232 + movb %dl, %bl
21233 + xorl %ebp, %edi
21234 + movl 0x200+des_SPtrans(%ecx),%ebp
21235 + xorl %ebp, %edi
21236 + movb %dh, %cl
21237 + shrl $16, %eax
21238 + movl 0x100+des_SPtrans(%ebx),%ebp
21239 + xorl %ebp, %edi
21240 + movb %ah, %bl
21241 + shrl $16, %edx
21242 + movl 0x300+des_SPtrans(%ecx),%ebp
21243 + xorl %ebp, %edi
21244 + movl 24(%esp), %ebp
21245 + movb %dh, %cl
21246 + andl $0xff, %eax
21247 + andl $0xff, %edx
21248 + movl 0x600+des_SPtrans(%ebx),%ebx
21249 + xorl %ebx, %edi
21250 + movl 0x700+des_SPtrans(%ecx),%ebx
21251 + xorl %ebx, %edi
21252 + movl 0x400+des_SPtrans(%eax),%ebx
21253 + xorl %ebx, %edi
21254 + movl 0x500+des_SPtrans(%edx),%ebx
21255 + xorl %ebx, %edi
21256 +
21257 +
21258 + movl 104(%ebp), %eax
21259 + xorl %ebx, %ebx
21260 + movl 108(%ebp), %edx
21261 + xorl %edi, %eax
21262 + xorl %edi, %edx
21263 + andl $0xfcfcfcfc, %eax
21264 + andl $0xcfcfcfcf, %edx
21265 + movb %al, %bl
21266 + movb %ah, %cl
21267 + rorl $4, %edx
21268 + movl des_SPtrans(%ebx),%ebp
21269 + movb %dl, %bl
21270 + xorl %ebp, %esi
21271 + movl 0x200+des_SPtrans(%ecx),%ebp
21272 + xorl %ebp, %esi
21273 + movb %dh, %cl
21274 + shrl $16, %eax
21275 + movl 0x100+des_SPtrans(%ebx),%ebp
21276 + xorl %ebp, %esi
21277 + movb %ah, %bl
21278 + shrl $16, %edx
21279 + movl 0x300+des_SPtrans(%ecx),%ebp
21280 + xorl %ebp, %esi
21281 + movl 24(%esp), %ebp
21282 + movb %dh, %cl
21283 + andl $0xff, %eax
21284 + andl $0xff, %edx
21285 + movl 0x600+des_SPtrans(%ebx),%ebx
21286 + xorl %ebx, %esi
21287 + movl 0x700+des_SPtrans(%ecx),%ebx
21288 + xorl %ebx, %esi
21289 + movl 0x400+des_SPtrans(%eax),%ebx
21290 + xorl %ebx, %esi
21291 + movl 0x500+des_SPtrans(%edx),%ebx
21292 + xorl %ebx, %esi
21293 +
21294 +
21295 + movl 112(%ebp), %eax
21296 + xorl %ebx, %ebx
21297 + movl 116(%ebp), %edx
21298 + xorl %esi, %eax
21299 + xorl %esi, %edx
21300 + andl $0xfcfcfcfc, %eax
21301 + andl $0xcfcfcfcf, %edx
21302 + movb %al, %bl
21303 + movb %ah, %cl
21304 + rorl $4, %edx
21305 + movl des_SPtrans(%ebx),%ebp
21306 + movb %dl, %bl
21307 + xorl %ebp, %edi
21308 + movl 0x200+des_SPtrans(%ecx),%ebp
21309 + xorl %ebp, %edi
21310 + movb %dh, %cl
21311 + shrl $16, %eax
21312 + movl 0x100+des_SPtrans(%ebx),%ebp
21313 + xorl %ebp, %edi
21314 + movb %ah, %bl
21315 + shrl $16, %edx
21316 + movl 0x300+des_SPtrans(%ecx),%ebp
21317 + xorl %ebp, %edi
21318 + movl 24(%esp), %ebp
21319 + movb %dh, %cl
21320 + andl $0xff, %eax
21321 + andl $0xff, %edx
21322 + movl 0x600+des_SPtrans(%ebx),%ebx
21323 + xorl %ebx, %edi
21324 + movl 0x700+des_SPtrans(%ecx),%ebx
21325 + xorl %ebx, %edi
21326 + movl 0x400+des_SPtrans(%eax),%ebx
21327 + xorl %ebx, %edi
21328 + movl 0x500+des_SPtrans(%edx),%ebx
21329 + xorl %ebx, %edi
21330 +
21331 +
21332 + movl 120(%ebp), %eax
21333 + xorl %ebx, %ebx
21334 + movl 124(%ebp), %edx
21335 + xorl %edi, %eax
21336 + xorl %edi, %edx
21337 + andl $0xfcfcfcfc, %eax
21338 + andl $0xcfcfcfcf, %edx
21339 + movb %al, %bl
21340 + movb %ah, %cl
21341 + rorl $4, %edx
21342 + movl des_SPtrans(%ebx),%ebp
21343 + movb %dl, %bl
21344 + xorl %ebp, %esi
21345 + movl 0x200+des_SPtrans(%ecx),%ebp
21346 + xorl %ebp, %esi
21347 + movb %dh, %cl
21348 + shrl $16, %eax
21349 + movl 0x100+des_SPtrans(%ebx),%ebp
21350 + xorl %ebp, %esi
21351 + movb %ah, %bl
21352 + shrl $16, %edx
21353 + movl 0x300+des_SPtrans(%ecx),%ebp
21354 + xorl %ebp, %esi
21355 + movl 24(%esp), %ebp
21356 + movb %dh, %cl
21357 + andl $0xff, %eax
21358 + andl $0xff, %edx
21359 + movl 0x600+des_SPtrans(%ebx),%ebx
21360 + xorl %ebx, %esi
21361 + movl 0x700+des_SPtrans(%ecx),%ebx
21362 + xorl %ebx, %esi
21363 + movl 0x400+des_SPtrans(%eax),%ebx
21364 + xorl %ebx, %esi
21365 + movl 0x500+des_SPtrans(%edx),%ebx
21366 + xorl %ebx, %esi
21367 + jmp .L003end
21368 +.L002start_decrypt:
21369 +
21370 +
21371 + movl 120(%ebp), %eax
21372 + xorl %ebx, %ebx
21373 + movl 124(%ebp), %edx
21374 + xorl %esi, %eax
21375 + xorl %esi, %edx
21376 + andl $0xfcfcfcfc, %eax
21377 + andl $0xcfcfcfcf, %edx
21378 + movb %al, %bl
21379 + movb %ah, %cl
21380 + rorl $4, %edx
21381 + movl des_SPtrans(%ebx),%ebp
21382 + movb %dl, %bl
21383 + xorl %ebp, %edi
21384 + movl 0x200+des_SPtrans(%ecx),%ebp
21385 + xorl %ebp, %edi
21386 + movb %dh, %cl
21387 + shrl $16, %eax
21388 + movl 0x100+des_SPtrans(%ebx),%ebp
21389 + xorl %ebp, %edi
21390 + movb %ah, %bl
21391 + shrl $16, %edx
21392 + movl 0x300+des_SPtrans(%ecx),%ebp
21393 + xorl %ebp, %edi
21394 + movl 24(%esp), %ebp
21395 + movb %dh, %cl
21396 + andl $0xff, %eax
21397 + andl $0xff, %edx
21398 + movl 0x600+des_SPtrans(%ebx),%ebx
21399 + xorl %ebx, %edi
21400 + movl 0x700+des_SPtrans(%ecx),%ebx
21401 + xorl %ebx, %edi
21402 + movl 0x400+des_SPtrans(%eax),%ebx
21403 + xorl %ebx, %edi
21404 + movl 0x500+des_SPtrans(%edx),%ebx
21405 + xorl %ebx, %edi
21406 +
21407 +
21408 + movl 112(%ebp), %eax
21409 + xorl %ebx, %ebx
21410 + movl 116(%ebp), %edx
21411 + xorl %edi, %eax
21412 + xorl %edi, %edx
21413 + andl $0xfcfcfcfc, %eax
21414 + andl $0xcfcfcfcf, %edx
21415 + movb %al, %bl
21416 + movb %ah, %cl
21417 + rorl $4, %edx
21418 + movl des_SPtrans(%ebx),%ebp
21419 + movb %dl, %bl
21420 + xorl %ebp, %esi
21421 + movl 0x200+des_SPtrans(%ecx),%ebp
21422 + xorl %ebp, %esi
21423 + movb %dh, %cl
21424 + shrl $16, %eax
21425 + movl 0x100+des_SPtrans(%ebx),%ebp
21426 + xorl %ebp, %esi
21427 + movb %ah, %bl
21428 + shrl $16, %edx
21429 + movl 0x300+des_SPtrans(%ecx),%ebp
21430 + xorl %ebp, %esi
21431 + movl 24(%esp), %ebp
21432 + movb %dh, %cl
21433 + andl $0xff, %eax
21434 + andl $0xff, %edx
21435 + movl 0x600+des_SPtrans(%ebx),%ebx
21436 + xorl %ebx, %esi
21437 + movl 0x700+des_SPtrans(%ecx),%ebx
21438 + xorl %ebx, %esi
21439 + movl 0x400+des_SPtrans(%eax),%ebx
21440 + xorl %ebx, %esi
21441 + movl 0x500+des_SPtrans(%edx),%ebx
21442 + xorl %ebx, %esi
21443 +
21444 +
21445 + movl 104(%ebp), %eax
21446 + xorl %ebx, %ebx
21447 + movl 108(%ebp), %edx
21448 + xorl %esi, %eax
21449 + xorl %esi, %edx
21450 + andl $0xfcfcfcfc, %eax
21451 + andl $0xcfcfcfcf, %edx
21452 + movb %al, %bl
21453 + movb %ah, %cl
21454 + rorl $4, %edx
21455 + movl des_SPtrans(%ebx),%ebp
21456 + movb %dl, %bl
21457 + xorl %ebp, %edi
21458 + movl 0x200+des_SPtrans(%ecx),%ebp
21459 + xorl %ebp, %edi
21460 + movb %dh, %cl
21461 + shrl $16, %eax
21462 + movl 0x100+des_SPtrans(%ebx),%ebp
21463 + xorl %ebp, %edi
21464 + movb %ah, %bl
21465 + shrl $16, %edx
21466 + movl 0x300+des_SPtrans(%ecx),%ebp
21467 + xorl %ebp, %edi
21468 + movl 24(%esp), %ebp
21469 + movb %dh, %cl
21470 + andl $0xff, %eax
21471 + andl $0xff, %edx
21472 + movl 0x600+des_SPtrans(%ebx),%ebx
21473 + xorl %ebx, %edi
21474 + movl 0x700+des_SPtrans(%ecx),%ebx
21475 + xorl %ebx, %edi
21476 + movl 0x400+des_SPtrans(%eax),%ebx
21477 + xorl %ebx, %edi
21478 + movl 0x500+des_SPtrans(%edx),%ebx
21479 + xorl %ebx, %edi
21480 +
21481 +
21482 + movl 96(%ebp), %eax
21483 + xorl %ebx, %ebx
21484 + movl 100(%ebp), %edx
21485 + xorl %edi, %eax
21486 + xorl %edi, %edx
21487 + andl $0xfcfcfcfc, %eax
21488 + andl $0xcfcfcfcf, %edx
21489 + movb %al, %bl
21490 + movb %ah, %cl
21491 + rorl $4, %edx
21492 + movl des_SPtrans(%ebx),%ebp
21493 + movb %dl, %bl
21494 + xorl %ebp, %esi
21495 + movl 0x200+des_SPtrans(%ecx),%ebp
21496 + xorl %ebp, %esi
21497 + movb %dh, %cl
21498 + shrl $16, %eax
21499 + movl 0x100+des_SPtrans(%ebx),%ebp
21500 + xorl %ebp, %esi
21501 + movb %ah, %bl
21502 + shrl $16, %edx
21503 + movl 0x300+des_SPtrans(%ecx),%ebp
21504 + xorl %ebp, %esi
21505 + movl 24(%esp), %ebp
21506 + movb %dh, %cl
21507 + andl $0xff, %eax
21508 + andl $0xff, %edx
21509 + movl 0x600+des_SPtrans(%ebx),%ebx
21510 + xorl %ebx, %esi
21511 + movl 0x700+des_SPtrans(%ecx),%ebx
21512 + xorl %ebx, %esi
21513 + movl 0x400+des_SPtrans(%eax),%ebx
21514 + xorl %ebx, %esi
21515 + movl 0x500+des_SPtrans(%edx),%ebx
21516 + xorl %ebx, %esi
21517 +
21518 +
21519 + movl 88(%ebp), %eax
21520 + xorl %ebx, %ebx
21521 + movl 92(%ebp), %edx
21522 + xorl %esi, %eax
21523 + xorl %esi, %edx
21524 + andl $0xfcfcfcfc, %eax
21525 + andl $0xcfcfcfcf, %edx
21526 + movb %al, %bl
21527 + movb %ah, %cl
21528 + rorl $4, %edx
21529 + movl des_SPtrans(%ebx),%ebp
21530 + movb %dl, %bl
21531 + xorl %ebp, %edi
21532 + movl 0x200+des_SPtrans(%ecx),%ebp
21533 + xorl %ebp, %edi
21534 + movb %dh, %cl
21535 + shrl $16, %eax
21536 + movl 0x100+des_SPtrans(%ebx),%ebp
21537 + xorl %ebp, %edi
21538 + movb %ah, %bl
21539 + shrl $16, %edx
21540 + movl 0x300+des_SPtrans(%ecx),%ebp
21541 + xorl %ebp, %edi
21542 + movl 24(%esp), %ebp
21543 + movb %dh, %cl
21544 + andl $0xff, %eax
21545 + andl $0xff, %edx
21546 + movl 0x600+des_SPtrans(%ebx),%ebx
21547 + xorl %ebx, %edi
21548 + movl 0x700+des_SPtrans(%ecx),%ebx
21549 + xorl %ebx, %edi
21550 + movl 0x400+des_SPtrans(%eax),%ebx
21551 + xorl %ebx, %edi
21552 + movl 0x500+des_SPtrans(%edx),%ebx
21553 + xorl %ebx, %edi
21554 +
21555 +
21556 + movl 80(%ebp), %eax
21557 + xorl %ebx, %ebx
21558 + movl 84(%ebp), %edx
21559 + xorl %edi, %eax
21560 + xorl %edi, %edx
21561 + andl $0xfcfcfcfc, %eax
21562 + andl $0xcfcfcfcf, %edx
21563 + movb %al, %bl
21564 + movb %ah, %cl
21565 + rorl $4, %edx
21566 + movl des_SPtrans(%ebx),%ebp
21567 + movb %dl, %bl
21568 + xorl %ebp, %esi
21569 + movl 0x200+des_SPtrans(%ecx),%ebp
21570 + xorl %ebp, %esi
21571 + movb %dh, %cl
21572 + shrl $16, %eax
21573 + movl 0x100+des_SPtrans(%ebx),%ebp
21574 + xorl %ebp, %esi
21575 + movb %ah, %bl
21576 + shrl $16, %edx
21577 + movl 0x300+des_SPtrans(%ecx),%ebp
21578 + xorl %ebp, %esi
21579 + movl 24(%esp), %ebp
21580 + movb %dh, %cl
21581 + andl $0xff, %eax
21582 + andl $0xff, %edx
21583 + movl 0x600+des_SPtrans(%ebx),%ebx
21584 + xorl %ebx, %esi
21585 + movl 0x700+des_SPtrans(%ecx),%ebx
21586 + xorl %ebx, %esi
21587 + movl 0x400+des_SPtrans(%eax),%ebx
21588 + xorl %ebx, %esi
21589 + movl 0x500+des_SPtrans(%edx),%ebx
21590 + xorl %ebx, %esi
21591 +
21592 +
21593 + movl 72(%ebp), %eax
21594 + xorl %ebx, %ebx
21595 + movl 76(%ebp), %edx
21596 + xorl %esi, %eax
21597 + xorl %esi, %edx
21598 + andl $0xfcfcfcfc, %eax
21599 + andl $0xcfcfcfcf, %edx
21600 + movb %al, %bl
21601 + movb %ah, %cl
21602 + rorl $4, %edx
21603 + movl des_SPtrans(%ebx),%ebp
21604 + movb %dl, %bl
21605 + xorl %ebp, %edi
21606 + movl 0x200+des_SPtrans(%ecx),%ebp
21607 + xorl %ebp, %edi
21608 + movb %dh, %cl
21609 + shrl $16, %eax
21610 + movl 0x100+des_SPtrans(%ebx),%ebp
21611 + xorl %ebp, %edi
21612 + movb %ah, %bl
21613 + shrl $16, %edx
21614 + movl 0x300+des_SPtrans(%ecx),%ebp
21615 + xorl %ebp, %edi
21616 + movl 24(%esp), %ebp
21617 + movb %dh, %cl
21618 + andl $0xff, %eax
21619 + andl $0xff, %edx
21620 + movl 0x600+des_SPtrans(%ebx),%ebx
21621 + xorl %ebx, %edi
21622 + movl 0x700+des_SPtrans(%ecx),%ebx
21623 + xorl %ebx, %edi
21624 + movl 0x400+des_SPtrans(%eax),%ebx
21625 + xorl %ebx, %edi
21626 + movl 0x500+des_SPtrans(%edx),%ebx
21627 + xorl %ebx, %edi
21628 +
21629 +
21630 + movl 64(%ebp), %eax
21631 + xorl %ebx, %ebx
21632 + movl 68(%ebp), %edx
21633 + xorl %edi, %eax
21634 + xorl %edi, %edx
21635 + andl $0xfcfcfcfc, %eax
21636 + andl $0xcfcfcfcf, %edx
21637 + movb %al, %bl
21638 + movb %ah, %cl
21639 + rorl $4, %edx
21640 + movl des_SPtrans(%ebx),%ebp
21641 + movb %dl, %bl
21642 + xorl %ebp, %esi
21643 + movl 0x200+des_SPtrans(%ecx),%ebp
21644 + xorl %ebp, %esi
21645 + movb %dh, %cl
21646 + shrl $16, %eax
21647 + movl 0x100+des_SPtrans(%ebx),%ebp
21648 + xorl %ebp, %esi
21649 + movb %ah, %bl
21650 + shrl $16, %edx
21651 + movl 0x300+des_SPtrans(%ecx),%ebp
21652 + xorl %ebp, %esi
21653 + movl 24(%esp), %ebp
21654 + movb %dh, %cl
21655 + andl $0xff, %eax
21656 + andl $0xff, %edx
21657 + movl 0x600+des_SPtrans(%ebx),%ebx
21658 + xorl %ebx, %esi
21659 + movl 0x700+des_SPtrans(%ecx),%ebx
21660 + xorl %ebx, %esi
21661 + movl 0x400+des_SPtrans(%eax),%ebx
21662 + xorl %ebx, %esi
21663 + movl 0x500+des_SPtrans(%edx),%ebx
21664 + xorl %ebx, %esi
21665 +
21666 +
21667 + movl 56(%ebp), %eax
21668 + xorl %ebx, %ebx
21669 + movl 60(%ebp), %edx
21670 + xorl %esi, %eax
21671 + xorl %esi, %edx
21672 + andl $0xfcfcfcfc, %eax
21673 + andl $0xcfcfcfcf, %edx
21674 + movb %al, %bl
21675 + movb %ah, %cl
21676 + rorl $4, %edx
21677 + movl des_SPtrans(%ebx),%ebp
21678 + movb %dl, %bl
21679 + xorl %ebp, %edi
21680 + movl 0x200+des_SPtrans(%ecx),%ebp
21681 + xorl %ebp, %edi
21682 + movb %dh, %cl
21683 + shrl $16, %eax
21684 + movl 0x100+des_SPtrans(%ebx),%ebp
21685 + xorl %ebp, %edi
21686 + movb %ah, %bl
21687 + shrl $16, %edx
21688 + movl 0x300+des_SPtrans(%ecx),%ebp
21689 + xorl %ebp, %edi
21690 + movl 24(%esp), %ebp
21691 + movb %dh, %cl
21692 + andl $0xff, %eax
21693 + andl $0xff, %edx
21694 + movl 0x600+des_SPtrans(%ebx),%ebx
21695 + xorl %ebx, %edi
21696 + movl 0x700+des_SPtrans(%ecx),%ebx
21697 + xorl %ebx, %edi
21698 + movl 0x400+des_SPtrans(%eax),%ebx
21699 + xorl %ebx, %edi
21700 + movl 0x500+des_SPtrans(%edx),%ebx
21701 + xorl %ebx, %edi
21702 +
21703 +
21704 + movl 48(%ebp), %eax
21705 + xorl %ebx, %ebx
21706 + movl 52(%ebp), %edx
21707 + xorl %edi, %eax
21708 + xorl %edi, %edx
21709 + andl $0xfcfcfcfc, %eax
21710 + andl $0xcfcfcfcf, %edx
21711 + movb %al, %bl
21712 + movb %ah, %cl
21713 + rorl $4, %edx
21714 + movl des_SPtrans(%ebx),%ebp
21715 + movb %dl, %bl
21716 + xorl %ebp, %esi
21717 + movl 0x200+des_SPtrans(%ecx),%ebp
21718 + xorl %ebp, %esi
21719 + movb %dh, %cl
21720 + shrl $16, %eax
21721 + movl 0x100+des_SPtrans(%ebx),%ebp
21722 + xorl %ebp, %esi
21723 + movb %ah, %bl
21724 + shrl $16, %edx
21725 + movl 0x300+des_SPtrans(%ecx),%ebp
21726 + xorl %ebp, %esi
21727 + movl 24(%esp), %ebp
21728 + movb %dh, %cl
21729 + andl $0xff, %eax
21730 + andl $0xff, %edx
21731 + movl 0x600+des_SPtrans(%ebx),%ebx
21732 + xorl %ebx, %esi
21733 + movl 0x700+des_SPtrans(%ecx),%ebx
21734 + xorl %ebx, %esi
21735 + movl 0x400+des_SPtrans(%eax),%ebx
21736 + xorl %ebx, %esi
21737 + movl 0x500+des_SPtrans(%edx),%ebx
21738 + xorl %ebx, %esi
21739 +
21740 +
21741 + movl 40(%ebp), %eax
21742 + xorl %ebx, %ebx
21743 + movl 44(%ebp), %edx
21744 + xorl %esi, %eax
21745 + xorl %esi, %edx
21746 + andl $0xfcfcfcfc, %eax
21747 + andl $0xcfcfcfcf, %edx
21748 + movb %al, %bl
21749 + movb %ah, %cl
21750 + rorl $4, %edx
21751 + movl des_SPtrans(%ebx),%ebp
21752 + movb %dl, %bl
21753 + xorl %ebp, %edi
21754 + movl 0x200+des_SPtrans(%ecx),%ebp
21755 + xorl %ebp, %edi
21756 + movb %dh, %cl
21757 + shrl $16, %eax
21758 + movl 0x100+des_SPtrans(%ebx),%ebp
21759 + xorl %ebp, %edi
21760 + movb %ah, %bl
21761 + shrl $16, %edx
21762 + movl 0x300+des_SPtrans(%ecx),%ebp
21763 + xorl %ebp, %edi
21764 + movl 24(%esp), %ebp
21765 + movb %dh, %cl
21766 + andl $0xff, %eax
21767 + andl $0xff, %edx
21768 + movl 0x600+des_SPtrans(%ebx),%ebx
21769 + xorl %ebx, %edi
21770 + movl 0x700+des_SPtrans(%ecx),%ebx
21771 + xorl %ebx, %edi
21772 + movl 0x400+des_SPtrans(%eax),%ebx
21773 + xorl %ebx, %edi
21774 + movl 0x500+des_SPtrans(%edx),%ebx
21775 + xorl %ebx, %edi
21776 +
21777 +
21778 + movl 32(%ebp), %eax
21779 + xorl %ebx, %ebx
21780 + movl 36(%ebp), %edx
21781 + xorl %edi, %eax
21782 + xorl %edi, %edx
21783 + andl $0xfcfcfcfc, %eax
21784 + andl $0xcfcfcfcf, %edx
21785 + movb %al, %bl
21786 + movb %ah, %cl
21787 + rorl $4, %edx
21788 + movl des_SPtrans(%ebx),%ebp
21789 + movb %dl, %bl
21790 + xorl %ebp, %esi
21791 + movl 0x200+des_SPtrans(%ecx),%ebp
21792 + xorl %ebp, %esi
21793 + movb %dh, %cl
21794 + shrl $16, %eax
21795 + movl 0x100+des_SPtrans(%ebx),%ebp
21796 + xorl %ebp, %esi
21797 + movb %ah, %bl
21798 + shrl $16, %edx
21799 + movl 0x300+des_SPtrans(%ecx),%ebp
21800 + xorl %ebp, %esi
21801 + movl 24(%esp), %ebp
21802 + movb %dh, %cl
21803 + andl $0xff, %eax
21804 + andl $0xff, %edx
21805 + movl 0x600+des_SPtrans(%ebx),%ebx
21806 + xorl %ebx, %esi
21807 + movl 0x700+des_SPtrans(%ecx),%ebx
21808 + xorl %ebx, %esi
21809 + movl 0x400+des_SPtrans(%eax),%ebx
21810 + xorl %ebx, %esi
21811 + movl 0x500+des_SPtrans(%edx),%ebx
21812 + xorl %ebx, %esi
21813 +
21814 +
21815 + movl 24(%ebp), %eax
21816 + xorl %ebx, %ebx
21817 + movl 28(%ebp), %edx
21818 + xorl %esi, %eax
21819 + xorl %esi, %edx
21820 + andl $0xfcfcfcfc, %eax
21821 + andl $0xcfcfcfcf, %edx
21822 + movb %al, %bl
21823 + movb %ah, %cl
21824 + rorl $4, %edx
21825 + movl des_SPtrans(%ebx),%ebp
21826 + movb %dl, %bl
21827 + xorl %ebp, %edi
21828 + movl 0x200+des_SPtrans(%ecx),%ebp
21829 + xorl %ebp, %edi
21830 + movb %dh, %cl
21831 + shrl $16, %eax
21832 + movl 0x100+des_SPtrans(%ebx),%ebp
21833 + xorl %ebp, %edi
21834 + movb %ah, %bl
21835 + shrl $16, %edx
21836 + movl 0x300+des_SPtrans(%ecx),%ebp
21837 + xorl %ebp, %edi
21838 + movl 24(%esp), %ebp
21839 + movb %dh, %cl
21840 + andl $0xff, %eax
21841 + andl $0xff, %edx
21842 + movl 0x600+des_SPtrans(%ebx),%ebx
21843 + xorl %ebx, %edi
21844 + movl 0x700+des_SPtrans(%ecx),%ebx
21845 + xorl %ebx, %edi
21846 + movl 0x400+des_SPtrans(%eax),%ebx
21847 + xorl %ebx, %edi
21848 + movl 0x500+des_SPtrans(%edx),%ebx
21849 + xorl %ebx, %edi
21850 +
21851 +
21852 + movl 16(%ebp), %eax
21853 + xorl %ebx, %ebx
21854 + movl 20(%ebp), %edx
21855 + xorl %edi, %eax
21856 + xorl %edi, %edx
21857 + andl $0xfcfcfcfc, %eax
21858 + andl $0xcfcfcfcf, %edx
21859 + movb %al, %bl
21860 + movb %ah, %cl
21861 + rorl $4, %edx
21862 + movl des_SPtrans(%ebx),%ebp
21863 + movb %dl, %bl
21864 + xorl %ebp, %esi
21865 + movl 0x200+des_SPtrans(%ecx),%ebp
21866 + xorl %ebp, %esi
21867 + movb %dh, %cl
21868 + shrl $16, %eax
21869 + movl 0x100+des_SPtrans(%ebx),%ebp
21870 + xorl %ebp, %esi
21871 + movb %ah, %bl
21872 + shrl $16, %edx
21873 + movl 0x300+des_SPtrans(%ecx),%ebp
21874 + xorl %ebp, %esi
21875 + movl 24(%esp), %ebp
21876 + movb %dh, %cl
21877 + andl $0xff, %eax
21878 + andl $0xff, %edx
21879 + movl 0x600+des_SPtrans(%ebx),%ebx
21880 + xorl %ebx, %esi
21881 + movl 0x700+des_SPtrans(%ecx),%ebx
21882 + xorl %ebx, %esi
21883 + movl 0x400+des_SPtrans(%eax),%ebx
21884 + xorl %ebx, %esi
21885 + movl 0x500+des_SPtrans(%edx),%ebx
21886 + xorl %ebx, %esi
21887 +
21888 +
21889 + movl 8(%ebp), %eax
21890 + xorl %ebx, %ebx
21891 + movl 12(%ebp), %edx
21892 + xorl %esi, %eax
21893 + xorl %esi, %edx
21894 + andl $0xfcfcfcfc, %eax
21895 + andl $0xcfcfcfcf, %edx
21896 + movb %al, %bl
21897 + movb %ah, %cl
21898 + rorl $4, %edx
21899 + movl des_SPtrans(%ebx),%ebp
21900 + movb %dl, %bl
21901 + xorl %ebp, %edi
21902 + movl 0x200+des_SPtrans(%ecx),%ebp
21903 + xorl %ebp, %edi
21904 + movb %dh, %cl
21905 + shrl $16, %eax
21906 + movl 0x100+des_SPtrans(%ebx),%ebp
21907 + xorl %ebp, %edi
21908 + movb %ah, %bl
21909 + shrl $16, %edx
21910 + movl 0x300+des_SPtrans(%ecx),%ebp
21911 + xorl %ebp, %edi
21912 + movl 24(%esp), %ebp
21913 + movb %dh, %cl
21914 + andl $0xff, %eax
21915 + andl $0xff, %edx
21916 + movl 0x600+des_SPtrans(%ebx),%ebx
21917 + xorl %ebx, %edi
21918 + movl 0x700+des_SPtrans(%ecx),%ebx
21919 + xorl %ebx, %edi
21920 + movl 0x400+des_SPtrans(%eax),%ebx
21921 + xorl %ebx, %edi
21922 + movl 0x500+des_SPtrans(%edx),%ebx
21923 + xorl %ebx, %edi
21924 +
21925 +
21926 + movl (%ebp), %eax
21927 + xorl %ebx, %ebx
21928 + movl 4(%ebp), %edx
21929 + xorl %edi, %eax
21930 + xorl %edi, %edx
21931 + andl $0xfcfcfcfc, %eax
21932 + andl $0xcfcfcfcf, %edx
21933 + movb %al, %bl
21934 + movb %ah, %cl
21935 + rorl $4, %edx
21936 + movl des_SPtrans(%ebx),%ebp
21937 + movb %dl, %bl
21938 + xorl %ebp, %esi
21939 + movl 0x200+des_SPtrans(%ecx),%ebp
21940 + xorl %ebp, %esi
21941 + movb %dh, %cl
21942 + shrl $16, %eax
21943 + movl 0x100+des_SPtrans(%ebx),%ebp
21944 + xorl %ebp, %esi
21945 + movb %ah, %bl
21946 + shrl $16, %edx
21947 + movl 0x300+des_SPtrans(%ecx),%ebp
21948 + xorl %ebp, %esi
21949 + movl 24(%esp), %ebp
21950 + movb %dh, %cl
21951 + andl $0xff, %eax
21952 + andl $0xff, %edx
21953 + movl 0x600+des_SPtrans(%ebx),%ebx
21954 + xorl %ebx, %esi
21955 + movl 0x700+des_SPtrans(%ecx),%ebx
21956 + xorl %ebx, %esi
21957 + movl 0x400+des_SPtrans(%eax),%ebx
21958 + xorl %ebx, %esi
21959 + movl 0x500+des_SPtrans(%edx),%ebx
21960 + xorl %ebx, %esi
21961 +.L003end:
21962 +
21963 +
21964 + rorl $3, %edi
21965 + movl 20(%esp), %eax
21966 + rorl $3, %esi
21967 + movl %edi, (%eax)
21968 + movl %esi, 4(%eax)
21969 + popl %ebp
21970 + popl %ebx
21971 + popl %edi
21972 + popl %esi
21973 + ret
21974 +.des_encrypt2_end:
21975 + .size des_encrypt2 , .des_encrypt2_end-des_encrypt2
21976 +.ident "desasm.pl"
21977 +.text
21978 + .align 16
21979 +.globl des_encrypt3
21980 + .type des_encrypt3 , @function
21981 +des_encrypt3:
21982 + pushl %ebx
21983 + movl 8(%esp), %ebx
21984 + pushl %ebp
21985 + pushl %esi
21986 + pushl %edi
21987 +
21988 +
21989 + movl (%ebx), %edi
21990 + movl 4(%ebx), %esi
21991 + subl $12, %esp
21992 +
21993 +
21994 + roll $4, %edi
21995 + movl %edi, %edx
21996 + xorl %esi, %edi
21997 + andl $0xf0f0f0f0, %edi
21998 + xorl %edi, %edx
21999 + xorl %edi, %esi
22000 +
22001 + roll $20, %esi
22002 + movl %esi, %edi
22003 + xorl %edx, %esi
22004 + andl $0xfff0000f, %esi
22005 + xorl %esi, %edi
22006 + xorl %esi, %edx
22007 +
22008 + roll $14, %edi
22009 + movl %edi, %esi
22010 + xorl %edx, %edi
22011 + andl $0x33333333, %edi
22012 + xorl %edi, %esi
22013 + xorl %edi, %edx
22014 +
22015 + roll $22, %edx
22016 + movl %edx, %edi
22017 + xorl %esi, %edx
22018 + andl $0x03fc03fc, %edx
22019 + xorl %edx, %edi
22020 + xorl %edx, %esi
22021 +
22022 + roll $9, %edi
22023 + movl %edi, %edx
22024 + xorl %esi, %edi
22025 + andl $0xaaaaaaaa, %edi
22026 + xorl %edi, %edx
22027 + xorl %edi, %esi
22028 +
22029 + rorl $3, %edx
22030 + rorl $2, %esi
22031 + movl %esi, 4(%ebx)
22032 + movl 36(%esp), %eax
22033 + movl %edx, (%ebx)
22034 + movl 40(%esp), %edi
22035 + movl 44(%esp), %esi
22036 + movl $1, 8(%esp)
22037 + movl %eax, 4(%esp)
22038 + movl %ebx, (%esp)
22039 + call des_encrypt2
22040 + movl $0, 8(%esp)
22041 + movl %edi, 4(%esp)
22042 + movl %ebx, (%esp)
22043 + call des_encrypt2
22044 + movl $1, 8(%esp)
22045 + movl %esi, 4(%esp)
22046 + movl %ebx, (%esp)
22047 + call des_encrypt2
22048 + addl $12, %esp
22049 + movl (%ebx), %edi
22050 + movl 4(%ebx), %esi
22051 +
22052 +
22053 + roll $2, %esi
22054 + roll $3, %edi
22055 + movl %edi, %eax
22056 + xorl %esi, %edi
22057 + andl $0xaaaaaaaa, %edi
22058 + xorl %edi, %eax
22059 + xorl %edi, %esi
22060 +
22061 + roll $23, %eax
22062 + movl %eax, %edi
22063 + xorl %esi, %eax
22064 + andl $0x03fc03fc, %eax
22065 + xorl %eax, %edi
22066 + xorl %eax, %esi
22067 +
22068 + roll $10, %edi
22069 + movl %edi, %eax
22070 + xorl %esi, %edi
22071 + andl $0x33333333, %edi
22072 + xorl %edi, %eax
22073 + xorl %edi, %esi
22074 +
22075 + roll $18, %esi
22076 + movl %esi, %edi
22077 + xorl %eax, %esi
22078 + andl $0xfff0000f, %esi
22079 + xorl %esi, %edi
22080 + xorl %esi, %eax
22081 +
22082 + roll $12, %edi
22083 + movl %edi, %esi
22084 + xorl %eax, %edi
22085 + andl $0xf0f0f0f0, %edi
22086 + xorl %edi, %esi
22087 + xorl %edi, %eax
22088 +
22089 + rorl $4, %eax
22090 + movl %eax, (%ebx)
22091 + movl %esi, 4(%ebx)
22092 + popl %edi
22093 + popl %esi
22094 + popl %ebp
22095 + popl %ebx
22096 + ret
22097 +.des_encrypt3_end:
22098 + .size des_encrypt3 , .des_encrypt3_end-des_encrypt3
22099 +.ident "desasm.pl"
22100 +.text
22101 + .align 16
22102 +.globl des_decrypt3
22103 + .type des_decrypt3 , @function
22104 +des_decrypt3:
22105 + pushl %ebx
22106 + movl 8(%esp), %ebx
22107 + pushl %ebp
22108 + pushl %esi
22109 + pushl %edi
22110 +
22111 +
22112 + movl (%ebx), %edi
22113 + movl 4(%ebx), %esi
22114 + subl $12, %esp
22115 +
22116 +
22117 + roll $4, %edi
22118 + movl %edi, %edx
22119 + xorl %esi, %edi
22120 + andl $0xf0f0f0f0, %edi
22121 + xorl %edi, %edx
22122 + xorl %edi, %esi
22123 +
22124 + roll $20, %esi
22125 + movl %esi, %edi
22126 + xorl %edx, %esi
22127 + andl $0xfff0000f, %esi
22128 + xorl %esi, %edi
22129 + xorl %esi, %edx
22130 +
22131 + roll $14, %edi
22132 + movl %edi, %esi
22133 + xorl %edx, %edi
22134 + andl $0x33333333, %edi
22135 + xorl %edi, %esi
22136 + xorl %edi, %edx
22137 +
22138 + roll $22, %edx
22139 + movl %edx, %edi
22140 + xorl %esi, %edx
22141 + andl $0x03fc03fc, %edx
22142 + xorl %edx, %edi
22143 + xorl %edx, %esi
22144 +
22145 + roll $9, %edi
22146 + movl %edi, %edx
22147 + xorl %esi, %edi
22148 + andl $0xaaaaaaaa, %edi
22149 + xorl %edi, %edx
22150 + xorl %edi, %esi
22151 +
22152 + rorl $3, %edx
22153 + rorl $2, %esi
22154 + movl %esi, 4(%ebx)
22155 + movl 36(%esp), %esi
22156 + movl %edx, (%ebx)
22157 + movl 40(%esp), %edi
22158 + movl 44(%esp), %eax
22159 + movl $0, 8(%esp)
22160 + movl %eax, 4(%esp)
22161 + movl %ebx, (%esp)
22162 + call des_encrypt2
22163 + movl $1, 8(%esp)
22164 + movl %edi, 4(%esp)
22165 + movl %ebx, (%esp)
22166 + call des_encrypt2
22167 + movl $0, 8(%esp)
22168 + movl %esi, 4(%esp)
22169 + movl %ebx, (%esp)
22170 + call des_encrypt2
22171 + addl $12, %esp
22172 + movl (%ebx), %edi
22173 + movl 4(%ebx), %esi
22174 +
22175 +
22176 + roll $2, %esi
22177 + roll $3, %edi
22178 + movl %edi, %eax
22179 + xorl %esi, %edi
22180 + andl $0xaaaaaaaa, %edi
22181 + xorl %edi, %eax
22182 + xorl %edi, %esi
22183 +
22184 + roll $23, %eax
22185 + movl %eax, %edi
22186 + xorl %esi, %eax
22187 + andl $0x03fc03fc, %eax
22188 + xorl %eax, %edi
22189 + xorl %eax, %esi
22190 +
22191 + roll $10, %edi
22192 + movl %edi, %eax
22193 + xorl %esi, %edi
22194 + andl $0x33333333, %edi
22195 + xorl %edi, %eax
22196 + xorl %edi, %esi
22197 +
22198 + roll $18, %esi
22199 + movl %esi, %edi
22200 + xorl %eax, %esi
22201 + andl $0xfff0000f, %esi
22202 + xorl %esi, %edi
22203 + xorl %esi, %eax
22204 +
22205 + roll $12, %edi
22206 + movl %edi, %esi
22207 + xorl %eax, %edi
22208 + andl $0xf0f0f0f0, %edi
22209 + xorl %edi, %esi
22210 + xorl %edi, %eax
22211 +
22212 + rorl $4, %eax
22213 + movl %eax, (%ebx)
22214 + movl %esi, 4(%ebx)
22215 + popl %edi
22216 + popl %esi
22217 + popl %ebp
22218 + popl %ebx
22219 + ret
22220 +.des_decrypt3_end:
22221 + .size des_decrypt3 , .des_decrypt3_end-des_decrypt3
22222 +.ident "desasm.pl"
22223 +.text
22224 + .align 16
22225 +.globl des_ncbc_encrypt
22226 + .type des_ncbc_encrypt , @function
22227 +des_ncbc_encrypt:
22228 +
22229 + pushl %ebp
22230 + pushl %ebx
22231 + pushl %esi
22232 + pushl %edi
22233 + movl 28(%esp), %ebp
22234 +
22235 + movl 36(%esp), %ebx
22236 + movl (%ebx), %esi
22237 + movl 4(%ebx), %edi
22238 + pushl %edi
22239 + pushl %esi
22240 + pushl %edi
22241 + pushl %esi
22242 + movl %esp, %ebx
22243 + movl 36(%esp), %esi
22244 + movl 40(%esp), %edi
22245 +
22246 + movl 56(%esp), %ecx
22247 +
22248 + pushl %ecx
22249 +
22250 + movl 52(%esp), %eax
22251 + pushl %eax
22252 + pushl %ebx
22253 + cmpl $0, %ecx
22254 + jz .L004decrypt
22255 + andl $4294967288, %ebp
22256 + movl 12(%esp), %eax
22257 + movl 16(%esp), %ebx
22258 + jz .L005encrypt_finish
22259 +.L006encrypt_loop:
22260 + movl (%esi), %ecx
22261 + movl 4(%esi), %edx
22262 + xorl %ecx, %eax
22263 + xorl %edx, %ebx
22264 + movl %eax, 12(%esp)
22265 + movl %ebx, 16(%esp)
22266 + call des_encrypt
22267 + movl 12(%esp), %eax
22268 + movl 16(%esp), %ebx
22269 + movl %eax, (%edi)
22270 + movl %ebx, 4(%edi)
22271 + addl $8, %esi
22272 + addl $8, %edi
22273 + subl $8, %ebp
22274 + jnz .L006encrypt_loop
22275 +.L005encrypt_finish:
22276 + movl 56(%esp), %ebp
22277 + andl $7, %ebp
22278 + jz .L007finish
22279 + xorl %ecx, %ecx
22280 + xorl %edx, %edx
22281 + movl .L008cbc_enc_jmp_table(,%ebp,4),%ebp
22282 + jmp *%ebp
22283 +.L009ej7:
22284 + movb 6(%esi), %dh
22285 + sall $8, %edx
22286 +.L010ej6:
22287 + movb 5(%esi), %dh
22288 +.L011ej5:
22289 + movb 4(%esi), %dl
22290 +.L012ej4:
22291 + movl (%esi), %ecx
22292 + jmp .L013ejend
22293 +.L014ej3:
22294 + movb 2(%esi), %ch
22295 + sall $8, %ecx
22296 +.L015ej2:
22297 + movb 1(%esi), %ch
22298 +.L016ej1:
22299 + movb (%esi), %cl
22300 +.L013ejend:
22301 + xorl %ecx, %eax
22302 + xorl %edx, %ebx
22303 + movl %eax, 12(%esp)
22304 + movl %ebx, 16(%esp)
22305 + call des_encrypt
22306 + movl 12(%esp), %eax
22307 + movl 16(%esp), %ebx
22308 + movl %eax, (%edi)
22309 + movl %ebx, 4(%edi)
22310 + jmp .L007finish
22311 +.align 16
22312 +.L004decrypt:
22313 + andl $4294967288, %ebp
22314 + movl 20(%esp), %eax
22315 + movl 24(%esp), %ebx
22316 + jz .L017decrypt_finish
22317 +.L018decrypt_loop:
22318 + movl (%esi), %eax
22319 + movl 4(%esi), %ebx
22320 + movl %eax, 12(%esp)
22321 + movl %ebx, 16(%esp)
22322 + call des_encrypt
22323 + movl 12(%esp), %eax
22324 + movl 16(%esp), %ebx
22325 + movl 20(%esp), %ecx
22326 + movl 24(%esp), %edx
22327 + xorl %eax, %ecx
22328 + xorl %ebx, %edx
22329 + movl (%esi), %eax
22330 + movl 4(%esi), %ebx
22331 + movl %ecx, (%edi)
22332 + movl %edx, 4(%edi)
22333 + movl %eax, 20(%esp)
22334 + movl %ebx, 24(%esp)
22335 + addl $8, %esi
22336 + addl $8, %edi
22337 + subl $8, %ebp
22338 + jnz .L018decrypt_loop
22339 +.L017decrypt_finish:
22340 + movl 56(%esp), %ebp
22341 + andl $7, %ebp
22342 + jz .L007finish
22343 + movl (%esi), %eax
22344 + movl 4(%esi), %ebx
22345 + movl %eax, 12(%esp)
22346 + movl %ebx, 16(%esp)
22347 + call des_encrypt
22348 + movl 12(%esp), %eax
22349 + movl 16(%esp), %ebx
22350 + movl 20(%esp), %ecx
22351 + movl 24(%esp), %edx
22352 + xorl %eax, %ecx
22353 + xorl %ebx, %edx
22354 + movl (%esi), %eax
22355 + movl 4(%esi), %ebx
22356 +.L019dj7:
22357 + rorl $16, %edx
22358 + movb %dl, 6(%edi)
22359 + shrl $16, %edx
22360 +.L020dj6:
22361 + movb %dh, 5(%edi)
22362 +.L021dj5:
22363 + movb %dl, 4(%edi)
22364 +.L022dj4:
22365 + movl %ecx, (%edi)
22366 + jmp .L023djend
22367 +.L024dj3:
22368 + rorl $16, %ecx
22369 + movb %cl, 2(%edi)
22370 + sall $16, %ecx
22371 +.L025dj2:
22372 + movb %ch, 1(%esi)
22373 +.L026dj1:
22374 + movb %cl, (%esi)
22375 +.L023djend:
22376 + jmp .L007finish
22377 +.align 16
22378 +.L007finish:
22379 + movl 64(%esp), %ecx
22380 + addl $28, %esp
22381 + movl %eax, (%ecx)
22382 + movl %ebx, 4(%ecx)
22383 + popl %edi
22384 + popl %esi
22385 + popl %ebx
22386 + popl %ebp
22387 + ret
22388 +.align 16
22389 +.L008cbc_enc_jmp_table:
22390 + .long 0
22391 + .long .L016ej1
22392 + .long .L015ej2
22393 + .long .L014ej3
22394 + .long .L012ej4
22395 + .long .L011ej5
22396 + .long .L010ej6
22397 + .long .L009ej7
22398 +.align 16
22399 +.L027cbc_dec_jmp_table:
22400 + .long 0
22401 + .long .L026dj1
22402 + .long .L025dj2
22403 + .long .L024dj3
22404 + .long .L022dj4
22405 + .long .L021dj5
22406 + .long .L020dj6
22407 + .long .L019dj7
22408 +.des_ncbc_encrypt_end:
22409 + .size des_ncbc_encrypt , .des_ncbc_encrypt_end-des_ncbc_encrypt
22410 +.ident "desasm.pl"
22411 +.text
22412 + .align 16
22413 +.globl des_ede3_cbc_encrypt
22414 + .type des_ede3_cbc_encrypt , @function
22415 +des_ede3_cbc_encrypt:
22416 +
22417 + pushl %ebp
22418 + pushl %ebx
22419 + pushl %esi
22420 + pushl %edi
22421 + movl 28(%esp), %ebp
22422 +
22423 + movl 44(%esp), %ebx
22424 + movl (%ebx), %esi
22425 + movl 4(%ebx), %edi
22426 + pushl %edi
22427 + pushl %esi
22428 + pushl %edi
22429 + pushl %esi
22430 + movl %esp, %ebx
22431 + movl 36(%esp), %esi
22432 + movl 40(%esp), %edi
22433 +
22434 + movl 64(%esp), %ecx
22435 +
22436 + movl 56(%esp), %eax
22437 + pushl %eax
22438 +
22439 + movl 56(%esp), %eax
22440 + pushl %eax
22441 +
22442 + movl 56(%esp), %eax
22443 + pushl %eax
22444 + pushl %ebx
22445 + cmpl $0, %ecx
22446 + jz .L028decrypt
22447 + andl $4294967288, %ebp
22448 + movl 16(%esp), %eax
22449 + movl 20(%esp), %ebx
22450 + jz .L029encrypt_finish
22451 +.L030encrypt_loop:
22452 + movl (%esi), %ecx
22453 + movl 4(%esi), %edx
22454 + xorl %ecx, %eax
22455 + xorl %edx, %ebx
22456 + movl %eax, 16(%esp)
22457 + movl %ebx, 20(%esp)
22458 + call des_encrypt3
22459 + movl 16(%esp), %eax
22460 + movl 20(%esp), %ebx
22461 + movl %eax, (%edi)
22462 + movl %ebx, 4(%edi)
22463 + addl $8, %esi
22464 + addl $8, %edi
22465 + subl $8, %ebp
22466 + jnz .L030encrypt_loop
22467 +.L029encrypt_finish:
22468 + movl 60(%esp), %ebp
22469 + andl $7, %ebp
22470 + jz .L031finish
22471 + xorl %ecx, %ecx
22472 + xorl %edx, %edx
22473 + movl .L032cbc_enc_jmp_table(,%ebp,4),%ebp
22474 + jmp *%ebp
22475 +.L033ej7:
22476 + movb 6(%esi), %dh
22477 + sall $8, %edx
22478 +.L034ej6:
22479 + movb 5(%esi), %dh
22480 +.L035ej5:
22481 + movb 4(%esi), %dl
22482 +.L036ej4:
22483 + movl (%esi), %ecx
22484 + jmp .L037ejend
22485 +.L038ej3:
22486 + movb 2(%esi), %ch
22487 + sall $8, %ecx
22488 +.L039ej2:
22489 + movb 1(%esi), %ch
22490 +.L040ej1:
22491 + movb (%esi), %cl
22492 +.L037ejend:
22493 + xorl %ecx, %eax
22494 + xorl %edx, %ebx
22495 + movl %eax, 16(%esp)
22496 + movl %ebx, 20(%esp)
22497 + call des_encrypt3
22498 + movl 16(%esp), %eax
22499 + movl 20(%esp), %ebx
22500 + movl %eax, (%edi)
22501 + movl %ebx, 4(%edi)
22502 + jmp .L031finish
22503 +.align 16
22504 +.L028decrypt:
22505 + andl $4294967288, %ebp
22506 + movl 24(%esp), %eax
22507 + movl 28(%esp), %ebx
22508 + jz .L041decrypt_finish
22509 +.L042decrypt_loop:
22510 + movl (%esi), %eax
22511 + movl 4(%esi), %ebx
22512 + movl %eax, 16(%esp)
22513 + movl %ebx, 20(%esp)
22514 + call des_decrypt3
22515 + movl 16(%esp), %eax
22516 + movl 20(%esp), %ebx
22517 + movl 24(%esp), %ecx
22518 + movl 28(%esp), %edx
22519 + xorl %eax, %ecx
22520 + xorl %ebx, %edx
22521 + movl (%esi), %eax
22522 + movl 4(%esi), %ebx
22523 + movl %ecx, (%edi)
22524 + movl %edx, 4(%edi)
22525 + movl %eax, 24(%esp)
22526 + movl %ebx, 28(%esp)
22527 + addl $8, %esi
22528 + addl $8, %edi
22529 + subl $8, %ebp
22530 + jnz .L042decrypt_loop
22531 +.L041decrypt_finish:
22532 + movl 60(%esp), %ebp
22533 + andl $7, %ebp
22534 + jz .L031finish
22535 + movl (%esi), %eax
22536 + movl 4(%esi), %ebx
22537 + movl %eax, 16(%esp)
22538 + movl %ebx, 20(%esp)
22539 + call des_decrypt3
22540 + movl 16(%esp), %eax
22541 + movl 20(%esp), %ebx
22542 + movl 24(%esp), %ecx
22543 + movl 28(%esp), %edx
22544 + xorl %eax, %ecx
22545 + xorl %ebx, %edx
22546 + movl (%esi), %eax
22547 + movl 4(%esi), %ebx
22548 +.L043dj7:
22549 + rorl $16, %edx
22550 + movb %dl, 6(%edi)
22551 + shrl $16, %edx
22552 +.L044dj6:
22553 + movb %dh, 5(%edi)
22554 +.L045dj5:
22555 + movb %dl, 4(%edi)
22556 +.L046dj4:
22557 + movl %ecx, (%edi)
22558 + jmp .L047djend
22559 +.L048dj3:
22560 + rorl $16, %ecx
22561 + movb %cl, 2(%edi)
22562 + sall $16, %ecx
22563 +.L049dj2:
22564 + movb %ch, 1(%esi)
22565 +.L050dj1:
22566 + movb %cl, (%esi)
22567 +.L047djend:
22568 + jmp .L031finish
22569 +.align 16
22570 +.L031finish:
22571 + movl 76(%esp), %ecx
22572 + addl $32, %esp
22573 + movl %eax, (%ecx)
22574 + movl %ebx, 4(%ecx)
22575 + popl %edi
22576 + popl %esi
22577 + popl %ebx
22578 + popl %ebp
22579 + ret
22580 +.align 16
22581 +.L032cbc_enc_jmp_table:
22582 + .long 0
22583 + .long .L040ej1
22584 + .long .L039ej2
22585 + .long .L038ej3
22586 + .long .L036ej4
22587 + .long .L035ej5
22588 + .long .L034ej6
22589 + .long .L033ej7
22590 +.align 16
22591 +.L051cbc_dec_jmp_table:
22592 + .long 0
22593 + .long .L050dj1
22594 + .long .L049dj2
22595 + .long .L048dj3
22596 + .long .L046dj4
22597 + .long .L045dj5
22598 + .long .L044dj6
22599 + .long .L043dj7
22600 +.des_ede3_cbc_encrypt_end:
22601 + .size des_ede3_cbc_encrypt , .des_ede3_cbc_encrypt_end-des_ede3_cbc_encrypt
22602 +.ident "desasm.pl"
22603 --- /dev/null Tue Mar 11 13:02:56 2003
22604 +++ linux/net/ipsec/des/ecb_enc.c Mon Feb 9 13:51:03 2004
22605 @@ -0,0 +1,135 @@
22606 +/* crypto/des/ecb_enc.c */
22607 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
22608 + * All rights reserved.
22609 + *
22610 + * This package is an SSL implementation written
22611 + * by Eric Young (eay@cryptsoft.com).
22612 + * The implementation was written so as to conform with Netscapes SSL.
22613 + *
22614 + * This library is free for commercial and non-commercial use as long as
22615 + * the following conditions are aheared to. The following conditions
22616 + * apply to all code found in this distribution, be it the RC4, RSA,
22617 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
22618 + * included with this distribution is covered by the same copyright terms
22619 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
22620 + *
22621 + * Copyright remains Eric Young's, and as such any Copyright notices in
22622 + * the code are not to be removed.
22623 + * If this package is used in a product, Eric Young should be given attribution
22624 + * as the author of the parts of the library used.
22625 + * This can be in the form of a textual message at program startup or
22626 + * in documentation (online or textual) provided with the package.
22627 + *
22628 + * Redistribution and use in source and binary forms, with or without
22629 + * modification, are permitted provided that the following conditions
22630 + * are met:
22631 + * 1. Redistributions of source code must retain the copyright
22632 + * notice, this list of conditions and the following disclaimer.
22633 + * 2. Redistributions in binary form must reproduce the above copyright
22634 + * notice, this list of conditions and the following disclaimer in the
22635 + * documentation and/or other materials provided with the distribution.
22636 + * 3. All advertising materials mentioning features or use of this software
22637 + * must display the following acknowledgement:
22638 + * "This product includes cryptographic software written by
22639 + * Eric Young (eay@cryptsoft.com)"
22640 + * The word 'cryptographic' can be left out if the rouines from the library
22641 + * being used are not cryptographic related :-).
22642 + * 4. If you include any Windows specific code (or a derivative thereof) from
22643 + * the apps directory (application code) you must include an acknowledgement:
22644 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
22645 + *
22646 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
22647 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22648 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22649 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22650 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22651 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22652 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22653 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22654 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22655 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22656 + * SUCH DAMAGE.
22657 + *
22658 + * The licence and distribution terms for any publically available version or
22659 + * derivative of this code cannot be changed. i.e. this code cannot simply be
22660 + * copied and put under another distribution licence
22661 + * [including the GNU Public Licence.]
22662 + */
22663 +
22664 +#include "des/des_locl.h"
22665 +#include "des/spr.h"
22666 +
22667 +char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay";
22668 +char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998";
22669 +
22670 +/* RCSID $Id: ecb_enc.c,v 1.8 2004/08/04 15:57:22 mcr Exp $ */
22671 +/* This function ifdef'ed out for FreeS/WAN project. */
22672 +#ifdef notdef
22673 +char *des_options()
22674 + {
22675 + static int init=1;
22676 + static char buf[32];
22677 +
22678 + if (init)
22679 + {
22680 + char *ptr,*unroll,*risc,*size;
22681 +
22682 + init=0;
22683 +#ifdef DES_PTR
22684 + ptr="ptr";
22685 +#else
22686 + ptr="idx";
22687 +#endif
22688 +#if defined(DES_RISC1) || defined(DES_RISC2)
22689 +#ifdef DES_RISC1
22690 + risc="risc1";
22691 +#endif
22692 +#ifdef DES_RISC2
22693 + risc="risc2";
22694 +#endif
22695 +#else
22696 + risc="cisc";
22697 +#endif
22698 +#ifdef DES_UNROLL
22699 + unroll="16";
22700 +#else
22701 + unroll="4";
22702 +#endif
22703 + if (sizeof(DES_LONG) != sizeof(long))
22704 + size="int";
22705 + else
22706 + size="long";
22707 + sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);
22708 + }
22709 + return(buf);
22710 + }
22711 +#endif
22712 +
22713 +
22714 +void des_ecb_encrypt(input, output, ks, enc)
22715 +des_cblock (*input);
22716 +des_cblock (*output);
22717 +des_key_schedule ks;
22718 +int enc;
22719 + {
22720 + register DES_LONG l;
22721 + register unsigned char *in,*out;
22722 + DES_LONG ll[2];
22723 +
22724 +#ifdef OCF_ASSIST
22725 + if (ocf_des_assist() & OCF_PROVIDES_DES_3DES) {
22726 + ocf_des_ecb_encrypt(input, output, ks, enc);
22727 + return;
22728 + }
22729 +#endif
22730 +
22731 + in=(unsigned char *)input;
22732 + out=(unsigned char *)output;
22733 + c2l(in,l); ll[0]=l;
22734 + c2l(in,l); ll[1]=l;
22735 + des_encrypt(ll,ks,enc);
22736 + l=ll[0]; l2c(l,out);
22737 + l=ll[1]; l2c(l,out);
22738 + l=ll[0]=ll[1]=0;
22739 + }
22740 +
22741 --- /dev/null Tue Mar 11 13:02:56 2003
22742 +++ linux/net/ipsec/des/ipsec_alg_3des.c Mon Feb 9 13:51:03 2004
22743 @@ -0,0 +1,182 @@
22744 +/*
22745 + * ipsec_alg 3DES cipher stubs
22746 + *
22747 + * Copyright (C) 2005 Michael Richardson <mcr@xelerance.com>
22748 + *
22749 + * Adapted from ipsec_alg_aes.c by JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
22750 + *
22751 + * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
22752 + *
22753 + * This program is free software; you can redistribute it and/or modify it
22754 + * under the terms of the GNU General Public License as published by the
22755 + * Free Software Foundation; either version 2 of the License, or (at your
22756 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
22757 + *
22758 + * This program is distributed in the hope that it will be useful, but
22759 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22760 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22761 + * for more details.
22762 + *
22763 + */
22764 +#ifndef AUTOCONF_INCLUDED
22765 +#include <linux/config.h>
22766 +#endif
22767 +#include <linux/version.h>
22768 +
22769 +/*
22770 + * special case: ipsec core modular with this static algo inside:
22771 + * must avoid MODULE magic for this file
22772 + */
22773 +#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_3DES)
22774 +#undef MODULE
22775 +#endif
22776 +
22777 +#include <linux/module.h>
22778 +#include <linux/init.h>
22779 +
22780 +#include <linux/kernel.h> /* printk() */
22781 +#include <linux/errno.h> /* error codes */
22782 +#include <linux/types.h> /* size_t */
22783 +#include <linux/string.h>
22784 +
22785 +/* Low freeswan header coupling */
22786 +#include "openswan/ipsec_xform.h"
22787 +#include "openswan/ipsec_alg.h"
22788 +#include "klips-crypto/des.h"
22789 +#include "openswan/ipsec_alg_3des.h"
22790 +
22791 +#define AES_CONTEXT_T aes_context
22792 +static int debug_3des=0;
22793 +static int test_3des=0;
22794 +static int excl_3des=0;
22795 +
22796 +#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
22797 +MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
22798 +#ifdef module_param
22799 +module_param(debug_3des, int, 0664);
22800 +module_param(test_des, int, 0664);
22801 +module_param(excl_des, int, 0664);
22802 +#else
22803 +MODULE_PARM(debug_3des, "i");
22804 +MODULE_PARM(test_des, "i");
22805 +MODULE_PARM(excl_des, "i");
22806 +#endif
22807 +#endif
22808 +
22809 +#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
22810 +#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
22811 +
22812 +static int _3des_set_key(struct ipsec_alg_enc *alg,
22813 + __u8 * key_e, const __u8 * key,
22814 + size_t keysize)
22815 +{
22816 + int ret = 0;
22817 + TripleDES_context *ctx = (TripleDES_context*)key_e;
22818 +
22819 + if(keysize != 192/8) {
22820 + return EINVAL;
22821 + }
22822 +
22823 + des_set_key((des_cblock *)(key + DES_KEY_SZ*0), ctx->s1);
22824 + des_set_key((des_cblock *)(key + DES_KEY_SZ*1), ctx->s2);
22825 + des_set_key((des_cblock *)(key + DES_KEY_SZ*2), ctx->s3);
22826 +
22827 + if (debug_3des > 0)
22828 + printk(KERN_DEBUG "klips_debug:_3des_set_key:"
22829 + "ret=%d key_e=%p key=%p keysize=%ld\n",
22830 + ret, key_e, key, (unsigned long int) keysize);
22831 + return ret;
22832 +}
22833 +
22834 +static int _3des_cbc_encrypt(struct ipsec_alg_enc *alg,
22835 + __u8 * key_e,
22836 + const __u8 * in,
22837 + int ilen, const __u8 * iv,
22838 + int encrypt)
22839 +{
22840 + TripleDES_context *ctx=(TripleDES_context*)key_e;
22841 + des_cblock miv;
22842 +
22843 + memcpy(&miv, iv, sizeof(miv));
22844 +
22845 + if (debug_3des > 0)
22846 + printk(KERN_DEBUG "klips_debug:_3des_cbc_encrypt:"
22847 + "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
22848 + key_e, in, ilen, iv, encrypt);
22849 +
22850 + des_ede3_cbc_encrypt((des_cblock *)in,
22851 + (des_cblock *)in,
22852 + ilen,
22853 + ctx->s1,
22854 + ctx->s2,
22855 + ctx->s3,
22856 + &miv, encrypt);
22857 + return 1;
22858 +}
22859 +
22860 +static struct ipsec_alg_enc ipsec_alg_3DES = {
22861 + ixt_common: { ixt_version: IPSEC_ALG_VERSION,
22862 + ixt_refcnt: ATOMIC_INIT(0),
22863 + ixt_name: "3des",
22864 + ixt_blocksize: ESP_3DES_CBC_BLK_LEN,
22865 + ixt_support: {
22866 + ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
22867 + ias_id: ESP_3DES,
22868 + //ias_ivlen: 64,
22869 + ias_keyminbits: ESP_3DES_KEY_SZ*8,
22870 + ias_keymaxbits: ESP_3DES_KEY_SZ*8,
22871 + },
22872 + },
22873 +#if defined(MODULE_KLIPS_ENC_3DES_MODULE)
22874 + ixt_module: THIS_MODULE,
22875 +#endif
22876 + ixt_e_keylen: ESP_3DES_KEY_SZ*8,
22877 + ixt_e_ctx_size: sizeof(TripleDES_context),
22878 + ixt_e_set_key: _3des_set_key,
22879 + ixt_e_cbc_encrypt:_3des_cbc_encrypt,
22880 +};
22881 +
22882 +#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
22883 +IPSEC_ALG_MODULE_INIT_MOD( ipsec_3des_init )
22884 +#else
22885 +IPSEC_ALG_MODULE_INIT_STATIC( ipsec_3des_init )
22886 +#endif
22887 +{
22888 + int ret, test_ret;
22889 +
22890 + if (excl_3des) ipsec_alg_3DES.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
22891 + ret=register_ipsec_alg_enc(&ipsec_alg_3DES);
22892 + printk("ipsec_3des_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
22893 + ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
22894 + ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
22895 + ipsec_alg_3DES.ixt_common.ixt_name,
22896 + ret);
22897 + if (ret==0 && test_3des) {
22898 + test_ret=ipsec_alg_test(
22899 + ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
22900 + ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
22901 + test_3des);
22902 + printk("ipsec_3des_init(alg_type=%d alg_id=%d): test_ret=%d\n",
22903 + ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
22904 + ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
22905 + test_ret);
22906 + }
22907 + return ret;
22908 +}
22909 +
22910 +#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
22911 +IPSEC_ALG_MODULE_EXIT_MOD( ipsec_3des_fini )
22912 +#else
22913 +IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_3des_fini )
22914 +#endif
22915 +{
22916 + unregister_ipsec_alg_enc(&ipsec_alg_3DES);
22917 + return;
22918 +}
22919 +
22920 +/* Dual, because 3des code is 4-clause BSD licensed */
22921 +#ifdef MODULE_LICENSE
22922 +MODULE_LICENSE("Dual BSD/GPL");
22923 +#endif
22924 +
22925 +
22926 --- /dev/null Tue Mar 11 13:02:56 2003
22927 +++ linux/net/ipsec/des/set_key.c Mon Feb 9 13:51:03 2004
22928 @@ -0,0 +1,251 @@
22929 +/* crypto/des/set_key.c */
22930 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
22931 + * All rights reserved.
22932 + *
22933 + * This package is an SSL implementation written
22934 + * by Eric Young (eay@cryptsoft.com).
22935 + * The implementation was written so as to conform with Netscapes SSL.
22936 + *
22937 + * This library is free for commercial and non-commercial use as long as
22938 + * the following conditions are aheared to. The following conditions
22939 + * apply to all code found in this distribution, be it the RC4, RSA,
22940 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
22941 + * included with this distribution is covered by the same copyright terms
22942 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
22943 + *
22944 + * Copyright remains Eric Young's, and as such any Copyright notices in
22945 + * the code are not to be removed.
22946 + * If this package is used in a product, Eric Young should be given attribution
22947 + * as the author of the parts of the library used.
22948 + * This can be in the form of a textual message at program startup or
22949 + * in documentation (online or textual) provided with the package.
22950 + *
22951 + * Redistribution and use in source and binary forms, with or without
22952 + * modification, are permitted provided that the following conditions
22953 + * are met:
22954 + * 1. Redistributions of source code must retain the copyright
22955 + * notice, this list of conditions and the following disclaimer.
22956 + * 2. Redistributions in binary form must reproduce the above copyright
22957 + * notice, this list of conditions and the following disclaimer in the
22958 + * documentation and/or other materials provided with the distribution.
22959 + * 3. All advertising materials mentioning features or use of this software
22960 + * must display the following acknowledgement:
22961 + * "This product includes cryptographic software written by
22962 + * Eric Young (eay@cryptsoft.com)"
22963 + * The word 'cryptographic' can be left out if the rouines from the library
22964 + * being used are not cryptographic related :-).
22965 + * 4. If you include any Windows specific code (or a derivative thereof) from
22966 + * the apps directory (application code) you must include an acknowledgement:
22967 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
22968 + *
22969 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
22970 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22971 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22972 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22973 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22974 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22975 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22976 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22977 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22978 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22979 + * SUCH DAMAGE.
22980 + *
22981 + * The licence and distribution terms for any publically available version or
22982 + * derivative of this code cannot be changed. i.e. this code cannot simply be
22983 + * copied and put under another distribution licence
22984 + * [including the GNU Public Licence.]
22985 + */
22986 +
22987 +/* set_key.c v 1.4 eay 24/9/91
22988 + * 1.4 Speed up by 400% :-)
22989 + * 1.3 added register declarations.
22990 + * 1.2 unrolled make_key_sched a bit more
22991 + * 1.1 added norm_expand_bits
22992 + * 1.0 First working version
22993 + */
22994 +#include "des/des_locl.h"
22995 +#include "des/podd.h"
22996 +#include "des/sk.h"
22997 +
22998 +#ifndef NOPROTO
22999 +static int check_parity(des_cblock (*key));
23000 +#else
23001 +static int check_parity();
23002 +#endif
23003 +
23004 +int des_check_key=0;
23005 +
23006 +void des_set_odd_parity(key)
23007 +des_cblock (*key);
23008 + {
23009 + int i;
23010 +
23011 + for (i=0; i<DES_KEY_SZ; i++)
23012 + (*key)[i]=odd_parity[(*key)[i]];
23013 + }
23014 +
23015 +static int check_parity(key)
23016 +des_cblock (*key);
23017 + {
23018 + int i;
23019 +
23020 + for (i=0; i<DES_KEY_SZ; i++)
23021 + {
23022 + if ((*key)[i] != odd_parity[(*key)[i]])
23023 + return(0);
23024 + }
23025 + return(1);
23026 + }
23027 +
23028 +/* Weak and semi week keys as take from
23029 + * %A D.W. Davies
23030 + * %A W.L. Price
23031 + * %T Security for Computer Networks
23032 + * %I John Wiley & Sons
23033 + * %D 1984
23034 + * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
23035 + * (and actual cblock values).
23036 + */
23037 +#define NUM_WEAK_KEY 16
23038 +static des_cblock weak_keys[NUM_WEAK_KEY]={
23039 + /* weak keys */
23040 + {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
23041 + {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
23042 + {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
23043 + {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
23044 + /* semi-weak keys */
23045 + {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
23046 + {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
23047 + {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
23048 + {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
23049 + {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
23050 + {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
23051 + {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
23052 + {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
23053 + {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
23054 + {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
23055 + {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
23056 + {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
23057 +
23058 +int des_is_weak_key(key)
23059 +des_cblock (*key);
23060 + {
23061 + int i;
23062 +
23063 + for (i=0; i<NUM_WEAK_KEY; i++)
23064 + /* Added == 0 to comparision, I obviously don't run
23065 + * this section very often :-(, thanks to
23066 + * engineering@MorningStar.Com for the fix
23067 + * eay 93/06/29
23068 + * Another problem, I was comparing only the first 4
23069 + * bytes, 97/03/18 */
23070 + if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1);
23071 + return(0);
23072 + }
23073 +
23074 +/* NOW DEFINED IN des_local.h
23075 + * See ecb_encrypt.c for a pseudo description of these macros.
23076 + * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
23077 + * (b)^=(t),\
23078 + * (a)=((a)^((t)<<(n))))
23079 + */
23080 +
23081 +#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
23082 + (a)=(a)^(t)^(t>>(16-(n))))
23083 +
23084 +/* return 0 if key parity is odd (correct),
23085 + * return -1 if key parity error,
23086 + * return -2 if illegal weak key.
23087 + */
23088 +int des_set_key(key, schedule)
23089 +des_cblock (*key);
23090 +des_key_schedule schedule;
23091 + {
23092 + static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
23093 + register DES_LONG c,d,t,s,t2;
23094 + register unsigned char *in;
23095 + register DES_LONG *k;
23096 + register int i;
23097 +
23098 + if (des_check_key)
23099 + {
23100 + if (!check_parity(key))
23101 + return(-1);
23102 +
23103 + if (des_is_weak_key(key))
23104 + return(-2);
23105 + }
23106 +
23107 +#ifdef OCF_ASSIST
23108 + if (ocf_des_assist() & OCF_PROVIDES_DES_3DES)
23109 + return(ocf_des_set_key(key, schedule));
23110 +#endif
23111 +
23112 + k=(DES_LONG *)schedule;
23113 + in=(unsigned char *)key;
23114 +
23115 + c2l(in,c);
23116 + c2l(in,d);
23117 +
23118 + /* do PC1 in 60 simple operations */
23119 +/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
23120 + HPERM_OP(c,t,-2, 0xcccc0000L);
23121 + HPERM_OP(c,t,-1, 0xaaaa0000L);
23122 + HPERM_OP(c,t, 8, 0x00ff0000L);
23123 + HPERM_OP(c,t,-1, 0xaaaa0000L);
23124 + HPERM_OP(d,t,-8, 0xff000000L);
23125 + HPERM_OP(d,t, 8, 0x00ff0000L);
23126 + HPERM_OP(d,t, 2, 0x33330000L);
23127 + d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
23128 + d=(d>>8)|((c&0xf0000000L)>>4);
23129 + c&=0x0fffffffL; */
23130 +
23131 + /* I now do it in 47 simple operations :-)
23132 + * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
23133 + * for the inspiration. :-) */
23134 + PERM_OP (d,c,t,4,0x0f0f0f0fL);
23135 + HPERM_OP(c,t,-2,0xcccc0000L);
23136 + HPERM_OP(d,t,-2,0xcccc0000L);
23137 + PERM_OP (d,c,t,1,0x55555555L);
23138 + PERM_OP (c,d,t,8,0x00ff00ffL);
23139 + PERM_OP (d,c,t,1,0x55555555L);
23140 + d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
23141 + ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
23142 + c&=0x0fffffffL;
23143 +
23144 + for (i=0; i<ITERATIONS; i++)
23145 + {
23146 + if (shifts2[i])
23147 + { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
23148 + else
23149 + { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
23150 + c&=0x0fffffffL;
23151 + d&=0x0fffffffL;
23152 + /* could be a few less shifts but I am to lazy at this
23153 + * point in time to investigate */
23154 + s= des_skb[0][ (c )&0x3f ]|
23155 + des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
23156 + des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
23157 + des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
23158 + ((c>>22L)&0x38)];
23159 + t= des_skb[4][ (d )&0x3f ]|
23160 + des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
23161 + des_skb[6][ (d>>15L)&0x3f ]|
23162 + des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
23163 +
23164 + /* table contained 0213 4657 */
23165 + t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
23166 + *(k++)=ROTATE(t2,30)&0xffffffffL;
23167 +
23168 + t2=((s>>16L)|(t&0xffff0000L));
23169 + *(k++)=ROTATE(t2,26)&0xffffffffL;
23170 + }
23171 + return(0);
23172 + }
23173 +
23174 +int des_key_sched(key, schedule)
23175 +des_cblock (*key);
23176 +des_key_schedule schedule;
23177 + {
23178 + return(des_set_key(key,schedule));
23179 + }
23180 --- /dev/null Tue Mar 11 13:02:56 2003
23181 +++ linux/net/ipsec/goodmask.c Mon Feb 9 13:51:03 2004
23182 @@ -0,0 +1,150 @@
23183 +/*
23184 + * minor utilities for subnet-mask manipulation
23185 + * Copyright (C) 1998, 1999 Henry Spencer.
23186 + *
23187 + * This library is free software; you can redistribute it and/or modify it
23188 + * under the terms of the GNU Library General Public License as published by
23189 + * the Free Software Foundation; either version 2 of the License, or (at your
23190 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
23191 + *
23192 + * This library is distributed in the hope that it will be useful, but
23193 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23194 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
23195 + * License for more details.
23196 + *
23197 + * RCSID $Id: goodmask.c,v 1.12 2004/07/10 07:43:47 mcr Exp $
23198 + */
23199 +#include "openswan.h"
23200 +
23201 +#ifndef ABITS
23202 +#define ABITS 32 /* bits in an IPv4 address */
23203 +#endif
23204 +
23205 +/* This file does not use sysdep.h, otherwise this should go into
23206 + * ports/darwin/include/sysdep.h
23207 + */
23208 +#ifndef s6_addr32
23209 +#define s6_addr32 __u6_addr.__u6_addr32
23210 +#endif
23211 +
23212 +/*
23213 + - goodmask - is this a good (^1*0*$) subnet mask?
23214 + * You are not expected to understand this. See Henry S. Warren Jr,
23215 + * "Functions realizable with word-parallel logical and two's-complement
23216 + * addition instructions", CACM 20.6 (June 1977), p.439.
23217 + */
23218 +int /* predicate */
23219 +goodmask(mask)
23220 +struct in_addr mask;
23221 +{
23222 + unsigned long x = ntohl(mask.s_addr);
23223 + /* clear rightmost contiguous string of 1-bits */
23224 +# define CRCS1B(x) (((x|(x-1))+1)&x)
23225 +# define TOPBIT (1UL << 31)
23226 +
23227 + /* either zero, or has one string of 1-bits which is left-justified */
23228 + if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT)))
23229 + return 1;
23230 + return 0;
23231 +}
23232 +
23233 +/*
23234 + - masktobits - how many bits in this mask?
23235 + * The algorithm is essentially a binary search, but highly optimized
23236 + * for this particular task.
23237 + */
23238 +int /* -1 means !goodmask() */
23239 +masktobits(mask)
23240 +struct in_addr mask;
23241 +{
23242 + unsigned long m = ntohl(mask.s_addr);
23243 + int masklen;
23244 +
23245 + if (!goodmask(mask))
23246 + return -1;
23247 +
23248 + if (m&0x00000001UL)
23249 + return 32;
23250 + masklen = 0;
23251 + if (m&(0x0000ffffUL<<1)) { /* <<1 for 1-origin numbering */
23252 + masklen |= 0x10;
23253 + m <<= 16;
23254 + }
23255 + if (m&(0x00ff0000UL<<1)) {
23256 + masklen |= 0x08;
23257 + m <<= 8;
23258 + }
23259 + if (m&(0x0f000000UL<<1)) {
23260 + masklen |= 0x04;
23261 + m <<= 4;
23262 + }
23263 + if (m&(0x30000000UL<<1)) {
23264 + masklen |= 0x02;
23265 + m <<= 2;
23266 + }
23267 + if (m&(0x40000000UL<<1))
23268 + masklen |= 0x01;
23269 +
23270 + return masklen;
23271 +}
23272 +
23273 +/*
23274 + - bitstomask - return a mask with this many high bits on
23275 + */
23276 +struct in_addr
23277 +bitstomask(n)
23278 +int n;
23279 +{
23280 + struct in_addr result;
23281 +
23282 + if (n > 0 && n <= ABITS)
23283 + result.s_addr = htonl(~((1UL << (ABITS - n)) - 1));
23284 + else if (n == 0)
23285 + result.s_addr = 0;
23286 + else
23287 + result.s_addr = 0; /* best error report we can do */
23288 + return result;
23289 +}
23290 +
23291 +/*
23292 + - bitstomask6 - return a mask with this many high bits on
23293 + */
23294 +struct in6_addr
23295 +bitstomask6(n)
23296 +int n;
23297 +{
23298 + struct in6_addr result;
23299 +
23300 + if (n > 0 && n <= 32) {
23301 + result.s6_addr32[0] = htonl(~((1UL << (32 - n)) - 1));
23302 + result.s6_addr32[1]=0;
23303 + result.s6_addr32[2]=0;
23304 + result.s6_addr32[3]=0;
23305 + }
23306 + else if (n > 32 && n <= 64) {
23307 + result.s6_addr32[0]=0xffffffffUL;
23308 + result.s6_addr32[1] = htonl(~((1UL << (64 - n)) - 1));
23309 + result.s6_addr32[2]=0;
23310 + result.s6_addr32[3]=0;
23311 + }
23312 + else if (n > 64 && n <= 96) {
23313 + result.s6_addr32[0]=0xffffffffUL;
23314 + result.s6_addr32[1]=0xffffffffUL;
23315 + result.s6_addr32[2] = htonl(~((1UL << (96 - n)) - 1));
23316 + result.s6_addr32[3]=0;
23317 + }
23318 + else if (n > 96 && n <= 128) {
23319 + result.s6_addr32[0]=0xffffffff;
23320 + result.s6_addr32[1]=0xffffffff;
23321 + result.s6_addr32[2]=0xffffffff;
23322 + result.s6_addr32[3] = htonl(~((1UL << (128 - n)) - 1));
23323 + }
23324 + else {
23325 + result.s6_addr32[0] = 0;
23326 + result.s6_addr32[0] = 0;
23327 + result.s6_addr32[0] = 0;
23328 + result.s6_addr32[0] = 0;
23329 + }
23330 +
23331 + return result;
23332 +}
23333 --- /dev/null Tue Mar 11 13:02:56 2003
23334 +++ linux/net/ipsec/infblock.c Mon Feb 9 13:51:03 2004
23335 @@ -0,0 +1,403 @@
23336 +/* infblock.c -- interpret and process block types to last block
23337 + * Copyright (C) 1995-2002 Mark Adler
23338 + * For conditions of distribution and use, see copyright notice in zlib.h
23339 + */
23340 +
23341 +#include <zlib/zutil.h>
23342 +#include "infblock.h"
23343 +#include "inftrees.h"
23344 +#include "infcodes.h"
23345 +#include "infutil.h"
23346 +
23347 +struct inflate_codes_state {int dummy;}; /* for buggy compilers */
23348 +
23349 +/* simplify the use of the inflate_huft type with some defines */
23350 +#define exop word.what.Exop
23351 +#define bits word.what.Bits
23352 +
23353 +/* Table for deflate from PKZIP's appnote.txt. */
23354 +local const uInt border[] = { /* Order of the bit length code lengths */
23355 + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
23356 +
23357 +/*
23358 + Notes beyond the 1.93a appnote.txt:
23359 +
23360 + 1. Distance pointers never point before the beginning of the output
23361 + stream.
23362 + 2. Distance pointers can point back across blocks, up to 32k away.
23363 + 3. There is an implied maximum of 7 bits for the bit length table and
23364 + 15 bits for the actual data.
23365 + 4. If only one code exists, then it is encoded using one bit. (Zero
23366 + would be more efficient, but perhaps a little confusing.) If two
23367 + codes exist, they are coded using one bit each (0 and 1).
23368 + 5. There is no way of sending zero distance codes--a dummy must be
23369 + sent if there are none. (History: a pre 2.0 version of PKZIP would
23370 + store blocks with no distance codes, but this was discovered to be
23371 + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
23372 + zero distance codes, which is sent as one code of zero bits in
23373 + length.
23374 + 6. There are up to 286 literal/length codes. Code 256 represents the
23375 + end-of-block. Note however that the static length tree defines
23376 + 288 codes just to fill out the Huffman codes. Codes 286 and 287
23377 + cannot be used though, since there is no length base or extra bits
23378 + defined for them. Similarily, there are up to 30 distance codes.
23379 + However, static trees define 32 codes (all 5 bits) to fill out the
23380 + Huffman codes, but the last two had better not show up in the data.
23381 + 7. Unzip can check dynamic Huffman blocks for complete code sets.
23382 + The exception is that a single code would not be complete (see #4).
23383 + 8. The five bits following the block type is really the number of
23384 + literal codes sent minus 257.
23385 + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
23386 + (1+6+6). Therefore, to output three times the length, you output
23387 + three codes (1+1+1), whereas to output four times the same length,
23388 + you only need two codes (1+3). Hmm.
23389 + 10. In the tree reconstruction algorithm, Code = Code + Increment
23390 + only if BitLength(i) is not zero. (Pretty obvious.)
23391 + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
23392 + 12. Note: length code 284 can represent 227-258, but length code 285
23393 + really is 258. The last length deserves its own, short code
23394 + since it gets used a lot in very redundant files. The length
23395 + 258 is special since 258 - 3 (the min match length) is 255.
23396 + 13. The literal/length and distance code bit lengths are read as a
23397 + single stream of lengths. It is possible (and advantageous) for
23398 + a repeat code (16, 17, or 18) to go across the boundary between
23399 + the two sets of lengths.
23400 + */
23401 +
23402 +
23403 +void inflate_blocks_reset(s, z, c)
23404 +inflate_blocks_statef *s;
23405 +z_streamp z;
23406 +uLongf *c;
23407 +{
23408 + if (c != Z_NULL)
23409 + *c = s->check;
23410 + if (s->mode == BTREE || s->mode == DTREE)
23411 + ZFREE(z, s->sub.trees.blens);
23412 + if (s->mode == CODES)
23413 + inflate_codes_free(s->sub.decode.codes, z);
23414 + s->mode = TYPE;
23415 + s->bitk = 0;
23416 + s->bitb = 0;
23417 + s->read = s->write = s->window;
23418 + if (s->checkfn != Z_NULL)
23419 + z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
23420 + Tracev((stderr, "inflate: blocks reset\n"));
23421 +}
23422 +
23423 +
23424 +inflate_blocks_statef *inflate_blocks_new(z, c, w)
23425 +z_streamp z;
23426 +check_func c;
23427 +uInt w;
23428 +{
23429 + inflate_blocks_statef *s;
23430 +
23431 + if ((s = (inflate_blocks_statef *)ZALLOC
23432 + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
23433 + return s;
23434 + if ((s->hufts =
23435 + (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
23436 + {
23437 + ZFREE(z, s);
23438 + return Z_NULL;
23439 + }
23440 + if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
23441 + {
23442 + ZFREE(z, s->hufts);
23443 + ZFREE(z, s);
23444 + return Z_NULL;
23445 + }
23446 + s->end = s->window + w;
23447 + s->checkfn = c;
23448 + s->mode = TYPE;
23449 + Tracev((stderr, "inflate: blocks allocated\n"));
23450 + inflate_blocks_reset(s, z, Z_NULL);
23451 + return s;
23452 +}
23453 +
23454 +
23455 +int inflate_blocks(s, z, r)
23456 +inflate_blocks_statef *s;
23457 +z_streamp z;
23458 +int r;
23459 +{
23460 + uInt t; /* temporary storage */
23461 + uLong b; /* bit buffer */
23462 + uInt k; /* bits in bit buffer */
23463 + Bytef *p; /* input data pointer */
23464 + uInt n; /* bytes available there */
23465 + Bytef *q; /* output window write pointer */
23466 + uInt m; /* bytes to end of window or read pointer */
23467 +
23468 + /* copy input/output information to locals (UPDATE macro restores) */
23469 + LOAD
23470 +
23471 + /* process input based on current state */
23472 + while (1) switch (s->mode)
23473 + {
23474 + case TYPE:
23475 + NEEDBITS(3)
23476 + t = (uInt)b & 7;
23477 + s->last = t & 1;
23478 + switch (t >> 1)
23479 + {
23480 + case 0: /* stored */
23481 + Tracev((stderr, "inflate: stored block%s\n",
23482 + s->last ? " (last)" : ""));
23483 + DUMPBITS(3)
23484 + t = k & 7; /* go to byte boundary */
23485 + DUMPBITS(t)
23486 + s->mode = LENS; /* get length of stored block */
23487 + break;
23488 + case 1: /* fixed */
23489 + Tracev((stderr, "inflate: fixed codes block%s\n",
23490 + s->last ? " (last)" : ""));
23491 + {
23492 + uInt bl, bd;
23493 + inflate_huft *tl, *td;
23494 +
23495 + inflate_trees_fixed(&bl, &bd, &tl, &td, z);
23496 + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
23497 + if (s->sub.decode.codes == Z_NULL)
23498 + {
23499 + r = Z_MEM_ERROR;
23500 + LEAVE
23501 + }
23502 + }
23503 + DUMPBITS(3)
23504 + s->mode = CODES;
23505 + break;
23506 + case 2: /* dynamic */
23507 + Tracev((stderr, "inflate: dynamic codes block%s\n",
23508 + s->last ? " (last)" : ""));
23509 + DUMPBITS(3)
23510 + s->mode = TABLE;
23511 + break;
23512 + case 3: /* illegal */
23513 + DUMPBITS(3)
23514 + s->mode = BAD;
23515 + z->msg = (char*)"invalid block type";
23516 + r = Z_DATA_ERROR;
23517 + LEAVE
23518 + }
23519 + break;
23520 + case LENS:
23521 + NEEDBITS(32)
23522 + if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
23523 + {
23524 + s->mode = BAD;
23525 + z->msg = (char*)"invalid stored block lengths";
23526 + r = Z_DATA_ERROR;
23527 + LEAVE
23528 + }
23529 + s->sub.left = (uInt)b & 0xffff;
23530 + b = k = 0; /* dump bits */
23531 + Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
23532 + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
23533 + break;
23534 + case STORED:
23535 + if (n == 0)
23536 + LEAVE
23537 + NEEDOUT
23538 + t = s->sub.left;
23539 + if (t > n) t = n;
23540 + if (t > m) t = m;
23541 + zmemcpy(q, p, t);
23542 + p += t; n -= t;
23543 + q += t; m -= t;
23544 + if ((s->sub.left -= t) != 0)
23545 + break;
23546 + Tracev((stderr, "inflate: stored end, %lu total out\n",
23547 + z->total_out + (q >= s->read ? q - s->read :
23548 + (s->end - s->read) + (q - s->window))));
23549 + s->mode = s->last ? DRY : TYPE;
23550 + break;
23551 + case TABLE:
23552 + NEEDBITS(14)
23553 + s->sub.trees.table = t = (uInt)b & 0x3fff;
23554 +#ifndef PKZIP_BUG_WORKAROUND
23555 + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
23556 + {
23557 + s->mode = BAD;
23558 + z->msg = (char*)"too many length or distance symbols";
23559 + r = Z_DATA_ERROR;
23560 + LEAVE
23561 + }
23562 +#endif
23563 + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
23564 + if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
23565 + {
23566 + r = Z_MEM_ERROR;
23567 + LEAVE
23568 + }
23569 + DUMPBITS(14)
23570 + s->sub.trees.index = 0;
23571 + Tracev((stderr, "inflate: table sizes ok\n"));
23572 + s->mode = BTREE;
23573 + case BTREE:
23574 + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
23575 + {
23576 + NEEDBITS(3)
23577 + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
23578 + DUMPBITS(3)
23579 + }
23580 + while (s->sub.trees.index < 19)
23581 + s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
23582 + s->sub.trees.bb = 7;
23583 + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
23584 + &s->sub.trees.tb, s->hufts, z);
23585 + if (t != Z_OK)
23586 + {
23587 + r = t;
23588 + if (r == Z_DATA_ERROR)
23589 + {
23590 + ZFREE(z, s->sub.trees.blens);
23591 + s->mode = BAD;
23592 + }
23593 + LEAVE
23594 + }
23595 + s->sub.trees.index = 0;
23596 + Tracev((stderr, "inflate: bits tree ok\n"));
23597 + s->mode = DTREE;
23598 + case DTREE:
23599 + while (t = s->sub.trees.table,
23600 + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
23601 + {
23602 + inflate_huft *h;
23603 + uInt i, j, c;
23604 +
23605 + t = s->sub.trees.bb;
23606 + NEEDBITS(t)
23607 + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
23608 + t = h->bits;
23609 + c = h->base;
23610 + if (c < 16)
23611 + {
23612 + DUMPBITS(t)
23613 + s->sub.trees.blens[s->sub.trees.index++] = c;
23614 + }
23615 + else /* c == 16..18 */
23616 + {
23617 + i = c == 18 ? 7 : c - 14;
23618 + j = c == 18 ? 11 : 3;
23619 + NEEDBITS(t + i)
23620 + DUMPBITS(t)
23621 + j += (uInt)b & inflate_mask[i];
23622 + DUMPBITS(i)
23623 + i = s->sub.trees.index;
23624 + t = s->sub.trees.table;
23625 + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
23626 + (c == 16 && i < 1))
23627 + {
23628 + ZFREE(z, s->sub.trees.blens);
23629 + s->mode = BAD;
23630 + z->msg = (char*)"invalid bit length repeat";
23631 + r = Z_DATA_ERROR;
23632 + LEAVE
23633 + }
23634 + c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
23635 + do {
23636 + s->sub.trees.blens[i++] = c;
23637 + } while (--j);
23638 + s->sub.trees.index = i;
23639 + }
23640 + }
23641 + s->sub.trees.tb = Z_NULL;
23642 + {
23643 + uInt bl, bd;
23644 + inflate_huft *tl, *td;
23645 + inflate_codes_statef *c;
23646 +
23647 + bl = 9; /* must be <= 9 for lookahead assumptions */
23648 + bd = 6; /* must be <= 9 for lookahead assumptions */
23649 + t = s->sub.trees.table;
23650 + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
23651 + s->sub.trees.blens, &bl, &bd, &tl, &td,
23652 + s->hufts, z);
23653 + if (t != Z_OK)
23654 + {
23655 + if (t == (uInt)Z_DATA_ERROR)
23656 + {
23657 + ZFREE(z, s->sub.trees.blens);
23658 + s->mode = BAD;
23659 + }
23660 + r = t;
23661 + LEAVE
23662 + }
23663 + Tracev((stderr, "inflate: trees ok\n"));
23664 + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
23665 + {
23666 + r = Z_MEM_ERROR;
23667 + LEAVE
23668 + }
23669 + s->sub.decode.codes = c;
23670 + }
23671 + ZFREE(z, s->sub.trees.blens);
23672 + s->mode = CODES;
23673 + case CODES:
23674 + UPDATE
23675 + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
23676 + return inflate_flush(s, z, r);
23677 + r = Z_OK;
23678 + inflate_codes_free(s->sub.decode.codes, z);
23679 + LOAD
23680 + Tracev((stderr, "inflate: codes end, %lu total out\n",
23681 + z->total_out + (q >= s->read ? q - s->read :
23682 + (s->end - s->read) + (q - s->window))));
23683 + if (!s->last)
23684 + {
23685 + s->mode = TYPE;
23686 + break;
23687 + }
23688 + s->mode = DRY;
23689 + case DRY:
23690 + FLUSH
23691 + if (s->read != s->write)
23692 + LEAVE
23693 + s->mode = DONE;
23694 + case DONE:
23695 + r = Z_STREAM_END;
23696 + LEAVE
23697 + case BAD:
23698 + r = Z_DATA_ERROR;
23699 + LEAVE
23700 + default:
23701 + r = Z_STREAM_ERROR;
23702 + LEAVE
23703 + }
23704 +}
23705 +
23706 +
23707 +int inflate_blocks_free(s, z)
23708 +inflate_blocks_statef *s;
23709 +z_streamp z;
23710 +{
23711 + inflate_blocks_reset(s, z, Z_NULL);
23712 + ZFREE(z, s->window);
23713 + ZFREE(z, s->hufts);
23714 + ZFREE(z, s);
23715 + Tracev((stderr, "inflate: blocks freed\n"));
23716 + return Z_OK;
23717 +}
23718 +
23719 +
23720 +void inflate_set_dictionary(s, d, n)
23721 +inflate_blocks_statef *s;
23722 +const Bytef *d;
23723 +uInt n;
23724 +{
23725 + zmemcpy(s->window, d, n);
23726 + s->read = s->write = s->window + n;
23727 +}
23728 +
23729 +
23730 +/* Returns true if inflate is currently at the end of a block generated
23731 + * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
23732 + * IN assertion: s != Z_NULL
23733 + */
23734 +int inflate_blocks_sync_point(s)
23735 +inflate_blocks_statef *s;
23736 +{
23737 + return s->mode == LENS;
23738 +}
23739 --- /dev/null Tue Mar 11 13:02:56 2003
23740 +++ linux/net/ipsec/infblock.h Mon Feb 9 13:51:03 2004
23741 @@ -0,0 +1,39 @@
23742 +/* infblock.h -- header to use infblock.c
23743 + * Copyright (C) 1995-2002 Mark Adler
23744 + * For conditions of distribution and use, see copyright notice in zlib.h
23745 + */
23746 +
23747 +/* WARNING: this file should *not* be used by applications. It is
23748 + part of the implementation of the compression library and is
23749 + subject to change. Applications should only use zlib.h.
23750 + */
23751 +
23752 +struct inflate_blocks_state;
23753 +typedef struct inflate_blocks_state FAR inflate_blocks_statef;
23754 +
23755 +extern inflate_blocks_statef * inflate_blocks_new OF((
23756 + z_streamp z,
23757 + check_func c, /* check function */
23758 + uInt w)); /* window size */
23759 +
23760 +extern int inflate_blocks OF((
23761 + inflate_blocks_statef *,
23762 + z_streamp ,
23763 + int)); /* initial return code */
23764 +
23765 +extern void inflate_blocks_reset OF((
23766 + inflate_blocks_statef *,
23767 + z_streamp ,
23768 + uLongf *)); /* check value on output */
23769 +
23770 +extern int inflate_blocks_free OF((
23771 + inflate_blocks_statef *,
23772 + z_streamp));
23773 +
23774 +extern void inflate_set_dictionary OF((
23775 + inflate_blocks_statef *s,
23776 + const Bytef *d, /* dictionary */
23777 + uInt n)); /* dictionary length */
23778 +
23779 +extern int inflate_blocks_sync_point OF((
23780 + inflate_blocks_statef *s));
23781 --- /dev/null Tue Mar 11 13:02:56 2003
23782 +++ linux/net/ipsec/infcodes.c Mon Feb 9 13:51:03 2004
23783 @@ -0,0 +1,251 @@
23784 +/* infcodes.c -- process literals and length/distance pairs
23785 + * Copyright (C) 1995-2002 Mark Adler
23786 + * For conditions of distribution and use, see copyright notice in zlib.h
23787 + */
23788 +
23789 +#include <zlib/zutil.h>
23790 +#include "inftrees.h"
23791 +#include "infblock.h"
23792 +#include "infcodes.h"
23793 +#include "infutil.h"
23794 +#include "inffast.h"
23795 +
23796 +/* simplify the use of the inflate_huft type with some defines */
23797 +#define exop word.what.Exop
23798 +#define bits word.what.Bits
23799 +
23800 +typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
23801 + START, /* x: set up for LEN */
23802 + LEN, /* i: get length/literal/eob next */
23803 + LENEXT, /* i: getting length extra (have base) */
23804 + DIST, /* i: get distance next */
23805 + DISTEXT, /* i: getting distance extra */
23806 + COPY, /* o: copying bytes in window, waiting for space */
23807 + LIT, /* o: got literal, waiting for output space */
23808 + WASH, /* o: got eob, possibly still output waiting */
23809 + END, /* x: got eob and all data flushed */
23810 + BADCODE} /* x: got error */
23811 +inflate_codes_mode;
23812 +
23813 +/* inflate codes private state */
23814 +struct inflate_codes_state {
23815 +
23816 + /* mode */
23817 + inflate_codes_mode mode; /* current inflate_codes mode */
23818 +
23819 + /* mode dependent information */
23820 + uInt len;
23821 + union {
23822 + struct {
23823 + inflate_huft *tree; /* pointer into tree */
23824 + uInt need; /* bits needed */
23825 + } code; /* if LEN or DIST, where in tree */
23826 + uInt lit; /* if LIT, literal */
23827 + struct {
23828 + uInt get; /* bits to get for extra */
23829 + uInt dist; /* distance back to copy from */
23830 + } copy; /* if EXT or COPY, where and how much */
23831 + } sub; /* submode */
23832 +
23833 + /* mode independent information */
23834 + Byte lbits; /* ltree bits decoded per branch */
23835 + Byte dbits; /* dtree bits decoder per branch */
23836 + inflate_huft *ltree; /* literal/length/eob tree */
23837 + inflate_huft *dtree; /* distance tree */
23838 +
23839 +};
23840 +
23841 +
23842 +inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
23843 +uInt bl, bd;
23844 +inflate_huft *tl;
23845 +inflate_huft *td; /* need separate declaration for Borland C++ */
23846 +z_streamp z;
23847 +{
23848 + inflate_codes_statef *c;
23849 +
23850 + if ((c = (inflate_codes_statef *)
23851 + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
23852 + {
23853 + c->mode = START;
23854 + c->lbits = (Byte)bl;
23855 + c->dbits = (Byte)bd;
23856 + c->ltree = tl;
23857 + c->dtree = td;
23858 + Tracev((stderr, "inflate: codes new\n"));
23859 + }
23860 + return c;
23861 +}
23862 +
23863 +
23864 +int inflate_codes(s, z, r)
23865 +inflate_blocks_statef *s;
23866 +z_streamp z;
23867 +int r;
23868 +{
23869 + uInt j; /* temporary storage */
23870 + inflate_huft *t; /* temporary pointer */
23871 + uInt e; /* extra bits or operation */
23872 + uLong b; /* bit buffer */
23873 + uInt k; /* bits in bit buffer */
23874 + Bytef *p; /* input data pointer */
23875 + uInt n; /* bytes available there */
23876 + Bytef *q; /* output window write pointer */
23877 + uInt m; /* bytes to end of window or read pointer */
23878 + Bytef *f; /* pointer to copy strings from */
23879 + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
23880 +
23881 + /* copy input/output information to locals (UPDATE macro restores) */
23882 + LOAD
23883 +
23884 + /* process input and output based on current state */
23885 + while (1) switch (c->mode)
23886 + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
23887 + case START: /* x: set up for LEN */
23888 +#ifndef SLOW
23889 + if (m >= 258 && n >= 10)
23890 + {
23891 + UPDATE
23892 + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
23893 + LOAD
23894 + if (r != Z_OK)
23895 + {
23896 + c->mode = r == Z_STREAM_END ? WASH : BADCODE;
23897 + break;
23898 + }
23899 + }
23900 +#endif /* !SLOW */
23901 + c->sub.code.need = c->lbits;
23902 + c->sub.code.tree = c->ltree;
23903 + c->mode = LEN;
23904 + case LEN: /* i: get length/literal/eob next */
23905 + j = c->sub.code.need;
23906 + NEEDBITS(j)
23907 + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
23908 + DUMPBITS(t->bits)
23909 + e = (uInt)(t->exop);
23910 + if (e == 0) /* literal */
23911 + {
23912 + c->sub.lit = t->base;
23913 + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
23914 + "inflate: literal '%c'\n" :
23915 + "inflate: literal 0x%02x\n", t->base));
23916 + c->mode = LIT;
23917 + break;
23918 + }
23919 + if (e & 16) /* length */
23920 + {
23921 + c->sub.copy.get = e & 15;
23922 + c->len = t->base;
23923 + c->mode = LENEXT;
23924 + break;
23925 + }
23926 + if ((e & 64) == 0) /* next table */
23927 + {
23928 + c->sub.code.need = e;
23929 + c->sub.code.tree = t + t->base;
23930 + break;
23931 + }
23932 + if (e & 32) /* end of block */
23933 + {
23934 + Tracevv((stderr, "inflate: end of block\n"));
23935 + c->mode = WASH;
23936 + break;
23937 + }
23938 + c->mode = BADCODE; /* invalid code */
23939 + z->msg = (char*)"invalid literal/length code";
23940 + r = Z_DATA_ERROR;
23941 + LEAVE
23942 + case LENEXT: /* i: getting length extra (have base) */
23943 + j = c->sub.copy.get;
23944 + NEEDBITS(j)
23945 + c->len += (uInt)b & inflate_mask[j];
23946 + DUMPBITS(j)
23947 + c->sub.code.need = c->dbits;
23948 + c->sub.code.tree = c->dtree;
23949 + Tracevv((stderr, "inflate: length %u\n", c->len));
23950 + c->mode = DIST;
23951 + case DIST: /* i: get distance next */
23952 + j = c->sub.code.need;
23953 + NEEDBITS(j)
23954 + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
23955 + DUMPBITS(t->bits)
23956 + e = (uInt)(t->exop);
23957 + if (e & 16) /* distance */
23958 + {
23959 + c->sub.copy.get = e & 15;
23960 + c->sub.copy.dist = t->base;
23961 + c->mode = DISTEXT;
23962 + break;
23963 + }
23964 + if ((e & 64) == 0) /* next table */
23965 + {
23966 + c->sub.code.need = e;
23967 + c->sub.code.tree = t + t->base;
23968 + break;
23969 + }
23970 + c->mode = BADCODE; /* invalid code */
23971 + z->msg = (char*)"invalid distance code";
23972 + r = Z_DATA_ERROR;
23973 + LEAVE
23974 + case DISTEXT: /* i: getting distance extra */
23975 + j = c->sub.copy.get;
23976 + NEEDBITS(j)
23977 + c->sub.copy.dist += (uInt)b & inflate_mask[j];
23978 + DUMPBITS(j)
23979 + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
23980 + c->mode = COPY;
23981 + case COPY: /* o: copying bytes in window, waiting for space */
23982 + f = q - c->sub.copy.dist;
23983 + while (f < s->window) /* modulo window size-"while" instead */
23984 + f += s->end - s->window; /* of "if" handles invalid distances */
23985 + while (c->len)
23986 + {
23987 + NEEDOUT
23988 + OUTBYTE(*f++)
23989 + if (f == s->end)
23990 + f = s->window;
23991 + c->len--;
23992 + }
23993 + c->mode = START;
23994 + break;
23995 + case LIT: /* o: got literal, waiting for output space */
23996 + NEEDOUT
23997 + OUTBYTE(c->sub.lit)
23998 + c->mode = START;
23999 + break;
24000 + case WASH: /* o: got eob, possibly more output */
24001 + if (k > 7) /* return unused byte, if any */
24002 + {
24003 + Assert(k < 16, "inflate_codes grabbed too many bytes")
24004 + k -= 8;
24005 + n++;
24006 + p--; /* can always return one */
24007 + }
24008 + FLUSH
24009 + if (s->read != s->write)
24010 + LEAVE
24011 + c->mode = END;
24012 + case END:
24013 + r = Z_STREAM_END;
24014 + LEAVE
24015 + case BADCODE: /* x: got error */
24016 + r = Z_DATA_ERROR;
24017 + LEAVE
24018 + default:
24019 + r = Z_STREAM_ERROR;
24020 + LEAVE
24021 + }
24022 +#ifdef NEED_DUMMY_RETURN
24023 + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
24024 +#endif
24025 +}
24026 +
24027 +
24028 +void inflate_codes_free(c, z)
24029 +inflate_codes_statef *c;
24030 +z_streamp z;
24031 +{
24032 + ZFREE(z, c);
24033 + Tracev((stderr, "inflate: codes free\n"));
24034 +}
24035 --- /dev/null Tue Mar 11 13:02:56 2003
24036 +++ linux/net/ipsec/infcodes.h Mon Feb 9 13:51:03 2004
24037 @@ -0,0 +1,31 @@
24038 +/* infcodes.h -- header to use infcodes.c
24039 + * Copyright (C) 1995-2002 Mark Adler
24040 + * For conditions of distribution and use, see copyright notice in zlib.h
24041 + */
24042 +
24043 +/* WARNING: this file should *not* be used by applications. It is
24044 + part of the implementation of the compression library and is
24045 + subject to change. Applications should only use zlib.h.
24046 + */
24047 +
24048 +#ifndef _INFCODES_H
24049 +#define _INFCODES_H
24050 +
24051 +struct inflate_codes_state;
24052 +typedef struct inflate_codes_state FAR inflate_codes_statef;
24053 +
24054 +extern inflate_codes_statef *inflate_codes_new OF((
24055 + uInt, uInt,
24056 + inflate_huft *, inflate_huft *,
24057 + z_streamp ));
24058 +
24059 +extern int inflate_codes OF((
24060 + inflate_blocks_statef *,
24061 + z_streamp ,
24062 + int));
24063 +
24064 +extern void inflate_codes_free OF((
24065 + inflate_codes_statef *,
24066 + z_streamp ));
24067 +
24068 +#endif /* _INFCODES_H */
24069 --- /dev/null Tue Mar 11 13:02:56 2003
24070 +++ linux/net/ipsec/inffast.c Mon Feb 9 13:51:03 2004
24071 @@ -0,0 +1,183 @@
24072 +/* inffast.c -- process literals and length/distance pairs fast
24073 + * Copyright (C) 1995-2002 Mark Adler
24074 + * For conditions of distribution and use, see copyright notice in zlib.h
24075 + */
24076 +
24077 +#include <zlib/zutil.h>
24078 +#include "inftrees.h"
24079 +#include "infblock.h"
24080 +#include "infcodes.h"
24081 +#include "infutil.h"
24082 +#include "inffast.h"
24083 +
24084 +struct inflate_codes_state {int dummy;}; /* for buggy compilers */
24085 +
24086 +/* simplify the use of the inflate_huft type with some defines */
24087 +#define exop word.what.Exop
24088 +#define bits word.what.Bits
24089 +
24090 +/* macros for bit input with no checking and for returning unused bytes */
24091 +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
24092 +#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
24093 +
24094 +/* Called with number of bytes left to write in window at least 258
24095 + (the maximum string length) and number of input bytes available
24096 + at least ten. The ten bytes are six bytes for the longest length/
24097 + distance pair plus four bytes for overloading the bit buffer. */
24098 +
24099 +int inflate_fast(bl, bd, tl, td, s, z)
24100 +uInt bl, bd;
24101 +inflate_huft *tl;
24102 +inflate_huft *td; /* need separate declaration for Borland C++ */
24103 +inflate_blocks_statef *s;
24104 +z_streamp z;
24105 +{
24106 + inflate_huft *t; /* temporary pointer */
24107 + uInt e; /* extra bits or operation */
24108 + uLong b; /* bit buffer */
24109 + uInt k; /* bits in bit buffer */
24110 + Bytef *p; /* input data pointer */
24111 + uInt n; /* bytes available there */
24112 + Bytef *q; /* output window write pointer */
24113 + uInt m; /* bytes to end of window or read pointer */
24114 + uInt ml; /* mask for literal/length tree */
24115 + uInt md; /* mask for distance tree */
24116 + uInt c; /* bytes to copy */
24117 + uInt d; /* distance back to copy from */
24118 + Bytef *r; /* copy source pointer */
24119 +
24120 + /* load input, output, bit values */
24121 + LOAD
24122 +
24123 + /* initialize masks */
24124 + ml = inflate_mask[bl];
24125 + md = inflate_mask[bd];
24126 +
24127 + /* do until not enough input or output space for fast loop */
24128 + do { /* assume called with m >= 258 && n >= 10 */
24129 + /* get literal/length code */
24130 + GRABBITS(20) /* max bits for literal/length code */
24131 + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
24132 + {
24133 + DUMPBITS(t->bits)
24134 + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
24135 + "inflate: * literal '%c'\n" :
24136 + "inflate: * literal 0x%02x\n", t->base));
24137 + *q++ = (Byte)t->base;
24138 + m--;
24139 + continue;
24140 + }
24141 + do {
24142 + DUMPBITS(t->bits)
24143 + if (e & 16)
24144 + {
24145 + /* get extra bits for length */
24146 + e &= 15;
24147 + c = t->base + ((uInt)b & inflate_mask[e]);
24148 + DUMPBITS(e)
24149 + Tracevv((stderr, "inflate: * length %u\n", c));
24150 +
24151 + /* decode distance base of block to copy */
24152 + GRABBITS(15); /* max bits for distance code */
24153 + e = (t = td + ((uInt)b & md))->exop;
24154 + do {
24155 + DUMPBITS(t->bits)
24156 + if (e & 16)
24157 + {
24158 + /* get extra bits to add to distance base */
24159 + e &= 15;
24160 + GRABBITS(e) /* get extra bits (up to 13) */
24161 + d = t->base + ((uInt)b & inflate_mask[e]);
24162 + DUMPBITS(e)
24163 + Tracevv((stderr, "inflate: * distance %u\n", d));
24164 +
24165 + /* do the copy */
24166 + m -= c;
24167 + r = q - d;
24168 + if (r < s->window) /* wrap if needed */
24169 + {
24170 + do {
24171 + r += s->end - s->window; /* force pointer in window */
24172 + } while (r < s->window); /* covers invalid distances */
24173 + e = s->end - r;
24174 + if (c > e)
24175 + {
24176 + c -= e; /* wrapped copy */
24177 + do {
24178 + *q++ = *r++;
24179 + } while (--e);
24180 + r = s->window;
24181 + do {
24182 + *q++ = *r++;
24183 + } while (--c);
24184 + }
24185 + else /* normal copy */
24186 + {
24187 + *q++ = *r++; c--;
24188 + *q++ = *r++; c--;
24189 + do {
24190 + *q++ = *r++;
24191 + } while (--c);
24192 + }
24193 + }
24194 + else /* normal copy */
24195 + {
24196 + *q++ = *r++; c--;
24197 + *q++ = *r++; c--;
24198 + do {
24199 + *q++ = *r++;
24200 + } while (--c);
24201 + }
24202 + break;
24203 + }
24204 + else if ((e & 64) == 0)
24205 + {
24206 + t += t->base;
24207 + e = (t += ((uInt)b & inflate_mask[e]))->exop;
24208 + }
24209 + else
24210 + {
24211 + z->msg = (char*)"invalid distance code";
24212 + UNGRAB
24213 + UPDATE
24214 + return Z_DATA_ERROR;
24215 + }
24216 + } while (1);
24217 + break;
24218 + }
24219 + if ((e & 64) == 0)
24220 + {
24221 + t += t->base;
24222 + if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
24223 + {
24224 + DUMPBITS(t->bits)
24225 + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
24226 + "inflate: * literal '%c'\n" :
24227 + "inflate: * literal 0x%02x\n", t->base));
24228 + *q++ = (Byte)t->base;
24229 + m--;
24230 + break;
24231 + }
24232 + }
24233 + else if (e & 32)
24234 + {
24235 + Tracevv((stderr, "inflate: * end of block\n"));
24236 + UNGRAB
24237 + UPDATE
24238 + return Z_STREAM_END;
24239 + }
24240 + else
24241 + {
24242 + z->msg = (char*)"invalid literal/length code";
24243 + UNGRAB
24244 + UPDATE
24245 + return Z_DATA_ERROR;
24246 + }
24247 + } while (1);
24248 + } while (m >= 258 && n >= 10);
24249 +
24250 + /* not enough input or output--restore pointers and return */
24251 + UNGRAB
24252 + UPDATE
24253 + return Z_OK;
24254 +}
24255 --- /dev/null Tue Mar 11 13:02:56 2003
24256 +++ linux/net/ipsec/inffast.h Mon Feb 9 13:51:03 2004
24257 @@ -0,0 +1,22 @@
24258 +/* inffast.h -- header to use inffast.c
24259 + * Copyright (C) 1995-2002 Mark Adler
24260 + * For conditions of distribution and use, see copyright notice in zlib.h
24261 + */
24262 +
24263 +/* WARNING: this file should *not* be used by applications. It is
24264 + part of the implementation of the compression library and is
24265 + subject to change. Applications should only use zlib.h.
24266 + */
24267 +
24268 +#ifndef _INFFAST_H
24269 +#define _INFFAST_H
24270 +
24271 +extern int inflate_fast OF((
24272 + uInt,
24273 + uInt,
24274 + inflate_huft *,
24275 + inflate_huft *,
24276 + inflate_blocks_statef *,
24277 + z_streamp ));
24278 +
24279 +#endif /* _INFFAST_H */
24280 --- /dev/null Tue Mar 11 13:02:56 2003
24281 +++ linux/net/ipsec/inffixed.h Mon Feb 9 13:51:03 2004
24282 @@ -0,0 +1,151 @@
24283 +/* inffixed.h -- table for decoding fixed codes
24284 + * Generated automatically by the maketree.c program
24285 + */
24286 +
24287 +/* WARNING: this file should *not* be used by applications. It is
24288 + part of the implementation of the compression library and is
24289 + subject to change. Applications should only use zlib.h.
24290 + */
24291 +
24292 +local uInt fixed_bl = 9;
24293 +local uInt fixed_bd = 5;
24294 +local inflate_huft fixed_tl[] = {
24295 + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
24296 + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
24297 + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
24298 + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
24299 + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
24300 + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
24301 + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
24302 + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
24303 + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
24304 + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
24305 + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
24306 + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
24307 + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
24308 + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
24309 + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
24310 + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
24311 + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
24312 + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
24313 + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
24314 + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
24315 + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
24316 + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
24317 + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
24318 + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
24319 + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
24320 + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
24321 + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
24322 + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
24323 + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
24324 + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
24325 + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
24326 + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
24327 + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
24328 + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
24329 + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
24330 + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
24331 + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
24332 + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
24333 + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
24334 + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
24335 + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
24336 + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
24337 + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
24338 + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
24339 + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
24340 + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
24341 + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
24342 + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
24343 + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
24344 + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
24345 + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
24346 + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
24347 + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
24348 + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
24349 + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
24350 + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
24351 + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
24352 + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
24353 + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
24354 + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
24355 + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
24356 + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
24357 + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
24358 + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
24359 + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
24360 + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
24361 + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
24362 + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
24363 + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
24364 + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
24365 + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
24366 + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
24367 + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
24368 + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
24369 + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
24370 + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
24371 + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
24372 + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
24373 + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
24374 + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
24375 + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
24376 + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
24377 + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
24378 + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
24379 + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
24380 + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
24381 + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
24382 + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
24383 + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
24384 + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
24385 + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
24386 + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
24387 + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
24388 + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
24389 + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
24390 + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
24391 + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
24392 + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
24393 + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
24394 + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
24395 + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
24396 + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
24397 + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
24398 + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
24399 + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
24400 + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
24401 + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
24402 + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
24403 + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
24404 + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
24405 + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
24406 + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
24407 + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
24408 + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
24409 + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
24410 + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
24411 + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
24412 + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
24413 + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
24414 + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
24415 + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
24416 + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
24417 + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
24418 + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
24419 + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
24420 + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
24421 + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
24422 + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
24423 + };
24424 +local inflate_huft fixed_td[] = {
24425 + {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
24426 + {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
24427 + {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
24428 + {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
24429 + {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
24430 + {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
24431 + {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
24432 + {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
24433 + };
24434 --- /dev/null Tue Mar 11 13:02:56 2003
24435 +++ linux/net/ipsec/inflate.c Mon Feb 9 13:51:03 2004
24436 @@ -0,0 +1,368 @@
24437 +/* inflate.c -- zlib interface to inflate modules
24438 + * Copyright (C) 1995-2002 Mark Adler
24439 + * For conditions of distribution and use, see copyright notice in zlib.h
24440 + */
24441 +
24442 +#include <zlib/zutil.h>
24443 +#include "infblock.h"
24444 +
24445 +struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
24446 +
24447 +typedef enum {
24448 + METHOD, /* waiting for method byte */
24449 + FLAG, /* waiting for flag byte */
24450 + DICT4, /* four dictionary check bytes to go */
24451 + DICT3, /* three dictionary check bytes to go */
24452 + DICT2, /* two dictionary check bytes to go */
24453 + DICT1, /* one dictionary check byte to go */
24454 + DICT0, /* waiting for inflateSetDictionary */
24455 + BLOCKS, /* decompressing blocks */
24456 + CHECK4, /* four check bytes to go */
24457 + CHECK3, /* three check bytes to go */
24458 + CHECK2, /* two check bytes to go */
24459 + CHECK1, /* one check byte to go */
24460 + DONE, /* finished check, done */
24461 + BAD} /* got an error--stay here */
24462 +inflate_mode;
24463 +
24464 +/* inflate private state */
24465 +struct internal_state {
24466 +
24467 + /* mode */
24468 + inflate_mode mode; /* current inflate mode */
24469 +
24470 + /* mode dependent information */
24471 + union {
24472 + uInt method; /* if FLAGS, method byte */
24473 + struct {
24474 + uLong was; /* computed check value */
24475 + uLong need; /* stream check value */
24476 + } check; /* if CHECK, check values to compare */
24477 + uInt marker; /* if BAD, inflateSync's marker bytes count */
24478 + } sub; /* submode */
24479 +
24480 + /* mode independent information */
24481 + int nowrap; /* flag for no wrapper */
24482 + uInt wbits; /* log2(window size) (8..15, defaults to 15) */
24483 + inflate_blocks_statef
24484 + *blocks; /* current inflate_blocks state */
24485 +
24486 +};
24487 +
24488 +
24489 +int ZEXPORT inflateReset(z)
24490 +z_streamp z;
24491 +{
24492 + if (z == Z_NULL || z->state == Z_NULL)
24493 + return Z_STREAM_ERROR;
24494 + z->total_in = z->total_out = 0;
24495 + z->msg = Z_NULL;
24496 + z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
24497 + inflate_blocks_reset(z->state->blocks, z, Z_NULL);
24498 + Tracev((stderr, "inflate: reset\n"));
24499 + return Z_OK;
24500 +}
24501 +
24502 +
24503 +int ZEXPORT inflateEnd(z)
24504 +z_streamp z;
24505 +{
24506 + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
24507 + return Z_STREAM_ERROR;
24508 + if (z->state->blocks != Z_NULL)
24509 + inflate_blocks_free(z->state->blocks, z);
24510 + ZFREE(z, z->state);
24511 + z->state = Z_NULL;
24512 + Tracev((stderr, "inflate: end\n"));
24513 + return Z_OK;
24514 +}
24515 +
24516 +
24517 +int ZEXPORT inflateInit2_(z, w, version, stream_size)
24518 +z_streamp z;
24519 +int w;
24520 +const char *version;
24521 +int stream_size;
24522 +{
24523 + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
24524 + stream_size != sizeof(z_stream))
24525 + return Z_VERSION_ERROR;
24526 +
24527 + /* initialize state */
24528 + if (z == Z_NULL)
24529 + return Z_STREAM_ERROR;
24530 + z->msg = Z_NULL;
24531 + if (z->zalloc == Z_NULL)
24532 + {
24533 + return Z_STREAM_ERROR;
24534 +/* z->zalloc = zcalloc;
24535 + z->opaque = (voidpf)0;
24536 +*/
24537 + }
24538 + if (z->zfree == Z_NULL) return Z_STREAM_ERROR; /* z->zfree = zcfree; */
24539 + if ((z->state = (struct internal_state FAR *)
24540 + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
24541 + return Z_MEM_ERROR;
24542 + z->state->blocks = Z_NULL;
24543 +
24544 + /* handle undocumented nowrap option (no zlib header or check) */
24545 + z->state->nowrap = 0;
24546 + if (w < 0)
24547 + {
24548 + w = - w;
24549 + z->state->nowrap = 1;
24550 + }
24551 +
24552 + /* set window size */
24553 + if (w < 8 || w > 15)
24554 + {
24555 + inflateEnd(z);
24556 + return Z_STREAM_ERROR;
24557 + }
24558 + z->state->wbits = (uInt)w;
24559 +
24560 + /* create inflate_blocks state */
24561 + if ((z->state->blocks =
24562 + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
24563 + == Z_NULL)
24564 + {
24565 + inflateEnd(z);
24566 + return Z_MEM_ERROR;
24567 + }
24568 + Tracev((stderr, "inflate: allocated\n"));
24569 +
24570 + /* reset state */
24571 + inflateReset(z);
24572 + return Z_OK;
24573 +}
24574 +
24575 +
24576 +int ZEXPORT inflateInit_(z, version, stream_size)
24577 +z_streamp z;
24578 +const char *version;
24579 +int stream_size;
24580 +{
24581 + return inflateInit2_(z, DEF_WBITS, version, stream_size);
24582 +}
24583 +
24584 +
24585 +#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
24586 +#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
24587 +
24588 +int ZEXPORT inflate(z, f)
24589 +z_streamp z;
24590 +int f;
24591 +{
24592 + int r;
24593 + uInt b;
24594 +
24595 + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
24596 + return Z_STREAM_ERROR;
24597 + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
24598 + r = Z_BUF_ERROR;
24599 + while (1) switch (z->state->mode)
24600 + {
24601 + case METHOD:
24602 + NEEDBYTE
24603 + if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
24604 + {
24605 + z->state->mode = BAD;
24606 + z->msg = (char*)"unknown compression method";
24607 + z->state->sub.marker = 5; /* can't try inflateSync */
24608 + break;
24609 + }
24610 + if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
24611 + {
24612 + z->state->mode = BAD;
24613 + z->msg = (char*)"invalid window size";
24614 + z->state->sub.marker = 5; /* can't try inflateSync */
24615 + break;
24616 + }
24617 + z->state->mode = FLAG;
24618 + case FLAG:
24619 + NEEDBYTE
24620 + b = NEXTBYTE;
24621 + if (((z->state->sub.method << 8) + b) % 31)
24622 + {
24623 + z->state->mode = BAD;
24624 + z->msg = (char*)"incorrect header check";
24625 + z->state->sub.marker = 5; /* can't try inflateSync */
24626 + break;
24627 + }
24628 + Tracev((stderr, "inflate: zlib header ok\n"));
24629 + if (!(b & PRESET_DICT))
24630 + {
24631 + z->state->mode = BLOCKS;
24632 + break;
24633 + }
24634 + z->state->mode = DICT4;
24635 + case DICT4:
24636 + NEEDBYTE
24637 + z->state->sub.check.need = (uLong)NEXTBYTE << 24;
24638 + z->state->mode = DICT3;
24639 + case DICT3:
24640 + NEEDBYTE
24641 + z->state->sub.check.need += (uLong)NEXTBYTE << 16;
24642 + z->state->mode = DICT2;
24643 + case DICT2:
24644 + NEEDBYTE
24645 + z->state->sub.check.need += (uLong)NEXTBYTE << 8;
24646 + z->state->mode = DICT1;
24647 + case DICT1:
24648 + NEEDBYTE
24649 + z->state->sub.check.need += (uLong)NEXTBYTE;
24650 + z->adler = z->state->sub.check.need;
24651 + z->state->mode = DICT0;
24652 + return Z_NEED_DICT;
24653 + case DICT0:
24654 + z->state->mode = BAD;
24655 + z->msg = (char*)"need dictionary";
24656 + z->state->sub.marker = 0; /* can try inflateSync */
24657 + return Z_STREAM_ERROR;
24658 + case BLOCKS:
24659 + r = inflate_blocks(z->state->blocks, z, r);
24660 + if (r == Z_DATA_ERROR)
24661 + {
24662 + z->state->mode = BAD;
24663 + z->state->sub.marker = 0; /* can try inflateSync */
24664 + break;
24665 + }
24666 + if (r == Z_OK)
24667 + r = f;
24668 + if (r != Z_STREAM_END)
24669 + return r;
24670 + r = f;
24671 + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
24672 + if (z->state->nowrap)
24673 + {
24674 + z->state->mode = DONE;
24675 + break;
24676 + }
24677 + z->state->mode = CHECK4;
24678 + case CHECK4:
24679 + NEEDBYTE
24680 + z->state->sub.check.need = (uLong)NEXTBYTE << 24;
24681 + z->state->mode = CHECK3;
24682 + case CHECK3:
24683 + NEEDBYTE
24684 + z->state->sub.check.need += (uLong)NEXTBYTE << 16;
24685 + z->state->mode = CHECK2;
24686 + case CHECK2:
24687 + NEEDBYTE
24688 + z->state->sub.check.need += (uLong)NEXTBYTE << 8;
24689 + z->state->mode = CHECK1;
24690 + case CHECK1:
24691 + NEEDBYTE
24692 + z->state->sub.check.need += (uLong)NEXTBYTE;
24693 +
24694 + if (z->state->sub.check.was != z->state->sub.check.need)
24695 + {
24696 + z->state->mode = BAD;
24697 + z->msg = (char*)"incorrect data check";
24698 + z->state->sub.marker = 5; /* can't try inflateSync */
24699 + break;
24700 + }
24701 + Tracev((stderr, "inflate: zlib check ok\n"));
24702 + z->state->mode = DONE;
24703 + case DONE:
24704 + return Z_STREAM_END;
24705 + case BAD:
24706 + return Z_DATA_ERROR;
24707 + default:
24708 + return Z_STREAM_ERROR;
24709 + }
24710 +#ifdef NEED_DUMMY_RETURN
24711 + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
24712 +#endif
24713 +}
24714 +
24715 +
24716 +int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
24717 +z_streamp z;
24718 +const Bytef *dictionary;
24719 +uInt dictLength;
24720 +{
24721 + uInt length = dictLength;
24722 +
24723 + if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
24724 + return Z_STREAM_ERROR;
24725 +
24726 + if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
24727 + z->adler = 1L;
24728 +
24729 + if (length >= ((uInt)1<<z->state->wbits))
24730 + {
24731 + length = (1<<z->state->wbits)-1;
24732 + dictionary += dictLength - length;
24733 + }
24734 + inflate_set_dictionary(z->state->blocks, dictionary, length);
24735 + z->state->mode = BLOCKS;
24736 + return Z_OK;
24737 +}
24738 +
24739 +
24740 +int ZEXPORT inflateSync(z)
24741 +z_streamp z;
24742 +{
24743 + uInt n; /* number of bytes to look at */
24744 + Bytef *p; /* pointer to bytes */
24745 + uInt m; /* number of marker bytes found in a row */
24746 + uLong r, w; /* temporaries to save total_in and total_out */
24747 +
24748 + /* set up */
24749 + if (z == Z_NULL || z->state == Z_NULL)
24750 + return Z_STREAM_ERROR;
24751 + if (z->state->mode != BAD)
24752 + {
24753 + z->state->mode = BAD;
24754 + z->state->sub.marker = 0;
24755 + }
24756 + if ((n = z->avail_in) == 0)
24757 + return Z_BUF_ERROR;
24758 + p = z->next_in;
24759 + m = z->state->sub.marker;
24760 +
24761 + /* search */
24762 + while (n && m < 4)
24763 + {
24764 + static const Byte mark[4] = {0, 0, 0xff, 0xff};
24765 + if (*p == mark[m])
24766 + m++;
24767 + else if (*p)
24768 + m = 0;
24769 + else
24770 + m = 4 - m;
24771 + p++, n--;
24772 + }
24773 +
24774 + /* restore */
24775 + z->total_in += p - z->next_in;
24776 + z->next_in = p;
24777 + z->avail_in = n;
24778 + z->state->sub.marker = m;
24779 +
24780 + /* return no joy or set up to restart on a new block */
24781 + if (m != 4)
24782 + return Z_DATA_ERROR;
24783 + r = z->total_in; w = z->total_out;
24784 + inflateReset(z);
24785 + z->total_in = r; z->total_out = w;
24786 + z->state->mode = BLOCKS;
24787 + return Z_OK;
24788 +}
24789 +
24790 +
24791 +/* Returns true if inflate is currently at the end of a block generated
24792 + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
24793 + * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
24794 + * but removes the length bytes of the resulting empty stored block. When
24795 + * decompressing, PPP checks that at the end of input packet, inflate is
24796 + * waiting for these length bytes.
24797 + */
24798 +int ZEXPORT inflateSyncPoint(z)
24799 +z_streamp z;
24800 +{
24801 + if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
24802 + return Z_STREAM_ERROR;
24803 + return inflate_blocks_sync_point(z->state->blocks);
24804 +}
24805 --- /dev/null Tue Mar 11 13:02:56 2003
24806 +++ linux/net/ipsec/inftrees.c Mon Feb 9 13:51:03 2004
24807 @@ -0,0 +1,454 @@
24808 +/* inftrees.c -- generate Huffman trees for efficient decoding
24809 + * Copyright (C) 1995-2002 Mark Adler
24810 + * For conditions of distribution and use, see copyright notice in zlib.h
24811 + */
24812 +
24813 +#include <zlib/zutil.h>
24814 +#include "inftrees.h"
24815 +
24816 +#if !defined(BUILDFIXED) && !defined(STDC)
24817 +# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
24818 +#endif
24819 +
24820 +local const char inflate_copyright[] =
24821 + " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
24822 +/*
24823 + If you use the zlib library in a product, an acknowledgment is welcome
24824 + in the documentation of your product. If for some reason you cannot
24825 + include such an acknowledgment, I would appreciate that you keep this
24826 + copyright string in the executable of your product.
24827 + */
24828 +struct internal_state {int dummy;}; /* for buggy compilers */
24829 +
24830 +/* simplify the use of the inflate_huft type with some defines */
24831 +#define exop word.what.Exop
24832 +#define bits word.what.Bits
24833 +
24834 +
24835 +local int huft_build OF((
24836 + uIntf *, /* code lengths in bits */
24837 + uInt, /* number of codes */
24838 + uInt, /* number of "simple" codes */
24839 + const uIntf *, /* list of base values for non-simple codes */
24840 + const uIntf *, /* list of extra bits for non-simple codes */
24841 + inflate_huft * FAR*,/* result: starting table */
24842 + uIntf *, /* maximum lookup bits (returns actual) */
24843 + inflate_huft *, /* space for trees */
24844 + uInt *, /* hufts used in space */
24845 + uIntf * )); /* space for values */
24846 +
24847 +/* Tables for deflate from PKZIP's appnote.txt. */
24848 +local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
24849 + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
24850 + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
24851 + /* see note #13 above about 258 */
24852 +local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
24853 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
24854 + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
24855 +local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
24856 + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
24857 + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
24858 + 8193, 12289, 16385, 24577};
24859 +local const uInt cpdext[30] = { /* Extra bits for distance codes */
24860 + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
24861 + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
24862 + 12, 12, 13, 13};
24863 +
24864 +/*
24865 + Huffman code decoding is performed using a multi-level table lookup.
24866 + The fastest way to decode is to simply build a lookup table whose
24867 + size is determined by the longest code. However, the time it takes
24868 + to build this table can also be a factor if the data being decoded
24869 + is not very long. The most common codes are necessarily the
24870 + shortest codes, so those codes dominate the decoding time, and hence
24871 + the speed. The idea is you can have a shorter table that decodes the
24872 + shorter, more probable codes, and then point to subsidiary tables for
24873 + the longer codes. The time it costs to decode the longer codes is
24874 + then traded against the time it takes to make longer tables.
24875 +
24876 + This results of this trade are in the variables lbits and dbits
24877 + below. lbits is the number of bits the first level table for literal/
24878 + length codes can decode in one step, and dbits is the same thing for
24879 + the distance codes. Subsequent tables are also less than or equal to
24880 + those sizes. These values may be adjusted either when all of the
24881 + codes are shorter than that, in which case the longest code length in
24882 + bits is used, or when the shortest code is *longer* than the requested
24883 + table size, in which case the length of the shortest code in bits is
24884 + used.
24885 +
24886 + There are two different values for the two tables, since they code a
24887 + different number of possibilities each. The literal/length table
24888 + codes 286 possible values, or in a flat code, a little over eight
24889 + bits. The distance table codes 30 possible values, or a little less
24890 + than five bits, flat. The optimum values for speed end up being
24891 + about one bit more than those, so lbits is 8+1 and dbits is 5+1.
24892 + The optimum values may differ though from machine to machine, and
24893 + possibly even between compilers. Your mileage may vary.
24894 + */
24895 +
24896 +
24897 +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
24898 +#define BMAX 15 /* maximum bit length of any code */
24899 +
24900 +local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
24901 +uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
24902 +uInt n; /* number of codes (assumed <= 288) */
24903 +uInt s; /* number of simple-valued codes (0..s-1) */
24904 +const uIntf *d; /* list of base values for non-simple codes */
24905 +const uIntf *e; /* list of extra bits for non-simple codes */
24906 +inflate_huft * FAR *t; /* result: starting table */
24907 +uIntf *m; /* maximum lookup bits, returns actual */
24908 +inflate_huft *hp; /* space for trees */
24909 +uInt *hn; /* hufts used in space */
24910 +uIntf *v; /* working area: values in order of bit length */
24911 +/* Given a list of code lengths and a maximum table size, make a set of
24912 + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
24913 + if the given code set is incomplete (the tables are still built in this
24914 + case), or Z_DATA_ERROR if the input is invalid. */
24915 +{
24916 +
24917 + uInt a; /* counter for codes of length k */
24918 + uInt c[BMAX+1]; /* bit length count table */
24919 + uInt f; /* i repeats in table every f entries */
24920 + int g; /* maximum code length */
24921 + int h; /* table level */
24922 + register uInt i; /* counter, current code */
24923 + register uInt j; /* counter */
24924 + register int k; /* number of bits in current code */
24925 + int l; /* bits per table (returned in m) */
24926 + uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
24927 + register uIntf *p; /* pointer into c[], b[], or v[] */
24928 + inflate_huft *q; /* points to current table */
24929 + struct inflate_huft_s r; /* table entry for structure assignment */
24930 + inflate_huft *u[BMAX]; /* table stack */
24931 + register int w; /* bits before this table == (l * h) */
24932 + uInt x[BMAX+1]; /* bit offsets, then code stack */
24933 + uIntf *xp; /* pointer into x */
24934 + int y; /* number of dummy codes added */
24935 + uInt z; /* number of entries in current table */
24936 +
24937 +
24938 + /* Generate counts for each bit length */
24939 + p = c;
24940 +#define C0 *p++ = 0;
24941 +#define C2 C0 C0 C0 C0
24942 +#define C4 C2 C2 C2 C2
24943 + C4 /* clear c[]--assume BMAX+1 is 16 */
24944 + p = b; i = n;
24945 + do {
24946 + c[*p++]++; /* assume all entries <= BMAX */
24947 + } while (--i);
24948 + if (c[0] == n) /* null input--all zero length codes */
24949 + {
24950 + *t = (inflate_huft *)Z_NULL;
24951 + *m = 0;
24952 + return Z_OK;
24953 + }
24954 +
24955 +
24956 + /* Find minimum and maximum length, bound *m by those */
24957 + l = *m;
24958 + for (j = 1; j <= BMAX; j++)
24959 + if (c[j])
24960 + break;
24961 + k = j; /* minimum code length */
24962 + if ((uInt)l < j)
24963 + l = j;
24964 + for (i = BMAX; i; i--)
24965 + if (c[i])
24966 + break;
24967 + g = i; /* maximum code length */
24968 + if ((uInt)l > i)
24969 + l = i;
24970 + *m = l;
24971 +
24972 +
24973 + /* Adjust last length count to fill out codes, if needed */
24974 + for (y = 1 << j; j < i; j++, y <<= 1)
24975 + if ((y -= c[j]) < 0)
24976 + return Z_DATA_ERROR;
24977 + if ((y -= c[i]) < 0)
24978 + return Z_DATA_ERROR;
24979 + c[i] += y;
24980 +
24981 +
24982 + /* Generate starting offsets into the value table for each length */
24983 + x[1] = j = 0;
24984 + p = c + 1; xp = x + 2;
24985 + while (--i) { /* note that i == g from above */
24986 + *xp++ = (j += *p++);
24987 + }
24988 +
24989 +
24990 + /* Make a table of values in order of bit lengths */
24991 + p = b; i = 0;
24992 + do {
24993 + if ((j = *p++) != 0)
24994 + v[x[j]++] = i;
24995 + } while (++i < n);
24996 + n = x[g]; /* set n to length of v */
24997 +
24998 +
24999 + /* Generate the Huffman codes and for each, make the table entries */
25000 + x[0] = i = 0; /* first Huffman code is zero */
25001 + p = v; /* grab values in bit order */
25002 + h = -1; /* no tables yet--level -1 */
25003 + w = -l; /* bits decoded == (l * h) */
25004 + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
25005 + q = (inflate_huft *)Z_NULL; /* ditto */
25006 + z = 0; /* ditto */
25007 +
25008 + /* go through the bit lengths (k already is bits in shortest code) */
25009 + for (; k <= g; k++)
25010 + {
25011 + a = c[k];
25012 + while (a--)
25013 + {
25014 + /* here i is the Huffman code of length k bits for value *p */
25015 + /* make tables up to required level */
25016 + while (k > w + l)
25017 + {
25018 + h++;
25019 + w += l; /* previous table always l bits */
25020 +
25021 + /* compute minimum size table less than or equal to l bits */
25022 + z = g - w;
25023 + z = z > (uInt)l ? l : z; /* table size upper limit */
25024 + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
25025 + { /* too few codes for k-w bit table */
25026 + f -= a + 1; /* deduct codes from patterns left */
25027 + xp = c + k;
25028 + if (j < z)
25029 + while (++j < z) /* try smaller tables up to z bits */
25030 + {
25031 + if ((f <<= 1) <= *++xp)
25032 + break; /* enough codes to use up j bits */
25033 + f -= *xp; /* else deduct codes from patterns */
25034 + }
25035 + }
25036 + z = 1 << j; /* table entries for j-bit table */
25037 +
25038 + /* allocate new table */
25039 + if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
25040 + return Z_DATA_ERROR; /* overflow of MANY */
25041 + u[h] = q = hp + *hn;
25042 + *hn += z;
25043 +
25044 + /* connect to last table, if there is one */
25045 + if (h)
25046 + {
25047 + x[h] = i; /* save pattern for backing up */
25048 + r.bits = (Byte)l; /* bits to dump before this table */
25049 + r.exop = (Byte)j; /* bits in this table */
25050 + j = i >> (w - l);
25051 + r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
25052 + u[h-1][j] = r; /* connect to last table */
25053 + }
25054 + else
25055 + *t = q; /* first table is returned result */
25056 + }
25057 +
25058 + /* set up table entry in r */
25059 + r.bits = (Byte)(k - w);
25060 + if (p >= v + n)
25061 + r.exop = 128 + 64; /* out of values--invalid code */
25062 + else if (*p < s)
25063 + {
25064 + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
25065 + r.base = *p++; /* simple code is just the value */
25066 + }
25067 + else
25068 + {
25069 + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
25070 + r.base = d[*p++ - s];
25071 + }
25072 +
25073 + /* fill code-like entries with r */
25074 + f = 1 << (k - w);
25075 + for (j = i >> w; j < z; j += f)
25076 + q[j] = r;
25077 +
25078 + /* backwards increment the k-bit code i */
25079 + for (j = 1 << (k - 1); i & j; j >>= 1)
25080 + i ^= j;
25081 + i ^= j;
25082 +
25083 + /* backup over finished tables */
25084 + mask = (1 << w) - 1; /* needed on HP, cc -O bug */
25085 + while ((i & mask) != x[h])
25086 + {
25087 + h--; /* don't need to update q */
25088 + w -= l;
25089 + mask = (1 << w) - 1;
25090 + }
25091 + }
25092 + }
25093 +
25094 +
25095 + /* Return Z_BUF_ERROR if we were given an incomplete table */
25096 + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
25097 +}
25098 +
25099 +
25100 +int inflate_trees_bits(c, bb, tb, hp, z)
25101 +uIntf *c; /* 19 code lengths */
25102 +uIntf *bb; /* bits tree desired/actual depth */
25103 +inflate_huft * FAR *tb; /* bits tree result */
25104 +inflate_huft *hp; /* space for trees */
25105 +z_streamp z; /* for messages */
25106 +{
25107 + int r;
25108 + uInt hn = 0; /* hufts used in space */
25109 + uIntf *v; /* work area for huft_build */
25110 +
25111 + if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
25112 + return Z_MEM_ERROR;
25113 + r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
25114 + tb, bb, hp, &hn, v);
25115 + if (r == Z_DATA_ERROR)
25116 + z->msg = (char*)"oversubscribed dynamic bit lengths tree";
25117 + else if (r == Z_BUF_ERROR || *bb == 0)
25118 + {
25119 + z->msg = (char*)"incomplete dynamic bit lengths tree";
25120 + r = Z_DATA_ERROR;
25121 + }
25122 + ZFREE(z, v);
25123 + return r;
25124 +}
25125 +
25126 +
25127 +int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
25128 +uInt nl; /* number of literal/length codes */
25129 +uInt nd; /* number of distance codes */
25130 +uIntf *c; /* that many (total) code lengths */
25131 +uIntf *bl; /* literal desired/actual bit depth */
25132 +uIntf *bd; /* distance desired/actual bit depth */
25133 +inflate_huft * FAR *tl; /* literal/length tree result */
25134 +inflate_huft * FAR *td; /* distance tree result */
25135 +inflate_huft *hp; /* space for trees */
25136 +z_streamp z; /* for messages */
25137 +{
25138 + int r;
25139 + uInt hn = 0; /* hufts used in space */
25140 + uIntf *v; /* work area for huft_build */
25141 +
25142 + /* allocate work area */
25143 + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25144 + return Z_MEM_ERROR;
25145 +
25146 + /* build literal/length tree */
25147 + r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
25148 + if (r != Z_OK || *bl == 0)
25149 + {
25150 + if (r == Z_DATA_ERROR)
25151 + z->msg = (char*)"oversubscribed literal/length tree";
25152 + else if (r != Z_MEM_ERROR)
25153 + {
25154 + z->msg = (char*)"incomplete literal/length tree";
25155 + r = Z_DATA_ERROR;
25156 + }
25157 + ZFREE(z, v);
25158 + return r;
25159 + }
25160 +
25161 + /* build distance tree */
25162 + r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
25163 + if (r != Z_OK || (*bd == 0 && nl > 257))
25164 + {
25165 + if (r == Z_DATA_ERROR)
25166 + z->msg = (char*)"oversubscribed distance tree";
25167 + else if (r == Z_BUF_ERROR) {
25168 +#ifdef PKZIP_BUG_WORKAROUND
25169 + r = Z_OK;
25170 + }
25171 +#else
25172 + z->msg = (char*)"incomplete distance tree";
25173 + r = Z_DATA_ERROR;
25174 + }
25175 + else if (r != Z_MEM_ERROR)
25176 + {
25177 + z->msg = (char*)"empty distance tree with lengths";
25178 + r = Z_DATA_ERROR;
25179 + }
25180 + ZFREE(z, v);
25181 + return r;
25182 +#endif
25183 + }
25184 +
25185 + /* done */
25186 + ZFREE(z, v);
25187 + return Z_OK;
25188 +}
25189 +
25190 +
25191 +/* build fixed tables only once--keep them here */
25192 +#ifdef BUILDFIXED
25193 +local int fixed_built = 0;
25194 +#define FIXEDH 544 /* number of hufts used by fixed tables */
25195 +local inflate_huft fixed_mem[FIXEDH];
25196 +local uInt fixed_bl;
25197 +local uInt fixed_bd;
25198 +local inflate_huft *fixed_tl;
25199 +local inflate_huft *fixed_td;
25200 +#else
25201 +#include "inffixed.h"
25202 +#endif
25203 +
25204 +
25205 +int inflate_trees_fixed(bl, bd, tl, td, z)
25206 +uIntf *bl; /* literal desired/actual bit depth */
25207 +uIntf *bd; /* distance desired/actual bit depth */
25208 +inflate_huft * FAR *tl; /* literal/length tree result */
25209 +inflate_huft * FAR *td; /* distance tree result */
25210 +z_streamp z; /* for memory allocation */
25211 +{
25212 +#ifdef BUILDFIXED
25213 + /* build fixed tables if not already */
25214 + if (!fixed_built)
25215 + {
25216 + int k; /* temporary variable */
25217 + uInt f = 0; /* number of hufts used in fixed_mem */
25218 + uIntf *c; /* length list for huft_build */
25219 + uIntf *v; /* work area for huft_build */
25220 +
25221 + /* allocate memory */
25222 + if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25223 + return Z_MEM_ERROR;
25224 + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25225 + {
25226 + ZFREE(z, c);
25227 + return Z_MEM_ERROR;
25228 + }
25229 +
25230 + /* literal table */
25231 + for (k = 0; k < 144; k++)
25232 + c[k] = 8;
25233 + for (; k < 256; k++)
25234 + c[k] = 9;
25235 + for (; k < 280; k++)
25236 + c[k] = 7;
25237 + for (; k < 288; k++)
25238 + c[k] = 8;
25239 + fixed_bl = 9;
25240 + huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
25241 + fixed_mem, &f, v);
25242 +
25243 + /* distance table */
25244 + for (k = 0; k < 30; k++)
25245 + c[k] = 5;
25246 + fixed_bd = 5;
25247 + huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
25248 + fixed_mem, &f, v);
25249 +
25250 + /* done */
25251 + ZFREE(z, v);
25252 + ZFREE(z, c);
25253 + fixed_built = 1;
25254 + }
25255 +#endif
25256 + *bl = fixed_bl;
25257 + *bd = fixed_bd;
25258 + *tl = fixed_tl;
25259 + *td = fixed_td;
25260 + return Z_OK;
25261 +}
25262 --- /dev/null Tue Mar 11 13:02:56 2003
25263 +++ linux/net/ipsec/inftrees.h Mon Feb 9 13:51:03 2004
25264 @@ -0,0 +1,63 @@
25265 +/* inftrees.h -- header to use inftrees.c
25266 + * Copyright (C) 1995-2002 Mark Adler
25267 + * For conditions of distribution and use, see copyright notice in zlib.h
25268 + */
25269 +
25270 +/* WARNING: this file should *not* be used by applications. It is
25271 + part of the implementation of the compression library and is
25272 + subject to change. Applications should only use zlib.h.
25273 + */
25274 +
25275 +/* Huffman code lookup table entry--this entry is four bytes for machines
25276 + that have 16-bit pointers (e.g. PC's in the small or medium model). */
25277 +
25278 +#ifndef _INFTREES_H
25279 +#define _INFTREES_H
25280 +
25281 +typedef struct inflate_huft_s FAR inflate_huft;
25282 +
25283 +struct inflate_huft_s {
25284 + union {
25285 + struct {
25286 + Byte Exop; /* number of extra bits or operation */
25287 + Byte Bits; /* number of bits in this code or subcode */
25288 + } what;
25289 + uInt pad; /* pad structure to a power of 2 (4 bytes for */
25290 + } word; /* 16-bit, 8 bytes for 32-bit int's) */
25291 + uInt base; /* literal, length base, distance base,
25292 + or table offset */
25293 +};
25294 +
25295 +/* Maximum size of dynamic tree. The maximum found in a long but non-
25296 + exhaustive search was 1004 huft structures (850 for length/literals
25297 + and 154 for distances, the latter actually the result of an
25298 + exhaustive search). The actual maximum is not known, but the
25299 + value below is more than safe. */
25300 +#define MANY 1440
25301 +
25302 +extern int inflate_trees_bits OF((
25303 + uIntf *, /* 19 code lengths */
25304 + uIntf *, /* bits tree desired/actual depth */
25305 + inflate_huft * FAR *, /* bits tree result */
25306 + inflate_huft *, /* space for trees */
25307 + z_streamp)); /* for messages */
25308 +
25309 +extern int inflate_trees_dynamic OF((
25310 + uInt, /* number of literal/length codes */
25311 + uInt, /* number of distance codes */
25312 + uIntf *, /* that many (total) code lengths */
25313 + uIntf *, /* literal desired/actual bit depth */
25314 + uIntf *, /* distance desired/actual bit depth */
25315 + inflate_huft * FAR *, /* literal/length tree result */
25316 + inflate_huft * FAR *, /* distance tree result */
25317 + inflate_huft *, /* space for trees */
25318 + z_streamp)); /* for messages */
25319 +
25320 +extern int inflate_trees_fixed OF((
25321 + uIntf *, /* literal desired/actual bit depth */
25322 + uIntf *, /* distance desired/actual bit depth */
25323 + inflate_huft * FAR *, /* literal/length tree result */
25324 + inflate_huft * FAR *, /* distance tree result */
25325 + z_streamp)); /* for memory allocation */
25326 +
25327 +#endif /* _INFTREES_H */
25328 --- /dev/null Tue Mar 11 13:02:56 2003
25329 +++ linux/net/ipsec/infutil.c Mon Feb 9 13:51:03 2004
25330 @@ -0,0 +1,87 @@
25331 +/* inflate_util.c -- data and routines common to blocks and codes
25332 + * Copyright (C) 1995-2002 Mark Adler
25333 + * For conditions of distribution and use, see copyright notice in zlib.h
25334 + */
25335 +
25336 +#include <zlib/zutil.h>
25337 +#include "infblock.h"
25338 +#include "inftrees.h"
25339 +#include "infcodes.h"
25340 +#include "infutil.h"
25341 +
25342 +struct inflate_codes_state {int dummy;}; /* for buggy compilers */
25343 +
25344 +/* And'ing with mask[n] masks the lower n bits */
25345 +uInt inflate_mask[17] = {
25346 + 0x0000,
25347 + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
25348 + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
25349 +};
25350 +
25351 +
25352 +/* copy as much as possible from the sliding window to the output area */
25353 +int inflate_flush(s, z, r)
25354 +inflate_blocks_statef *s;
25355 +z_streamp z;
25356 +int r;
25357 +{
25358 + uInt n;
25359 + Bytef *p;
25360 + Bytef *q;
25361 +
25362 + /* local copies of source and destination pointers */
25363 + p = z->next_out;
25364 + q = s->read;
25365 +
25366 + /* compute number of bytes to copy as far as end of window */
25367 + n = (uInt)((q <= s->write ? s->write : s->end) - q);
25368 + if (n > z->avail_out) n = z->avail_out;
25369 + if (n && r == Z_BUF_ERROR) r = Z_OK;
25370 +
25371 + /* update counters */
25372 + z->avail_out -= n;
25373 + z->total_out += n;
25374 +
25375 + /* update check information */
25376 + if (s->checkfn != Z_NULL)
25377 + z->adler = s->check = (*s->checkfn)(s->check, q, n);
25378 +
25379 + /* copy as far as end of window */
25380 + zmemcpy(p, q, n);
25381 + p += n;
25382 + q += n;
25383 +
25384 + /* see if more to copy at beginning of window */
25385 + if (q == s->end)
25386 + {
25387 + /* wrap pointers */
25388 + q = s->window;
25389 + if (s->write == s->end)
25390 + s->write = s->window;
25391 +
25392 + /* compute bytes to copy */
25393 + n = (uInt)(s->write - q);
25394 + if (n > z->avail_out) n = z->avail_out;
25395 + if (n && r == Z_BUF_ERROR) r = Z_OK;
25396 +
25397 + /* update counters */
25398 + z->avail_out -= n;
25399 + z->total_out += n;
25400 +
25401 + /* update check information */
25402 + if (s->checkfn != Z_NULL)
25403 + z->adler = s->check = (*s->checkfn)(s->check, q, n);
25404 +
25405 + /* copy */
25406 + zmemcpy(p, q, n);
25407 + p += n;
25408 + q += n;
25409 + }
25410 +
25411 + /* update pointers */
25412 + z->next_out = p;
25413 + s->read = q;
25414 +
25415 + /* done */
25416 + return r;
25417 +}
25418 --- /dev/null Tue Mar 11 13:02:56 2003
25419 +++ linux/net/ipsec/infutil.h Mon Feb 9 13:51:03 2004
25420 @@ -0,0 +1,98 @@
25421 +/* infutil.h -- types and macros common to blocks and codes
25422 + * Copyright (C) 1995-2002 Mark Adler
25423 + * For conditions of distribution and use, see copyright notice in zlib.h
25424 + */
25425 +
25426 +/* WARNING: this file should *not* be used by applications. It is
25427 + part of the implementation of the compression library and is
25428 + subject to change. Applications should only use zlib.h.
25429 + */
25430 +
25431 +#ifndef _INFUTIL_H
25432 +#define _INFUTIL_H
25433 +
25434 +typedef enum {
25435 + TYPE, /* get type bits (3, including end bit) */
25436 + LENS, /* get lengths for stored */
25437 + STORED, /* processing stored block */
25438 + TABLE, /* get table lengths */
25439 + BTREE, /* get bit lengths tree for a dynamic block */
25440 + DTREE, /* get length, distance trees for a dynamic block */
25441 + CODES, /* processing fixed or dynamic block */
25442 + DRY, /* output remaining window bytes */
25443 + DONE, /* finished last block, done */
25444 + BAD} /* got a data error--stuck here */
25445 +inflate_block_mode;
25446 +
25447 +/* inflate blocks semi-private state */
25448 +struct inflate_blocks_state {
25449 +
25450 + /* mode */
25451 + inflate_block_mode mode; /* current inflate_block mode */
25452 +
25453 + /* mode dependent information */
25454 + union {
25455 + uInt left; /* if STORED, bytes left to copy */
25456 + struct {
25457 + uInt table; /* table lengths (14 bits) */
25458 + uInt index; /* index into blens (or border) */
25459 + uIntf *blens; /* bit lengths of codes */
25460 + uInt bb; /* bit length tree depth */
25461 + inflate_huft *tb; /* bit length decoding tree */
25462 + } trees; /* if DTREE, decoding info for trees */
25463 + struct {
25464 + inflate_codes_statef
25465 + *codes;
25466 + } decode; /* if CODES, current state */
25467 + } sub; /* submode */
25468 + uInt last; /* true if this block is the last block */
25469 +
25470 + /* mode independent information */
25471 + uInt bitk; /* bits in bit buffer */
25472 + uLong bitb; /* bit buffer */
25473 + inflate_huft *hufts; /* single malloc for tree space */
25474 + Bytef *window; /* sliding window */
25475 + Bytef *end; /* one byte after sliding window */
25476 + Bytef *read; /* window read pointer */
25477 + Bytef *write; /* window write pointer */
25478 + check_func checkfn; /* check function */
25479 + uLong check; /* check on output */
25480 +
25481 +};
25482 +
25483 +
25484 +/* defines for inflate input/output */
25485 +/* update pointers and return */
25486 +#define UPDBITS {s->bitb=b;s->bitk=k;}
25487 +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
25488 +#define UPDOUT {s->write=q;}
25489 +#define UPDATE {UPDBITS UPDIN UPDOUT}
25490 +#define LEAVE {UPDATE return inflate_flush(s,z,r);}
25491 +/* get bytes and bits */
25492 +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
25493 +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
25494 +#define NEXTBYTE (n--,*p++)
25495 +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
25496 +#define DUMPBITS(j) {b>>=(j);k-=(j);}
25497 +/* output bytes */
25498 +#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
25499 +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
25500 +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
25501 +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
25502 +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
25503 +#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
25504 +/* load local pointers */
25505 +#define LOAD {LOADIN LOADOUT}
25506 +
25507 +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
25508 +extern uInt inflate_mask[17];
25509 +
25510 +/* copy as much as possible from the sliding window to the output area */
25511 +extern int inflate_flush OF((
25512 + inflate_blocks_statef *,
25513 + z_streamp ,
25514 + int));
25515 +
25516 +struct internal_state {int dummy;}; /* for buggy compilers */
25517 +
25518 +#endif /* _INFUTIL_H */
25519 --- /dev/null Tue Mar 11 13:02:56 2003
25520 +++ linux/net/ipsec/initaddr.c Mon Feb 9 13:51:03 2004
25521 @@ -0,0 +1,85 @@
25522 +/*
25523 + * initialize address structure
25524 + * Copyright (C) 2000 Henry Spencer.
25525 + *
25526 + * This library is free software; you can redistribute it and/or modify it
25527 + * under the terms of the GNU Library General Public License as published by
25528 + * the Free Software Foundation; either version 2 of the License, or (at your
25529 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
25530 + *
25531 + * This library is distributed in the hope that it will be useful, but
25532 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25533 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
25534 + * License for more details.
25535 + *
25536 + * RCSID $Id: initaddr.c,v 1.6 2004/07/10 07:43:47 mcr Exp $
25537 + */
25538 +#include "openswan.h"
25539 +
25540 +err_t
25541 +add_port(af, addr, port)
25542 +int af;
25543 +ip_address *addr;
25544 +unsigned short port;
25545 +{
25546 + switch (af) {
25547 + case AF_INET:
25548 + addr->u.v4.sin_port = port;
25549 + break;
25550 + case AF_INET6:
25551 + addr->u.v6.sin6_port = port;
25552 + break;
25553 + default:
25554 + return "unknown address family in add_port";
25555 + break;
25556 + }
25557 + return NULL;
25558 +}
25559 +
25560 +/*
25561 + - initaddr - initialize ip_address from bytes
25562 + */
25563 +err_t /* NULL for success, else string literal */
25564 +initaddr(src, srclen, af, dst)
25565 +const unsigned char *src;
25566 +size_t srclen;
25567 +int af; /* address family */
25568 +ip_address *dst;
25569 +{
25570 + switch (af) {
25571 + case AF_INET:
25572 + if (srclen != 4)
25573 + return "IPv4 address must be exactly 4 bytes";
25574 +#if !defined(__KERNEL__)
25575 + /* On BSD, the kernel compares the entire struct sockaddr when
25576 + * using bind(). However, this is as large as the largest
25577 + * address family, so the 'remainder' has to be 0. Linux
25578 + * compares interface addresses with the length of sa_len,
25579 + * instead of sizeof(struct sockaddr), so in that case padding
25580 + * is not needed.
25581 + *
25582 + * Patch by Stefan Arentz <stefan@soze.com>
25583 + */
25584 + bzero(&dst->u.v4, sizeof(dst->u.v4));
25585 +#endif
25586 + dst->u.v4.sin_family = af;
25587 + dst->u.v4.sin_port = 0;
25588 + memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen);
25589 + break;
25590 + case AF_INET6:
25591 + if (srclen != 16)
25592 + return "IPv6 address must be exactly 16 bytes";
25593 +#if !defined(__KERNEL__)
25594 + bzero(&dst->u.v6, sizeof(dst->u.v6));
25595 +#endif
25596 + dst->u.v6.sin6_family = af;
25597 + dst->u.v6.sin6_flowinfo = 0; /* unused */
25598 + dst->u.v6.sin6_port = 0;
25599 + memcpy((char *)&dst->u.v6.sin6_addr, src, srclen);
25600 + break;
25601 + default:
25602 + return "unknown address family in initaddr";
25603 + break;
25604 + }
25605 + return NULL;
25606 +}
25607 --- /dev/null Tue Mar 11 13:02:56 2003
25608 +++ linux/net/ipsec/ipcomp.c Mon Feb 9 13:51:03 2004
25609 @@ -0,0 +1,694 @@
25610 +/*
25611 + * IPCOMP zlib interface code.
25612 + * implementation of RFC 3173.
25613 + *
25614 + * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
25615 + * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
25616 + *
25617 + * This program is free software; you can redistribute it and/or modify it
25618 + * under the terms of the GNU General Public License as published by the
25619 + * Free Software Foundation; either version 2 of the License, or (at your
25620 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
25621 + *
25622 + * This program is distributed in the hope that it will be useful, but
25623 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25624 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25625 + * for more details.
25626 + */
25627 +
25628 +/* SSS */
25629 +
25630 +#ifndef AUTOCONF_INCLUDED
25631 +#include <linux/config.h>
25632 +#endif
25633 +#include <linux/version.h>
25634 +
25635 +#define __NO_VERSION__
25636 +#include <linux/module.h>
25637 +#include <linux/kernel.h> /* printk() */
25638 +
25639 +#include "openswan/ipsec_param.h"
25640 +
25641 +#ifdef MALLOC_SLAB
25642 +# include <linux/slab.h> /* kmalloc() */
25643 +#else /* MALLOC_SLAB */
25644 +# include <linux/malloc.h> /* kmalloc() */
25645 +#endif /* MALLOC_SLAB */
25646 +#include <linux/errno.h> /* error codes */
25647 +#include <linux/types.h>
25648 +#include <linux/netdevice.h>
25649 +#include <linux/ip.h>
25650 +#include <linux/skbuff.h>
25651 +
25652 +#include <linux/netdevice.h> /* struct device, and other headers */
25653 +#include <linux/etherdevice.h> /* eth_type_trans */
25654 +#include <linux/ip.h> /* struct iphdr */
25655 +#include <linux/skbuff.h>
25656 +#include <asm/uaccess.h>
25657 +#include <asm/checksum.h>
25658 +
25659 +#include <openswan.h>
25660 +
25661 +#include <net/ip.h>
25662 +
25663 +#include "openswan/ipsec_kern24.h"
25664 +#include "openswan/radij.h"
25665 +#include "openswan/ipsec_encap.h"
25666 +#include "openswan/ipsec_sa.h"
25667 +
25668 +#include "openswan/ipsec_xform.h"
25669 +#include "openswan/ipsec_tunnel.h"
25670 +#include "openswan/ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */
25671 +#include "openswan/ipsec_proto.h"
25672 +#include "openswan/ipcomp.h"
25673 +#include "zlib/zlib.h"
25674 +#include "zlib/zutil.h"
25675 +
25676 +#include <openswan/pfkeyv2.h> /* SADB_X_CALG_DEFLATE */
25677 +
25678 +static
25679 +struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask);
25680 +
25681 +static
25682 +voidpf my_zcalloc(voidpf opaque, uInt items, uInt size)
25683 +{
25684 + return (voidpf) kmalloc(items*size, GFP_ATOMIC);
25685 +}
25686 +
25687 +static
25688 +void my_zfree(voidpf opaque, voidpf address)
25689 +{
25690 + kfree(address);
25691 +}
25692 +
25693 +/*
25694 + * We use this function because sometimes we want to pass a negative offset
25695 + * into skb_put(), this does not work on 64bit platforms because long to
25696 + * unsigned int casting.
25697 + */
25698 +static inline unsigned char *
25699 +safe_skb_put(struct sk_buff *skb, int extend)
25700 +{
25701 + unsigned char *ptr;
25702 +
25703 + if (extend>0) {
25704 + // increase the size of the packet
25705 + ptr = skb_put(skb, extend);
25706 + } else {
25707 + // shrink the size of the packet
25708 + ptr = skb_tail_pointer(skb);
25709 + skb_trim (skb, skb->len + extend);
25710 + }
25711 +
25712 + return ptr;
25713 +}
25714 +
25715 +struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
25716 +{
25717 + struct iphdr *iph;
25718 + unsigned int iphlen, pyldsz, cpyldsz;
25719 + unsigned char *buffer;
25720 + z_stream zs;
25721 + int zresult;
25722 +
25723 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25724 + "klips_debug:skb_compress: .\n");
25725 +
25726 + if(skb == NULL) {
25727 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25728 + "klips_debug:skb_compress: "
25729 + "passed in NULL skb, returning ERROR.\n");
25730 + if(flags != NULL) {
25731 + *flags |= IPCOMP_PARMERROR;
25732 + }
25733 + return skb;
25734 + }
25735 +
25736 + if(ips == NULL) {
25737 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25738 + "klips_debug:skb_compress: "
25739 + "passed in NULL ipsec_sa needed for cpi, returning ERROR.\n");
25740 + if(flags) {
25741 + *flags |= IPCOMP_PARMERROR;
25742 + }
25743 + return skb;
25744 + }
25745 +
25746 + if (flags == NULL) {
25747 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25748 + "klips_debug:skb_compress: "
25749 + "passed in NULL flags, returning ERROR.\n");
25750 + ipsec_kfree_skb(skb);
25751 + return NULL;
25752 + }
25753 +
25754 +#ifdef NET_21
25755 + iph = ip_hdr(skb);
25756 +#else /* NET_21 */
25757 + iph = skb->ip_hdr;
25758 +#endif /* NET_21 */
25759 +
25760 + switch (iph->protocol) {
25761 + case IPPROTO_COMP:
25762 + case IPPROTO_AH:
25763 + case IPPROTO_ESP:
25764 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25765 + "klips_debug:skb_compress: "
25766 + "skipping compression of packet with ip protocol %d.\n",
25767 + iph->protocol);
25768 + *flags |= IPCOMP_UNCOMPRESSABLE;
25769 + return skb;
25770 + }
25771 +
25772 + /* Don't compress packets already fragmented */
25773 + if (iph->frag_off & __constant_htons(IP_MF | IP_OFFSET)) {
25774 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25775 + "klips_debug:skb_compress: "
25776 + "skipping compression of fragmented packet.\n");
25777 + *flags |= IPCOMP_UNCOMPRESSABLE;
25778 + return skb;
25779 + }
25780 +
25781 + iphlen = iph->ihl << 2;
25782 + pyldsz = ntohs(iph->tot_len) - iphlen;
25783 +
25784 + /* Don't compress less than 90 bytes (rfc 2394) */
25785 + if (pyldsz < 90) {
25786 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25787 + "klips_debug:skb_compress: "
25788 + "skipping compression of tiny packet, len=%d.\n",
25789 + pyldsz);
25790 + *flags |= IPCOMP_UNCOMPRESSABLE;
25791 + return skb;
25792 + }
25793 +
25794 + /* Adaptive decision */
25795 + if (ips->ips_comp_adapt_skip) {
25796 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25797 + "klips_debug:skb_compress: "
25798 + "skipping compression: ips_comp_adapt_skip=%d.\n",
25799 + ips->ips_comp_adapt_skip);
25800 + ips->ips_comp_adapt_skip--;
25801 + *flags |= IPCOMP_UNCOMPRESSABLE;
25802 + return skb;
25803 + }
25804 +
25805 + zs.zalloc = my_zcalloc;
25806 + zs.zfree = my_zfree;
25807 + zs.opaque = 0;
25808 +
25809 + /* We want to use deflateInit2 because we don't want the adler
25810 + header. */
25811 + zresult = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -11,
25812 + DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
25813 + if (zresult != Z_OK) {
25814 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25815 + "klips_error:skb_compress: "
25816 + "deflateInit2() returned error %d (%s), "
25817 + "skipping compression.\n",
25818 + zresult,
25819 + zs.msg ? zs.msg : zError(zresult));
25820 + *flags |= IPCOMP_COMPRESSIONERROR;
25821 + return skb;
25822 + }
25823 +
25824 +
25825 + /* Max output size. Result should be max this size.
25826 + * Implementation specific tweak:
25827 + * If it's not at least 32 bytes and 6.25% smaller than
25828 + * the original packet, it's probably not worth wasting
25829 + * the receiver's CPU cycles decompressing it.
25830 + * Your mileage may vary.
25831 + */
25832 + cpyldsz = pyldsz - sizeof(struct ipcomphdr) - (pyldsz <= 512 ? 32 : pyldsz >> 4);
25833 +
25834 + buffer = kmalloc(cpyldsz, GFP_ATOMIC);
25835 + if (!buffer) {
25836 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25837 + "klips_error:skb_compress: "
25838 + "unable to kmalloc(%d, GFP_ATOMIC), "
25839 + "skipping compression.\n",
25840 + cpyldsz);
25841 + *flags |= IPCOMP_COMPRESSIONERROR;
25842 + deflateEnd(&zs);
25843 + return skb;
25844 + }
25845 +
25846 +#ifdef CONFIG_KLIPS_DEBUG
25847 + if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
25848 + __u8 *c;
25849 +
25850 + c = (__u8*)iph + iphlen;
25851 + ipsec_dmp_block("compress before", c, pyldsz);
25852 + }
25853 +#endif /* CONFIG_KLIPS_DEBUG */
25854 +
25855 + zs.next_in = (char *) iph + iphlen; /* start of payload */
25856 + zs.avail_in = pyldsz;
25857 + zs.next_out = buffer; /* start of compressed payload */
25858 + zs.avail_out = cpyldsz;
25859 +
25860 + /* Finish compression in one step */
25861 + zresult = deflate(&zs, Z_FINISH);
25862 +
25863 + /* Free all dynamically allocated buffers */
25864 + deflateEnd(&zs);
25865 + if (zresult != Z_STREAM_END) {
25866 + *flags |= IPCOMP_UNCOMPRESSABLE;
25867 + kfree(buffer);
25868 +
25869 + /* Adjust adaptive counters */
25870 + if (++(ips->ips_comp_adapt_tries) == IPCOMP_ADAPT_INITIAL_TRIES) {
25871 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25872 + "klips_debug:skb_compress: "
25873 + "first %d packets didn't compress, "
25874 + "skipping next %d\n",
25875 + IPCOMP_ADAPT_INITIAL_TRIES,
25876 + IPCOMP_ADAPT_INITIAL_SKIP);
25877 + ips->ips_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP;
25878 + }
25879 + else if (ips->ips_comp_adapt_tries == IPCOMP_ADAPT_INITIAL_TRIES + IPCOMP_ADAPT_SUBSEQ_TRIES) {
25880 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25881 + "klips_debug:skb_compress: "
25882 + "next %d packets didn't compress, "
25883 + "skipping next %d\n",
25884 + IPCOMP_ADAPT_SUBSEQ_TRIES,
25885 + IPCOMP_ADAPT_SUBSEQ_SKIP);
25886 + ips->ips_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP;
25887 + ips->ips_comp_adapt_tries = IPCOMP_ADAPT_INITIAL_TRIES;
25888 + }
25889 +
25890 + return skb;
25891 + }
25892 +
25893 + /* resulting compressed size */
25894 + cpyldsz -= zs.avail_out;
25895 +
25896 + /* Insert IPCOMP header */
25897 + ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_nh = iph->protocol;
25898 + ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_flags = 0;
25899 + /* use the bottom 16 bits of the spi for the cpi. The top 16 bits are
25900 + for internal reference only. */
25901 + ((struct ipcomphdr*) (((char*)iph) + iphlen))->ipcomp_cpi = htons((__u16)(ntohl(ips->ips_said.spi) & 0x0000ffff));
25902 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25903 + "klips_debug:skb_compress: "
25904 + "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: raw=%d, comp=%d.\n",
25905 + ntohl(ips->ips_said.spi),
25906 + ntohl(ips->ips_said.spi) & 0x0000ffff,
25907 + ntohs(((struct ipcomphdr*)(((char*)iph)+iphlen))->ipcomp_cpi),
25908 + pyldsz,
25909 + cpyldsz);
25910 +
25911 + /* Update IP header */
25912 + iph->protocol = IPPROTO_COMP;
25913 + iph->tot_len = htons(iphlen + sizeof(struct ipcomphdr) + cpyldsz);
25914 +#if 1 /* XXX checksum is done by ipsec_tunnel ? */
25915 + iph->check = 0;
25916 + iph->check = ip_fast_csum((char *) iph, iph->ihl);
25917 +#endif
25918 +
25919 + /* Copy compressed payload */
25920 + memcpy((char *) iph + iphlen + sizeof(struct ipcomphdr),
25921 + buffer,
25922 + cpyldsz);
25923 + kfree(buffer);
25924 +
25925 + /* Update skb length/tail by "unputting" the shrinkage */
25926 + safe_skb_put (skb, cpyldsz + sizeof(struct ipcomphdr) - pyldsz);
25927 +
25928 +#ifdef CONFIG_KLIPS_DEBUG
25929 + if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
25930 + __u8 *c;
25931 +
25932 + c = (__u8*)iph + iphlen + sizeof(struct ipcomphdr);
25933 + ipsec_dmp_block("compress result", c, cpyldsz);
25934 + }
25935 +#endif /* CONFIG_KLIPS_DEBUG */
25936 +
25937 + ips->ips_comp_adapt_skip = 0;
25938 + ips->ips_comp_adapt_tries = 0;
25939 +
25940 + return skb;
25941 +}
25942 +
25943 +struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
25944 +{
25945 + struct sk_buff *nskb = NULL;
25946 +
25947 + /* original ip header */
25948 + struct iphdr *oiph, *iph;
25949 + unsigned int iphlen, pyldsz, cpyldsz;
25950 + z_stream zs;
25951 + int zresult;
25952 +
25953 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25954 + "klips_debug:skb_decompress: .\n");
25955 +
25956 + if(!skb) {
25957 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25958 + "klips_error:skb_decompress: "
25959 + "passed in NULL skb, returning ERROR.\n");
25960 + if (flags) *flags |= IPCOMP_PARMERROR;
25961 + return skb;
25962 + }
25963 +
25964 + if(!ips && sysctl_ipsec_inbound_policy_check) {
25965 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25966 + "klips_error:skb_decompress: "
25967 + "passed in NULL ipsec_sa needed for comp alg, returning ERROR.\n");
25968 + if (flags) *flags |= IPCOMP_PARMERROR;
25969 + return skb;
25970 + }
25971 +
25972 + if (!flags) {
25973 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25974 + "klips_error:skb_decompress: "
25975 + "passed in NULL flags, returning ERROR.\n");
25976 + ipsec_kfree_skb(skb);
25977 + return NULL;
25978 + }
25979 +
25980 +#ifdef NET_21
25981 + oiph = ip_hdr(skb);
25982 +#else /* NET_21 */
25983 + oiph = skb->ip_hdr;
25984 +#endif /* NET_21 */
25985 +
25986 + iphlen = oiph->ihl << 2;
25987 +
25988 + if (oiph->protocol != IPPROTO_COMP) {
25989 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25990 + "klips_error:skb_decompress: "
25991 + "called with non-IPCOMP packet (protocol=%d),"
25992 + "skipping decompression.\n",
25993 + oiph->protocol);
25994 + *flags |= IPCOMP_PARMERROR;
25995 + return skb;
25996 + }
25997 +
25998 + if ( (((struct ipcomphdr*)((char*) oiph + iphlen))->ipcomp_flags != 0)
25999 + || ((((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi
26000 + != htons(SADB_X_CALG_DEFLATE))
26001 + && sysctl_ipsec_inbound_policy_check
26002 + && (!ips || (ips && (ips->ips_encalg != SADB_X_CALG_DEFLATE)))) ) {
26003 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26004 + "klips_error:skb_decompress: "
26005 + "called with incompatible IPCOMP packet (flags=%d, "
26006 + "cpi=%d), ips-compalg=%d, skipping decompression.\n",
26007 + ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags),
26008 + ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi),
26009 + ips ? ips->ips_encalg : 0);
26010 + *flags |= IPCOMP_PARMERROR;
26011 +
26012 + return skb;
26013 + }
26014 +
26015 + if (ntohs(oiph->frag_off) & ~0x4000) {
26016 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26017 + "klips_error:skb_decompress: "
26018 + "called with fragmented IPCOMP packet, "
26019 + "skipping decompression.\n");
26020 + *flags |= IPCOMP_PARMERROR;
26021 + return skb;
26022 + }
26023 +
26024 + /* original compressed payload size */
26025 + cpyldsz = ntohs(oiph->tot_len) - iphlen - sizeof(struct ipcomphdr);
26026 +
26027 + zs.zalloc = my_zcalloc;
26028 + zs.zfree = my_zfree;
26029 + zs.opaque = 0;
26030 +
26031 + zs.next_in = (char *) oiph + iphlen + sizeof(struct ipcomphdr);
26032 + zs.avail_in = cpyldsz;
26033 +
26034 + /* Maybe we should be a bit conservative about memory
26035 + requirements and use inflateInit2 */
26036 + /* Beware, that this might make us unable to decompress packets
26037 + from other implementations - HINT: check PGPnet source code */
26038 + /* We want to use inflateInit2 because we don't want the adler
26039 + header. */
26040 + zresult = inflateInit2(&zs, -15);
26041 + if (zresult != Z_OK) {
26042 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26043 + "klips_error:skb_decompress: "
26044 + "inflateInit2() returned error %d (%s), "
26045 + "skipping decompression.\n",
26046 + zresult,
26047 + zs.msg ? zs.msg : zError(zresult));
26048 + *flags |= IPCOMP_DECOMPRESSIONERROR;
26049 +
26050 + return skb;
26051 + }
26052 +
26053 + /* We have no way of knowing the exact length of the resulting
26054 + decompressed output before we have actually done the decompression.
26055 + For now, we guess that the packet will not be bigger than the
26056 + attached ipsec device's mtu or 16260, whichever is biggest.
26057 + This may be wrong, since the sender's mtu may be bigger yet.
26058 + XXX This must be dealt with later XXX
26059 + */
26060 +
26061 + /* max payload size */
26062 + pyldsz = skb->dev ? (skb->dev->mtu < 16260 ? 16260 : skb->dev->mtu)
26063 + : (65520 - iphlen);
26064 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26065 + "klips_debug:skb_decompress: "
26066 + "max payload size: %d\n", pyldsz);
26067 +
26068 + while (pyldsz > (cpyldsz + sizeof(struct ipcomphdr)) &&
26069 + (nskb = skb_copy_ipcomp(skb,
26070 + pyldsz - cpyldsz - sizeof(struct ipcomphdr),
26071 + GFP_ATOMIC)) == NULL) {
26072 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26073 + "klips_error:skb_decompress: "
26074 + "unable to skb_copy_ipcomp(skb, %d, GFP_ATOMIC), "
26075 + "trying with less payload size.\n",
26076 + (int)(pyldsz - cpyldsz - sizeof(struct ipcomphdr)));
26077 + pyldsz >>=1;
26078 + }
26079 +
26080 + if (!nskb) {
26081 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26082 + "klips_error:skb_decompress: "
26083 + "unable to allocate memory, dropping packet.\n");
26084 + *flags |= IPCOMP_DECOMPRESSIONERROR;
26085 + inflateEnd(&zs);
26086 +
26087 + return skb;
26088 + }
26089 +
26090 +#ifdef CONFIG_KLIPS_DEBUG
26091 + if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26092 + __u8 *c;
26093 +
26094 + c = (__u8*)oiph + iphlen + sizeof(struct ipcomphdr);
26095 + ipsec_dmp_block("decompress before", c, cpyldsz);
26096 + }
26097 +#endif /* CONFIG_KLIPS_DEBUG */
26098 +
26099 +#ifdef NET_21
26100 + iph = ip_hdr(nskb);
26101 +#else /* NET_21 */
26102 + iph = nskb->ip_hdr;
26103 +#endif /* NET_21 */
26104 + zs.next_out = (char *)iph + iphlen;
26105 + zs.avail_out = pyldsz;
26106 +
26107 + zresult = inflate(&zs, Z_SYNC_FLUSH);
26108 +
26109 + /* work around a bug in zlib, which sometimes wants to taste an extra
26110 + * byte when being used in the (undocumented) raw deflate mode.
26111 + */
26112 + if (zresult == Z_OK && !zs.avail_in && zs.avail_out) {
26113 + __u8 zerostuff = 0;
26114 +
26115 + zs.next_in = &zerostuff;
26116 + zs.avail_in = 1;
26117 + zresult = inflate(&zs, Z_FINISH);
26118 + }
26119 +
26120 + inflateEnd(&zs);
26121 + if (zresult != Z_STREAM_END) {
26122 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26123 + "klips_error:skb_decompress: "
26124 + "inflate() returned error %d (%s), "
26125 + "skipping decompression.\n",
26126 + zresult,
26127 + zs.msg ? zs.msg : zError(zresult));
26128 + *flags |= IPCOMP_DECOMPRESSIONERROR;
26129 + ipsec_kfree_skb(nskb);
26130 +
26131 + return skb;
26132 + }
26133 +
26134 + /* Update IP header */
26135 + /* resulting decompressed size */
26136 + pyldsz -= zs.avail_out;
26137 + iph->tot_len = htons(iphlen + pyldsz);
26138 + iph->protocol = ((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_nh;
26139 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26140 + "klips_debug:skb_decompress: "
26141 + "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n",
26142 + ips ? ntohl(ips->ips_said.spi) : 0,
26143 + ips ? ntohl(ips->ips_said.spi) & 0x0000ffff : 0,
26144 + ntohs(((struct ipcomphdr*)(((char*)oiph)+iphlen))->ipcomp_cpi),
26145 + cpyldsz,
26146 + pyldsz,
26147 + iph->protocol);
26148 +
26149 +#if 1 /* XXX checksum is done by ipsec_rcv ? */
26150 + iph->check = 0;
26151 + iph->check = ip_fast_csum((char*) iph, iph->ihl);
26152 +#endif
26153 +
26154 + /* Update skb length/tail by "unputting" the unused data area */
26155 + safe_skb_put(nskb, -zs.avail_out);
26156 +
26157 + ipsec_kfree_skb(skb);
26158 +
26159 + if (iph->protocol == IPPROTO_COMP)
26160 + {
26161 +#ifdef CONFIG_KLIPS_DEBUG
26162 + if(sysctl_ipsec_debug_ipcomp)
26163 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26164 + "klips_debug:skb_decompress: "
26165 + "Eh? inner packet is also compressed, dropping.\n");
26166 +#endif /* CONFIG_KLIPS_DEBUG */
26167 +
26168 + ipsec_kfree_skb(nskb);
26169 + return NULL;
26170 + }
26171 +
26172 +#ifdef CONFIG_KLIPS_DEBUG
26173 + if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26174 + __u8 *c;
26175 +
26176 + c = (__u8*)iph + iphlen;
26177 + ipsec_dmp_block("decompress result", c, pyldsz);
26178 + }
26179 +#endif /* CONFIG_KLIPS_DEBUG */
26180 +
26181 + return nskb;
26182 +}
26183 +
26184 +
26185 +/* this is derived from skb_copy() in linux 2.2.14 */
26186 +/* May be incompatible with other kernel versions!! */
26187 +static
26188 +struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask)
26189 +{
26190 + struct sk_buff *n;
26191 + struct iphdr *iph;
26192 + unsigned long offset;
26193 + unsigned int iphlen;
26194 +
26195 + if(!skb) {
26196 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26197 + "klips_debug:skb_copy_ipcomp: "
26198 + "passed in NULL skb, returning NULL.\n");
26199 + return NULL;
26200 + }
26201 +
26202 + /*
26203 + * Allocate the copy buffer
26204 + */
26205 +
26206 +#ifdef NET_21
26207 + iph = ip_hdr(skb);
26208 +#else /* NET_21 */
26209 + iph = skb->ip_hdr;
26210 +#endif /* NET_21 */
26211 + if (!iph) return NULL;
26212 + iphlen = iph->ihl << 2;
26213 +
26214 + n=alloc_skb(skb_end_pointer(skb) - skb->head + data_growth, gfp_mask);
26215 + if(n==NULL)
26216 + return NULL;
26217 +
26218 + /*
26219 + * Shift between the two data areas in bytes
26220 + */
26221 +
26222 + offset=n->head-skb->head;
26223 +
26224 + /* Set the data pointer */
26225 + skb_reserve(n,skb->data-skb->head);
26226 + /* Set the tail pointer and length */
26227 + safe_skb_put(n,skb->len+data_growth);
26228 + /* Copy the bytes up to and including the ip header */
26229 + memcpy(n->head,
26230 + skb->head,
26231 + ((char *)iph - (char *)skb->head) + iphlen);
26232 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
26233 + n->list=NULL;
26234 +#endif
26235 + n->next=NULL;
26236 + n->prev=NULL;
26237 + n->sk=NULL;
26238 + n->dev=skb->dev;
26239 + if (skb_transport_header(skb))
26240 + skb_set_transport_header(n, offset);
26241 + n->protocol=skb->protocol;
26242 +#ifdef NET_21
26243 + n->csum = 0;
26244 + n->priority=skb->priority;
26245 + n->dst=dst_clone(skb->dst);
26246 + skb_set_network_header(n, offset);
26247 +#ifndef NETDEV_23
26248 + n->is_clone=0;
26249 +#endif /* NETDEV_23 */
26250 + atomic_set(&n->users, 1);
26251 + n->destructor = NULL;
26252 +#ifdef HAVE_SOCK_SECURITY
26253 + n->security=skb->security;
26254 +#endif
26255 + memcpy(n->cb, skb->cb, sizeof(skb->cb));
26256 +#ifdef CONFIG_IP_FIREWALL
26257 + n->fwmark = skb->fwmark;
26258 +#endif
26259 +#else /* NET_21 */
26260 + n->link3=NULL;
26261 + n->when=skb->when;
26262 + n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
26263 + n->saddr=skb->saddr;
26264 + n->daddr=skb->daddr;
26265 + n->raddr=skb->raddr;
26266 + n->seq=skb->seq;
26267 + n->end_seq=skb->end_seq;
26268 + n->ack_seq=skb->ack_seq;
26269 + n->acked=skb->acked;
26270 + n->free=1;
26271 + n->arp=skb->arp;
26272 + n->tries=0;
26273 + n->lock=0;
26274 + n->users=0;
26275 + memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
26276 +#endif /* NET_21 */
26277 + if (skb_mac_header(skb))
26278 + skb_set_mac_header(n, offset);
26279 +#ifndef NETDEV_23
26280 + n->used=skb->used;
26281 +#endif /* !NETDEV_23 */
26282 + n->pkt_type=skb->pkt_type;
26283 +#ifndef NETDEV_23
26284 + n->pkt_bridged=skb->pkt_bridged;
26285 +#endif /* NETDEV_23 */
26286 + n->ip_summed=0;
26287 +#ifdef HAVE_TSTAMP
26288 + n->tstamp = skb->tstamp;
26289 +#else
26290 + n->stamp=skb->stamp;
26291 +#endif
26292 +#ifndef NETDEV_23 /* this seems to have been removed in 2.4 */
26293 +#if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE)
26294 + n->shapelatency=skb->shapelatency; /* Latency on frame */
26295 + n->shapeclock=skb->shapeclock; /* Time it should go out */
26296 + n->shapelen=skb->shapelen; /* Frame length in clocks */
26297 + n->shapestamp=skb->shapestamp; /* Stamp for shaper */
26298 + n->shapepend=skb->shapepend; /* Pending */
26299 +#endif /* defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) */
26300 +#endif /* NETDEV_23 */
26301 +
26302 + return n;
26303 +}
26304 --- /dev/null Tue Mar 11 13:02:56 2003
26305 +++ linux/net/ipsec/ipsec_ah.c Mon Feb 9 13:51:03 2004
26306 @@ -0,0 +1,369 @@
26307 +/*
26308 + * processing code for AH
26309 + * Copyright (C) 2003-2004 Michael Richardson <mcr@xelerance.com>
26310 + *
26311 + * This program is free software; you can redistribute it and/or modify it
26312 + * under the terms of the GNU General Public License as published by the
26313 + * Free Software Foundation; either version 2 of the License, or (at your
26314 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
26315 + *
26316 + * This program is distributed in the hope that it will be useful, but
26317 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26318 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26319 + * for more details.
26320 + */
26321 +
26322 +#ifndef AUTOCONF_INCLUDED
26323 +#include <linux/config.h>
26324 +#endif
26325 +#include <linux/version.h>
26326 +
26327 +#define __NO_VERSION__
26328 +#include <linux/module.h>
26329 +#include <linux/kernel.h> /* printk() */
26330 +
26331 +#include "openswan/ipsec_param.h"
26332 +
26333 +#ifdef MALLOC_SLAB
26334 +# include <linux/slab.h> /* kmalloc() */
26335 +#else /* MALLOC_SLAB */
26336 +# include <linux/malloc.h> /* kmalloc() */
26337 +#endif /* MALLOC_SLAB */
26338 +#include <linux/errno.h> /* error codes */
26339 +#include <linux/types.h> /* size_t */
26340 +#include <linux/interrupt.h> /* mark_bh */
26341 +
26342 +#include <linux/netdevice.h> /* struct device, and other headers */
26343 +#include <linux/etherdevice.h> /* eth_type_trans */
26344 +#include <linux/ip.h> /* struct iphdr */
26345 +#include <linux/skbuff.h>
26346 +#include <openswan.h>
26347 +#ifdef SPINLOCK
26348 +# ifdef SPINLOCK_23
26349 +# include <linux/spinlock.h> /* *lock* */
26350 +# else /* SPINLOCK_23 */
26351 +# include <asm/spinlock.h> /* *lock* */
26352 +# endif /* SPINLOCK_23 */
26353 +#endif /* SPINLOCK */
26354 +
26355 +#include <net/ip.h>
26356 +#include <net/protocol.h>
26357 +
26358 +#include "openswan/radij.h"
26359 +#include "openswan/ipsec_encap.h"
26360 +#include "openswan/ipsec_sa.h"
26361 +
26362 +#include "openswan/ipsec_radij.h"
26363 +#include "openswan/ipsec_xform.h"
26364 +#include "openswan/ipsec_tunnel.h"
26365 +#include "openswan/ipsec_rcv.h"
26366 +#include "openswan/ipsec_xmit.h"
26367 +
26368 +#include "openswan/ipsec_auth.h"
26369 +#include "openswan/ipsec_ah.h"
26370 +#include "openswan/ipsec_proto.h"
26371 +
26372 +#include "ipsec_ocf.h"
26373 +
26374 +__u32 zeroes[AH_AMAX];
26375 +
26376 +enum ipsec_rcv_value
26377 +ipsec_rcv_ah_checks(struct ipsec_rcv_state *irs,
26378 + struct sk_buff *skb)
26379 +{
26380 + int ahminlen;
26381 +
26382 + ahminlen = irs->hard_header_len + sizeof(struct iphdr);
26383 +
26384 + /* take care not to deref this pointer until we check the minlen though */
26385 + irs->protostuff.ahstuff.ahp = (struct ahhdr *)skb_transport_header(skb);
26386 +
26387 + if((skb->len < ahminlen+sizeof(struct ahhdr)) ||
26388 + (skb->len < ahminlen+(irs->protostuff.ahstuff.ahp->ah_hl << 2))) {
26389 + KLIPS_PRINT(debug_rcv & DB_RX_INAU,
26390 + "klips_debug:ipsec_rcv: "
26391 + "runt ah packet of skb->len=%d received from %s, dropped.\n",
26392 + skb->len,
26393 + irs->ipsaddr_txt);
26394 + if(irs->stats) {
26395 + irs->stats->rx_errors++;
26396 + }
26397 + return IPSEC_RCV_BADLEN;
26398 + }
26399 +
26400 + irs->said.spi = irs->protostuff.ahstuff.ahp->ah_spi;
26401 +
26402 + /* XXX we only support the one 12-byte authenticator for now */
26403 + if(irs->protostuff.ahstuff.ahp->ah_hl != ((AHHMAC_HASHLEN+AHHMAC_RPLLEN) >> 2)) {
26404 + KLIPS_PRINT(debug_rcv & DB_RX_INAU,
26405 + "klips_debug:ipsec_rcv: "
26406 + "bad authenticator length %ld, expected %lu from %s.\n",
26407 + (long)(irs->protostuff.ahstuff.ahp->ah_hl << 2),
26408 + (unsigned long) sizeof(struct ahhdr),
26409 + irs->ipsaddr_txt);
26410 + if(irs->stats) {
26411 + irs->stats->rx_errors++;
26412 + }
26413 + return IPSEC_RCV_BADLEN;
26414 + }
26415 +
26416 + return IPSEC_RCV_OK;
26417 +}
26418 +
26419 +
26420 +enum ipsec_rcv_value
26421 +ipsec_rcv_ah_setup_auth(struct ipsec_rcv_state *irs,
26422 + struct sk_buff *skb,
26423 + __u32 *replay,
26424 + unsigned char **authenticator)
26425 +{
26426 + struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26427 +
26428 + *replay = ntohl(ahp->ah_rpl);
26429 + *authenticator = ahp->ah_data;
26430 +
26431 + return IPSEC_RCV_OK;
26432 +}
26433 +
26434 +enum ipsec_rcv_value
26435 +ipsec_rcv_ah_authcalc(struct ipsec_rcv_state *irs,
26436 + struct sk_buff *skb)
26437 +{
26438 + struct auth_alg *aa;
26439 + struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26440 + union {
26441 + MD5_CTX md5;
26442 + SHA1_CTX sha1;
26443 + } tctx;
26444 + struct iphdr ipo;
26445 + int ahhlen;
26446 +
26447 +#ifdef CONFIG_KLIPS_OCF
26448 + if (irs->ipsp->ocf_in_use)
26449 + return(ipsec_ocf_rcv(irs));
26450 +#endif
26451 +
26452 + aa = irs->authfuncs;
26453 +
26454 + /* copy the initialized keying material */
26455 + memcpy(&tctx, irs->ictx, irs->ictx_len);
26456 +
26457 + ipo = *irs->ipp;
26458 + ipo.tos = 0; /* mutable RFC 2402 3.3.3.1.1.1 */
26459 + ipo.frag_off = 0;
26460 + ipo.ttl = 0;
26461 + ipo.check = 0;
26462 +
26463 +
26464 + /* do the sanitized header */
26465 + (*aa->update)((void*)&tctx, (caddr_t)&ipo, sizeof(struct iphdr));
26466 +
26467 + /* XXX we didn't do the options here! */
26468 +
26469 + /* now do the AH header itself */
26470 + ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
26471 + (*aa->update)((void*)&tctx, (caddr_t)ahp, ahhlen - AHHMAC_HASHLEN);
26472 +
26473 + /* now, do some zeroes */
26474 + (*aa->update)((void*)&tctx, (caddr_t)zeroes, AHHMAC_HASHLEN);
26475 +
26476 + /* finally, do the packet contents themselves */
26477 + (*aa->update)((void*)&tctx,
26478 + (caddr_t)skb_transport_header(skb) + ahhlen,
26479 + skb->len - ahhlen);
26480 +
26481 + (*aa->final)(irs->hash, (void *)&tctx);
26482 +
26483 + memcpy(&tctx, irs->octx, irs->octx_len);
26484 +
26485 + (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
26486 + (*aa->final)(irs->hash, (void *)&tctx);
26487 +
26488 + return IPSEC_RCV_OK;
26489 +}
26490 +
26491 +enum ipsec_rcv_value
26492 +ipsec_rcv_ah_decap(struct ipsec_rcv_state *irs)
26493 +{
26494 + struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26495 + struct sk_buff *skb;
26496 + int ahhlen;
26497 +
26498 + skb=irs->skb;
26499 +
26500 + ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
26501 +
26502 + irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - ahhlen);
26503 + irs->next_header = ahp->ah_nh;
26504 +
26505 + /*
26506 + * move the IP header forward by the size of the AH header, which
26507 + * will remove the the AH header from the packet.
26508 + */
26509 + memmove((void *)(skb_network_header(skb) + ahhlen),
26510 + (void *)(skb_network_header(skb)), irs->iphlen);
26511 +
26512 + ipsec_rcv_dmp("ah postmove", skb->data, skb->len);
26513 +
26514 + /* skb_pull below, will move up by ahhlen */
26515 +
26516 + /* XXX not clear how this can happen, as the message indicates */
26517 + if(skb->len < ahhlen) {
26518 + printk(KERN_WARNING
26519 + "klips_error:ipsec_rcv: "
26520 + "tried to skb_pull ahhlen=%d, %d available. This should never happen, please report.\n",
26521 + ahhlen,
26522 + (int)(skb->len));
26523 + return IPSEC_RCV_DECAPFAIL;
26524 + }
26525 + skb_pull(skb, ahhlen);
26526 +
26527 + skb_set_network_header(skb, ahhlen);
26528 + irs->ipp = ip_hdr(skb);
26529 +
26530 + ipsec_rcv_dmp("ah postpull", (void *)ip_hdr(skb), skb->len);
26531 +
26532 + return IPSEC_RCV_OK;
26533 +}
26534 +
26535 +enum ipsec_xmit_value
26536 +ipsec_xmit_ah_setup(struct ipsec_xmit_state *ixs)
26537 +{
26538 + struct iphdr ipo;
26539 + struct ahhdr *ahp;
26540 +#if defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMAC_SHA1)
26541 + __u8 hash[AH_AMAX];
26542 + union {
26543 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
26544 + MD5_CTX md5;
26545 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
26546 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
26547 + SHA1_CTX sha1;
26548 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
26549 + } tctx;
26550 +#endif
26551 + unsigned char *dat = (unsigned char *)ixs->iph;
26552 +
26553 + ahp = (struct ahhdr *)(dat + ixs->iphlen);
26554 + ahp->ah_spi = ixs->ipsp->ips_said.spi;
26555 + ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
26556 + ahp->ah_rv = 0;
26557 + ahp->ah_nh = ixs->iph->protocol;
26558 + ahp->ah_hl = (sizeof(struct ahhdr) >> 2) - sizeof(__u64)/sizeof(__u32);
26559 + ixs->iph->protocol = IPPROTO_AH;
26560 + ipsec_xmit_dmp("ahp", (char*)ahp, sizeof(*ahp));
26561 +
26562 + ipo = *ixs->iph;
26563 + ipo.tos = 0;
26564 + ipo.frag_off = 0;
26565 + ipo.ttl = 0;
26566 + ipo.check = 0;
26567 + ipsec_xmit_dmp("ipo", (char*)&ipo, sizeof(ipo));
26568 +
26569 + switch(ixs->ipsp->ips_authalg) {
26570 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
26571 + case AH_MD5:
26572 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
26573 + ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
26574 + osMD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
26575 + ipsec_xmit_dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
26576 + osMD5Update(&tctx.md5, (unsigned char *)ahp,
26577 + sizeof(struct ahhdr) - sizeof(ahp->ah_data));
26578 + ipsec_xmit_dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
26579 + osMD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
26580 + ipsec_xmit_dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
26581 + osMD5Update(&tctx.md5, dat + ixs->iphlen + sizeof(struct ahhdr),
26582 + ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
26583 + ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
26584 + osMD5Final(hash, &tctx.md5);
26585 + ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
26586 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
26587 + ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
26588 + osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
26589 + ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
26590 + osMD5Final(hash, &tctx.md5);
26591 + ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
26592 +
26593 + memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
26594 +
26595 + /* paranoid */
26596 + memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
26597 + memset((caddr_t)hash, 0, sizeof(*hash));
26598 + break;
26599 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
26600 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
26601 + case AH_SHA:
26602 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
26603 + SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
26604 + SHA1Update(&tctx.sha1, (unsigned char *)ahp, sizeof(struct ahhdr) - sizeof(ahp->ah_data));
26605 + SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
26606 + SHA1Update(&tctx.sha1, dat + ixs->iphlen + sizeof(struct ahhdr),
26607 + ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
26608 + SHA1Final(hash, &tctx.sha1);
26609 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
26610 + SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
26611 + SHA1Final(hash, &tctx.sha1);
26612 +
26613 + memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
26614 +
26615 + /* paranoid */
26616 + memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
26617 + memset((caddr_t)hash, 0, sizeof(*hash));
26618 + break;
26619 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
26620 + default:
26621 + ixs->stats->tx_errors++;
26622 + return IPSEC_XMIT_AH_BADALG;
26623 + }
26624 +#ifdef NET_21
26625 + skb_set_transport_header(ixs->skb, ipsec_skb_offset(ixs->skb, ahp));
26626 +#endif /* NET_21 */
26627 +
26628 + return IPSEC_XMIT_OK;
26629 +}
26630 +
26631 +struct xform_functions ah_xform_funcs[]={
26632 + {
26633 + protocol: IPPROTO_AH,
26634 + rcv_checks: ipsec_rcv_ah_checks,
26635 + rcv_setup_auth: ipsec_rcv_ah_setup_auth,
26636 + rcv_calc_auth: ipsec_rcv_ah_authcalc,
26637 + rcv_decrypt: ipsec_rcv_ah_decap,
26638 +
26639 + xmit_setup: ipsec_xmit_ah_setup,
26640 + xmit_headroom: sizeof(struct ahhdr),
26641 + xmit_needtailroom: 0,
26642 + },
26643 +};
26644 +
26645 +
26646 +#ifndef CONFIG_XFRM_ALTERNATE_STACK
26647 +#ifdef NET_26
26648 +struct inet_protocol ah_protocol = {
26649 + .handler = ipsec_rcv,
26650 + .no_policy = 1,
26651 +};
26652 +#else
26653 +struct inet_protocol ah_protocol =
26654 +{
26655 + ipsec_rcv, /* AH handler */
26656 + NULL, /* TUNNEL error control */
26657 +#ifdef NETDEV_25
26658 + 1, /* no policy */
26659 +#else
26660 + 0, /* next */
26661 + IPPROTO_AH, /* protocol ID */
26662 + 0, /* copy */
26663 + NULL, /* data */
26664 + "AH" /* name */
26665 +#endif
26666 +};
26667 +#endif /* NET_26 */
26668 +#endif /* CONFIG_XFRM_ALTERNATE_STACK */
26669 +
26670 +/*
26671 + * Local variables:
26672 + * c-file-style: "linux"
26673 + * End:
26674 + *
26675 + */
26676 --- /dev/null Tue Mar 11 13:02:56 2003
26677 +++ linux/net/ipsec/ipsec_alg.c Mon Feb 9 13:51:03 2004
26678 @@ -0,0 +1,1045 @@
26679 +/*
26680 + * Modular extensions service and registration functions
26681 + *
26682 + * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
26683 + *
26684 + * Version: 0.8.1
26685 + *
26686 + * ipsec_alg.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
26687 + *
26688 + * This program is free software; you can redistribute it and/or modify it
26689 + * under the terms of the GNU General Public License as published by the
26690 + * Free Software Foundation; either version 2 of the License, or (at your
26691 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
26692 + *
26693 + * This program is distributed in the hope that it will be useful, but
26694 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26695 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26696 + * for more details.
26697 + *
26698 + */
26699 +#ifndef AUTOCONF_INCLUDED
26700 +#include <linux/config.h>
26701 +#endif
26702 +#include <linux/version.h>
26703 +
26704 +#define __NO_VERSION__
26705 +#include <linux/module.h>
26706 +#include <linux/kernel.h> /* printk() */
26707 +
26708 +#include <linux/netdevice.h> /* struct device, and other headers */
26709 +#include <linux/etherdevice.h> /* eth_type_trans */
26710 +#include <linux/ip.h> /* struct iphdr */
26711 +#include <linux/skbuff.h>
26712 +#include <linux/socket.h>
26713 +#include <linux/in.h>
26714 +#include <linux/types.h>
26715 +#include <linux/string.h> /* memcmp() */
26716 +#include <linux/random.h> /* get_random_bytes() */
26717 +#include <linux/errno.h> /* error codes */
26718 +#ifdef SPINLOCK
26719 +# ifdef SPINLOCK_23
26720 +# include <linux/spinlock.h> /* *lock* */
26721 +# else /* SPINLOCK_23 */
26722 +# include <asm/spinlock.h> /* *lock* */
26723 +# endif /* SPINLOCK_23 */
26724 +#endif /* SPINLOCK */
26725 +
26726 +#include "openswan/ipsec_param.h"
26727 +#include <openswan.h>
26728 +#include "openswan/ipsec_sa.h"
26729 +#include "openswan/radij.h"
26730 +#include "openswan/ipsec_encap.h"
26731 +#include "openswan/ipsec_radij.h"
26732 +#include "openswan/ipsec_xform.h"
26733 +#include "openswan/ipsec_tunnel.h"
26734 +#include "openswan/ipsec_rcv.h"
26735 +#if defined(CONFIG_KLIPS_ESP) || defined(CONFIG_KLIPS_AH)
26736 +# include "openswan/ipsec_ah.h"
26737 +#endif /* defined(CONFIG_KLIPS_ESP) || defined(CONFIG_KLIPS_AH) */
26738 +#ifdef CONFIG_KLIPS_ESP
26739 +# include "openswan/ipsec_esp.h"
26740 +#endif /* !CONFIG_KLIPS_ESP */
26741 +#ifdef CONFIG_KLIPS_IPCOMP
26742 +# include "openswan/ipcomp.h"
26743 +#endif /* CONFIG_KLIPS_COMP */
26744 +
26745 +#include <openswan/pfkeyv2.h>
26746 +#include <openswan/pfkey.h>
26747 +
26748 +#include "openswan/ipsec_alg.h"
26749 +#include "openswan/ipsec_proto.h"
26750 +
26751 +#if K_SADB_EALG_MAX < 255
26752 +#warning Compiling with limited ESP support ( K_SADB_EALG_MAX < 256 )
26753 +#endif
26754 +
26755 +static rwlock_t ipsec_alg_lock = RW_LOCK_UNLOCKED;
26756 +#define IPSEC_ALG_HASHSZ 16 /* must be power of 2, even 2^0=1 */
26757 +static struct list_head ipsec_alg_hash_table[IPSEC_ALG_HASHSZ];
26758 +
26759 +/* Old gcc's will fail here */
26760 +#define barf_out(fmt, args...) do { struct ipsec_alg *ixtc = (struct ipsec_alg *)ixt; printk(KERN_ERR "%s: (%s) " fmt, __FUNCTION__, ixtc->ixt_name , ## args) \
26761 + ; goto out; } while(0)
26762 +
26763 +#ifdef NET_26
26764 +/*
26765 + * Must be already protected by lock
26766 + */
26767 +static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt)
26768 +{
26769 +#ifdef MODULE
26770 + if (ixt->ixt_module)
26771 + try_module_get(ixt->ixt_module);
26772 +#endif
26773 + atomic_inc(&ixt->ixt_refcnt);
26774 +}
26775 +static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
26776 + atomic_dec(&ixt->ixt_refcnt);
26777 +#ifdef MODULE
26778 + if (ixt->ixt_module)
26779 + module_put(ixt->ixt_module);
26780 +#endif
26781 +}
26782 +
26783 +#else
26784 +
26785 +/*
26786 + * Must be already protected by lock
26787 + */
26788 +static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt) {
26789 +#ifdef MODULE
26790 + if (ixt->ixt_module) {
26791 + __MOD_INC_USE_COUNT(ixt->ixt_module);
26792 + }
26793 +#endif
26794 + atomic_inc(&ixt->ixt_refcnt);
26795 +}
26796 +static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
26797 + atomic_dec(&ixt->ixt_refcnt);
26798 +#ifdef MODULE
26799 + if (ixt->ixt_module)
26800 + __MOD_DEC_USE_COUNT(ixt->ixt_module);
26801 +#endif
26802 +}
26803 +#endif
26804 +
26805 +/*
26806 + * simple hash function, optimized for 0-hash (1 list) special
26807 + * case
26808 + */
26809 +#if IPSEC_ALG_HASHSZ > 1
26810 +static inline unsigned ipsec_alg_hashfn(int alg_type, int alg_id) {
26811 + return ((alg_type^alg_id)&(IPSEC_ALG_HASHSZ-1));
26812 +}
26813 +#else
26814 +#define ipsec_alg_hashfn(x,y) (0)
26815 +#endif
26816 +
26817 +/*****************************************************************
26818 + *
26819 + * INTERNAL table handling: insert, delete, find
26820 + *
26821 + *****************************************************************/
26822 +
26823 +/*
26824 + * hash table initialization, called from ipsec_alg_init()
26825 + */
26826 +static void ipsec_alg_hash_init(void) {
26827 + struct list_head *head = ipsec_alg_hash_table;
26828 + int i = IPSEC_ALG_HASHSZ;
26829 + do {
26830 + INIT_LIST_HEAD(head);
26831 + head++;
26832 + i--;
26833 + } while (i);
26834 +}
26835 +/*
26836 + * hash list lookup by {alg_type, alg_id} and table head,
26837 + * must be already protected by lock
26838 + */
26839 +static struct ipsec_alg *__ipsec_alg_find(unsigned alg_type, unsigned alg_id, struct list_head * head) {
26840 + struct list_head *p;
26841 + struct ipsec_alg *ixt=NULL;
26842 + for (p=head->next; p!=head; p=p->next) {
26843 + ixt = list_entry(p, struct ipsec_alg, ixt_list);
26844 + if (ixt->ixt_alg_type == alg_type && ixt->ixt_alg_id==alg_id) {
26845 + goto out;
26846 + }
26847 + }
26848 + ixt=NULL;
26849 +out:
26850 + return ixt;
26851 +}
26852 +/*
26853 + * inserts (in front) a new entry in hash table,
26854 + * called from ipsec_alg_register() when new algorithm is registered.
26855 + */
26856 +static int ipsec_alg_insert(struct ipsec_alg *ixt) {
26857 + int ret=-EINVAL;
26858 + unsigned hashval=ipsec_alg_hashfn(ixt->ixt_alg_type, ixt->ixt_alg_id);
26859 + struct list_head *head= ipsec_alg_hash_table + hashval;
26860 + struct ipsec_alg *ixt_cur;
26861 +
26862 + /* new element must be virgin ... */
26863 + if (ixt->ixt_list.next != &ixt->ixt_list ||
26864 + ixt->ixt_list.prev != &ixt->ixt_list) {
26865 + printk(KERN_ERR "ipsec_alg_insert: ixt object \"%s\" "
26866 + "list head not initialized\n",
26867 + ixt->ixt_name);
26868 + return ret;
26869 + }
26870 + write_lock_bh(&ipsec_alg_lock);
26871 +
26872 + ixt_cur = __ipsec_alg_find(ixt->ixt_alg_type, ixt->ixt_alg_id, head);
26873 +
26874 + /* if previous (current) ipsec_alg found check excl flag of _anyone_ */
26875 + if (ixt_cur
26876 + && ((ixt->ixt_state|ixt_cur->ixt_state) & IPSEC_ALG_ST_EXCL)) {
26877 + barf_out("ipsec_alg for alg_type=%d, alg_id=%d already exist. "
26878 + "Not loaded (ret=%d).\n",
26879 + ixt->ixt_alg_type,
26880 + ixt->ixt_alg_id, ret=-EEXIST);
26881 + }
26882 + list_add(&ixt->ixt_list, head);
26883 + ixt->ixt_state |= IPSEC_ALG_ST_REGISTERED;
26884 + ret=0;
26885 +out:
26886 + write_unlock_bh(&ipsec_alg_lock);
26887 + return ret;
26888 +}
26889 +
26890 +/*
26891 + * deletes an existing entry in hash table,
26892 + * called from ipsec_alg_unregister() when algorithm is unregistered.
26893 + */
26894 +static int ipsec_alg_delete(struct ipsec_alg *ixt) {
26895 + write_lock_bh(&ipsec_alg_lock);
26896 + list_del(&ixt->ixt_list);
26897 + write_unlock_bh(&ipsec_alg_lock);
26898 + return 0;
26899 +}
26900 +
26901 +/*
26902 + * here @user context (read-only when @kernel bh context)
26903 + * -> no bh disabling
26904 + *
26905 + * called from ipsec_sa_init() -> ipsec_alg_sa_init()
26906 + */
26907 +static struct ipsec_alg *ipsec_alg_get(int alg_type, int alg_id)
26908 +{
26909 + unsigned hashval=ipsec_alg_hashfn(alg_type, alg_id);
26910 + struct list_head *head= ipsec_alg_hash_table + hashval;
26911 + struct ipsec_alg *ixt;
26912 +
26913 + read_lock(&ipsec_alg_lock);
26914 + ixt=__ipsec_alg_find(alg_type, alg_id, head);
26915 + if (ixt) __ipsec_alg_usage_inc(ixt);
26916 + read_unlock(&ipsec_alg_lock);
26917 +
26918 + return ixt;
26919 +}
26920 +
26921 +static void ipsec_alg_put(struct ipsec_alg *ixt) {
26922 + __ipsec_alg_usage_dec((struct ipsec_alg *)ixt);
26923 +}
26924 +
26925 +/*****************************************************************
26926 + *
26927 + * INTERFACE for ENC services: key creation, encrypt function
26928 + *
26929 + *****************************************************************/
26930 +
26931 +/*
26932 + * main encrypt service entry point
26933 + * called from ipsec_rcv() with encrypt=IPSEC_ALG_DECRYPT and
26934 + * ipsec_tunnel_start_xmit with encrypt=IPSEC_ALG_ENCRYPT
26935 + */
26936 +int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 * idat,
26937 + int ilen, __u8 * iv, int encrypt)
26938 +{
26939 + int ret;
26940 + struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
26941 +#ifdef CONFIG_KLIPS_DEBUG
26942 + int debug_flag = (encrypt==IPSEC_ALG_ENCRYPT ?
26943 + debug_tunnel : debug_rcv);
26944 +#endif
26945 +
26946 + KLIPS_PRINT(debug_flag,
26947 + "klips_debug:ipsec_alg_esp_encrypt: "
26948 + "entering with encalg=%d, ixt_e=%p\n",
26949 + sa_p->ips_encalg, ixt_e);
26950 + if (ixt_e == NULL) {
26951 + KLIPS_ERROR(debug_flag,
26952 + "klips_debug:ipsec_alg_esp_encrypt: "
26953 + "NULL ipsec_alg_enc object\n");
26954 + return -1;
26955 + }
26956 + KLIPS_PRINT(debug_flag,
26957 + "klips_debug:ipsec_alg_esp_encrypt: "
26958 + "calling cbc_encrypt encalg=%d "
26959 + "ips_key_e=%p idat=%p ilen=%d iv=%p, encrypt=%d\n",
26960 + sa_p->ips_encalg,
26961 + sa_p->ips_key_e, idat, ilen, iv, encrypt);
26962 + ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, sa_p->ips_key_e, idat,
26963 + ilen, iv, encrypt);
26964 + KLIPS_PRINT(debug_flag,
26965 + "klips_debug:ipsec_alg_esp_encrypt: "
26966 + "returned ret=%d\n",
26967 + ret);
26968 + return ret;
26969 +}
26970 +
26971 +/*
26972 + * encryption key context creation function
26973 + * called from pfkey_v2_parser.c:pfkey_ips_init()
26974 + */
26975 +int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p) {
26976 + int ret=-EINVAL;
26977 + int keyminbits, keymaxbits;
26978 + caddr_t ekp;
26979 + struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
26980 +
26981 + KLIPS_PRINT(debug_pfkey,
26982 + "klips_debug:ipsec_alg_enc_key_create: "
26983 + "entering with encalg=%d ixt_e=%p\n",
26984 + sa_p->ips_encalg, ixt_e);
26985 + if (!ixt_e) {
26986 + KLIPS_ERROR(debug_pfkey,
26987 + "klips_debug:ipsec_alg_enc_key_create: "
26988 + "NULL ipsec_alg_enc object\n");
26989 + return -EPROTO;
26990 + }
26991 +
26992 + /*
26993 + * grRRR... DES 7bits jurassic stuff ... f*ckk --jjo
26994 + */
26995 + switch(ixt_e->ixt_common.ixt_support.ias_id) {
26996 + case ESP_3DES:
26997 + keyminbits=keymaxbits=192;break;
26998 + case ESP_DES:
26999 + keyminbits=keymaxbits=64;break;
27000 + default:
27001 + keyminbits=ixt_e->ixt_common.ixt_support.ias_keyminbits;
27002 + keymaxbits=ixt_e->ixt_common.ixt_support.ias_keymaxbits;
27003 + }
27004 + if(sa_p->ips_key_bits_e<keyminbits ||
27005 + sa_p->ips_key_bits_e>keymaxbits) {
27006 + KLIPS_PRINT(debug_pfkey,
27007 + "klips_debug:ipsec_alg_enc_key_create: "
27008 + "incorrect encryption key size for id=%d: %d bits -- "
27009 + "must be between %d,%d bits\n" /*octets (bytes)\n"*/,
27010 + ixt_e->ixt_common.ixt_support.ias_id,
27011 + sa_p->ips_key_bits_e, keyminbits, keymaxbits);
27012 + ret=-EINVAL;
27013 + goto ixt_out;
27014 + }
27015 + /* save encryption key pointer */
27016 + ekp = sa_p->ips_key_e;
27017 +
27018 +
27019 + if (ixt_e->ixt_e_new_key) {
27020 + sa_p->ips_key_e = ixt_e->ixt_e_new_key(ixt_e,
27021 + ekp, sa_p->ips_key_bits_e/8);
27022 + ret = (sa_p->ips_key_e)? 0 : -EINVAL;
27023 + } else {
27024 + if((sa_p->ips_key_e = (caddr_t)
27025 + kmalloc((sa_p->ips_key_e_size = ixt_e->ixt_e_ctx_size),
27026 + GFP_ATOMIC)) == NULL) {
27027 + ret=-ENOMEM;
27028 + goto ixt_out;
27029 + }
27030 + /* zero-out key_e */
27031 + memset(sa_p->ips_key_e, 0, sa_p->ips_key_e_size);
27032 +
27033 + /* I cast here to allow more decoupling in alg module */
27034 + KLIPS_PRINT(debug_pfkey,
27035 + "klips_debug:ipsec_alg_enc_key_create: about to call:"
27036 + "set_key(key_e=%p, ekp=%p, key_size=%d)\n",
27037 + (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
27038 + ret = ixt_e->ixt_e_set_key(ixt_e, (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
27039 + }
27040 + /* paranoid */
27041 + memset(ekp, 0, sa_p->ips_key_bits_e/8);
27042 + kfree(ekp);
27043 +ixt_out:
27044 + return ret;
27045 +}
27046 +
27047 +/***************************************************************
27048 + *
27049 + * INTERFACE for AUTH services: key creation, hash functions
27050 + *
27051 + ***************************************************************/
27052 +
27053 +/*
27054 + * auth key context creation function
27055 + * called from pfkey_v2_parser.c:pfkey_ips_init()
27056 + */
27057 +int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p) {
27058 + int ret=-EINVAL;
27059 + struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
27060 + int keyminbits, keymaxbits;
27061 + unsigned char *akp;
27062 + unsigned int aks;
27063 + KLIPS_PRINT(debug_pfkey,
27064 + "klips_debug:ipsec_alg_auth_key_create: "
27065 + "entering with authalg=%d ixt_a=%p\n",
27066 + sa_p->ips_authalg, ixt_a);
27067 + if (!ixt_a) {
27068 + KLIPS_PRINT(debug_pfkey,
27069 + "klips_debug:ipsec_alg_auth_key_create: "
27070 + "NULL ipsec_alg_auth object\n");
27071 + return -EPROTO;
27072 + }
27073 + keyminbits=ixt_a->ixt_common.ixt_support.ias_keyminbits;
27074 + keymaxbits=ixt_a->ixt_common.ixt_support.ias_keymaxbits;
27075 + if(sa_p->ips_key_bits_a<keyminbits || sa_p->ips_key_bits_a>keymaxbits) {
27076 + KLIPS_PRINT(debug_pfkey,
27077 + "klips_debug:ipsec_alg_auth_key_create: incorrect auth"
27078 + "key size: %d bits -- must be between %d,%d bits\n"/*octets (bytes)\n"*/,
27079 + sa_p->ips_key_bits_a, keyminbits, keymaxbits);
27080 + ret=-EINVAL;
27081 + goto ixt_out;
27082 + }
27083 + /* save auth key pointer */
27084 + sa_p->ips_auth_bits = ixt_a->ixt_a_keylen * 8; /* XXX XXX */
27085 + akp = sa_p->ips_key_a;
27086 + aks = sa_p->ips_key_a_size;
27087 +
27088 + /* will hold: 2 ctx and a blocksize buffer: kb */
27089 + sa_p->ips_key_a_size = ixt_a->ixt_a_ctx_size;
27090 + if((sa_p->ips_key_a =
27091 + (caddr_t) kmalloc(sa_p->ips_key_a_size, GFP_ATOMIC)) == NULL) {
27092 + ret=-ENOMEM;
27093 + goto ixt_out;
27094 + }
27095 + ixt_a->ixt_a_hmac_set_key(ixt_a, sa_p->ips_key_a, akp, sa_p->ips_key_bits_a/8); /* XXX XXX */
27096 + ret=0;
27097 + memset(akp, 0, aks);
27098 + kfree(akp);
27099 +
27100 +ixt_out:
27101 + return ret;
27102 +}
27103 +
27104 +
27105 +int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp,
27106 + int len, __u8 *hash, int hashlen)
27107 +{
27108 + struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
27109 + if (!ixt_a) {
27110 + KLIPS_PRINT(debug_pfkey,
27111 + "klips_debug:ipsec_sa_esp_hash: "
27112 + "NULL ipsec_alg_auth object\n");
27113 + return -EPROTO;
27114 + }
27115 + KLIPS_PRINT(debug_tunnel|debug_rcv,
27116 + "klips_debug:ipsec_sa_esp_hash: "
27117 + "hashing %p (%d bytes) to %p (%d bytes)\n",
27118 + espp, len,
27119 + hash, hashlen);
27120 + ixt_a->ixt_a_hmac_hash(ixt_a,
27121 + sa_p->ips_key_a,
27122 + espp, len,
27123 + hash, hashlen);
27124 + return 0;
27125 +}
27126 +
27127 +/***************************************************************
27128 + *
27129 + * INTERFACE for module loading,testing, and unloading
27130 + *
27131 + ***************************************************************/
27132 +
27133 +/* validation for registering (enc) module */
27134 +static int check_enc(struct ipsec_alg_enc *ixt)
27135 +{
27136 + int ret=-EINVAL;
27137 + if (ixt->ixt_common.ixt_blocksize==0) /* || ixt->ixt_common.ixt_blocksize%2) need for ESP_NULL */
27138 + barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_common.ixt_blocksize);
27139 + if (ixt->ixt_common.ixt_support.ias_keyminbits==0
27140 + && ixt->ixt_common.ixt_support.ias_keymaxbits==0
27141 + && ixt->ixt_e_keylen==0)
27142 + goto zero_key_ok;
27143 +
27144 + if (ixt->ixt_common.ixt_support.ias_keyminbits==0)
27145 + barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_common.ixt_support.ias_keyminbits);
27146 +
27147 + if (ixt->ixt_common.ixt_support.ias_keymaxbits==0)
27148 + barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_common.ixt_support.ias_keymaxbits);
27149 +
27150 + if (ixt->ixt_e_keylen==0)
27151 + barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_e_keylen);
27152 +
27153 +zero_key_ok:
27154 + if (ixt->ixt_e_ctx_size==0 && ixt->ixt_e_new_key == NULL)
27155 + barf_out(KERN_ERR "invalid key_e_size=%d and ixt_e_new_key=NULL\n", ixt->ixt_e_ctx_size);
27156 + if (ixt->ixt_e_cbc_encrypt==NULL)
27157 + barf_out(KERN_ERR "e_cbc_encrypt() must be not NULL\n");
27158 + ret=0;
27159 +out:
27160 + return ret;
27161 +}
27162 +
27163 +/* validation for registering (auth) module */
27164 +static int check_auth(struct ipsec_alg_auth *ixt)
27165 +{
27166 + int ret=-EINVAL;
27167 + if (ixt->ixt_common.ixt_support.ias_id==0 || ixt->ixt_common.ixt_support.ias_id > K_SADB_AALG_MAX)
27168 + barf_out("invalid alg_id=%d > %d (K_SADB_AALG_MAX)\n",
27169 + ixt->ixt_common.ixt_support.ias_id, K_SADB_AALG_MAX);
27170 +
27171 + if (ixt->ixt_common.ixt_blocksize==0
27172 + || ixt->ixt_common.ixt_blocksize%2)
27173 + barf_out(KERN_ERR "invalid blocksize=%d\n",
27174 + ixt->ixt_common.ixt_blocksize);
27175 +
27176 + if (ixt->ixt_common.ixt_blocksize>AH_BLKLEN_MAX)
27177 + barf_out(KERN_ERR "sorry blocksize=%d > %d. "
27178 + "Please increase AH_BLKLEN_MAX and recompile\n",
27179 + ixt->ixt_common.ixt_blocksize,
27180 + AH_BLKLEN_MAX);
27181 + if (ixt->ixt_common.ixt_support.ias_keyminbits==0 && ixt->ixt_common.ixt_support.ias_keymaxbits==0 && ixt->ixt_a_keylen==0)
27182 + goto zero_key_ok;
27183 + if (ixt->ixt_common.ixt_support.ias_keyminbits==0)
27184 + barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_common.ixt_support.ias_keyminbits);
27185 + if (ixt->ixt_common.ixt_support.ias_keymaxbits==0)
27186 + barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_common.ixt_support.ias_keymaxbits);
27187 + if (ixt->ixt_common.ixt_support.ias_keymaxbits!=ixt->ixt_common.ixt_support.ias_keyminbits)
27188 + barf_out(KERN_ERR "keymaxbits must equal keyminbits (not sure).\n");
27189 + if (ixt->ixt_a_keylen==0)
27190 + barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_a_keylen);
27191 +zero_key_ok:
27192 + if (ixt->ixt_a_ctx_size==0)
27193 + barf_out(KERN_ERR "invalid a_ctx_size=%d\n", ixt->ixt_a_ctx_size);
27194 + if (ixt->ixt_a_hmac_set_key==NULL)
27195 + barf_out(KERN_ERR "a_hmac_set_key() must be not NULL\n");
27196 + if (ixt->ixt_a_hmac_hash==NULL)
27197 + barf_out(KERN_ERR "a_hmac_hash() must be not NULL\n");
27198 + ret=0;
27199 +out:
27200 + return ret;
27201 +}
27202 +
27203 +/*
27204 + * Generic (enc, auth) registration entry point
27205 + */
27206 +int register_ipsec_alg(struct ipsec_alg *ixt)
27207 +{
27208 + int ret=-EINVAL;
27209 + /* Validation */
27210 + if (ixt==NULL)
27211 + barf_out("NULL ipsec_alg object passed\n");
27212 + if ((ixt->ixt_version&0xffffff00) != (IPSEC_ALG_VERSION&0xffffff00))
27213 + barf_out("incorrect version: %d.%d.%d-%d, "
27214 + "must be %d.%d.%d[-%d]\n",
27215 + IPSEC_ALG_VERSION_QUAD(ixt->ixt_version),
27216 + IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION));
27217 +
27218 + switch(ixt->ixt_alg_type) {
27219 + case IPSEC_ALG_TYPE_AUTH:
27220 + if ((ret=check_auth((struct ipsec_alg_auth *)ixt)<0))
27221 + goto out;
27222 + break;
27223 + case IPSEC_ALG_TYPE_ENCRYPT:
27224 + if ((ret=check_enc((struct ipsec_alg_enc *)ixt)<0))
27225 + goto out;
27226 + /*
27227 + * Adapted two lines below:
27228 + * ivlen == 0 is possible (NULL enc has blocksize==1)
27229 + *
27230 + * fixed NULL support by David De Reu <DeReu@tComLabs.com>
27231 + */
27232 + if (ixt->ixt_support.ias_ivlen == 0
27233 + && ixt->ixt_blocksize > 1) {
27234 + ixt->ixt_support.ias_ivlen = ixt->ixt_blocksize*8;
27235 + }
27236 + break;
27237 + default:
27238 + barf_out("alg_type=%d not supported\n", ixt->ixt_alg_type);
27239 + }
27240 + INIT_LIST_HEAD(&ixt->ixt_list);
27241 + ret = ipsec_alg_insert(ixt);
27242 + if (ret<0)
27243 + barf_out(KERN_WARNING "ipsec_alg for alg_id=%d failed."
27244 + "Not loaded (ret=%d).\n",
27245 + ixt->ixt_support.ias_id, ret);
27246 +
27247 +
27248 + ret = pfkey_list_insert_supported((struct ipsec_alg_supported *)&ixt->ixt_support
27249 + , &(pfkey_supported_list[K_SADB_SATYPE_ESP]));
27250 +
27251 + if (ret==0) {
27252 + ixt->ixt_state |= IPSEC_ALG_ST_SUPP;
27253 + /* send register event to userspace */
27254 + pfkey_register_reply(K_SADB_SATYPE_ESP, NULL);
27255 + } else
27256 + printk(KERN_ERR "pfkey_list_insert_supported returned %d. "
27257 + "Loading anyway.\n", ret);
27258 + ret=0;
27259 +out:
27260 + return ret;
27261 +}
27262 +
27263 +/*
27264 + * unregister ipsec_alg object from own tables, if
27265 + * success => calls pfkey_list_remove_supported()
27266 + */
27267 +int unregister_ipsec_alg(struct ipsec_alg *ixt) {
27268 + int ret= -EINVAL;
27269 + switch(ixt->ixt_alg_type) {
27270 + case IPSEC_ALG_TYPE_AUTH:
27271 + case IPSEC_ALG_TYPE_ENCRYPT:
27272 + break;
27273 + default:
27274 + /* this is not a typo :) */
27275 + barf_out("frog found in list (\"%s\"): ixt_p=NULL\n",
27276 + ixt->ixt_name);
27277 + }
27278 +
27279 + ret=ipsec_alg_delete(ixt);
27280 + if (ixt->ixt_state&IPSEC_ALG_ST_SUPP) {
27281 + ixt->ixt_state &= ~IPSEC_ALG_ST_SUPP;
27282 + pfkey_list_remove_supported((struct ipsec_alg_supported *)&ixt->ixt_support
27283 + , &(pfkey_supported_list[K_SADB_SATYPE_ESP]));
27284 +
27285 + /* send register event to userspace */
27286 + pfkey_register_reply(K_SADB_SATYPE_ESP, NULL);
27287 + }
27288 +
27289 +out:
27290 + return ret;
27291 +}
27292 +
27293 +/*
27294 + * Must be called from user context
27295 + * used at module load type for testing algo implementation
27296 + */
27297 +static int ipsec_alg_test_encrypt(int enc_alg, int test) {
27298 + int ret;
27299 + caddr_t buf = NULL;
27300 + int iv_size, keysize, key_e_size;
27301 + struct ipsec_alg_enc *ixt_e;
27302 + void *tmp_key_e = NULL;
27303 + #define BUFSZ 1024
27304 + #define MARGIN 0
27305 + #define test_enc (buf+MARGIN)
27306 + #define test_dec (test_enc+BUFSZ+MARGIN)
27307 + #define test_tmp (test_dec+BUFSZ+MARGIN)
27308 + #define test_key_e (test_tmp+BUFSZ+MARGIN)
27309 + #define test_iv (test_key_e+key_e_size+MARGIN)
27310 + #define test_key (test_iv+iv_size+MARGIN)
27311 + #define test_size (BUFSZ*3+key_e_size+iv_size+keysize+MARGIN*7)
27312 + ixt_e=(struct ipsec_alg_enc *)ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, enc_alg);
27313 + if (ixt_e==NULL) {
27314 + KLIPS_PRINT(1,
27315 + "klips_debug: ipsec_alg_test_encrypt: "
27316 + "encalg=%d object not found\n",
27317 + enc_alg);
27318 + ret=-EINVAL;
27319 + goto out;
27320 + }
27321 + iv_size=ixt_e->ixt_common.ixt_support.ias_ivlen / 8;
27322 + key_e_size=ixt_e->ixt_e_ctx_size;
27323 + keysize=ixt_e->ixt_e_keylen;
27324 + KLIPS_PRINT(1,
27325 + "klips_debug: ipsec_alg_test_encrypt: "
27326 + "enc_alg=%d blocksize=%d key_e_size=%d keysize=%d\n",
27327 + enc_alg, iv_size, key_e_size, keysize);
27328 + if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
27329 + ret= -ENOMEM;
27330 + goto out;
27331 + }
27332 + get_random_bytes(test_key, keysize);
27333 + get_random_bytes(test_iv, iv_size);
27334 + if (ixt_e->ixt_e_new_key) {
27335 + tmp_key_e = ixt_e->ixt_e_new_key(ixt_e, test_key, keysize);
27336 + ret = tmp_key_e ? 0 : -EINVAL;
27337 + } else {
27338 + tmp_key_e = test_key_e;
27339 + ret = ixt_e->ixt_e_set_key(ixt_e, test_key_e, test_key, keysize);
27340 + }
27341 + if (ret < 0)
27342 + goto out;
27343 + get_random_bytes(test_enc, BUFSZ);
27344 + memcpy(test_tmp, test_enc, BUFSZ);
27345 + ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_enc, BUFSZ, test_iv, 1);
27346 + printk(KERN_INFO
27347 + "klips_info: ipsec_alg_test_encrypt: "
27348 + "cbc_encrypt=1 ret=%d\n",
27349 + ret);
27350 + ret=memcmp(test_enc, test_tmp, BUFSZ);
27351 + printk(KERN_INFO
27352 + "klips_info: ipsec_alg_test_encrypt: "
27353 + "memcmp(enc, tmp) ret=%d: %s\n", ret,
27354 + ret!=0? "OK. (encr->DIFFers)" : "FAIL! (encr->SAME)" );
27355 + memcpy(test_dec, test_enc, BUFSZ);
27356 + ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_dec, BUFSZ, test_iv, 0);
27357 + printk(KERN_INFO
27358 + "klips_info: ipsec_alg_test_encrypt: "
27359 + "cbc_encrypt=0 ret=%d\n", ret);
27360 + ret=memcmp(test_dec, test_tmp, BUFSZ);
27361 + printk(KERN_INFO
27362 + "klips_info: ipsec_alg_test_encrypt: "
27363 + "memcmp(dec,tmp) ret=%d: %s\n", ret,
27364 + ret==0? "OK. (encr->decr->SAME)" : "FAIL! (encr->decr->DIFFers)" );
27365 + {
27366 + /* Shamelessly taken from drivers/md sources O:) */
27367 + unsigned long now;
27368 + int i, count, max=0;
27369 + int encrypt, speed;
27370 + for (encrypt=0; encrypt <2;encrypt ++) {
27371 + for (i = 0; i < 5; i++) {
27372 + now = jiffies;
27373 + count = 0;
27374 + while (jiffies == now) {
27375 + mb();
27376 + ixt_e->ixt_e_cbc_encrypt(ixt_e,
27377 + tmp_key_e, test_tmp,
27378 + BUFSZ, test_iv, encrypt);
27379 + mb();
27380 + count++;
27381 + mb();
27382 + }
27383 + if (count > max)
27384 + max = count;
27385 + }
27386 + speed = max * (HZ * BUFSZ / 1024);
27387 + printk(KERN_INFO
27388 + "klips_info: ipsec_alg_test_encrypt: "
27389 + "%s %s speed=%d KB/s\n",
27390 + ixt_e->ixt_common.ixt_name,
27391 + encrypt? "encrypt": "decrypt", speed);
27392 + }
27393 + }
27394 +out:
27395 + if (tmp_key_e && ixt_e->ixt_e_destroy_key) ixt_e->ixt_e_destroy_key(ixt_e, tmp_key_e);
27396 + if (buf) kfree(buf);
27397 + if (ixt_e) ipsec_alg_put((struct ipsec_alg *)ixt_e);
27398 + return ret;
27399 + #undef test_enc
27400 + #undef test_dec
27401 + #undef test_tmp
27402 + #undef test_key_e
27403 + #undef test_iv
27404 + #undef test_key
27405 + #undef test_size
27406 +}
27407 +
27408 +/*
27409 + * Must be called from user context
27410 + * used at module load type for testing algo implementation
27411 + */
27412 +static int ipsec_alg_test_auth(int auth_alg, int test) {
27413 + int ret;
27414 + caddr_t buf = NULL;
27415 + int blocksize, keysize, key_a_size;
27416 + struct ipsec_alg_auth *ixt_a;
27417 + #define BUFSZ 1024
27418 + #define MARGIN 0
27419 + #define test_auth (buf+MARGIN)
27420 + #define test_key_a (test_auth+BUFSZ+MARGIN)
27421 + #define test_key (test_key_a+key_a_size+MARGIN)
27422 + #define test_hash (test_key+keysize+MARGIN)
27423 + #define test_size (BUFSZ+key_a_size+keysize+AHHMAC_HASHLEN+MARGIN*4)
27424 + ixt_a=(struct ipsec_alg_auth *)ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, auth_alg);
27425 + if (ixt_a==NULL) {
27426 + KLIPS_PRINT(1,
27427 + "klips_debug: ipsec_alg_test_auth: "
27428 + "encalg=%d object not found\n",
27429 + auth_alg);
27430 + ret=-EINVAL;
27431 + goto out;
27432 + }
27433 + blocksize=ixt_a->ixt_common.ixt_blocksize;
27434 + key_a_size=ixt_a->ixt_a_ctx_size;
27435 + keysize=ixt_a->ixt_a_keylen;
27436 + KLIPS_PRINT(1,
27437 + "klips_debug: ipsec_alg_test_auth: "
27438 + "auth_alg=%d blocksize=%d key_a_size=%d keysize=%d\n",
27439 + auth_alg, blocksize, key_a_size, keysize);
27440 + if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
27441 + ret= -ENOMEM;
27442 + goto out;
27443 + }
27444 + get_random_bytes(test_key, keysize);
27445 + ret = ixt_a->ixt_a_hmac_set_key(ixt_a, test_key_a, test_key, keysize);
27446 + if (ret < 0 )
27447 + goto out;
27448 + get_random_bytes(test_auth, BUFSZ);
27449 + ret=ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
27450 + printk(KERN_INFO
27451 + "klips_info: ipsec_alg_test_auth: "
27452 + "ret=%d\n", ret);
27453 + {
27454 + /* Shamelessly taken from drivers/md sources O:) */
27455 + unsigned long now;
27456 + int i, count, max=0;
27457 + int speed;
27458 + for (i = 0; i < 5; i++) {
27459 + now = jiffies;
27460 + count = 0;
27461 + while (jiffies == now) {
27462 + mb();
27463 + ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
27464 + mb();
27465 + count++;
27466 + mb();
27467 + }
27468 + if (count > max)
27469 + max = count;
27470 + }
27471 + speed = max * (HZ * BUFSZ / 1024);
27472 + printk(KERN_INFO
27473 + "klips_info: ipsec_alg_test_auth: "
27474 + "%s hash speed=%d KB/s\n",
27475 + ixt_a->ixt_common.ixt_name,
27476 + speed);
27477 + }
27478 +out:
27479 + if (buf) kfree(buf);
27480 + if (ixt_a) ipsec_alg_put((struct ipsec_alg *)ixt_a);
27481 + return ret;
27482 + #undef test_auth
27483 + #undef test_key_a
27484 + #undef test_key
27485 + #undef test_hash
27486 + #undef test_size
27487 +}
27488 +
27489 +int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int test) {
27490 + switch(alg_type) {
27491 + case IPSEC_ALG_TYPE_ENCRYPT:
27492 + return ipsec_alg_test_encrypt(alg_id, test);
27493 + break;
27494 + case IPSEC_ALG_TYPE_AUTH:
27495 + return ipsec_alg_test_auth(alg_id, test);
27496 + break;
27497 + }
27498 + printk(KERN_ERR "klips_info: ipsec_alg_test() called incorrectly: "
27499 + "alg_type=%d alg_id=%d\n",
27500 + alg_type, alg_id);
27501 + return -EINVAL;
27502 +}
27503 +
27504 +int ipsec_alg_init(void) {
27505 + KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
27506 + "KLIPS alg v=%d.%d.%d-%d (EALG_MAX=%d, AALG_MAX=%d)\n",
27507 + IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION),
27508 + K_SADB_EALG_MAX, K_SADB_AALG_MAX);
27509 + /* Initialize tables */
27510 + write_lock_bh(&ipsec_alg_lock);
27511 + ipsec_alg_hash_init();
27512 + write_unlock_bh(&ipsec_alg_lock);
27513 +
27514 + /* Initialize static algos */
27515 + KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
27516 + "calling ipsec_alg_static_init()\n");
27517 +
27518 + /* If we are suppose to use our AES, and don't have
27519 + * CryptoAPI enabled...
27520 + */
27521 +#if defined(CONFIG_KLIPS_ENC_AES) && CONFIG_KLIPS_ENC_AES && !defined(CONFIG_KLIPS_ENC_AES_MODULE)
27522 +#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
27523 +#warning "Using built-in AES rather than CryptoAPI AES"
27524 +#endif
27525 + {
27526 + extern int ipsec_aes_init(void);
27527 + ipsec_aes_init();
27528 + }
27529 +#endif
27530 +
27531 +#if defined(CONFIG_KLIPS_ENC_3DES) && !defined(CONFIG_KLIPS_ENC_3DES_MODULE)
27532 +#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
27533 +#warning "Using built-in 3des rather than CryptoAPI 3des"
27534 +#endif
27535 + {
27536 + extern int ipsec_3des_init(void);
27537 + ipsec_3des_init();
27538 + }
27539 +#endif
27540 +
27541 + /* If we are doing CryptoAPI, then init */
27542 +#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI && !defined(CONFIG_KLIPS_ENC_CRYPTOAPI_MODULE)
27543 + {
27544 + extern int ipsec_cryptoapi_init(void);
27545 + ipsec_cryptoapi_init();
27546 + }
27547 +#endif
27548 +
27549 +
27550 + return 0;
27551 +}
27552 +
27553 +/**********************************************
27554 + *
27555 + * INTERFACE for ipsec_sa init and wipe
27556 + *
27557 + **********************************************/
27558 +
27559 +/*
27560 + * Called from pluto -> pfkey_v2_parser.c:pfkey_ipsec_sa_init()
27561 + */
27562 +int ipsec_alg_sa_init(struct ipsec_sa *sa_p) {
27563 + struct ipsec_alg_enc *ixt_e;
27564 + struct ipsec_alg_auth *ixt_a;
27565 +
27566 + /* Only ESP for now ... */
27567 + if (sa_p->ips_said.proto != IPPROTO_ESP)
27568 + return -EPROTONOSUPPORT;
27569 +
27570 + KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_init() :"
27571 + "entering for encalg=%d, authalg=%d\n",
27572 + sa_p->ips_encalg, sa_p->ips_authalg);
27573 +
27574 + if ((ixt_e=(struct ipsec_alg_enc *)
27575 + ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, sa_p->ips_encalg))) {
27576 + KLIPS_PRINT(debug_pfkey,
27577 + "klips_debug: ipsec_alg_sa_init() :"
27578 + "found ipsec_alg (ixt_e=%p) for encalg=%d\n",
27579 + ixt_e, sa_p->ips_encalg);
27580 + sa_p->ips_alg_enc=ixt_e;
27581 + }
27582 +
27583 + if ((ixt_a=(struct ipsec_alg_auth *)
27584 + ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, sa_p->ips_authalg))) {
27585 + KLIPS_PRINT(debug_pfkey,
27586 + "klips_debug: ipsec_alg_sa_init() :"
27587 + "found ipsec_alg (ixt_a=%p) for auth=%d\n",
27588 + ixt_a, sa_p->ips_authalg);
27589 + sa_p->ips_alg_auth=ixt_a;
27590 + }
27591 + return 0;
27592 +}
27593 +
27594 +/*
27595 + * Called from pluto -> ipsec_sa.c:ipsec_sa_delchain()
27596 + */
27597 +int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p) {
27598 + struct ipsec_alg *ixt;
27599 + if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_enc)) {
27600 + KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
27601 + "unlinking for encalg=%d\n",
27602 + ixt->ixt_support.ias_id);
27603 + ipsec_alg_put(ixt);
27604 + }
27605 + if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_auth)) {
27606 + KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
27607 + "unlinking for authalg=%d\n",
27608 + ixt->ixt_support.ias_id);
27609 + ipsec_alg_put(ixt);
27610 + }
27611 + return 0;
27612 +}
27613 +
27614 +IPSEC_PROCFS_DEBUG_NO_STATIC
27615 +int
27616 +ipsec_xform_get_info(char *buffer,
27617 + char **start,
27618 + off_t offset,
27619 + int length IPSEC_PROC_LAST_ARG)
27620 +{
27621 + int len = 0;
27622 + off_t begin = 0;
27623 + int i;
27624 + struct list_head *head;
27625 + struct ipsec_alg *ixt;
27626 +
27627 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
27628 + "klips_debug:ipsec_tncfg_get_info: "
27629 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
27630 + buffer,
27631 + *start,
27632 + (int)offset,
27633 + length);
27634 +
27635 + for(i = 0, head = ipsec_alg_hash_table;
27636 + i<IPSEC_ALG_HASHSZ;
27637 + i++, head++)
27638 + {
27639 + struct list_head *p;
27640 + for (p=head->next; p!=head; p=p->next)
27641 + {
27642 + ixt = list_entry(p, struct ipsec_alg, ixt_list);
27643 + len += ipsec_snprintf(buffer+len, length-len,
27644 + "VERSION=%d TYPE=%d ID=%d NAME=%s REFCNT=%d ",
27645 + ixt->ixt_version, ixt->ixt_alg_type, ixt->ixt_support.ias_id,
27646 + ixt->ixt_name, ixt->ixt_refcnt);
27647 +
27648 + len += ipsec_snprintf(buffer+len, length-len,
27649 + "STATE=%08x BLOCKSIZE=%d IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
27650 + ixt->ixt_state, ixt->ixt_blocksize,
27651 + ixt->ixt_support.ias_ivlen, ixt->ixt_support.ias_keyminbits, ixt->ixt_support.ias_keymaxbits);
27652 +
27653 + len += ipsec_snprintf(buffer+len, length-len,
27654 + "IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
27655 + ixt->ixt_support.ias_ivlen, ixt->ixt_support.ias_keyminbits, ixt->ixt_support.ias_keymaxbits);
27656 +
27657 + switch(ixt->ixt_alg_type)
27658 + {
27659 + case IPSEC_ALG_TYPE_AUTH:
27660 + {
27661 + struct ipsec_alg_auth *auth = (struct ipsec_alg_auth *)ixt;
27662 +
27663 + len += ipsec_snprintf(buffer+len, length-len,
27664 + "KEYLEN=%d CTXSIZE=%d AUTHLEN=%d ",
27665 + auth->ixt_a_keylen, auth->ixt_a_ctx_size,
27666 + auth->ixt_a_authlen);
27667 + break;
27668 + }
27669 + case IPSEC_ALG_TYPE_ENCRYPT:
27670 + {
27671 + struct ipsec_alg_enc *enc = (struct ipsec_alg_enc *)ixt;
27672 + len += ipsec_snprintf(buffer+len, length-len,
27673 + "KEYLEN=%d CTXSIZE=%d ",
27674 + enc->ixt_e_keylen, enc->ixt_e_ctx_size);
27675 +
27676 + break;
27677 + }
27678 + }
27679 +
27680 + len += ipsec_snprintf(buffer+len, length-len, "\n");
27681 + }
27682 + }
27683 +
27684 + *start = buffer + (offset - begin); /* Start of wanted data */
27685 + len -= (offset - begin); /* Start slop */
27686 + if (len > length)
27687 + len = length;
27688 + return len;
27689 +}
27690 +
27691 +
27692 +/*
27693 + * As the author of this module, I ONLY ALLOW using it from
27694 + * GPL (or same LICENSE TERMS as kernel source) modules.
27695 + *
27696 + * In respect to hardware crypto engines this means:
27697 + * * Closed-source device drivers ARE NOT ALLOWED to use
27698 + * this interface.
27699 + * * Closed-source VHDL/Verilog firmware running on
27700 + * the crypto hardware device IS ALLOWED to use this interface
27701 + * via a GPL (or same LICENSE TERMS as kernel source) device driver.
27702 + * --Juan Jose Ciarlante 20/03/2002 (thanks RGB for the correct wording)
27703 + */
27704 +
27705 +/*
27706 + * These symbols can only be used from GPL modules
27707 + * for now, I'm disabling this because it creates false
27708 + * symbol problems for old modutils.
27709 + */
27710 +
27711 +#ifdef CONFIG_MODULES
27712 +#ifndef NET_26
27713 +#if 0
27714 +#ifndef EXPORT_SYMBOL_GPL
27715 +#undef EXPORT_SYMBOL_GPL
27716 +#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
27717 +#endif
27718 +#endif
27719 +EXPORT_SYMBOL(register_ipsec_alg);
27720 +EXPORT_SYMBOL(unregister_ipsec_alg);
27721 +EXPORT_SYMBOL(ipsec_alg_test);
27722 +#endif
27723 +#endif
27724 --- /dev/null Tue Mar 11 13:02:56 2003
27725 +++ linux/net/ipsec/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
27726 @@ -0,0 +1,515 @@
27727 +/*
27728 + * ipsec_alg to linux cryptoapi GLUE
27729 + *
27730 + * Authors: CODE.ar TEAM
27731 + * Harpo MAxx <harpo@linuxmendoza.org.ar>
27732 + * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
27733 + * Luciano Ruete <docemeses@softhome.net>
27734 + *
27735 + * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
27736 + *
27737 + * This program is free software; you can redistribute it and/or modify it
27738 + * under the terms of the GNU General Public License as published by the
27739 + * Free Software Foundation; either version 2 of the License, or (at your
27740 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
27741 + *
27742 + * This program is distributed in the hope that it will be useful, but
27743 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27744 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27745 + * for more details.
27746 + *
27747 + * Example usage:
27748 + * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
27749 + * modprobe ipsec_cryptoapi
27750 + * modprobe ipsec_cryptoapi test=1
27751 + * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
27752 + * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
27753 + * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
27754 + * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
27755 + */
27756 +#ifndef AUTOCONF_INCLUDED
27757 +#include <linux/config.h>
27758 +#endif
27759 +#include <linux/version.h>
27760 +
27761 +/*
27762 + * special case: ipsec core modular with this static algo inside:
27763 + * must avoid MODULE magic for this file
27764 + */
27765 +#if CONFIG_KLIPS_MODULE && CONFIG_KLIPS_ENC_CRYPTOAPI
27766 +#undef MODULE
27767 +#endif
27768 +
27769 +#include <linux/module.h>
27770 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
27771 +# include <linux/moduleparam.h>
27772 +#endif
27773 +#include <linux/init.h>
27774 +
27775 +#include <linux/kernel.h> /* printk() */
27776 +#include <linux/errno.h> /* error codes */
27777 +#include <linux/types.h> /* size_t */
27778 +#include <linux/string.h>
27779 +
27780 +/* Check if __exit is defined, if not null it */
27781 +#ifndef __exit
27782 +#define __exit
27783 +#endif
27784 +
27785 +/* warn the innocent */
27786 +#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
27787 +#warning "No linux CryptoAPI configured, install 2.4.22+ or 2.6.x or enable CryptoAPI"
27788 +#define NO_CRYPTOAPI_SUPPORT
27789 +#endif
27790 +
27791 +#include "openswan.h"
27792 +#include "openswan/ipsec_alg.h"
27793 +#include "openswan/ipsec_policy.h"
27794 +
27795 +#include <linux/crypto.h>
27796 +#ifdef CRYPTO_API_VERSION_CODE
27797 +#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
27798 +#define NO_CRYPTOAPI_SUPPORT
27799 +#endif
27800 +
27801 +#ifdef NO_CRYPTOAPI_SUPPORT
27802 +#warning "Building an unusable module :P"
27803 +/* Catch old CryptoAPI by not allowing module to load */
27804 +IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
27805 +{
27806 + printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
27807 + return -EINVAL;
27808 +}
27809 +#else
27810 +#include <asm/scatterlist.h>
27811 +#include <asm/pgtable.h>
27812 +#include <linux/mm.h>
27813 +
27814 +/*
27815 + * CryptoAPI compat code - we use the current API and macro back to
27816 + * the older ones.
27817 + */
27818 +
27819 +#ifndef CRYPTO_TFM_MODE_CBC
27820 +/*
27821 + * As of linux-2.6.21 this is no longer defined, and presumably no longer
27822 + * needed to be passed into the crypto core code.
27823 + */
27824 +#define CRYPTO_TFM_MODE_CBC 0
27825 +#define CRYPTO_TFM_MODE_ECB 0
27826 +#endif
27827 +
27828 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
27829 + /*
27830 + * Linux 2.6.19 introduced a new Crypto API, setup macro's to convert new
27831 + * API into old API.
27832 + */
27833 +
27834 + /* Symmetric/Block Cipher */
27835 + struct blkcipher_desc
27836 + {
27837 + struct crypto_tfm *tfm;
27838 + void *info;
27839 + };
27840 + #define ecb(X) #X
27841 + #define cbc(X) #X
27842 + #define crypto_has_blkcipher(X, Y, Z) crypto_alg_available(X, 0)
27843 + #define crypto_blkcipher_cast(X) X
27844 + #define crypto_blkcipher_tfm(X) X
27845 + #define crypto_alloc_blkcipher(X, Y, Z) crypto_alloc_tfm(X, CRYPTO_TFM_MODE_CBC)
27846 + #define crypto_blkcipher_ivsize(X) crypto_tfm_alg_ivsize(X)
27847 + #define crypto_blkcipher_blocksize(X) crypto_tfm_alg_blocksize(X)
27848 + #define crypto_blkcipher_setkey(X, Y, Z) crypto_cipher_setkey(X, Y, Z)
27849 + #define crypto_blkcipher_encrypt_iv(W, X, Y, Z) \
27850 + crypto_cipher_encrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
27851 + #define crypto_blkcipher_decrypt_iv(W, X, Y, Z) \
27852 + crypto_cipher_decrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
27853 +
27854 + /* Hash/HMAC/Digest */
27855 + struct hash_desc
27856 + {
27857 + struct crypto_tfm *tfm;
27858 + };
27859 + #define hmac(X) #X
27860 + #define crypto_has_hash(X, Y, Z) crypto_alg_available(X, 0)
27861 + #define crypto_hash_cast(X) X
27862 + #define crypto_hash_tfm(X) X
27863 + #define crypto_alloc_hash(X, Y, Z) crypto_alloc_tfm(X, 0)
27864 + #define crypto_hash_digestsize(X) crypto_tfm_alg_digestsize(X)
27865 + #define crypto_hash_digest(W, X, Y, Z) \
27866 + crypto_digest_digest((W)->tfm, X, sg_num, Z)
27867 +
27868 + /* Asymmetric Cipher */
27869 + #define crypto_has_cipher(X, Y, Z) crypto_alg_available(X, 0)
27870 +
27871 + /* Compression */
27872 + #define crypto_has_comp(X, Y, Z) crypto_alg_available(X, 0)
27873 + #define crypto_comp_tfm(X) X
27874 + #define crypto_comp_cast(X) X
27875 + #define crypto_alloc_comp(X, Y, Z) crypto_alloc_tfm(X, 0)
27876 +#else
27877 + #define ecb(X) "ecb(" #X ")"
27878 + #define cbc(X) "cbc(" #X ")"
27879 + #define hmac(X) "hmac(" #X ")"
27880 +#endif /* if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
27881 +
27882 +#define CIPHERNAME_AES cbc(aes)
27883 +#define CIPHERNAME_1DES cbc(des)
27884 +#define CIPHERNAME_3DES cbc(des3_ede)
27885 +#define CIPHERNAME_BLOWFISH cbc(blowfish)
27886 +#define CIPHERNAME_CAST cbc(cast5)
27887 +#define CIPHERNAME_SERPENT cbc(serpent)
27888 +#define CIPHERNAME_TWOFISH cbc(twofish)
27889 +
27890 +#define DIGESTNAME_MD5 "md5"
27891 +#define DIGESTNAME_SHA1 "sha1"
27892 +
27893 +#define ESP_SERPENT 252 /* from ipsec drafts */
27894 +#define ESP_TWOFISH 253 /* from ipsec drafts */
27895 +
27896 +MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
27897 +static int debug_crypto=0;
27898 +static int test_crypto=0;
27899 +static int excl_crypto=0;
27900 +static int noauto = 0;
27901 +module_param(debug_crypto,int,0644);
27902 +module_param(test_crypto,int,0644);
27903 +module_param(excl_crypto,int,0644);
27904 +module_param(noauto,int,0644);
27905 +
27906 +MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
27907 +
27908 +#ifdef CONFIG_KLIPS_ENC_1DES
27909 +static int des_ede1[] = {-1, -1};
27910 +#endif
27911 +static int des_ede3[] = {-1, -1};
27912 +static int aes[] = {-1, -1};
27913 +static int blowfish[] = {-1, -1};
27914 +static int cast[] = {-1, -1};
27915 +static int serpent[] = {-1, -1};
27916 +static int twofish[] = {-1, -1};
27917 +
27918 +#ifdef CONFIG_KLIPS_ENC_1DES
27919 +module_param_array(des_ede1,int,NULL,0444);
27920 +#endif
27921 +module_param_array(des_ede3,int,NULL,0444);
27922 +module_param_array(aes,int,NULL,0444);
27923 +module_param_array(blowfish,int,NULL,0444);
27924 +module_param_array(cast,int,NULL,0444);
27925 +module_param_array(serpent,int,NULL,0444);
27926 +module_param_array(twofish,int,NULL,0444);
27927 +
27928 +MODULE_PARM_DESC(des_ede1, "0: disable | 1: force_enable | min,max: dontuse");
27929 +MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
27930 +MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
27931 +MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
27932 +MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
27933 +MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
27934 +MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
27935 +
27936 +struct ipsec_alg_capi_cipher {
27937 + const char *ciphername; /* cryptoapi's ciphername */
27938 + unsigned blocksize;
27939 + unsigned short minbits;
27940 + unsigned short maxbits;
27941 + int *parm; /* lkm param for this cipher */
27942 + struct ipsec_alg_enc alg; /* note it's not a pointer */
27943 +};
27944 +
27945 +static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
27946 + { CIPHERNAME_AES, 16, 128, 256, aes, { ixt_common:{ ixt_support:{ ias_id: ESP_AES}}}},
27947 + { CIPHERNAME_TWOFISH, 16, 128, 256, twofish, { ixt_common:{ ixt_support:{ ias_id: ESP_TWOFISH,}}}},
27948 + { CIPHERNAME_SERPENT, 16, 128, 256, serpent, { ixt_common:{ ixt_support:{ ias_id: ESP_SERPENT,}}}},
27949 + { CIPHERNAME_CAST, 8, 128, 128, cast , { ixt_common:{ ixt_support:{ ias_id: ESP_CAST,}}}},
27950 + { CIPHERNAME_BLOWFISH, 8, 96, 448, blowfish, { ixt_common:{ ixt_support:{ ias_id: ESP_BLOWFISH,}}}},
27951 + { CIPHERNAME_3DES, 8, 192, 192, des_ede3, { ixt_common:{ ixt_support:{ ias_id: ESP_3DES,}}}},
27952 +#ifdef CONFIG_KLIPS_ENC_1DES
27953 + { CIPHERNAME_1DES, 8, 64, 64, des_ede1, { ixt_common:{ ixt_support:{ ias_id: ESP_DES,}}}},
27954 +#endif
27955 + { NULL, 0, 0, 0, NULL, {} }
27956 +};
27957 +
27958 +#ifdef NOT_YET
27959 +struct ipsec_alg_capi_digest {
27960 + const char *digestname; /* cryptoapi's digestname */
27961 + struct digest_implementation *di;
27962 + struct ipsec_alg_auth alg; /* note it's not a pointer */
27963 +};
27964 +static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
27965 + { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
27966 + { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
27967 + { NULL, NULL, {} }
27968 +};
27969 +#endif
27970 +/*
27971 + * "generic" linux cryptoapi setup_cipher() function
27972 + */
27973 +int setup_cipher(const char *ciphername)
27974 +{
27975 + return crypto_has_blkcipher(ciphername, 0, CRYPTO_ALG_ASYNC);
27976 +}
27977 +
27978 +/*
27979 + * setups ipsec_alg_capi_cipher "hyper" struct components, calling
27980 + * register_ipsec_alg for cointaned ipsec_alg object
27981 + */
27982 +static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
27983 +static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
27984 +static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, __u8 * iv, int encrypt);
27985 +
27986 +static int
27987 +setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
27988 +{
27989 + int ret;
27990 + cptr->alg.ixt_common.ixt_version = IPSEC_ALG_VERSION;
27991 + cptr->alg.ixt_common.ixt_module = THIS_MODULE;
27992 + atomic_set (& cptr->alg.ixt_common.ixt_refcnt, 0);
27993 + strncpy (cptr->alg.ixt_common.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_common.ixt_name));
27994 +
27995 + cptr->alg.ixt_common.ixt_blocksize=cptr->blocksize;
27996 + cptr->alg.ixt_common.ixt_support.ias_keyminbits=cptr->minbits;
27997 + cptr->alg.ixt_common.ixt_support.ias_keymaxbits=cptr->maxbits;
27998 + cptr->alg.ixt_common.ixt_state = 0;
27999 + if (excl_crypto) cptr->alg.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
28000 + cptr->alg.ixt_e_keylen=cptr->alg.ixt_common.ixt_support.ias_keymaxbits/8;
28001 + cptr->alg.ixt_e_ctx_size = 0;
28002 + cptr->alg.ixt_common.ixt_support.ias_exttype = IPSEC_ALG_TYPE_ENCRYPT;
28003 + cptr->alg.ixt_e_new_key = _capi_new_key;
28004 + cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
28005 + cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
28006 + cptr->alg.ixt_common.ixt_data = cptr;
28007 +
28008 + ret=register_ipsec_alg_enc(&cptr->alg);
28009 + printk(KERN_INFO "KLIPS cryptoapi interface: "
28010 + "alg_type=%d alg_id=%d name=%s "
28011 + "keyminbits=%d keymaxbits=%d, %s(%d)\n",
28012 + cptr->alg.ixt_common.ixt_support.ias_exttype,
28013 + cptr->alg.ixt_common.ixt_support.ias_id,
28014 + cptr->alg.ixt_common.ixt_name,
28015 + cptr->alg.ixt_common.ixt_support.ias_keyminbits,
28016 + cptr->alg.ixt_common.ixt_support.ias_keymaxbits,
28017 + ret ? "not found" : "found", ret);
28018 + return ret;
28019 +}
28020 +/*
28021 + * called in ipsec_sa_wipe() time, will destroy key contexts
28022 + * and do 1 unbind()
28023 + */
28024 +static void
28025 +_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
28026 +{
28027 + struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
28028 +
28029 + if (debug_crypto > 0)
28030 + printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
28031 + "name=%s key_e=%p \n",
28032 + alg->ixt_common.ixt_name, key_e);
28033 + if (!key_e) {
28034 + printk(KERN_ERR "klips_debug: _capi_destroy_key:"
28035 + "name=%s NULL key_e!\n",
28036 + alg->ixt_common.ixt_name);
28037 + return;
28038 + }
28039 + crypto_free_tfm(tfm);
28040 +}
28041 +
28042 +/*
28043 + * create new key context, need alg->ixt_data to know which
28044 + * (of many) cipher inside this module is the target
28045 + */
28046 +static __u8 *
28047 +_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
28048 +{
28049 + struct ipsec_alg_capi_cipher *cptr;
28050 + struct crypto_tfm *tfm=NULL;
28051 +
28052 + cptr = alg->ixt_common.ixt_data;
28053 + if (!cptr) {
28054 + printk(KERN_ERR "_capi_new_key(): "
28055 + "NULL ixt_data (?!) for \"%s\" algo\n"
28056 + , alg->ixt_common.ixt_name);
28057 + goto err;
28058 + }
28059 + if (debug_crypto > 0)
28060 + printk(KERN_DEBUG "klips_debug:_capi_new_key:"
28061 + "name=%s cptr=%p key=%p keysize=%d\n",
28062 + alg->ixt_common.ixt_name, cptr, key, keylen);
28063 +
28064 + /*
28065 + * alloc tfm
28066 + */
28067 + tfm = crypto_blkcipher_tfm(crypto_alloc_blkcipher(cptr->ciphername, 0, CRYPTO_ALG_ASYNC));
28068 + if (!tfm) {
28069 + printk(KERN_ERR "_capi_new_key(): "
28070 + "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
28071 + , alg->ixt_common.ixt_name, cptr->ciphername);
28072 + goto err;
28073 + }
28074 + if (crypto_blkcipher_setkey(crypto_blkcipher_cast(tfm), key, keylen) < 0) {
28075 + printk(KERN_ERR "_capi_new_key(): "
28076 + "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
28077 + , alg->ixt_common.ixt_name, keylen);
28078 + crypto_free_tfm(tfm);
28079 + tfm=NULL;
28080 + }
28081 +err:
28082 + if (debug_crypto > 0)
28083 + printk(KERN_DEBUG "klips_debug:_capi_new_key:"
28084 + "name=%s key=%p keylen=%d tfm=%p\n",
28085 + alg->ixt_common.ixt_name, key, keylen, tfm);
28086 + return (__u8 *) tfm;
28087 +}
28088 +/*
28089 + * core encryption function: will use cx->ci to call actual cipher's
28090 + * cbc function
28091 + */
28092 +static int
28093 +_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, __u8 * iv, int encrypt) {
28094 + int error =0;
28095 + struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
28096 + struct scatterlist sg;
28097 + struct blkcipher_desc desc;
28098 + if (debug_crypto > 1)
28099 + printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
28100 + "key_e=%p "
28101 + "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
28102 + , key_e
28103 + , in, in, ilen, iv, encrypt);
28104 +
28105 + memset(&sg, 0, sizeof(sg));
28106 + sg_set_page(&sg, virt_to_page(in), ilen, offset_in_page(in));
28107 +
28108 + memset(&desc, 0, sizeof(desc));
28109 + desc.tfm = crypto_blkcipher_cast(tfm);
28110 + desc.info = (void *) iv;
28111 +
28112 + if (encrypt)
28113 + error = crypto_blkcipher_encrypt_iv (&desc, &sg, &sg, ilen);
28114 + else
28115 + error = crypto_blkcipher_decrypt_iv (&desc, &sg, &sg, ilen);
28116 + if (debug_crypto > 1)
28117 + printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
28118 + "error=%d\n"
28119 + , error);
28120 + return (error<0)? error : ilen;
28121 +}
28122 +/*
28123 + * main initialization loop: for each cipher in list, do
28124 + * 1) setup cryptoapi cipher else continue
28125 + * 2) register ipsec_alg object
28126 + */
28127 +static int
28128 +setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
28129 +{
28130 + struct ipsec_alg_capi_cipher *cptr;
28131 + /* foreach cipher in list ... */
28132 + for (cptr=clist;cptr->ciphername;cptr++) {
28133 + /*
28134 + * see if cipher has been disabled (0) or
28135 + * if noauto set and not enabled (1)
28136 + */
28137 + if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
28138 + if (debug_crypto>0)
28139 + printk(KERN_INFO "setup_cipher_list(): "
28140 + "ciphername=%s skipped at user request: "
28141 + "noauto=%d parm[0]=%d parm[1]=%d\n"
28142 + , cptr->ciphername
28143 + , noauto
28144 + , cptr->parm[0]
28145 + , cptr->parm[1]);
28146 + continue;
28147 + } else {
28148 + if (debug_crypto>0)
28149 + printk(KERN_INFO "setup_cipher_list(): going to init ciphername=%s: noauto=%d parm[0]=%d parm[1]=%d\n",
28150 + , cptr->ciphername
28151 + , noauto
28152 + , cptr->parm[0]
28153 + , cptr->parm[1]);
28154 + }
28155 + /*
28156 + * use a local ci to avoid touching cptr->ci,
28157 + * if register ipsec_alg success then bind cipher
28158 + */
28159 + if(cptr->alg.ixt_common.ixt_support.ias_name == NULL) {
28160 + cptr->alg.ixt_common.ixt_support.ias_name = cptr->ciphername;
28161 + }
28162 +
28163 + if( setup_cipher(cptr->ciphername) ) {
28164 + if (debug_crypto > 0)
28165 + printk(KERN_DEBUG "klips_debug:"
28166 + "setup_cipher_list():"
28167 + "ciphername=%s found\n"
28168 + , cptr->ciphername);
28169 +
28170 + if (setup_ipsec_alg_capi_cipher(cptr) != 0) {
28171 + printk(KERN_ERR "klips_debug:"
28172 + "setup_cipher_list():"
28173 + "ciphername=%s failed ipsec_alg_register\n"
28174 + , cptr->ciphername);
28175 + }
28176 + } else {
28177 + printk(KERN_INFO "KLIPS: lookup for ciphername=%s: not found \n",
28178 + cptr->ciphername);
28179 + }
28180 + }
28181 + return 0;
28182 +}
28183 +/*
28184 + * deregister ipsec_alg objects and unbind ciphers
28185 + */
28186 +static int
28187 +unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
28188 +{
28189 + struct ipsec_alg_capi_cipher *cptr;
28190 + /* foreach cipher in list ... */
28191 + for (cptr=clist;cptr->ciphername;cptr++) {
28192 + if (cptr->alg.ixt_common.ixt_state & IPSEC_ALG_ST_REGISTERED) {
28193 + unregister_ipsec_alg_enc(&cptr->alg);
28194 + }
28195 + }
28196 + return 0;
28197 +}
28198 +/*
28199 + * test loop for registered algos
28200 + */
28201 +static int
28202 +test_cipher_list (struct ipsec_alg_capi_cipher* clist)
28203 +{
28204 + int test_ret;
28205 + struct ipsec_alg_capi_cipher *cptr;
28206 + /* foreach cipher in list ... */
28207 + for (cptr=clist;cptr->ciphername;cptr++) {
28208 + if (cptr->alg.ixt_common.ixt_state & IPSEC_ALG_ST_REGISTERED) {
28209 + test_ret=ipsec_alg_test(
28210 + cptr->alg.ixt_common.ixt_support.ias_exttype,
28211 + cptr->alg.ixt_common.ixt_support.ias_id,
28212 + test_crypto);
28213 + printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
28214 + cptr->alg.ixt_common.ixt_support.ias_exttype,
28215 + cptr->alg.ixt_common.ixt_support.ias_id,
28216 + test_ret);
28217 + }
28218 + }
28219 + return 0;
28220 +}
28221 +
28222 +IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
28223 +{
28224 + int ret, test_ret;
28225 + if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
28226 + return -EPROTONOSUPPORT;
28227 + if (ret==0 && test_crypto) {
28228 + test_ret=test_cipher_list(alg_capi_carray);
28229 + }
28230 + return ret;
28231 +}
28232 +IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_cryptoapi_fini )
28233 +{
28234 + unsetup_cipher_list(alg_capi_carray);
28235 + return;
28236 +}
28237 +#ifdef MODULE_LICENSE
28238 +MODULE_LICENSE("GPL");
28239 +#endif
28240 +
28241 +#endif /* NO_CRYPTOAPI_SUPPORT */
28242 --- /dev/null Tue Mar 11 13:02:56 2003
28243 +++ linux/net/ipsec/ipsec_esp.c Mon Feb 9 13:51:03 2004
28244 @@ -0,0 +1,584 @@
28245 +/*
28246 + * processing code for ESP
28247 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
28248 + *
28249 + * This program is free software; you can redistribute it and/or modify it
28250 + * under the terms of the GNU General Public License as published by the
28251 + * Free Software Foundation; either version 2 of the License, or (at your
28252 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
28253 + *
28254 + * This program is distributed in the hope that it will be useful, but
28255 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28256 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28257 + * for more details.
28258 + */
28259 +
28260 +#ifndef AUTOCONF_INCLUDED
28261 +#include <linux/config.h>
28262 +#endif
28263 +#include <linux/version.h>
28264 +
28265 +#define __NO_VERSION__
28266 +#include <linux/module.h>
28267 +#include <linux/kernel.h> /* printk() */
28268 +
28269 +#include "openswan/ipsec_param.h"
28270 +
28271 +#ifdef MALLOC_SLAB
28272 +# include <linux/slab.h> /* kmalloc() */
28273 +#else /* MALLOC_SLAB */
28274 +# include <linux/malloc.h> /* kmalloc() */
28275 +#endif /* MALLOC_SLAB */
28276 +#include <linux/errno.h> /* error codes */
28277 +#include <linux/types.h> /* size_t */
28278 +#include <linux/interrupt.h> /* mark_bh */
28279 +
28280 +#include <linux/netdevice.h> /* struct device, and other headers */
28281 +#include <linux/etherdevice.h> /* eth_type_trans */
28282 +#include <linux/ip.h> /* struct iphdr */
28283 +#include <linux/skbuff.h>
28284 +#include <openswan.h>
28285 +#ifdef SPINLOCK
28286 +# ifdef SPINLOCK_23
28287 +# include <linux/spinlock.h> /* *lock* */
28288 +# else /* SPINLOCK_23 */
28289 +# include <asm/spinlock.h> /* *lock* */
28290 +# endif /* SPINLOCK_23 */
28291 +#endif /* SPINLOCK */
28292 +
28293 +#include <net/ip.h>
28294 +#include <net/protocol.h>
28295 +
28296 +#include "openswan/radij.h"
28297 +#include "openswan/ipsec_encap.h"
28298 +#include "openswan/ipsec_sa.h"
28299 +
28300 +#include "openswan/ipsec_radij.h"
28301 +#include "openswan/ipsec_xform.h"
28302 +#include "openswan/ipsec_tunnel.h"
28303 +#include "openswan/ipsec_rcv.h"
28304 +#include "openswan/ipsec_xmit.h"
28305 +
28306 +#include "openswan/ipsec_auth.h"
28307 +
28308 +#ifdef CONFIG_KLIPS_ESP
28309 +#include "openswan/ipsec_esp.h"
28310 +#endif /* CONFIG_KLIPS_ESP */
28311 +
28312 +#include "openswan/ipsec_proto.h"
28313 +#include "openswan/ipsec_alg.h"
28314 +#include "ipsec_ocf.h"
28315 +
28316 +#ifdef CONFIG_KLIPS_DEBUG
28317 +#define ESP_DMP(_x,_y,_z) if(debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
28318 +#else
28319 +#define ESP_DMP(_x,_y,_z)
28320 +#endif
28321 +
28322 +#ifdef CONFIG_KLIPS_ESP
28323 +enum ipsec_rcv_value
28324 +ipsec_rcv_esp_checks(struct ipsec_rcv_state *irs,
28325 + struct sk_buff *skb)
28326 +{
28327 + __u8 proto;
28328 + int len; /* packet length */
28329 +
28330 + len = skb->len;
28331 + proto = irs->ipp->protocol;
28332 +
28333 + /* XXX this will need to be 8 for IPv6 */
28334 + if ((proto == IPPROTO_ESP) && ((len - irs->iphlen) % 4)) {
28335 + printk("klips_error:ipsec_rcv: "
28336 + "got packet with content length = %d from %s -- should be on 4 octet boundary, packet dropped\n",
28337 + len - irs->iphlen,
28338 + irs->ipsaddr_txt);
28339 + if(irs->stats) {
28340 + irs->stats->rx_errors++;
28341 + }
28342 + return IPSEC_RCV_BADLEN;
28343 + }
28344 +
28345 + if(skb->len < (irs->hard_header_len + sizeof(struct iphdr) + sizeof(struct esphdr))) {
28346 + KLIPS_PRINT(debug_rcv & DB_RX_INAU,
28347 + "klips_debug:ipsec_rcv: "
28348 + "runt esp packet of skb->len=%d received from %s, dropped.\n",
28349 + skb->len,
28350 + irs->ipsaddr_txt);
28351 + if(irs->stats) {
28352 + irs->stats->rx_errors++;
28353 + }
28354 + return IPSEC_RCV_BADLEN;
28355 + }
28356 +
28357 + irs->protostuff.espstuff.espp = (struct esphdr *)skb_transport_header(skb);
28358 + irs->said.spi = irs->protostuff.espstuff.espp->esp_spi;
28359 +
28360 + return IPSEC_RCV_OK;
28361 +}
28362 +
28363 +enum ipsec_rcv_value
28364 +ipsec_rcv_esp_decrypt_setup(struct ipsec_rcv_state *irs,
28365 + struct sk_buff *skb,
28366 + __u32 *replay,
28367 + unsigned char **authenticator)
28368 +{
28369 + struct esphdr *espp = irs->protostuff.espstuff.espp;
28370 + //unsigned char *idat = (unsigned char *)espp;
28371 +
28372 + KLIPS_PRINT(debug_rcv,
28373 + "klips_debug:ipsec_rcv: "
28374 + "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n",
28375 + irs->ipsaddr_txt,
28376 + (__u32)ntohl(espp->esp_rpl),
28377 + (__u32)ntohl(*((__u32 *)(espp->esp_iv) )),
28378 + (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)),
28379 + irs->len,
28380 + irs->ilen,
28381 + irs->sa_len ? irs->sa : " (error)");
28382 +
28383 + *replay = ntohl(espp->esp_rpl);
28384 + *authenticator = &(skb_transport_header(skb)[irs->ilen]);
28385 +
28386 + return IPSEC_RCV_OK;
28387 +}
28388 +
28389 +enum ipsec_rcv_value
28390 +ipsec_rcv_esp_authcalc(struct ipsec_rcv_state *irs,
28391 + struct sk_buff *skb)
28392 +{
28393 + struct auth_alg *aa;
28394 + struct esphdr *espp = irs->protostuff.espstuff.espp;
28395 + union {
28396 + MD5_CTX md5;
28397 + SHA1_CTX sha1;
28398 + } tctx;
28399 +
28400 +#ifdef CONFIG_KLIPS_OCF
28401 + if (irs->ipsp->ocf_in_use)
28402 + return(ipsec_ocf_rcv(irs));
28403 +#endif
28404 +
28405 +#ifdef CONFIG_KLIPS_ALG
28406 + if (irs->ipsp->ips_alg_auth) {
28407 + KLIPS_PRINT(debug_rcv,
28408 + "klips_debug:ipsec_rcv: "
28409 + "ipsec_alg hashing proto=%d... ",
28410 + irs->said.proto);
28411 + if(irs->said.proto == IPPROTO_ESP) {
28412 + ipsec_alg_sa_esp_hash(irs->ipsp,
28413 + (caddr_t)espp, irs->ilen,
28414 + irs->hash, AHHMAC_HASHLEN);
28415 + return IPSEC_RCV_OK;
28416 + }
28417 + return IPSEC_RCV_BADPROTO;
28418 + }
28419 +#endif
28420 + aa = irs->authfuncs;
28421 +
28422 + /* copy the initialized keying material */
28423 + memcpy(&tctx, irs->ictx, irs->ictx_len);
28424 +
28425 +#ifdef HASH_DEBUG
28426 + ESP_DMP("ictx", irs->ictx, irs->ictx_len);
28427 +
28428 + ESP_DMP("mac_esp", (caddr_t)espp, irs->ilen);
28429 +#endif
28430 + (*aa->update)((void *)&tctx, (caddr_t)espp, irs->ilen);
28431 +
28432 + (*aa->final)(irs->hash, (void *)&tctx);
28433 +
28434 +#ifdef HASH_DEBUG
28435 + ESP_DMP("hash1", irs->hash, aa->hashlen);
28436 +#endif
28437 +
28438 + memcpy(&tctx, irs->octx, irs->octx_len);
28439 +
28440 +#ifdef HASH_DEBUG
28441 + ESP_DMP("octx", irs->octx, irs->octx_len);
28442 +#endif
28443 +
28444 + (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
28445 + (*aa->final)(irs->hash, (void *)&tctx);
28446 +
28447 + return IPSEC_RCV_OK;
28448 +}
28449 +
28450 +
28451 +enum ipsec_rcv_value
28452 +ipsec_rcv_esp_decrypt(struct ipsec_rcv_state *irs)
28453 +{
28454 + struct ipsec_sa *ipsp = irs->ipsp;
28455 +#ifdef CONFIG_KLIPS_ALG
28456 + struct esphdr *espp = irs->protostuff.espstuff.espp;
28457 + __u8 *idat; /* pointer to content to be decrypted/authenticated */
28458 + int encaplen = 0;
28459 + struct sk_buff *skb;
28460 + struct ipsec_alg_enc *ixt_e=NULL;
28461 +#endif
28462 +
28463 +#ifdef CONFIG_KLIPS_OCF
28464 + if (ipsp->ocf_in_use)
28465 + return(ipsec_ocf_rcv(irs));
28466 +#endif
28467 +
28468 +#ifdef CONFIG_KLIPS_ALG
28469 + skb=irs->skb;
28470 +
28471 + idat = skb_transport_header(skb);
28472 +
28473 + /* encaplen is the distance between the end of the IP
28474 + * header and the beginning of the ESP header.
28475 + * on ESP headers it is zero, but on UDP-encap ESP
28476 + * it includes the space for the UDP header.
28477 + *
28478 + * Note: UDP-encap code has already moved the
28479 + * skb->data forward to accomodate this.
28480 + */
28481 + encaplen = skb_transport_header(skb) - (skb_network_header(skb) + irs->iphlen);
28482 +
28483 + ixt_e=ipsp->ips_alg_enc;
28484 + irs->esphlen = ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
28485 + KLIPS_PRINT(debug_rcv,
28486 + "klips_debug:ipsec_rcv: "
28487 + "encalg=%d esphlen=%d\n",
28488 + ipsp->ips_encalg, irs->esphlen);
28489 +
28490 + idat += irs->esphlen;
28491 + irs->ilen -= irs->esphlen;
28492 +
28493 + if (ipsec_alg_esp_encrypt(ipsp,
28494 + idat, irs->ilen, espp->esp_iv,
28495 + IPSEC_ALG_DECRYPT) <= 0) {
28496 +#ifdef CONFIG_KLIPS_DEBUG
28497 + KLIPS_ERROR(debug_rcv, "klips_error:ipsec_rcv: "
28498 + "got packet with esplen = %d "
28499 + "from %s -- should be on "
28500 + "ENC(%d) octet boundary, "
28501 + "packet dropped\n",
28502 + irs->ilen,
28503 + irs->ipsaddr_txt,
28504 + ipsp->ips_encalg);
28505 +#endif
28506 + if(irs->stats) {
28507 + irs->stats->rx_errors++;
28508 + }
28509 + return IPSEC_RCV_BAD_DECRYPT;
28510 + }
28511 +
28512 + return ipsec_rcv_esp_post_decrypt(irs);
28513 +#else
28514 + return IPSEC_RCV_BAD_DECRYPT;
28515 +#endif /* CONFIG_KLIPS_ALG */
28516 +}
28517 +
28518 +
28519 +enum ipsec_rcv_value
28520 +ipsec_rcv_esp_post_decrypt(struct ipsec_rcv_state *irs)
28521 +{
28522 + struct sk_buff *skb;
28523 + __u8 *idat; /* pointer to content to be decrypted/authenticated */
28524 + struct ipsec_sa *ipsp = irs->ipsp;
28525 + int pad = 0, padlen;
28526 + int badpad = 0;
28527 + int i;
28528 +
28529 + skb = irs->skb;
28530 +
28531 + idat = skb_transport_header(skb) + irs->esphlen;
28532 +
28533 + ESP_DMP("postdecrypt", idat, irs->ilen);
28534 +
28535 + irs->next_header = idat[irs->ilen - 1];
28536 + padlen = idat[irs->ilen - 2];
28537 + pad = padlen + 2 + irs->authlen;
28538 +
28539 + KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28540 + "klips_debug:ipsec_rcv_esp_post_decrypt: "
28541 + "padlen=%d, contents: 0x<offset>: 0x<value> 0x<value> ...\n",
28542 + padlen);
28543 +
28544 + for (i = 1; i <= padlen; i++) {
28545 + if((i % 16) == 1) {
28546 + KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28547 + "klips_debug: %02x:",
28548 + i - 1);
28549 + }
28550 + KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28551 + " %02x",
28552 + idat[irs->ilen - 2 - padlen + i - 1]);
28553 + if(i != idat[irs->ilen - 2 - padlen + i - 1]) {
28554 + badpad = 1;
28555 + }
28556 + if((i % 16) == 0) {
28557 + KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28558 + "\n");
28559 + }
28560 + }
28561 + if((i % 16) != 1) {
28562 + KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28563 + "\n");
28564 + }
28565 + if(badpad) {
28566 + KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28567 + "klips_debug:ipsec_rcv_esp_post_decrypt: "
28568 + "warning, decrypted packet from %s has bad padding\n",
28569 + irs->ipsaddr_txt);
28570 + KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28571 + "klips_debug:ipsec_rcv_esp_post_decrypt: "
28572 + "...may be bad decryption -- not dropped\n");
28573 + ipsp->ips_errs.ips_encpad_errs += 1;
28574 + }
28575 +
28576 + KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28577 + "klips_debug:ipsec_rcv_esp_post_decrypt: "
28578 + "packet decrypted from %s: next_header = %d, padding = %d\n",
28579 + irs->ipsaddr_txt,
28580 + irs->next_header,
28581 + pad - 2 - irs->authlen);
28582 +
28583 + irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - (irs->esphlen + pad));
28584 +
28585 + /*
28586 + * move the IP header forward by the size of the ESP header, which
28587 + * will remove the the ESP header from the packet.
28588 + *
28589 + * XXX this is really unnecessary, since odds we are in tunnel
28590 + * mode, and we will be *removing* this IP header.
28591 + *
28592 + */
28593 + memmove((void *)(idat - irs->iphlen),
28594 + (void *)(skb_network_header(skb)), irs->iphlen);
28595 +
28596 + ESP_DMP("esp postmove", (idat - irs->iphlen),
28597 + irs->iphlen + irs->ilen);
28598 +
28599 + /* skb_pull below, will move up by esphlen */
28600 +
28601 + /* XXX not clear how this can happen, as the message indicates */
28602 + if(skb->len < irs->esphlen) {
28603 + printk(KERN_WARNING
28604 + "klips_error:ipsec_rcv_esp_post_decrypt: "
28605 + "tried to skb_pull esphlen=%d, %d available. This should never happen, please report.\n",
28606 + irs->esphlen, (int)(skb->len));
28607 + return IPSEC_RCV_ESP_DECAPFAIL;
28608 + }
28609 + skb_pull(skb, irs->esphlen);
28610 + skb_set_network_header(skb, ipsec_skb_offset(skb, idat - irs->iphlen));
28611 + irs->ipp = ip_hdr(skb);
28612 +
28613 + ESP_DMP("esp postpull", skb->data, skb->len);
28614 +
28615 + /* now, trip off the padding from the end */
28616 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
28617 + "klips_debug:ipsec_rcv: "
28618 + "trimming to %d.\n",
28619 + irs->len - irs->esphlen - pad);
28620 + if(pad + irs->esphlen <= irs->len) {
28621 + skb_trim(skb, irs->len - irs->esphlen - pad);
28622 + } else {
28623 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
28624 + "klips_debug:ipsec_rcv: "
28625 + "bogus packet, size is zero or negative, dropping.\n");
28626 + return IPSEC_RCV_DECAPFAIL;
28627 + }
28628 +
28629 + return IPSEC_RCV_OK;
28630 +}
28631 +
28632 +/*
28633 + *
28634 + */
28635 +enum ipsec_xmit_value
28636 +ipsec_xmit_esp_setup(struct ipsec_xmit_state *ixs)
28637 +{
28638 +#ifdef CONFIG_KLIPS_ENC_3DES
28639 + __u32 iv[2];
28640 +#endif
28641 + struct esphdr *espp;
28642 + int ilen = 0;
28643 + int padlen = 0, i;
28644 + unsigned char *dat;
28645 + unsigned char *idat, *pad;
28646 +#if defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMAC_SHA1)
28647 + __u8 hash[AH_AMAX];
28648 + union {
28649 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
28650 + MD5_CTX md5;
28651 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
28652 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
28653 + SHA1_CTX sha1;
28654 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
28655 + } tctx;
28656 +#endif
28657 +
28658 + dat = (unsigned char *)ixs->iph;
28659 +
28660 + espp = (struct esphdr *)(dat + ixs->iphlen);
28661 + espp->esp_spi = ixs->ipsp->ips_said.spi;
28662 + espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
28663 +
28664 + switch(ixs->ipsp->ips_encalg) {
28665 +#if defined(CONFIG_KLIPS_ENC_3DES)
28666 +#ifdef CONFIG_KLIPS_ENC_3DES
28667 + case ESP_3DES:
28668 +#endif /* CONFIG_KLIPS_ENC_3DES */
28669 + iv[0] = *((__u32*)&(espp->esp_iv) ) =
28670 + ((__u32*)(ixs->ipsp->ips_iv))[0];
28671 + iv[1] = *((__u32*)&(espp->esp_iv) + 1) =
28672 + ((__u32*)(ixs->ipsp->ips_iv))[1];
28673 + break;
28674 +#endif /* defined(CONFIG_KLIPS_ENC_3DES) */
28675 + default:
28676 + ixs->stats->tx_errors++;
28677 + return IPSEC_XMIT_ESP_BADALG;
28678 + }
28679 +
28680 + idat = dat + ixs->iphlen + sizeof(struct esphdr);
28681 + ilen = ixs->skb->len - (ixs->iphlen + sizeof(struct esphdr) + ixs->authlen);
28682 +
28683 + /* Self-describing padding */
28684 + pad = &dat[ixs->skb->len - ixs->tailroom];
28685 + padlen = ixs->tailroom - 2 - ixs->authlen;
28686 + for (i = 0; i < padlen; i++) {
28687 + pad[i] = i + 1;
28688 + }
28689 + dat[ixs->skb->len - ixs->authlen - 2] = padlen;
28690 +
28691 + dat[ixs->skb->len - ixs->authlen - 1] = ixs->iph->protocol;
28692 + ixs->iph->protocol = IPPROTO_ESP;
28693 +
28694 + switch(ixs->ipsp->ips_encalg) {
28695 +#ifdef CONFIG_KLIPS_ENC_3DES
28696 + case ESP_3DES:
28697 + des_ede3_cbc_encrypt((des_cblock *)idat,
28698 + (des_cblock *)idat,
28699 + ilen,
28700 + ((struct des_eks *)(ixs->ipsp->ips_key_e))[0].ks,
28701 + ((struct des_eks *)(ixs->ipsp->ips_key_e))[1].ks,
28702 + ((struct des_eks *)(ixs->ipsp->ips_key_e))[2].ks,
28703 + (des_cblock *)iv, 1);
28704 + break;
28705 +#endif /* CONFIG_KLIPS_ENC_3DES */
28706 + default:
28707 + ixs->stats->tx_errors++;
28708 + return IPSEC_XMIT_ESP_BADALG;
28709 + }
28710 +
28711 + switch(ixs->ipsp->ips_encalg) {
28712 +#if defined(CONFIG_KLIPS_ENC_3DES)
28713 +#ifdef CONFIG_KLIPS_ENC_3DES
28714 + case ESP_3DES:
28715 +#endif /* CONFIG_KLIPS_ENC_3DES */
28716 + /* XXX update IV with the last 8 octets of the encryption */
28717 +#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK
28718 + ((__u32*)(ixs->ipsp->ips_iv))[0] =
28719 + ((__u32 *)(idat))[(ilen >> 2) - 2];
28720 + ((__u32*)(ixs->ipsp->ips_iv))[1] =
28721 + ((__u32 *)(idat))[(ilen >> 2) - 1];
28722 +#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
28723 + prng_bytes(&ipsec_prng, (char *)ixs->ipsp->ips_iv, EMT_ESPDES_IV_SZ);
28724 +#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
28725 + break;
28726 +#endif /* defined(CONFIG_KLIPS_ENC_3DES) */
28727 + default:
28728 + ixs->stats->tx_errors++;
28729 + return IPSEC_XMIT_ESP_BADALG;
28730 + }
28731 +
28732 + switch(ixs->ipsp->ips_authalg) {
28733 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
28734 + case AH_MD5:
28735 + ipsec_xmit_dmp("espp", (char*)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
28736 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
28737 + ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
28738 + osMD5Update(&tctx.md5, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
28739 + ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
28740 + osMD5Final(hash, &tctx.md5);
28741 + ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
28742 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
28743 + ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
28744 + osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
28745 + ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
28746 + osMD5Final(hash, &tctx.md5);
28747 + ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
28748 + memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
28749 +
28750 + /* paranoid */
28751 + memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
28752 + memset((caddr_t)hash, 0, sizeof(*hash));
28753 + break;
28754 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
28755 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
28756 + case AH_SHA:
28757 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
28758 + SHA1Update(&tctx.sha1, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
28759 + SHA1Final(hash, &tctx.sha1);
28760 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
28761 + SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
28762 + SHA1Final(hash, &tctx.sha1);
28763 + memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
28764 +
28765 + /* paranoid */
28766 + memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
28767 + memset((caddr_t)hash, 0, sizeof(*hash));
28768 + break;
28769 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
28770 + case AH_NONE:
28771 + break;
28772 + default:
28773 + ixs->stats->tx_errors++;
28774 + return IPSEC_XMIT_AH_BADALG;
28775 + }
28776 +
28777 + skb_set_transport_header(ixs->skb, ipsec_skb_offset(ixs->skb, espp));
28778 +
28779 + return IPSEC_XMIT_OK;
28780 +}
28781 +
28782 +
28783 +struct xform_functions esp_xform_funcs[]={
28784 + {
28785 + protocol: IPPROTO_ESP,
28786 + rcv_checks: ipsec_rcv_esp_checks,
28787 + rcv_setup_auth: ipsec_rcv_esp_decrypt_setup,
28788 + rcv_calc_auth: ipsec_rcv_esp_authcalc,
28789 + rcv_decrypt: ipsec_rcv_esp_decrypt,
28790 +
28791 + xmit_setup: ipsec_xmit_esp_setup,
28792 + xmit_headroom: sizeof(struct esphdr),
28793 + xmit_needtailroom: 1,
28794 + },
28795 +};
28796 +
28797 +#ifndef CONFIG_XFRM_ALTERNATE_STACK
28798 +#ifdef NET_26
28799 +struct inet_protocol esp_protocol = {
28800 + .handler = ipsec_rcv,
28801 + .no_policy = 1,
28802 +};
28803 +#else
28804 +struct inet_protocol esp_protocol =
28805 +{
28806 + ipsec_rcv, /* ESP handler */
28807 + NULL, /* TUNNEL error control */
28808 +#ifdef NETDEV_25
28809 + 1, /* no policy */
28810 +#else
28811 + 0, /* next */
28812 + IPPROTO_ESP, /* protocol ID */
28813 + 0, /* copy */
28814 + NULL, /* data */
28815 + "ESP" /* name */
28816 +#endif
28817 +};
28818 +#endif /* NET_26 */
28819 +#endif /* CONFIG_XFRM_ALTERNATE_STACK */
28820 +
28821 +#endif /* !CONFIG_KLIPS_ESP */
28822 +
28823 +/*
28824 + * Local variables:
28825 + * c-file-style: "linux"
28826 + * End:
28827 + *
28828 + */
28829 --- /dev/null Tue Mar 11 13:02:56 2003
28830 +++ linux/net/ipsec/ipsec_init.c Mon Feb 9 13:51:03 2004
28831 @@ -0,0 +1,460 @@
28832 +/*
28833 + * @(#) Initialization code.
28834 + * Copyright (C) 1996, 1997 John Ioannidis.
28835 + * Copyright (C) 1998 - 2002 Richard Guy Briggs <rgb@freeswan.org>
28836 + * 2001 - 2004 Michael Richardson <mcr@xelerance.com>
28837 + *
28838 + * This program is free software; you can redistribute it and/or modify it
28839 + * under the terms of the GNU General Public License as published by the
28840 + * Free Software Foundation; either version 2 of the License, or (at your
28841 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
28842 + *
28843 + * This program is distributed in the hope that it will be useful, but
28844 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28845 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28846 + * for more details.
28847 + *
28848 + * /proc system code was split out into ipsec_proc.c after rev. 1.70.
28849 + *
28850 + */
28851 +
28852 +#ifndef AUTOCONF_INCLUDED
28853 +#include <linux/config.h>
28854 +#endif
28855 +#include <linux/version.h>
28856 +#include <linux/module.h>
28857 +#include <linux/kernel.h> /* printk() */
28858 +
28859 +#include "openswan/ipsec_param.h"
28860 +
28861 +#ifdef MALLOC_SLAB
28862 +# include <linux/slab.h> /* kmalloc() */
28863 +#else /* MALLOC_SLAB */
28864 +# include <linux/malloc.h> /* kmalloc() */
28865 +#endif /* MALLOC_SLAB */
28866 +#include <linux/errno.h> /* error codes */
28867 +#include <linux/types.h> /* size_t */
28868 +#include <linux/interrupt.h> /* mark_bh */
28869 +
28870 +#include <linux/netdevice.h> /* struct device, and other headers */
28871 +#include <linux/etherdevice.h> /* eth_type_trans */
28872 +#include <linux/ip.h> /* struct iphdr */
28873 +#include <linux/in.h> /* struct sockaddr_in */
28874 +#include <linux/skbuff.h>
28875 +#include <linux/random.h> /* get_random_bytes() */
28876 +#include <net/protocol.h>
28877 +
28878 +#include <openswan.h>
28879 +
28880 +#ifdef SPINLOCK
28881 +# ifdef SPINLOCK_23
28882 +# include <linux/spinlock.h> /* *lock* */
28883 +# else /* 23_SPINLOCK */
28884 +# include <asm/spinlock.h> /* *lock* */
28885 +# endif /* 23_SPINLOCK */
28886 +#endif /* SPINLOCK */
28887 +
28888 +#include <net/ip.h>
28889 +
28890 +#ifdef CONFIG_PROC_FS
28891 +# include <linux/proc_fs.h>
28892 +#endif /* CONFIG_PROC_FS */
28893 +
28894 +#ifdef NETLINK_SOCK
28895 +# include <linux/netlink.h>
28896 +#else
28897 +# include <net/netlink.h>
28898 +#endif
28899 +
28900 +#include "openswan/radij.h"
28901 +
28902 +#include "openswan/ipsec_life.h"
28903 +#include "openswan/ipsec_stats.h"
28904 +#include "openswan/ipsec_sa.h"
28905 +
28906 +#include "openswan/ipsec_encap.h"
28907 +#include "openswan/ipsec_radij.h"
28908 +#include "openswan/ipsec_xform.h"
28909 +#include "openswan/ipsec_tunnel.h"
28910 +#include "openswan/ipsec_mast.h"
28911 +
28912 +#include "openswan/ipsec_rcv.h"
28913 +#include "openswan/ipsec_xmit.h"
28914 +#include "openswan/ipsec_ah.h"
28915 +#include "openswan/ipsec_esp.h"
28916 +
28917 +#ifdef CONFIG_KLIPS_IPCOMP
28918 +# include "openswan/ipcomp.h"
28919 +#endif /* CONFIG_KLIPS_IPCOMP */
28920 +
28921 +#include "openswan/ipsec_proto.h"
28922 +#include "openswan/ipsec_alg.h"
28923 +
28924 +#ifdef CONFIG_KLIPS_OCF
28925 +#include "ipsec_ocf.h"
28926 +#endif
28927 +
28928 +#include <openswan/pfkeyv2.h>
28929 +#include <openswan/pfkey.h>
28930 +
28931 +#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
28932 +#include <net/xfrmudp.h>
28933 +#endif
28934 +
28935 +#ifndef HAVE_UDP_ENCAP_CONVERT
28936 +# if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(HAVE_XFRM4_UDP_REGISTER)
28937 +# warning "You are trying to build KLIPS2.6 with NAT-T support, but you did not"
28938 +# error "properly apply the NAT-T patch to your 2.6 kernel source tree."
28939 +# endif
28940 +#endif
28941 +
28942 +#if !defined(CONFIG_KLIPS_ESP) && !defined(CONFIG_KLIPS_AH)
28943 +#error "kernel configuration must include ESP or AH"
28944 +#endif
28945 +
28946 +/*
28947 + * seems to be present in 2.4.10 (Linus), but also in some RH and other
28948 + * distro kernels of a lower number.
28949 + */
28950 +#ifdef MODULE_LICENSE
28951 +MODULE_LICENSE("GPL");
28952 +#endif
28953 +
28954 +struct prng ipsec_prng;
28955 +
28956 +#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
28957 +xfrm4_rcv_encap_t klips_old_encap = NULL;
28958 +#endif
28959 +
28960 +extern int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr);
28961 +/*
28962 + * the following structure is required so that we receive
28963 + * event notifications when network devices are enabled and
28964 + * disabled (ifconfig up and down).
28965 + */
28966 +static struct notifier_block ipsec_dev_notifier={
28967 + .notifier_call = ipsec_device_event
28968 +};
28969 +
28970 +#ifdef CONFIG_SYSCTL
28971 +extern int ipsec_sysctl_register(void);
28972 +extern void ipsec_sysctl_unregister(void);
28973 +#endif
28974 +
28975 +/*
28976 + * inet_*_protocol returns void on 2.4.x, int on 2.6.x
28977 + * So we need our own wrapper
28978 +*/
28979 +#ifdef NET_26
28980 +static inline int
28981 +openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol, char *protstr)
28982 +{
28983 + int err = inet_add_protocol(prot, protocol);
28984 + if (err)
28985 + printk(KERN_ERR "KLIPS: can not register %s protocol - recompile with CONFIG_INET_%s disabled or as module\n", protstr,protstr);
28986 + return err;
28987 +}
28988 +
28989 +static inline int
28990 +openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
28991 +{
28992 + return inet_del_protocol(prot, protocol);
28993 +}
28994 +
28995 +#else
28996 +static inline int
28997 +openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol)
28998 +{
28999 +#ifdef IPSKB_XFRM_TUNNEL_SIZE
29000 + inet_add_protocol(prot, protocol);
29001 +#else
29002 + inet_add_protocol(prot);
29003 +#endif
29004 + return 0;
29005 +}
29006 +
29007 +static inline int
29008 +openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
29009 +{
29010 +#ifdef IPSKB_XFRM_TUNNEL_SIZE
29011 + inet_del_protocol(prot, protocol);
29012 +#else
29013 + inet_del_protocol(prot);
29014 +#endif
29015 + return 0;
29016 +}
29017 +
29018 +#endif
29019 +
29020 +/* void */
29021 +int
29022 +ipsec_klips_init(void)
29023 +{
29024 + int error = 0;
29025 + unsigned char seed[256];
29026 +#ifdef CONFIG_KLIPS_ENC_3DES
29027 + extern int des_check_key;
29028 +
29029 + /* turn off checking of keys */
29030 + des_check_key=0;
29031 +#endif /* CONFIG_KLIPS_ENC_3DES */
29032 +
29033 + KLIPS_PRINT(1, "klips_info:ipsec_init: "
29034 + "KLIPS startup, Openswan KLIPS IPsec stack version: %s\n",
29035 + ipsec_version_code());
29036 +
29037 + error = ipsec_xmit_state_cache_init ();
29038 + if (error)
29039 + goto error_xmit_state_cache;
29040 +
29041 + error = ipsec_rcv_state_cache_init ();
29042 + if (error)
29043 + goto error_rcv_state_cache;
29044 +
29045 + error |= ipsec_proc_init();
29046 + if (error)
29047 + goto error_proc_init;
29048 +
29049 +#ifdef SPINLOCK
29050 + ipsec_sadb.sadb_lock = SPIN_LOCK_UNLOCKED;
29051 +#else /* SPINLOCK */
29052 + ipsec_sadb.sadb_lock = 0;
29053 +#endif /* SPINLOCK */
29054 +
29055 +#ifndef SPINLOCK
29056 + tdb_lock.lock = 0;
29057 + eroute_lock.lock = 0;
29058 +#endif /* !SPINLOCK */
29059 +
29060 + error |= ipsec_sadb_init();
29061 + if (error)
29062 + goto error_sadb_init;
29063 +
29064 + error |= ipsec_radijinit();
29065 + if (error)
29066 + goto error_radijinit;
29067 +
29068 + error |= pfkey_init();
29069 + if (error)
29070 + goto error_pfkey_init;
29071 +
29072 + error |= register_netdevice_notifier(&ipsec_dev_notifier);
29073 + if (error)
29074 + goto error_netdev_notifier;
29075 +
29076 +#ifdef CONFIG_XFRM_ALTERNATE_STACK
29077 + error = xfrm_register_alternate_rcv (ipsec_rcv);
29078 + if (error)
29079 + goto error_xfrm_register;
29080 +
29081 +#else // CONFIG_XFRM_ALTERNATE_STACK
29082 +
29083 +#ifdef CONFIG_KLIPS_ESP
29084 + error |= openswan_inet_add_protocol(&esp_protocol, IPPROTO_ESP,"ESP");
29085 + if (error)
29086 + goto error_openswan_inet_add_protocol_esp;
29087 +
29088 +#endif /* CONFIG_KLIPS_ESP */
29089 +
29090 +#ifdef CONFIG_KLIPS_AH
29091 + error |= openswan_inet_add_protocol(&ah_protocol, IPPROTO_AH,"AH");
29092 + if (error)
29093 + goto error_openswan_inet_add_protocol_ah;
29094 +#endif /* CONFIG_KLIPS_AH */
29095 +
29096 +/* we never actually link IPCOMP to the stack */
29097 +#ifdef IPCOMP_USED_ALONE
29098 +#ifdef CONFIG_KLIPS_IPCOMP
29099 + error |= openswan_inet_add_protocol(&comp_protocol, IPPROTO_COMP,"IPCOMP");
29100 + if (error)
29101 + goto error_openswan_inet_add_protocol_comp;
29102 +#endif /* CONFIG_KLIPS_IPCOMP */
29103 +#endif
29104 +
29105 +#endif // CONFIG_XFRM_ALTERNATE_STACK
29106 +
29107 + error |= ipsec_tunnel_init_devices();
29108 + if (error)
29109 + goto error_tunnel_init_devices;
29110 +
29111 + error |= ipsec_mast_init_devices();
29112 +
29113 +#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29114 + /* register our ESP-UDP handler */
29115 + if(udp4_register_esp_rcvencap(klips26_rcv_encap
29116 + , &klips_old_encap)!=0) {
29117 + printk(KERN_ERR "KLIPS: can not register klips_rcv_encap function\n");
29118 + }
29119 +#endif
29120 +
29121 +#ifdef CONFIG_SYSCTL
29122 + error |= ipsec_sysctl_register();
29123 + if (error)
29124 + goto error_sysctl_register;
29125 +#endif
29126 +
29127 +#ifdef CONFIG_KLIPS_ALG
29128 + ipsec_alg_init();
29129 +#endif
29130 +
29131 +#ifdef CONFIG_KLIPS_OCF
29132 + ipsec_ocf_init();
29133 +#endif
29134 +
29135 + get_random_bytes((void *)seed, sizeof(seed));
29136 + prng_init(&ipsec_prng, seed, sizeof(seed));
29137 + return error;
29138 +
29139 + // undo ipsec_sysctl_register
29140 +error_sysctl_register:
29141 + ipsec_tunnel_cleanup_devices();
29142 +error_tunnel_init_devices:
29143 +#ifdef CONFIG_XFRM_ALTERNATE_STACK
29144 + xfrm_deregister_alternate_rcv(ipsec_rcv);
29145 +error_xfrm_register:
29146 +#else // CONFIG_XFRM_ALTERNATE_STACK
29147 +#ifdef IPCOMP_USED_ALONE
29148 +#ifdef CONFIG_KLIPS_IPCOMP
29149 +error_openswan_inet_add_protocol_comp:
29150 + openswan_inet_del_protocol(&comp_protocol, IPPROTO_COMP);
29151 +#endif /* CONFIG_KLIPS_IPCOMP */
29152 +#endif
29153 +error_openswan_inet_add_protocol_ah:
29154 + openswan_inet_del_protocol(&ah_protocol, IPPROTO_AH);
29155 +error_openswan_inet_add_protocol_esp:
29156 + openswan_inet_del_protocol(&esp_protocol, IPPROTO_ESP);
29157 +#endif
29158 + unregister_netdevice_notifier(&ipsec_dev_notifier);
29159 +error_netdev_notifier:
29160 + pfkey_cleanup();
29161 +error_pfkey_init:
29162 + ipsec_radijcleanup();
29163 +error_radijinit:
29164 + ipsec_sadb_cleanup(0);
29165 + ipsec_sadb_free();
29166 +error_sadb_init:
29167 +error_proc_init:
29168 + // ipsec_proc_init() does not cleanup after itself, so we have to do it here
29169 + // TODO: ipsec_proc_init() should roll back what it chaned on failure
29170 + ipsec_proc_cleanup();
29171 + ipsec_rcv_state_cache_cleanup ();
29172 +error_rcv_state_cache:
29173 + ipsec_xmit_state_cache_cleanup ();
29174 +error_xmit_state_cache:
29175 + return error;
29176 +}
29177 +
29178 +
29179 +/* void */
29180 +int
29181 +ipsec_cleanup(void)
29182 +{
29183 + int error = 0;
29184 +
29185 +#ifdef CONFIG_SYSCTL
29186 + ipsec_sysctl_unregister();
29187 +#endif
29188 +#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29189 + if(udp4_unregister_esp_rcvencap(klips_old_encap) < 0) {
29190 + printk(KERN_ERR "KLIPS: can not unregister klips_rcv_encap function\n");
29191 + }
29192 +#endif
29193 +
29194 + KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29195 + "klips_debug:ipsec_cleanup: "
29196 + "calling ipsec_tunnel_cleanup_devices.\n");
29197 + error |= ipsec_tunnel_cleanup_devices();
29198 +
29199 + KLIPS_PRINT(debug_netlink, "called ipsec_tunnel_cleanup_devices");
29200 +
29201 +#ifdef CONFIG_XFRM_ALTERNATE_STACK
29202 +
29203 + xfrm_deregister_alternate_rcv(ipsec_rcv);
29204 +
29205 +#else // CONFIG_XFRM_ALTERNATE_STACK
29206 +
29207 +/* we never actually link IPCOMP to the stack */
29208 +#ifdef IPCOMP_USED_ALONE
29209 +#ifdef CONFIG_KLIPS_IPCOMP
29210 + if (openswan_inet_del_protocol(&comp_protocol, IPPROTO_COMP) < 0)
29211 + printk(KERN_INFO "klips_debug:ipsec_cleanup: "
29212 + "comp close: can't remove protocol\n");
29213 +#endif /* CONFIG_KLIPS_IPCOMP */
29214 +#endif /* IPCOMP_USED_ALONE */
29215 +
29216 +#ifdef CONFIG_KLIPS_AH
29217 + if (openswan_inet_del_protocol(&ah_protocol, IPPROTO_AH) < 0)
29218 + printk(KERN_INFO "klips_debug:ipsec_cleanup: "
29219 + "ah close: can't remove protocol\n");
29220 +#endif /* CONFIG_KLIPS_AH */
29221 +
29222 +#ifdef CONFIG_KLIPS_ESP
29223 + if (openswan_inet_del_protocol(&esp_protocol, IPPROTO_ESP) < 0)
29224 + printk(KERN_INFO "klips_debug:ipsec_cleanup: "
29225 + "esp close: can't remove protocol\n");
29226 +#endif /* CONFIG_KLIPS_ESP */
29227 +
29228 +#endif // CONFIG_XFRM_ALTERNATE_STACK
29229 +
29230 + error |= unregister_netdevice_notifier(&ipsec_dev_notifier);
29231 +
29232 + KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29233 + "klips_debug:ipsec_cleanup: "
29234 + "calling ipsec_sadb_cleanup.\n");
29235 + error |= ipsec_sadb_cleanup(0);
29236 + error |= ipsec_sadb_free();
29237 +
29238 + KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29239 + "klips_debug:ipsec_cleanup: "
29240 + "calling ipsec_radijcleanup.\n");
29241 + error |= ipsec_radijcleanup();
29242 +
29243 + KLIPS_PRINT(debug_pfkey, /* debug_tunnel & DB_TN_INIT, */
29244 + "klips_debug:ipsec_cleanup: "
29245 + "calling pfkey_cleanup.\n");
29246 + error |= pfkey_cleanup();
29247 +
29248 + ipsec_rcv_state_cache_cleanup ();
29249 + ipsec_xmit_state_cache_cleanup ();
29250 +
29251 + ipsec_proc_cleanup();
29252 +
29253 + prng_final(&ipsec_prng);
29254 +
29255 + return error;
29256 +}
29257 +
29258 +#ifdef MODULE
29259 +int
29260 +init_module(void)
29261 +{
29262 + int error = 0;
29263 +
29264 + error |= ipsec_klips_init();
29265 +
29266 + return error;
29267 +}
29268 +
29269 +#ifndef NET_26
29270 +void
29271 +cleanup_module(void)
29272 +{
29273 + KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29274 + "klips_debug:cleanup_module: "
29275 + "calling ipsec_cleanup.\n");
29276 +
29277 + ipsec_cleanup();
29278 +
29279 + KLIPS_PRINT(1, "klips_info:cleanup_module: "
29280 + "ipsec module unloaded.\n");
29281 +}
29282 +#endif
29283 +#endif /* MODULE */
29284 +
29285 +/*
29286 + *
29287 + * Local variables:
29288 + * c-file-style: "linux"
29289 + * End:
29290 + *
29291 + */
29292 --- /dev/null Tue Mar 11 13:02:56 2003
29293 +++ linux/net/ipsec/ipsec_ipcomp.c Mon Feb 9 13:51:03 2004
29294 @@ -0,0 +1,253 @@
29295 +/*
29296 + * processing code for IPCOMP
29297 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
29298 + *
29299 + * This program is free software; you can redistribute it and/or modify it
29300 + * under the terms of the GNU General Public License as published by the
29301 + * Free Software Foundation; either version 2 of the License, or (at your
29302 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29303 + *
29304 + * This program is distributed in the hope that it will be useful, but
29305 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29306 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29307 + * for more details.
29308 + */
29309 +
29310 +#ifndef AUTOCONF_INCLUDED
29311 +#include <linux/config.h>
29312 +#endif
29313 +#include <linux/version.h>
29314 +
29315 +#define __NO_VERSION__
29316 +#include <linux/module.h>
29317 +#include <linux/kernel.h> /* printk() */
29318 +
29319 +#include "openswan/ipsec_param.h"
29320 +
29321 +#ifdef MALLOC_SLAB
29322 +# include <linux/slab.h> /* kmalloc() */
29323 +#else /* MALLOC_SLAB */
29324 +# include <linux/malloc.h> /* kmalloc() */
29325 +#endif /* MALLOC_SLAB */
29326 +#include <linux/errno.h> /* error codes */
29327 +#include <linux/types.h> /* size_t */
29328 +#include <linux/interrupt.h> /* mark_bh */
29329 +
29330 +#include <linux/netdevice.h> /* struct device, and other headers */
29331 +#include <linux/etherdevice.h> /* eth_type_trans */
29332 +#include <linux/ip.h> /* struct iphdr */
29333 +#include <linux/skbuff.h>
29334 +#include <openswan.h>
29335 +#ifdef SPINLOCK
29336 +# ifdef SPINLOCK_23
29337 +# include <linux/spinlock.h> /* *lock* */
29338 +# else /* SPINLOCK_23 */
29339 +# include <asm/spinlock.h> /* *lock* */
29340 +# endif /* SPINLOCK_23 */
29341 +#endif /* SPINLOCK */
29342 +
29343 +#include <net/ip.h>
29344 +
29345 +#include "openswan/radij.h"
29346 +#include "openswan/ipsec_encap.h"
29347 +#include "openswan/ipsec_sa.h"
29348 +
29349 +#include "openswan/ipsec_radij.h"
29350 +#include "openswan/ipsec_xform.h"
29351 +#include "openswan/ipsec_tunnel.h"
29352 +#include "openswan/ipsec_rcv.h"
29353 +#include "openswan/ipsec_xmit.h"
29354 +
29355 +#include "openswan/ipsec_auth.h"
29356 +
29357 +#ifdef CONFIG_KLIPS_IPCOMP
29358 +#include "openswan/ipsec_ipcomp.h"
29359 +#endif /* CONFIG_KLIPS_IPCOMP */
29360 +
29361 +#include "openswan/ipsec_proto.h"
29362 +
29363 +#ifdef CONFIG_KLIPS_IPCOMP
29364 +enum ipsec_rcv_value
29365 +ipsec_rcv_ipcomp_checks(struct ipsec_rcv_state *irs,
29366 + struct sk_buff *skb)
29367 +{
29368 + int ipcompminlen;
29369 +
29370 + ipcompminlen = sizeof(struct iphdr);
29371 +
29372 + if(skb->len < (ipcompminlen + sizeof(struct ipcomphdr))) {
29373 + KLIPS_PRINT(debug_rcv & DB_RX_INAU,
29374 + "klips_debug:ipsec_rcv: "
29375 + "runt comp packet of skb->len=%d received from %s, dropped.\n",
29376 + skb->len,
29377 + irs->ipsaddr_txt);
29378 + if(irs->stats) {
29379 + irs->stats->rx_errors++;
29380 + }
29381 + return IPSEC_RCV_BADLEN;
29382 + }
29383 +
29384 + irs->protostuff.ipcompstuff.compp = (struct ipcomphdr *)skb_transport_header(skb);
29385 + irs->said.spi = htonl((__u32)ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi));
29386 + return IPSEC_RCV_OK;
29387 +}
29388 +
29389 +enum ipsec_rcv_value
29390 +ipsec_rcv_ipcomp_decomp(struct ipsec_rcv_state *irs)
29391 +{
29392 + unsigned int flags = 0;
29393 + struct ipsec_sa *ipsp = irs->ipsp;
29394 + struct sk_buff *skb;
29395 +
29396 + skb=irs->skb;
29397 +
29398 + ipsec_xmit_dmp("ipcomp", skb_transport_header(skb), skb->len);
29399 +
29400 + if(ipsp == NULL) {
29401 + return IPSEC_RCV_SAIDNOTFOUND;
29402 + }
29403 +
29404 + if(sysctl_ipsec_inbound_policy_check &&
29405 + ((((ntohl(ipsp->ips_said.spi) & 0x0000ffff) != (ntohl(irs->said.spi) & 0x0000ffff)) &&
29406 + (ipsp->ips_encalg != ntohl(irs->said.spi)) /* this is a workaround for peer non-compliance with rfc2393 */
29407 + ))) {
29408 + char sa2[SATOT_BUF];
29409 + size_t sa_len2 = 0;
29410 +
29411 + sa_len2 = KLIPS_SATOT(debug_rcv, &ipsp->ips_said, 0, sa2, sizeof(sa2));
29412 +
29413 + KLIPS_PRINT(debug_rcv,
29414 + "klips_debug:ipsec_rcv: "
29415 + "Incoming packet with SA(IPCA):%s does not match policy SA(IPCA):%s cpi=%04x cpi->spi=%08x spi=%08x, spi->cpi=%04x for SA grouping, dropped.\n",
29416 + irs->sa_len ? irs->sa : " (error)",
29417 + ipsp != NULL ? (sa_len2 ? sa2 : " (error)") : "NULL",
29418 + ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi),
29419 + (__u32)ntohl(irs->said.spi),
29420 + ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
29421 + ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0);
29422 + if(irs->stats) {
29423 + irs->stats->rx_dropped++;
29424 + }
29425 + return IPSEC_RCV_SAIDNOTFOUND;
29426 + }
29427 +
29428 + ipsp->ips_comp_ratio_cbytes += ntohs(irs->ipp->tot_len);
29429 + irs->next_header = irs->protostuff.ipcompstuff.compp->ipcomp_nh;
29430 +
29431 + skb = skb_decompress(skb, ipsp, &flags);
29432 + if (!skb || flags) {
29433 + KLIPS_PRINT(debug_rcv,
29434 + "klips_debug:ipsec_rcv: "
29435 + "skb_decompress() returned error flags=%x, dropped.\n",
29436 + flags);
29437 + if (irs->stats) {
29438 + if (flags)
29439 + irs->stats->rx_errors++;
29440 + else
29441 + irs->stats->rx_dropped++;
29442 + }
29443 + return IPSEC_RCV_IPCOMPFAILED;
29444 + }
29445 +
29446 + /* make sure we update the pointer */
29447 + irs->skb = skb;
29448 +
29449 +#ifdef NET_21
29450 + irs->ipp = ip_hdr(skb);
29451 +#else /* NET_21 */
29452 + irs->ipp = skb->ip_hdr;
29453 +#endif /* NET_21 */
29454 +
29455 + ipsp->ips_comp_ratio_dbytes += ntohs(irs->ipp->tot_len);
29456 +
29457 + KLIPS_PRINT(debug_rcv,
29458 + "klips_debug:ipsec_rcv: "
29459 + "packet decompressed SA(IPCA):%s cpi->spi=%08x spi=%08x, spi->cpi=%04x, nh=%d.\n",
29460 + irs->sa_len ? irs->sa : " (error)",
29461 + (__u32)ntohl(irs->said.spi),
29462 + ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
29463 + ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0,
29464 + irs->next_header);
29465 + KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, irs->ipp);
29466 +
29467 + return IPSEC_RCV_OK;
29468 +}
29469 +
29470 +enum ipsec_xmit_value
29471 +ipsec_xmit_ipcomp_setup(struct ipsec_xmit_state *ixs)
29472 +{
29473 + unsigned int flags = 0;
29474 +#ifdef CONFIG_KLIPS_DEBUG
29475 + unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
29476 +#endif /* CONFIG_KLIPS_DEBUG */
29477 +
29478 + ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
29479 +
29480 + ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
29481 +
29482 +#ifdef NET_21
29483 + ixs->iph = ip_hdr(ixs->skb);
29484 +#else /* NET_21 */
29485 + ixs->iph = ixs->skb->ip_hdr;
29486 +#endif /* NET_21 */
29487 +
29488 + ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
29489 +
29490 +#ifdef CONFIG_KLIPS_DEBUG
29491 + if (debug_tunnel & DB_TN_CROUT)
29492 + {
29493 + if (old_tot_len > ntohs(ixs->iph->tot_len))
29494 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
29495 + "klips_debug:ipsec_xmit_encap_once: "
29496 + "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
29497 + old_tot_len, ntohs(ixs->iph->tot_len),
29498 + ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
29499 + ntohl(ixs->ipsp->ips_said.spi),
29500 + (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
29501 + else
29502 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
29503 + "klips_debug:ipsec_xmit_encap_once: "
29504 + "packet did not compress (flags = %d).\n",
29505 + flags);
29506 + }
29507 +#endif /* CONFIG_KLIPS_DEBUG */
29508 +
29509 + return IPSEC_XMIT_OK;
29510 +}
29511 +
29512 +struct xform_functions ipcomp_xform_funcs[]={
29513 + {
29514 + protocol: IPPROTO_COMP,
29515 + rcv_checks: ipsec_rcv_ipcomp_checks,
29516 + rcv_decrypt: ipsec_rcv_ipcomp_decomp,
29517 + xmit_setup: ipsec_xmit_ipcomp_setup,
29518 + xmit_headroom: 0,
29519 + xmit_needtailroom: 0,
29520 + },
29521 +};
29522 +
29523 +#if 0
29524 +/* We probably don't want to install a pure IPCOMP protocol handler, but
29525 + only want to handle IPCOMP if it is encapsulated inside an ESP payload
29526 + (which is already handled) */
29527 +#ifndef CONFIG_XFRM_ALTERNATE_STACK
29528 +#ifdef CONFIG_KLIPS_IPCOMP
29529 +struct inet_protocol comp_protocol =
29530 +{
29531 + ipsec_rcv, /* COMP handler */
29532 + NULL, /* COMP error control */
29533 +#ifdef NETDEV_25
29534 + 1, /* no policy */
29535 +#else
29536 + 0, /* next */
29537 + IPPROTO_COMP, /* protocol ID */
29538 + 0, /* copy */
29539 + NULL, /* data */
29540 + "COMP" /* name */
29541 +#endif
29542 +};
29543 +#endif /* CONFIG_KLIPS_IPCOMP */
29544 +#endif /* CONFIG_XFRM_ALTERNATE_STACK */
29545 +#endif
29546 +
29547 +#endif /* CONFIG_KLIPS_IPCOMP */
29548 --- /dev/null Tue Mar 11 13:02:56 2003
29549 +++ linux/net/ipsec/ipsec_ipip.c Mon Feb 9 13:51:03 2004
29550 @@ -0,0 +1,123 @@
29551 +/*
29552 + * processing code for IPIP
29553 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
29554 + *
29555 + * This program is free software; you can redistribute it and/or modify it
29556 + * under the terms of the GNU General Public License as published by the
29557 + * Free Software Foundation; either version 2 of the License, or (at your
29558 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29559 + *
29560 + * This program is distributed in the hope that it will be useful, but
29561 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29562 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29563 + * for more details.
29564 + */
29565 +
29566 +#ifndef AUTOCONF_INCLUDED
29567 +#include <linux/config.h>
29568 +#endif
29569 +#include <linux/version.h>
29570 +
29571 +#define __NO_VERSION__
29572 +#include <linux/module.h>
29573 +#include <linux/kernel.h> /* printk() */
29574 +
29575 +#include "openswan/ipsec_param.h"
29576 +
29577 +#ifdef MALLOC_SLAB
29578 +# include <linux/slab.h> /* kmalloc() */
29579 +#else /* MALLOC_SLAB */
29580 +# include <linux/malloc.h> /* kmalloc() */
29581 +#endif /* MALLOC_SLAB */
29582 +#include <linux/errno.h> /* error codes */
29583 +#include <linux/types.h> /* size_t */
29584 +#include <linux/interrupt.h> /* mark_bh */
29585 +
29586 +#include <linux/netdevice.h> /* struct device, and other headers */
29587 +#include <linux/etherdevice.h> /* eth_type_trans */
29588 +#include <linux/ip.h> /* struct iphdr */
29589 +#include <linux/skbuff.h>
29590 +#include <openswan.h>
29591 +#ifdef SPINLOCK
29592 +# ifdef SPINLOCK_23
29593 +# include <linux/spinlock.h> /* *lock* */
29594 +# else /* SPINLOCK_23 */
29595 +# include <asm/spinlock.h> /* *lock* */
29596 +# endif /* SPINLOCK_23 */
29597 +#endif /* SPINLOCK */
29598 +
29599 +#include <net/ip.h>
29600 +
29601 +#include "openswan/radij.h"
29602 +#include "openswan/ipsec_encap.h"
29603 +#include "openswan/ipsec_sa.h"
29604 +
29605 +#include "openswan/ipsec_radij.h"
29606 +#include "openswan/ipsec_xform.h"
29607 +#include "openswan/ipsec_tunnel.h"
29608 +#include "openswan/ipsec_rcv.h"
29609 +#include "openswan/ipsec_xmit.h"
29610 +
29611 +#include "openswan/ipsec_auth.h"
29612 +#include "openswan/ipsec_ipip.h"
29613 +#include "openswan/ipsec_param.h"
29614 +
29615 +#include "openswan/ipsec_proto.h"
29616 +
29617 +enum ipsec_xmit_value
29618 +ipsec_xmit_ipip_setup(struct ipsec_xmit_state *ixs)
29619 +{
29620 + ixs->iph->version = 4;
29621 +
29622 + switch(sysctl_ipsec_tos) {
29623 + case 0:
29624 +#ifdef NET_21
29625 + ixs->iph->tos = ip_hdr(ixs->skb)->tos;
29626 +#else /* NET_21 */
29627 + ixs->iph->tos = ixs->skb->ip_hdr->tos;
29628 +#endif /* NET_21 */
29629 + break;
29630 + case 1:
29631 + ixs->iph->tos = 0;
29632 + break;
29633 + default:
29634 + break;
29635 + }
29636 + ixs->iph->ttl = SYSCTL_IPSEC_DEFAULT_TTL;
29637 + ixs->iph->frag_off = 0;
29638 + ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
29639 + ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
29640 + ixs->iph->protocol = IPPROTO_IPIP;
29641 + ixs->iph->ihl = sizeof(struct iphdr) >> 2;
29642 +
29643 + KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
29644 +
29645 + ixs->newdst = (__u32)ixs->iph->daddr;
29646 + ixs->newsrc = (__u32)ixs->iph->saddr;
29647 +
29648 +#ifdef NET_21
29649 + skb_set_transport_header(ixs->skb, ipsec_skb_offset(ixs->skb, ip_hdr(ixs->skb)));
29650 +#endif /* NET_21 */
29651 + return IPSEC_XMIT_OK;
29652 +}
29653 +
29654 +struct xform_functions ipip_xform_funcs[]={
29655 + {
29656 + protocol: IPPROTO_IPIP,
29657 + rcv_checks: NULL,
29658 + rcv_setup_auth: NULL,
29659 + rcv_calc_auth: NULL,
29660 + rcv_decrypt: NULL,
29661 +
29662 + xmit_setup: ipsec_xmit_ipip_setup,
29663 + xmit_headroom: sizeof(struct iphdr),
29664 + xmit_needtailroom: 0,
29665 + },
29666 +};
29667 +
29668 +
29669 +
29670 +
29671 +
29672 +
29673 +
29674 --- /dev/null Tue Mar 11 13:02:56 2003
29675 +++ linux/net/ipsec/ipsec_kern24.c Mon Feb 9 13:51:03 2004
29676 @@ -0,0 +1,74 @@
29677 +/*
29678 + * Copyright 2005 (C) Michael Richardson <mcr@xelerance.com>
29679 + *
29680 + * This is a file of functions which are present in 2.6 kernels,
29681 + * but are not available by default in the 2.4 series.
29682 + *
29683 + * As such this code is usually from the Linux kernel, and is covered by
29684 + * GPL.
29685 + *
29686 + * This program is free software; you can redistribute it and/or modify it
29687 + * under the terms of the GNU General Public License as published by the
29688 + * Free Software Foundation; either version 2 of the License, or (at your
29689 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29690 + *
29691 + * This program is distributed in the hope that it will be useful, but
29692 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29693 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29694 + * for more details.
29695 + *
29696 + * $Id: ipsec_kern24.c,v 1.2 2005/05/20 03:19:18 mcr Exp $
29697 + *
29698 + */
29699 +
29700 +#include <linux/kernel.h>
29701 +#include <linux/mm.h>
29702 +#include <linux/spinlock.h>
29703 +
29704 +/*
29705 + * printk rate limiting, lifted from the networking subsystem.
29706 + *
29707 + * This enforces a rate limit: not more than one kernel message
29708 + * every printk_ratelimit_jiffies to make a denial-of-service
29709 + * attack impossible.
29710 + */
29711 +static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
29712 +
29713 +int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
29714 +{
29715 + static unsigned long toks = 10*5*HZ;
29716 + static unsigned long last_msg;
29717 + static int missed;
29718 + unsigned long flags;
29719 + unsigned long now = jiffies;
29720 +
29721 + spin_lock_irqsave(&ratelimit_lock, flags);
29722 + toks += now - last_msg;
29723 + last_msg = now;
29724 + if (toks > (ratelimit_burst * ratelimit_jiffies))
29725 + toks = ratelimit_burst * ratelimit_jiffies;
29726 + if (toks >= ratelimit_jiffies) {
29727 + int lost = missed;
29728 + missed = 0;
29729 + toks -= ratelimit_jiffies;
29730 + spin_unlock_irqrestore(&ratelimit_lock, flags);
29731 + if (lost)
29732 + printk(KERN_WARNING "printk: %d messages suppressed.\n", lost);
29733 + return 1;
29734 + }
29735 + missed++;
29736 + spin_unlock_irqrestore(&ratelimit_lock, flags);
29737 + return 0;
29738 +}
29739 +
29740 +/* minimum time in jiffies between messages */
29741 +int printk_ratelimit_jiffies = 5*HZ;
29742 +
29743 +/* number of messages we send before ratelimiting */
29744 +int printk_ratelimit_burst = 10;
29745 +
29746 +int printk_ratelimit(void)
29747 +{
29748 + return __printk_ratelimit(printk_ratelimit_jiffies,
29749 + printk_ratelimit_burst);
29750 +}
29751 --- /dev/null Tue Mar 11 13:02:56 2003
29752 +++ linux/net/ipsec/ipsec_life.c Mon Feb 9 13:51:03 2004
29753 @@ -0,0 +1,221 @@
29754 +/*
29755 + * @(#) lifetime structure utilities
29756 + *
29757 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
29758 + * and Michael Richardson <mcr@freeswan.org>
29759 + *
29760 + * This program is free software; you can redistribute it and/or modify it
29761 + * under the terms of the GNU General Public License as published by the
29762 + * Free Software Foundation; either version 2 of the License, or (at your
29763 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29764 + *
29765 + * This program is distributed in the hope that it will be useful, but
29766 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29767 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29768 + * for more details.
29769 + *
29770 + *
29771 + */
29772 +
29773 +/*
29774 + * This provides series of utility functions for dealing with lifetime
29775 + * structures.
29776 + *
29777 + * ipsec_check_lifetime - returns -1 hard lifetime exceeded
29778 + * 0 soft lifetime exceeded
29779 + * 1 everything is okay
29780 + * based upon whether or not the count exceeds hard/soft
29781 + *
29782 + */
29783 +
29784 +#define __NO_VERSION__
29785 +#include <linux/module.h>
29786 +#ifndef AUTOCONF_INCLUDED
29787 +#include <linux/config.h>
29788 +#endif /* for CONFIG_IP_FORWARD */
29789 +#include <linux/version.h>
29790 +#include <linux/kernel.h> /* printk() */
29791 +
29792 +#include "openswan/ipsec_param.h"
29793 +
29794 +#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
29795 +#include <linux/etherdevice.h> /* eth_type_trans */
29796 +#include <linux/skbuff.h>
29797 +#include <linux/ip.h>
29798 +#include <openswan.h>
29799 +
29800 +#include "openswan/radij.h"
29801 +#include "openswan/ipsec_life.h"
29802 +#include "openswan/ipsec_xform.h"
29803 +#include "openswan/ipsec_eroute.h"
29804 +#include "openswan/ipsec_encap.h"
29805 +#include "openswan/ipsec_radij.h"
29806 +
29807 +#include "openswan/ipsec_sa.h"
29808 +#include "openswan/ipsec_tunnel.h"
29809 +#include "openswan/ipsec_ipe4.h"
29810 +#include "openswan/ipsec_ah.h"
29811 +#include "openswan/ipsec_esp.h"
29812 +
29813 +#ifdef CONFIG_KLIPS_IPCOMP
29814 +#include "openswan/ipcomp.h"
29815 +#endif /* CONFIG_KLIPS_IPCOMP */
29816 +
29817 +#include <openswan/pfkeyv2.h>
29818 +#include <openswan/pfkey.h>
29819 +
29820 +#include "openswan/ipsec_proto.h"
29821 +
29822 +
29823 +enum ipsec_life_alive
29824 +ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
29825 + const char *lifename,
29826 + const char *saname,
29827 + enum ipsec_life_type ilt,
29828 + enum ipsec_direction idir,
29829 + struct ipsec_sa *ips)
29830 +{
29831 + __u64 count;
29832 + const char *dir;
29833 +
29834 + if(saname == NULL) {
29835 + saname = "unknown-SA";
29836 + }
29837 +
29838 + if(idir == ipsec_incoming) {
29839 + dir = "incoming";
29840 + } else {
29841 + dir = "outgoing";
29842 + }
29843 +
29844 +
29845 + if(ilt == ipsec_life_timebased) {
29846 + count = jiffies/HZ - il64->ipl_count;
29847 + } else {
29848 + count = il64->ipl_count;
29849 + }
29850 +
29851 + if(il64->ipl_hard &&
29852 + (count > il64->ipl_hard)) {
29853 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
29854 + "klips_debug:ipsec_lifetime_check: "
29855 + "hard %s lifetime of SA:<%s%s%s> %s has been reached, SA expired, "
29856 + "%s packet dropped.\n",
29857 + lifename,
29858 + IPS_XFORM_NAME(ips),
29859 + saname,
29860 + dir);
29861 +
29862 + pfkey_expire(ips, 1);
29863 + return ipsec_life_harddied;
29864 + }
29865 +
29866 + if(il64->ipl_soft &&
29867 + (count > il64->ipl_soft)) {
29868 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
29869 + "klips_debug:ipsec_lifetime_check: "
29870 + "soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, "
29871 + "soft expire message sent up, %s packet still processed.\n",
29872 + lifename,
29873 + IPS_XFORM_NAME(ips),
29874 + saname,
29875 + dir);
29876 +
29877 + if(ips->ips_state != K_SADB_SASTATE_DYING) {
29878 + pfkey_expire(ips, 0);
29879 + }
29880 + ips->ips_state = K_SADB_SASTATE_DYING;
29881 +
29882 + return ipsec_life_softdied;
29883 + }
29884 + return ipsec_life_okay;
29885 +}
29886 +
29887 +
29888 +/*
29889 + * This function takes a buffer (with length), a lifetime name and type,
29890 + * and formats a string to represent the current values of the lifetime.
29891 + *
29892 + * It returns the number of bytes that the format took (or would take,
29893 + * if the buffer were large enough: snprintf semantics).
29894 + * This is used in /proc routines and in debug output.
29895 + */
29896 +int
29897 +ipsec_lifetime_format(char *buffer,
29898 + int buflen,
29899 + char *lifename,
29900 + enum ipsec_life_type timebaselife,
29901 + struct ipsec_lifetime64 *lifetime)
29902 +{
29903 + int len = 0;
29904 + __u64 count;
29905 +
29906 + if(timebaselife == ipsec_life_timebased) {
29907 + count = jiffies/HZ - lifetime->ipl_count;
29908 + } else {
29909 + count = lifetime->ipl_count;
29910 + }
29911 +
29912 + if(lifetime->ipl_count > 1 ||
29913 + lifetime->ipl_soft ||
29914 + lifetime->ipl_hard) {
29915 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
29916 + len = ipsec_snprintf(buffer, buflen,
29917 + "%s(%Lu,%Lu,%Lu)",
29918 + lifename,
29919 + count,
29920 + lifetime->ipl_soft,
29921 + lifetime->ipl_hard);
29922 +#else /* XXX high 32 bits are not displayed */
29923 + len = ipsec_snprintf(buffer, buflen,
29924 + "%s(%lu,%lu,%lu)",
29925 + lifename,
29926 + (unsigned long)count,
29927 + (unsigned long)lifetime->ipl_soft,
29928 + (unsigned long)lifetime->ipl_hard);
29929 +#endif
29930 + }
29931 +
29932 + return len;
29933 +}
29934 +
29935 +void
29936 +ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
29937 + __u64 newvalue)
29938 +{
29939 + if(newvalue &&
29940 + (!lifetime->ipl_hard ||
29941 + (newvalue < lifetime->ipl_hard))) {
29942 + lifetime->ipl_hard = newvalue;
29943 +
29944 + if(!lifetime->ipl_soft &&
29945 + (lifetime->ipl_hard < lifetime->ipl_soft)) {
29946 + lifetime->ipl_soft = lifetime->ipl_hard;
29947 + }
29948 + }
29949 +}
29950 +
29951 +void
29952 +ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
29953 + __u64 newvalue)
29954 +{
29955 + if(newvalue &&
29956 + (!lifetime->ipl_soft ||
29957 + (newvalue < lifetime->ipl_soft))) {
29958 + lifetime->ipl_soft = newvalue;
29959 +
29960 + if(lifetime->ipl_hard &&
29961 + (lifetime->ipl_hard < lifetime->ipl_soft)) {
29962 + lifetime->ipl_soft = lifetime->ipl_hard;
29963 + }
29964 + }
29965 +}
29966 +
29967 +
29968 +/*
29969 + *
29970 + * Local variables:
29971 + * c-file-style: "linux"
29972 + * End:
29973 + *
29974 + */
29975 --- /dev/null Tue Mar 11 13:02:56 2003
29976 +++ linux/net/ipsec/ipsec_mast.c Mon Feb 9 13:51:03 2004
29977 @@ -0,0 +1,869 @@
29978 +/*
29979 + * IPSEC MAST code.
29980 + * Copyright (C) 2005 Michael Richardson <mcr@xelerance.com>
29981 + *
29982 + * This program is free software; you can redistribute it and/or modify it
29983 + * under the terms of the GNU General Public License as published by the
29984 + * Free Software Foundation; either version 2 of the License, or (at your
29985 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29986 + *
29987 + * This program is distributed in the hope that it will be useful, but
29988 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29989 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29990 + * for more details.
29991 + */
29992 +
29993 +char ipsec_mast_c_version[] = "RCSID $Id: ipsec_mast.c,v 1.7 2005/04/29 05:10:22 mcr Exp $";
29994 +
29995 +#define __NO_VERSION__
29996 +#include <linux/module.h>
29997 +#ifndef AUTOCONF_INCLUDED
29998 +#include <linux/config.h>
29999 +#endif /* for CONFIG_IP_FORWARD */
30000 +#include <linux/version.h>
30001 +#include <linux/kernel.h> /* printk() */
30002 +
30003 +#include "openswan/ipsec_param.h"
30004 +
30005 +#ifdef MALLOC_SLAB
30006 +# include <linux/slab.h> /* kmalloc() */
30007 +#else /* MALLOC_SLAB */
30008 +# include <linux/malloc.h> /* kmalloc() */
30009 +#endif /* MALLOC_SLAB */
30010 +#include <linux/errno.h> /* error codes */
30011 +#include <linux/types.h> /* size_t */
30012 +#include <linux/interrupt.h> /* mark_bh */
30013 +
30014 +#include <net/arp.h>
30015 +#include <net/tcp.h>
30016 +#include <net/udp.h>
30017 +#include <linux/skbuff.h>
30018 +
30019 +#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
30020 +#include <linux/etherdevice.h> /* eth_type_trans */
30021 +#include <linux/ip.h> /* struct iphdr */
30022 +#include <linux/skbuff.h>
30023 +#include <net/xfrm.h>
30024 +
30025 +#include <openswan.h>
30026 +
30027 +#include <net/icmp.h> /* icmp_send() */
30028 +#include <net/ip.h>
30029 +#ifdef NETDEV_23
30030 +# include <linux/netfilter_ipv4.h>
30031 +#endif /* NETDEV_23 */
30032 +
30033 +#include <linux/if_arp.h>
30034 +
30035 +#include "openswan/ipsec_kversion.h"
30036 +#include "openswan/radij.h"
30037 +#include "openswan/ipsec_life.h"
30038 +#include "openswan/ipsec_xform.h"
30039 +#include "openswan/ipsec_eroute.h"
30040 +#include "openswan/ipsec_encap.h"
30041 +#include "openswan/ipsec_radij.h"
30042 +#include "openswan/ipsec_sa.h"
30043 +#include "openswan/ipsec_xmit.h"
30044 +#include "openswan/ipsec_mast.h"
30045 +#include "openswan/ipsec_tunnel.h"
30046 +#include "openswan/ipsec_ipe4.h"
30047 +#include "openswan/ipsec_ah.h"
30048 +#include "openswan/ipsec_esp.h"
30049 +#include "openswan/ipsec_kern24.h"
30050 +
30051 +#include <openswan/pfkeyv2.h>
30052 +#include <openswan/pfkey.h>
30053 +
30054 +#include "openswan/ipsec_proto.h"
30055 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
30056 +#include <linux/udp.h>
30057 +#endif
30058 +
30059 +int ipsec_mastdevice_count = -1;
30060 +int debug_mast;
30061 +
30062 +static __u32 zeroes[64];
30063 +
30064 +DEBUG_NO_STATIC int
30065 +ipsec_mast_open(struct net_device *dev)
30066 +{
30067 + struct mastpriv *prv = dev->priv;
30068 +
30069 + prv = prv;
30070 +
30071 + /*
30072 + * Can't open until attached.
30073 + */
30074 +
30075 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30076 + "klips_debug:ipsec_mast_open: "
30077 + "dev = %s\n",
30078 + dev->name);
30079 +
30080 + return 0;
30081 +}
30082 +
30083 +DEBUG_NO_STATIC int
30084 +ipsec_mast_close(struct net_device *dev)
30085 +{
30086 + return 0;
30087 +}
30088 +
30089 +static inline int ipsec_mast_xmit2(struct sk_buff *skb)
30090 +{
30091 + return dst_output(skb);
30092 +}
30093 +
30094 +#ifdef HAVE_IPSEC_SAREF
30095 +int ip_cmsg_send_ipsec(struct cmsghdr *cmsg, struct ipcm_cookie *ipc)
30096 +{
30097 + struct ipsec_sa *sa1;
30098 + xfrm_sec_unique_t *ref;
30099 + struct sec_path *sp;
30100 +
30101 + if(cmsg->cmsg_len != CMSG_LEN(sizeof(xfrm_sec_unique_t))) {
30102 + return -EINVAL;
30103 + }
30104 +
30105 + ref = (xfrm_sec_unique_t *)CMSG_DATA(cmsg);
30106 +
30107 + sp = secpath_dup(NULL);
30108 + if(!sp) {
30109 + return -EINVAL;
30110 + }
30111 +
30112 + sp->ref = *ref;
30113 + KLIPS_PRINT(debug_mast, "sending with saref=%u\n", sp->ref);
30114 +
30115 + sa1 = ipsec_sa_getbyref(sp->ref);
30116 + if(sa1 && sa1->ips_out) {
30117 + ipc->oif = sa1->ips_out->ifindex;
30118 + KLIPS_PRINT(debug_mast, "setting oif: %d\n", ipc->oif);
30119 + }
30120 + ipsec_sa_put(sa1);
30121 +
30122 + ipc->sp = sp;
30123 +
30124 + return 0;
30125 +}
30126 +#endif
30127 +
30128 +#if 0
30129 +/* Paul: This seems to be unused dead code */
30130 +enum ipsec_xmit_value
30131 +ipsec_mast_send(struct ipsec_xmit_state*ixs)
30132 +{
30133 + /* new route/dst cache code from James Morris */
30134 + ixs->skb->dev = ixs->physdev;
30135 + /*skb_orphan(ixs->skb);*/
30136 + if((ixs->error = ip_route_output(&ixs->route,
30137 + ixs->skb->nh.iph->daddr,
30138 + ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
30139 + RT_TOS(ixs->skb->nh.iph->tos),
30140 + ixs->physdev->ifindex /* rgb: should this be 0? */))) {
30141 + ixs->stats->tx_errors++;
30142 + KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30143 + "klips_debug:ipsec_xmit_send: "
30144 + "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
30145 + ixs->error,
30146 + ixs->route->u.dst.dev->name);
30147 + return IPSEC_XMIT_ROUTEERR;
30148 + }
30149 + if(ixs->dev == ixs->route->u.dst.dev) {
30150 + ip_rt_put(ixs->route);
30151 + /* This is recursion, drop it. */
30152 + ixs->stats->tx_errors++;
30153 + KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30154 + "klips_debug:ipsec_xmit_send: "
30155 + "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
30156 + ixs->dev->name);
30157 + return IPSEC_XMIT_RECURSDETECT;
30158 + }
30159 + dst_release(ixs->skb->dst);
30160 + ixs->skb->dst = &ixs->route->u.dst;
30161 + ixs->stats->tx_bytes += ixs->skb->len;
30162 + if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
30163 + ixs->stats->tx_errors++;
30164 + printk(KERN_WARNING
30165 + "klips_error:ipsec_xmit_send: "
30166 + "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
30167 + (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
30168 + ixs->skb->len);
30169 + return IPSEC_XMIT_PUSHPULLERR;
30170 + }
30171 + __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
30172 +
30173 + ipsec_nf_reset(ixs->skb);
30174 +
30175 + KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30176 + "klips_debug:ipsec_xmit_send: "
30177 + "...done, calling ip_send() on device:%s\n",
30178 + ixs->skb->dev ? ixs->skb->dev->name : "NULL");
30179 + KLIPS_IP_PRINT(debug_mast & DB_MAST_XMIT, ixs->skb->nh.iph);
30180 + {
30181 + int err;
30182 +
30183 + err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
30184 + ipsec_mast_xmit2);
30185 + if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
30186 + if(net_ratelimit())
30187 + printk(KERN_ERR
30188 + "klips_error:ipsec_xmit_send: "
30189 + "ip_send() failed, err=%d\n",
30190 + -err);
30191 + ixs->stats->tx_errors++;
30192 + ixs->stats->tx_aborted_errors++;
30193 + ixs->skb = NULL;
30194 + return IPSEC_XMIT_IPSENDFAILURE;
30195 + }
30196 + }
30197 + ixs->stats->tx_packets++;
30198 + ixs->skb = NULL;
30199 +
30200 + return IPSEC_XMIT_OK;
30201 +}
30202 +#endif
30203 +
30204 +static void
30205 +ipsec_mast_xsm_complete(
30206 + struct ipsec_xmit_state *ixs,
30207 + enum ipsec_xmit_value stat)
30208 +{
30209 + if (stat != IPSEC_XMIT_OK) {
30210 + KLIPS_PRINT(debug_mast,
30211 + "klips_debug:ipsec_mast_xsm_complete: ipsec_xsm failed: %d\n",
30212 + stat);
30213 + goto cleanup;
30214 + }
30215 +
30216 + /* do any final NAT-encapsulation */
30217 + stat = ipsec_nat_encap(ixs);
30218 + if(stat != IPSEC_XMIT_OK) {
30219 + goto cleanup;
30220 + }
30221 +
30222 + /* now send the packet again */
30223 + {
30224 + struct flowi fl;
30225 +
30226 + memset(&fl, 0, sizeof(fl));
30227 + ipsec_xmit_send(ixs, &fl);
30228 + }
30229 +
30230 +cleanup:
30231 + ipsec_xmit_cleanup(ixs);
30232 +
30233 + if(ixs->ipsp) {
30234 + ipsec_sa_put(ixs->ipsp);
30235 + ixs->ipsp=NULL;
30236 + }
30237 + if(ixs->skb) {
30238 + ipsec_kfree_skb(ixs->skb);
30239 + ixs->skb=NULL;
30240 + }
30241 + ipsec_xmit_state_delete(ixs);
30242 +}
30243 +
30244 +/*
30245 + * This function assumes it is being called from dev_queue_xmit()
30246 + * and that skb is filled properly by that function.
30247 + */
30248 +int
30249 +ipsec_mast_start_xmit(struct sk_buff *skb, struct net_device *dev)
30250 +{
30251 + struct ipsec_xmit_state *ixs;
30252 + IPsecSAref_t SAref;
30253 +
30254 + if(skb == NULL) {
30255 + printk("mast start_xmit passed NULL\n");
30256 + return 0;
30257 + }
30258 +
30259 + ixs = ipsec_xmit_state_new();
30260 + if(ixs == NULL) {
30261 + printk("mast failed to allocate IXS\n");
30262 + return 0;
30263 + }
30264 +
30265 + ixs->skb = skb;
30266 + SAref = 0;
30267 + if(skb->nfmark & 0x80000000) {
30268 + SAref = NFmark2IPsecSAref(skb->nfmark);
30269 + KLIPS_PRINT(debug_mast, "getting SAref=%d from nfmark\n",
30270 + SAref);
30271 + }
30272 +
30273 +#ifdef HAVE_IPSEC_SAREF
30274 + if(skb->sp && skb->sp->ref != IPSEC_SAREF_NULL) {
30275 + SAref = skb->sp->ref;
30276 + KLIPS_PRINT(debug_mast, "getting SAref=%d from sec_path\n",
30277 + SAref);
30278 + }
30279 +#endif
30280 + KLIPS_PRINT(debug_mast, "skb=%p\n", skb);
30281 +
30282 + ipsec_xmit_sanity_check_skb(ixs);
30283 +
30284 + ixs->ipsp = ipsec_sa_getbyref(SAref);
30285 + if(ixs->ipsp == NULL) {
30286 + KLIPS_ERROR(debug_mast, "%s: no SA for saref=%d (sp=%p)\n",
30287 + dev->name, SAref, skb->sp);
30288 + ipsec_kfree_skb(skb);
30289 + return 0;
30290 + }
30291 +
30292 + /*
30293 + * we should be calculating the MTU by looking up a route
30294 + * based upon the destination in the SA, and then cache
30295 + * it into the SA, but we don't do that right now.
30296 + */
30297 + ixs->cur_mtu = 1460;
30298 + ixs->physmtu = 1460;
30299 +
30300 + ixs->xsm_complete = ipsec_mast_xsm_complete;
30301 + ixs->state = IPSEC_XSM_INIT2; /* we start later in the process */
30302 +
30303 + ipsec_xsm(ixs);
30304 + return 0;
30305 +
30306 +}
30307 +
30308 +DEBUG_NO_STATIC struct net_device_stats *
30309 +ipsec_mast_get_stats(struct net_device *dev)
30310 +{
30311 + return &(((struct mastpriv *)(dev->priv))->mystats);
30312 +}
30313 +
30314 +#if 0
30315 +/*
30316 + * Revectored calls.
30317 + * For each of these calls, a field exists in our private structure.
30318 + */
30319 +DEBUG_NO_STATIC int
30320 +ipsec_mast_hard_header(struct sk_buff *skb, struct net_device *dev,
30321 + unsigned short type, void *daddr, void *saddr, unsigned len)
30322 +{
30323 + struct mastpriv *prv = dev->priv;
30324 + struct net_device_stats *stats; /* This device's statistics */
30325 + int ret = 0;
30326 +
30327 + if(skb == NULL) {
30328 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30329 + "klips_debug:ipsec_mast_hard_header: "
30330 + "no skb...\n");
30331 + return -ENODATA;
30332 + }
30333 +
30334 + if(dev == NULL) {
30335 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30336 + "klips_debug:ipsec_mast_hard_header: "
30337 + "no device...\n");
30338 + return -ENODEV;
30339 + }
30340 +
30341 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30342 + "klips_debug:ipsec_mast_hard_header: "
30343 + "skb->dev=%s\n",
30344 + dev->name);
30345 +
30346 + if(prv == NULL) {
30347 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30348 + "klips_debug:ipsec_mast_hard_header: "
30349 + "no private space associated with dev=%s\n",
30350 + dev->name ? dev->name : "NULL");
30351 + return -ENODEV;
30352 + }
30353 +
30354 + stats = (struct net_device_stats *) &(prv->mystats);
30355 +
30356 + /* check if we have to send a IPv6 packet. It might be a Router
30357 + Solicitation, where the building of the packet happens in
30358 + reverse order:
30359 + 1. ll hdr,
30360 + 2. IPv6 hdr,
30361 + 3. ICMPv6 hdr
30362 + -> skb->nh.raw is still uninitialized when this function is
30363 + called!! If this is no IPv6 packet, we can print debugging
30364 + messages, otherwise we skip all debugging messages and just
30365 + build the ll header */
30366 + if(type != ETH_P_IPV6) {
30367 + /* execute this only, if we don't have to build the
30368 + header for a IPv6 packet */
30369 + if(!prv->hard_header) {
30370 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30371 + "klips_debug:ipsec_mast_hard_header: "
30372 + "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
30373 + saddr,
30374 + daddr,
30375 + len,
30376 + type,
30377 + dev->name);
30378 + KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
30379 + "ip=%08x->%08x\n",
30380 + (__u32)ntohl(skb->nh.iph->saddr),
30381 + (__u32)ntohl(skb->nh.iph->daddr) );
30382 + stats->tx_dropped++;
30383 + return -ENODEV;
30384 + }
30385 + } else {
30386 + KLIPS_PRINT(debug_mast,
30387 + "klips_debug:ipsec_mast_hard_header: "
30388 + "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
30389 + }
30390 +
30391 + return ret;
30392 +}
30393 +
30394 +DEBUG_NO_STATIC int
30395 +ipsec_mast_rebuild_header(struct sk_buff *skb)
30396 +{
30397 + struct mastpriv *prv = skb->dev->priv;
30398 +
30399 + prv = prv;
30400 + return 0;
30401 +}
30402 +
30403 +DEBUG_NO_STATIC int
30404 +ipsec_mast_set_mac_address(struct net_device *dev, void *addr)
30405 +{
30406 + struct mastpriv *prv = dev->priv;
30407 +
30408 + prv = prv;
30409 + return 0;
30410 +
30411 +}
30412 +
30413 +DEBUG_NO_STATIC void
30414 +ipsec_mast_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
30415 +{
30416 + struct mastpriv *prv = dev->priv;
30417 +
30418 + if(dev == NULL) {
30419 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30420 + "klips_debug:ipsec_mast_cache_update: "
30421 + "no device...");
30422 + return;
30423 + }
30424 +
30425 + if(prv == NULL) {
30426 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30427 + "klips_debug:ipsec_mast_cache_update: "
30428 + "no private space associated with dev=%s",
30429 + dev->name ? dev->name : "NULL");
30430 + return;
30431 + }
30432 +
30433 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30434 + "klips_debug:ipsec_mast: "
30435 + "Revectored cache_update\n");
30436 + return;
30437 +}
30438 +#endif
30439 +
30440 +DEBUG_NO_STATIC int
30441 +ipsec_mast_neigh_setup(struct neighbour *n)
30442 +{
30443 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30444 + "klips_debug:ipsec_mast_neigh_setup:\n");
30445 +
30446 + if (n->nud_state == NUD_NONE) {
30447 + n->ops = &arp_broken_ops;
30448 + n->output = n->ops->output;
30449 + }
30450 + return 0;
30451 +}
30452 +
30453 +DEBUG_NO_STATIC int
30454 +ipsec_mast_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
30455 +{
30456 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30457 + "klips_debug:ipsec_mast_neigh_setup_dev: "
30458 + "setting up %s\n",
30459 + dev ? dev->name : "NULL");
30460 +
30461 + if (p->tbl->family == AF_INET) {
30462 + p->neigh_setup = ipsec_mast_neigh_setup;
30463 + p->ucast_probes = 0;
30464 + p->mcast_probes = 0;
30465 + }
30466 + return 0;
30467 +}
30468 +
30469 +DEBUG_NO_STATIC int
30470 +ipsec_mast_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
30471 +{
30472 + struct ipsecmastconf *cf = (struct ipsecmastconf *)&ifr->ifr_data;
30473 + struct ipsecpriv *prv = dev->priv;
30474 +
30475 + cf = cf;
30476 + prv=prv;
30477 +
30478 + if(dev == NULL) {
30479 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30480 + "klips_debug:ipsec_mast_ioctl: "
30481 + "device not supplied.\n");
30482 + return -ENODEV;
30483 + }
30484 +
30485 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30486 + "klips_debug:ipsec_mast_ioctl: "
30487 + "tncfg service call #%d for dev=%s\n",
30488 + cmd,
30489 + dev->name ? dev->name : "NULL");
30490 +
30491 + switch (cmd) {
30492 + default:
30493 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30494 + "klips_debug:ipsec_mast_ioctl: "
30495 + "unknown command %d.\n",
30496 + cmd);
30497 + return -EOPNOTSUPP;
30498 +
30499 + }
30500 +}
30501 +
30502 +int
30503 +ipsec_mast_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
30504 +{
30505 + struct net_device *dev = ptr;
30506 + struct mastpriv *priv = dev->priv;
30507 +
30508 + priv = priv;
30509 +
30510 + if (dev == NULL) {
30511 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30512 + "klips_debug:ipsec_mast_device_event: "
30513 + "dev=NULL for event type %ld.\n",
30514 + event);
30515 + return(NOTIFY_DONE);
30516 + }
30517 +
30518 + /* check for loopback devices */
30519 + if (dev && (dev->flags & IFF_LOOPBACK)) {
30520 + return(NOTIFY_DONE);
30521 + }
30522 +
30523 + switch (event) {
30524 + case NETDEV_DOWN:
30525 + /* look very carefully at the scope of these compiler
30526 + directives before changing anything... -- RGB */
30527 +
30528 + case NETDEV_UNREGISTER:
30529 + switch (event) {
30530 + case NETDEV_DOWN:
30531 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30532 + "klips_debug:ipsec_mast_device_event: "
30533 + "NETDEV_DOWN dev=%s flags=%x\n",
30534 + dev->name,
30535 + dev->flags);
30536 + if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
30537 + printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
30538 + dev->name);
30539 + }
30540 + break;
30541 + case NETDEV_UNREGISTER:
30542 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30543 + "klips_debug:ipsec_mast_device_event: "
30544 + "NETDEV_UNREGISTER dev=%s flags=%x\n",
30545 + dev->name,
30546 + dev->flags);
30547 + break;
30548 + }
30549 + break;
30550 +
30551 + case NETDEV_UP:
30552 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30553 + "klips_debug:ipsec_mast_device_event: "
30554 + "NETDEV_UP dev=%s\n",
30555 + dev->name);
30556 + break;
30557 +
30558 + case NETDEV_REBOOT:
30559 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30560 + "klips_debug:ipsec_mast_device_event: "
30561 + "NETDEV_REBOOT dev=%s\n",
30562 + dev->name);
30563 + break;
30564 +
30565 + case NETDEV_CHANGE:
30566 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30567 + "klips_debug:ipsec_mast_device_event: "
30568 + "NETDEV_CHANGE dev=%s flags=%x\n",
30569 + dev->name,
30570 + dev->flags);
30571 + break;
30572 +
30573 + case NETDEV_REGISTER:
30574 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30575 + "klips_debug:ipsec_mast_device_event: "
30576 + "NETDEV_REGISTER dev=%s\n",
30577 + dev->name);
30578 + break;
30579 +
30580 + case NETDEV_CHANGEMTU:
30581 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30582 + "klips_debug:ipsec_mast_device_event: "
30583 + "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
30584 + dev->name,
30585 + dev->mtu);
30586 + break;
30587 +
30588 + case NETDEV_CHANGEADDR:
30589 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30590 + "klips_debug:ipsec_mast_device_event: "
30591 + "NETDEV_CHANGEADDR dev=%s\n",
30592 + dev->name);
30593 + break;
30594 +
30595 + case NETDEV_GOING_DOWN:
30596 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30597 + "klips_debug:ipsec_mast_device_event: "
30598 + "NETDEV_GOING_DOWN dev=%s\n",
30599 + dev->name);
30600 + break;
30601 +
30602 + case NETDEV_CHANGENAME:
30603 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30604 + "klips_debug:ipsec_mast_device_event: "
30605 + "NETDEV_CHANGENAME dev=%s\n",
30606 + dev->name);
30607 + break;
30608 +
30609 + default:
30610 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30611 + "klips_debug:ipsec_mast_device_event: "
30612 + "event type %ld unrecognised for dev=%s\n",
30613 + event,
30614 + dev->name);
30615 + break;
30616 + }
30617 + return NOTIFY_DONE;
30618 +}
30619 +
30620 +/*
30621 + * Called when an ipsec mast device is initialized.
30622 + * The ipsec mast device structure is passed to us.
30623 + */
30624 +int
30625 +ipsec_mast_probe(struct net_device *dev)
30626 +{
30627 + int i;
30628 +
30629 + KLIPS_PRINT(debug_mast,
30630 + "klips_debug:ipsec_mast_init: "
30631 + "allocating %lu bytes initialising device: %s\n",
30632 + (unsigned long) sizeof(struct mastpriv),
30633 + dev->name ? dev->name : "NULL");
30634 +
30635 + /* Add our mast functions to the device */
30636 + dev->open = ipsec_mast_open;
30637 + dev->stop = ipsec_mast_close;
30638 + dev->hard_start_xmit = ipsec_mast_start_xmit;
30639 + dev->get_stats = ipsec_mast_get_stats;
30640 +
30641 + dev->priv = kmalloc(sizeof(struct mastpriv), GFP_KERNEL);
30642 + if (dev->priv == NULL)
30643 + return -ENOMEM;
30644 + memset((caddr_t)(dev->priv), 0, sizeof(struct mastpriv));
30645 +
30646 + for(i = 0; i < sizeof(zeroes); i++) {
30647 + ((__u8*)(zeroes))[i] = 0;
30648 + }
30649 +
30650 + dev->set_multicast_list = NULL;
30651 + dev->do_ioctl = ipsec_mast_ioctl;
30652 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
30653 + dev->header_ops = NULL;
30654 +#else
30655 + dev->hard_header = NULL;
30656 + dev->rebuild_header = NULL;
30657 + dev->header_cache_update= NULL;
30658 +#endif
30659 + dev->set_mac_address = NULL;
30660 + dev->neigh_setup = ipsec_mast_neigh_setup_dev;
30661 + dev->hard_header_len = 8+20+20+8;
30662 + dev->mtu = 0;
30663 + dev->addr_len = 0;
30664 + dev->type = ARPHRD_NONE;
30665 + dev->tx_queue_len = 10;
30666 + memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
30667 +
30668 + /* New-style flags. */
30669 + dev->flags = IFF_NOARP;
30670 +
30671 + /* We're done. Have I forgotten anything? */
30672 + return 0;
30673 +}
30674 +
30675 +#ifdef alloc_netdev
30676 +static void ipsec_mast_netdev_setup(struct net_device *dev)
30677 +{
30678 +}
30679 +#endif
30680 +struct net_device *mastdevices[IPSEC_NUM_IFMAX];
30681 +int mastdevices_max=-1;
30682 +
30683 +int ipsec_mast_createnum(int vifnum)
30684 +{
30685 + struct net_device *im;
30686 + int vifentry;
30687 + char name[IFNAMSIZ];
30688 +
30689 + if(vifnum > IPSEC_NUM_IFMAX) {
30690 + return -ENOENT;
30691 + }
30692 +
30693 + if(mastdevices[vifnum]!=NULL) {
30694 + return -EEXIST;
30695 + }
30696 +
30697 + /* no identical device */
30698 + if(vifnum > mastdevices_max) {
30699 + mastdevices_max=vifnum;
30700 + }
30701 + vifentry = vifnum;
30702 +
30703 + snprintf(name, IFNAMSIZ, MAST_DEV_FORMAT, vifnum);
30704 +
30705 +#ifdef alloc_netdev
30706 + im = alloc_netdev(0, name, ipsec_mast_netdev_setup);
30707 +#else
30708 + im = (struct net_device *)kmalloc(sizeof(struct net_device),GFP_KERNEL);
30709 +#endif
30710 + if(im == NULL) {
30711 + printk(KERN_ERR "failed to allocate space for mast%d device\n", vifnum);
30712 + return -ENOMEM;
30713 + }
30714 +
30715 +#ifndef alloc_netdev
30716 + memset((caddr_t)im, 0, sizeof(struct net_device));
30717 + memcpy(im->name, name, IFNAMSIZ);
30718 +#endif
30719 +
30720 + im->init = ipsec_mast_probe;
30721 +
30722 + if(register_netdev(im) != 0) {
30723 + printk(KERN_ERR "ipsec_mast: failed to register %s\n",
30724 + im->name);
30725 + return -EIO;
30726 + }
30727 +
30728 + dev_hold(im);
30729 + mastdevices[vifentry]=im;
30730 +
30731 + return 0;
30732 +}
30733 +
30734 +
30735 +int
30736 +ipsec_mast_deletenum(int vifnum)
30737 +{
30738 + struct net_device *dev_ipsec;
30739 +
30740 + if(vifnum > IPSEC_NUM_IFMAX) {
30741 + return -ENOENT;
30742 + }
30743 +
30744 + dev_ipsec = mastdevices[vifnum];
30745 + if(dev_ipsec == NULL) {
30746 + return -ENOENT;
30747 + }
30748 +
30749 + /* release reference */
30750 + mastdevices[vifnum]=NULL;
30751 + ipsec_dev_put(dev_ipsec);
30752 +
30753 + KLIPS_PRINT(debug_tunnel, "Unregistering %s (refcnt=%d)\n",
30754 + dev_ipsec->name,
30755 + atomic_read(&dev_ipsec->refcnt));
30756 + unregister_netdev(dev_ipsec);
30757 + KLIPS_PRINT(debug_tunnel, "Unregisted %s\n", dev_ipsec->name);
30758 +#ifndef NETDEV_23
30759 + kfree(dev_ipsec->name);
30760 + dev_ipsec->name=NULL;
30761 +#endif /* !NETDEV_23 */
30762 + kfree(dev_ipsec->priv);
30763 + dev_ipsec->priv=NULL;
30764 +
30765 + return 0;
30766 +}
30767 +
30768 +
30769 +struct net_device *
30770 +ipsec_mast_get_device(int vifnum)
30771 +{
30772 + int ovifnum = vifnum;
30773 +
30774 + if(vifnum > IPSECDEV_OFFSET) {
30775 + return ipsec_tunnel_get_device(vifnum-IPSECDEV_OFFSET);
30776 + } else {
30777 + struct net_device *nd;
30778 +
30779 + if(vifnum >= MASTTRANSPORT_OFFSET) {
30780 + vifnum -= MASTTRANSPORT_OFFSET;
30781 + }
30782 +
30783 + if(vifnum <= mastdevices_max) {
30784 + nd = mastdevices[vifnum];
30785 +
30786 + if(nd) dev_hold(nd);
30787 + return nd;
30788 + } else {
30789 + KLIPS_ERROR(debug_tunnel,
30790 + "no such vif %d (ovif=%d)\n", vifnum, ovifnum);
30791 + return NULL;
30792 + }
30793 + }
30794 +}
30795 +
30796 +unsigned int
30797 +ipsec_mast_is_transport(int vifnum)
30798 +{
30799 + if(vifnum > MASTTRANSPORT_OFFSET && vifnum <IPSECDEV_OFFSET) {
30800 + return 1;
30801 + }
30802 + return 0;
30803 +}
30804 +
30805 +int
30806 +ipsec_mast_init_devices(void)
30807 +{
30808 + /*
30809 + * mast0 is used for transport mode stuff, and generally is
30810 + * the default unless the user decides to create more.
30811 + */
30812 + ipsec_mast_createnum(0);
30813 +
30814 + return 0;
30815 +}
30816 +
30817 +/* void */
30818 +int
30819 +ipsec_mast_cleanup_devices(void)
30820 +{
30821 + int error = 0;
30822 + int i;
30823 + struct net_device *dev_mast;
30824 +
30825 + for(i = 0; i <= mastdevices_max; i++) {
30826 + if(mastdevices[i]!=NULL) {
30827 + dev_mast = mastdevices[i];
30828 + unregister_netdev(dev_mast);
30829 + kfree(dev_mast->priv);
30830 + dev_mast->priv=NULL;
30831 + dev_put(mastdevices[i]);
30832 + mastdevices[i]=NULL;
30833 + }
30834 + }
30835 + return error;
30836 +}
30837 +
30838 +/*
30839 + *
30840 + * Local Variables:
30841 + * c-file-style: "linux"
30842 + * End:
30843 + *
30844 + */
30845 +
30846 +
30847 --- /dev/null Tue Mar 11 13:02:56 2003
30848 +++ linux/net/ipsec/ipsec_md5c.c Mon Feb 9 13:51:03 2004
30849 @@ -0,0 +1,406 @@
30850 +/*
30851 + * RCSID $Id: ipsec_md5c.c,v 1.10 2005/04/15 01:25:57 mcr Exp $
30852 + */
30853 +
30854 +/*
30855 + * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic
30856 + * changes to accomodate it in the kernel by ji.
30857 + */
30858 +
30859 +#include <asm/byteorder.h>
30860 +#include <linux/string.h>
30861 +
30862 +#include "openswan/ipsec_md5h.h"
30863 +
30864 +/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
30865 + */
30866 +
30867 +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
30868 +rights reserved.
30869 +
30870 +License to copy and use this software is granted provided that it
30871 +is identified as the "RSA Data Security, Inc. MD5 Message-Digest
30872 +Algorithm" in all material mentioning or referencing this software
30873 +or this function.
30874 +
30875 +License is also granted to make and use derivative works provided
30876 +that such works are identified as "derived from the RSA Data
30877 +Security, Inc. MD5 Message-Digest Algorithm" in all material
30878 +mentioning or referencing the derived work.
30879 +
30880 +RSA Data Security, Inc. makes no representations concerning either
30881 +the merchantability of this software or the suitability of this
30882 +software for any particular purpose. It is provided "as is"
30883 +without express or implied warranty of any kind.
30884 +
30885 +These notices must be retained in any copies of any part of this
30886 +documentation and/or software.
30887 + */
30888 +
30889 +/*
30890 + * Additions by JI
30891 + *
30892 + * HAVEMEMCOPY is defined if mem* routines are available
30893 + *
30894 + * HAVEHTON is defined if htons() and htonl() can be used
30895 + * for big/little endian conversions
30896 + *
30897 + */
30898 +
30899 +#define HAVEMEMCOPY
30900 +#ifdef __LITTLE_ENDIAN
30901 +#define LITTLENDIAN
30902 +#endif
30903 +#ifdef __BIG_ENDIAN
30904 +#define BIGENDIAN
30905 +#endif
30906 +
30907 +/* Constants for MD5Transform routine.
30908 + */
30909 +
30910 +#define S11 7
30911 +#define S12 12
30912 +#define S13 17
30913 +#define S14 22
30914 +#define S21 5
30915 +#define S22 9
30916 +#define S23 14
30917 +#define S24 20
30918 +#define S31 4
30919 +#define S32 11
30920 +#define S33 16
30921 +#define S34 23
30922 +#define S41 6
30923 +#define S42 10
30924 +#define S43 15
30925 +#define S44 21
30926 +
30927 +static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
30928 +
30929 +#ifdef LITTLEENDIAN
30930 +#define Encode MD5_memcpy
30931 +#define Decode MD5_memcpy
30932 +#else
30933 +static void Encode PROTO_LIST
30934 + ((unsigned char *, UINT4 *, unsigned int));
30935 +static void Decode PROTO_LIST
30936 + ((UINT4 *, unsigned char *, unsigned int));
30937 +#endif
30938 +
30939 +#ifdef HAVEMEMCOPY
30940 +/* no need to include <memory.h> here; <linux/string.h> defines these */
30941 +#define MD5_memcpy memcpy
30942 +#define MD5_memset memset
30943 +#else
30944 +#ifdef HAVEBCOPY
30945 +#define MD5_memcpy(_a,_b,_c) bcopy((_b),(_a),(_c))
30946 +#define MD5_memset(_a,_b,_c) bzero((_a),(_c))
30947 +#else
30948 +static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
30949 +static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
30950 +#endif
30951 +#endif
30952 +static unsigned char PADDING[64] = {
30953 + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
30954 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
30955 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
30956 +};
30957 +
30958 +/* F, G, H and I are basic MD5 functions.
30959 + */
30960 +#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
30961 +#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
30962 +#define H(x, y, z) ((x) ^ (y) ^ (z))
30963 +#define I(x, y, z) ((y) ^ ((x) | (~z)))
30964 +
30965 +/* ROTATE_LEFT rotates x left n bits.
30966 + */
30967 +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
30968 +
30969 +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
30970 +Rotation is separate from addition to prevent recomputation.
30971 + */
30972 +#define FF(a, b, c, d, x, s, ac) { \
30973 + (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
30974 + (a) = ROTATE_LEFT ((a), (s)); \
30975 + (a) += (b); \
30976 + }
30977 +#define GG(a, b, c, d, x, s, ac) { \
30978 + (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
30979 + (a) = ROTATE_LEFT ((a), (s)); \
30980 + (a) += (b); \
30981 + }
30982 +#define HH(a, b, c, d, x, s, ac) { \
30983 + (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
30984 + (a) = ROTATE_LEFT ((a), (s)); \
30985 + (a) += (b); \
30986 + }
30987 +#define II(a, b, c, d, x, s, ac) { \
30988 + (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
30989 + (a) = ROTATE_LEFT ((a), (s)); \
30990 + (a) += (b); \
30991 + }
30992 +
30993 +/*
30994 + * MD5 initialization. Begins an MD5 operation, writing a new context.
30995 + */
30996 +void osMD5Init(void *vcontext)
30997 +{
30998 + MD5_CTX *context = vcontext;
30999 +
31000 + context->count[0] = context->count[1] = 0;
31001 + /* Load magic initialization constants.*/
31002 + context->state[0] = 0x67452301;
31003 + context->state[1] = 0xefcdab89;
31004 + context->state[2] = 0x98badcfe;
31005 + context->state[3] = 0x10325476;
31006 +}
31007 +
31008 +/* MD5 block update operation. Continues an MD5 message-digest
31009 + operation, processing another message block, and updating the
31010 + context.
31011 + */
31012 +void osMD5Update (vcontext, input, inputLen)
31013 + void *vcontext;
31014 + unsigned char *input; /* input block */
31015 + __u32 inputLen; /* length of input block */
31016 +{
31017 + MD5_CTX *context = vcontext;
31018 + __u32 i;
31019 + unsigned int index, partLen;
31020 +
31021 + /* Compute number of bytes mod 64 */
31022 + index = (unsigned int)((context->count[0] >> 3) & 0x3F);
31023 +
31024 + /* Update number of bits */
31025 + if ((context->count[0] += ((UINT4)inputLen << 3))
31026 + < ((UINT4)inputLen << 3))
31027 + context->count[1]++;
31028 + context->count[1] += ((UINT4)inputLen >> 29);
31029 +
31030 + partLen = 64 - index;
31031 +
31032 + /* Transform as many times as possible.
31033 +*/
31034 + if (inputLen >= partLen) {
31035 + MD5_memcpy
31036 + ((POINTER)&context->buffer[index], (POINTER)input, partLen);
31037 + MD5Transform (context->state, context->buffer);
31038 +
31039 + for (i = partLen; i + 63 < inputLen; i += 64)
31040 + MD5Transform (context->state, &input[i]);
31041 +
31042 + index = 0;
31043 + }
31044 + else
31045 + i = 0;
31046 +
31047 + /* Buffer remaining input */
31048 + MD5_memcpy
31049 + ((POINTER)&context->buffer[index], (POINTER)&input[i],
31050 + inputLen-i);
31051 +}
31052 +
31053 +/* MD5 finalization. Ends an MD5 message-digest operation, writing the
31054 + the message digest and zeroizing the context.
31055 + */
31056 +void osMD5Final (digest, vcontext)
31057 +unsigned char digest[16]; /* message digest */
31058 +void *vcontext; /* context */
31059 +{
31060 + MD5_CTX *context = vcontext;
31061 + unsigned char bits[8];
31062 + unsigned int index, padLen;
31063 +
31064 + /* Save number of bits */
31065 + Encode (bits, context->count, 8);
31066 +
31067 + /* Pad out to 56 mod 64.
31068 +*/
31069 + index = (unsigned int)((context->count[0] >> 3) & 0x3f);
31070 + padLen = (index < 56) ? (56 - index) : (120 - index);
31071 + osMD5Update (context, PADDING, padLen);
31072 +
31073 + /* Append length (before padding) */
31074 + osMD5Update (context, bits, 8);
31075 +
31076 + if (digest != NULL) /* Bill Simpson's padding */
31077 + {
31078 + /* store state in digest */
31079 + Encode (digest, context->state, 16);
31080 +
31081 + /* Zeroize sensitive information.
31082 + */
31083 + MD5_memset ((POINTER)context, 0, sizeof (*context));
31084 + }
31085 +}
31086 +
31087 +/* MD5 basic transformation. Transforms state based on block.
31088 + */
31089 +static void MD5Transform (state, block)
31090 +UINT4 state[4];
31091 +unsigned char block[64];
31092 +{
31093 + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
31094 +
31095 + Decode (x, block, 64);
31096 +
31097 + /* Round 1 */
31098 + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
31099 + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
31100 + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
31101 + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
31102 + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
31103 + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
31104 + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
31105 + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
31106 + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
31107 + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
31108 + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
31109 + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
31110 + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
31111 + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
31112 + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
31113 + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
31114 +
31115 + /* Round 2 */
31116 + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
31117 + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
31118 + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
31119 + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
31120 + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
31121 + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
31122 + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
31123 + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
31124 + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
31125 + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
31126 + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
31127 + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
31128 + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
31129 + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
31130 + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
31131 + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
31132 +
31133 + /* Round 3 */
31134 + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
31135 + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
31136 + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
31137 + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
31138 + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
31139 + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
31140 + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
31141 + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
31142 + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
31143 + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
31144 + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
31145 + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
31146 + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
31147 + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
31148 + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
31149 + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
31150 +
31151 + /* Round 4 */
31152 + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
31153 + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
31154 + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
31155 + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
31156 + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
31157 + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
31158 + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
31159 + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
31160 + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
31161 + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
31162 + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
31163 + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
31164 + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
31165 + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
31166 + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
31167 + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
31168 +
31169 + state[0] += a;
31170 + state[1] += b;
31171 + state[2] += c;
31172 + state[3] += d;
31173 +
31174 + /* Zeroize sensitive information.
31175 +*/
31176 + MD5_memset ((POINTER)x, 0, sizeof (x));
31177 +}
31178 +
31179 +#ifndef LITTLEENDIAN
31180 +
31181 +/* Encodes input (UINT4) into output (unsigned char). Assumes len is
31182 + a multiple of 4.
31183 + */
31184 +static void Encode (output, input, len)
31185 +unsigned char *output;
31186 +UINT4 *input;
31187 +unsigned int len;
31188 +{
31189 + unsigned int i, j;
31190 +
31191 + for (i = 0, j = 0; j < len; i++, j += 4) {
31192 + output[j] = (unsigned char)(input[i] & 0xff);
31193 + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
31194 + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
31195 + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
31196 + }
31197 +}
31198 +
31199 +/* Decodes input (unsigned char) into output (UINT4). Assumes len is
31200 + a multiple of 4.
31201 + */
31202 +static void Decode (output, input, len)
31203 +UINT4 *output;
31204 +unsigned char *input;
31205 +unsigned int len;
31206 +{
31207 + unsigned int i, j;
31208 +
31209 + for (i = 0, j = 0; j < len; i++, j += 4)
31210 + output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
31211 + (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
31212 +}
31213 +
31214 +#endif
31215 +
31216 +#ifndef HAVEMEMCOPY
31217 +#ifndef HAVEBCOPY
31218 +/* Note: Replace "for loop" with standard memcpy if possible.
31219 + */
31220 +
31221 +static void MD5_memcpy (output, input, len)
31222 +POINTER output;
31223 +POINTER input;
31224 +unsigned int len;
31225 +{
31226 + unsigned int i;
31227 +
31228 + for (i = 0; i < len; i++)
31229 +
31230 + output[i] = input[i];
31231 +}
31232 +
31233 +/* Note: Replace "for loop" with standard memset if possible.
31234 + */
31235 +
31236 +static void MD5_memset (output, value, len)
31237 +POINTER output;
31238 +int value;
31239 +unsigned int len;
31240 +{
31241 + unsigned int i;
31242 +
31243 + for (i = 0; i < len; i++)
31244 + ((char *)output)[i] = (char)value;
31245 +}
31246 +#endif
31247 +#endif
31248 +
31249 +/*
31250 + *
31251 + * Local Variables:
31252 + * c-file-style: "linux"
31253 + * End:
31254 + *
31255 + */
31256 --- /dev/null Tue Mar 11 13:02:56 2003
31257 +++ linux/net/ipsec/ipsec_ocf.c Mon Feb 9 13:51:03 2004
31258 @@ -0,0 +1,739 @@
31259 +/*
31260 + * IPSEC OCF support
31261 + *
31262 + * This code written by David McCullough <dmccullough@cyberguard.com>
31263 + * Copyright (C) 2005 Intel Corporation. All Rights Reserved.
31264 + *
31265 + * This program is free software; you can redistribute it and/or modify it
31266 + * under the terms of the GNU General Public License as published by the
31267 + * Free Software Foundation; either version 2 of the License, or (at your
31268 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
31269 + *
31270 + * This program is distributed in the hope that it will be useful, but
31271 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
31272 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
31273 + * for more details.
31274 + */
31275 +
31276 +#ifndef AUTOCONF_INCLUDED
31277 +#include <linux/config.h>
31278 +#endif
31279 +#include <linux/version.h>
31280 +
31281 +#define __NO_VERSION__
31282 +#include <linux/module.h>
31283 +#include <linux/kernel.h> /* printk() */
31284 +
31285 +#include <linux/errno.h> /* error codes */
31286 +#include <linux/types.h> /* size_t */
31287 +
31288 +#include <linux/interrupt.h>
31289 +
31290 +#include <net/ip.h>
31291 +
31292 +#include <openswan.h>
31293 +#include "openswan/ipsec_sa.h"
31294 +#include "openswan/ipsec_rcv.h"
31295 +#include "openswan/ipsec_xmit.h"
31296 +#include "openswan/ipsec_tunnel.h"
31297 +#include "openswan/ipsec_xform.h"
31298 +#include "openswan/ipsec_auth.h"
31299 +#include "openswan/ipsec_esp.h"
31300 +#include "openswan/ipsec_ah.h"
31301 +
31302 +#include <openswan/pfkeyv2.h>
31303 +#include <openswan/pfkey.h>
31304 +
31305 +#include "ipsec_ocf.h"
31306 +
31307 +extern int debug_pfkey;
31308 +extern int debug_rcv;
31309 +
31310 +int ipsec_ocf_crid = (CRYPTOCAP_F_HARDWARE|CRYPTOCAP_F_SOFTWARE);
31311 +#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
31312 +/*
31313 + * allow users to force us to a particular OCF driver
31314 + */
31315 +char *ipsec_ocf_driver = NULL;
31316 +module_parm(ipsec_ocf_driver, charp, 0644);
31317 +MODULE_PARM_DESC(ipsec_ocf_driver,
31318 + "Driver name (ie., cryptosoft), hw, sw, both (default both)");
31319 +#endif
31320 +
31321 +/*
31322 + * Tuning parameters, the settings below appear best for
31323 + * the IXP
31324 + */
31325 +#define USE_BATCH 1 /* enable batch mode */
31326 +#define USE_CBIMM 1 /* enable immediate callbacks */
31327 +#define FORCE_QS 0 /* force use of queues for continuation of state machine */
31328 +#ifdef DECLARE_TASKLET
31329 +#define USE_TASKLET 1 /* use tasklet for continuation of state machine */
31330 +#else
31331 +#define USE_TASKLET 0 /* don't use tasklet for continuation of state machine */
31332 +#endif
31333 +/*
31334 + * Because some OCF operations are synchronous (ie., software encryption)
31335 + * we need to protect ourselves from distructive re-entry. All we do
31336 + * is track where we are at and either callback immediately or Q the
31337 + * callback to avoid conflicts. This allows us to deal with the fact that
31338 + * OCF doesn't tell us if our crypto operations will be async or sync.
31339 + */
31340 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
31341 +#define _INIT_WORK(wq, fn, arg) INIT_WORK(&(wq), (void (*)(struct work_struct *))(fn))
31342 +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
31343 +#define _INIT_WORK(wq, fn, arg) INIT_WORK(&(wq), (void (*)(struct work_queue *))(fn))
31344 +#else
31345 +#define _INIT_WORK(wq, fn, arg) INIT_WORK(&(wq), (void (*)(void *))(fn), (void *)(arg))
31346 +#endif
31347 +
31348 +#define PROCESS_LATER(wq, sm, arg) \
31349 + ({ \
31350 + _INIT_WORK(wq, sm, arg); \
31351 + schedule_work(&(wq)); \
31352 + })
31353 +
31354 +#define PROCESS_NOW(sm, arg) \
31355 + ({ \
31356 + (*sm)(arg); \
31357 + })
31358 +
31359 +#if USE_TASKLET == 1
31360 + #define PROCESS_NEXT(this, wqsm, sm) ({ \
31361 + tasklet_init(&this->tasklet, \
31362 + (void (*)(unsigned long)) sm, (unsigned long)this); \
31363 + tasklet_schedule(&this->tasklet); \
31364 + })
31365 +#elif FORCE_QS == 0
31366 + #define PROCESS_NEXT(this, wqsm, sm) \
31367 + if (in_interrupt()) { \
31368 + PROCESS_LATER(this->workq, wqsm, this); \
31369 + } else { \
31370 + PROCESS_NOW(sm, this); \
31371 + }
31372 +#else
31373 + #define PROCESS_NEXT(this, wqsm, sm) PROCESS_LATER(this->workq, wqsm, this)
31374 +#endif
31375 +
31376 +/*
31377 + * convert openswan values to OCF values
31378 + */
31379 +
31380 +static int
31381 +ipsec_ocf_authalg(int authalg)
31382 +{
31383 + switch (authalg) {
31384 + case AH_SHA: return CRYPTO_SHA1_HMAC;
31385 + case AH_MD5: return CRYPTO_MD5_HMAC;
31386 + }
31387 + return 0;
31388 +}
31389 +
31390 +
31391 +static int
31392 +ipsec_ocf_encalg(int encalg)
31393 +{
31394 + switch (encalg) {
31395 + case ESP_NULL: return CRYPTO_NULL_CBC;
31396 + case ESP_DES: return CRYPTO_DES_CBC;
31397 + case ESP_3DES: return CRYPTO_3DES_CBC;
31398 + case ESP_AES: return CRYPTO_AES_CBC;
31399 + case ESP_CAST: return CRYPTO_CAST_CBC;
31400 + case ESP_BLOWFISH: return CRYPTO_BLF_CBC;
31401 + }
31402 + return 0;
31403 +}
31404 +
31405 +/*
31406 + * if we can do the request ops, setup the sessions and return true
31407 + * otherwise return false with ipsp unchanged
31408 + */
31409 +
31410 +int
31411 +ipsec_ocf_sa_init(struct ipsec_sa *ipsp, int authalg, int encalg)
31412 +{
31413 + struct cryptoini crie, cria;
31414 + int error;
31415 +
31416 + KLIPS_PRINT(debug_pfkey, "klips_debug:ipsec_ocf_sa_init(a=0x%x,e=0x%x)\n",
31417 + authalg, encalg);
31418 +
31419 + if (authalg && ipsp->ips_key_bits_a == 0) {
31420 + KLIPS_PRINT(debug_pfkey,
31421 + "klips_debug:ipsec_ocf_sa_init(a=0x%x,e=0x%x) a-key-bits=0\n",
31422 + authalg, encalg);
31423 + /* pretend we are happy with this */
31424 + return 1;
31425 + }
31426 +
31427 + if (encalg && ipsp->ips_key_bits_e == 0) {
31428 + KLIPS_PRINT(debug_pfkey,
31429 + "klips_debug:ipsec_ocf_sa_init(a=0x%x,e=0x%x) e-key-bits=0\n",
31430 + authalg, encalg);
31431 + /* pretend we are happy with this */
31432 + return 1;
31433 + }
31434 +
31435 + memset(&crie, 0, sizeof(crie));
31436 + memset(&cria, 0, sizeof(cria));
31437 +
31438 + cria.cri_alg = ipsec_ocf_authalg(authalg);
31439 + cria.cri_klen = ipsp->ips_key_bits_a;
31440 + cria.cri_key = ipsp->ips_key_a;
31441 + cria.cri_mlen = 12;
31442 +
31443 + crie.cri_alg = ipsec_ocf_encalg(encalg);
31444 + crie.cri_klen = ipsp->ips_key_bits_e;
31445 + crie.cri_key = ipsp->ips_key_e;
31446 + switch (crie.cri_alg) {
31447 + case CRYPTO_AES_CBC:
31448 + ipsp->ips_iv_size = 16;
31449 + break;
31450 + case CRYPTO_DES_CBC:
31451 + case CRYPTO_3DES_CBC:
31452 + ipsp->ips_iv_size = 8;
31453 + break;
31454 + default:
31455 + ipsp->ips_iv_size = 0;
31456 + break;
31457 + }
31458 + ipsp->ips_iv_bits = ipsp->ips_iv_size * 8;
31459 + ipsp->ips_auth_bits = ipsp->ips_key_bits_a;
31460 +
31461 + if (authalg && encalg) {
31462 + crie.cri_next = &cria;
31463 + error = crypto_newsession(&ipsp->ocf_cryptoid, &crie, ipsec_ocf_crid);
31464 + } else if (encalg) {
31465 + error = crypto_newsession(&ipsp->ocf_cryptoid, &crie, ipsec_ocf_crid);
31466 + } else if (authalg) {
31467 + error = crypto_newsession(&ipsp->ocf_cryptoid, &cria, ipsec_ocf_crid);
31468 + } else {
31469 + KLIPS_PRINT(debug_pfkey, "klips_debug:ipsec_ocf_sa_init: "
31470 + "no authalg or encalg\n");
31471 + return 0;
31472 + }
31473 +
31474 + if (error) {
31475 + KLIPS_PRINT(debug_pfkey, "klips_debug:ipsec_ocf_sa_init: "
31476 + "crypto_newsession failed 0x%x\n", error);
31477 + return 0;
31478 + }
31479 +
31480 + /* make sure no ALG stuff bites us */
31481 + if (ipsp->ips_alg_enc)
31482 + printk("We received an ALG initted SA\n");
31483 + ipsp->ips_alg_enc = NULL;
31484 +
31485 + ipsp->ocf_in_use = 1;
31486 + return 1;
31487 +}
31488 +
31489 +
31490 +int
31491 +ipsec_ocf_sa_free(struct ipsec_sa *ipsp)
31492 +{
31493 + KLIPS_PRINT(debug_pfkey, "klips_debug:ipsec_ocf_sa_free()\n");
31494 + crypto_freesession(ipsp->ocf_cryptoid);
31495 + ipsp->ocf_cryptoid = -1;
31496 + ipsp->ocf_in_use = 0;
31497 + return 1;
31498 +}
31499 +
31500 +#if USE_TASKLET == 0
31501 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
31502 +static void
31503 +ipsec_rsm_wq(struct work_struct *work)
31504 +{
31505 + struct ipsec_rcv_state *irs = container_of(work, struct ipsec_rcv_state, workq);
31506 + ipsec_rsm(irs);
31507 +}
31508 +#else
31509 +#define ipsec_rsm_wq ipsec_rsm
31510 +#endif
31511 +#endif /* USE_TASKLET */
31512 +
31513 +static int
31514 +ipsec_ocf_rcv_cb(struct cryptop *crp)
31515 +{
31516 + struct ipsec_rcv_state *irs = (struct ipsec_rcv_state *)crp->crp_opaque;
31517 +
31518 + KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_ocf_rcv_cb\n");
31519 + if (irs == NULL) {
31520 + KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_ocf_rcv_cb: "
31521 + "NULL irs in callback\n");
31522 + return 0;
31523 + }
31524 +
31525 + /*
31526 + * we must update the state before returning to the state machine.
31527 + * if we have an error, terminate the processing by moving to the DONE
31528 + * state
31529 + */
31530 +
31531 + irs->state = IPSEC_RSM_DONE; /* assume it went badly */
31532 + if (crp->crp_etype) {
31533 + KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_ocf_rcv_cb: "
31534 + "error in processing 0x%x\n", crp->crp_etype);
31535 + } else {
31536 + if (!irs->ipsp->ips_encalg) {
31537 + /* AH post processing, put back fields we had to zero */
31538 + irs->ipp->ttl = irs->ttl;
31539 + irs->ipp->check = irs->check;
31540 + irs->ipp->frag_off = irs->frag_off;
31541 + irs->ipp->tos = irs->tos;
31542 + irs->state = IPSEC_RSM_AUTH_CHK;
31543 + /* pull up the IP header again after processing */
31544 + skb_pull(irs->skb, ((unsigned char *)irs->protostuff.ahstuff.ahp) -
31545 + ((unsigned char *)irs->ipp));
31546 + } else if (ipsec_rcv_esp_post_decrypt(irs) == IPSEC_RCV_OK) {
31547 + /* this one came up good, set next state */
31548 + irs->state = IPSEC_RSM_DECAP_CONT;
31549 + }
31550 + }
31551 +
31552 + crypto_freereq(crp);
31553 + crp = NULL;
31554 +
31555 + /* setup the rest of the processing now */
31556 + PROCESS_NEXT(irs, ipsec_rsm_wq, ipsec_rsm);
31557 + return 0;
31558 +}
31559 +
31560 +enum ipsec_rcv_value
31561 +ipsec_ocf_rcv(struct ipsec_rcv_state *irs)
31562 +{
31563 + struct cryptop *crp;
31564 + struct cryptodesc *crde, *crda = NULL;
31565 + struct ipsec_sa *ipsp;
31566 +
31567 + KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_ocf_rcv\n");
31568 +
31569 + ipsp = irs->ipsp;
31570 + if (!ipsp) {
31571 + KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_ocf_rcv: "
31572 + "no SA for rcv processing\n");
31573 + return IPSEC_RCV_SAIDNOTFOUND;
31574 + }
31575 +
31576 + if (!irs->skb) {
31577 + KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_ocf_rcv: no skb\n");
31578 + return IPSEC_RCV_SAIDNOTFOUND;
31579 + }
31580 +
31581 + crp = crypto_getreq((ipsp->ips_authalg && ipsp->ips_encalg) ? 2 : 1);
31582 + if (!crp) {
31583 + KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_ocf_rcv: "
31584 + "crypto_getreq returned NULL\n");
31585 + return IPSEC_RCV_REALLYBAD;
31586 + }
31587 +
31588 + if (ipsp->ips_authalg) {
31589 + crda = crp->crp_desc;
31590 + crde = crda->crd_next;
31591 + } else {
31592 + crde = crp->crp_desc;
31593 + crda = crde->crd_next;
31594 + }
31595 +
31596 + if (crda) {
31597 + /* Authentication descriptor */
31598 + crda->crd_alg = ipsec_ocf_authalg(ipsp->ips_authalg);
31599 + if (!crda->crd_alg) {
31600 + KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_ocf_rcv: "
31601 + "bad auth alg 0x%x\n", ipsp->ips_authalg);
31602 + crypto_freereq(crp);
31603 + return IPSEC_RCV_BADPROTO;
31604 + }
31605 +
31606 + if (!crde) { /* assuming AH processing */
31607 + /* push the IP header so we can authenticate it */
31608 + skb_push(irs->skb, ((unsigned char *)irs->protostuff.ahstuff.ahp) -
31609 + ((unsigned char *)irs->ipp));
31610 + }
31611 +
31612 + crda->crd_key = ipsp->ips_key_a;
31613 + crda->crd_klen = ipsp->ips_key_bits_a;
31614 + crda->crd_inject = irs->authenticator - irs->skb->data;
31615 + /* Copy the authenticator to check aganinst later */
31616 + memcpy(irs->hash, irs->authenticator, 12);
31617 +
31618 + if (!crde) { /* assume AH processing */
31619 + /* AH processing, save fields we have to zero */
31620 + irs->ttl = irs->ipp->ttl;
31621 + irs->check = irs->ipp->check;
31622 + irs->frag_off = irs->ipp->frag_off;
31623 + irs->tos = irs->ipp->tos;
31624 + irs->ipp->ttl = 0;
31625 + irs->ipp->check = 0;
31626 + irs->ipp->frag_off = 0;
31627 + irs->ipp->tos = 0;
31628 + crda->crd_len = irs->skb->len;
31629 + crda->crd_skip = ((unsigned char *)irs->ipp) - irs->skb->data;
31630 + memset(irs->authenticator, 0, 12);
31631 + } else {
31632 + crda->crd_len = irs->ilen;
31633 + crda->crd_skip =
31634 + ((unsigned char *) irs->protostuff.espstuff.espp) -
31635 + irs->skb->data;
31636 + /*
31637 + * It would be nice to clear the authenticator here
31638 + * to be sure we do not see it again later when checking.
31639 + * We cannot. Some HW actually expects to check the in-data
31640 + * hash and and flag an error if it is incorrect.
31641 + *
31642 + * What we do to allow this is to pass in the current in-data
31643 + * value. Your OCF driver must ensure that it fails a request
31644 + * for hash+decrypt with an invalid hash value, or returns the
31645 + * computed in-data hash as requested.
31646 + *
31647 + * If your driver does not check the in-data hash but just
31648 + * computes it value, you must ensure that it does not return
31649 + * the original in-data hash by accident. It must invalidate the
31650 + * in-data hash itself to force an auth check error.
31651 + *
31652 + * All existing drivers that do not care about the current
31653 + * in-data hash do this by clearing the in-data hash before
31654 + * processing, either directly or via their implementation.
31655 + */
31656 +#if 0
31657 + memset(irs->authenticator, 0, 12);
31658 +#endif
31659 + }
31660 + }
31661 +
31662 + if (crde) {
31663 + crde->crd_alg = ipsec_ocf_encalg(ipsp->ips_encalg);
31664 + if (!crde->crd_alg) {
31665 + KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_ocf_rcv: "
31666 + "bad enc alg 0x%x\n", ipsp->ips_encalg);
31667 + crypto_freereq(crp);
31668 + return IPSEC_RCV_BADPROTO;
31669 + }
31670 +
31671 + irs->esphlen = ESP_HEADER_LEN + ipsp->ips_iv_size;
31672 + irs->ilen -= irs->esphlen;
31673 + crde->crd_skip = (skb_transport_header(irs->skb) - irs->skb->data) + irs->esphlen;
31674 + crde->crd_len = irs->ilen;
31675 + crde->crd_inject = crde->crd_skip - ipsp->ips_iv_size;
31676 + crde->crd_klen = ipsp->ips_key_bits_e;
31677 + crde->crd_key = ipsp->ips_key_e;
31678 + }
31679 +
31680 + crp->crp_ilen = irs->skb->len; /* Total input length */
31681 + crp->crp_flags =
31682 + CRYPTO_F_SKBUF |
31683 +#if USE_CBIMM == 1
31684 + CRYPTO_F_CBIMM |
31685 +#endif
31686 +#if USE_BATCH == 1
31687 + CRYPTO_F_BATCH |
31688 +#endif
31689 + 0;
31690 + crp->crp_buf = (caddr_t) irs->skb;
31691 + crp->crp_callback = ipsec_ocf_rcv_cb;
31692 + crp->crp_sid = ipsp->ocf_cryptoid;
31693 + crp->crp_opaque = (caddr_t) irs;
31694 + if (crypto_dispatch(crp)){
31695 + crypto_freereq(crp);
31696 + return IPSEC_RCV_REALLYBAD;
31697 + }
31698 + return(IPSEC_RCV_PENDING);
31699 +}
31700 +
31701 +#if USE_TASKLET == 0
31702 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
31703 +static void
31704 +ipsec_xsm_wq(struct work_struct *work)
31705 +{
31706 + struct ipsec_xmit_state *ixs = container_of(work, struct ipsec_xmit_state, workq);
31707 + ipsec_xsm(ixs);
31708 +}
31709 +#else
31710 +#define ipsec_xsm_wq ipsec_xsm
31711 +#endif
31712 +#endif /* USE_TASKLET */
31713 +
31714 +static int
31715 +ipsec_ocf_xmit_cb(struct cryptop *crp)
31716 +{
31717 + struct ipsec_xmit_state *ixs = (struct ipsec_xmit_state *)crp->crp_opaque;
31718 +
31719 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, "klips_debug:ipsec_ocf_xmit_cb\n");
31720 +
31721 + if (ixs == NULL) {
31722 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, "klips_debug:ipsec_ocf_xmit_cb: "
31723 + "NULL ixs in callback\n");
31724 + return 0;
31725 + }
31726 +
31727 + /*
31728 + * we must update the state before returning to the state machine.
31729 + * if we have an error, terminate the processing by moving to the DONE
31730 + * state
31731 + */
31732 +
31733 + ixs->state = IPSEC_XSM_DONE; /* assume bad xmit */
31734 + if (crp->crp_etype) {
31735 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, "klips_debug:ipsec_ocf_xmit_cb: "
31736 + "error in processing 0x%x\n", crp->crp_etype);
31737 + } else {
31738 + if (!ixs->ipsp->ips_encalg) {
31739 + /* AH post processing, put back fields we had to zero */
31740 + ixs->iph->ttl = ixs->ttl;
31741 + ixs->iph->check = ixs->check;
31742 + ixs->iph->frag_off = ixs->frag_off;
31743 + ixs->iph->tos = ixs->tos;
31744 + }
31745 + ixs->state = IPSEC_XSM_CONT; /* ESP was all good */
31746 + }
31747 +
31748 + crypto_freereq(crp);
31749 + crp = NULL;
31750 +
31751 + /* setup the rest of the processing now */
31752 + PROCESS_NEXT(ixs, ipsec_xsm_wq, ipsec_xsm);
31753 + return 0;
31754 +}
31755 +
31756 +
31757 +enum ipsec_xmit_value
31758 +ipsec_ocf_xmit(struct ipsec_xmit_state *ixs)
31759 +{
31760 + struct cryptop *crp;
31761 + struct cryptodesc *crde, *crda;
31762 + struct ipsec_sa *ipsp;
31763 +
31764 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, "klips_debug:ipsec_ocf_xmit\n");
31765 +
31766 + ipsp = ixs->ipsp;
31767 + if (!ipsp) {
31768 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, "klips_debug:ipsec_ocf_xmit: "
31769 + "no SA for rcv processing\n");
31770 + return IPSEC_XMIT_SAIDNOTFOUND;
31771 + }
31772 +
31773 + if (!ixs->skb) {
31774 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
31775 + "klips_debug:ipsec_ocf_xmit: no skb\n");
31776 + return IPSEC_XMIT_SAIDNOTFOUND;
31777 + }
31778 +
31779 + crp = crypto_getreq((ipsp->ips_authalg && ipsp->ips_encalg) ? 2 : 1);
31780 + if (!crp) {
31781 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, "klips_debug:ipsec_ocf_xmit: "
31782 + "crypto_getreq returned NULL\n");
31783 + return IPSEC_XMIT_ERRMEMALLOC;
31784 + }
31785 +
31786 + if (ipsp->ips_encalg) {
31787 + crde = crp->crp_desc;
31788 + crda = crde->crd_next;
31789 + } else {
31790 + crda = crp->crp_desc;
31791 + crde = crda->crd_next;
31792 + }
31793 +
31794 + if (crda) {
31795 + /* Authentication descriptor */
31796 + crda->crd_alg = ipsec_ocf_authalg(ipsp->ips_authalg);
31797 + if (!crda->crd_alg) {
31798 + KLIPS_PRINT(debug_tunnel&DB_TN_XMIT, "klips_debug:ipsec_ocf_xmit: "
31799 + "bad auth alg 0x%x\n", ipsp->ips_authalg);
31800 + crypto_freereq(crp);
31801 + return IPSEC_RCV_BADPROTO;
31802 + }
31803 + if (!crde) { /* assume AH processing */
31804 + /* AH processing, save fields we have to zero */
31805 + crda->crd_skip = ((unsigned char *) ixs->iph) - ixs->skb->data;
31806 + ixs->ttl = ixs->iph->ttl;
31807 + ixs->check = ixs->iph->check;
31808 + ixs->frag_off = ixs->iph->frag_off;
31809 + ixs->tos = ixs->iph->tos;
31810 + ixs->iph->ttl = 0;
31811 + ixs->iph->check = 0;
31812 + ixs->iph->frag_off = 0;
31813 + ixs->iph->tos = 0;
31814 + crda->crd_inject =
31815 + (((struct ahhdr *)(ixs->dat + ixs->iphlen))->ah_data) -
31816 + ixs->skb->data;
31817 + crda->crd_len = ixs->len - ixs->authlen;
31818 + memset(ixs->skb->data + crda->crd_inject, 0, 12); // DM
31819 + } else {
31820 + crda->crd_skip = ((unsigned char *) ixs->espp) - ixs->skb->data;
31821 + crda->crd_inject = ixs->len - ixs->authlen;
31822 + crda->crd_len = ixs->len - ixs->iphlen - ixs->authlen;
31823 + }
31824 + crda->crd_key = ipsp->ips_key_a;
31825 + crda->crd_klen = ipsp->ips_key_bits_a;
31826 + }
31827 +
31828 + if (crde) {
31829 + /* Encryption descriptor */
31830 + crde->crd_alg = ipsec_ocf_encalg(ipsp->ips_encalg);
31831 + if (!crde->crd_alg) {
31832 + KLIPS_PRINT(debug_tunnel&DB_TN_XMIT, "klips_debug:ipsec_ocf_xmit: "
31833 + "bad enc alg 0x%x\n", ipsp->ips_encalg);
31834 + crypto_freereq(crp);
31835 + return IPSEC_RCV_BADPROTO;
31836 + }
31837 + crde->crd_flags = CRD_F_ENCRYPT;
31838 + crde->crd_skip = ixs->idat - ixs->dat;
31839 + crde->crd_len = ixs->ilen;
31840 + crde->crd_inject = ((unsigned char *) ixs->espp->esp_iv) - ixs->dat;
31841 + crde->crd_klen = ipsp->ips_key_bits_e;
31842 + crde->crd_key = ipsp->ips_key_e;
31843 + }
31844 +
31845 + crp->crp_ilen = ixs->skb->len; /* Total input length */
31846 + crp->crp_flags =
31847 + CRYPTO_F_SKBUF |
31848 +#if USE_CBIMM == 1
31849 + CRYPTO_F_CBIMM |
31850 +#endif
31851 +#if USE_BATCH == 1
31852 + CRYPTO_F_BATCH |
31853 +#endif
31854 + 0;
31855 + crp->crp_buf = (caddr_t) ixs->skb;
31856 + crp->crp_callback = ipsec_ocf_xmit_cb;
31857 + crp->crp_sid = ipsp->ocf_cryptoid;
31858 + crp->crp_opaque = (caddr_t) ixs;
31859 + if (crypto_dispatch(crp)){
31860 + crypto_freereq(crp);
31861 + return IPSEC_XMIT_ERRMEMALLOC;
31862 + }
31863 + return(IPSEC_XMIT_PENDING);
31864 +}
31865 +
31866 +
31867 +
31868 +
31869 +#ifdef CONFIG_KLIPS_AH
31870 +static struct ipsec_alg_supported ocf_ah_algs[] = {
31871 + {
31872 + .ias_name = "ocf-md5hmac",
31873 + .ias_id = AH_MD5,
31874 + .ias_exttype = SADB_EXT_SUPPORTED_AUTH,
31875 + .ias_ivlen = 0,
31876 + .ias_keyminbits = 128,
31877 + .ias_keymaxbits = 128,
31878 + },
31879 + {
31880 + .ias_name = "ocf-sha1hmac",
31881 + .ias_id = AH_SHA,
31882 + .ias_exttype = SADB_EXT_SUPPORTED_AUTH,
31883 + .ias_ivlen = 0,
31884 + .ias_keyminbits = 160,
31885 + .ias_keymaxbits = 160,
31886 + },
31887 + {
31888 + .ias_name = NULL,
31889 + .ias_id = 0,
31890 + .ias_exttype = 0,
31891 + .ias_ivlen = 0,
31892 + .ias_keyminbits = 0,
31893 + .ias_keymaxbits = 0,
31894 + }
31895 +};
31896 +#endif /* CONFIG_KLIPS_AH */
31897 +
31898 +static struct ipsec_alg_supported ocf_esp_algs[] = {
31899 + {
31900 + .ias_name = "ocf-md5hmac",
31901 + .ias_id = AH_MD5,
31902 + .ias_exttype = SADB_EXT_SUPPORTED_AUTH,
31903 + .ias_ivlen = 0,
31904 + .ias_keyminbits = 128,
31905 + .ias_keymaxbits = 128,
31906 + },
31907 + {
31908 + .ias_name = "ocf-sha1hmac",
31909 + .ias_id = AH_SHA,
31910 + .ias_exttype = SADB_EXT_SUPPORTED_AUTH,
31911 + .ias_ivlen = 0,
31912 + .ias_keyminbits = 160,
31913 + .ias_keymaxbits = 160,
31914 + },
31915 + {
31916 + .ias_name = "ocf-aes",
31917 + .ias_id = ESP_AES,
31918 + .ias_exttype = SADB_EXT_SUPPORTED_ENCRYPT,
31919 + .ias_ivlen = 16,
31920 + .ias_keyminbits = 128,
31921 + .ias_keymaxbits = 256,
31922 + },
31923 + {
31924 + .ias_name = "ocf-3des",
31925 + .ias_id = ESP_3DES,
31926 + .ias_exttype = SADB_EXT_SUPPORTED_ENCRYPT,
31927 + .ias_ivlen = 8,
31928 + .ias_keyminbits = 192,
31929 + .ias_keymaxbits = 192,
31930 + },
31931 + {
31932 + .ias_name = "ocf-des",
31933 + .ias_id = ESP_DES,
31934 + .ias_exttype = SADB_EXT_SUPPORTED_ENCRYPT,
31935 + .ias_ivlen = 8,
31936 + .ias_keyminbits = 64,
31937 + .ias_keymaxbits = 64,
31938 + },
31939 + {
31940 + .ias_name = NULL,
31941 + .ias_id = 0,
31942 + .ias_exttype = 0,
31943 + .ias_ivlen = 0,
31944 + .ias_keyminbits = 0,
31945 + .ias_keymaxbits = 0,
31946 + }
31947 +};
31948 +
31949 +static int
31950 +ipsec_ocf_check_alg(struct ipsec_alg_supported *s)
31951 +{
31952 + struct cryptoini cri;
31953 + int64_t cryptoid;
31954 +
31955 + memset(&cri, 0, sizeof(cri));
31956 + if (s->ias_exttype == SADB_EXT_SUPPORTED_ENCRYPT)
31957 + cri.cri_alg = ipsec_ocf_encalg(s->ias_id);
31958 + else
31959 + cri.cri_alg = ipsec_ocf_authalg(s->ias_id);
31960 + cri.cri_klen = s->ias_keyminbits;
31961 + cri.cri_key = "0123456789abcdefghijklmnopqrstuvwxyz";
31962 +
31963 + if (crypto_newsession(&cryptoid, &cri, ipsec_ocf_crid)) {
31964 + KLIPS_PRINT(debug_pfkey, "klips_debug:ipsec_ocf:%s not supported\n",
31965 + s->ias_name);
31966 + return 0;
31967 + }
31968 + crypto_freesession(cryptoid);
31969 + KLIPS_PRINT(debug_pfkey, "klips_debug:ipsec_ocf:%s supported\n",
31970 + s->ias_name);
31971 + return 1;
31972 +}
31973 +
31974 +void
31975 +ipsec_ocf_init(void)
31976 +{
31977 + struct ipsec_alg_supported *s;
31978 +
31979 + for (s = ocf_esp_algs; s->ias_name; s++) {
31980 + if (ipsec_ocf_check_alg(s))
31981 + (void)pfkey_list_insert_supported(s,
31982 + &(pfkey_supported_list[SADB_SATYPE_ESP]));
31983 + }
31984 +
31985 +#ifdef CONFIG_KLIPS_AH
31986 + for (s = ocf_ah_algs; s->ias_name; s++) {
31987 + if (ipsec_ocf_check_alg(s))
31988 + (void)pfkey_list_insert_supported(s,
31989 + &(pfkey_supported_list[SADB_SATYPE_AH]));
31990 + }
31991 +#endif
31992 +
31993 + /* send register event to userspace */
31994 + pfkey_register_reply(SADB_SATYPE_ESP, NULL);
31995 + pfkey_register_reply(SADB_SATYPE_AH, NULL);
31996 +}
31997 +
31998 --- /dev/null Tue Mar 11 13:02:56 2003
31999 +++ linux/net/ipsec/ipsec_ocf.h Mon Feb 9 13:51:03 2004
32000 @@ -0,0 +1,41 @@
32001 +#ifndef _IPSEC_OCF_H_
32002 +#define _IPSEC_OCF_H_
32003 +/****************************************************************************/
32004 +/*
32005 + * IPSEC OCF support
32006 + *
32007 + * This code written by David McCullough <dmccullough@cyberguard.com>
32008 + * Copyright (C) 2005 Intel Corporation. All Rights Reserved.
32009 + *
32010 + * This program is free software; you can redistribute it and/or modify it
32011 + * under the terms of the GNU General Public License as published by the
32012 + * Free Software Foundation; either version 2 of the License, or (at your
32013 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
32014 + *
32015 + * This program is distributed in the hope that it will be useful, but
32016 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
32017 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
32018 + * for more details.
32019 + */
32020 +
32021 +#ifndef AUTOCONF_INCLUDED
32022 +#include <linux/config.h>
32023 +#endif
32024 +#include <linux/version.h>
32025 +#include <linux/kernel.h>
32026 +
32027 +#ifdef CONFIG_KLIPS_OCF
32028 +
32029 +#include <cryptodev.h>
32030 +
32031 +extern int ipsec_ocf_sa_init(struct ipsec_sa *ipsp, int authalg, int encalg);
32032 +extern int ipsec_ocf_sa_free(struct ipsec_sa *ipsp);
32033 +extern enum ipsec_rcv_value ipsec_ocf_rcv(struct ipsec_rcv_state *irs);
32034 +extern enum ipsec_xmit_value ipsec_ocf_xmit(struct ipsec_xmit_state *ixs);
32035 +extern void ipsec_ocf_init(void);
32036 +
32037 +#endif
32038 +
32039 +/****************************************************************************/
32040 +#endif /* _IPSEC_OCF_H_ */
32041 +
32042 --- /dev/null Tue Mar 11 13:02:56 2003
32043 +++ linux/net/ipsec/ipsec_proc.c Mon Feb 9 13:51:03 2004
32044 @@ -0,0 +1,1056 @@
32045 +/*
32046 + * @(#) /proc file system interface code.
32047 + *
32048 + * Copyright (C) 1996, 1997 John Ioannidis.
32049 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
32050 + * 2001 Michael Richardson <mcr@freeswan.org>
32051 + *
32052 + * This program is free software; you can redistribute it and/or modify it
32053 + * under the terms of the GNU General Public License as published by the
32054 + * Free Software Foundation; either version 2 of the License, or (at your
32055 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
32056 + *
32057 + * This program is distributed in the hope that it will be useful, but
32058 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
32059 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
32060 + * for more details.
32061 + *
32062 + * Split out from ipsec_init.c version 1.70.
32063 + */
32064 +
32065 +#ifndef AUTOCONF_INCLUDED
32066 +#include <linux/config.h>
32067 +#endif
32068 +#include <linux/version.h>
32069 +#define __NO_VERSION__
32070 +#include <linux/module.h>
32071 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
32072 +#include <linux/moduleparam.h>
32073 +#endif
32074 +#include <linux/kernel.h> /* printk() */
32075 +#include <linux/ip.h> /* struct iphdr */
32076 +
32077 +#include "openswan/ipsec_kversion.h"
32078 +#include "openswan/ipsec_param.h"
32079 +
32080 +#ifdef MALLOC_SLAB
32081 +# include <linux/slab.h> /* kmalloc() */
32082 +#else /* MALLOC_SLAB */
32083 +# include <linux/malloc.h> /* kmalloc() */
32084 +#endif /* MALLOC_SLAB */
32085 +#include <linux/errno.h> /* error codes */
32086 +#include <linux/types.h> /* size_t */
32087 +#include <linux/interrupt.h> /* mark_bh */
32088 +
32089 +#include <linux/netdevice.h> /* struct device, and other headers */
32090 +#include <linux/etherdevice.h> /* eth_type_trans */
32091 +#include <linux/in.h> /* struct sockaddr_in */
32092 +#include <linux/skbuff.h>
32093 +#include <asm/uaccess.h> /* copy_from_user */
32094 +#include <openswan.h>
32095 +#ifdef SPINLOCK
32096 +#ifdef SPINLOCK_23
32097 +#include <linux/spinlock.h> /* *lock* */
32098 +#else /* SPINLOCK_23 */
32099 +#include <asm/spinlock.h> /* *lock* */
32100 +#endif /* SPINLOCK_23 */
32101 +#endif /* SPINLOCK */
32102 +
32103 +#include <net/ip.h>
32104 +#ifdef CONFIG_PROC_FS
32105 +#include <linux/proc_fs.h>
32106 +#endif /* CONFIG_PROC_FS */
32107 +#ifdef NETLINK_SOCK
32108 +#include <linux/netlink.h>
32109 +#else
32110 +#include <net/netlink.h>
32111 +#endif
32112 +
32113 +#include "openswan/radij.h"
32114 +
32115 +#include "openswan/ipsec_life.h"
32116 +#include "openswan/ipsec_stats.h"
32117 +#include "openswan/ipsec_sa.h"
32118 +
32119 +#include "openswan/ipsec_encap.h"
32120 +#include "openswan/ipsec_radij.h"
32121 +#include "openswan/ipsec_xform.h"
32122 +#include "openswan/ipsec_tunnel.h"
32123 +#include "openswan/ipsec_xmit.h"
32124 +
32125 +#include "openswan/ipsec_rcv.h"
32126 +#include "openswan/ipsec_ah.h"
32127 +#include "openswan/ipsec_esp.h"
32128 +#include "openswan/ipsec_kern24.h"
32129 +
32130 +#ifdef CONFIG_KLIPS_IPCOMP
32131 +#include "openswan/ipcomp.h"
32132 +#endif /* CONFIG_KLIPS_IPCOMP */
32133 +
32134 +#include "openswan/ipsec_proto.h"
32135 +
32136 +#include <openswan/pfkeyv2.h>
32137 +#include <openswan/pfkey.h>
32138 +
32139 +#ifdef CONFIG_PROC_FS
32140 +
32141 +#ifdef IPSEC_PROC_SUBDIRS
32142 +static struct proc_dir_entry *proc_net_ipsec_dir = NULL;
32143 +static struct proc_dir_entry *proc_eroute_dir = NULL;
32144 +static struct proc_dir_entry *proc_spi_dir = NULL;
32145 +static struct proc_dir_entry *proc_spigrp_dir = NULL;
32146 +static struct proc_dir_entry *proc_birth_dir = NULL;
32147 +static struct proc_dir_entry *proc_stats_dir = NULL;
32148 +#endif
32149 +
32150 +struct ipsec_birth_reply ipsec_ipv4_birth_packet;
32151 +struct ipsec_birth_reply ipsec_ipv6_birth_packet;
32152 +
32153 +#ifdef CONFIG_KLIPS_DEBUG
32154 +int debug_esp = 0;
32155 +int debug_ah = 0;
32156 +int sysctl_ipsec_inbound_policy_check = 1;
32157 +int debug_tunnel = 0;
32158 +int debug_xmit = 0;
32159 +int debug_xform = 0;
32160 +int debug_eroute = 0;
32161 +int debug_spi = 0;
32162 +int debug_radij = 0;
32163 +int debug_pfkey = 0;
32164 +int debug_rcv = 0;
32165 +int debug_netlink = 0;
32166 +int sysctl_ipsec_debug_verbose = 0;
32167 +int sysctl_ipsec_debug_ipcomp =0;
32168 +int sysctl_ipsec_icmp = 0;
32169 +int sysctl_ipsec_tos = 0;
32170 +#endif /* CONFIG_KLIPS_DEBUG */
32171 +
32172 +#define DECREMENT_UNSIGNED(X, amount) ((amount < (X)) ? (X)-amount : 0)
32173 +
32174 +#ifdef CONFIG_KLIPS_ALG
32175 +extern int ipsec_xform_get_info(char *buffer, char **start,
32176 + off_t offset, int length IPSEC_PROC_LAST_ARG);
32177 +#endif
32178 +
32179 +IPSEC_PROCFS_DEBUG_NO_STATIC
32180 +int
32181 +ipsec_eroute_get_info(char *buffer,
32182 + char **start,
32183 + off_t offset,
32184 + int length IPSEC_PROC_LAST_ARG)
32185 +{
32186 + struct wsbuf w = {buffer, length, offset, 0, 0};
32187 +
32188 +#ifdef CONFIG_KLIPS_DEBUG
32189 + if (debug_radij & DB_RJ_DUMPTREES)
32190 + rj_dumptrees(); /* XXXXXXXXX */
32191 +#endif /* CONFIG_KLIPS_DEBUG */
32192 +
32193 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32194 + "klips_debug:ipsec_eroute_get_info: "
32195 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32196 + buffer,
32197 + *start,
32198 + (int)offset,
32199 + length);
32200 +
32201 + spin_lock_bh(&eroute_lock);
32202 +
32203 + rj_walktree(rnh, ipsec_rj_walker_procprint, &w);
32204 +/* rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */
32205 +
32206 + spin_unlock_bh(&eroute_lock);
32207 +
32208 + *start = buffer + (offset - w.begin); /* Start of wanted data */
32209 + return w.len - (offset - w.begin);
32210 +}
32211 +
32212 +IPSEC_PROCFS_DEBUG_NO_STATIC
32213 +int
32214 +ipsec_spi_get_info(char *buffer,
32215 + char **start,
32216 + off_t offset,
32217 + int length IPSEC_PROC_LAST_ARG)
32218 +{
32219 + const int max_content = length > 0? length-1 : 0;
32220 + int len = 0;
32221 + off_t begin = 0;
32222 + int i;
32223 + struct ipsec_sa *sa_p;
32224 + char sa[SATOT_BUF];
32225 + char buf_s[SUBNETTOA_BUF];
32226 + char buf_d[SUBNETTOA_BUF];
32227 + size_t sa_len;
32228 +
32229 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32230 + "klips_debug:ipsec_spi_get_info: "
32231 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32232 + buffer,
32233 + *start,
32234 + (int)offset,
32235 + length);
32236 +
32237 + spin_lock_bh(&tdb_lock);
32238 +
32239 + for (i = 0; i < SADB_HASHMOD; i++) {
32240 + for (sa_p = ipsec_sadb_hash[i];
32241 + sa_p;
32242 + sa_p = sa_p->ips_hnext) {
32243 + ipsec_sa_get(sa_p);
32244 + sa_len = satot(&sa_p->ips_said, 'x', sa, sizeof(sa));
32245 + len += ipsec_snprintf(buffer+len, length-len, "%s ",
32246 + sa_len ? sa : " (error)");
32247 +
32248 + len += ipsec_snprintf(buffer+len, length-len, "%s%s%s",
32249 + IPS_XFORM_NAME(sa_p));
32250 +
32251 + len += ipsec_snprintf(buffer+len, length-len, ": dir=%s",
32252 + (sa_p->ips_flags & EMT_INBOUND) ?
32253 + "in " : "out");
32254 +
32255 + if(sa_p->ips_addr_s) {
32256 + addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr,
32257 + 0, buf_s, sizeof(buf_s));
32258 + len += ipsec_snprintf(buffer+len, length-len, " src=%s",
32259 + buf_s);
32260 + }
32261 +
32262 + if((sa_p->ips_said.proto == IPPROTO_IPIP)
32263 + && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) {
32264 + subnettoa(sa_p->ips_flow_s.u.v4.sin_addr,
32265 + sa_p->ips_mask_s.u.v4.sin_addr,
32266 + 0,
32267 + buf_s,
32268 + sizeof(buf_s));
32269 +
32270 + subnettoa(sa_p->ips_flow_d.u.v4.sin_addr,
32271 + sa_p->ips_mask_d.u.v4.sin_addr,
32272 + 0,
32273 + buf_d,
32274 + sizeof(buf_d));
32275 +
32276 + len += ipsec_snprintf(buffer+len, length-len, " policy=%s->%s",
32277 + buf_s, buf_d);
32278 + }
32279 +
32280 + if(sa_p->ips_iv_bits) {
32281 + int j;
32282 + len += ipsec_snprintf(buffer+len, length-len, " iv_bits=%dbits iv=0x",
32283 + sa_p->ips_iv_bits);
32284 +
32285 +#ifdef CONFIG_KLIPS_OCF
32286 + if (!sa_p->ips_iv) {
32287 + /* ocf doesn't set the IV, fake it for the UML tests */
32288 + len += ipsec_snprintf(buffer+len, length-len, "0cf0");
32289 + for (j = 0; j < (sa_p->ips_iv_bits / 8) - 2; j++) {
32290 + len += ipsec_snprintf(buffer+len, length-len, "%02x",
32291 + (int) ((((long)sa_p) >> j) & 0xff));
32292 + }
32293 + } else
32294 +#endif
32295 + for(j = 0; j < sa_p->ips_iv_bits / 8; j++) {
32296 + len += ipsec_snprintf(buffer+len, length-len, "%02x",
32297 + (__u32)((__u8*)(sa_p->ips_iv))[j]);
32298 + }
32299 + }
32300 +
32301 + if(sa_p->ips_encalg || sa_p->ips_authalg) {
32302 + if(sa_p->ips_replaywin) {
32303 + len += ipsec_snprintf(buffer+len, length-len, " ooowin=%d",
32304 + sa_p->ips_replaywin);
32305 + }
32306 + if(sa_p->ips_errs.ips_replaywin_errs) {
32307 + len += ipsec_snprintf(buffer+len, length-len, " ooo_errs=%d",
32308 + sa_p->ips_errs.ips_replaywin_errs);
32309 + }
32310 + if(sa_p->ips_replaywin_lastseq) {
32311 + len += ipsec_snprintf(buffer+len, length-len, " seq=%d",
32312 + sa_p->ips_replaywin_lastseq);
32313 + }
32314 + if(sa_p->ips_replaywin_bitmap) {
32315 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
32316 + len += ipsec_snprintf(buffer+len, length-len, " bit=0x%Lx",
32317 + sa_p->ips_replaywin_bitmap);
32318 +#else
32319 + len += ipsec_snprintf(buffer+len, length-len, " bit=0x%x%08x",
32320 + (__u32)(sa_p->ips_replaywin_bitmap >> 32),
32321 + (__u32)sa_p->ips_replaywin_bitmap);
32322 +#endif
32323 + }
32324 + if(sa_p->ips_replaywin_maxdiff) {
32325 + len += ipsec_snprintf(buffer+len, length-len, " max_seq_diff=%d",
32326 + sa_p->ips_replaywin_maxdiff);
32327 + }
32328 + }
32329 + if(sa_p->ips_flags & ~EMT_INBOUND) {
32330 + len += ipsec_snprintf(buffer+len, length-len, " flags=0x%x",
32331 + sa_p->ips_flags & ~EMT_INBOUND);
32332 + len += ipsec_snprintf(buffer+len, length-len, "<");
32333 + /* flag printing goes here */
32334 + len += ipsec_snprintf(buffer+len, length-len, ">");
32335 + }
32336 + if(sa_p->ips_auth_bits) {
32337 + len += ipsec_snprintf(buffer+len, length-len, " alen=%d",
32338 + sa_p->ips_auth_bits);
32339 + }
32340 + if(sa_p->ips_key_bits_a) {
32341 + len += ipsec_snprintf(buffer+len, length-len, " aklen=%d",
32342 + sa_p->ips_key_bits_a);
32343 + }
32344 + if(sa_p->ips_errs.ips_auth_errs) {
32345 + len += ipsec_snprintf(buffer+len, length-len, " auth_errs=%d",
32346 + sa_p->ips_errs.ips_auth_errs);
32347 + }
32348 + if(sa_p->ips_key_bits_e) {
32349 + len += ipsec_snprintf(buffer+len, length-len, " eklen=%d",
32350 + sa_p->ips_key_bits_e);
32351 + }
32352 + if(sa_p->ips_errs.ips_encsize_errs) {
32353 + len += ipsec_snprintf(buffer+len, length-len, " encr_size_errs=%d",
32354 + sa_p->ips_errs.ips_encsize_errs);
32355 + }
32356 + if(sa_p->ips_errs.ips_encpad_errs) {
32357 + len += ipsec_snprintf(buffer+len, length-len, " encr_pad_errs=%d",
32358 + sa_p->ips_errs.ips_encpad_errs);
32359 + }
32360 +
32361 + len += ipsec_snprintf(buffer+len, length-len, " life(c,s,h)=");
32362 +
32363 + len += ipsec_lifetime_format(buffer + len,
32364 + length - len,
32365 + "alloc",
32366 + ipsec_life_countbased,
32367 + &sa_p->ips_life.ipl_allocations);
32368 +
32369 + len += ipsec_lifetime_format(buffer + len,
32370 + length - len,
32371 + "bytes",
32372 + ipsec_life_countbased,
32373 + &sa_p->ips_life.ipl_bytes);
32374 +
32375 + len += ipsec_lifetime_format(buffer + len,
32376 + length - len,
32377 + "addtime",
32378 + ipsec_life_timebased,
32379 + &sa_p->ips_life.ipl_addtime);
32380 +
32381 + len += ipsec_lifetime_format(buffer + len,
32382 + length - len,
32383 + "usetime",
32384 + ipsec_life_timebased,
32385 + &sa_p->ips_life.ipl_usetime);
32386 +
32387 + len += ipsec_lifetime_format(buffer + len,
32388 + length - len,
32389 + "packets",
32390 + ipsec_life_countbased,
32391 + &sa_p->ips_life.ipl_packets);
32392 +
32393 + if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */
32394 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
32395 + len += ipsec_snprintf(buffer+len, length-len, " idle=%Ld",
32396 + jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last);
32397 +#else
32398 + len += ipsec_snprintf(buffer+len, length-len, " idle=%lu",
32399 + jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last);
32400 +#endif
32401 + }
32402 +
32403 +#ifdef CONFIG_KLIPS_IPCOMP
32404 + if(sa_p->ips_said.proto == IPPROTO_COMP &&
32405 + (sa_p->ips_comp_ratio_dbytes ||
32406 + sa_p->ips_comp_ratio_cbytes)) {
32407 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
32408 + len += ipsec_snprintf(buffer+len, length-len, " ratio=%Ld:%Ld",
32409 + sa_p->ips_comp_ratio_dbytes,
32410 + sa_p->ips_comp_ratio_cbytes);
32411 +#else
32412 + len += ipsec_snprintf(buffer+len, length-len, " ratio=%lu:%lu",
32413 + (unsigned long)sa_p->ips_comp_ratio_dbytes,
32414 + (unsigned long)sa_p->ips_comp_ratio_cbytes);
32415 +#endif
32416 + }
32417 +#endif /* CONFIG_KLIPS_IPCOMP */
32418 +
32419 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
32420 + {
32421 + char *natttype_name;
32422 +
32423 + switch(sa_p->ips_natt_type)
32424 + {
32425 + case 0:
32426 + natttype_name="none";
32427 + break;
32428 + case ESPINUDP_WITH_NON_IKE:
32429 + natttype_name="nonike";
32430 + break;
32431 + case ESPINUDP_WITH_NON_ESP:
32432 + natttype_name="nonesp";
32433 + break;
32434 + default:
32435 + natttype_name = "unknown";
32436 + break;
32437 + }
32438 +
32439 + len += ipsec_snprintf(buffer + len, length-len, " natencap=%s",
32440 + natttype_name);
32441 +
32442 + len += ipsec_snprintf(buffer + len, length-len, " natsport=%d",
32443 + sa_p->ips_natt_sport);
32444 +
32445 + len += ipsec_snprintf(buffer + len,length-len, " natdport=%d",
32446 + sa_p->ips_natt_dport);
32447 + }
32448 +#else
32449 + len += ipsec_snprintf(buffer + len, length-len, " natencap=na");
32450 +#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
32451 +
32452 + /* we decrement by one, because this SA has been referenced in order to dump this info */
32453 + len += ipsec_snprintf(buffer + len,length-len, " refcount=%d",
32454 + atomic_read(&sa_p->ips_refcount)-1);
32455 +
32456 + len += ipsec_snprintf(buffer+len, length-len, " ref=%d",
32457 + sa_p->ips_ref);
32458 + len += ipsec_snprintf(buffer+len, length-len, " refhim=%d",
32459 + sa_p->ips_refhim);
32460 +
32461 + if(sa_p->ips_out) {
32462 + len += ipsec_snprintf(buffer+len, length-len, " outif=%s:%d",
32463 + sa_p->ips_out->name,
32464 + sa_p->ips_transport_direct);
32465 + }
32466 +#ifdef CONFIG_KLIPS_DEBUG
32467 + if(debug_xform) {
32468 + len += ipsec_snprintf(buffer+len, length-len, " reftable=%lu refentry=%lu",
32469 + (unsigned long)IPsecSAref2table(sa_p->ips_ref),
32470 + (unsigned long)IPsecSAref2entry(sa_p->ips_ref));
32471 + }
32472 +#endif /* CONFIG_KLIPS_DEBUG */
32473 +
32474 + len += ipsec_snprintf(buffer+len, length-len, "\n");
32475 +
32476 + ipsec_sa_put(sa_p);
32477 +
32478 + if (len >= max_content) {
32479 + /* we've done all that can fit -- stop loops */
32480 + len = max_content; /* truncate crap */
32481 + goto done_spi_i;
32482 + } else {
32483 + const off_t pos = begin + len; /* file position of end of what we've generated */
32484 +
32485 + if (pos <= offset) {
32486 + /* all is before first interesting character:
32487 + * discard, but note where we are.
32488 + */
32489 + len = 0;
32490 + begin = pos;
32491 + }
32492 + }
32493 + }
32494 + }
32495 +
32496 +done_spi_i:
32497 + spin_unlock_bh(&tdb_lock);
32498 +
32499 + *start = buffer + (offset - begin); /* Start of wanted data */
32500 + return len - (offset - begin);
32501 +}
32502 +
32503 +IPSEC_PROCFS_DEBUG_NO_STATIC
32504 +int
32505 +ipsec_spigrp_get_info(char *buffer,
32506 + char **start,
32507 + off_t offset,
32508 + int length IPSEC_PROC_LAST_ARG)
32509 +{
32510 + /* Limit of useful snprintf output */
32511 + const int max_content = length > 0? length-1 : 0;
32512 +
32513 + int len = 0;
32514 + off_t begin = 0;
32515 + int i;
32516 + struct ipsec_sa *sa_p, *sa_p2;
32517 + char sa[SATOT_BUF];
32518 + size_t sa_len;
32519 +
32520 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32521 + "klips_debug:ipsec_spigrp_get_info: "
32522 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32523 + buffer,
32524 + *start,
32525 + (int)offset,
32526 + length);
32527 +
32528 + spin_lock_bh(&tdb_lock);
32529 +
32530 + for (i = 0; i < SADB_HASHMOD; i++) {
32531 + for (sa_p = ipsec_sadb_hash[i];
32532 + sa_p != NULL;
32533 + sa_p = sa_p->ips_hnext)
32534 + {
32535 + sa_p2 = sa_p;
32536 + while(sa_p2 != NULL) {
32537 + struct ipsec_sa *sa2n;
32538 + sa_len = satot(&sa_p2->ips_said,
32539 + 'x', sa, sizeof(sa));
32540 +
32541 + len += ipsec_snprintf(buffer+len, length-len, "%s ",
32542 + sa_len ? sa : " (error)");
32543 +
32544 + sa2n = sa_p2->ips_next;
32545 + sa_p2 = sa2n;
32546 + }
32547 + len += ipsec_snprintf(buffer+len, length-len, "\n");
32548 +
32549 + if (len >= max_content) {
32550 + /* we've done all that can fit -- stop loops */
32551 + len = max_content; /* truncate crap */
32552 + goto done_spigrp_i;
32553 + } else {
32554 + const off_t pos = begin + len;
32555 +
32556 + if (pos <= offset) {
32557 + /* all is before first interesting character:
32558 + * discard, but note where we are.
32559 + */
32560 + len = 0;
32561 + begin = pos;
32562 + }
32563 + }
32564 + }
32565 + }
32566 +
32567 +done_spigrp_i:
32568 + spin_unlock_bh(&tdb_lock);
32569 +
32570 + *start = buffer + (offset - begin); /* Start of wanted data */
32571 + return len - (offset - begin);
32572 +}
32573 +
32574 +
32575 +IPSEC_PROCFS_DEBUG_NO_STATIC
32576 +int
32577 +ipsec_tncfg_get_info(char *buffer,
32578 + char **start,
32579 + off_t offset,
32580 + int length IPSEC_PROC_LAST_ARG)
32581 +{
32582 + /* limit of useful snprintf output */
32583 + const int max_content = length > 0? length-1 : 0;
32584 + int len = 0;
32585 + off_t begin = 0;
32586 + int i;
32587 + char name[9];
32588 + struct net_device *dev, *privdev;
32589 + struct ipsecpriv *priv;
32590 +
32591 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32592 + "klips_debug:ipsec_tncfg_get_info: "
32593 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32594 + buffer,
32595 + *start,
32596 + (int)offset,
32597 + length);
32598 +
32599 + for(i = 0; i < IPSEC_NUM_IF; i++) {
32600 + ipsec_snprintf(name, (ssize_t) sizeof(name), IPSEC_DEV_FORMAT, i);
32601 + dev = __ipsec_dev_get(name);
32602 + if(dev) {
32603 + priv = (struct ipsecpriv *)(dev->priv);
32604 + len += ipsec_snprintf(buffer+len, length-len, "%s",
32605 + dev->name);
32606 + if(priv) {
32607 + privdev = (struct net_device *)(priv->dev);
32608 + len += ipsec_snprintf(buffer+len, length-len, " -> %s",
32609 + privdev ? privdev->name : "NULL");
32610 + len += ipsec_snprintf(buffer+len, length-len, " mtu=%d(%d) -> %d",
32611 + dev->mtu,
32612 + priv->mtu,
32613 + privdev ? privdev->mtu : 0);
32614 + } else {
32615 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32616 + "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n",
32617 + dev->name);
32618 + }
32619 + len += ipsec_snprintf(buffer+len, length-len, "\n");
32620 +
32621 + if (len >= max_content) {
32622 + /* we've done all that can fit -- stop loop */
32623 + len = max_content; /* truncate crap */
32624 + break;
32625 + } else {
32626 + const off_t pos = begin + len;
32627 + if (pos <= offset) {
32628 + len = 0;
32629 + begin = pos;
32630 + }
32631 + }
32632 + }
32633 + }
32634 + *start = buffer + (offset - begin); /* Start of wanted data */
32635 + len -= (offset - begin); /* Start slop */
32636 + if (len > length)
32637 + len = length;
32638 + return len;
32639 +}
32640 +
32641 +IPSEC_PROCFS_DEBUG_NO_STATIC
32642 +int
32643 +ipsec_version_get_info(char *buffer,
32644 + char **start,
32645 + off_t offset,
32646 + int length IPSEC_PROC_LAST_ARG)
32647 +{
32648 + int len = 0;
32649 + off_t begin = 0;
32650 +
32651 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32652 + "klips_debug:ipsec_version_get_info: "
32653 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32654 + buffer,
32655 + *start,
32656 + (int)offset,
32657 + length);
32658 +
32659 + len += ipsec_snprintf(buffer + len,length-len, "Openswan version: %s\n",
32660 + ipsec_version_code());
32661 +#if 0
32662 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32663 + "klips_debug:ipsec_version_get_info: "
32664 + "ipsec_init version: %s\n",
32665 + ipsec_init_c_version);
32666 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32667 + "klips_debug:ipsec_version_get_info: "
32668 + "ipsec_tunnel version: %s\n",
32669 + ipsec_tunnel_c_version);
32670 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32671 + "klips_debug:ipsec_version_get_info: "
32672 + "ipsec_netlink version: %s\n",
32673 + ipsec_netlink_c_version);
32674 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32675 + "klips_debug:ipsec_version_get_info: "
32676 + "radij_c_version: %s\n",
32677 + radij_c_version);
32678 +#endif
32679 +
32680 +
32681 + *start = buffer + (offset - begin); /* Start of wanted data */
32682 + len -= (offset - begin); /* Start slop */
32683 + if (len > length)
32684 + len = length;
32685 + return len;
32686 +}
32687 +
32688 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
32689 +unsigned int natt_available = 1;
32690 +#else
32691 +unsigned int natt_available = 0;
32692 +#endif
32693 +module_param(natt_available,int,0644);
32694 +
32695 +IPSEC_PROCFS_DEBUG_NO_STATIC
32696 +int
32697 +ipsec_natt_get_info(char *buffer,
32698 + char **start,
32699 + off_t offset,
32700 + int length IPSEC_PROC_LAST_ARG)
32701 +{
32702 + int len = 0;
32703 + off_t begin = 0;
32704 +
32705 + len += ipsec_snprintf(buffer + len,
32706 + length-len, "%d\n",
32707 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
32708 + 1
32709 +#else
32710 + 0
32711 +#endif
32712 + );
32713 +
32714 + *start = buffer + (offset - begin); /* Start of wanted data */
32715 + len -= (offset - begin); /* Start slop */
32716 + if (len > length)
32717 + len = length;
32718 + return len;
32719 +}
32720 +
32721 +IPSEC_PROCFS_DEBUG_NO_STATIC
32722 +int
32723 +ipsec_birth_info(char *page,
32724 + char **start,
32725 + off_t offset,
32726 + int count,
32727 + int *eof,
32728 + void *data)
32729 +{
32730 + struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
32731 + int len;
32732 +
32733 + if(offset >= ibr->packet_template_len) {
32734 + if(eof) {
32735 + *eof=1;
32736 + }
32737 + return 0;
32738 + }
32739 +
32740 + len = ibr->packet_template_len;
32741 + len -= offset;
32742 + if (len > count)
32743 + len = count;
32744 +
32745 + memcpy(page + offset, ibr->packet_template+offset, len);
32746 +
32747 + return len;
32748 +}
32749 +
32750 +IPSEC_PROCFS_DEBUG_NO_STATIC
32751 +int
32752 +ipsec_birth_set(struct file *file, const char *buffer,
32753 + unsigned long count, void *data)
32754 +{
32755 + struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
32756 + int len;
32757 +
32758 + KLIPS_INC_USE;
32759 + if(count > IPSEC_BIRTH_TEMPLATE_MAXLEN) {
32760 + len = IPSEC_BIRTH_TEMPLATE_MAXLEN;
32761 + } else {
32762 + len = count;
32763 + }
32764 +
32765 + if(copy_from_user(ibr->packet_template, buffer, len)) {
32766 + KLIPS_DEC_USE;
32767 + return -EFAULT;
32768 + }
32769 + ibr->packet_template_len = len;
32770 +
32771 + KLIPS_DEC_USE;
32772 +
32773 + return len;
32774 +}
32775 +
32776 +
32777 +#ifdef CONFIG_KLIPS_DEBUG
32778 +IPSEC_PROCFS_DEBUG_NO_STATIC
32779 +int
32780 +ipsec_klipsdebug_get_info(char *buffer,
32781 + char **start,
32782 + off_t offset,
32783 + int length IPSEC_PROC_LAST_ARG)
32784 +{
32785 + int len = 0;
32786 + off_t begin = 0;
32787 +
32788 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32789 + "klips_debug:ipsec_klipsdebug_get_info: "
32790 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32791 + buffer,
32792 + *start,
32793 + (int)offset,
32794 + length);
32795 +
32796 + len += ipsec_snprintf(buffer+len, length-len, "debug_tunnel=%08x.\n", debug_tunnel);
32797 + len += ipsec_snprintf(buffer+len, length-len, "debug_xform=%08x.\n", debug_xform);
32798 + len += ipsec_snprintf(buffer+len, length-len, "debug_eroute=%08x.\n", debug_eroute);
32799 + len += ipsec_snprintf(buffer+len, length-len, "debug_spi=%08x.\n", debug_spi);
32800 + len += ipsec_snprintf(buffer+len, length-len, "debug_radij=%08x.\n", debug_radij);
32801 + len += ipsec_snprintf(buffer+len, length-len, "debug_esp=%08x.\n", debug_esp);
32802 + len += ipsec_snprintf(buffer+len, length-len, "debug_ah=%08x.\n", debug_ah);
32803 + len += ipsec_snprintf(buffer+len, length-len, "debug_rcv=%08x.\n", debug_rcv);
32804 + len += ipsec_snprintf(buffer+len, length-len, "debug_pfkey=%08x.\n", debug_pfkey);
32805 +
32806 + *start = buffer + (offset - begin); /* Start of wanted data */
32807 + len -= (offset - begin); /* Start slop */
32808 + if (len > length)
32809 + len = length;
32810 + return len;
32811 +}
32812 +#endif /* CONFIG_KLIPS_DEBUG */
32813 +
32814 +IPSEC_PROCFS_DEBUG_NO_STATIC
32815 +int
32816 +ipsec_stats_get_int_info(char *buffer,
32817 + char **start,
32818 + off_t offset,
32819 + int length,
32820 + int *eof,
32821 + void *data)
32822 +{
32823 +
32824 + const int max_content = length > 0? length-1 : 0;
32825 + int len = 0;
32826 + int *thing;
32827 +
32828 + thing = (int *)data;
32829 +
32830 + len = ipsec_snprintf(buffer+len, length-len, "%08x\n", *thing);
32831 +
32832 + if (len >= max_content)
32833 + len = max_content; /* truncate crap */
32834 +
32835 + *start = buffer + offset; /* Start of wanted data */
32836 + return len > offset? len - offset : 0;
32837 +
32838 +}
32839 +
32840 +#ifndef PROC_FS_2325
32841 +struct proc_dir_entry ipsec_eroute =
32842 +{
32843 + 0,
32844 + 12, "ipsec_eroute",
32845 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32846 + &proc_net_inode_operations,
32847 + ipsec_eroute_get_info,
32848 + NULL, NULL, NULL, NULL, NULL
32849 +};
32850 +
32851 +struct proc_dir_entry ipsec_spi =
32852 +{
32853 + 0,
32854 + 9, "ipsec_spi",
32855 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32856 + &proc_net_inode_operations,
32857 + ipsec_spi_get_info,
32858 + NULL, NULL, NULL, NULL, NULL
32859 +};
32860 +
32861 +struct proc_dir_entry ipsec_spigrp =
32862 +{
32863 + 0,
32864 + 12, "ipsec_spigrp",
32865 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32866 + &proc_net_inode_operations,
32867 + ipsec_spigrp_get_info,
32868 + NULL, NULL, NULL, NULL, NULL
32869 +};
32870 +
32871 +struct proc_dir_entry ipsec_tncfg =
32872 +{
32873 + 0,
32874 + 11, "ipsec_tncfg",
32875 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32876 + &proc_net_inode_operations,
32877 + ipsec_tncfg_get_info,
32878 + NULL, NULL, NULL, NULL, NULL
32879 +};
32880 +
32881 +struct proc_dir_entry ipsec_version =
32882 +{
32883 + 0,
32884 + 13, "ipsec_version",
32885 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32886 + &proc_net_inode_operations,
32887 + ipsec_version_get_info,
32888 + NULL, NULL, NULL, NULL, NULL
32889 +};
32890 +
32891 +#ifdef CONFIG_KLIPS_DEBUG
32892 +struct proc_dir_entry ipsec_klipsdebug =
32893 +{
32894 + 0,
32895 + 16, "ipsec_klipsdebug",
32896 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32897 + &proc_net_inode_operations,
32898 + ipsec_klipsdebug_get_info,
32899 + NULL, NULL, NULL, NULL, NULL
32900 +};
32901 +#endif /* CONFIG_KLIPS_DEBUG */
32902 +#endif /* !PROC_FS_2325 */
32903 +#endif /* CONFIG_PROC_FS */
32904 +
32905 +#if defined(PROC_FS_2325)
32906 +struct ipsec_proc_list {
32907 + char *name;
32908 + struct proc_dir_entry **parent;
32909 + struct proc_dir_entry **dir;
32910 + read_proc_t *readthing;
32911 + write_proc_t *writething;
32912 + void *data;
32913 +};
32914 +static struct ipsec_proc_list proc_items[]={
32915 +#ifdef CONFIG_KLIPS_DEBUG
32916 + {"klipsdebug", &proc_net_ipsec_dir, NULL, ipsec_klipsdebug_get_info, NULL, NULL},
32917 +#endif
32918 + {"eroute", &proc_net_ipsec_dir, &proc_eroute_dir, NULL, NULL, NULL},
32919 + {"all", &proc_eroute_dir, NULL, ipsec_eroute_get_info, NULL, NULL},
32920 + {"spi", &proc_net_ipsec_dir, &proc_spi_dir, NULL, NULL, NULL},
32921 + {"all", &proc_spi_dir, NULL, ipsec_spi_get_info, NULL, NULL},
32922 + {"spigrp", &proc_net_ipsec_dir, &proc_spigrp_dir, NULL, NULL, NULL},
32923 + {"all", &proc_spigrp_dir, NULL, ipsec_spigrp_get_info, NULL, NULL},
32924 + {"birth", &proc_net_ipsec_dir, &proc_birth_dir, NULL, NULL, NULL},
32925 + {"ipv4", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv4_birth_packet},
32926 + {"ipv6", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv6_birth_packet},
32927 + {"tncfg", &proc_net_ipsec_dir, NULL, ipsec_tncfg_get_info, NULL, NULL},
32928 +#ifdef CONFIG_KLIPS_ALG
32929 +
32930 + {"xforms", &proc_net_ipsec_dir, NULL, ipsec_xform_get_info, NULL, NULL},
32931 +#endif
32932 + {"stats", &proc_net_ipsec_dir, &proc_stats_dir, NULL, NULL, NULL},
32933 + {"trap_count", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_count},
32934 + {"trap_sendcount", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_sendcount},
32935 + {"natt", &proc_net_ipsec_dir, NULL, ipsec_natt_get_info, NULL, NULL},
32936 + {"version", &proc_net_ipsec_dir, NULL, ipsec_version_get_info, NULL, NULL},
32937 + {NULL, NULL, NULL, NULL, NULL, NULL}
32938 +};
32939 +#endif
32940 +
32941 +int
32942 +ipsec_proc_init()
32943 +{
32944 + int error = 0;
32945 +#ifdef IPSEC_PROC_SUBDIRS
32946 + struct proc_dir_entry *item;
32947 +#endif
32948 +
32949 + /*
32950 + * just complain because pluto won't run without /proc!
32951 + */
32952 +#ifndef CONFIG_PROC_FS
32953 +#error You must have PROC_FS built in to use KLIPS
32954 +#endif
32955 +
32956 + /* for 2.0 kernels */
32957 +#if !defined(PROC_FS_2325) && !defined(PROC_FS_21)
32958 + error |= proc_register_dynamic(&PROC_NET, &ipsec_eroute);
32959 + error |= proc_register_dynamic(&PROC_NET, &ipsec_spi);
32960 + error |= proc_register_dynamic(&PROC_NET, &ipsec_spigrp);
32961 + error |= proc_register_dynamic(&PROC_NET, &ipsec_tncfg);
32962 + error |= proc_register_dynamic(&PROC_NET, &ipsec_version);
32963 +#ifdef CONFIG_KLIPS_DEBUG
32964 + error |= proc_register_dynamic(&PROC_NET, &ipsec_klipsdebug);
32965 +#endif /* CONFIG_KLIPS_DEBUG */
32966 +#endif
32967 +
32968 + /* for 2.2 kernels */
32969 +#if !defined(PROC_FS_2325) && defined(PROC_FS_21)
32970 + error |= proc_register(PROC_NET, &ipsec_eroute);
32971 + error |= proc_register(PROC_NET, &ipsec_spi);
32972 + error |= proc_register(PROC_NET, &ipsec_spigrp);
32973 + error |= proc_register(PROC_NET, &ipsec_tncfg);
32974 + error |= proc_register(PROC_NET, &ipsec_version);
32975 +#ifdef CONFIG_KLIPS_DEBUG
32976 + error |= proc_register(PROC_NET, &ipsec_klipsdebug);
32977 +#endif /* CONFIG_KLIPS_DEBUG */
32978 +#endif
32979 +
32980 + /* for 2.4 kernels */
32981 +#if defined(PROC_FS_2325)
32982 + /* create /proc/net/ipsec */
32983 +
32984 + /* zero these out before we initialize /proc/net/ipsec/birth/stuff */
32985 + memset(&ipsec_ipv4_birth_packet, 0, sizeof(struct ipsec_birth_reply));
32986 + memset(&ipsec_ipv6_birth_packet, 0, sizeof(struct ipsec_birth_reply));
32987 +
32988 + proc_net_ipsec_dir = proc_mkdir("ipsec", PROC_NET);
32989 + if(proc_net_ipsec_dir == NULL) {
32990 + /* no point in continuing */
32991 + return 1;
32992 + }
32993 +
32994 + {
32995 + struct ipsec_proc_list *it;
32996 +
32997 + it=proc_items;
32998 + while(it->name!=NULL) {
32999 + if(it->dir) {
33000 + /* make a dir instead */
33001 + item = proc_mkdir(it->name, *it->parent);
33002 + *it->dir = item;
33003 + } else {
33004 + item = create_proc_entry(it->name, 0400, *it->parent);
33005 + }
33006 + if(item) {
33007 + item->read_proc = it->readthing;
33008 + item->write_proc = it->writething;
33009 + item->data = it->data;
33010 +#ifdef MODULE
33011 + item->owner = THIS_MODULE;
33012 +#endif
33013 + } else {
33014 + error |= 1;
33015 + }
33016 + it++;
33017 + }
33018 + }
33019 +
33020 + /* now create some symlinks to provide compatibility */
33021 + proc_symlink("ipsec_eroute", PROC_NET, "ipsec/eroute/all");
33022 + proc_symlink("ipsec_spi", PROC_NET, "ipsec/spi/all");
33023 + proc_symlink("ipsec_spigrp", PROC_NET, "ipsec/spigrp/all");
33024 + proc_symlink("ipsec_tncfg", PROC_NET, "ipsec/tncfg");
33025 + proc_symlink("ipsec_version",PROC_NET, "ipsec/version");
33026 + proc_symlink("ipsec_klipsdebug",PROC_NET,"ipsec/klipsdebug");
33027 +
33028 +#endif /* !PROC_FS_2325 */
33029 +
33030 + return error;
33031 +}
33032 +
33033 +void
33034 +ipsec_proc_cleanup()
33035 +{
33036 +
33037 + /* for 2.0 and 2.2 kernels */
33038 +#if !defined(PROC_FS_2325)
33039 +
33040 +#ifdef CONFIG_KLIPS_DEBUG
33041 + if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0)
33042 + printk("klips_debug:ipsec_cleanup: "
33043 + "cannot unregister /proc/net/ipsec_klipsdebug\n");
33044 +#endif /* CONFIG_KLIPS_DEBUG */
33045 +
33046 + if (proc_net_unregister(ipsec_version.low_ino) != 0)
33047 + printk("klips_debug:ipsec_cleanup: "
33048 + "cannot unregister /proc/net/ipsec_version\n");
33049 + if (proc_net_unregister(ipsec_eroute.low_ino) != 0)
33050 + printk("klips_debug:ipsec_cleanup: "
33051 + "cannot unregister /proc/net/ipsec_eroute\n");
33052 + if (proc_net_unregister(ipsec_spi.low_ino) != 0)
33053 + printk("klips_debug:ipsec_cleanup: "
33054 + "cannot unregister /proc/net/ipsec_spi\n");
33055 + if (proc_net_unregister(ipsec_spigrp.low_ino) != 0)
33056 + printk("klips_debug:ipsec_cleanup: "
33057 + "cannot unregister /proc/net/ipsec_spigrp\n");
33058 + if (proc_net_unregister(ipsec_tncfg.low_ino) != 0)
33059 + printk("klips_debug:ipsec_cleanup: "
33060 + "cannot unregister /proc/net/ipsec_tncfg\n");
33061 +#endif
33062 +
33063 + /* for 2.4 kernels */
33064 +#if defined(PROC_FS_2325)
33065 + {
33066 + struct ipsec_proc_list *it;
33067 +
33068 + /* find end of list */
33069 + it=proc_items;
33070 + while(it->name!=NULL) {
33071 + it++;
33072 + }
33073 + it--;
33074 +
33075 + do {
33076 + remove_proc_entry(it->name, *it->parent);
33077 + it--;
33078 + } while(it >= proc_items);
33079 + }
33080 +
33081 +
33082 +#ifdef CONFIG_KLIPS_DEBUG
33083 + remove_proc_entry("ipsec_klipsdebug", PROC_NET);
33084 +#endif /* CONFIG_KLIPS_DEBUG */
33085 + remove_proc_entry("ipsec_eroute", PROC_NET);
33086 + remove_proc_entry("ipsec_spi", PROC_NET);
33087 + remove_proc_entry("ipsec_spigrp", PROC_NET);
33088 + remove_proc_entry("ipsec_tncfg", PROC_NET);
33089 + remove_proc_entry("ipsec_version", PROC_NET);
33090 + remove_proc_entry("ipsec", PROC_NET);
33091 +#endif /* 2.4 kernel */
33092 +}
33093 +
33094 +/*
33095 + *
33096 + * Local variables:
33097 + * c-file-style: "linux"
33098 + * End:
33099 + *
33100 + */
33101 --- /dev/null Tue Mar 11 13:02:56 2003
33102 +++ linux/net/ipsec/ipsec_radij.c Mon Feb 9 13:51:03 2004
33103 @@ -0,0 +1,554 @@
33104 +/*
33105 + * Interface between the IPSEC code and the radix (radij) tree code
33106 + * Copyright (C) 1996, 1997 John Ioannidis.
33107 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
33108 + *
33109 + * This program is free software; you can redistribute it and/or modify it
33110 + * under the terms of the GNU General Public License as published by the
33111 + * Free Software Foundation; either version 2 of the License, or (at your
33112 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
33113 + *
33114 + * This program is distributed in the hope that it will be useful, but
33115 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
33116 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
33117 + * for more details.
33118 + *
33119 + */
33120 +
33121 +#ifndef AUTOCONF_INCLUDED
33122 +#include <linux/config.h>
33123 +#endif
33124 +#include <linux/version.h>
33125 +#include <linux/kernel.h> /* printk() */
33126 +
33127 +#include "openswan/ipsec_param.h"
33128 +
33129 +#ifdef MALLOC_SLAB
33130 +# include <linux/slab.h> /* kmalloc() */
33131 +#else /* MALLOC_SLAB */
33132 +# include <linux/malloc.h> /* kmalloc() */
33133 +#endif /* MALLOC_SLAB */
33134 +#include <linux/errno.h> /* error codes */
33135 +#include <linux/types.h> /* size_t */
33136 +#include <linux/interrupt.h> /* mark_bh */
33137 +
33138 +#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
33139 +#include <linux/etherdevice.h> /* eth_type_trans */
33140 +#include <linux/ip.h> /* struct iphdr */
33141 +#include <linux/skbuff.h>
33142 +#include <openswan.h>
33143 +#ifdef SPINLOCK
33144 +# ifdef SPINLOCK_23
33145 +# include <linux/spinlock.h> /* *lock* */
33146 +# else /* 23_SPINLOCK */
33147 +# include <asm/spinlock.h> /* *lock* */
33148 +# endif /* 23_SPINLOCK */
33149 +#endif /* SPINLOCK */
33150 +
33151 +#include <net/ip.h>
33152 +
33153 +#include "openswan/ipsec_eroute.h"
33154 +#include "openswan/ipsec_sa.h"
33155 +
33156 +#include "openswan/radij.h"
33157 +#include "openswan/ipsec_encap.h"
33158 +#include "openswan/radij.h"
33159 +#include "openswan/ipsec_encap.h"
33160 +#include "openswan/ipsec_radij.h"
33161 +#include "openswan/ipsec_tunnel.h" /* struct ipsecpriv */
33162 +#include "openswan/ipsec_xform.h"
33163 +
33164 +#include <openswan/pfkeyv2.h>
33165 +#include <openswan/pfkey.h>
33166 +
33167 +#include "openswan/ipsec_proto.h"
33168 +
33169 +struct radij_node_head *rnh = NULL;
33170 +#ifdef SPINLOCK
33171 +spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED;
33172 +#else /* SPINLOCK */
33173 +spinlock_t eroute_lock;
33174 +#endif /* SPINLOCK */
33175 +
33176 +int
33177 +ipsec_radijinit(void)
33178 +{
33179 + maj_keylen = sizeof (struct sockaddr_encap);
33180 +
33181 + rj_init();
33182 +
33183 + if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */
33184 + return -1;
33185 + return 0;
33186 +}
33187 +
33188 +int
33189 +ipsec_radijcleanup(void)
33190 +{
33191 + int error = 0;
33192 +
33193 + spin_lock_bh(&eroute_lock);
33194 +
33195 + error = radijcleanup();
33196 +
33197 + spin_unlock_bh(&eroute_lock);
33198 +
33199 + return error;
33200 +}
33201 +
33202 +int
33203 +ipsec_cleareroutes(void)
33204 +{
33205 + int error;
33206 +
33207 + spin_lock_bh(&eroute_lock);
33208 +
33209 + error = radijcleartree();
33210 +
33211 + spin_unlock_bh(&eroute_lock);
33212 +
33213 + return error;
33214 +}
33215 +
33216 +int
33217 +ipsec_breakroute(struct sockaddr_encap *eaddr,
33218 + struct sockaddr_encap *emask,
33219 + struct sk_buff **first,
33220 + struct sk_buff **last)
33221 +{
33222 + struct eroute *ro;
33223 + struct radij_node *rn;
33224 + int error;
33225 +#ifdef CONFIG_KLIPS_DEBUG
33226 +
33227 + if (debug_eroute) {
33228 + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33229 + subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
33230 + subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
33231 + KLIPS_PRINT(debug_eroute,
33232 + "klips_debug:ipsec_breakroute: "
33233 + "attempting to delete eroute for %s:%d->%s:%d %d\n",
33234 + buf1, ntohs(eaddr->sen_sport),
33235 + buf2, ntohs(eaddr->sen_dport), eaddr->sen_proto);
33236 + }
33237 +#endif /* CONFIG_KLIPS_DEBUG */
33238 +
33239 + spin_lock_bh(&eroute_lock);
33240 +
33241 + if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) {
33242 + spin_unlock_bh(&eroute_lock);
33243 + KLIPS_PRINT(debug_eroute,
33244 + "klips_debug:ipsec_breakroute: "
33245 + "node not found, eroute delete failed.\n");
33246 + return error;
33247 + }
33248 +
33249 + spin_unlock_bh(&eroute_lock);
33250 +
33251 + ro = (struct eroute *)rn;
33252 +
33253 + KLIPS_PRINT(debug_eroute,
33254 + "klips_debug:ipsec_breakroute: "
33255 + "deleted eroute=0p%p, ident=0p%p->0p%p, first=0p%p, last=0p%p\n",
33256 + ro,
33257 + ro->er_ident_s.data,
33258 + ro->er_ident_d.data,
33259 + ro->er_first,
33260 + ro->er_last);
33261 +
33262 + if (ro->er_ident_s.data != NULL) {
33263 + kfree(ro->er_ident_s.data);
33264 + }
33265 + if (ro->er_ident_d.data != NULL) {
33266 + kfree(ro->er_ident_d.data);
33267 + }
33268 + if (ro->er_first != NULL) {
33269 +#if 0
33270 + struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_first->dev->priv))->mystats);
33271 + stats->tx_dropped--;
33272 +#endif
33273 + *first = ro->er_first;
33274 + }
33275 + if (ro->er_last != NULL) {
33276 +#if 0
33277 + struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_last->dev->priv))->mystats);
33278 + stats->tx_dropped--;
33279 +#endif
33280 + *last = ro->er_last;
33281 + }
33282 +
33283 + if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT))
33284 + panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n");
33285 + memset((caddr_t)rn, 0, sizeof (struct eroute));
33286 + kfree(rn);
33287 +
33288 + return 0;
33289 +}
33290 +
33291 +int
33292 +ipsec_makeroute(struct sockaddr_encap *eaddr,
33293 + struct sockaddr_encap *emask,
33294 + ip_said said,
33295 + uint32_t pid,
33296 + struct sk_buff *skb,
33297 + struct ident *ident_s,
33298 + struct ident *ident_d)
33299 +{
33300 + struct eroute *retrt;
33301 + int error;
33302 + char sa[SATOT_BUF];
33303 + size_t sa_len;
33304 +
33305 +#ifdef CONFIG_KLIPS_DEBUG
33306 +
33307 + if (debug_eroute) {
33308 +
33309 + {
33310 + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33311 +
33312 + subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
33313 + subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
33314 + sa_len = satot(&said, 0, sa, sizeof(sa));
33315 + KLIPS_PRINT(debug_eroute,
33316 + "klips_debug:ipsec_makeroute: "
33317 + "attempting to allocate %lu bytes to insert eroute for %s->%s, SA: %s, PID:%d, skb=0p%p, ident:%s->%s\n",
33318 + (unsigned long) sizeof(struct eroute),
33319 + buf1,
33320 + buf2,
33321 + sa_len ? sa : " (error)",
33322 + pid,
33323 + skb,
33324 + (ident_s ? (ident_s->data ? ident_s->data : "NULL") : "NULL"),
33325 + (ident_d ? (ident_d->data ? ident_d->data : "NULL") : "NULL"));
33326 + }
33327 + {
33328 + char buf1[sizeof(struct sockaddr_encap)*2 + 1],
33329 + buf2[sizeof(struct sockaddr_encap)*2 + 1];
33330 + int i;
33331 + unsigned char *b1 = buf1,
33332 + *b2 = buf2,
33333 + *ea = (unsigned char *)eaddr,
33334 + *em = (unsigned char *)emask;
33335 +
33336 +
33337 + for (i=0; i<sizeof(struct sockaddr_encap); i++) {
33338 + sprintf(b1, "%02x", ea[i]);
33339 + sprintf(b2, "%02x", em[i]);
33340 + b1+=2;
33341 + b2+=2;
33342 + }
33343 + KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_makeroute: %s / %s \n", buf1, buf2);
33344 + }
33345 +
33346 + }
33347 +#endif /* CONFIG_KLIPS_DEBUG */
33348 +
33349 + retrt = (struct eroute *)kmalloc(sizeof (struct eroute), GFP_ATOMIC);
33350 + if (retrt == NULL) {
33351 + printk("klips_error:ipsec_makeroute: "
33352 + "not able to allocate kernel memory");
33353 + return -ENOMEM;
33354 + }
33355 + memset((caddr_t)retrt, 0, sizeof (struct eroute));
33356 +
33357 + retrt->er_eaddr = *eaddr;
33358 + retrt->er_emask = *emask;
33359 + retrt->er_said = said;
33360 + retrt->er_pid = pid;
33361 + retrt->er_count = 0;
33362 + retrt->er_lasttime = jiffies/HZ;
33363 +
33364 + {
33365 + /* this is because gcc 3. doesn't like cast's as lvalues */
33366 + struct rjtentry *rje = (struct rjtentry *)&(retrt->er_rjt);
33367 + caddr_t er = (caddr_t)&(retrt->er_eaddr);
33368 +
33369 + rje->rd_nodes->rj_key= er;
33370 + }
33371 +
33372 + if (ident_s && ident_s->type != SADB_IDENTTYPE_RESERVED) {
33373 + int data_len = ident_s->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
33374 +
33375 + retrt->er_ident_s.type = ident_s->type;
33376 + retrt->er_ident_s.id = ident_s->id;
33377 + retrt->er_ident_s.len = ident_s->len;
33378 + if(data_len) {
33379 + KLIPS_PRINT(debug_eroute,
33380 + "klips_debug:ipsec_makeroute: "
33381 + "attempting to allocate %u bytes for ident_s.\n",
33382 + data_len);
33383 + if(!(retrt->er_ident_s.data = kmalloc(data_len, GFP_KERNEL))) {
33384 + kfree(retrt);
33385 + printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
33386 + return ENOMEM;
33387 + }
33388 + memcpy(retrt->er_ident_s.data, ident_s->data, data_len);
33389 + } else {
33390 + retrt->er_ident_s.data = NULL;
33391 + }
33392 + }
33393 +
33394 + if (ident_d && ident_d->type != SADB_IDENTTYPE_RESERVED) {
33395 + int data_len = ident_d->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
33396 +
33397 + retrt->er_ident_d.type = ident_d->type;
33398 + retrt->er_ident_d.id = ident_d->id;
33399 + retrt->er_ident_d.len = ident_d->len;
33400 + if(data_len) {
33401 + KLIPS_PRINT(debug_eroute,
33402 + "klips_debug:ipsec_makeroute: "
33403 + "attempting to allocate %u bytes for ident_d.\n",
33404 + data_len);
33405 + if(!(retrt->er_ident_d.data = kmalloc(data_len, GFP_KERNEL))) {
33406 + if (retrt->er_ident_s.data)
33407 + kfree(retrt->er_ident_s.data);
33408 + kfree(retrt);
33409 + printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
33410 + return ENOMEM;
33411 + }
33412 + memcpy(retrt->er_ident_d.data, ident_d->data, data_len);
33413 + } else {
33414 + retrt->er_ident_d.data = NULL;
33415 + }
33416 + }
33417 + retrt->er_first = skb;
33418 + retrt->er_last = NULL;
33419 +
33420 + KLIPS_PRINT(debug_eroute,
33421 + "klips_debug:ipsec_makeroute: "
33422 + "calling rj_addroute now\n");
33423 +
33424 + spin_lock_bh(&eroute_lock);
33425 +
33426 + error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask),
33427 + rnh, retrt->er_rjt.rd_nodes);
33428 +
33429 + spin_unlock_bh(&eroute_lock);
33430 +
33431 + if(error) {
33432 + sa_len = KLIPS_SATOT(debug_eroute, &said, 0, sa, sizeof(sa));
33433 + KLIPS_PRINT(debug_eroute,
33434 + "klips_debug:ipsec_makeroute: "
33435 + "rj_addroute not able to insert eroute for SA:%s (error:%d)\n",
33436 + sa_len ? sa : " (error)", error);
33437 + if (retrt->er_ident_s.data)
33438 + kfree(retrt->er_ident_s.data);
33439 + if (retrt->er_ident_d.data)
33440 + kfree(retrt->er_ident_d.data);
33441 +
33442 + kfree(retrt);
33443 +
33444 + return error;
33445 + }
33446 +
33447 +#ifdef CONFIG_KLIPS_DEBUG
33448 + if (debug_eroute) {
33449 + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33450 +/*
33451 + subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
33452 + subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
33453 +*/
33454 + subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1));
33455 + subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2));
33456 + sa_len = satot(&retrt->er_said, 0, sa, sizeof(sa));
33457 +
33458 + KLIPS_PRINT(debug_eroute,
33459 + "klips_debug:ipsec_makeroute: "
33460 + "pid=%05d "
33461 + "count=%10d "
33462 + "lasttime=%6d "
33463 + "%-18s -> %-18s => %s\n",
33464 + retrt->er_pid,
33465 + retrt->er_count,
33466 + (int)(jiffies/HZ - retrt->er_lasttime),
33467 + buf1,
33468 + buf2,
33469 + sa_len ? sa : " (error)");
33470 + }
33471 +#endif /* CONFIG_KLIPS_DEBUG */
33472 + KLIPS_PRINT(debug_eroute,
33473 + "klips_debug:ipsec_makeroute: "
33474 + "succeeded.\n");
33475 + return 0;
33476 +}
33477 +
33478 +struct eroute *
33479 +ipsec_findroute(struct sockaddr_encap *eaddr)
33480 +{
33481 + struct radij_node *rn;
33482 +#ifdef CONFIG_KLIPS_DEBUG
33483 + char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF];
33484 +
33485 + if (debug_radij & DB_RJ_FINDROUTE) {
33486 + addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1));
33487 + addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2));
33488 + KLIPS_PRINT(debug_eroute,
33489 + "klips_debug:ipsec_findroute: "
33490 + "%s:%d->%s:%d %d\n",
33491 + buf1, ntohs(eaddr->sen_sport),
33492 + buf2, ntohs(eaddr->sen_dport),
33493 + eaddr->sen_proto);
33494 + }
33495 +#endif /* CONFIG_KLIPS_DEBUG */
33496 + rn = rj_match((caddr_t)eaddr, rnh);
33497 + if(rn) {
33498 + KLIPS_PRINT(debug_eroute && sysctl_ipsec_debug_verbose,
33499 + "klips_debug:ipsec_findroute: "
33500 + "found, points to proto=%d, spi=%x, dst=%x.\n",
33501 + ((struct eroute*)rn)->er_said.proto,
33502 + ntohl(((struct eroute*)rn)->er_said.spi),
33503 + ntohl(((struct eroute*)rn)->er_said.dst.u.v4.sin_addr.s_addr));
33504 + }
33505 + return (struct eroute *)rn;
33506 +}
33507 +
33508 +#ifdef CONFIG_PROC_FS
33509 +/** ipsec_rj_walker_procprint: print one line of eroute table output.
33510 + *
33511 + * Theoretical BUG: if w->length is less than the length
33512 + * of some line we should produce, that line will never
33513 + * be finished. In effect, the "file" will stop part way
33514 + * through that line.
33515 + */
33516 +int
33517 +ipsec_rj_walker_procprint(struct radij_node *rn, void *w0)
33518 +{
33519 + struct eroute *ro = (struct eroute *)rn;
33520 + struct rjtentry *rd = (struct rjtentry *)rn;
33521 + struct wsbuf *w = (struct wsbuf *)w0;
33522 + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33523 + char buf3[16];
33524 + char sa[SATOT_BUF];
33525 + size_t sa_len, buf_len;
33526 + struct sockaddr_encap *key, *mask;
33527 +
33528 + KLIPS_PRINT(debug_radij,
33529 + "klips_debug:ipsec_rj_walker_procprint: "
33530 + "rn=0p%p, w0=0p%p\n",
33531 + rn,
33532 + w0);
33533 + if (rn->rj_b >= 0) {
33534 + return 0;
33535 + }
33536 +
33537 + key = rd_key(rd);
33538 + mask = rd_mask(rd);
33539 +
33540 + if (key == NULL || mask == NULL) {
33541 + return 0;
33542 + }
33543 +
33544 + buf_len = subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
33545 + if(key->sen_sport != 0) {
33546 + sprintf(buf1+buf_len-1, ":%d", ntohs(key->sen_sport));
33547 + }
33548 +
33549 + buf_len = subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
33550 + if(key->sen_dport != 0) {
33551 + sprintf(buf2+buf_len-1, ":%d", ntohs(key->sen_dport));
33552 + }
33553 +
33554 + buf3[0]='\0';
33555 + if(key->sen_proto != 0) {
33556 + sprintf(buf3, ":%d", key->sen_proto);
33557 + }
33558 +
33559 + sa_len = satot(&ro->er_said, 'x', sa, sizeof(sa));
33560 + w->len += ipsec_snprintf(w->buffer + w->len,
33561 + w->length - w->len,
33562 + "%-10d "
33563 + "%-18s -> %-18s => %s%s\n",
33564 + ro->er_count,
33565 + buf1,
33566 + buf2,
33567 + sa_len ? sa : " (error)",
33568 + buf3);
33569 +
33570 + {
33571 + /* snprintf can only fill the last character with NUL
33572 + * so the maximum useful character is w->length-1.
33573 + * However, if w->length == 0, we cannot go back.
33574 + * (w->length surely cannot be negative.)
33575 + */
33576 + int max_content = w->length > 0? w->length-1 : 0;
33577 +
33578 + if (w->len >= max_content) {
33579 + /* we've done all that can fit -- stop treewalking */
33580 + w->len = max_content; /* truncate crap */
33581 + return -ENOBUFS;
33582 + } else {
33583 + const off_t pos = w->begin + w->len; /* file position of end of what we've generated */
33584 +
33585 + if (pos <= w->offset) {
33586 + /* all is before first interesting character:
33587 + * discard, but note where we are.
33588 + */
33589 + w->len = 0;
33590 + w->begin = pos;
33591 + }
33592 + return 0;
33593 + }
33594 + }
33595 +}
33596 +#endif /* CONFIG_PROC_FS */
33597 +
33598 +int
33599 +ipsec_rj_walker_delete(struct radij_node *rn, void *w0)
33600 +{
33601 + struct eroute *ro;
33602 + struct rjtentry *rd = (struct rjtentry *)rn;
33603 + struct radij_node *rn2;
33604 + int error;
33605 + struct sockaddr_encap *key, *mask;
33606 +
33607 + key = rd_key(rd);
33608 + mask = rd_mask(rd);
33609 +
33610 + if(!key || !mask) {
33611 + return -ENODATA;
33612 + }
33613 +#ifdef CONFIG_KLIPS_DEBUG
33614 + if(debug_radij) {
33615 + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33616 + subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
33617 + subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
33618 + KLIPS_PRINT(debug_radij,
33619 + "klips_debug:ipsec_rj_walker_delete: "
33620 + "deleting: %s -> %s\n",
33621 + buf1,
33622 + buf2);
33623 + }
33624 +#endif /* CONFIG_KLIPS_DEBUG */
33625 +
33626 + if((error = rj_delete(key, mask, rnh, &rn2))) {
33627 + KLIPS_PRINT(debug_radij,
33628 + "klips_debug:ipsec_rj_walker_delete: "
33629 + "rj_delete failed with error=%d.\n", error);
33630 + return error;
33631 + }
33632 +
33633 + if(rn2 != rn) {
33634 + printk("klips_debug:ipsec_rj_walker_delete: "
33635 + "tried to delete a different node?!? This should never happen!\n");
33636 + }
33637 +
33638 + ro = (struct eroute *)rn;
33639 +
33640 + if (ro->er_ident_s.data)
33641 + kfree(ro->er_ident_s.data);
33642 + if (ro->er_ident_d.data)
33643 + kfree(ro->er_ident_d.data);
33644 +
33645 + memset((caddr_t)rn, 0, sizeof (struct eroute));
33646 + kfree(rn);
33647 +
33648 + return 0;
33649 +}
33650 +
33651 +/*
33652 + *
33653 + * Local Variables:
33654 + * c-file-style: "linux"
33655 + * End:
33656 + *
33657 + */
33658 --- /dev/null Tue Mar 11 13:02:56 2003
33659 +++ linux/net/ipsec/ipsec_rcv.c Mon Feb 9 13:51:03 2004
33660 @@ -0,0 +1,2124 @@
33661 +/*
33662 + * receive code
33663 + * Copyright (C) 1996, 1997 John Ioannidis.
33664 + * Copyright (C) 1998-2003 Richard Guy Briggs.
33665 + * Copyright (C) 2004-2007 Michael Richardson <mcr@xelerance.com>
33666 + * Copyright (C) 2007-2008 Paul Wouters <paul@xelerance.com>
33667 + *
33668 + * OCF/receive state machine written by
33669 + * David McCullough <dmccullough@cyberguard.com>
33670 + * Copyright (C) 2004-2005 Intel Corporation. All Rights Reserved.
33671 + *
33672 + * This program is free software; you can redistribute it and/or modify it
33673 + * under the terms of the GNU General Public License as published by the
33674 + * Free Software Foundation; either version 2 of the License, or (at your
33675 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
33676 + *
33677 + * This program is distributed in the hope that it will be useful, but
33678 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
33679 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
33680 + * for more details.
33681 + */
33682 +
33683 +#ifndef AUTOCONF_INCLUDED
33684 +#include <linux/config.h>
33685 +#endif
33686 +#include <linux/version.h>
33687 +
33688 +#define __NO_VERSION__
33689 +#include <linux/module.h>
33690 +#include <linux/kernel.h> /* printk() */
33691 +
33692 +#include "openswan/ipsec_param.h"
33693 +
33694 +#ifdef MALLOC_SLAB
33695 +# include <linux/slab.h> /* kmalloc() */
33696 +#else /* MALLOC_SLAB */
33697 +# include <linux/malloc.h> /* kmalloc() */
33698 +#endif /* MALLOC_SLAB */
33699 +#include <linux/errno.h> /* error codes */
33700 +#include <linux/types.h> /* size_t */
33701 +#include <linux/interrupt.h> /* mark_bh */
33702 +
33703 +#include <linux/netdevice.h> /* struct device, and other headers */
33704 +#include <linux/etherdevice.h> /* eth_type_trans */
33705 +#include <linux/ip.h> /* struct iphdr */
33706 +
33707 +#include <net/tcp.h>
33708 +#include <net/udp.h>
33709 +#include <net/xfrm.h>
33710 +#include <linux/skbuff.h>
33711 +#include <openswan.h>
33712 +
33713 +#ifdef SPINLOCK
33714 +# ifdef SPINLOCK_23
33715 +# include <linux/spinlock.h> /* *lock* */
33716 +# ifdef NEED_SPINLOCK_TYPES
33717 +# include <linux/spinlock_types.h>
33718 +# endif
33719 +# else /* SPINLOCK_23 */
33720 +# include <asm/spinlock.h> /* *lock* */
33721 +# endif /* SPINLOCK_23 */
33722 +#endif /* SPINLOCK */
33723 +
33724 +#include <net/ip.h>
33725 +
33726 +#include "openswan/ipsec_kern24.h"
33727 +#include "openswan/radij.h"
33728 +#include "openswan/ipsec_encap.h"
33729 +#include "openswan/ipsec_sa.h"
33730 +
33731 +#include "openswan/ipsec_radij.h"
33732 +#include "openswan/ipsec_xform.h"
33733 +#include "openswan/ipsec_tunnel.h"
33734 +#include "openswan/ipsec_mast.h"
33735 +#include "openswan/ipsec_rcv.h"
33736 +
33737 +#include "openswan/ipsec_auth.h"
33738 +
33739 +#include "openswan/ipsec_esp.h"
33740 +
33741 +#ifdef CONFIG_KLIPS_AH
33742 +#include "openswan/ipsec_ah.h"
33743 +#endif /* CONFIG_KLIPS_AH */
33744 +
33745 +#ifdef CONFIG_KLIPS_IPCOMP
33746 +#include "openswan/ipsec_ipcomp.h"
33747 +#endif /* CONFIG_KLIPS_COMP */
33748 +
33749 +#include <openswan/pfkeyv2.h>
33750 +#include <openswan/pfkey.h>
33751 +
33752 +#include "openswan/ipsec_proto.h"
33753 +#include "openswan/ipsec_alg.h"
33754 +#include "openswan/ipsec_kern24.h"
33755 +
33756 +#ifdef CONFIG_KLIPS_OCF
33757 +#include "ipsec_ocf.h"
33758 +#endif
33759 +
33760 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
33761 +#include <linux/udp.h>
33762 +#endif
33763 +
33764 +/* This is a private use protocol, and AT&T should be ashamed. They should have
33765 + * used protocol # 59, which is "no next header" instead of 0xFE.
33766 + */
33767 +#ifndef IPPROTO_ATT_HEARTBEAT
33768 +#define IPPROTO_ATT_HEARTBEAT 0xFE
33769 +#endif
33770 +
33771 +/* management of buffers */
33772 +static struct ipsec_rcv_state *ipsec_rcv_state_new (void);
33773 +static void ipsec_rcv_state_delete (struct ipsec_rcv_state *irs);
33774 +
33775 +/*
33776 + * Check-replay-window routine, adapted from the original
33777 + * by J. Hughes, from draft-ietf-ipsec-esp-des-md5-03.txt
33778 + *
33779 + * This is a routine that implements a 64 packet window. This is intend-
33780 + * ed on being an implementation sample.
33781 + */
33782 +
33783 +DEBUG_NO_STATIC int
33784 +ipsec_checkreplaywindow(struct ipsec_sa*ipsp, __u32 seq)
33785 +{
33786 + __u32 diff;
33787 +
33788 + if (ipsp->ips_replaywin == 0) /* replay shut off */
33789 + return 1;
33790 + if (seq == 0)
33791 + return 0; /* first == 0 or wrapped */
33792 +
33793 + /* new larger sequence number */
33794 + if (seq > ipsp->ips_replaywin_lastseq) {
33795 + return 1; /* larger is good */
33796 + }
33797 + diff = ipsp->ips_replaywin_lastseq - seq;
33798 +
33799 + /* too old or wrapped */ /* if wrapped, kill off SA? */
33800 + if (diff >= ipsp->ips_replaywin) {
33801 + return 0;
33802 + }
33803 + /* this packet already seen */
33804 + if (ipsp->ips_replaywin_bitmap & (1 << diff))
33805 + return 0;
33806 + return 1; /* out of order but good */
33807 +}
33808 +
33809 +DEBUG_NO_STATIC int
33810 +ipsec_updatereplaywindow(struct ipsec_sa*ipsp, __u32 seq)
33811 +{
33812 + __u32 diff;
33813 +
33814 + if (ipsp->ips_replaywin == 0) /* replay shut off */
33815 + return 1;
33816 + if (seq == 0)
33817 + return 0; /* first == 0 or wrapped */
33818 +
33819 + /* new larger sequence number */
33820 + if (seq > ipsp->ips_replaywin_lastseq) {
33821 + diff = seq - ipsp->ips_replaywin_lastseq;
33822 +
33823 + /* In win, set bit for this pkt */
33824 + if (diff < ipsp->ips_replaywin)
33825 + ipsp->ips_replaywin_bitmap =
33826 + (ipsp->ips_replaywin_bitmap << diff) | 1;
33827 + else
33828 + /* This packet has way larger seq num */
33829 + ipsp->ips_replaywin_bitmap = 1;
33830 +
33831 + if(seq - ipsp->ips_replaywin_lastseq - 1 > ipsp->ips_replaywin_maxdiff) {
33832 + ipsp->ips_replaywin_maxdiff = seq - ipsp->ips_replaywin_lastseq - 1;
33833 + }
33834 + ipsp->ips_replaywin_lastseq = seq;
33835 + return 1; /* larger is good */
33836 + }
33837 + diff = ipsp->ips_replaywin_lastseq - seq;
33838 +
33839 + /* too old or wrapped */ /* if wrapped, kill off SA? */
33840 + if (diff >= ipsp->ips_replaywin) {
33841 +/*
33842 + if(seq < 0.25*max && ipsp->ips_replaywin_lastseq > 0.75*max) {
33843 + ipsec_sa_delchain(ipsp);
33844 + }
33845 +*/
33846 + return 0;
33847 + }
33848 + /* this packet already seen */
33849 + if (ipsp->ips_replaywin_bitmap & (1 << diff))
33850 + return 0;
33851 + ipsp->ips_replaywin_bitmap |= (1 << diff); /* mark as seen */
33852 + return 1; /* out of order but good */
33853 +}
33854 +
33855 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
33856 +struct auth_alg ipsec_rcv_md5[]={
33857 + {osMD5Init, osMD5Update, osMD5Final, AHMD596_ALEN}
33858 +};
33859 +
33860 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
33861 +
33862 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
33863 +struct auth_alg ipsec_rcv_sha1[]={
33864 + {SHA1Init, SHA1Update, SHA1Final, AHSHA196_ALEN}
33865 +};
33866 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
33867 +
33868 +
33869 +static inline void ipsec_rcv_redodebug(struct ipsec_rcv_state *irs)
33870 +{
33871 + struct iphdr * ipp = irs->ipp;
33872 + struct in_addr ipsaddr, ipdaddr;
33873 +
33874 + ipsaddr.s_addr = ipp->saddr;
33875 + addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
33876 + ipdaddr.s_addr = ipp->daddr;
33877 + addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
33878 +}
33879 +
33880 +
33881 +#ifdef CONFIG_KLIPS_DEBUG
33882 +DEBUG_NO_STATIC char *
33883 +ipsec_rcv_err(int err)
33884 +{
33885 + static char tmp[32];
33886 + switch ((int) err) {
33887 + case IPSEC_RCV_PENDING: return("IPSEC_RCV_PENDING");
33888 + case IPSEC_RCV_LASTPROTO: return("IPSEC_RCV_LASTPROTO");
33889 + case IPSEC_RCV_OK: return("IPSEC_RCV_OK");
33890 + case IPSEC_RCV_BADPROTO: return("IPSEC_RCV_BADPROTO");
33891 + case IPSEC_RCV_BADLEN: return("IPSEC_RCV_BADLEN");
33892 + case IPSEC_RCV_ESP_BADALG: return("IPSEC_RCV_ESP_BADALG");
33893 + case IPSEC_RCV_3DES_BADBLOCKING:return("IPSEC_RCV_3DES_BADBLOCKING");
33894 + case IPSEC_RCV_ESP_DECAPFAIL: return("IPSEC_RCV_ESP_DECAPFAIL");
33895 + case IPSEC_RCV_DECAPFAIL: return("IPSEC_RCV_DECAPFAIL");
33896 + case IPSEC_RCV_SAIDNOTFOUND: return("IPSEC_RCV_SAIDNOTFOUND");
33897 + case IPSEC_RCV_IPCOMPALONE: return("IPSEC_RCV_IPCOMPALONE");
33898 + case IPSEC_RCV_IPCOMPFAILED: return("IPSEC_RCV_IPCOMPFAILED");
33899 + case IPSEC_RCV_SAIDNOTLIVE: return("IPSEC_RCV_SAIDNOTLIVE");
33900 + case IPSEC_RCV_FAILEDINBOUND: return("IPSEC_RCV_FAILEDINBOUND");
33901 + case IPSEC_RCV_LIFETIMEFAILED: return("IPSEC_RCV_LIFETIMEFAILED");
33902 + case IPSEC_RCV_BADAUTH: return("IPSEC_RCV_BADAUTH");
33903 + case IPSEC_RCV_REPLAYFAILED: return("IPSEC_RCV_REPLAYFAILED");
33904 + case IPSEC_RCV_AUTHFAILED: return("IPSEC_RCV_AUTHFAILED");
33905 + case IPSEC_RCV_REPLAYROLLED: return("IPSEC_RCV_REPLAYROLLED");
33906 + case IPSEC_RCV_BAD_DECRYPT: return("IPSEC_RCV_BAD_DECRYPT");
33907 + case IPSEC_RCV_REALLYBAD: return("IPSEC_RCV_REALLYBAD");
33908 + }
33909 + snprintf(tmp, sizeof(tmp), "%d", err);
33910 + return tmp;
33911 +}
33912 +#endif
33913 +
33914 +/*
33915 + * here is a state machine to handle receiving ipsec packets.
33916 + * basically we keep getting re-entered until processing is
33917 + * complete. For the simple case we step down the states and finish.
33918 + * each state is ideally some logical part of the process. If a state
33919 + * can pend (ie., require async processing to complete), then this
33920 + * should be the part of last action before it returns IPSEC_RCV_PENDING
33921 + *
33922 + * Any particular action may alter the next_state in irs to move us to
33923 + * a state other than the preferred "next_state", but this is the
33924 + * exception and is highlighted when it is done.
33925 + *
33926 + * prototypes for state action
33927 + */
33928 +
33929 +static enum ipsec_rcv_value ipsec_rcv_init(struct ipsec_rcv_state *irs);
33930 +static enum ipsec_rcv_value ipsec_rcv_decap_init(struct ipsec_rcv_state *irs);
33931 +static enum ipsec_rcv_value ipsec_rcv_decap_lookup(struct ipsec_rcv_state *irs);
33932 +static enum ipsec_rcv_value ipsec_rcv_auth_init(struct ipsec_rcv_state *irs);
33933 +static enum ipsec_rcv_value ipsec_rcv_auth_decap(struct ipsec_rcv_state *irs);
33934 +static enum ipsec_rcv_value ipsec_rcv_auth_calc(struct ipsec_rcv_state *irs);
33935 +static enum ipsec_rcv_value ipsec_rcv_auth_chk(struct ipsec_rcv_state *irs);
33936 +static enum ipsec_rcv_value ipsec_rcv_decrypt(struct ipsec_rcv_state *irs);
33937 +static enum ipsec_rcv_value ipsec_rcv_decap_cont(struct ipsec_rcv_state *irs);
33938 +static enum ipsec_rcv_value ipsec_rcv_cleanup(struct ipsec_rcv_state *irs);
33939 +static enum ipsec_rcv_value ipsec_rcv_complete(struct ipsec_rcv_state *irs);
33940 +
33941 +/*
33942 + * the state table and each action
33943 + */
33944 +
33945 +struct {
33946 + enum ipsec_rcv_value (*action)(struct ipsec_rcv_state *irs);
33947 + int next_state;
33948 +} rcv_state_table[] = {
33949 + [IPSEC_RSM_INIT] = {ipsec_rcv_init, IPSEC_RSM_DECAP_INIT },
33950 + [IPSEC_RSM_DECAP_INIT] = {ipsec_rcv_decap_init, IPSEC_RSM_DECAP_LOOKUP },
33951 + [IPSEC_RSM_DECAP_LOOKUP] = {ipsec_rcv_decap_lookup,IPSEC_RSM_AUTH_INIT },
33952 + [IPSEC_RSM_AUTH_INIT] = {ipsec_rcv_auth_init, IPSEC_RSM_AUTH_DECAP },
33953 + [IPSEC_RSM_AUTH_DECAP] = {ipsec_rcv_auth_decap, IPSEC_RSM_AUTH_CALC },
33954 + [IPSEC_RSM_AUTH_CALC] = {ipsec_rcv_auth_calc, IPSEC_RSM_AUTH_CHK },
33955 + [IPSEC_RSM_AUTH_CHK] = {ipsec_rcv_auth_chk, IPSEC_RSM_DECRYPT },
33956 + [IPSEC_RSM_DECRYPT] = {ipsec_rcv_decrypt, IPSEC_RSM_DECAP_CONT },
33957 + [IPSEC_RSM_DECAP_CONT] = {ipsec_rcv_decap_cont, IPSEC_RSM_CLEANUP },
33958 + [IPSEC_RSM_CLEANUP] = {ipsec_rcv_cleanup, IPSEC_RSM_COMPLETE },
33959 + [IPSEC_RSM_COMPLETE] = {ipsec_rcv_complete, IPSEC_RSM_DONE },
33960 +
33961 + [IPSEC_RSM_DONE] = {NULL, IPSEC_RSM_DONE},
33962 +};
33963 +
33964 +
33965 +
33966 +struct sk_buff *ipsec_rcv_unclone(struct sk_buff *skb,
33967 + struct ipsec_rcv_state *irs)
33968 +{
33969 + /* if skb was cloned (most likely due to a packet sniffer such as
33970 + tcpdump being momentarily attached to the interface), make
33971 + a copy of our own to modify */
33972 + if(skb_cloned(skb)) {
33973 + /* include any mac header while copying.. */
33974 + if(skb_headroom(skb) < irs->hard_header_len) {
33975 + printk(KERN_WARNING "klips_error:ipsec_rcv: "
33976 + "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
33977 + irs->hard_header_len,
33978 + skb_headroom(skb));
33979 + goto rcvleave;
33980 + }
33981 + skb_push(skb, irs->hard_header_len);
33982 + if
33983 +#ifdef SKB_COW_NEW
33984 + (skb_cow(skb, skb_headroom(skb)) != 0)
33985 +#else /* SKB_COW_NEW */
33986 + ((skb = skb_cow(skb, skb_headroom(skb))) == NULL)
33987 +#endif /* SKB_COW_NEW */
33988 + {
33989 + goto rcvleave;
33990 + }
33991 + if(skb->len < irs->hard_header_len) {
33992 + printk(KERN_WARNING "klips_error:ipsec_rcv: "
33993 + "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
33994 + irs->hard_header_len,
33995 + skb->len);
33996 + goto rcvleave;
33997 + }
33998 + skb_pull(skb, irs->hard_header_len);
33999 + }
34000 + return skb;
34001 +
34002 +rcvleave:
34003 + ipsec_kfree_skb(skb);
34004 + return NULL;
34005 +}
34006 +
34007 +
34008 +
34009 +
34010 +#if !defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
34011 +/*
34012 + * decapsulate a UDP encapsulated ESP packet
34013 + */
34014 +struct sk_buff *ipsec_rcv_natt_decap(struct sk_buff *skb
34015 + , struct ipsec_rcv_state *irs
34016 + , int *udp_decap_ret_p)
34017 +{
34018 + *udp_decap_ret_p = 0;
34019 + if (skb->sk && ip_hdr(skb) && ip_hdr(skb)->protocol==IPPROTO_UDP) {
34020 + /**
34021 + * Packet comes from udp_queue_rcv_skb so it is already defrag,
34022 + * checksum verified, ... (ie safe to use)
34023 + *
34024 + * If the packet is not for us, return -1 and udp_queue_rcv_skb
34025 + * will continue to handle it (do not kfree skb !!).
34026 + */
34027 +
34028 +#ifndef UDP_OPT_IN_SOCK
34029 + struct udp_opt {
34030 + __u32 esp_in_udp;
34031 + };
34032 + struct udp_opt *tp = (struct udp_opt *)&(skb->sk->tp_pinfo.af_tcp);
34033 +#else
34034 + struct udp_opt *tp = &(skb->sk->tp_pinfo.af_udp);
34035 +#endif
34036 +
34037 + struct iphdr *ip = ip_hdr(skb);
34038 + struct udphdr *udp = (struct udphdr *)((__u32 *)ip+ip->ihl);
34039 + __u8 *udpdata = (__u8 *)udp + sizeof(struct udphdr);
34040 + __u32 *udpdata32 = (__u32 *)udpdata;
34041 +
34042 + irs->natt_sport = ntohs(udp->source);
34043 + irs->natt_dport = ntohs(udp->dest);
34044 +
34045 + KLIPS_PRINT(debug_rcv,
34046 + "klips_debug:ipsec_rcv: "
34047 + "suspected ESPinUDP packet (NAT-Traversal) [%d].\n",
34048 + tp->esp_in_udp);
34049 + KLIPS_IP_PRINT(debug_rcv, ip);
34050 +
34051 + if (udpdata < skb->tail) {
34052 + unsigned int len = skb->tail - udpdata;
34053 + if ((len==1) && (udpdata[0]==0xff)) {
34054 + KLIPS_PRINT(debug_rcv,
34055 + "klips_debug:ipsec_rcv: "
34056 + /* not IPv6 compliant message */
34057 + "NAT-keepalive from %d.%d.%d.%d.\n", NIPQUAD(ip->saddr));
34058 + *udp_decap_ret_p = 0;
34059 + return NULL;
34060 + }
34061 + else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_IKE) &&
34062 + (len > (2*sizeof(__u32) + sizeof(struct esphdr))) &&
34063 + (udpdata32[0]==0) && (udpdata32[1]==0) ) {
34064 + /* ESP Packet with Non-IKE header */
34065 + KLIPS_PRINT(debug_rcv,
34066 + "klips_debug:ipsec_rcv: "
34067 + "ESPinUDP pkt with Non-IKE - spi=0x%x\n",
34068 + ntohl(udpdata32[2]));
34069 + irs->natt_type = ESPINUDP_WITH_NON_IKE;
34070 + irs->natt_len = sizeof(struct udphdr)+(2*sizeof(__u32));
34071 + }
34072 + else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_ESP) &&
34073 + (len > sizeof(struct esphdr)) &&
34074 + (udpdata32[0]!=0) ) {
34075 + /* ESP Packet without Non-ESP header */
34076 + irs->natt_type = ESPINUDP_WITH_NON_ESP;
34077 + irs->natt_len = sizeof(struct udphdr);
34078 + KLIPS_PRINT(debug_rcv,
34079 + "klips_debug:ipsec_rcv: "
34080 + "ESPinUDP pkt without Non-ESP - spi=0x%x\n",
34081 + ntohl(udpdata32[0]));
34082 + }
34083 + else {
34084 + KLIPS_PRINT(debug_rcv,
34085 + "klips_debug:ipsec_rcv: "
34086 + "IKE packet - not handled here\n");
34087 + *udp_decap_ret_p = -1;
34088 + return NULL;
34089 + }
34090 + }
34091 + else {
34092 + return NULL;
34093 + }
34094 + }
34095 + return skb;
34096 +}
34097 +#endif
34098 +
34099 +#ifdef HAVE_IPSEC_SAREF
34100 +void ip_cmsg_recv_ipsec(struct msghdr *msg, struct sk_buff *skb)
34101 +{
34102 + struct ipsec_sa *sa1;
34103 + struct sec_path *sp;
34104 + xfrm_sec_unique_t refs[2];
34105 +
34106 + sp = skb->sp;
34107 +
34108 + if(sp==NULL) return;
34109 +
34110 + KLIPS_PRINT(debug_rcv, "retrieving saref=%u from skb=%p\n",
34111 + sp->ref, skb);
34112 +
34113 + sa1 = ipsec_sa_getbyref(sp->ref);
34114 + if(sa1) {
34115 + refs[1]= sa1->ips_refhim;
34116 + }
34117 + refs[0]=sp->ref;
34118 +
34119 + put_cmsg(msg, SOL_IP, IP_IPSEC_REFINFO,
34120 + sizeof(xfrm_sec_unique_t)*2, &refs);
34121 +}
34122 +#endif
34123 +
34124 +
34125 +void ipsec_rcv_setoutif(struct ipsec_rcv_state *irs)
34126 +{
34127 + struct sk_buff *skb = irs->skb;
34128 +
34129 + if(skb!=NULL && irs->ipsp->ips_out) {
34130 + if(skb->dev != irs->ipsp->ips_out) {
34131 + KLIPS_PRINT(debug_rcv,
34132 + "changing originating interface from %s to %s\n",
34133 + skb->dev->name,
34134 + irs->ipsp->ips_out->name);
34135 + }
34136 + skb->dev = irs->ipsp->ips_out;
34137 +
34138 + if(skb->dev && skb->dev->get_stats) {
34139 + struct net_device_stats *stats = skb->dev->get_stats(skb->dev);
34140 + irs->stats = stats;
34141 + }
34142 + }
34143 +}
34144 +
34145 +static enum ipsec_rcv_value
34146 +ipsec_rcv_decap_ipip(struct ipsec_rcv_state *irs)
34147 +{
34148 + struct ipsec_sa *ipsp = NULL;
34149 + struct ipsec_sa* ipsnext = NULL;
34150 + struct iphdr *ipp;
34151 + struct sk_buff *skb;
34152 + enum ipsec_rcv_value result = IPSEC_RCV_DECAPFAIL;
34153 +
34154 + ipp = irs->ipp;
34155 + ipsp = irs->ipsp;
34156 + skb = irs->skb;
34157 + irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa));
34158 + if((ipp->protocol != IPPROTO_IPIP) &&
34159 + (ipp->protocol != IPPROTO_ATT_HEARTBEAT)) { /* AT&T heartbeats to SIG/GIG */
34160 + KLIPS_PRINT(debug_rcv,
34161 + "klips_debug:ipsec_rcv: "
34162 + "SA:%s, Hey! How did this get through? Dropped.\n",
34163 + irs->sa_len ? irs->sa : " (error)");
34164 + if(irs->stats) {
34165 + irs->stats->rx_dropped++;
34166 + }
34167 + goto rcvleave;
34168 + }
34169 + if(sysctl_ipsec_inbound_policy_check) {
34170 + struct sockaddr_in *psin = (struct sockaddr_in*)(ipsp->ips_addr_s);
34171 + if((ipsnext = ipsp->ips_next)) {
34172 + char sa2[SATOT_BUF];
34173 + size_t sa_len2;
34174 + sa_len2 = satot(&ipsnext->ips_said, 0, sa2, sizeof(sa2));
34175 + KLIPS_PRINT(debug_rcv,
34176 + "klips_debug:ipsec_rcv: "
34177 + "unexpected SA:%s after IPIP SA:%s\n",
34178 + sa_len2 ? sa2 : " (error)",
34179 + irs->sa_len ? irs->sa : " (error)");
34180 + if(irs->stats) {
34181 + irs->stats->rx_dropped++;
34182 + }
34183 + goto rcvleave;
34184 + }
34185 + if(ipp->saddr != psin->sin_addr.s_addr) {
34186 + KLIPS_PRINT(debug_rcv,
34187 + "klips_debug:ipsec_rcv: "
34188 + "SA:%s, src=%s(%08x) does match expected 0x%08x.\n",
34189 + irs->sa_len ? irs->sa : " (error)",
34190 + irs->ipsaddr_txt,
34191 + ipp->saddr, psin->sin_addr.s_addr);
34192 + if(irs->stats) {
34193 + irs->stats->rx_dropped++;
34194 + }
34195 + goto rcvleave;
34196 + }
34197 + }
34198 +
34199 + ipsec_rcv_setoutif(irs);
34200 +
34201 + if(ipp->protocol == IPPROTO_IPIP) /* added to support AT&T heartbeats to SIG/GIG */
34202 + {
34203 + /*
34204 + * XXX this needs to be locked from when it was first looked
34205 + * up in the decapsulation loop. Perhaps it is better to put
34206 + * the IPIP decap inside the loop.
34207 + */
34208 + ipsp->ips_life.ipl_bytes.ipl_count += skb->len;
34209 + ipsp->ips_life.ipl_bytes.ipl_last = skb->len;
34210 +
34211 + if(!ipsp->ips_life.ipl_usetime.ipl_count) {
34212 + ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
34213 + }
34214 + ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
34215 + ipsp->ips_life.ipl_packets.ipl_count += 1;
34216 +
34217 + if(skb->len < irs->iphlen) {
34218 + printk(KERN_WARNING "klips_debug:ipsec_rcv: "
34219 + "tried to skb_pull iphlen=%d, %d available. This should never happen, please report.\n",
34220 + irs->iphlen,
34221 + (int)(skb->len));
34222 +
34223 + goto rcvleave;
34224 + }
34225 +
34226 + /*
34227 + * we need to pull up by size of IP header,
34228 + * options, but also by any UDP/ESP encap there might
34229 + * have been, and this deals with all cases.
34230 + */
34231 + skb_pull(skb, (skb_transport_header(skb) - skb_network_header(skb)));
34232 +
34233 + /* new L3 header is where L4 payload was */
34234 + skb_set_network_header(skb, ipsec_skb_offset(skb, skb_transport_header(skb)));
34235 +
34236 + /* now setup new L4 payload location */
34237 + ipp = (struct iphdr *)skb_network_header(skb);
34238 + skb_set_transport_header(skb, ipsec_skb_offset(skb, skb_network_header(skb) + (ipp->ihl << 2)));
34239 +
34240 +
34241 + /* remove any saved options that we might have,
34242 + * since we have a new IP header.
34243 + */
34244 + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
34245 +
34246 +#if 0
34247 + KLIPS_PRINT(debug_rcv, "csum: %d\n", ip_fast_csum((u8 *)ipp, ipp->ihl));
34248 +#endif
34249 +
34250 + /* re-do any strings for debugging */
34251 + irs->ipp = ipp;
34252 + ipsec_rcv_redodebug(irs);
34253 +
34254 + skb->protocol = htons(ETH_P_IP);
34255 + skb->ip_summed = 0;
34256 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
34257 + "klips_debug:ipsec_rcv: "
34258 + "IPIP tunnel stripped.\n");
34259 + KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
34260 + }
34261 +
34262 + if(sysctl_ipsec_inbound_policy_check
34263 + /*
34264 + Note: "xor" (^) logically replaces "not equal"
34265 + (!=) and "bitwise or" (|) logically replaces
34266 + "boolean or" (||). This is done to speed up
34267 + execution by doing only bitwise operations and
34268 + no branch operations
34269 + */
34270 + && (((ipp->saddr & ipsp->ips_mask_s.u.v4.sin_addr.s_addr)
34271 + ^ ipsp->ips_flow_s.u.v4.sin_addr.s_addr)
34272 + | ((ipp->daddr & ipsp->ips_mask_d.u.v4.sin_addr.s_addr)
34273 + ^ ipsp->ips_flow_d.u.v4.sin_addr.s_addr)) )
34274 + {
34275 + char sflow_txt[SUBNETTOA_BUF], dflow_txt[SUBNETTOA_BUF];
34276 +
34277 + subnettoa(ipsp->ips_flow_s.u.v4.sin_addr,
34278 + ipsp->ips_mask_s.u.v4.sin_addr,
34279 + 0, sflow_txt, sizeof(sflow_txt));
34280 + subnettoa(ipsp->ips_flow_d.u.v4.sin_addr,
34281 + ipsp->ips_mask_d.u.v4.sin_addr,
34282 + 0, dflow_txt, sizeof(dflow_txt));
34283 + KLIPS_PRINT(debug_rcv,
34284 + "klips_debug:ipsec_rcv: "
34285 + "SA:%s, inner tunnel policy [%s -> %s] does not agree with pkt contents [%s -> %s].\n",
34286 + irs->sa_len ? irs->sa : " (error)",
34287 + sflow_txt,
34288 + dflow_txt,
34289 + irs->ipsaddr_txt,
34290 + irs->ipdaddr_txt);
34291 + if(irs->stats) {
34292 + irs->stats->rx_dropped++;
34293 + }
34294 + goto rcvleave;
34295 + }
34296 +#ifdef CONFIG_NETFILTER
34297 + skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_TABLE_MASK))))
34298 + | IPsecSAref2NFmark(IPsecSA2SAref(ipsp));
34299 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
34300 + "klips_debug:ipsec_rcv: "
34301 + "IPIP SA sets skb->nfmark=0x%x.\n",
34302 + (unsigned)skb->nfmark);
34303 +#endif /* CONFIG_NETFILTER */
34304 +
34305 + result = IPSEC_RCV_OK;
34306 +
34307 +rcvleave:
34308 + return result;
34309 +}
34310 +
34311 +/*
34312 + * get all the initial checking and setup done. Not of this can be off
34313 + * loaded by any currently support hardware
34314 + *
34315 + * the following things should be setup when we exit this function.
34316 + *
34317 + * irs->stats == stats structure (or NULL)
34318 + * irs->ipp = IP header.
34319 + * irs->len = total length of packet
34320 + * skb->nh.iph = ipp;
34321 + * skb->h.raw = start of payload
34322 + * irs->ipsp = NULL.
34323 + * irs->iphlen = N/A = is recalculated.
34324 + * irs->ilen = 0;
34325 + * irs->authlen = 0;
34326 + * irs->authfuncs = NULL;
34327 + * irs->skb = the skb;
34328 + *
34329 + * proto_funcs should be from ipsec_esp.c, ipsec_ah.c or ipsec_ipcomp.c.
34330 + *
34331 + */
34332 +
34333 +static enum ipsec_rcv_value
34334 +ipsec_rcv_init(struct ipsec_rcv_state *irs)
34335 +{
34336 +#ifdef CONFIG_KLIPS_DEBUG
34337 + struct net_device *dev;
34338 +#endif /* CONFIG_KLIPS_DEBUG */
34339 + unsigned char protoc;
34340 + struct iphdr *ipp;
34341 + struct net_device_stats *stats = NULL; /* This device's statistics */
34342 + int i;
34343 + struct sk_buff *skb;
34344 +
34345 + KLIPS_PRINT(debug_rcv, "klips_debug: %s(st=%d,nxt=%d)\n", __FUNCTION__,
34346 + irs->state, irs->next_state);
34347 +
34348 + if (irs == NULL) {
34349 + KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv_init: NULL irs.");
34350 + return IPSEC_RCV_REALLYBAD;
34351 + }
34352 +
34353 + skb = irs->skb;
34354 + if (!skb) {
34355 + KLIPS_PRINT(debug_rcv, "klips_debug:ipsec_rcv_init: NULL skb.");
34356 + return IPSEC_RCV_REALLYBAD;
34357 + }
34358 + dev = skb->dev;
34359 +
34360 + if (skb->data == NULL) {
34361 + KLIPS_PRINT(debug_rcv,
34362 + "klips_debug:ipsec_rcv: "
34363 + "NULL skb->data passed in, packet is bogus, dropping.\n");
34364 + return IPSEC_RCV_REALLYBAD;
34365 + }
34366 +
34367 + /* dev->hard_header_len is unreliable and should not be used */
34368 + /* klips26_rcv_encap will have already set hard_header_len for us */
34369 + if (irs->hard_header_len == 0) {
34370 + irs->hard_header_len = skb_mac_header(skb) ? (skb_network_header(skb) - skb_mac_header(skb)) : 0;
34371 + if((irs->hard_header_len < 0) || (irs->hard_header_len > skb_headroom(skb)))
34372 + irs->hard_header_len = 0;
34373 + }
34374 +
34375 + skb = ipsec_rcv_unclone(skb, irs);
34376 + if(skb == NULL) {
34377 + return IPSEC_RCV_REALLYBAD;
34378 + }
34379 +
34380 +#if IP_FRAGMENT_LINEARIZE
34381 + /* In Linux 2.4.4, we may have to reassemble fragments. They are
34382 + not assembled automatically to save TCP from having to copy
34383 + twice.
34384 + */
34385 + if (skb_is_nonlinear(skb)) {
34386 +#ifdef HAVE_NEW_SKB_LINEARIZE
34387 + if (skb_linearize_cow(skb) != 0)
34388 +#else
34389 + if (skb_linearize(skb, GFP_ATOMIC) != 0)
34390 +#endif
34391 + {
34392 + return IPSEC_RCV_REALLYBAD;
34393 + }
34394 + }
34395 +#endif /* IP_FRAGMENT_LINEARIZE */
34396 +
34397 + ipp = ip_hdr(skb);
34398 + irs->ipp = ipp;
34399 +
34400 +#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(NET_26)
34401 + if (irs->natt_len) {
34402 + /**
34403 + * Now, we are sure packet is ESPinUDP, and we have a private
34404 + * copy that has been linearized, remove natt_len bytes
34405 + * from packet and modify protocol to ESP.
34406 + */
34407 + if (((unsigned char *)skb->data > (unsigned char *)ip_hdr(skb))
34408 + && ((unsigned char *)ip_hdr(skb) > (unsigned char *)skb->head))
34409 + {
34410 + unsigned int _len = (unsigned char *)skb->data -
34411 + (unsigned char *)ip_hdr(skb);
34412 + KLIPS_PRINT(debug_rcv,
34413 + "klips_debug:ipsec_rcv: adjusting skb: skb_push(%u)\n",
34414 + _len);
34415 + skb_push(skb, _len);
34416 + }
34417 + KLIPS_PRINT(debug_rcv,
34418 + "klips_debug:ipsec_rcv: "
34419 + "removing %d bytes from ESPinUDP packet\n"
34420 + , irs->natt_len);
34421 +
34422 + ipp = (struct iphdr *)skb->data;
34423 + irs->iphlen = ipp->ihl << 2;
34424 + ipp->tot_len = htons(ntohs(ipp->tot_len) - irs->natt_len);
34425 + if (skb->len < irs->iphlen + irs->natt_len) {
34426 + printk(KERN_WARNING
34427 + "klips_error:ipsec_rcv: "
34428 + "ESPinUDP packet is too small (%d < %d+%d). "
34429 + "This should never happen, please report.\n",
34430 + (int)(skb->len), irs->iphlen, irs->natt_len);
34431 + return IPSEC_RCV_REALLYBAD;
34432 + }
34433 +
34434 + /* advance payload pointer to point past the UDP header */
34435 + skb->h.raw = skb->h.raw + irs->natt_len;
34436 +
34437 + /* modify protocol */
34438 + ipp->protocol = IPPROTO_ESP;
34439 +
34440 + skb->sk = NULL;
34441 +
34442 + KLIPS_IP_PRINT(debug_rcv, ip_hdr(skb));
34443 + }
34444 +#endif
34445 +
34446 + if (debug_rcv)
34447 + ipsec_rcv_redodebug(irs);
34448 +
34449 + irs->iphlen = ipp->ihl << 2;
34450 +
34451 + KLIPS_PRINT(debug_rcv,
34452 + "klips_debug:ipsec_rcv: "
34453 + "<<< Info -- ");
34454 + KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ",
34455 + skb->dev->name ? skb->dev->name : "NULL");
34456 + KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ",
34457 + dev->name ? dev->name : "NULL");
34458 + KLIPS_PRINTMORE(debug_rcv, "\n");
34459 +
34460 + KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)),
34461 + "klips_debug:ipsec_rcv: "
34462 + "Informational -- **if this happens, find out why** skb->dev:%s is not equal to dev:%s\n",
34463 + skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL",
34464 + dev ? (dev->name ? dev->name : "NULL") : "NULL");
34465 +
34466 + protoc = ipp->protocol;
34467 +#ifndef NET_21
34468 + if((!protocol) || (protocol->protocol != protoc)) {
34469 + KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
34470 + "klips_debug:ipsec_rcv: "
34471 + "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n");
34472 + }
34473 +#endif /* !NET_21 */
34474 +
34475 + if( (protoc != IPPROTO_AH) &&
34476 +#ifdef CONFIG_KLIPS_IPCOMP_disabled_until_we_register_IPCOMP_HANDLER
34477 + (protoc != IPPROTO_COMP) &&
34478 +#endif /* CONFIG_KLIPS_IPCOMP */
34479 + (protoc != IPPROTO_ESP) ) {
34480 + KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
34481 + "klips_debug:ipsec_rcv: Why the hell is someone "
34482 + "passing me a non-ipsec protocol = %d packet? -- dropped.\n",
34483 + protoc);
34484 + return IPSEC_RCV_REALLYBAD;
34485 + }
34486 +
34487 + /*
34488 + * if there is an attached ipsec device, then use that device for
34489 + * stats until we know better.
34490 + */
34491 + if(skb->dev) {
34492 + struct ipsecpriv *prvdev = NULL;
34493 + struct net_device *ipsecdev = NULL;
34494 +
34495 + for(i = 0; i <= ipsecdevices_max; i++) {
34496 + if(ipsecdevices[i] == NULL) continue;
34497 + prvdev = ipsecdevices[i]->priv;
34498 +
34499 + if(prvdev == NULL) continue;
34500 +
34501 + if(prvdev->dev == skb->dev) {
34502 + ipsecdev = ipsecdevices[i];
34503 + break;
34504 + }
34505 + }
34506 +
34507 + if(ipsecdev) {
34508 + skb->dev = ipsecdev;
34509 + } else {
34510 + skb->dev = ipsec_mast_get_device(0);
34511 +
34512 + /* ipsec_mast_get takes the device */
34513 + if(skb->dev) dev_put(skb->dev);
34514 + }
34515 +
34516 + if(prvdev) {
34517 + stats = (struct net_device_stats *) &(prvdev->mystats);
34518 + }
34519 + }
34520 +
34521 + if(stats) {
34522 + stats->rx_packets++;
34523 + }
34524 +
34525 + KLIPS_IP_PRINT(debug_rcv, ipp);
34526 +
34527 + /* set up for decap */
34528 + irs->stats= stats;
34529 + irs->ipp = ipp;
34530 + irs->ipsp = NULL;
34531 + irs->ilen = 0;
34532 + irs->authlen=0;
34533 + irs->authfuncs=NULL;
34534 + irs->skb = skb;
34535 + return IPSEC_RCV_OK;
34536 +}
34537 +
34538 +
34539 +static enum ipsec_rcv_value
34540 +ipsec_rcv_decap_init(struct ipsec_rcv_state *irs)
34541 +{
34542 + KLIPS_PRINT(debug_rcv, "klips_debug: %s(st=%d,nxt=%d)\n", __FUNCTION__,
34543 + irs->state, irs->next_state);
34544 +
34545 + switch (irs->ipp->protocol) {
34546 + case IPPROTO_ESP:
34547 + irs->proto_funcs = esp_xform_funcs;
34548 + break;
34549 +
34550 +#ifdef CONFIG_KLIPS_AH
34551 + case IPPROTO_AH:
34552 + irs->proto_funcs = ah_xform_funcs;
34553 + break;
34554 +#endif /* !CONFIG_KLIPS_AH */
34555 +
34556 +#ifdef CONFIG_KLIPS_IPCOMP
34557 + case IPPROTO_COMP:
34558 + irs->proto_funcs = ipcomp_xform_funcs;
34559 + break;
34560 +#endif /* !CONFIG_KLIPS_IPCOMP */
34561 +
34562 + default:
34563 + if (irs->stats) {
34564 + irs->stats->rx_errors++;
34565 + }
34566 + return IPSEC_RCV_BADPROTO;
34567 + }
34568 + return IPSEC_RCV_OK;
34569 +}
34570 +
34571 +
34572 +static enum ipsec_rcv_value
34573 +ipsec_rcv_decap_lookup(struct ipsec_rcv_state *irs)
34574 +{
34575 + struct iphdr *ipp;
34576 + struct sk_buff *skb;
34577 +
34578 + KLIPS_PRINT(debug_rcv, "klips_debug: %s(st=%d,nxt=%d)\n", __FUNCTION__,
34579 + irs->state, irs->next_state);
34580 +
34581 + irs->replay = 0;
34582 +#ifdef CONFIG_KLIPS_ALG
34583 + irs->ixt_a = NULL;
34584 +#endif /* CONFIG_KLIPS_ALG */
34585 +
34586 + skb = irs->skb;
34587 + irs->len = skb->len;
34588 + ipp = irs->ipp;
34589 + irs->proto = ipp->protocol;
34590 + if (debug_rcv)
34591 + ipsec_rcv_redodebug(irs);
34592 +
34593 + irs->iphlen = ipp->ihl << 2;
34594 + ipp->check = 0; /* we know the sum is good */
34595 +
34596 + irs->said.dst.u.v4.sin_addr.s_addr = ipp->daddr;
34597 + irs->said.dst.u.v4.sin_family = AF_INET;
34598 +
34599 + /* note: rcv_checks set up the said.spi value, if appropriate */
34600 + if (irs->proto_funcs->rcv_checks)
34601 + return (*irs->proto_funcs->rcv_checks)(irs, irs->skb);
34602 +
34603 + return IPSEC_RCV_OK;
34604 +}
34605 +
34606 +
34607 +static enum ipsec_rcv_value
34608 +ipsec_rcv_auth_init(struct ipsec_rcv_state *irs)
34609 +{
34610 + struct ipsec_sa *newipsp;
34611 +
34612 + KLIPS_PRINT(debug_rcv, "klips_debug: %s(st=%d,nxt=%d)\n", __FUNCTION__,
34613 + irs->state, irs->next_state);
34614 +
34615 + irs->said.proto = irs->proto;
34616 + if (debug_rcv) {
34617 + irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa));
34618 + if(irs->sa_len == 0) {
34619 + strcpy(irs->sa, "(error)");
34620 + }
34621 + } else
34622 + irs->sa_len = 0;
34623 +
34624 + newipsp = ipsec_sa_getbyid(&irs->said);
34625 + if (newipsp == NULL) {
34626 + KLIPS_PRINT(debug_rcv,
34627 + "klips_debug:ipsec_rcv: "
34628 + "no ipsec_sa for SA:%s: incoming packet with no SA dropped\n",
34629 + irs->sa_len ? irs->sa : " (error)");
34630 + if(irs->stats) {
34631 + irs->stats->rx_dropped++;
34632 + }
34633 + return IPSEC_RCV_SAIDNOTFOUND;
34634 + }
34635 +
34636 + /* If it is in larval state, drop the packet, we cannot process yet. */
34637 + if(newipsp->ips_state == K_SADB_SASTATE_LARVAL) {
34638 + KLIPS_PRINT(debug_rcv,
34639 + "klips_debug:ipsec_rcv: "
34640 + "ipsec_sa in larval state, cannot be used yet, dropping packet.\n");
34641 + if(irs->stats) {
34642 + irs->stats->rx_dropped++;
34643 + }
34644 + ipsec_sa_put(newipsp);
34645 + return IPSEC_RCV_SAIDNOTLIVE;
34646 + }
34647 +
34648 + if(newipsp->ips_state == K_SADB_SASTATE_DEAD) {
34649 + KLIPS_PRINT(debug_rcv,
34650 + "klips_debug:ipsec_rcv: "
34651 + "ipsec_sa in dead state, cannot be used any more, dropping packet.\n");
34652 + if(irs->stats) {
34653 + irs->stats->rx_dropped++;
34654 + }
34655 + ipsec_sa_put(newipsp);
34656 + return IPSEC_RCV_SAIDNOTLIVE;
34657 + }
34658 +
34659 + if(sysctl_ipsec_inbound_policy_check) {
34660 + if(irs->ipp->saddr != ((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr) {
34661 + KLIPS_ERROR(debug_rcv,
34662 + "klips_debug:ipsec_rcv: "
34663 + "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n",
34664 + irs->sa_len ? irs->sa : " (error)",
34665 + irs->ipsaddr_txt);
34666 + if(irs->stats) {
34667 + irs->stats->rx_dropped++;
34668 + }
34669 + ipsec_sa_put(newipsp);
34670 + return IPSEC_RCV_FAILEDINBOUND;
34671 + }
34672 +
34673 + KLIPS_PRINT(debug_rcv,
34674 + "klips_debug:ipsec_rcv: "
34675 + "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n",
34676 + irs->sa_len ? irs->sa : " (error)",
34677 + irs->ipsaddr_txt);
34678 +
34679 + /*
34680 + * at this point, we have looked up a new SA, and we want to
34681 + * make sure that if this isn't the first SA in the list,
34682 + * that the previous SA actually points at this one.
34683 + */
34684 + if(irs->ipsp) {
34685 + if(irs->ipsp->ips_next != newipsp) {
34686 + KLIPS_ERROR(debug_rcv,
34687 + "klips_debug:ipsec_rcv: "
34688 + "unexpected SA:%s: does not agree with ips->inext policy, dropped\n",
34689 + irs->sa_len ? irs->sa : " (error)");
34690 + if(irs->stats) {
34691 + irs->stats->rx_dropped++;
34692 + }
34693 + ipsec_sa_put(newipsp);
34694 + return IPSEC_RCV_FAILEDINBOUND;
34695 + }
34696 + KLIPS_PRINT(debug_rcv,
34697 + "klips_debug:ipsec_rcv: "
34698 + "SA:%s grouping from previous SA is OK.\n",
34699 + irs->sa_len ? irs->sa : " (error)");
34700 + } else {
34701 + KLIPS_PRINT(debug_rcv,
34702 + "klips_debug:ipsec_rcv: "
34703 + "SA:%s First SA in group.\n",
34704 + irs->sa_len ? irs->sa : " (error)");
34705 + }
34706 +
34707 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34708 + if (irs->proto == IPPROTO_ESP) {
34709 + KLIPS_PRINT(debug_rcv,
34710 + "klips_debug:ipsec_rcv: "
34711 + "natt_type=%u tdbp->ips_natt_type=%u : %s\n",
34712 + irs->natt_type, newipsp->ips_natt_type,
34713 + (irs->natt_type==newipsp->ips_natt_type)?"ok":"bad");
34714 + if (irs->natt_type != newipsp->ips_natt_type) {
34715 + KLIPS_PRINT(debug_rcv,
34716 + "klips_debug:ipsec_rcv: "
34717 + "SA:%s does not agree with expected NAT-T policy.\n",
34718 + irs->sa_len ? irs->sa : " (error)");
34719 + if(irs->stats) {
34720 + irs->stats->rx_dropped++;
34721 + }
34722 + ipsec_sa_put(newipsp);
34723 + return IPSEC_RCV_FAILEDINBOUND;
34724 + }
34725 + }
34726 +#endif
34727 + }
34728 +
34729 + irs->ipsp=newipsp;
34730 +
34731 + return IPSEC_RCV_OK;
34732 +}
34733 +
34734 +static enum ipsec_rcv_value
34735 +ipsec_rcv_auth_decap(struct ipsec_rcv_state *irs)
34736 +{
34737 + ipsec_rcv_setoutif(irs);
34738 +
34739 + irs->proto_funcs = irs->ipsp->ips_xformfuncs;
34740 + if (irs->proto_funcs == NULL)
34741 + return IPSEC_RCV_BADPROTO;
34742 +
34743 + if (irs->proto_funcs->protocol != irs->ipp->protocol) {
34744 + if(irs->proto_funcs->protocol == IPPROTO_COMP) {
34745 + /* looks like an IPCOMP that we can skip */
34746 + struct ipsec_sa *newipsp = NULL;
34747 +
34748 + newipsp = irs->ipsp->ips_next;
34749 + if(newipsp) {
34750 + ipsec_sa_get(newipsp);
34751 + }
34752 + if(irs->lastipsp) {
34753 + ipsec_sa_put(irs->lastipsp);
34754 + }
34755 + irs->lastipsp = irs->ipsp;
34756 + irs->ipsp=newipsp;
34757 +
34758 + /* come back into here with the next transform */
34759 + irs->next_state = IPSEC_RSM_AUTH_DECAP;
34760 + return IPSEC_RCV_OK;
34761 + }
34762 +
34763 + if(irs->stats) {
34764 + irs->stats->rx_errors++;
34765 + }
34766 + return IPSEC_RCV_FAILEDINBOUND;
34767 + }
34768 +
34769 + if (debug_rcv)
34770 + ipsec_rcv_redodebug(irs);
34771 +
34772 + /* now check the lifetimes */
34773 + if(ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_bytes, "bytes",
34774 + irs->sa, ipsec_life_countbased, ipsec_incoming,
34775 + irs->ipsp) == ipsec_life_harddied ||
34776 + ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "addtime",
34777 + irs->sa, ipsec_life_timebased, ipsec_incoming,
34778 + irs->ipsp) == ipsec_life_harddied ||
34779 + ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "usetime",
34780 + irs->sa, ipsec_life_timebased, ipsec_incoming,
34781 + irs->ipsp) == ipsec_life_harddied ||
34782 + ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_packets, "packets",
34783 + irs->sa, ipsec_life_countbased, ipsec_incoming,
34784 + irs->ipsp) == ipsec_life_harddied) {
34785 +
34786 + /*
34787 + * disconnect SA from the hash table, so it can not be
34788 + * found again.
34789 + */
34790 + ipsec_sa_rm(irs->ipsp);
34791 + if(irs->stats) {
34792 + irs->stats->rx_dropped++;
34793 + }
34794 +
34795 + KLIPS_PRINT(debug_rcv,
34796 + "klips_debug:ipsec_rcv_decap_once: "
34797 + "decap (%d) failed lifetime check\n",
34798 + irs->proto);
34799 +
34800 + return IPSEC_RCV_LIFETIMEFAILED;
34801 + }
34802 +
34803 +#if 0
34804 + /*
34805 + * This is removed for some reasons:
34806 + * 1) it needs to happen *after* authentication.
34807 + * 2) do we really care, if it authenticates, if it came
34808 + * from the wrong location?
34809 + * 3) the NAT_KA messages in IKE will also get to pluto
34810 + * and it will figure out that stuff has moved.
34811 + * 4) the 2.6 udp-esp encap function does not pass us
34812 + * the originating port number, and I can't tell
34813 + * if skb->sk is guaranteed to be valid here.
34814 + * 2005-04-16: mcr@xelerance.com
34815 + */
34816 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34817 + /*
34818 + *
34819 + * XXX we should ONLY update pluto if the SA passes all checks,
34820 + * which we clearly do not now.
34821 + */
34822 + if ((irs->natt_type) &&
34823 + ( (irs->ipp->saddr != (((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr)) ||
34824 + (irs->natt_sport != newipsp->ips_natt_sport)
34825 + )) {
34826 + struct sockaddr sipaddr;
34827 + struct sockaddr_in *psin = (struct sockaddr_in*)(newipsp->ips_addr_s);
34828 +
34829 + /** Advertise NAT-T addr change to pluto **/
34830 + sipaddr.sa_family = AF_INET;
34831 + ((struct sockaddr_in*)&sipaddr)->sin_addr.s_addr = irs->ipp->saddr;
34832 + ((struct sockaddr_in*)&sipaddr)->sin_port = htons(irs->natt_sport);
34833 + pfkey_nat_t_new_mapping(newipsp, &sipaddr, irs->natt_sport);
34834 +
34835 + /**
34836 + * Then allow or block packet depending on
34837 + * sysctl_ipsec_inbound_policy_check.
34838 + *
34839 + * In all cases, pluto will update SA if new mapping is
34840 + * accepted.
34841 + */
34842 + if (sysctl_ipsec_inbound_policy_check) {
34843 + KLIPS_PRINT(debug_rcv,
34844 + "klips_debug:ipsec_rcv: "
34845 + "SA:%s, src=%s:%u of pkt does not agree with expected "
34846 + "SA source address [%08x:%u] (notifying pluto of change).\n",
34847 + irs->sa_len ? irs->sa : " (error)",
34848 + irs->ipsaddr_txt, irs->natt_sport,
34849 + psin->sin_addr.s_addr,
34850 + newipsp->ips_natt_sport);
34851 + if(irs->stats) {
34852 + irs->stats->rx_dropped++;
34853 + }
34854 + ipsec_sa_put(newipsp);
34855 + return IPSEC_RCV_FAILEDINBOUND;
34856 + }
34857 + }
34858 +#endif
34859 +#endif
34860 +
34861 + irs->authfuncs=NULL;
34862 +
34863 + /* authenticate, if required */
34864 +#ifdef CONFIG_KLIPS_OCF
34865 + if (irs->ipsp->ocf_in_use) {
34866 + irs->authlen = AHHMAC_HASHLEN;
34867 + irs->authfuncs = NULL;
34868 + irs->ictx = NULL;
34869 + irs->octx = NULL;
34870 + irs->ictx_len = 0;
34871 + irs->octx_len = 0;
34872 + } else
34873 +#endif /* CONFIG_KLIPS_OCF */
34874 +#ifdef CONFIG_KLIPS_ALG
34875 + /* authenticate, if required */
34876 + if ((irs->ixt_a=irs->ipsp->ips_alg_auth)) {
34877 + irs->authlen = AHHMAC_HASHLEN;
34878 + irs->authfuncs = NULL;
34879 + irs->ictx = NULL;
34880 + irs->octx = NULL;
34881 + irs->ictx_len = 0;
34882 + irs->octx_len = 0;
34883 + KLIPS_PRINT(debug_rcv,
34884 + "klips_debug:ipsec_rcv: "
34885 + "authalg=%d authlen=%d\n",
34886 + irs->ipsp->ips_authalg,
34887 + irs->authlen);
34888 + } else
34889 +#endif /* CONFIG_KLIPS_ALG */
34890 + switch(irs->ipsp->ips_authalg) {
34891 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
34892 + case AH_MD5:
34893 + irs->authlen = AHHMAC_HASHLEN;
34894 + irs->authfuncs = ipsec_rcv_md5;
34895 + irs->ictx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx;
34896 + irs->octx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx;
34897 + irs->ictx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx);
34898 + irs->octx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx);
34899 + break;
34900 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
34901 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
34902 + case AH_SHA:
34903 + irs->authlen = AHHMAC_HASHLEN;
34904 + irs->authfuncs = ipsec_rcv_sha1;
34905 + irs->ictx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx;
34906 + irs->octx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx;
34907 + irs->ictx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx);
34908 + irs->octx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx);
34909 + break;
34910 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
34911 + case AH_NONE:
34912 + irs->authlen = 0;
34913 + irs->authfuncs = NULL;
34914 + irs->ictx = NULL;
34915 + irs->octx = NULL;
34916 + irs->ictx_len = 0;
34917 + irs->octx_len = 0;
34918 + break;
34919 + default:
34920 + irs->ipsp->ips_errs.ips_alg_errs += 1;
34921 + if(irs->stats) {
34922 + irs->stats->rx_errors++;
34923 + }
34924 + return IPSEC_RCV_BADAUTH;
34925 + }
34926 +
34927 + /* ilen counts number of bytes in ESP portion */
34928 + irs->ilen = ((irs->skb->data + irs->skb->len) - skb_transport_header(irs->skb)) - irs->authlen;
34929 + if(irs->ilen <= 0) {
34930 + KLIPS_PRINT(debug_rcv,
34931 + "klips_debug:ipsec_rcv: "
34932 + "runt %s packet with no data, dropping.\n",
34933 + (irs->proto == IPPROTO_ESP ? "esp" : "ah"));
34934 + if(irs->stats) {
34935 + irs->stats->rx_dropped++;
34936 + }
34937 + return IPSEC_RCV_BADLEN;
34938 + }
34939 +
34940 + if(irs->authfuncs ||
34941 +#ifdef CONFIG_KLIPS_OCF
34942 + irs->ipsp->ocf_in_use ||
34943 +#endif
34944 +#ifdef CONFIG_KLIPS_ALG
34945 + irs->ixt_a ||
34946 +#endif
34947 + 0) {
34948 + if(irs->proto_funcs->rcv_setup_auth)
34949 + return (*irs->proto_funcs->rcv_setup_auth)(irs, irs->skb,
34950 + &irs->replay, &irs->authenticator);
34951 + }
34952 + return IPSEC_RCV_OK;
34953 +}
34954 +
34955 +
34956 +static enum ipsec_rcv_value
34957 +ipsec_rcv_auth_calc(struct ipsec_rcv_state *irs)
34958 +{
34959 + KLIPS_PRINT(debug_rcv, "klips_debug: %s(st=%d,nxt=%d)\n", __FUNCTION__,
34960 + irs->state, irs->next_state);
34961 +
34962 + if(irs->authfuncs ||
34963 +#ifdef CONFIG_KLIPS_OCF
34964 + irs->ipsp->ocf_in_use ||
34965 +#endif
34966 +#ifdef CONFIG_KLIPS_ALG
34967 + irs->ixt_a ||
34968 +#endif
34969 + 0) {
34970 + if(!irs->authenticator) {
34971 + irs->ipsp->ips_errs.ips_auth_errs += 1;
34972 + if(irs->stats) {
34973 + irs->stats->rx_dropped++;
34974 + }
34975 + return IPSEC_RCV_BADAUTH;
34976 + }
34977 +
34978 + if(!ipsec_checkreplaywindow(irs->ipsp, irs->replay)) {
34979 + irs->ipsp->ips_errs.ips_replaywin_errs += 1;
34980 + KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
34981 + "klips_debug:ipsec_rcv: "
34982 + "duplicate frame from %s, packet dropped\n",
34983 + irs->ipsaddr_txt);
34984 + if(irs->stats) {
34985 + irs->stats->rx_dropped++;
34986 + }
34987 + return IPSEC_RCV_REPLAYFAILED;
34988 + }
34989 +
34990 + /*
34991 + * verify authenticator
34992 + */
34993 +
34994 + KLIPS_PRINT(debug_rcv,
34995 + "klips_debug:ipsec_rcv: "
34996 + "encalg = %d, authalg = %d.\n",
34997 + irs->ipsp->ips_encalg,
34998 + irs->ipsp->ips_authalg);
34999 +
35000 + /* calculate authenticator */
35001 + if(irs->proto_funcs->rcv_calc_auth == NULL) {
35002 + return IPSEC_RCV_BADAUTH;
35003 + }
35004 + return (*irs->proto_funcs->rcv_calc_auth)(irs, irs->skb);
35005 + }
35006 + return IPSEC_RCV_OK;
35007 +}
35008 +
35009 +static enum ipsec_rcv_value
35010 +ipsec_rcv_auth_chk(struct ipsec_rcv_state *irs)
35011 +{
35012 + KLIPS_PRINT(debug_rcv, "klips_debug: %s(st=%d,nxt=%d) - %s\n", __FUNCTION__,
35013 + irs->state, irs->next_state,
35014 + irs->auth_checked ? "already checked" : "will check");
35015 +
35016 + if (irs->auth_checked)
35017 + return IPSEC_RCV_OK;
35018 +
35019 + if(irs->authfuncs ||
35020 +#ifdef CONFIG_KLIPS_OCF
35021 + irs->ipsp->ocf_in_use ||
35022 +#endif
35023 +#ifdef CONFIG_KLIPS_ALG
35024 + irs->ixt_a ||
35025 +#endif
35026 + 0) {
35027 + if (memcmp(irs->hash, irs->authenticator, irs->authlen)) {
35028 + irs->ipsp->ips_errs.ips_auth_errs += 1;
35029 + KLIPS_ERROR(debug_rcv & DB_RX_INAU,
35030 + "klips_debug:ipsec_rcv: "
35031 + "auth failed on incoming packet from %s (replay=%d): calculated hash=%08x%08x%08x received hash=%08x%08x%08x, dropped\n",
35032 + irs->ipsaddr_txt,
35033 + irs->replay,
35034 + ntohl(*(__u32*)&irs->hash[0]),
35035 + ntohl(*(__u32*)&irs->hash[4]),
35036 + ntohl(*(__u32*)&irs->hash[8]),
35037 + ntohl(*(__u32*)irs->authenticator),
35038 + ntohl(*((__u32*)irs->authenticator + 1)),
35039 + ntohl(*((__u32*)irs->authenticator + 2)));
35040 + if(irs->stats) {
35041 + irs->stats->rx_dropped++;
35042 + }
35043 + return IPSEC_RCV_AUTHFAILED;
35044 + } else {
35045 + KLIPS_PRINT(debug_rcv,
35046 + "klips_debug:ipsec_rcv: "
35047 + "authentication successful.\n");
35048 + }
35049 +
35050 + /* Crypto hygiene: clear memory used to calculate autheticator.
35051 + * The length varies with the algorithm.
35052 + */
35053 + memset(irs->hash, 0, irs->authlen);
35054 +
35055 + /* If the sequence number == 0, expire SA, it had rolled */
35056 + if(irs->ipsp->ips_replaywin && !irs->replay /* !irs->ipsp->ips_replaywin_lastseq */) {
35057 + /* we need to remove it from the sadb hash, so that it can't be found again */
35058 + ipsec_sa_rm(irs->ipsp);
35059 +
35060 + KLIPS_ERROR(debug_rcv,
35061 + "klips_debug:ipsec_rcv: "
35062 + "replay window counter rolled, expiring SA.\n");
35063 + if(irs->stats) {
35064 + irs->stats->rx_dropped++;
35065 + }
35066 + return IPSEC_RCV_REPLAYROLLED;
35067 + }
35068 +
35069 + /* now update the replay counter */
35070 + if (!ipsec_updatereplaywindow(irs->ipsp, irs->replay)) {
35071 + irs->ipsp->ips_errs.ips_replaywin_errs += 1;
35072 + KLIPS_ERROR(debug_rcv & DB_RX_REPLAY,
35073 + "klips_debug:ipsec_rcv: "
35074 + "duplicate frame from %s, packet dropped\n",
35075 + irs->ipsaddr_txt);
35076 + if(irs->stats) {
35077 + irs->stats->rx_dropped++;
35078 + }
35079 + return IPSEC_RCV_REPLAYROLLED;
35080 + }
35081 + irs->auth_checked = 1;
35082 + }
35083 + return IPSEC_RCV_OK;
35084 +}
35085 +
35086 +static enum ipsec_rcv_value
35087 +ipsec_rcv_decrypt(struct ipsec_rcv_state *irs)
35088 +{
35089 + KLIPS_PRINT(debug_rcv, "klips_debug: %s(st=%d,nxt=%d)\n", __FUNCTION__,
35090 + irs->state, irs->next_state);
35091 +
35092 + if (irs->proto_funcs->rcv_decrypt) {
35093 + return (*irs->proto_funcs->rcv_decrypt)(irs);
35094 + }
35095 + return IPSEC_RCV_OK;
35096 +}
35097 +
35098 +/*
35099 + * here we decide if there is more decapsulating required and
35100 + * change the next state appropriately
35101 + */
35102 +static enum ipsec_rcv_value
35103 +ipsec_rcv_decap_cont(struct ipsec_rcv_state *irs)
35104 +{
35105 + struct sk_buff *skb;
35106 + struct iphdr *ipp;
35107 + struct ipsec_sa *ipsnext = NULL; /* next SA towards inside of packet */
35108 + enum ipsec_rcv_value rv;
35109 +
35110 + KLIPS_PRINT(debug_rcv, "klips_debug: %s(st=%d,nxt=%d)\n", __FUNCTION__,
35111 + irs->state, irs->next_state);
35112 +
35113 + /*
35114 + * if we haven't checked the auth values yet, do it now.
35115 + * This is needed for the case where drivers do crypt+hash
35116 + * in one operation.
35117 + */
35118 + rv = ipsec_rcv_auth_chk(irs);
35119 + if (rv != IPSEC_RCV_OK)
35120 + return rv;
35121 +
35122 + /*
35123 + * Adjust pointers after decrypt
35124 + */
35125 + skb = irs->skb;
35126 + irs->len = skb->len;
35127 + ipp = irs->ipp = ip_hdr(skb);
35128 + irs->iphlen = ipp->ihl<<2;
35129 + skb_set_transport_header(skb, ipsec_skb_offset(skb, skb_network_header(skb) + irs->iphlen));
35130 +
35131 + /* zero any options that there might be */
35132 + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
35133 +
35134 + if (debug_rcv)
35135 + ipsec_rcv_redodebug(irs);
35136 +
35137 + /*
35138 + * Discard the original ESP/AH header
35139 + */
35140 + ipp->protocol = irs->next_header;
35141 +
35142 + ipp->check = 0; /* NOTE: this will be included in checksum */
35143 + ipp->check = ip_fast_csum((unsigned char *)ip_hdr(skb), irs->iphlen >> 2);
35144 +
35145 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35146 + "klips_debug:ipsec_rcv: "
35147 + "after <%s%s%s>, SA:%s:\n",
35148 + IPS_XFORM_NAME(irs->ipsp),
35149 + irs->sa_len ? irs->sa : " (error)");
35150 + KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
35151 +
35152 + skb->protocol = htons(ETH_P_IP);
35153 + skb->ip_summed = 0;
35154 +
35155 + ipsnext = irs->ipsp->ips_next;
35156 + if(sysctl_ipsec_inbound_policy_check) {
35157 + if(ipsnext) {
35158 + if(
35159 + ipp->protocol != IPPROTO_AH
35160 + && ipp->protocol != IPPROTO_ESP
35161 +#ifdef CONFIG_KLIPS_IPCOMP
35162 + && ipp->protocol != IPPROTO_COMP
35163 + && (ipsnext->ips_said.proto != IPPROTO_COMP
35164 + || ipsnext->ips_next)
35165 +#endif /* CONFIG_KLIPS_IPCOMP */
35166 + && ipp->protocol != IPPROTO_IPIP
35167 + && ipp->protocol != IPPROTO_ATT_HEARTBEAT /* heartbeats to AT&T SIG/GIG */
35168 + ) {
35169 + KLIPS_PRINT(debug_rcv,
35170 + "klips_debug:ipsec_rcv: "
35171 + "packet with incomplete policy dropped, last successful SA:%s.\n",
35172 + irs->sa_len ? irs->sa : " (error)");
35173 + if(irs->stats) {
35174 + irs->stats->rx_dropped++;
35175 + }
35176 + return IPSEC_RCV_FAILEDINBOUND;
35177 + }
35178 + KLIPS_PRINT(debug_rcv,
35179 + "klips_debug:ipsec_rcv: "
35180 + "SA:%s, Another IPSEC header to process.\n",
35181 + irs->sa_len ? irs->sa : " (error)");
35182 + } else {
35183 + KLIPS_PRINT(debug_rcv,
35184 + "klips_debug:ipsec_rcv: "
35185 + "No ips_inext from this SA:%s.\n",
35186 + irs->sa_len ? irs->sa : " (error)");
35187 + }
35188 + }
35189 +
35190 +#ifdef CONFIG_KLIPS_IPCOMP
35191 + /* update ipcomp ratio counters, even if no ipcomp packet is present */
35192 + if (ipsnext
35193 + && ipsnext->ips_said.proto == IPPROTO_COMP
35194 + && ipp->protocol != IPPROTO_COMP) {
35195 + ipsnext->ips_comp_ratio_cbytes += ntohs(ipp->tot_len);
35196 + ipsnext->ips_comp_ratio_dbytes += ntohs(ipp->tot_len);
35197 + }
35198 +#endif /* CONFIG_KLIPS_IPCOMP */
35199 +
35200 + irs->ipsp->ips_life.ipl_bytes.ipl_count += irs->len;
35201 + irs->ipsp->ips_life.ipl_bytes.ipl_last = irs->len;
35202 +
35203 + if(!irs->ipsp->ips_life.ipl_usetime.ipl_count) {
35204 + irs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
35205 + }
35206 + irs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
35207 + irs->ipsp->ips_life.ipl_packets.ipl_count += 1;
35208 +
35209 +#ifdef CONFIG_NETFILTER
35210 + if(irs->proto == IPPROTO_ESP || irs->proto == IPPROTO_AH) {
35211 + skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_MASK))))
35212 + | IPsecSAref2NFmark(IPsecSA2SAref(irs->ipsp));
35213 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35214 + "klips_debug:ipsec_rcv: "
35215 + "%s SA sets skb->nfmark=0x%x.\n",
35216 + irs->proto == IPPROTO_ESP ? "ESP" : "AH",
35217 + (unsigned)skb->nfmark);
35218 + }
35219 +#endif /* CONFIG_NETFILTER */
35220 +
35221 + /* okay, acted on this SA, so free any previous SA, and record a new one */
35222 + if(irs->ipsp) {
35223 + struct ipsec_sa *newipsp = NULL;
35224 + newipsp = irs->ipsp->ips_next;
35225 + if(newipsp) {
35226 + ipsec_sa_get(newipsp);
35227 + }
35228 + if(irs->lastipsp) {
35229 + ipsec_sa_put(irs->lastipsp);
35230 + }
35231 + irs->lastipsp = irs->ipsp;
35232 + irs->ipsp=newipsp;
35233 + }
35234 +
35235 + /* do we need to do more decapsulation */
35236 + if ((irs->ipp->protocol == IPPROTO_ESP ||
35237 + irs->ipp->protocol == IPPROTO_AH ||
35238 +#ifdef CONFIG_KLIPS_IPCOMP
35239 + irs->ipp->protocol == IPPROTO_COMP ||
35240 +#endif /* CONFIG_KLIPS_IPCOMP */
35241 + 0) && irs->ipsp != NULL) {
35242 + irs->next_state = IPSEC_RSM_AUTH_DECAP;
35243 + }
35244 + return IPSEC_RCV_OK;
35245 +}
35246 +
35247 +
35248 +static enum ipsec_rcv_value
35249 +ipsec_rcv_cleanup(struct ipsec_rcv_state *irs)
35250 +{
35251 + struct sk_buff *skb;
35252 + struct iphdr *ipp;
35253 + struct ipsec_sa *ipsp = NULL;
35254 +
35255 + KLIPS_PRINT(debug_rcv, "klips_debug: %s(st=%d,nxt=%d)\n", __FUNCTION__,
35256 + irs->state, irs->next_state);
35257 +
35258 + /* set up for decap loop */
35259 + ipp = irs->ipp;
35260 + ipsp = irs->ipsp;
35261 + skb = irs->skb;
35262 +
35263 + /* if there is an IPCOMP, but we don't have an IPPROTO_COMP,
35264 + * then we can just skip it
35265 + */
35266 +#ifdef CONFIG_KLIPS_IPCOMP
35267 + if(irs->ipsp && irs->ipsp->ips_said.proto == IPPROTO_COMP) {
35268 + struct ipsec_sa *newipsp = NULL;
35269 + newipsp = irs->ipsp->ips_next;
35270 + if(newipsp) {
35271 + ipsec_sa_get(newipsp);
35272 + }
35273 + if(irs->lastipsp) {
35274 + ipsec_sa_put(irs->lastipsp);
35275 + }
35276 + irs->lastipsp = irs->ipsp;
35277 + irs->ipsp=newipsp;
35278 + }
35279 +#endif /* CONFIG_KLIPS_IPCOMP */
35280 +
35281 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
35282 + if ((irs->natt_type) && (ipp->protocol != IPPROTO_IPIP)) {
35283 + /**
35284 + * NAT-Traversal and Transport Mode:
35285 + * we need to correct TCP/UDP checksum
35286 + *
35287 + * If we've got NAT-OA, we can fix checksum without recalculation.
35288 + */
35289 + __u32 natt_oa = ipsp->ips_natt_oa ?
35290 + ((struct sockaddr_in*)(ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
35291 +
35292 + if(natt_oa != 0) {
35293 + /* reset source address to what it was before NAT */
35294 + ipp->saddr = natt_oa;
35295 + ipp->check = 0;
35296 + ipp->check = ip_fast_csum((unsigned char *)ipp, ipp->ihl);
35297 + KLIPS_PRINT(debug_rcv, "csum: %04x\n", ipp->check);
35298 + }
35299 + }
35300 +#endif
35301 +
35302 + /*
35303 + * the SA is still locked from the loop
35304 + */
35305 + if(irs->ipsp && irs->ipsp->ips_xformfuncs->protocol == IPPROTO_IPIP) {
35306 + enum ipsec_rcv_value decap_stat;
35307 +
35308 + decap_stat = ipsec_rcv_decap_ipip(irs);
35309 + if(decap_stat != IPSEC_RCV_OK) {
35310 + return decap_stat;
35311 + }
35312 + }
35313 +
35314 + if(irs->stats) {
35315 + irs->stats->rx_bytes += skb->len;
35316 + }
35317 +
35318 + /*
35319 + * if we are supposed to return the packet directly to the transport
35320 + * layer, then dump it out correctly.
35321 + */
35322 + if(unlikely(!irs->lastipsp))
35323 + printk("%s,%d: %s lastipsp should never be NULL\n",
35324 + __FILE__, __LINE__, __FUNCTION__);
35325 + if(irs->lastipsp->ips_transport_direct) {
35326 + KLIPS_PRINT(debug_rcv, "receiving packet as transport direct\n");
35327 + skb->ip_summed=CHECKSUM_UNNECESSARY;
35328 + /* STUFF */
35329 + }
35330 +
35331 +#ifdef HAVE_IPSEC_SAREF
35332 + if(skb->sp) {
35333 + secpath_put(skb->sp);
35334 + }
35335 + skb->sp = secpath_dup(NULL);
35336 + skb->sp->ref = irs->lastipsp->ips_ref;
35337 +#endif
35338 +
35339 + /* release the dst that was attached, since we have likely
35340 + * changed the actual destination of the packet.
35341 + */
35342 + if(skb->dst) {
35343 + dst_release(skb->dst);
35344 + skb->dst = NULL;
35345 + }
35346 + skb->pkt_type = PACKET_HOST;
35347 + if(irs->hard_header_len &&
35348 + (skb_mac_header(skb) != (skb_network_header(skb) - irs->hard_header_len)) &&
35349 + (irs->hard_header_len <= skb_headroom(skb))) {
35350 + /* copy back original MAC header */
35351 + memmove(skb_network_header(skb) - irs->hard_header_len,
35352 + skb_mac_header(skb), irs->hard_header_len);
35353 + skb_set_mac_header(skb, ipsec_skb_offset(skb, skb_network_header(skb) - irs->hard_header_len));
35354 + }
35355 + return IPSEC_RCV_OK;
35356 +}
35357 +
35358 +
35359 +static enum ipsec_rcv_value
35360 +ipsec_rcv_complete(struct ipsec_rcv_state *irs)
35361 +{
35362 + KLIPS_PRINT(debug_rcv, "klips_debug: %s(st=%d,nxt=%d)\n", __FUNCTION__,
35363 + irs->state, irs->next_state);
35364 +
35365 + /*
35366 + * make sure that data now starts at IP header, since we are going
35367 + * to pass this back to ip_input (aka netif_rx). Rules for what the
35368 + * pointers wind up a different for 2.6 vs 2.4, so we just fudge it here.
35369 + */
35370 +#ifdef NET_26
35371 + irs->skb->data = skb_push(irs->skb, skb_transport_header(irs->skb) - skb_network_header(irs->skb));
35372 +#else
35373 + irs->skb->data = skb_network_header(irs->skb);
35374 + {
35375 + struct iphdr *iph = ip_hdr(irs->skb);
35376 + int len = ntohs(iph->tot_len);
35377 + irs->skb->len = len;
35378 + }
35379 +#endif
35380 +
35381 + ipsec_nf_reset(irs->skb);
35382 +
35383 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35384 + "klips_debug:ipsec_rcv: "
35385 + "netif_rx(%s) called.\n", irs->skb->dev->name);
35386 + netif_rx(irs->skb);
35387 + irs->skb = NULL;
35388 + return IPSEC_RCV_OK;
35389 +}
35390 +
35391 +
35392 +
35393 +/*
35394 + * ipsec_rsm is responsible for walking us through the state machine
35395 + * it is the only entry point into the receive processing and does
35396 + * appropriate checks and state changes for us.
35397 + */
35398 +
35399 +void
35400 +ipsec_rsm(struct ipsec_rcv_state *irs)
35401 +{
35402 + if (irs == NULL) {
35403 + KLIPS_PRINT(debug_rcv,
35404 + "klips_debug:ipsec_rsm: "
35405 + "irs == NULL.\n");
35406 + return;
35407 + }
35408 +
35409 + /*
35410 + * make sure nothing is removed from underneath us
35411 + */
35412 + spin_lock_bh(&tdb_lock);
35413 +
35414 + /*
35415 + * if we have a valid said, then we must check it here to ensure it
35416 + * hasn't gone away while we were waiting for a task to complete
35417 + */
35418 +
35419 + if (irs->said.proto && ipsec_sa_getbyid(&irs->said) == NULL) {
35420 + KLIPS_PRINT(debug_rcv,
35421 + "klips_debug:ipsec_rcv: "
35422 + "no ipsec_sa for SA:%s: incoming packet with no SA dropped\n",
35423 + irs->sa_len ? irs->sa : " (error)");
35424 + if (irs->stats)
35425 + irs->stats->rx_dropped++;
35426 +
35427 + /* drop through and cleanup */
35428 + irs->state = IPSEC_RSM_DONE;
35429 + }
35430 +
35431 + while (irs->state != IPSEC_RSM_DONE) {
35432 + int rc;
35433 +
35434 + irs->next_state = rcv_state_table[irs->state].next_state;
35435 +
35436 + rc = rcv_state_table[irs->state].action(irs);
35437 +
35438 + if (rc == IPSEC_RCV_OK) {
35439 + /* some functions change the next state, see the state table */
35440 + irs->state = irs->next_state;
35441 + } else if (rc == IPSEC_RCV_PENDING) {
35442 + /*
35443 + * things are on hold until we return here in the next/new state
35444 + * we check our SA is valid when we return
35445 + */
35446 + spin_unlock_bh(&tdb_lock);
35447 + return;
35448 + } else {
35449 + /* bad result, force state change to done */
35450 + KLIPS_PRINT(debug_rcv,
35451 + "klips_debug:ipsec_rsm: "
35452 + "processing completed due to %s.\n",
35453 + ipsec_rcv_err(rc));
35454 + irs->state = IPSEC_RSM_DONE;
35455 + }
35456 + }
35457 +
35458 + /*
35459 + * all done with anything needing locks
35460 + */
35461 + spin_unlock_bh(&tdb_lock);
35462 +
35463 + if (irs->lastipsp) {
35464 + ipsec_sa_put(irs->lastipsp);
35465 + irs->lastipsp=NULL;
35466 + }
35467 +
35468 + if (irs->ipsp) {
35469 + ipsec_sa_put(irs->ipsp);
35470 + irs->ipsp=NULL;
35471 + }
35472 +
35473 + if (irs->skb) {
35474 + ipsec_kfree_skb(irs->skb);
35475 + irs->skb = NULL;
35476 + }
35477 +
35478 + ipsec_rcv_state_delete(irs);
35479 +
35480 + KLIPS_DEC_USE; /* once less packet using the driver */
35481 +}
35482 +
35483 +
35484 +int
35485 +ipsec_rcv(struct sk_buff *skb
35486 +#ifndef PROTO_HANDLER_SINGLE_PARM
35487 + unsigned short xlen
35488 +#endif /* PROTO_HANDLER_SINGLE_PARM */
35489 + )
35490 +{
35491 + struct ipsec_rcv_state *irs = NULL;
35492 +
35493 + /* Don't unlink in the middle of a turnaround */
35494 + KLIPS_INC_USE;
35495 +
35496 + if (skb == NULL) {
35497 + KLIPS_PRINT(debug_rcv,
35498 + "klips_debug:ipsec_rcv: "
35499 + "NULL skb passed in.\n");
35500 + goto rcvleave;
35501 + }
35502 +
35503 + if (skb->data == NULL) {
35504 + KLIPS_PRINT(debug_rcv,
35505 + "klips_debug:ipsec_rcv: "
35506 + "NULL skb->data passed in, packet is bogus, dropping.\n");
35507 + goto rcvleave;
35508 + }
35509 +
35510 + irs = ipsec_rcv_state_new();
35511 + if (unlikely (! irs)) {
35512 + KLIPS_PRINT(debug_rcv,
35513 + "klips_debug:ipsec_rcv: "
35514 + "failled to allocate a rcv state object\n");
35515 + goto rcvleave;
35516 + }
35517 +
35518 +#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(NET_26)
35519 + {
35520 + /* NET_26 NAT-T is handled by seperate function */
35521 + struct sk_buff *nskb;
35522 + int udp_decap_ret = 0;
35523 +
35524 + nskb = ipsec_rcv_natt_decap(skb, irs, &udp_decap_ret);
35525 + if(nskb == NULL) {
35526 + /* return with non-zero, because UDP.c code
35527 + * need to send it upstream.
35528 + */
35529 + if(skb && udp_decap_ret == 0) {
35530 + ipsec_kfree_skb(skb);
35531 + }
35532 + if (irs) {
35533 + ipsec_rcv_state_delete(irs);
35534 + }
35535 + KLIPS_DEC_USE;
35536 + return(udp_decap_ret);
35537 + }
35538 + skb = nskb;
35539 + }
35540 +#endif /* NAT_T */
35541 +
35542 + irs->skb = skb;
35543 +
35544 + /*
35545 + * we hand off real early to the state machine because we just cannot
35546 + * know how much processing it is off-loading
35547 + */
35548 + ipsec_rsm(irs);
35549 +
35550 + return(0);
35551 +
35552 + rcvleave:
35553 + if (irs) {
35554 + ipsec_rcv_state_delete(irs);
35555 + }
35556 + if (skb) {
35557 + ipsec_kfree_skb(skb);
35558 + }
35559 + KLIPS_DEC_USE;
35560 + return(0);
35561 +}
35562 +
35563 +
35564 +#ifdef NET_26
35565 +/*
35566 + * this entry point is not a protocol entry point, so the entry
35567 + * is a bit different.
35568 + *
35569 + * skb->iph->tot_len has been byte-swapped, and reduced by the size of
35570 + * the IP header (and options).
35571 + *
35572 + * skb->h.raw has been pulled up the ESP header.
35573 + *
35574 + * skb->iph->protocol = 50 IPPROTO_ESP;
35575 + *
35576 + */
35577 +int klips26_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
35578 +{
35579 + return klips26_rcv_encap(skb, udp_sk(sk)->encap_type);
35580 +}
35581 +
35582 +int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type)
35583 +{
35584 + struct ipsec_rcv_state *irs = NULL;
35585 +
35586 + /* Don't unlink in the middle of a turnaround */
35587 + KLIPS_INC_USE;
35588 +
35589 + if (skb == NULL) {
35590 + KLIPS_PRINT(debug_rcv,
35591 + "klips_debug:ipsec_rcv: "
35592 + "NULL skb passed in.\n");
35593 + goto rcvleave;
35594 + }
35595 +
35596 + if (skb->data == NULL) {
35597 + KLIPS_PRINT(debug_rcv,
35598 + "klips_debug:ipsec_rcv: "
35599 + "NULL skb->data passed in, packet is bogus, dropping.\n");
35600 + goto rcvleave;
35601 + }
35602 +
35603 + irs = ipsec_rcv_state_new();
35604 + if (unlikely (! irs)) {
35605 + KLIPS_PRINT(debug_rcv,
35606 + "klips_debug:ipsec_rcv: "
35607 + "failled to allocate a rcv state object\n");
35608 + goto rcvleave;
35609 + }
35610 +
35611 + /* XXX fudge it so that all nat-t stuff comes from ipsec0 */
35612 + /* eventually, the SA itself will determine which device
35613 + * it comes from
35614 + */
35615 + {
35616 + skb->dev = ipsec_get_device(0);
35617 + }
35618 + irs->hard_header_len = skb->dev->hard_header_len;
35619 +
35620 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
35621 + switch(encap_type) {
35622 + case UDP_ENCAP_ESPINUDP:
35623 + irs->natt_type = ESPINUDP_WITH_NON_ESP;
35624 + break;
35625 +
35626 + case UDP_ENCAP_ESPINUDP_NON_IKE:
35627 + irs->natt_type = ESPINUDP_WITH_NON_IKE;
35628 + break;
35629 +
35630 + default:
35631 + if(printk_ratelimit()) {
35632 + printk(KERN_INFO "KLIPS received unknown UDP-ESP encap type %u\n",
35633 + encap_type);
35634 + }
35635 + goto rcvleave;
35636 + }
35637 +#endif /* NAT_T */
35638 +
35639 + irs->skb = skb;
35640 +
35641 + /*
35642 + * we hand off real early to the state machine because we just cannot
35643 + * know how much processing it is off-loading
35644 + */
35645 + ipsec_rsm(irs);
35646 +
35647 + return(0);
35648 +
35649 + rcvleave:
35650 + if (irs) {
35651 + ipsec_rcv_state_delete(irs);
35652 + }
35653 + if (skb) {
35654 + ipsec_kfree_skb(skb);
35655 + }
35656 + KLIPS_DEC_USE;
35657 + return(0);
35658 +}
35659 +#endif
35660 +
35661 +// ------------------------------------------------------------------------
35662 +// this handles creating and managing state for recv path
35663 +
35664 +static spinlock_t irs_cache_lock = SPIN_LOCK_UNLOCKED;
35665 +#ifdef HAVE_KMEM_CACHE_MACRO
35666 +static struct kmem_cache *irs_cache_allocator = NULL;
35667 +#else
35668 +static kmem_cache_t *irs_cache_allocator = NULL;
35669 +#endif
35670 +static unsigned irs_cache_allocated_count = 0;
35671 +
35672 +int ipsec_irs_cache_allocated_max = 1000;
35673 +module_param(ipsec_irs_cache_allocated_max,int,0644);
35674 +MODULE_PARM_DESC(ipsec_irs_cache_allocated_max,
35675 + "Maximum outstanding receive packets (before they are dropped)");
35676 +
35677 +int
35678 +ipsec_rcv_state_cache_init (void)
35679 +{
35680 + if (irs_cache_allocator)
35681 + return -EBUSY;
35682 +
35683 + spin_lock_init(&irs_cache_lock);
35684 +#ifdef HAVE_KMEM_CACHE_MACRO
35685 + /* irs_cache_allocator = KMEM_CACHE(ipsec_irs,0); */
35686 + irs_cache_allocator = kmem_cache_create ("ipsec_irs",
35687 + sizeof (struct ipsec_rcv_state), 0,
35688 + 0, NULL);
35689 +#else
35690 + irs_cache_allocator = kmem_cache_create ("ipsec_irs",
35691 + sizeof (struct ipsec_rcv_state), 0,
35692 + 0, NULL, NULL);
35693 +#endif
35694 + if (! irs_cache_allocator)
35695 + return -ENOMEM;
35696 +
35697 + return 0;
35698 +}
35699 +
35700 +void
35701 +ipsec_rcv_state_cache_cleanup (void)
35702 +{
35703 + if (unlikely (irs_cache_allocated_count))
35704 + printk ("ipsec: deleting ipsec_irs kmem_cache while in use\n");
35705 +
35706 + if (irs_cache_allocator) {
35707 + kmem_cache_destroy (irs_cache_allocator);
35708 + irs_cache_allocator = NULL;
35709 + }
35710 + irs_cache_allocated_count = 0;
35711 +}
35712 +
35713 +static struct ipsec_rcv_state *
35714 +ipsec_rcv_state_new (void)
35715 +{
35716 + struct ipsec_rcv_state *irs;
35717 +
35718 + spin_lock_bh (&irs_cache_lock);
35719 +
35720 + if (irs_cache_allocated_count >= ipsec_irs_cache_allocated_max) {
35721 + spin_unlock_bh (&irs_cache_lock);
35722 + KLIPS_PRINT(debug_rcv,
35723 + "klips_debug:ipsec_rcv_state_new: "
35724 + "exceeded maximum outstanding RX packet cnt %d\n",
35725 + irs_cache_allocated_count);
35726 + return NULL;
35727 + }
35728 +
35729 + irs = kmem_cache_alloc (irs_cache_allocator, GFP_ATOMIC);
35730 +
35731 + if (likely (irs != NULL))
35732 + irs_cache_allocated_count++;
35733 +
35734 + spin_unlock_bh (&irs_cache_lock);
35735 +
35736 + if (unlikely (NULL == irs))
35737 + goto bail;
35738 +
35739 + // initialize the object
35740 +#if 1
35741 + memset((caddr_t)irs, 0, sizeof(*irs));
35742 +#else
35743 + /* optimised to only clear the essentials */
35744 + irs->state = 0;
35745 + irs->next_state = 0;
35746 + irs->auth_checked = 0;
35747 + irs->stats = NULL;
35748 + irs->authenticator = NULL;
35749 + irs->said.proto = 0;
35750 +
35751 + irs->hard_header_len = 0;
35752 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
35753 + irs->natt_type = 0;
35754 + irs->natt_len = 0;
35755 +#endif
35756 +
35757 + irs->lastipsp = NULL;
35758 +#endif
35759 +
35760 +bail:
35761 + return irs;
35762 +}
35763 +
35764 +static void
35765 +ipsec_rcv_state_delete (struct ipsec_rcv_state *irs)
35766 +{
35767 + if (unlikely (! irs))
35768 + return;
35769 +
35770 + spin_lock_bh (&irs_cache_lock);
35771 +
35772 + irs_cache_allocated_count--;
35773 + kmem_cache_free (irs_cache_allocator, irs);
35774 +
35775 + spin_unlock_bh (&irs_cache_lock);
35776 +}
35777 +
35778 +/*
35779 + *
35780 + * Local Variables:
35781 + * c-set-style: linux
35782 + * End:
35783 + *
35784 + */
35785 --- /dev/null Tue Mar 11 13:02:56 2003
35786 +++ linux/net/ipsec/ipsec_sa.c Mon Feb 9 13:51:03 2004
35787 @@ -0,0 +1,1575 @@
35788 +/*
35789 + * Common routines for IPsec SA maintenance routines.
35790 + *
35791 + * Copyright (C) 1996, 1997 John Ioannidis.
35792 + * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
35793 + *
35794 + * This program is free software; you can redistribute it and/or modify it
35795 + * under the terms of the GNU General Public License as published by the
35796 + * Free Software Foundation; either version 2 of the License, or (at your
35797 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
35798 + *
35799 + * This program is distributed in the hope that it will be useful, but
35800 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
35801 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
35802 + * for more details.
35803 + *
35804 + * RCSID $Id: ipsec_sa.c,v 1.31 2005/11/11 04:38:56 paul Exp $
35805 + *
35806 + * This is the file formerly known as "ipsec_xform.h"
35807 + *
35808 + */
35809 +
35810 +#ifndef AUTOCONF_INCLUDED
35811 +#include <linux/config.h>
35812 +#endif
35813 +#include <linux/version.h>
35814 +#include <linux/kernel.h> /* printk() */
35815 +
35816 +#include "openswan/ipsec_param.h"
35817 +
35818 +#ifdef MALLOC_SLAB
35819 +# include <linux/slab.h> /* kmalloc() */
35820 +#else /* MALLOC_SLAB */
35821 +# include <linux/malloc.h> /* kmalloc() */
35822 +#endif /* MALLOC_SLAB */
35823 +#include <linux/vmalloc.h> /* vmalloc() */
35824 +#include <linux/errno.h> /* error codes */
35825 +#include <linux/types.h> /* size_t */
35826 +#include <linux/interrupt.h> /* mark_bh */
35827 +
35828 +#include <linux/netdevice.h> /* struct device, and other headers */
35829 +#include <linux/etherdevice.h> /* eth_type_trans */
35830 +#include <linux/ip.h> /* struct iphdr */
35831 +#include <linux/skbuff.h>
35832 +#include <openswan.h>
35833 +#ifdef SPINLOCK
35834 +#ifdef SPINLOCK_23
35835 +#include <linux/spinlock.h> /* *lock* */
35836 +#else /* SPINLOCK_23 */
35837 +#include <asm/spinlock.h> /* *lock* */
35838 +#endif /* SPINLOCK_23 */
35839 +#endif /* SPINLOCK */
35840 +
35841 +#include <net/ip.h>
35842 +
35843 +#include "openswan/radij.h"
35844 +
35845 +#include "openswan/ipsec_stats.h"
35846 +#include "openswan/ipsec_life.h"
35847 +#include "openswan/ipsec_sa.h"
35848 +#include "openswan/ipsec_xform.h"
35849 +
35850 +#include "openswan/ipsec_encap.h"
35851 +#include "openswan/ipsec_radij.h"
35852 +#include "openswan/ipsec_xform.h"
35853 +#include "openswan/ipsec_ipe4.h"
35854 +#include "openswan/ipsec_ah.h"
35855 +#include "openswan/ipsec_esp.h"
35856 +#include "openswan/ipsec_ipip.h"
35857 +#ifdef CONFIG_KLIPS_IPCOMP
35858 +#include "openswan/ipsec_ipcomp.h"
35859 +#endif /* CONFIG_KLIPS_COMP */
35860 +
35861 +#include <openswan/pfkeyv2.h>
35862 +#include <openswan/pfkey.h>
35863 +
35864 +#include "openswan/ipsec_proto.h"
35865 +#include "openswan/ipsec_alg.h"
35866 +
35867 +#include "ipsec_ocf.h"
35868 +
35869 +
35870 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
35871 +
35872 +struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
35873 +#ifdef SPINLOCK
35874 +spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
35875 +#else /* SPINLOCK */
35876 +spinlock_t tdb_lock;
35877 +#endif /* SPINLOCK */
35878 +
35879 +struct ipsec_sadb ipsec_sadb;
35880 +
35881 +/* the sub table must be narrower (or equal) in bits than the variable type
35882 + in the main table to count the number of unused entries in it. */
35883 +typedef struct {
35884 + int testSizeOf_refSubTable :
35885 + ((sizeof(IPsecRefTableUnusedCount) * 8) < IPSEC_SA_REF_SUBTABLE_IDX_WIDTH ? -1 : 1);
35886 +} dummy;
35887 +
35888 +
35889 +/* The field where the saref will be hosted in the skb must be wide enough to
35890 + accomodate the information it needs to store. */
35891 +typedef struct {
35892 + int testSizeOf_refField :
35893 + (IPSEC_SA_REF_HOST_FIELD_WIDTH < IPSEC_SA_REF_TABLE_IDX_WIDTH ? -1 : 1 );
35894 +} dummy2;
35895 +
35896 +
35897 +#define IPS_HASH(said) (((said)->spi + (said)->dst.u.v4.sin_addr.s_addr + (said)->proto) % SADB_HASHMOD)
35898 +
35899 +int
35900 +ipsec_SAref_recycle(void)
35901 +{
35902 + int table, i;
35903 + int error = 0;
35904 + int entry;
35905 + int addone;
35906 +
35907 + ipsec_sadb.refFreeListHead = IPSEC_SAREF_NULL;
35908 + ipsec_sadb.refFreeListTail = IPSEC_SAREF_NULL;
35909 +
35910 + if(ipsec_sadb.refFreeListCont == IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) {
35911 + KLIPS_PRINT(debug_xform,
35912 + "klips_debug:ipsec_SAref_recycle: "
35913 + "end of table reached, continuing at start..\n");
35914 + ipsec_sadb.refFreeListCont = IPSEC_SAREF_FIRST;
35915 + }
35916 +
35917 + KLIPS_PRINT(debug_xform,
35918 + "klips_debug:ipsec_SAref_recycle: "
35919 + "recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n",
35920 + ipsec_sadb.refFreeListCont,
35921 + (ipsec_sadb.refTable[IPsecSAref2table(ipsec_sadb.refFreeListCont)] != NULL) ? IPsecSAref2SA(ipsec_sadb.refFreeListCont) : NULL,
35922 + IPsecSAref2table(ipsec_sadb.refFreeListCont),
35923 + IPsecSAref2entry(ipsec_sadb.refFreeListCont));
35924 +
35925 + /* add one additional table entry */
35926 + addone = 0;
35927 +
35928 + ipsec_sadb.refFreeListHead = IPSEC_SAREF_FIRST;
35929 + for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) {
35930 + table = IPsecSAref2table(ipsec_sadb.refFreeListCont);
35931 + if(addone == 0 && ipsec_sadb.refTable[table] == NULL) {
35932 + addone = 1;
35933 + error = ipsec_SArefSubTable_alloc(table);
35934 + if(error) {
35935 + return error;
35936 + }
35937 + }
35938 + for(entry = IPsecSAref2entry(ipsec_sadb.refFreeListCont);
35939 + entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES;
35940 + entry++) {
35941 + if(ipsec_sadb.refTable[table]->entry[entry] == NULL) {
35942 + ipsec_sadb.refFreeList[++ipsec_sadb.refFreeListTail] = IPsecSArefBuild(table, entry);
35943 + if(ipsec_sadb.refFreeListTail == (IPSEC_SA_REF_FREELIST_NUM_ENTRIES - 1)) {
35944 + ipsec_sadb.refFreeListHead = IPSEC_SAREF_FIRST;
35945 + ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
35946 + KLIPS_PRINT(debug_xform,
35947 + "klips_debug:ipsec_SAref_recycle: "
35948 + "SArefFreeList refilled.\n");
35949 + return 0;
35950 + }
35951 + }
35952 + }
35953 + ipsec_sadb.refFreeListCont++;
35954 + ipsec_sadb.refFreeListTail=i;
35955 + }
35956 +
35957 + if(ipsec_sadb.refFreeListTail == IPSEC_SAREF_NULL) {
35958 + KLIPS_PRINT(debug_xform,
35959 + "klips_debug:ipsec_SAref_recycle: "
35960 + "out of room in the SArefTable.\n");
35961 +
35962 + return(-ENOSPC);
35963 + }
35964 +
35965 + ipsec_sadb.refFreeListHead = IPSEC_SAREF_FIRST;
35966 + ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
35967 + KLIPS_PRINT(debug_xform,
35968 + "klips_debug:ipsec_SAref_recycle: "
35969 + "SArefFreeList partly refilled to %d of %d.\n",
35970 + ipsec_sadb.refFreeListTail,
35971 + IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
35972 + return 0;
35973 +}
35974 +
35975 +int
35976 +ipsec_SArefSubTable_alloc(unsigned table)
35977 +{
35978 + unsigned entry;
35979 + struct IPsecSArefSubTable* SArefsub;
35980 +
35981 + KLIPS_PRINT(debug_xform,
35982 + "klips_debug:ipsec_SArefSubTable_alloc: "
35983 + "allocating %lu bytes for table %u of %u.\n",
35984 + (unsigned long) (IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)),
35985 + table,
35986 + IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
35987 +
35988 + /* allocate another sub-table */
35989 + SArefsub = vmalloc(IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *));
35990 + if(SArefsub == NULL) {
35991 + KLIPS_PRINT(debug_xform,
35992 + "klips_debug:ipsec_SArefSubTable_alloc: "
35993 + "error allocating memory for table %u of %u!\n",
35994 + table,
35995 + IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
35996 + return -ENOMEM;
35997 + }
35998 +
35999 + /* add this sub-table to the main table */
36000 + ipsec_sadb.refTable[table] = SArefsub;
36001 +
36002 + /* initialise each element to NULL */
36003 + KLIPS_PRINT(debug_xform,
36004 + "klips_debug:ipsec_SArefSubTable_alloc: "
36005 + "initialising %u elements (2 ^ %u) of table %u.\n",
36006 + IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
36007 + IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
36008 + table);
36009 + for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
36010 + SArefsub->entry[entry] = NULL;
36011 + }
36012 +
36013 + return 0;
36014 +}
36015 +
36016 +int
36017 +ipsec_saref_verify_slot(IPsecSAref_t ref)
36018 +{
36019 + int ref_table=IPsecSAref2table(ref);
36020 +
36021 + if(ipsec_sadb.refTable[ref_table] == NULL) {
36022 + return ipsec_SArefSubTable_alloc(ref_table);
36023 + }
36024 + return 0;
36025 +}
36026 +
36027 +int
36028 +ipsec_saref_freelist_init(void)
36029 +{
36030 + int i;
36031 +
36032 + KLIPS_PRINT(debug_xform,
36033 + "klips_debug:ipsec_saref_freelist_init: "
36034 + "initialising %u elements of FreeList.\n",
36035 + IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
36036 +
36037 + for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) {
36038 + ipsec_sadb.refFreeList[i] = IPSEC_SAREF_NULL;
36039 + }
36040 + ipsec_sadb.refFreeListHead = IPSEC_SAREF_NULL;
36041 + ipsec_sadb.refFreeListCont = IPSEC_SAREF_FIRST;
36042 + ipsec_sadb.refFreeListTail = IPSEC_SAREF_NULL;
36043 +
36044 + return 0;
36045 +}
36046 +
36047 +int
36048 +ipsec_sadb_init(void)
36049 +{
36050 + int error = 0;
36051 + unsigned i;
36052 +
36053 + for(i = 0; i < SADB_HASHMOD; i++) {
36054 + ipsec_sadb_hash[i] = NULL;
36055 + }
36056 + /* parts above are for the old style SADB hash table */
36057 +
36058 +
36059 + /* initialise SA reference table */
36060 +
36061 + /* initialise the main table */
36062 + KLIPS_PRINT(debug_xform,
36063 + "klips_debug:ipsec_sadb_init: "
36064 + "initialising main table of size %u (2 ^ %u).\n",
36065 + IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
36066 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH);
36067 + {
36068 + unsigned table;
36069 + for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
36070 + ipsec_sadb.refTable[table] = NULL;
36071 + }
36072 + }
36073 +
36074 + /* allocate the first sub-table */
36075 + error = ipsec_SArefSubTable_alloc(0);
36076 + if(error) {
36077 + return error;
36078 + }
36079 +
36080 + error = ipsec_saref_freelist_init();
36081 + return error;
36082 +}
36083 +
36084 +IPsecSAref_t
36085 +ipsec_SAref_alloc(int*error) /* pass in error var by pointer */
36086 +{
36087 + IPsecSAref_t SAref;
36088 +
36089 + KLIPS_PRINT(debug_xform,
36090 + "ipsec_SAref_alloc: "
36091 + "SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n",
36092 + ipsec_sadb.refFreeListHead,
36093 + ipsec_sadb.refFreeListCont,
36094 + ipsec_sadb.refFreeListTail,
36095 + IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
36096 +
36097 + if(ipsec_sadb.refFreeListHead == IPSEC_SAREF_NULL) {
36098 + KLIPS_PRINT(debug_xform,
36099 + "ipsec_SAref_alloc: "
36100 + "FreeList empty, recycling...\n");
36101 + *error = ipsec_SAref_recycle();
36102 + if(*error) {
36103 + return IPSEC_SAREF_NULL;
36104 + }
36105 + }
36106 +
36107 + SAref = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead];
36108 + if(SAref == IPSEC_SAREF_NULL) {
36109 + KLIPS_ERROR(debug_xform,
36110 + "ipsec_SAref_alloc: "
36111 + "unexpected error, refFreeListHead = %d points to invalid entry.\n",
36112 + ipsec_sadb.refFreeListHead);
36113 + *error = -ESPIPE;
36114 + return IPSEC_SAREF_NULL;
36115 + }
36116 +
36117 + KLIPS_PRINT(debug_xform,
36118 + "ipsec_SAref_alloc: "
36119 + "allocating SAref=%d, table=%u, entry=%u of %u.\n",
36120 + SAref,
36121 + IPsecSAref2table(SAref),
36122 + IPsecSAref2entry(SAref),
36123 + IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES);
36124 +
36125 + ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead] = IPSEC_SAREF_NULL;
36126 + ipsec_sadb.refFreeListHead++;
36127 + if(ipsec_sadb.refFreeListHead > ipsec_sadb.refFreeListTail) {
36128 + KLIPS_PRINT(debug_xform,
36129 + "ipsec_SAref_alloc: "
36130 + "last FreeList entry allocated, resetting list head to empty.\n");
36131 + ipsec_sadb.refFreeListHead = IPSEC_SAREF_NULL;
36132 + }
36133 +
36134 + return SAref;
36135 +}
36136 +
36137 +int
36138 +ipsec_sa_print(struct ipsec_sa *ips)
36139 +{
36140 + char sa[SATOT_BUF];
36141 + size_t sa_len;
36142 +
36143 + printk(KERN_INFO "klips_debug: SA:");
36144 + if(ips == NULL) {
36145 + printk("NULL\n");
36146 + return -ENOENT;
36147 + }
36148 + printk(" ref=%d", ips->ips_ref);
36149 + printk(" refcount=%d", atomic_read(&ips->ips_refcount));
36150 + if(ips->ips_hnext != NULL) {
36151 + printk(" hnext=0p%p", ips->ips_hnext);
36152 + }
36153 + if(ips->ips_next != NULL) {
36154 + printk(" next=0p%p", ips->ips_next);
36155 + }
36156 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
36157 + printk(" said=%s", sa_len ? sa : " (error)");
36158 + if(ips->ips_seq) {
36159 + printk(" seq=%u", ips->ips_seq);
36160 + }
36161 + if(ips->ips_pid) {
36162 + printk(" pid=%u", ips->ips_pid);
36163 + }
36164 + if(ips->ips_authalg) {
36165 + printk(" authalg=%u", ips->ips_authalg);
36166 + }
36167 + if(ips->ips_encalg) {
36168 + printk(" encalg=%u", ips->ips_encalg);
36169 + }
36170 + printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips));
36171 + if(ips->ips_replaywin) {
36172 + printk(" ooowin=%u", ips->ips_replaywin);
36173 + }
36174 + if(ips->ips_flags) {
36175 + printk(" flags=%u", ips->ips_flags);
36176 + }
36177 + if(ips->ips_addr_s) {
36178 + char buf[SUBNETTOA_BUF];
36179 + addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
36180 + 0, buf, sizeof(buf));
36181 + printk(" src=%s", buf);
36182 + }
36183 + if(ips->ips_addr_d) {
36184 + char buf[SUBNETTOA_BUF];
36185 + addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
36186 + 0, buf, sizeof(buf));
36187 + printk(" dst=%s", buf);
36188 + }
36189 + if(ips->ips_addr_p) {
36190 + char buf[SUBNETTOA_BUF];
36191 + addrtoa(((struct sockaddr_in*)(ips->ips_addr_p))->sin_addr,
36192 + 0, buf, sizeof(buf));
36193 + printk(" proxy=%s", buf);
36194 + }
36195 + if(ips->ips_key_bits_a) {
36196 + printk(" key_bits_a=%u", ips->ips_key_bits_a);
36197 + }
36198 + if(ips->ips_key_bits_e) {
36199 + printk(" key_bits_e=%u", ips->ips_key_bits_e);
36200 + }
36201 +
36202 + printk("\n");
36203 + return 0;
36204 +}
36205 +
36206 +struct ipsec_sa*
36207 +ipsec_sa_alloc(int*error) /* pass in error var by pointer */
36208 +{
36209 + struct ipsec_sa* ips;
36210 +
36211 + if((ips = kmalloc(sizeof(*ips), GFP_ATOMIC) ) == NULL) {
36212 + KLIPS_PRINT(debug_xform,
36213 + "ipsec_sa_alloc: "
36214 + "memory allocation error\n");
36215 + *error = -ENOMEM;
36216 + return NULL;
36217 + }
36218 + memset((caddr_t)ips, 0, sizeof(*ips));
36219 +
36220 + /* return with at least counter = 1 */
36221 + ipsec_sa_get(ips);
36222 +
36223 + *error = 0;
36224 + return(ips);
36225 +}
36226 +
36227 +void
36228 +ipsec_sa_untern(struct ipsec_sa *ips)
36229 +{
36230 + IPsecSAref_t ref = ips->ips_ref;
36231 + int error;
36232 +
36233 + /* verify that we are removing correct item! */
36234 + error = ipsec_saref_verify_slot(ref);
36235 + if(error) {
36236 + return;
36237 + }
36238 +
36239 + if(IPsecSAref2SA(ref) == ips) {
36240 + IPsecSAref2SA(ref) = NULL;
36241 + ipsec_sa_put(ips);
36242 + } else {
36243 + KLIPS_PRINT(debug_xform,
36244 + "ipsec_sa_untern: "
36245 + "ref=%u -> %p but untern'ing %p\n", ref,
36246 + IPsecSAref2SA(ref), ips);
36247 + }
36248 +
36249 +}
36250 +
36251 +int
36252 +ipsec_sa_intern(struct ipsec_sa *ips)
36253 +{
36254 + int error;
36255 + IPsecSAref_t ref = ips->ips_ref;
36256 +
36257 + if(ref == IPSEC_SAREF_NULL) {
36258 + ref = ipsec_SAref_alloc(&error); /* pass in error return by pointer */
36259 + KLIPS_PRINT(debug_xform,
36260 + "ipsec_sa_intern: "
36261 + "allocated ref=%u for sa %p\n", ref, ips);
36262 +
36263 + if(ref == IPSEC_SAREF_NULL) {
36264 + KLIPS_PRINT(debug_xform,
36265 + "ipsec_sa_intern: "
36266 + "SAref allocation error\n");
36267 + return error;
36268 + }
36269 +
36270 + ips->ips_ref = ref;
36271 + }
36272 +
36273 + error = ipsec_saref_verify_slot(ref);
36274 + if(error) {
36275 + return error;
36276 + }
36277 +
36278 + ipsec_sa_get(ips);
36279 + /*
36280 + * if there is an existing SA at this reference, then free it
36281 + * note, that nsa might == ips!. That's okay, we just incremented
36282 + * the reference count above.
36283 + */
36284 + {
36285 + struct ipsec_sa *nsa = IPsecSAref2SA(ref);
36286 + if(nsa) {
36287 + ipsec_sa_put(nsa);
36288 + }
36289 + }
36290 +
36291 + KLIPS_PRINT(debug_xform,
36292 + "ipsec_sa_alloc: "
36293 + "SAref[%d]=%p\n",
36294 + ips->ips_ref, ips);
36295 + IPsecSAref2SA(ips->ips_ref) = ips;
36296 +
36297 + /* return OK */
36298 + return 0;
36299 +}
36300 +
36301 +
36302 +struct ipsec_sa *
36303 +ipsec_sa_getbyid(ip_said *said)
36304 +{
36305 + int hashval;
36306 + struct ipsec_sa *ips;
36307 + char sa[SATOT_BUF];
36308 + size_t sa_len;
36309 +
36310 + if(said == NULL) {
36311 + KLIPS_PRINT(debug_xform,
36312 + "ipsec_sa_getbyid: "
36313 + "null pointer passed in!\n");
36314 + return NULL;
36315 + }
36316 +
36317 + hashval = IPS_HASH(said);
36318 +
36319 + sa_len = KLIPS_SATOT(debug_xform, said, 0, sa, sizeof(sa));
36320 + KLIPS_PRINT(debug_xform,
36321 + "ipsec_sa_getbyid: "
36322 + "linked entry in ipsec_sa table for hash=%d of SA:%s requested.\n",
36323 + hashval,
36324 + sa_len ? sa : " (error)");
36325 +
36326 + if((ips = ipsec_sadb_hash[hashval]) == NULL) {
36327 + KLIPS_PRINT(debug_xform,
36328 + "ipsec_sa_getbyid: "
36329 + "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
36330 + hashval,
36331 + sa_len ? sa : " (error)");
36332 + return NULL;
36333 + }
36334 +
36335 + for (; ips; ips = ips->ips_hnext) {
36336 + if ((ips->ips_said.spi == said->spi) &&
36337 + (ips->ips_said.dst.u.v4.sin_addr.s_addr == said->dst.u.v4.sin_addr.s_addr) &&
36338 + (ips->ips_said.proto == said->proto)) {
36339 + ipsec_sa_get(ips);
36340 + return ips;
36341 + }
36342 + }
36343 +
36344 + KLIPS_PRINT(debug_xform,
36345 + "ipsec_sa_getbyid: "
36346 + "no entry in linked list for hash=%d of SA:%s.\n",
36347 + hashval,
36348 + sa_len ? sa : " (error)");
36349 + return NULL;
36350 +}
36351 +
36352 +struct ipsec_sa *
36353 +ipsec_sa_getbyref(IPsecSAref_t ref)
36354 +{
36355 + struct ipsec_sa *ips;
36356 + struct IPsecSArefSubTable *st = ipsec_sadb.refTable[IPsecSAref2table(ref)];
36357 +
36358 + if(st == NULL) {
36359 + return NULL;
36360 + }
36361 +
36362 + ips = st->entry[IPsecSAref2entry(ref)];
36363 + if(ips) {
36364 + ipsec_sa_get(ips);
36365 + }
36366 + return ips;
36367 +}
36368 +
36369 +
36370 +void
36371 +__ipsec_sa_put(struct ipsec_sa *ips, const char *func, int line)
36372 +{
36373 + if(ips == NULL) {
36374 + KLIPS_PRINT(debug_xform,
36375 + "ipsec_sa_put: "
36376 + "null pointer passed in!\n");
36377 + return;
36378 + }
36379 +
36380 +#ifdef CONFIG_KLIPS_DEBUG
36381 + if(debug_xform) {
36382 + char sa[SATOT_BUF];
36383 + size_t sa_len;
36384 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
36385 +
36386 + KLIPS_PRINT(debug_xform,
36387 + "ipsec_sa_put: "
36388 + "ipsec_sa %p SA:%s, ref:%d reference count (%d--) decremented by %s:%d.\n",
36389 + ips,
36390 + sa_len ? sa : " (error)",
36391 + ips->ips_ref,
36392 + atomic_read(&ips->ips_refcount),
36393 + func, line);
36394 + }
36395 +#endif
36396 +
36397 + if(atomic_dec_and_test(&ips->ips_refcount)) {
36398 + KLIPS_PRINT(debug_xform,
36399 + "ipsec_sa_put: freeing %p\n",
36400 + ips);
36401 + /* it was zero */
36402 + ipsec_sa_wipe(ips);
36403 + }
36404 +
36405 + return;
36406 +}
36407 +
36408 +struct ipsec_sa *
36409 +__ipsec_sa_get(struct ipsec_sa *ips, const char *func, int line)
36410 +{
36411 + if (ips == NULL)
36412 + return NULL;
36413 +
36414 +#ifdef CONFIG_KLIPS_DEBUG
36415 + if(debug_xform) {
36416 + char sa[SATOT_BUF];
36417 + size_t sa_len;
36418 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
36419 +
36420 + KLIPS_PRINT(debug_xform,
36421 + "ipsec_sa_get: "
36422 + "ipsec_sa %p SA:%s, ref:%d reference count (%d++) incremented by %s:%d.\n",
36423 + ips,
36424 + sa_len ? sa : " (error)",
36425 + ips->ips_ref,
36426 + atomic_read(&ips->ips_refcount),
36427 + func, line);
36428 + }
36429 +#endif
36430 +
36431 + atomic_inc(&ips->ips_refcount);
36432 +
36433 +#if 0
36434 + /*
36435 + * DAVIDM: if we include this code it means the SA is freed immediately
36436 + * on creation and then reused ! Not sure why it is here.
36437 + */
36438 +
36439 + if(atomic_dec_and_test(&ips->ips_refcount)) {
36440 + KLIPS_PRINT(debug_xform,
36441 + "ipsec_sa_get: freeing %p\n",
36442 + ips);
36443 + /* it was zero */
36444 + ipsec_sa_wipe(ips);
36445 + }
36446 +#endif
36447 +
36448 + return ips;
36449 +}
36450 +
36451 +/*
36452 + The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen
36453 +*/
36454 +int
36455 +ipsec_sa_add(struct ipsec_sa *ips)
36456 +{
36457 + int error = 0;
36458 + unsigned int hashval;
36459 +
36460 + ips = ipsec_sa_get(ips);
36461 +
36462 + if(ips == NULL) {
36463 + KLIPS_PRINT(debug_xform,
36464 + "klips_error:ipsec_sa_add: "
36465 + "null pointer passed in!\n");
36466 + return -ENODATA;
36467 + }
36468 + hashval = IPS_HASH(&ips->ips_said);
36469 +
36470 + ipsec_sa_get(ips);
36471 + spin_lock_bh(&tdb_lock);
36472 +
36473 + ips->ips_hnext = ipsec_sadb_hash[hashval];
36474 + ipsec_sadb_hash[hashval] = ips;
36475 +
36476 + spin_unlock_bh(&tdb_lock);
36477 +
36478 + return error;
36479 +}
36480 +
36481 +/*
36482 + * remove it from the hash chain, decrementing hash count
36483 + */
36484 +void ipsec_sa_rm(struct ipsec_sa *ips)
36485 +{
36486 + unsigned int hashval;
36487 + char sa[SATOT_BUF];
36488 + size_t sa_len;
36489 +
36490 +
36491 + if(ips == NULL) return;
36492 +
36493 +
36494 + hashval = IPS_HASH(&ips->ips_said);
36495 +
36496 + sa_len = KLIPS_SATOT(debug_xform, &ips->ips_said, 0, sa, sizeof(sa));
36497 + KLIPS_PRINT(debug_xform,
36498 + "klips_debug:ipsec_sa_del: "
36499 + "unhashing SA:%s (ref=%u), hashval=%d.\n",
36500 + sa_len ? sa : " (error)",
36501 + ips->ips_ref,
36502 + hashval);
36503 +
36504 + if(ipsec_sadb_hash[hashval] == NULL) {
36505 + return;
36506 + }
36507 +
36508 + if (ips == ipsec_sadb_hash[hashval]) {
36509 + ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext;
36510 + ips->ips_hnext = NULL;
36511 + ipsec_sa_put(ips);
36512 + KLIPS_PRINT(debug_xform,
36513 + "klips_debug:ipsec_sa_del: "
36514 + "successfully unhashed first ipsec_sa in chain.\n");
36515 + return;
36516 + } else {
36517 + struct ipsec_sa *ipstp;
36518 +
36519 + for (ipstp = ipsec_sadb_hash[hashval];
36520 + ipstp;
36521 + ipstp = ipstp->ips_hnext) {
36522 + if (ipstp->ips_hnext == ips) {
36523 + ipstp->ips_hnext = ips->ips_hnext;
36524 + ips->ips_hnext = NULL;
36525 + ipsec_sa_put(ips);
36526 + KLIPS_PRINT(debug_xform,
36527 + "klips_debug:ipsec_sa_del: "
36528 + "successfully unhashed link in ipsec_sa chain.\n");
36529 + return;
36530 + }
36531 + }
36532 + }
36533 +}
36534 +
36535 +
36536 +#if 0
36537 +/*
36538 + * The ipsec_sa table better be locked before it is handed in,
36539 + * or races might happen.
36540 + *
36541 + * this routine assumes the SA has a refcount==0, and we free it.
36542 + * we also assume that the pointers are already cleaned up.
36543 + */
36544 +static int
36545 +ipsec_sa_del(struct ipsec_sa *ips)
36546 +{
36547 + unsigned int hashval;
36548 + struct ipsec_sa *ipstp;
36549 + char sa[SATOT_BUF];
36550 + size_t sa_len;
36551 +
36552 + if(ips == NULL) {
36553 + KLIPS_ERROR(debug_xform,
36554 + "klips_error:ipsec_sa_del: "
36555 + "null pointer passed in!\n");
36556 + return -ENODATA;
36557 + }
36558 +
36559 + if(ips->ips_next) {
36560 + struct ipsec_sa *in = ips->ips_next;
36561 +
36562 + ips->ips_next=NULL;
36563 + ipsec_sa_put(in);
36564 + }
36565 +
36566 + sa_len = KLIPS_SATOT(debug_xform, &ips->ips_said, 0, sa, sizeof(sa));
36567 + hashval = IPS_HASH(&ips->ips_said);
36568 +
36569 + KLIPS_PRINT(debug_xform,
36570 + "klips_debug:ipsec_sa_del: "
36571 + "deleting SA:%s (ref=%u), hashval=%d.\n",
36572 + sa_len ? sa : " (error)",
36573 + ips->ips_ref,
36574 + hashval);
36575 +
36576 + if(ipsec_sadb_hash[hashval] == NULL) {
36577 + /* if this is NULL, then we can be sure that the SA was never
36578 + * added to the SADB, so we just free it.
36579 + */
36580 + KLIPS_PRINT(debug_xform,
36581 + "klips_debug:ipsec_sa_del: "
36582 + "no entries in ipsec_sa table for hash=%d (ref=%u) of SA:%s.\n",
36583 + hashval,
36584 + ips->ips_ref,
36585 + sa_len ? sa : " (error)");
36586 + return -ENOENT;
36587 + }
36588 +
36589 + if (ips == ipsec_sadb_hash[hashval]) {
36590 + ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext;
36591 + ips->ips_hnext = NULL;
36592 +
36593 + ipsec_sa_put(ips);
36594 + KLIPS_PRINT(debug_xform,
36595 + "klips_debug:ipsec_sa_del: "
36596 + "successfully deleted first ipsec_sa in chain.\n");
36597 + return 0;
36598 + } else {
36599 + for (ipstp = ipsec_sadb_hash[hashval];
36600 + ipstp;
36601 + ipstp = ipstp->ips_hnext) {
36602 + if (ipstp->ips_hnext == ips) {
36603 + ipstp->ips_hnext = ips->ips_hnext;
36604 + ips->ips_hnext = NULL;
36605 + ipsec_sa_put(ips);
36606 + KLIPS_PRINT(debug_xform,
36607 + "klips_debug:ipsec_sa_del: "
36608 + "successfully deleted link in ipsec_sa chain.\n");
36609 + return 0;
36610 + }
36611 + }
36612 + }
36613 +
36614 + KLIPS_PRINT(debug_xform,
36615 + "klips_debug:ipsec_sa_del: "
36616 + "no entries in linked list for hash=%d of SA:%s.\n",
36617 + hashval,
36618 + sa_len ? sa : " (error)");
36619 + return -ENOENT;
36620 +}
36621 +#endif
36622 +
36623 +int
36624 +ipsec_sadb_cleanup(__u8 proto)
36625 +{
36626 + unsigned i;
36627 + int error = 0;
36628 + struct ipsec_sa *ips;
36629 + //struct ipsec_sa *ipsnext, **ipsprev;
36630 + //char sa[SATOT_BUF];
36631 + //size_t sa_len;
36632 +
36633 + KLIPS_PRINT(debug_xform,
36634 + "klips_debug:ipsec_sadb_cleanup: "
36635 + "cleaning up proto=%d.\n",
36636 + proto);
36637 +
36638 + spin_lock_bh(&tdb_lock);
36639 +
36640 + for (i = 0; i < SADB_HASHMOD; i++) {
36641 + ips = ipsec_sadb_hash[i];
36642 +
36643 + while(ips) {
36644 + ipsec_sadb_hash[i]=ips->ips_hnext;
36645 + ips->ips_hnext=NULL;
36646 + ipsec_sa_put(ips);
36647 +
36648 + ips = ipsec_sadb_hash[i];
36649 + }
36650 + }
36651 +
36652 +//errlab:
36653 +
36654 + spin_unlock_bh(&tdb_lock);
36655 +
36656 +
36657 +#if IPSEC_SA_REF_CODE
36658 + /* clean up SA reference table */
36659 +
36660 + /* go through the ref table and clean out all the SAs */
36661 + KLIPS_PRINT(debug_xform,
36662 + "klips_debug:ipsec_sadb_cleanup: "
36663 + "removing SAref entries and tables.");
36664 + {
36665 + unsigned table, entry;
36666 + for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
36667 + KLIPS_PRINT(debug_xform,
36668 + "klips_debug:ipsec_sadb_cleanup: "
36669 + "cleaning SAref table=%u.\n",
36670 + table);
36671 + if(ipsec_sadb.refTable[table] == NULL) {
36672 + printk("\n");
36673 + KLIPS_PRINT(debug_xform,
36674 + "klips_debug:ipsec_sadb_cleanup: "
36675 + "cleaned %u used refTables.\n",
36676 + table);
36677 + break;
36678 + }
36679 + for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
36680 + if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
36681 + struct ipsec_sa *sa1 = ipsec_sadb.refTable[table]->entry[entry];
36682 + ipsec_sa_put(sa1);
36683 + ipsec_sadb.refTable[table]->entry[entry] = NULL;
36684 + }
36685 + }
36686 + }
36687 + }
36688 +#endif /* IPSEC_SA_REF_CODE */
36689 +
36690 + return(error);
36691 +}
36692 +
36693 +int
36694 +ipsec_sadb_free(void)
36695 +{
36696 + int error = 0;
36697 +
36698 + KLIPS_PRINT(debug_xform,
36699 + "klips_debug:ipsec_sadb_free: "
36700 + "freeing SArefTable memory.\n");
36701 +
36702 + /* clean up SA reference table */
36703 +
36704 + /* go through the ref table and clean out all the SAs if any are
36705 + left and free table memory */
36706 + KLIPS_PRINT(debug_xform,
36707 + "klips_debug:ipsec_sadb_free: "
36708 + "removing SAref entries and tables.\n");
36709 + {
36710 + unsigned table, entry;
36711 + for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
36712 + KLIPS_PRINT(debug_xform,
36713 + "klips_debug:ipsec_sadb_free: "
36714 + "removing SAref table=%u.\n",
36715 + table);
36716 + if(ipsec_sadb.refTable[table] == NULL) {
36717 + KLIPS_PRINT(debug_xform,
36718 + "klips_debug:ipsec_sadb_free: "
36719 + "removed %u used refTables.\n",
36720 + table);
36721 + break;
36722 + }
36723 + for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
36724 + if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
36725 + struct ipsec_sa *sa1 = ipsec_sadb.refTable[table]->entry[entry];
36726 +
36727 + BUG_ON(atomic_read(&sa1->ips_refcount) == 1);
36728 + ipsec_sa_put(sa1);
36729 + ipsec_sadb.refTable[table]->entry[entry] = NULL;
36730 + }
36731 + }
36732 + vfree(ipsec_sadb.refTable[table]);
36733 + ipsec_sadb.refTable[table] = NULL;
36734 + }
36735 + }
36736 +
36737 + return(error);
36738 +}
36739 +
36740 +int
36741 +ipsec_sa_wipe(struct ipsec_sa *ips)
36742 +{
36743 + if(ips == NULL) {
36744 + return -ENODATA;
36745 + }
36746 +
36747 +#if IPSEC_SA_REF_CODE
36748 + /* remove me from the SArefTable */
36749 + if(debug_xform)
36750 + {
36751 + char sa[SATOT_BUF];
36752 + size_t sa_len;
36753 + struct IPsecSArefSubTable *subtable = NULL;
36754 +
36755 + if(IPsecSAref2table(IPsecSA2SAref(ips))<IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES
36756 + && ipsec_sadb.refTable != NULL) {
36757 + subtable = ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))];
36758 + }
36759 +
36760 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
36761 + KLIPS_PRINT(debug_xform,
36762 + "klips_debug:ipsec_sa_wipe: "
36763 + "removing SA=%s(0p%p), SAref=%d, table=%d(0p%p), entry=%d from the refTable.\n",
36764 + sa_len ? sa : " (error)",
36765 + ips,
36766 + ips->ips_ref,
36767 + IPsecSAref2table(IPsecSA2SAref(ips)),
36768 + subtable,
36769 + subtable ? IPsecSAref2entry(IPsecSA2SAref(ips)) : 0);
36770 + }
36771 +
36772 + if(ips->ips_ref != IPSEC_SAREF_NULL) {
36773 + struct IPsecSArefSubTable *subtable = NULL;
36774 + int ref_table=IPsecSAref2table(IPsecSA2SAref(ips));
36775 + int ref_entry=IPsecSAref2entry(IPsecSA2SAref(ips));
36776 +
36777 + if(ref_table < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) {
36778 + subtable = ipsec_sadb.refTable[ref_table];
36779 + if(subtable!=NULL && subtable->entry[ref_entry] == ips) {
36780 +
36781 + subtable->entry[ref_entry] = NULL;
36782 + }
36783 + }
36784 + ips->ips_ref = IPSEC_SAREF_NULL;
36785 + }
36786 +#endif /* IPSEC_SA_REF_CODE */
36787 +
36788 + /* paranoid clean up */
36789 + if(ips->ips_addr_s != NULL) {
36790 + memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size);
36791 + kfree(ips->ips_addr_s);
36792 + }
36793 + ips->ips_addr_s = NULL;
36794 +
36795 + if(ips->ips_addr_d != NULL) {
36796 + memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size);
36797 + kfree(ips->ips_addr_d);
36798 + }
36799 + ips->ips_addr_d = NULL;
36800 +
36801 + if(ips->ips_addr_p != NULL) {
36802 + memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size);
36803 + kfree(ips->ips_addr_p);
36804 + }
36805 + ips->ips_addr_p = NULL;
36806 +
36807 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
36808 + if(ips->ips_natt_oa) {
36809 + memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size);
36810 + kfree(ips->ips_natt_oa);
36811 + }
36812 + ips->ips_natt_oa = NULL;
36813 +#endif
36814 +
36815 + if(ips->ips_key_a != NULL) {
36816 + memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size);
36817 + kfree(ips->ips_key_a);
36818 + }
36819 + ips->ips_key_a = NULL;
36820 +
36821 + if(ips->ips_key_e != NULL) {
36822 +#ifdef CONFIG_KLIPS_ALG
36823 + if (ips->ips_alg_enc &&
36824 + ips->ips_alg_enc->ixt_e_destroy_key)
36825 + {
36826 + ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc,
36827 + ips->ips_key_e);
36828 + } else
36829 +#endif
36830 + {
36831 + memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size);
36832 + kfree(ips->ips_key_e);
36833 + }
36834 + }
36835 + ips->ips_key_e = NULL;
36836 +
36837 + if(ips->ips_iv != NULL) {
36838 + memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
36839 + kfree(ips->ips_iv);
36840 + }
36841 + ips->ips_iv = NULL;
36842 +
36843 +#ifdef CONFIG_KLIPS_OCF
36844 + if (ips->ocf_in_use)
36845 + ipsec_ocf_sa_free(ips);
36846 +#endif
36847 +
36848 + if(ips->ips_ident_s.data != NULL) {
36849 + memset((caddr_t)(ips->ips_ident_s.data),
36850 + 0,
36851 + ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
36852 + kfree(ips->ips_ident_s.data);
36853 + }
36854 + ips->ips_ident_s.data = NULL;
36855 +
36856 + if(ips->ips_ident_d.data != NULL) {
36857 + memset((caddr_t)(ips->ips_ident_d.data),
36858 + 0,
36859 + ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
36860 + kfree(ips->ips_ident_d.data);
36861 + }
36862 + ips->ips_ident_d.data = NULL;
36863 +
36864 +#ifdef CONFIG_KLIPS_ALG
36865 + if (ips->ips_alg_enc||ips->ips_alg_auth) {
36866 + ipsec_alg_sa_wipe(ips);
36867 + }
36868 +#endif
36869 +
36870 + BUG_ON(atomic_read(&ips->ips_refcount) != 0);
36871 +
36872 + memset((caddr_t)ips, 0, sizeof(*ips));
36873 + kfree(ips);
36874 + ips = NULL;
36875 +
36876 + return 0;
36877 +}
36878 +
36879 +extern int sysctl_ipsec_debug_verbose;
36880 +
36881 +int ipsec_sa_init(struct ipsec_sa *ipsp)
36882 +{
36883 + int error = 0;
36884 + char sa[SATOT_BUF];
36885 + size_t sa_len;
36886 + char ipaddr_txt[ADDRTOA_BUF];
36887 + char ipaddr2_txt[ADDRTOA_BUF];
36888 +#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || defined (CONFIG_KLIPS_AUTH_HMAC_SHA1)
36889 + unsigned char kb[AHMD596_BLKLEN];
36890 +#endif
36891 +#ifdef CONFIG_KLIPS_ALG
36892 + struct ipsec_alg_enc *ixt_e = NULL;
36893 + struct ipsec_alg_auth *ixt_a = NULL;
36894 + int i;
36895 +#endif
36896 +
36897 + if(ipsp == NULL) {
36898 + KLIPS_PRINT(debug_pfkey,
36899 + "ipsec_sa_init: "
36900 + "ipsp is NULL, fatal\n");
36901 + SENDERR(EINVAL);
36902 + }
36903 +
36904 + sa_len = KLIPS_SATOT(debug_pfkey, &ipsp->ips_said, 0, sa, sizeof(sa));
36905 +
36906 + KLIPS_PRINT(debug_pfkey,
36907 + "ipsec_sa_init: "
36908 + "(pfkey defined) called for SA:%s\n",
36909 + sa_len ? sa : " (error)");
36910 +
36911 + KLIPS_PRINT(debug_pfkey,
36912 + "ipsec_sa_init: "
36913 + "calling init routine of %s%s%s\n",
36914 + IPS_XFORM_NAME(ipsp));
36915 +
36916 + switch(ipsp->ips_said.proto) {
36917 +#ifdef CONFIG_KLIPS_IPIP
36918 + case IPPROTO_IPIP: {
36919 + ipsp->ips_xformfuncs = ipip_xform_funcs;
36920 + addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr,
36921 + 0,
36922 + ipaddr_txt, sizeof(ipaddr_txt));
36923 + addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
36924 + 0,
36925 + ipaddr2_txt, sizeof(ipaddr_txt));
36926 + KLIPS_PRINT(debug_pfkey,
36927 + "ipsec_sa_init: "
36928 + "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n",
36929 + ipaddr_txt,
36930 + ipaddr2_txt);
36931 + }
36932 + break;
36933 +#endif /* !CONFIG_KLIPS_IPIP */
36934 +
36935 +#ifdef CONFIG_KLIPS_AH
36936 + case IPPROTO_AH:
36937 +
36938 +#ifdef CONFIG_KLIPS_OCF
36939 + if (ipsec_ocf_sa_init(ipsp, ipsp->ips_authalg, 0))
36940 + break;
36941 +#endif
36942 +
36943 + ipsp->ips_xformfuncs = ah_xform_funcs;
36944 + switch(ipsp->ips_authalg) {
36945 +# ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
36946 + case AH_MD5: {
36947 + unsigned char *akp;
36948 + unsigned int aks;
36949 + MD5_CTX *ictx;
36950 + MD5_CTX *octx;
36951 +
36952 + if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
36953 + KLIPS_PRINT(debug_pfkey,
36954 + "ipsec_sa_init: "
36955 + "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
36956 + ipsp->ips_key_bits_a, AHMD596_KLEN * 8);
36957 + SENDERR(EINVAL);
36958 + }
36959 +
36960 +# if KLIPS_DIVULGE_HMAC_KEY
36961 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
36962 + "ipsec_sa_init: "
36963 + "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
36964 + ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
36965 + ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
36966 + ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
36967 + ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
36968 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
36969 +
36970 + ipsp->ips_auth_bits = AHMD596_ALEN * 8;
36971 +
36972 + /* save the pointer to the key material */
36973 + akp = ipsp->ips_key_a;
36974 + aks = ipsp->ips_key_a_size;
36975 +
36976 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
36977 + "ipsec_sa_init: "
36978 + "allocating %lu bytes for md5_ctx.\n",
36979 + (unsigned long) sizeof(struct md5_ctx));
36980 + if((ipsp->ips_key_a = (caddr_t)
36981 + kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
36982 + ipsp->ips_key_a = akp;
36983 + SENDERR(ENOMEM);
36984 + }
36985 + ipsp->ips_key_a_size = sizeof(struct md5_ctx);
36986 +
36987 + for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
36988 + kb[i] = akp[i] ^ HMAC_IPAD;
36989 + }
36990 + for (; i < AHMD596_BLKLEN; i++) {
36991 + kb[i] = HMAC_IPAD;
36992 + }
36993 +
36994 + ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
36995 + osMD5Init(ictx);
36996 + osMD5Update(ictx, kb, AHMD596_BLKLEN);
36997 +
36998 + for (i = 0; i < AHMD596_BLKLEN; i++) {
36999 + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37000 + }
37001 +
37002 + octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
37003 + osMD5Init(octx);
37004 + osMD5Update(octx, kb, AHMD596_BLKLEN);
37005 +
37006 +# if KLIPS_DIVULGE_HMAC_KEY
37007 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37008 + "ipsec_sa_init: "
37009 + "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37010 + ((__u32*)ictx)[0],
37011 + ((__u32*)ictx)[1],
37012 + ((__u32*)ictx)[2],
37013 + ((__u32*)ictx)[3],
37014 + ((__u32*)octx)[0],
37015 + ((__u32*)octx)[1],
37016 + ((__u32*)octx)[2],
37017 + ((__u32*)octx)[3] );
37018 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37019 +
37020 + /* zero key buffer -- paranoid */
37021 + memset(akp, 0, aks);
37022 + kfree(akp);
37023 + }
37024 + break;
37025 +# endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
37026 +# ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
37027 + case AH_SHA: {
37028 + unsigned char *akp;
37029 + unsigned int aks;
37030 + SHA1_CTX *ictx;
37031 + SHA1_CTX *octx;
37032 +
37033 + if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
37034 + KLIPS_PRINT(debug_pfkey,
37035 + "ipsec_sa_init: "
37036 + "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37037 + ipsp->ips_key_bits_a, AHSHA196_KLEN * 8);
37038 + SENDERR(EINVAL);
37039 + }
37040 +
37041 +# if KLIPS_DIVULGE_HMAC_KEY
37042 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37043 + "ipsec_sa_init: "
37044 + "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
37045 + ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
37046 + ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
37047 + ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
37048 + ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
37049 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37050 +
37051 + ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
37052 +
37053 + /* save the pointer to the key material */
37054 + akp = ipsp->ips_key_a;
37055 + aks = ipsp->ips_key_a_size;
37056 +
37057 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37058 + "ipsec_sa_init: "
37059 + "allocating %lu bytes for sha1_ctx.\n",
37060 + (unsigned long) sizeof(struct sha1_ctx));
37061 + if((ipsp->ips_key_a = (caddr_t)
37062 + kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
37063 + ipsp->ips_key_a = akp;
37064 + SENDERR(ENOMEM);
37065 + }
37066 + ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
37067 +
37068 + for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37069 + kb[i] = akp[i] ^ HMAC_IPAD;
37070 + }
37071 + for (; i < AHMD596_BLKLEN; i++) {
37072 + kb[i] = HMAC_IPAD;
37073 + }
37074 +
37075 + ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
37076 + SHA1Init(ictx);
37077 + SHA1Update(ictx, kb, AHSHA196_BLKLEN);
37078 +
37079 + for (i = 0; i < AHSHA196_BLKLEN; i++) {
37080 + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37081 + }
37082 +
37083 + octx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->octx);
37084 + SHA1Init(octx);
37085 + SHA1Update(octx, kb, AHSHA196_BLKLEN);
37086 +
37087 +# if KLIPS_DIVULGE_HMAC_KEY
37088 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37089 + "ipsec_sa_init: "
37090 + "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37091 + ((__u32*)ictx)[0],
37092 + ((__u32*)ictx)[1],
37093 + ((__u32*)ictx)[2],
37094 + ((__u32*)ictx)[3],
37095 + ((__u32*)octx)[0],
37096 + ((__u32*)octx)[1],
37097 + ((__u32*)octx)[2],
37098 + ((__u32*)octx)[3] );
37099 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37100 + /* zero key buffer -- paranoid */
37101 + memset(akp, 0, aks);
37102 + kfree(akp);
37103 + }
37104 + break;
37105 +# endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
37106 + default:
37107 + KLIPS_PRINT(debug_pfkey,
37108 + "ipsec_sa_init: "
37109 + "authalg=%d support not available in the kernel",
37110 + ipsp->ips_authalg);
37111 + SENDERR(EINVAL);
37112 + }
37113 + break;
37114 +#endif /* CONFIG_KLIPS_AH */
37115 +
37116 +#ifdef CONFIG_KLIPS_ESP
37117 + case IPPROTO_ESP:
37118 + ipsp->ips_xformfuncs = esp_xform_funcs;
37119 + {
37120 +#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || defined (CONFIG_KLIPS_AUTH_HMAC_SHA1)
37121 + unsigned char *akp;
37122 + unsigned int aks;
37123 +#endif
37124 +
37125 +#ifdef CONFIG_KLIPS_OCF
37126 + if (ipsec_ocf_sa_init(ipsp, ipsp->ips_authalg, ipsp->ips_encalg))
37127 + break;
37128 +#endif
37129 +
37130 +#ifdef CONFIG_KLIPS_ALG
37131 + ipsec_alg_sa_init(ipsp);
37132 + ixt_e=ipsp->ips_alg_enc;
37133 +
37134 + if (ixt_e == NULL) {
37135 + if(printk_ratelimit()) {
37136 + printk(KERN_ERR
37137 + "ipsec_sa_init: "
37138 + "encalg=%d support not available in the kernel",
37139 + ipsp->ips_encalg);
37140 + }
37141 + SENDERR(ENOENT);
37142 + }
37143 +
37144 + ipsp->ips_iv_size = ixt_e->ixt_common.ixt_support.ias_ivlen/8;
37145 +
37146 + /* Create IV */
37147 + if (ipsp->ips_iv_size) {
37148 + if((ipsp->ips_iv = (caddr_t)
37149 + kmalloc(ipsp->ips_iv_size, GFP_ATOMIC)) == NULL) {
37150 + SENDERR(ENOMEM);
37151 + }
37152 + prng_bytes(&ipsec_prng,
37153 + (char *)ipsp->ips_iv,
37154 + ipsp->ips_iv_size);
37155 + ipsp->ips_iv_bits = ipsp->ips_iv_size * 8;
37156 + }
37157 +
37158 + if ((error=ipsec_alg_enc_key_create(ipsp)) < 0)
37159 + SENDERR(-error);
37160 +
37161 + if ((ixt_a=ipsp->ips_alg_auth)) {
37162 + if ((error=ipsec_alg_auth_key_create(ipsp)) < 0)
37163 + SENDERR(-error);
37164 + } else
37165 +#endif /* CONFIG_KLIPS_ALG */
37166 +
37167 + switch(ipsp->ips_authalg) {
37168 +# ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
37169 + case AH_MD5: {
37170 + MD5_CTX *ictx;
37171 + MD5_CTX *octx;
37172 +
37173 + if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
37174 + KLIPS_PRINT(debug_pfkey,
37175 + "ipsec_sa_init: "
37176 + "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37177 + ipsp->ips_key_bits_a,
37178 + AHMD596_KLEN * 8);
37179 + SENDERR(EINVAL);
37180 + }
37181 +
37182 +# if KLIPS_DIVULGE_HMAC_KEY
37183 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37184 + "ipsec_sa_init: "
37185 + "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
37186 + ntohl(*(((__u32 *)(ipsp->ips_key_a))+0)),
37187 + ntohl(*(((__u32 *)(ipsp->ips_key_a))+1)),
37188 + ntohl(*(((__u32 *)(ipsp->ips_key_a))+2)),
37189 + ntohl(*(((__u32 *)(ipsp->ips_key_a))+3)));
37190 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37191 + ipsp->ips_auth_bits = AHMD596_ALEN * 8;
37192 +
37193 + /* save the pointer to the key material */
37194 + akp = ipsp->ips_key_a;
37195 + aks = ipsp->ips_key_a_size;
37196 +
37197 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37198 + "ipsec_sa_init: "
37199 + "allocating %lu bytes for md5_ctx.\n",
37200 + (unsigned long) sizeof(struct md5_ctx));
37201 + if((ipsp->ips_key_a = (caddr_t)
37202 + kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
37203 + ipsp->ips_key_a = akp;
37204 + SENDERR(ENOMEM);
37205 + }
37206 + ipsp->ips_key_a_size = sizeof(struct md5_ctx);
37207 +
37208 + for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37209 + kb[i] = akp[i] ^ HMAC_IPAD;
37210 + }
37211 + for (; i < AHMD596_BLKLEN; i++) {
37212 + kb[i] = HMAC_IPAD;
37213 + }
37214 +
37215 + ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
37216 + osMD5Init(ictx);
37217 + osMD5Update(ictx, kb, AHMD596_BLKLEN);
37218 +
37219 + for (i = 0; i < AHMD596_BLKLEN; i++) {
37220 + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37221 + }
37222 +
37223 + octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
37224 + osMD5Init(octx);
37225 + osMD5Update(octx, kb, AHMD596_BLKLEN);
37226 +
37227 +# if KLIPS_DIVULGE_HMAC_KEY
37228 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37229 + "ipsec_sa_init: "
37230 + "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37231 + ((__u32*)ictx)[0],
37232 + ((__u32*)ictx)[1],
37233 + ((__u32*)ictx)[2],
37234 + ((__u32*)ictx)[3],
37235 + ((__u32*)octx)[0],
37236 + ((__u32*)octx)[1],
37237 + ((__u32*)octx)[2],
37238 + ((__u32*)octx)[3] );
37239 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37240 + /* paranoid */
37241 + memset(akp, 0, aks);
37242 + kfree(akp);
37243 + break;
37244 + }
37245 +# endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
37246 +# ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
37247 + case AH_SHA: {
37248 + SHA1_CTX *ictx;
37249 + SHA1_CTX *octx;
37250 +
37251 + if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
37252 + KLIPS_PRINT(debug_pfkey,
37253 + "ipsec_sa_init: "
37254 + "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37255 + ipsp->ips_key_bits_a,
37256 + AHSHA196_KLEN * 8);
37257 + SENDERR(EINVAL);
37258 + }
37259 +
37260 +# if KLIPS_DIVULGE_HMAC_KEY
37261 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37262 + "ipsec_sa_init: "
37263 + "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
37264 + ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
37265 + ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
37266 + ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
37267 + ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
37268 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37269 + ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
37270 +
37271 + /* save the pointer to the key material */
37272 + akp = ipsp->ips_key_a;
37273 + aks = ipsp->ips_key_a_size;
37274 +
37275 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37276 + "ipsec_sa_init: "
37277 + "allocating %lu bytes for sha1_ctx.\n",
37278 + (unsigned long) sizeof(struct sha1_ctx));
37279 + if((ipsp->ips_key_a = (caddr_t)
37280 + kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
37281 + ipsp->ips_key_a = akp;
37282 + SENDERR(ENOMEM);
37283 + }
37284 + ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
37285 +
37286 + for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37287 + kb[i] = akp[i] ^ HMAC_IPAD;
37288 + }
37289 + for (; i < AHMD596_BLKLEN; i++) {
37290 + kb[i] = HMAC_IPAD;
37291 + }
37292 +
37293 + ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
37294 + SHA1Init(ictx);
37295 + SHA1Update(ictx, kb, AHSHA196_BLKLEN);
37296 +
37297 + for (i = 0; i < AHSHA196_BLKLEN; i++) {
37298 + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37299 + }
37300 +
37301 + octx = &((struct sha1_ctx*)(ipsp->ips_key_a))->octx;
37302 + SHA1Init(octx);
37303 + SHA1Update(octx, kb, AHSHA196_BLKLEN);
37304 +
37305 +# if KLIPS_DIVULGE_HMAC_KEY
37306 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37307 + "ipsec_sa_init: "
37308 + "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37309 + ((__u32*)ictx)[0],
37310 + ((__u32*)ictx)[1],
37311 + ((__u32*)ictx)[2],
37312 + ((__u32*)ictx)[3],
37313 + ((__u32*)octx)[0],
37314 + ((__u32*)octx)[1],
37315 + ((__u32*)octx)[2],
37316 + ((__u32*)octx)[3] );
37317 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37318 + memset(akp, 0, aks);
37319 + kfree(akp);
37320 + break;
37321 + }
37322 +# endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
37323 + case AH_NONE:
37324 + break;
37325 + default:
37326 + KLIPS_PRINT(debug_pfkey,
37327 + "ipsec_sa_init: "
37328 + "authalg=%d support not available in the kernel.\n",
37329 + ipsp->ips_authalg);
37330 + SENDERR(EINVAL);
37331 + }
37332 + }
37333 + break;
37334 +#endif /* !CONFIG_KLIPS_ESP */
37335 +#ifdef CONFIG_KLIPS_IPCOMP
37336 + case IPPROTO_COMP:
37337 + ipsp->ips_xformfuncs = ipcomp_xform_funcs;
37338 + ipsp->ips_comp_adapt_tries = 0;
37339 + ipsp->ips_comp_adapt_skip = 0;
37340 + ipsp->ips_comp_ratio_cbytes = 0;
37341 + ipsp->ips_comp_ratio_dbytes = 0;
37342 + break;
37343 +#endif /* CONFIG_KLIPS_IPCOMP */
37344 + default:
37345 + printk(KERN_ERR "KLIPS sa initialization: "
37346 + "proto=%d unknown.\n",
37347 + ipsp->ips_said.proto);
37348 + SENDERR(EINVAL);
37349 + }
37350 +
37351 + errlab:
37352 + return(error);
37353 +}
37354 +
37355 +/*
37356 + *
37357 + * Local Variables:
37358 + * c-file-style: "linux"
37359 + * End:
37360 + *
37361 + */
37362 +
37363 --- /dev/null Tue Mar 11 13:02:56 2003
37364 +++ linux/net/ipsec/ipsec_sha1.c Mon Feb 9 13:51:03 2004
37365 @@ -0,0 +1,177 @@
37366 +/*
37367 + * RCSID $Id: ipsec_sha1.c,v 1.9 2004/04/06 02:49:26 mcr Exp $
37368 + */
37369 +
37370 +/*
37371 + * The rest of the code is derived from sha1.c by Steve Reid, which is
37372 + * public domain.
37373 + * Minor cosmetic changes to accomodate it in the Linux kernel by ji.
37374 + */
37375 +
37376 +#include <asm/byteorder.h>
37377 +#include <linux/string.h>
37378 +
37379 +#include "openswan/ipsec_sha1.h"
37380 +
37381 +#if defined(rol)
37382 +#undef rol
37383 +#endif
37384 +
37385 +#define SHA1HANDSOFF
37386 +
37387 +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
37388 +
37389 +/* blk0() and blk() perform the initial expand. */
37390 +/* I got the idea of expanding during the round function from SSLeay */
37391 +#ifdef __LITTLE_ENDIAN
37392 +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
37393 + |(rol(block->l[i],8)&0x00FF00FF))
37394 +#else
37395 +#define blk0(i) block->l[i]
37396 +#endif
37397 +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
37398 + ^block->l[(i+2)&15]^block->l[i&15],1))
37399 +
37400 +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
37401 +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
37402 +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
37403 +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
37404 +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
37405 +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
37406 +
37407 +
37408 +/* Hash a single 512-bit block. This is the core of the algorithm. */
37409 +
37410 +void SHA1Transform(__u32 state[5], __u8 buffer[64])
37411 +{
37412 +__u32 a, b, c, d, e;
37413 +typedef union {
37414 + unsigned char c[64];
37415 + __u32 l[16];
37416 +} CHAR64LONG16;
37417 +CHAR64LONG16* block;
37418 +#ifdef SHA1HANDSOFF
37419 +static unsigned char workspace[64];
37420 + block = (CHAR64LONG16*)workspace;
37421 + memcpy(block, buffer, 64);
37422 +#else
37423 + block = (CHAR64LONG16*)buffer;
37424 +#endif
37425 + /* Copy context->state[] to working vars */
37426 + a = state[0];
37427 + b = state[1];
37428 + c = state[2];
37429 + d = state[3];
37430 + e = state[4];
37431 + /* 4 rounds of 20 operations each. Loop unrolled. */
37432 + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
37433 + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
37434 + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
37435 + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
37436 + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
37437 + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
37438 + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
37439 + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
37440 + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
37441 + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
37442 + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
37443 + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
37444 + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
37445 + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
37446 + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
37447 + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
37448 + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
37449 + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
37450 + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
37451 + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
37452 + /* Add the working vars back into context.state[] */
37453 + state[0] += a;
37454 + state[1] += b;
37455 + state[2] += c;
37456 + state[3] += d;
37457 + state[4] += e;
37458 + /* Wipe variables */
37459 + a = b = c = d = e = 0;
37460 +}
37461 +
37462 +
37463 +/* SHA1Init - Initialize new context */
37464 +
37465 +void SHA1Init(void *vcontext)
37466 +{
37467 + SHA1_CTX* context = vcontext;
37468 +
37469 + /* SHA1 initialization constants */
37470 + context->state[0] = 0x67452301;
37471 + context->state[1] = 0xEFCDAB89;
37472 + context->state[2] = 0x98BADCFE;
37473 + context->state[3] = 0x10325476;
37474 + context->state[4] = 0xC3D2E1F0;
37475 + context->count[0] = context->count[1] = 0;
37476 +}
37477 +
37478 +
37479 +/* Run your data through this. */
37480 +
37481 +void SHA1Update(void *vcontext, unsigned char* data, __u32 len)
37482 +{
37483 + SHA1_CTX* context = vcontext;
37484 + __u32 i, j;
37485 +
37486 + j = context->count[0];
37487 + if ((context->count[0] += len << 3) < j)
37488 + context->count[1]++;
37489 + context->count[1] += (len>>29);
37490 + j = (j >> 3) & 63;
37491 + if ((j + len) > 63) {
37492 + memcpy(&context->buffer[j], data, (i = 64-j));
37493 + SHA1Transform(context->state, context->buffer);
37494 + for ( ; i + 63 < len; i += 64) {
37495 + SHA1Transform(context->state, &data[i]);
37496 + }
37497 + j = 0;
37498 + }
37499 + else i = 0;
37500 + memcpy(&context->buffer[j], &data[i], len - i);
37501 +}
37502 +
37503 +
37504 +/* Add padding and return the message digest. */
37505 +
37506 +void SHA1Final(unsigned char digest[20], void *vcontext)
37507 +{
37508 + __u32 i, j;
37509 + unsigned char finalcount[8];
37510 + SHA1_CTX* context = vcontext;
37511 +
37512 + for (i = 0; i < 8; i++) {
37513 + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
37514 + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
37515 + }
37516 + SHA1Update(context, (unsigned char *)"\200", 1);
37517 + while ((context->count[0] & 504) != 448) {
37518 + SHA1Update(context, (unsigned char *)"\0", 1);
37519 + }
37520 + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
37521 + for (i = 0; i < 20; i++) {
37522 + digest[i] = (unsigned char)
37523 + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
37524 + }
37525 + /* Wipe variables */
37526 + i = j = 0;
37527 + memset(context->buffer, 0, 64);
37528 + memset(context->state, 0, 20);
37529 + memset(context->count, 0, 8);
37530 + memset(&finalcount, 0, 8);
37531 +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
37532 + SHA1Transform(context->state, context->buffer);
37533 +#endif
37534 +}
37535 +
37536 +/*
37537 + *
37538 + * Local Variables:
37539 + * c-file-style: "linux"
37540 + * End:
37541 + *
37542 + */
37543 --- /dev/null Tue Mar 11 13:02:56 2003
37544 +++ linux/net/ipsec/ipsec_snprintf.c Mon Feb 9 13:51:03 2004
37545 @@ -0,0 +1,121 @@
37546 +/*
37547 + * @(#) ipsec_snprintf() function
37548 + *
37549 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
37550 + * 2001 Michael Richardson <mcr@freeswan.org>
37551 + * Copyright (C) 2005 Michael Richardson <mcr@xelerance.com>
37552 + *
37553 + * This program is free software; you can redistribute it and/or modify it
37554 + * under the terms of the GNU General Public License as published by the
37555 + * Free Software Foundation; either version 2 of the License, or (at your
37556 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
37557 + *
37558 + * This program is distributed in the hope that it will be useful, but
37559 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
37560 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37561 + * for more details.
37562 + *
37563 + * Split out from ipsec_proc.c.
37564 + */
37565 +
37566 +#ifndef AUTOCONF_INCLUDED
37567 +#include <linux/config.h>
37568 +#endif
37569 +#include <linux/version.h>
37570 +#define __NO_VERSION__
37571 +#include <linux/module.h>
37572 +#include <linux/kernel.h> /* printk() */
37573 +
37574 +#include "openswan/ipsec_kversion.h"
37575 +#include "openswan/ipsec_param.h"
37576 +
37577 +#include <net/ip.h>
37578 +
37579 +#include "openswan/radij.h"
37580 +
37581 +#include "openswan/ipsec_life.h"
37582 +#include "openswan/ipsec_stats.h"
37583 +#include "openswan/ipsec_sa.h"
37584 +
37585 +#include "openswan/ipsec_encap.h"
37586 +#include "openswan/ipsec_radij.h"
37587 +#include "openswan/ipsec_xform.h"
37588 +#include "openswan/ipsec_tunnel.h"
37589 +#include "openswan/ipsec_xmit.h"
37590 +
37591 +#include "openswan/ipsec_rcv.h"
37592 +#include "openswan/ipsec_ah.h"
37593 +#include "openswan/ipsec_esp.h"
37594 +#include "openswan/ipsec_kern24.h"
37595 +
37596 +#ifdef CONFIG_KLIPS_IPCOMP
37597 +#include "openswan/ipcomp.h"
37598 +#endif /* CONFIG_KLIPS_IPCOMP */
37599 +
37600 +#include "openswan/ipsec_proto.h"
37601 +
37602 +#include <openswan/pfkeyv2.h>
37603 +#include <openswan/pfkey.h>
37604 +
37605 +/* ipsec_snprintf: like snprintf except
37606 + * - size is signed and a negative value is treated as if it were 0
37607 + * - the returned result is never negative --
37608 + * an error generates a "?" or null output (depending on space).
37609 + * (Our callers are too lazy to check for an error return.)
37610 + *
37611 + * @param buf String buffer
37612 + * @param size Size of the string
37613 + * @param fmt printf string
37614 + * @param ... Variables to be displayed in fmt
37615 + * @return int Return code
37616 + */
37617 +int ipsec_snprintf(char *buf, ssize_t size, const char *fmt, ...)
37618 +{
37619 + va_list args;
37620 + int i;
37621 + size_t possize = size < 0? 0 : size;
37622 + va_start(args, fmt);
37623 + i = vsnprintf(buf,possize,fmt,args);
37624 + va_end(args);
37625 + if (i < 0) {
37626 + /* create empty output in place of error */
37627 + i = 0;
37628 + if (size > 0) {
37629 + *buf = '\0';
37630 + }
37631 + }
37632 + return i;
37633 +}
37634 +
37635 +
37636 +void ipsec_dmp_block(char *s, caddr_t bb, int len)
37637 +{
37638 + int i;
37639 + unsigned char *b = bb;
37640 +
37641 + printk(KERN_INFO "klips_dmp: "
37642 + "at %s, len=%d:\n", s, len);
37643 +
37644 + for(i = 0; i < len; i++ /*, c++*/) {
37645 + if(!(i % 16)) {
37646 + printk(KERN_INFO
37647 + "klips_debug: @%03x:",
37648 + i);
37649 + }
37650 + printk(" %02x", b[i]);
37651 + if(!((i + 1) % 16)) {
37652 + printk("\n");
37653 + }
37654 + }
37655 + if(i % 16) {
37656 + printk("\n");
37657 + }
37658 +}
37659 +
37660 +/*
37661 + * Local Variables:
37662 + * c-file-style: "linux"
37663 + * End:
37664 + *
37665 + */
37666 +
37667 --- /dev/null Tue Mar 11 13:02:56 2003
37668 +++ linux/net/ipsec/ipsec_tunnel.c Mon Feb 9 13:51:03 2004
37669 @@ -0,0 +1,2004 @@
37670 +/*
37671 + * IPSEC Tunneling code. Heavily based on drivers/net/new_tunnel.c
37672 + * Copyright (C) 1996, 1997 John Ioannidis.
37673 + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
37674 + *
37675 + * OCF/receive state machine written by
37676 + * David McCullough <dmccullough@cyberguard.com>
37677 + * Copyright (C) 2004-2005 Intel Corporation. All Rights Reserved.
37678 + *
37679 + * This program is free software; you can redistribute it and/or modify it
37680 + * under the terms of the GNU General Public License as published by the
37681 + * Free Software Foundation; either version 2 of the License, or (at your
37682 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
37683 + *
37684 + * This program is distributed in the hope that it will be useful, but
37685 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
37686 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37687 + * for more details.
37688 + */
37689 +
37690 +#define __NO_VERSION__
37691 +#include <linux/module.h>
37692 +#ifndef AUTOCONF_INCLUDED
37693 +#include <linux/config.h>
37694 +#endif /* for CONFIG_IP_FORWARD */
37695 +#include <linux/version.h>
37696 +#include <linux/kernel.h> /* printk() */
37697 +
37698 +#include "openswan/ipsec_param.h"
37699 +
37700 +#ifdef MALLOC_SLAB
37701 +# include <linux/slab.h> /* kmalloc() */
37702 +#else /* MALLOC_SLAB */
37703 +# include <linux/malloc.h> /* kmalloc() */
37704 +#endif /* MALLOC_SLAB */
37705 +#include <linux/errno.h> /* error codes */
37706 +#include <linux/types.h> /* size_t */
37707 +#include <linux/interrupt.h> /* mark_bh */
37708 +
37709 +#include <net/tcp.h>
37710 +#include <net/udp.h>
37711 +#include <linux/skbuff.h>
37712 +
37713 +#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
37714 +#include <linux/etherdevice.h> /* eth_type_trans */
37715 +#include <linux/ip.h> /* struct iphdr */
37716 +#include <net/arp.h>
37717 +#include <linux/skbuff.h>
37718 +
37719 +#include <openswan.h>
37720 +
37721 +#ifdef NET_21
37722 +# include <linux/in6.h>
37723 +# define IS_MYADDR RTN_LOCAL
37724 +# include <net/dst.h>
37725 +# undef dev_kfree_skb
37726 +# define dev_kfree_skb(a,b) kfree_skb(a)
37727 +# define PHYSDEV_TYPE
37728 +#endif /* NET_21 */
37729 +
37730 +#ifndef NETDEV_TX_BUSY
37731 +# ifdef NETDEV_XMIT_CN
37732 +# define NETDEV_TX_BUSY NETDEV_XMIT_CN
37733 +# else
37734 +# define NETDEV_TX_BUSY 1
37735 +# endif
37736 +#endif
37737 +
37738 +#include <net/icmp.h> /* icmp_send() */
37739 +#include <net/ip.h>
37740 +#include <net/arp.h>
37741 +#ifdef NETDEV_23
37742 +# include <linux/netfilter_ipv4.h>
37743 +#endif /* NETDEV_23 */
37744 +
37745 +#include <linux/if_arp.h>
37746 +#include <net/arp.h>
37747 +
37748 +#include "openswan/ipsec_kversion.h"
37749 +#include "openswan/radij.h"
37750 +#include "openswan/ipsec_life.h"
37751 +#include "openswan/ipsec_xform.h"
37752 +#include "openswan/ipsec_eroute.h"
37753 +#include "openswan/ipsec_encap.h"
37754 +#include "openswan/ipsec_radij.h"
37755 +#include "openswan/ipsec_sa.h"
37756 +#include "openswan/ipsec_tunnel.h"
37757 +#include "openswan/ipsec_xmit.h"
37758 +#include "openswan/ipsec_ipe4.h"
37759 +#include "openswan/ipsec_ah.h"
37760 +#include "openswan/ipsec_esp.h"
37761 +#include "openswan/ipsec_kern24.h"
37762 +
37763 +#include <openswan/pfkeyv2.h>
37764 +#include <openswan/pfkey.h>
37765 +
37766 +#include "openswan/ipsec_proto.h"
37767 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
37768 +#include <linux/udp.h>
37769 +#endif
37770 +
37771 +static __u32 zeroes[64];
37772 +
37773 +DEBUG_NO_STATIC int
37774 +ipsec_tunnel_open(struct net_device *dev)
37775 +{
37776 + struct ipsecpriv *prv = dev->priv;
37777 +
37778 + /*
37779 + * Can't open until attached.
37780 + */
37781 +
37782 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
37783 + "klips_debug:ipsec_tunnel_open: "
37784 + "dev = %s, prv->dev = %s\n",
37785 + dev->name, prv->dev?prv->dev->name:"NONE");
37786 +
37787 + if (prv->dev == NULL)
37788 + return -ENODEV;
37789 +
37790 + KLIPS_INC_USE;
37791 + return 0;
37792 +}
37793 +
37794 +DEBUG_NO_STATIC int
37795 +ipsec_tunnel_close(struct net_device *dev)
37796 +{
37797 + KLIPS_DEC_USE;
37798 + return 0;
37799 +}
37800 +
37801 +static inline int ipsec_tunnel_xmit2(struct sk_buff *skb)
37802 +{
37803 +
37804 +#ifdef NETDEV_25 /* 2.6 kernels */
37805 + return dst_output(skb);
37806 +#else
37807 + return ip_send(skb);
37808 +#endif
37809 +}
37810 +
37811 +enum ipsec_xmit_value
37812 +ipsec_tunnel_strip_hard_header(struct ipsec_xmit_state *ixs)
37813 +{
37814 + /* ixs->physdev->hard_header_len is unreliable and should not be used */
37815 + ixs->hard_header_len = (unsigned char *)(ixs->iph) - ixs->skb->data;
37816 +
37817 + if(ixs->hard_header_len < 0) {
37818 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
37819 + "klips_error:ipsec_xmit_strip_hard_header: "
37820 + "Negative hard_header_len (%d)?!\n", ixs->hard_header_len);
37821 + ixs->stats->tx_dropped++;
37822 + return IPSEC_XMIT_BADHHLEN;
37823 + }
37824 +
37825 + /* while ixs->physdev->hard_header_len is unreliable and
37826 + * should not be trusted, it accurate and required for ATM, GRE and
37827 + * some other interfaces to work. Thanks to Willy Tarreau
37828 + * <willy@w.ods.org>.
37829 + */
37830 + if(ixs->hard_header_len == 0) { /* no hard header present */
37831 + ixs->hard_header_stripped = 1;
37832 + ixs->hard_header_len = ixs->physdev->hard_header_len;
37833 + }
37834 +
37835 +#ifdef CONFIG_KLIPS_DEBUG
37836 + if (debug_tunnel & DB_TN_XMIT) {
37837 + int i;
37838 + char c;
37839 +
37840 + printk(KERN_INFO "klips_debug:ipsec_xmit_strip_hard_header: "
37841 + ">>> skb->len=%ld hard_header_len:%d",
37842 + (unsigned long int)ixs->skb->len, ixs->hard_header_len);
37843 + c = ' ';
37844 + for (i=0; i < ixs->hard_header_len; i++) {
37845 + printk("%c%02x", c, ixs->skb->data[i]);
37846 + c = ':';
37847 + }
37848 + printk(" \n");
37849 + }
37850 +#endif /* CONFIG_KLIPS_DEBUG */
37851 +
37852 + KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
37853 +
37854 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
37855 + "klips_debug:ipsec_xmit_strip_hard_header: "
37856 + "Original head,tailroom: %d,%d\n",
37857 + skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
37858 +
37859 + return IPSEC_XMIT_OK;
37860 +}
37861 +
37862 +enum ipsec_xmit_value
37863 +ipsec_tunnel_SAlookup(struct ipsec_xmit_state *ixs)
37864 +{
37865 + unsigned int bypass;
37866 +
37867 + bypass = FALSE;
37868 +
37869 + /*
37870 + * First things first -- look us up in the erouting tables.
37871 + */
37872 + ixs->matcher.sen_len = sizeof (struct sockaddr_encap);
37873 + ixs->matcher.sen_family = AF_ENCAP;
37874 + ixs->matcher.sen_type = SENT_IP4;
37875 + ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
37876 + ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
37877 + ixs->matcher.sen_proto = ixs->iph->protocol;
37878 + ipsec_extract_ports(ixs->iph, &ixs->matcher);
37879 +
37880 + /*
37881 + * The spinlock is to prevent any other process from accessing or deleting
37882 + * the eroute while we are using and updating it.
37883 + */
37884 + spin_lock_bh(&eroute_lock);
37885 +
37886 + ixs->eroute = ipsec_findroute(&ixs->matcher);
37887 +
37888 + if(ixs->iph->protocol == IPPROTO_UDP) {
37889 + struct udphdr *t = NULL;
37890 +
37891 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
37892 + "klips_debug:udp port check: "
37893 + "fragoff: %d len: %d>%ld \n",
37894 + ntohs(ixs->iph->frag_off) & IP_OFFSET,
37895 + (ixs->skb->len - ixs->hard_header_len),
37896 + (unsigned long int) ((ixs->iph->ihl << 2) + sizeof(struct udphdr)));
37897 +
37898 + if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 &&
37899 + ((ixs->skb->len - ixs->hard_header_len) >=
37900 + ((ixs->iph->ihl << 2) + sizeof(struct udphdr))))
37901 + {
37902 + t =((struct udphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)));
37903 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
37904 + "klips_debug:udp port in packet: "
37905 + "port %d -> %d\n",
37906 + ntohs(t->source), ntohs(t->dest));
37907 + }
37908 +
37909 + ixs->sport=0; ixs->dport=0;
37910 +
37911 + if(ixs->skb->sk) {
37912 +#ifdef NET_26
37913 +#ifdef HAVE_INET_SK_SPORT
37914 + ixs->sport = ntohs(inet_sk(ixs->skb->sk)->sport);
37915 + ixs->dport = ntohs(inet_sk(ixs->skb->sk)->dport);
37916 +#else
37917 + struct udp_sock *us;
37918 +
37919 + us = (struct udp_sock *)ixs->skb->sk;
37920 +
37921 + ixs->sport = ntohs(us->inet.sport);
37922 + ixs->dport = ntohs(us->inet.dport);
37923 +#endif
37924 +#else
37925 + ixs->sport = ntohs(ixs->skb->sk->sport);
37926 + ixs->dport = ntohs(ixs->skb->sk->dport);
37927 +#endif
37928 +
37929 + }
37930 +
37931 + if(t != NULL) {
37932 + if(ixs->sport == 0) {
37933 + ixs->sport = ntohs(t->source);
37934 + }
37935 + if(ixs->dport == 0) {
37936 + ixs->dport = ntohs(t->dest);
37937 + }
37938 + }
37939 + }
37940 +
37941 + /*
37942 + * practically identical to above, but let's be careful about
37943 + * tcp vs udp headers
37944 + */
37945 + if(ixs->iph->protocol == IPPROTO_TCP) {
37946 + struct tcphdr *t = NULL;
37947 +
37948 + if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 &&
37949 + ((ixs->skb->len - ixs->hard_header_len) >=
37950 + ((ixs->iph->ihl << 2) + sizeof(struct tcphdr)))) {
37951 + t =((struct tcphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)));
37952 + }
37953 +
37954 + ixs->sport=0; ixs->dport=0;
37955 +
37956 + if(ixs->skb->sk) {
37957 +#ifdef NET_26
37958 +#ifdef HAVE_INET_SK_SPORT
37959 + ixs->sport = ntohs(inet_sk(ixs->skb->sk)->sport);
37960 + ixs->dport = ntohs(inet_sk(ixs->skb->sk)->dport);
37961 +#else
37962 + struct tcp_tw_bucket *tw;
37963 + tw = (struct tcp_tw_bucket *)ixs->skb->sk;
37964 + ixs->sport = ntohs(tw->tw_sport);
37965 + ixs->dport = ntohs(tw->tw_dport);
37966 +#endif
37967 +#else
37968 + ixs->sport = ntohs(ixs->skb->sk->sport);
37969 + ixs->dport = ntohs(ixs->skb->sk->dport);
37970 +#endif
37971 + }
37972 +
37973 + if(t != NULL) {
37974 + if(ixs->sport == 0) {
37975 + ixs->sport = ntohs(t->source);
37976 + }
37977 + if(ixs->dport == 0) {
37978 + ixs->dport = ntohs(t->dest);
37979 + }
37980 + }
37981 + }
37982 +
37983 + /* default to a %drop eroute */
37984 + ixs->outgoing_said.proto = IPPROTO_INT;
37985 + ixs->outgoing_said.spi = htonl(SPI_DROP);
37986 + ixs->outgoing_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
37987 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
37988 + "klips_debug:ipsec_xmit_SAlookup: "
37989 + "checking for local udp/500 IKE packet "
37990 + "saddr=%x, er=0p%p, daddr=%x, er_dst=%x, proto=%d sport=%d dport=%d\n",
37991 + ntohl((unsigned int)ixs->iph->saddr),
37992 + ixs->eroute,
37993 + ntohl((unsigned int)ixs->iph->daddr),
37994 + ixs->eroute ? ntohl((unsigned int)ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr) : 0,
37995 + ixs->iph->protocol,
37996 + ixs->sport,
37997 + ixs->dport);
37998 +
37999 + /*
38000 + * cheat for now...are we udp/500? If so, let it through
38001 + * without interference since it is most likely an IKE packet.
38002 + */
38003 +
38004 + if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR
38005 + && (ixs->eroute==NULL
38006 + || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr
38007 + || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr)
38008 + && (ixs->iph->protocol == IPPROTO_UDP &&
38009 + (ixs->sport == 500 || ixs->sport == 4500))) {
38010 + /* Whatever the eroute, this is an IKE message
38011 + * from us (i.e. not being forwarded).
38012 + * Furthermore, if there is a tunnel eroute,
38013 + * the destination is the peer for this eroute.
38014 + * So %pass the packet: modify the default %drop.
38015 + */
38016 +
38017 + ixs->outgoing_said.spi = htonl(SPI_PASS);
38018 + if(!(ixs->skb->sk) && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0)) {
38019 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38020 + "klips_debug:ipsec_xmit_SAlookup: "
38021 + "local UDP/500 (probably IKE) passthrough: base fragment, rest of fragments will probably get filtered.\n");
38022 + }
38023 + bypass = TRUE;
38024 + }
38025 +
38026 +#ifdef KLIPS_EXCEPT_DNS53
38027 + /*
38028 + *
38029 + * if we are udp/53 or tcp/53, also let it through a %trap or %hold,
38030 + * since it is DNS, but *also* follow the %trap.
38031 + *
38032 + * we do not do this for tunnels, only %trap's and %hold's.
38033 + *
38034 + */
38035 +
38036 + if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR
38037 + && (ixs->eroute==NULL
38038 + || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr
38039 + || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr)
38040 + && ((ixs->iph->protocol == IPPROTO_UDP
38041 + || ixs->iph->protocol == IPPROTO_TCP)
38042 + && ixs->dport == 53)) {
38043 +
38044 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38045 + "klips_debug:ipsec_xmit_SAlookup: "
38046 + "possible DNS packet\n");
38047 +
38048 + if(ixs->eroute)
38049 + {
38050 + if(ixs->eroute->er_said.spi == htonl(SPI_TRAP)
38051 + || ixs->eroute->er_said.spi == htonl(SPI_HOLD))
38052 + {
38053 + ixs->outgoing_said.spi = htonl(SPI_PASSTRAP);
38054 + bypass = TRUE;
38055 + }
38056 + }
38057 + else
38058 + {
38059 + ixs->outgoing_said.spi = htonl(SPI_PASSTRAP);
38060 + bypass = TRUE;
38061 + }
38062 +
38063 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38064 + "klips_debug:ipsec_xmit_SAlookup: "
38065 + "bypass = %d\n", bypass);
38066 +
38067 + if(bypass
38068 + && !(ixs->skb->sk)
38069 + && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0))
38070 + {
38071 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38072 + "klips_debug:ipsec_xmit_SAlookup: "
38073 + "local port 53 (probably DNS) passthrough:"
38074 + "base fragment, rest of fragments will "
38075 + "probably get filtered.\n");
38076 + }
38077 + }
38078 +#endif
38079 +
38080 + if (bypass==FALSE && ixs->eroute) {
38081 + ixs->eroute->er_count++;
38082 + ixs->eroute->er_lasttime = jiffies/HZ;
38083 + if(ixs->eroute->er_said.proto==IPPROTO_INT
38084 + && ixs->eroute->er_said.spi==htonl(SPI_HOLD))
38085 + {
38086 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38087 + "klips_debug:ipsec_xmit_SAlookup: "
38088 + "shunt SA of HOLD: skb stored in HOLD.\n");
38089 + if(ixs->eroute->er_last != NULL) {
38090 + kfree_skb(ixs->eroute->er_last);
38091 + }
38092 + ixs->eroute->er_last = ixs->skb;
38093 + ixs->skb = NULL;
38094 + ixs->stats->tx_dropped++;
38095 + spin_unlock_bh(&eroute_lock);
38096 + return IPSEC_XMIT_STOLEN;
38097 + }
38098 + ixs->outgoing_said = ixs->eroute->er_said;
38099 + ixs->eroute_pid = ixs->eroute->er_pid;
38100 +
38101 + /* Copy of the ident for the TRAP/TRAPSUBNET eroutes */
38102 + if(ixs->outgoing_said.proto==IPPROTO_INT
38103 + && (ixs->outgoing_said.spi==htonl(SPI_TRAP)
38104 + || (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)))) {
38105 + int len;
38106 +
38107 + ixs->ips.ips_ident_s.type = ixs->eroute->er_ident_s.type;
38108 + ixs->ips.ips_ident_s.id = ixs->eroute->er_ident_s.id;
38109 + ixs->ips.ips_ident_s.len = ixs->eroute->er_ident_s.len;
38110 + if (ixs->ips.ips_ident_s.len)
38111 + {
38112 + len = ixs->ips.ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
38113 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38114 + "klips_debug:ipsec_xmit_SAlookup: "
38115 + "allocating %d bytes for ident_s shunt SA of HOLD: skb stored in HOLD.\n",
38116 + len);
38117 + if ((ixs->ips.ips_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
38118 + printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
38119 + "Failed, tried to allocate %d bytes for source ident.\n",
38120 + len);
38121 + ixs->stats->tx_dropped++;
38122 + spin_unlock_bh(&eroute_lock);
38123 + return IPSEC_XMIT_ERRMEMALLOC;
38124 + }
38125 + memcpy(ixs->ips.ips_ident_s.data, ixs->eroute->er_ident_s.data, len);
38126 + }
38127 + ixs->ips.ips_ident_d.type = ixs->eroute->er_ident_d.type;
38128 + ixs->ips.ips_ident_d.id = ixs->eroute->er_ident_d.id;
38129 + ixs->ips.ips_ident_d.len = ixs->eroute->er_ident_d.len;
38130 + if (ixs->ips.ips_ident_d.len)
38131 + {
38132 + len = ixs->ips.ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
38133 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38134 + "klips_debug:ipsec_xmit_SAlookup: "
38135 + "allocating %d bytes for ident_d shunt SA of HOLD: skb stored in HOLD.\n",
38136 + len);
38137 + if ((ixs->ips.ips_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
38138 + printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
38139 + "Failed, tried to allocate %d bytes for dest ident.\n",
38140 + len);
38141 + ixs->stats->tx_dropped++;
38142 + spin_unlock_bh(&eroute_lock);
38143 + return IPSEC_XMIT_ERRMEMALLOC;
38144 + }
38145 + memcpy(ixs->ips.ips_ident_d.data, ixs->eroute->er_ident_d.data, len);
38146 + }
38147 + }
38148 + }
38149 +
38150 + spin_unlock_bh(&eroute_lock);
38151 + return IPSEC_XMIT_OK;
38152 +}
38153 +
38154 +
38155 +enum ipsec_xmit_value
38156 +ipsec_tunnel_restore_hard_header(struct ipsec_xmit_state*ixs)
38157 +{
38158 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
38159 + "klips_debug:ipsec_xmit_restore_hard_header: "
38160 + "After recursive xforms -- head,tailroom: %d,%d\n",
38161 + skb_headroom(ixs->skb),
38162 + skb_tailroom(ixs->skb));
38163 +
38164 + if(ixs->saved_header) {
38165 + if(skb_headroom(ixs->skb) < ixs->hard_header_len) {
38166 + printk(KERN_WARNING
38167 + "klips_error:ipsec_xmit_restore_hard_header: "
38168 + "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
38169 + ixs->hard_header_len,
38170 + skb_headroom(ixs->skb));
38171 + ixs->stats->tx_errors++;
38172 + return IPSEC_XMIT_PUSHPULLERR;
38173 +
38174 + }
38175 + skb_push(ixs->skb, ixs->hard_header_len);
38176 + {
38177 + int i;
38178 + for (i = 0; i < ixs->hard_header_len; i++) {
38179 + ixs->skb->data[i] = ixs->saved_header[i];
38180 + }
38181 + }
38182 + }
38183 +
38184 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
38185 + "klips_debug:ipsec_xmit_restore_hard_header: "
38186 + "With hard_header, final head,tailroom: %d,%d\n",
38187 + skb_headroom(ixs->skb),
38188 + skb_tailroom(ixs->skb));
38189 +
38190 + return IPSEC_XMIT_OK;
38191 +}
38192 +
38193 +
38194 +/*
38195 + * when encap processing is complete it call this for us to continue
38196 + */
38197 +
38198 +void
38199 +ipsec_tunnel_xsm_complete(
38200 + struct ipsec_xmit_state *ixs,
38201 + enum ipsec_xmit_value stat)
38202 +{
38203 + if(stat != IPSEC_XMIT_OK) {
38204 + if(stat == IPSEC_XMIT_PASS) {
38205 + goto bypass;
38206 + }
38207 +
38208 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38209 + "klips_debug:ipsec_tunnel_start_xmit: encap_bundle failed: %d\n",
38210 + stat);
38211 + goto cleanup;
38212 + }
38213 +
38214 + ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
38215 + ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
38216 + ixs->matcher.sen_proto = ixs->iph->protocol;
38217 + ipsec_extract_ports(ixs->iph, &ixs->matcher);
38218 +
38219 + spin_lock_bh(&eroute_lock);
38220 + ixs->eroute = ipsec_findroute(&ixs->matcher);
38221 + if(ixs->eroute) {
38222 + ixs->outgoing_said = ixs->eroute->er_said;
38223 + ixs->eroute_pid = ixs->eroute->er_pid;
38224 + ixs->eroute->er_count++;
38225 + ixs->eroute->er_lasttime = jiffies/HZ;
38226 + }
38227 + spin_unlock_bh(&eroute_lock);
38228 +
38229 + KLIPS_PRINT((debug_tunnel & DB_TN_XMIT) &&
38230 + /* ((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc)) */
38231 + (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
38232 + ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
38233 + ixs->eroute,
38234 + "klips_debug:ipsec_tunnel_start_xmit: "
38235 + "We are recursing here.\n");
38236 +
38237 + if (/*((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc))*/
38238 + (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
38239 + ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
38240 + ixs->eroute) {
38241 + ipsec_xsm(ixs);
38242 + return;
38243 + }
38244 +
38245 + stat = ipsec_nat_encap(ixs);
38246 + if(stat != IPSEC_XMIT_OK) {
38247 + goto cleanup;
38248 + }
38249 +
38250 + stat = ipsec_tunnel_restore_hard_header(ixs);
38251 + if(stat != IPSEC_XMIT_OK) {
38252 + goto cleanup;
38253 + }
38254 +
38255 +bypass:
38256 + stat = ipsec_tunnel_send(ixs);
38257 +
38258 +cleanup:
38259 + ipsec_xmit_cleanup(ixs);
38260 + ipsec_xmit_state_delete(ixs);
38261 +}
38262 +
38263 +
38264 +/*
38265 + * This function assumes it is being called from dev_queue_xmit()
38266 + * and that skb is filled properly by that function.
38267 + */
38268 +int
38269 +ipsec_tunnel_start_xmit(struct sk_buff *skb, struct net_device *dev)
38270 +{
38271 + struct ipsec_xmit_state *ixs = NULL;
38272 + enum ipsec_xmit_value stat;
38273 +
38274 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38275 + "\n\nipsec_tunnel_start_xmit: STARTING");
38276 +
38277 + stat = IPSEC_XMIT_ERRMEMALLOC;
38278 + ixs = ipsec_xmit_state_new();
38279 + if (! ixs) {
38280 + goto alloc_error;
38281 + }
38282 +
38283 + ixs->dev = dev;
38284 + ixs->skb = skb;
38285 +
38286 + stat = ipsec_xmit_sanity_check_dev(ixs);
38287 + if(stat != IPSEC_XMIT_OK) {
38288 + goto cleanup;
38289 + }
38290 +
38291 + stat = ipsec_xmit_sanity_check_skb(ixs);
38292 + if(stat != IPSEC_XMIT_OK) {
38293 + goto cleanup;
38294 + }
38295 +
38296 + stat = ipsec_tunnel_strip_hard_header(ixs);
38297 + if(stat != IPSEC_XMIT_OK) {
38298 + goto cleanup;
38299 + }
38300 +
38301 + stat = ipsec_tunnel_SAlookup(ixs);
38302 + if(stat != IPSEC_XMIT_OK) {
38303 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38304 + "klips_debug:ipsec_tunnel_start_xmit: SAlookup failed: %d\n",
38305 + stat);
38306 + goto cleanup;
38307 + }
38308 +
38309 + ixs->innersrc = ixs->iph->saddr;
38310 +
38311 + ixs->xsm_complete = ipsec_tunnel_xsm_complete;
38312 +
38313 + ipsec_xsm(ixs);
38314 + return 0;
38315 +
38316 + cleanup:
38317 + ipsec_xmit_cleanup(ixs);
38318 + ipsec_xmit_state_delete(ixs);
38319 +alloc_error:
38320 + return 0;
38321 +}
38322 +
38323 +DEBUG_NO_STATIC struct net_device_stats *
38324 +ipsec_tunnel_get_stats(struct net_device *dev)
38325 +{
38326 + return &(((struct ipsecpriv *)(dev->priv))->mystats);
38327 +}
38328 +
38329 +/*
38330 + * Revectored calls.
38331 + * For each of these calls, a field exists in our private structure.
38332 + */
38333 +
38334 +DEBUG_NO_STATIC int
38335 +ipsec_tunnel_hard_header(struct sk_buff *skb, struct net_device *dev,
38336 + unsigned short type, const void *daddr, const void *saddr, unsigned len)
38337 +{
38338 + struct ipsecpriv *prv = dev->priv;
38339 + struct net_device *tmp;
38340 + int ret;
38341 + struct net_device_stats *stats; /* This device's statistics */
38342 +
38343 + if(skb == NULL) {
38344 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38345 + "klips_debug:ipsec_tunnel_hard_header: "
38346 + "no skb...\n");
38347 + return -ENODATA;
38348 + }
38349 +
38350 + if(dev == NULL) {
38351 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38352 + "klips_debug:ipsec_tunnel_hard_header: "
38353 + "no device...\n");
38354 + return -ENODEV;
38355 + }
38356 +
38357 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38358 + "klips_debug:ipsec_tunnel_hard_header: "
38359 + "skb->dev=%s dev=%s.\n",
38360 + skb->dev ? skb->dev->name : "NULL",
38361 + dev->name);
38362 +
38363 + if(prv == NULL) {
38364 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38365 + "klips_debug:ipsec_tunnel_hard_header: "
38366 + "no private space associated with dev=%s\n",
38367 + dev->name ? dev->name : "NULL");
38368 + return -ENODEV;
38369 + }
38370 +
38371 + stats = (struct net_device_stats *) &(prv->mystats);
38372 +
38373 + if(prv->dev == NULL) {
38374 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38375 + "klips_debug:ipsec_tunnel_hard_header: "
38376 + "no physical device associated with dev=%s\n",
38377 + dev->name ? dev->name : "NULL");
38378 + stats->tx_dropped++;
38379 + return -ENODEV;
38380 + }
38381 +
38382 + /* check if we have to send a IPv6 packet. It might be a Router
38383 + Solicitation, where the building of the packet happens in
38384 + reverse order:
38385 + 1. ll hdr,
38386 + 2. IPv6 hdr,
38387 + 3. ICMPv6 hdr
38388 + -> skb->nh.raw is still uninitialized when this function is
38389 + called!! If this is no IPv6 packet, we can print debugging
38390 + messages, otherwise we skip all debugging messages and just
38391 + build the ll header */
38392 + if(type != ETH_P_IPV6) {
38393 + /* execute this only, if we don't have to build the
38394 + header for a IPv6 packet */
38395 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
38396 + if(!prv->header_ops->create)
38397 +#else
38398 + if(!prv->hard_header)
38399 +#endif
38400 + {
38401 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38402 + "klips_debug:ipsec_tunnel_hard_header: "
38403 + "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
38404 + saddr,
38405 + daddr,
38406 + len,
38407 + type,
38408 + dev->name);
38409 +#ifdef NET_21
38410 + KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
38411 + "ip=%08x->%08x\n",
38412 + (__u32)ntohl(ip_hdr(skb)->saddr),
38413 + (__u32)ntohl(ip_hdr(skb)->daddr) );
38414 +#else /* NET_21 */
38415 + KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
38416 + "ip=%08x->%08x\n",
38417 + (__u32)ntohl(skb->ip_hdr->saddr),
38418 + (__u32)ntohl(skb->ip_hdr->daddr) );
38419 +#endif /* NET_21 */
38420 + stats->tx_dropped++;
38421 + return -ENODEV;
38422 + }
38423 +
38424 +#define da ((struct net_device *)(prv->dev))->dev_addr
38425 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38426 + "klips_debug:ipsec_tunnel_hard_header: "
38427 + "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
38428 + saddr,
38429 + daddr,
38430 + len,
38431 + type,
38432 + dev->name,
38433 + prv->dev->name,
38434 + da[0], da[1], da[2], da[3], da[4], da[5]);
38435 +#ifdef NET_21
38436 + KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
38437 + "ip=%08x->%08x\n",
38438 + (__u32)ntohl(ip_hdr(skb)->saddr),
38439 + (__u32)ntohl(ip_hdr(skb)->daddr) );
38440 +#else /* NET_21 */
38441 + KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
38442 + "ip=%08x->%08x\n",
38443 + (__u32)ntohl(skb->ip_hdr->saddr),
38444 + (__u32)ntohl(skb->ip_hdr->daddr) );
38445 +#endif /* NET_21 */
38446 + } else {
38447 + KLIPS_PRINT(debug_tunnel,
38448 + "klips_debug:ipsec_tunnel_hard_header: "
38449 + "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
38450 + }
38451 + tmp = skb->dev;
38452 + skb->dev = prv->dev;
38453 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
38454 + ret = prv->header_ops->create(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
38455 +#else
38456 + ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
38457 +#endif
38458 + skb->dev = tmp;
38459 + return ret;
38460 +}
38461 +
38462 +DEBUG_NO_STATIC int
38463 +#ifdef NET_21
38464 +ipsec_tunnel_rebuild_header(struct sk_buff *skb)
38465 +#else /* NET_21 */
38466 +ipsec_tunnel_rebuild_header(void *buff, struct net_device *dev,
38467 + unsigned long raddr, struct sk_buff *skb)
38468 +#endif /* NET_21 */
38469 +{
38470 + struct ipsecpriv *prv = skb->dev->priv;
38471 + struct net_device *tmp;
38472 + int ret;
38473 + struct net_device_stats *stats; /* This device's statistics */
38474 +
38475 + if(skb->dev == NULL) {
38476 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38477 + "klips_debug:ipsec_tunnel_rebuild_header: "
38478 + "no device...");
38479 + return -ENODEV;
38480 + }
38481 +
38482 + if(prv == NULL) {
38483 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38484 + "klips_debug:ipsec_tunnel_rebuild_header: "
38485 + "no private space associated with dev=%s",
38486 + skb->dev->name ? skb->dev->name : "NULL");
38487 + return -ENODEV;
38488 + }
38489 +
38490 + stats = (struct net_device_stats *) &(prv->mystats);
38491 +
38492 + if(prv->dev == NULL) {
38493 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38494 + "klips_debug:ipsec_tunnel_rebuild_header: "
38495 + "no physical device associated with dev=%s",
38496 + skb->dev->name ? skb->dev->name : "NULL");
38497 + stats->tx_dropped++;
38498 + return -ENODEV;
38499 + }
38500 +
38501 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
38502 + if(!prv->header_ops->rebuild)
38503 +#else
38504 + if(!prv->rebuild_header)
38505 +#endif
38506 + {
38507 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38508 + "klips_debug:ipsec_tunnel_rebuild_header: "
38509 + "physical device has been detached, packet dropped skb->dev=%s->NULL ",
38510 + skb->dev->name);
38511 +#ifdef NET_21
38512 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38513 + "ip=%08x->%08x\n",
38514 + (__u32)ntohl(ip_hdr(skb)->saddr),
38515 + (__u32)ntohl(ip_hdr(skb)->daddr) );
38516 +#else /* NET_21 */
38517 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38518 + "ip=%08x->%08x\n",
38519 + (__u32)ntohl(skb->ip_hdr->saddr),
38520 + (__u32)ntohl(skb->ip_hdr->daddr) );
38521 +#endif /* NET_21 */
38522 + stats->tx_dropped++;
38523 + return -ENODEV;
38524 + }
38525 +
38526 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38527 + "klips_debug:ipsec_tunnel: "
38528 + "Revectored rebuild_header dev=%s->%s ",
38529 + skb->dev->name, prv->dev->name);
38530 +#ifdef NET_21
38531 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38532 + "ip=%08x->%08x\n",
38533 + (__u32)ntohl(ip_hdr(skb)->saddr),
38534 + (__u32)ntohl(ip_hdr(skb)->daddr) );
38535 +#else /* NET_21 */
38536 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38537 + "ip=%08x->%08x\n",
38538 + (__u32)ntohl(skb->ip_hdr->saddr),
38539 + (__u32)ntohl(skb->ip_hdr->daddr) );
38540 +#endif /* NET_21 */
38541 + tmp = skb->dev;
38542 + skb->dev = prv->dev;
38543 +
38544 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
38545 + ret = prv->header_ops->rebuild(skb);
38546 +#else
38547 +#ifdef NET_21
38548 + ret = prv->rebuild_header(skb);
38549 +#else /* NET_21 */
38550 + ret = prv->rebuild_header(buff, prv->dev, raddr, skb);
38551 +#endif /* NET_21 */
38552 +#endif
38553 + skb->dev = tmp;
38554 + return ret;
38555 +}
38556 +
38557 +DEBUG_NO_STATIC int
38558 +ipsec_tunnel_set_mac_address(struct net_device *dev, void *addr)
38559 +{
38560 + struct ipsecpriv *prv = dev->priv;
38561 +
38562 + struct net_device_stats *stats; /* This device's statistics */
38563 +
38564 + if(dev == NULL) {
38565 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38566 + "klips_debug:ipsec_tunnel_set_mac_address: "
38567 + "no device...");
38568 + return -ENODEV;
38569 + }
38570 +
38571 + if(prv == NULL) {
38572 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38573 + "klips_debug:ipsec_tunnel_set_mac_address: "
38574 + "no private space associated with dev=%s",
38575 + dev->name ? dev->name : "NULL");
38576 + return -ENODEV;
38577 + }
38578 +
38579 + stats = (struct net_device_stats *) &(prv->mystats);
38580 +
38581 + if(prv->dev == NULL) {
38582 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38583 + "klips_debug:ipsec_tunnel_set_mac_address: "
38584 + "no physical device associated with dev=%s",
38585 + dev->name ? dev->name : "NULL");
38586 + stats->tx_dropped++;
38587 + return -ENODEV;
38588 + }
38589 +
38590 + if(!prv->set_mac_address) {
38591 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38592 + "klips_debug:ipsec_tunnel_set_mac_address: "
38593 + "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
38594 + dev->name);
38595 + return -ENODEV;
38596 + }
38597 +
38598 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38599 + "klips_debug:ipsec_tunnel_set_mac_address: "
38600 + "Revectored dev=%s->%s addr=0p%p\n",
38601 + dev->name, prv->dev->name, addr);
38602 + return prv->set_mac_address(prv->dev, addr);
38603 +
38604 +}
38605 +
38606 +#ifndef NET_21
38607 +DEBUG_NO_STATIC void
38608 +ipsec_tunnel_cache_bind(struct hh_cache **hhp, struct net_device *dev,
38609 + unsigned short htype, __u32 daddr)
38610 +{
38611 + struct ipsecpriv *prv = dev->priv;
38612 +
38613 + struct net_device_stats *stats; /* This device's statistics */
38614 +
38615 + if(dev == NULL) {
38616 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38617 + "klips_debug:ipsec_tunnel_cache_bind: "
38618 + "no device...");
38619 + return;
38620 + }
38621 +
38622 + if(prv == NULL) {
38623 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38624 + "klips_debug:ipsec_tunnel_cache_bind: "
38625 + "no private space associated with dev=%s",
38626 + dev->name ? dev->name : "NULL");
38627 + return;
38628 + }
38629 +
38630 + stats = (struct net_device_stats *) &(prv->mystats);
38631 +
38632 + if(prv->dev == NULL) {
38633 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38634 + "klips_debug:ipsec_tunnel_cache_bind: "
38635 + "no physical device associated with dev=%s",
38636 + dev->name ? dev->name : "NULL");
38637 + stats->tx_dropped++;
38638 + return;
38639 + }
38640 +
38641 + if(!prv->header_cache_bind) {
38642 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38643 + "klips_debug:ipsec_tunnel_cache_bind: "
38644 + "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
38645 + dev->name);
38646 + stats->tx_dropped++;
38647 + return;
38648 + }
38649 +
38650 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38651 + "klips_debug:ipsec_tunnel_cache_bind: "
38652 + "Revectored \n");
38653 + prv->header_cache_bind(hhp, prv->dev, htype, daddr);
38654 + return;
38655 +}
38656 +#endif /* !NET_21 */
38657 +
38658 +
38659 +DEBUG_NO_STATIC void
38660 +ipsec_tunnel_cache_update(struct hh_cache *hh, const struct net_device *dev,
38661 + const unsigned char * haddr)
38662 +{
38663 + struct ipsecpriv *prv = dev->priv;
38664 +
38665 + struct net_device_stats *stats; /* This device's statistics */
38666 +
38667 + if(dev == NULL) {
38668 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38669 + "klips_debug:ipsec_tunnel_cache_update: "
38670 + "no device...");
38671 + return;
38672 + }
38673 +
38674 + if(prv == NULL) {
38675 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38676 + "klips_debug:ipsec_tunnel_cache_update: "
38677 + "no private space associated with dev=%s",
38678 + dev->name ? dev->name : "NULL");
38679 + return;
38680 + }
38681 +
38682 + stats = (struct net_device_stats *) &(prv->mystats);
38683 +
38684 + if(prv->dev == NULL) {
38685 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38686 + "klips_debug:ipsec_tunnel_cache_update: "
38687 + "no physical device associated with dev=%s",
38688 + dev->name ? dev->name : "NULL");
38689 + stats->tx_dropped++;
38690 + return;
38691 + }
38692 +
38693 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
38694 + if(!prv->header_ops->cache_update)
38695 +#else
38696 + if(!prv->header_cache_update)
38697 +#endif
38698 + {
38699 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38700 + "klips_debug:ipsec_tunnel_cache_update: "
38701 + "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
38702 + dev->name);
38703 + return;
38704 + }
38705 +
38706 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38707 + "klips_debug:ipsec_tunnel: "
38708 + "Revectored cache_update\n");
38709 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
38710 + prv->header_ops->cache_update(hh, prv->dev, haddr);
38711 +#else
38712 + prv->header_cache_update(hh, prv->dev, haddr);
38713 +#endif
38714 + return;
38715 +}
38716 +
38717 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
38718 +const struct header_ops ipsec_tunnel_header_ops = {
38719 + .create = ipsec_tunnel_hard_header,
38720 + .rebuild = ipsec_tunnel_rebuild_header,
38721 + .cache_update = ipsec_tunnel_cache_update,
38722 +};
38723 +#endif
38724 +
38725 +#ifdef NET_21
38726 +DEBUG_NO_STATIC int
38727 +ipsec_tunnel_neigh_setup(struct neighbour *n)
38728 +{
38729 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38730 + "klips_debug:ipsec_tunnel_neigh_setup:\n");
38731 +
38732 + if (n->nud_state == NUD_NONE) {
38733 + n->ops = &arp_broken_ops;
38734 + n->output = n->ops->output;
38735 + }
38736 + return 0;
38737 +}
38738 +
38739 +DEBUG_NO_STATIC int
38740 +ipsec_tunnel_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
38741 +{
38742 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38743 + "klips_debug:ipsec_tunnel_neigh_setup_dev: "
38744 + "setting up %s\n",
38745 + dev ? dev->name : "NULL");
38746 +
38747 + if (p->tbl->family == AF_INET) {
38748 + p->neigh_setup = ipsec_tunnel_neigh_setup;
38749 + p->ucast_probes = 0;
38750 + p->mcast_probes = 0;
38751 + }
38752 + return 0;
38753 +}
38754 +#endif /* NET_21 */
38755 +
38756 +/*
38757 + * We call the attach routine to attach another device.
38758 + */
38759 +
38760 +DEBUG_NO_STATIC int
38761 +ipsec_tunnel_attach(struct net_device *dev, struct net_device *physdev)
38762 +{
38763 + int i;
38764 + struct ipsecpriv *prv = dev->priv;
38765 +
38766 + if(dev == NULL) {
38767 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38768 + "klips_debug:ipsec_tunnel_attach: "
38769 + "no device...");
38770 + return -ENODEV;
38771 + }
38772 +
38773 + if(prv == NULL) {
38774 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38775 + "klips_debug:ipsec_tunnel_attach: "
38776 + "no private space associated with dev=%s",
38777 + dev->name ? dev->name : "NULL");
38778 + return -ENODATA;
38779 + }
38780 +
38781 + prv->dev = physdev;
38782 + prv->hard_start_xmit = physdev->hard_start_xmit;
38783 + prv->get_stats = physdev->get_stats;
38784 +
38785 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
38786 + if (physdev->header_ops) {
38787 + prv->header_ops = physdev->header_ops;
38788 + dev->header_ops = &ipsec_tunnel_header_ops;
38789 + } else
38790 + dev->header_ops = NULL;
38791 +#else
38792 + if (physdev->hard_header) {
38793 + prv->hard_header = physdev->hard_header;
38794 + dev->hard_header = &ipsec_tunnel_hard_header;
38795 + } else
38796 + dev->hard_header = NULL;
38797 +
38798 + if (physdev->rebuild_header) {
38799 + prv->rebuild_header = physdev->rebuild_header;
38800 + dev->rebuild_header = ipsec_tunnel_rebuild_header;
38801 + } else
38802 + dev->rebuild_header = NULL;
38803 +
38804 +#ifndef NET_21
38805 + if (physdev->header_cache_bind) {
38806 + prv->header_cache_bind = physdev->header_cache_bind;
38807 + dev->header_cache_bind = ipsec_tunnel_cache_bind;
38808 + } else
38809 + dev->header_cache_bind = NULL;
38810 +#endif /* !NET_21 */
38811 +
38812 + if (physdev->header_cache_update) {
38813 + prv->header_cache_update = physdev->header_cache_update;
38814 + dev->header_cache_update = ipsec_tunnel_cache_update;
38815 + } else
38816 + dev->header_cache_update = NULL;
38817 +#endif
38818 +
38819 + if (physdev->set_mac_address) {
38820 + prv->set_mac_address = physdev->set_mac_address;
38821 + dev->set_mac_address = ipsec_tunnel_set_mac_address;
38822 + } else
38823 + dev->set_mac_address = NULL;
38824 +
38825 + dev->hard_header_len = physdev->hard_header_len;
38826 +
38827 +#ifdef NET_21
38828 +/* prv->neigh_setup = physdev->neigh_setup; */
38829 + dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
38830 +#endif /* NET_21 */
38831 + dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
38832 + prv->mtu = physdev->mtu;
38833 +
38834 +#ifdef PHYSDEV_TYPE
38835 + dev->type = physdev->type; /* ARPHRD_TUNNEL; */
38836 +#endif /* PHYSDEV_TYPE */
38837 +
38838 + dev->addr_len = physdev->addr_len;
38839 + for (i=0; i<dev->addr_len; i++) {
38840 + dev->dev_addr[i] = physdev->dev_addr[i];
38841 + }
38842 +#ifdef CONFIG_KLIPS_DEBUG
38843 + if(debug_tunnel & DB_TN_INIT) {
38844 + printk(KERN_INFO "klips_debug:ipsec_tunnel_attach: "
38845 + "physical device %s being attached has HW address: %2x",
38846 + physdev->name, physdev->dev_addr[0]);
38847 + for (i=1; i < physdev->addr_len; i++) {
38848 + printk(":%02x", physdev->dev_addr[i]);
38849 + }
38850 + printk("\n");
38851 + }
38852 +#endif /* CONFIG_KLIPS_DEBUG */
38853 +
38854 + return 0;
38855 +}
38856 +
38857 +/*
38858 + * We call the detach routine to detach the ipsec tunnel from another device.
38859 + */
38860 +
38861 +DEBUG_NO_STATIC int
38862 +ipsec_tunnel_detach(struct net_device *dev)
38863 +{
38864 + int i;
38865 + struct ipsecpriv *prv = dev->priv;
38866 +
38867 + if(dev == NULL) {
38868 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38869 + "klips_debug:ipsec_tunnel_detach: "
38870 + "no device...");
38871 + return -ENODEV;
38872 + }
38873 +
38874 + if(prv == NULL) {
38875 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38876 + "klips_debug:ipsec_tunnel_detach: "
38877 + "no private space associated with dev=%s",
38878 + dev->name ? dev->name : "NULL");
38879 + return -ENODATA;
38880 + }
38881 +
38882 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
38883 + "klips_debug:ipsec_tunnel_detach: "
38884 + "physical device %s being detached from virtual device %s\n",
38885 + prv->dev ? prv->dev->name : "NULL",
38886 + dev->name);
38887 +
38888 + ipsec_dev_put(prv->dev);
38889 + prv->dev = NULL;
38890 + prv->hard_start_xmit = NULL;
38891 + prv->get_stats = NULL;
38892 +
38893 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
38894 + prv->header_ops = NULL;
38895 +#else
38896 + prv->hard_header = NULL;
38897 + prv->rebuild_header = NULL;
38898 + prv->header_cache_update = NULL;
38899 +#ifndef NET_21
38900 + prv->header_cache_bind = NULL;
38901 +#else
38902 +/* prv->neigh_setup = NULL; */
38903 +#endif
38904 +#endif
38905 + prv->set_mac_address = NULL;
38906 + dev->hard_header_len = 0;
38907 +
38908 +#ifdef DETACH_AND_DOWN
38909 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
38910 + dev->header_ops = NULL;
38911 +#else
38912 + dev->hard_header = NULL;
38913 + dev->rebuild_header = NULL;
38914 + dev->header_cache_update = NULL;
38915 +#ifndef NET_21
38916 + dev->header_cache_bind = NULL;
38917 +#else
38918 + dev->neigh_setup = NULL;
38919 +#endif
38920 +#endif
38921 + dev->set_mac_address = NULL;
38922 + dev->mtu = 0;
38923 +#endif /* DETACH_AND_DOWN */
38924 +
38925 + prv->mtu = 0;
38926 + for (i=0; i<MAX_ADDR_LEN; i++) {
38927 + dev->dev_addr[i] = 0;
38928 + }
38929 + dev->addr_len = 0;
38930 +#ifdef PHYSDEV_TYPE
38931 + dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */
38932 +#endif /* PHYSDEV_TYPE */
38933 +
38934 + return 0;
38935 +}
38936 +
38937 +/*
38938 + * We call the clear routine to detach all ipsec tunnels from other devices.
38939 + */
38940 +DEBUG_NO_STATIC int
38941 +ipsec_tunnel_clear(void)
38942 +{
38943 + int i;
38944 + struct net_device *ipsecdev = NULL, *prvdev;
38945 + struct ipsecpriv *prv;
38946 + int ret;
38947 +
38948 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
38949 + "klips_debug:ipsec_tunnel_clear: .\n");
38950 +
38951 + for(i = 0; i < IPSEC_NUM_IF; i++) {
38952 + ipsecdev = ipsecdevices[i];
38953 + if(ipsecdev != NULL) {
38954 + if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
38955 + prvdev = (struct net_device *)(prv->dev);
38956 + if(prvdev) {
38957 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
38958 + "klips_debug:ipsec_tunnel_clear: "
38959 + "physical device for device %s is %s\n",
38960 + ipsecdev->name, prvdev->name);
38961 + if((ret = ipsec_tunnel_detach(ipsecdev))) {
38962 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
38963 + "klips_debug:ipsec_tunnel_clear: "
38964 + "error %d detatching device %s from device %s.\n",
38965 + ret, ipsecdev->name, prvdev->name);
38966 + return ret;
38967 + }
38968 + }
38969 + }
38970 + }
38971 + }
38972 + return 0;
38973 +}
38974 +
38975 +DEBUG_NO_STATIC int
38976 +ipsec_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
38977 +{
38978 + struct ipsectunnelconf *cf = (struct ipsectunnelconf *)&ifr->ifr_data;
38979 + struct ipsecpriv *prv = dev->priv;
38980 + struct net_device *them; /* physical device */
38981 +#ifdef CONFIG_IP_ALIAS
38982 + char *colon;
38983 + char realphysname[IFNAMSIZ];
38984 +#endif /* CONFIG_IP_ALIAS */
38985 +
38986 + if(dev == NULL) {
38987 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
38988 + "klips_debug:ipsec_tunnel_ioctl: "
38989 + "device not supplied.\n");
38990 + return -ENODEV;
38991 + }
38992 +
38993 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
38994 + "klips_debug:ipsec_tunnel_ioctl: "
38995 + "tncfg service call #%d for dev=%s\n",
38996 + cmd,
38997 + dev->name ? dev->name : "NULL");
38998 + switch (cmd) {
38999 + /* attach a virtual ipsec? device to a physical device */
39000 + case IPSEC_SET_DEV:
39001 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39002 + "klips_debug:ipsec_tunnel_ioctl: "
39003 + "calling ipsec_tunnel_attatch...\n");
39004 +#ifdef CONFIG_IP_ALIAS
39005 + /* If this is an IP alias interface, get its real physical name */
39006 + strncpy(realphysname, cf->cf_name, IFNAMSIZ);
39007 + realphysname[IFNAMSIZ-1] = 0;
39008 + colon = strchr(realphysname, ':');
39009 + if (colon) *colon = 0;
39010 + them = ipsec_dev_get(realphysname);
39011 +#else /* CONFIG_IP_ALIAS */
39012 + them = ipsec_dev_get(cf->cf_name);
39013 +#endif /* CONFIG_IP_ALIAS */
39014 +
39015 + if (them == NULL) {
39016 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39017 + "klips_debug:ipsec_tunnel_ioctl: "
39018 + "physical device %s requested is null\n",
39019 + cf->cf_name);
39020 + return -ENXIO;
39021 + }
39022 +
39023 +#if 0
39024 + if (them->flags & IFF_UP) {
39025 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39026 + "klips_debug:ipsec_tunnel_ioctl: "
39027 + "physical device %s requested is not up.\n",
39028 + cf->cf_name);
39029 + ipsec_dev_put(them);
39030 + return -ENXIO;
39031 + }
39032 +#endif
39033 +
39034 + if (prv && prv->dev) {
39035 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39036 + "klips_debug:ipsec_tunnel_ioctl: "
39037 + "virtual device is already connected to %s.\n",
39038 + prv->dev->name ? prv->dev->name : "NULL");
39039 + ipsec_dev_put(them);
39040 + return -EBUSY;
39041 + }
39042 + return ipsec_tunnel_attach(dev, them);
39043 +
39044 + case IPSEC_DEL_DEV:
39045 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39046 + "klips_debug:ipsec_tunnel_ioctl: "
39047 + "calling ipsec_tunnel_detatch.\n");
39048 + if (! prv->dev) {
39049 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39050 + "klips_debug:ipsec_tunnel_ioctl: "
39051 + "physical device not connected.\n");
39052 + return -ENODEV;
39053 + }
39054 + return ipsec_tunnel_detach(dev);
39055 +
39056 + case IPSEC_CLR_DEV:
39057 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39058 + "klips_debug:ipsec_tunnel_ioctl: "
39059 + "calling ipsec_tunnel_clear.\n");
39060 + return ipsec_tunnel_clear();
39061 +
39062 +#ifdef HAVE_UDP_ENCAP_CONVERT
39063 + case IPSEC_UDP_ENCAP_CONVERT:
39064 + {
39065 + unsigned int *socknum =(unsigned int *)&ifr->ifr_data;
39066 + struct socket *sock;
39067 + int err, fput_needed;
39068 +
39069 + /* that's a static function in socket.c
39070 + * sock = sockfd_lookup_light(*socknum, &err, &fput_needed); */
39071 + sock = sockfd_lookup(*socknum, &err);
39072 + if (!sock)
39073 + goto encap_out;
39074 +
39075 + /* check that it's a UDP socket */
39076 + udp_sk(sk)->encap_type = UDP_ENCAP_ESPINUDP_NON_IKE;
39077 + udp_sk(sk)->encap_rcv = klips26_udp_encap_rcv;
39078 +
39079 + KLIPS_PRINT(debug_tunnel
39080 + , "UDP socket: %u set to NON-IKE encap mode\n"
39081 + , socknum);
39082 +
39083 + err = 0;
39084 +
39085 + encap_output:
39086 + fput_light(sock->file, fput_needed);
39087 + encap_out:
39088 + return err;
39089 +#endif
39090 +
39091 + default:
39092 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39093 + "klips_debug:ipsec_tunnel_ioctl: "
39094 + "unknown command %d.\n",
39095 + cmd);
39096 + return -EOPNOTSUPP;
39097 + }
39098 +}
39099 +
39100 +struct net_device *ipsec_get_device(int inst)
39101 +{
39102 + struct net_device *ipsec_dev;
39103 +
39104 + ipsec_dev = NULL;
39105 +
39106 + if(inst < IPSEC_NUM_IF) {
39107 + ipsec_dev = ipsecdevices[inst];
39108 + }
39109 +
39110 + return ipsec_dev;
39111 +}
39112 +
39113 +int
39114 +ipsec_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
39115 +{
39116 + struct net_device *dev = ptr;
39117 + struct net_device *ipsec_dev;
39118 + struct ipsecpriv *priv;
39119 + int i;
39120 +
39121 + if (dev == NULL) {
39122 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39123 + "klips_debug:ipsec_device_event: "
39124 + "dev=NULL for event type %ld.\n",
39125 + event);
39126 + return(NOTIFY_DONE);
39127 + }
39128 +
39129 + /* check for loopback devices */
39130 + if (dev && (dev->flags & IFF_LOOPBACK)) {
39131 + return(NOTIFY_DONE);
39132 + }
39133 +
39134 + switch (event) {
39135 + case NETDEV_DOWN:
39136 + /* look very carefully at the scope of these compiler
39137 + directives before changing anything... -- RGB */
39138 +#ifdef NET_21
39139 + case NETDEV_UNREGISTER:
39140 + switch (event) {
39141 + case NETDEV_DOWN:
39142 +#endif /* NET_21 */
39143 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39144 + "klips_debug:ipsec_device_event: "
39145 + "NETDEV_DOWN dev=%s flags=%x\n",
39146 + dev->name,
39147 + dev->flags);
39148 + if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
39149 + printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
39150 + dev->name);
39151 + }
39152 +#ifdef NET_21
39153 + break;
39154 + case NETDEV_UNREGISTER:
39155 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39156 + "klips_debug:ipsec_device_event: "
39157 + "NETDEV_UNREGISTER dev=%s flags=%x\n",
39158 + dev->name,
39159 + dev->flags);
39160 + break;
39161 + }
39162 +#endif /* NET_21 */
39163 +
39164 + /* find the attached physical device and detach it. */
39165 + for(i = 0; i < IPSEC_NUM_IF; i++) {
39166 + ipsec_dev = ipsecdevices[i];
39167 +
39168 + if(ipsec_dev) {
39169 + priv = (struct ipsecpriv *)(ipsec_dev->priv);
39170 + if(priv) {
39171 + ;
39172 + if(((struct net_device *)(priv->dev)) == dev) {
39173 + /* dev_close(ipsec_dev); */
39174 + /* return */ ipsec_tunnel_detach(ipsec_dev);
39175 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39176 + "klips_debug:ipsec_device_event: "
39177 + "device '%s' has been detached.\n",
39178 + ipsec_dev->name);
39179 + break;
39180 + }
39181 + } else {
39182 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39183 + "klips_debug:ipsec_device_event: "
39184 + "device '%s' has no private data space!\n",
39185 + ipsec_dev->name);
39186 + }
39187 + }
39188 + }
39189 + break;
39190 + case NETDEV_UP:
39191 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39192 + "klips_debug:ipsec_device_event: "
39193 + "NETDEV_UP dev=%s\n",
39194 + dev->name);
39195 + break;
39196 +#ifdef NET_21
39197 + case NETDEV_REBOOT:
39198 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39199 + "klips_debug:ipsec_device_event: "
39200 + "NETDEV_REBOOT dev=%s\n",
39201 + dev->name);
39202 + break;
39203 + case NETDEV_CHANGE:
39204 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39205 + "klips_debug:ipsec_device_event: "
39206 + "NETDEV_CHANGE dev=%s flags=%x\n",
39207 + dev->name,
39208 + dev->flags);
39209 + break;
39210 + case NETDEV_REGISTER:
39211 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39212 + "klips_debug:ipsec_device_event: "
39213 + "NETDEV_REGISTER dev=%s\n",
39214 + dev->name);
39215 + break;
39216 + case NETDEV_CHANGEMTU:
39217 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39218 + "klips_debug:ipsec_device_event: "
39219 + "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
39220 + dev->name,
39221 + dev->mtu);
39222 + break;
39223 + case NETDEV_CHANGEADDR:
39224 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39225 + "klips_debug:ipsec_device_event: "
39226 + "NETDEV_CHANGEADDR dev=%s\n",
39227 + dev->name);
39228 + break;
39229 + case NETDEV_GOING_DOWN:
39230 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39231 + "klips_debug:ipsec_device_event: "
39232 + "NETDEV_GOING_DOWN dev=%s\n",
39233 + dev->name);
39234 + break;
39235 + case NETDEV_CHANGENAME:
39236 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39237 + "klips_debug:ipsec_device_event: "
39238 + "NETDEV_CHANGENAME dev=%s\n",
39239 + dev->name);
39240 + break;
39241 +#endif /* NET_21 */
39242 + default:
39243 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39244 + "klips_debug:ipsec_device_event: "
39245 + "event type %ld unrecognised for dev=%s\n",
39246 + event,
39247 + dev->name);
39248 + break;
39249 + }
39250 + return NOTIFY_DONE;
39251 +}
39252 +
39253 +/*
39254 + * Called when an ipsec tunnel device is initialized.
39255 + * The ipsec tunnel device structure is passed to us.
39256 + */
39257 +
39258 +int
39259 +ipsec_tunnel_init(struct net_device *dev)
39260 +{
39261 + int i;
39262 +
39263 + KLIPS_PRINT(debug_tunnel,
39264 + "klips_debug:ipsec_tunnel_init: "
39265 + "allocating %lu bytes initialising device: %s\n",
39266 + (unsigned long) sizeof(struct ipsecpriv),
39267 + dev->name ? dev->name : "NULL");
39268 +
39269 + /* Add our tunnel functions to the device */
39270 + dev->open = ipsec_tunnel_open;
39271 + dev->stop = ipsec_tunnel_close;
39272 + dev->hard_start_xmit = ipsec_tunnel_start_xmit;
39273 + dev->get_stats = ipsec_tunnel_get_stats;
39274 +
39275 + dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
39276 + if (dev->priv == NULL)
39277 + return -ENOMEM;
39278 + memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
39279 +
39280 + for(i = 0; i < sizeof(zeroes); i++) {
39281 + ((__u8*)(zeroes))[i] = 0;
39282 + }
39283 +
39284 +#ifndef NET_21
39285 + /* Initialize the tunnel device structure */
39286 + for (i = 0; i < DEV_NUMBUFFS; i++)
39287 + skb_queue_head_init(&dev->buffs[i]);
39288 +#endif /* !NET_21 */
39289 +
39290 + dev->set_multicast_list = NULL;
39291 + dev->do_ioctl = ipsec_tunnel_ioctl;
39292 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
39293 + dev->header_ops = NULL;
39294 +#else
39295 + dev->hard_header = NULL;
39296 + dev->rebuild_header = NULL;
39297 + dev->set_mac_address = NULL;
39298 +#ifndef NET_21
39299 + dev->header_cache_bind = NULL;
39300 +#endif /* !NET_21 */
39301 + dev->header_cache_update= NULL;
39302 +#endif
39303 +
39304 +#ifdef NET_21
39305 +/* prv->neigh_setup = NULL; */
39306 + dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
39307 +#endif /* NET_21 */
39308 + dev->hard_header_len = 0;
39309 + dev->mtu = 0;
39310 + dev->addr_len = 0;
39311 + dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */ /* ARPHRD_ETHER; */
39312 + dev->tx_queue_len = 10; /* Small queue */
39313 + memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
39314 +
39315 + /* New-style flags. */
39316 + dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
39317 +
39318 + /* We're done. Have I forgotten anything? */
39319 + return 0;
39320 +}
39321 +
39322 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
39323 +/* Module specific interface (but it links with the rest of IPSEC) */
39324 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
39325 +
39326 +int
39327 +ipsec_tunnel_probe(struct net_device *dev)
39328 +{
39329 + ipsec_tunnel_init(dev);
39330 + return 0;
39331 +}
39332 +
39333 +#ifdef alloc_netdev
39334 +static void ipsec_tunnel_netdev_setup(struct net_device *dev)
39335 +{
39336 +}
39337 +#endif
39338 +
39339 +struct net_device *ipsecdevices[IPSEC_NUM_IFMAX];
39340 +int ipsecdevices_max=-1;
39341 +
39342 +int
39343 +ipsec_tunnel_createnum(int ifnum)
39344 +{
39345 + char name[IFNAMSIZ];
39346 + struct net_device *dev_ipsec;
39347 + int vifentry;
39348 +
39349 + if(ifnum > IPSEC_NUM_IFMAX) {
39350 + return -ENOENT;
39351 + }
39352 +
39353 + if(ipsecdevices[ifnum]!=NULL) {
39354 + return -EEXIST;
39355 + }
39356 +
39357 + /* no identical device */
39358 + if(ifnum > ipsecdevices_max) {
39359 + ipsecdevices_max=ifnum;
39360 + }
39361 + vifentry = ifnum;
39362 +
39363 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39364 + "klips_debug:ipsec_tunnel_init_devices: "
39365 + "creating and registering IPSEC_NUM_IF=%u device\n",
39366 + ifnum);
39367 +
39368 + sprintf(name, IPSEC_DEV_FORMAT, ifnum);
39369 +#ifdef alloc_netdev
39370 + dev_ipsec = alloc_netdev(0, name, ipsec_tunnel_netdev_setup);
39371 +#else
39372 + dev_ipsec = (struct net_device*)kmalloc(sizeof(struct net_device), GFP_KERNEL);
39373 +#endif
39374 + if (dev_ipsec == NULL) {
39375 + printk(KERN_ERR "klips_debug:ipsec_tunnel_init_devices: "
39376 + "failed to allocate memory for device %s, quitting device init.\n",
39377 + name);
39378 + return -ENOMEM;
39379 + }
39380 +#ifndef alloc_netdev
39381 + memset((caddr_t)dev_ipsec, 0, sizeof(struct net_device));
39382 +#ifdef NETDEV_23
39383 + strncpy(dev_ipsec->name, name, sizeof(dev_ipsec->name));
39384 +#else /* NETDEV_23 */
39385 + dev_ipsec->name = (char*)kmalloc(IFNAMSIZ, GFP_KERNEL);
39386 + if (dev_ipsec->name == NULL) {
39387 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39388 + "klips_debug:ipsec_tunnel_init_devices: "
39389 + "failed to allocate memory for device %s name, quitting device init.\n",
39390 + name);
39391 + return -ENOMEM;
39392 + }
39393 + memset((caddr_t)dev_ipsec->name, 0, IFNAMSIZ);
39394 + strncpy(dev_ipsec->name, name, IFNAMSIZ);
39395 +#endif /* NETDEV_23 */
39396 +#ifdef PAUL_FIXME
39397 + dev_ipsec->next = NULL;
39398 +#endif
39399 +#endif /* alloc_netdev */
39400 + dev_ipsec->init = &ipsec_tunnel_probe;
39401 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39402 + "klips_debug:ipsec_tunnel_init_devices: "
39403 + "registering device %s\n",
39404 + dev_ipsec->name);
39405 +
39406 + /* reference and hold the device reference */
39407 + dev_hold(dev_ipsec);
39408 + ipsecdevices[vifentry]=dev_ipsec;
39409 +
39410 + if (register_netdev(dev_ipsec) != 0) {
39411 + KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT,
39412 + "klips_debug:ipsec_tunnel_init_devices: "
39413 + "registering device %s failed, quitting device init.\n",
39414 + dev_ipsec->name);
39415 + return -EIO;
39416 + } else {
39417 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39418 + "klips_debug:ipsec_tunnel_init_devices: "
39419 + "registering device %s succeeded, continuing...\n",
39420 + dev_ipsec->name);
39421 + }
39422 + return 0;
39423 +}
39424 +
39425 +
39426 +int
39427 +ipsec_tunnel_init_devices(void)
39428 +{
39429 + int i;
39430 + int error;
39431 +
39432 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39433 + "klips_debug:ipsec_tunnel_init_devices: "
39434 + "creating and registering IPSEC_NUM_IF=%u devices, allocating %lu per device, IFNAMSIZ=%u.\n",
39435 + IPSEC_NUM_IF,
39436 + (unsigned long) (sizeof(struct net_device) + IFNAMSIZ),
39437 + IFNAMSIZ);
39438 +
39439 + for(i = 0; i < IPSEC_NUM_IF; i++) {
39440 + error = ipsec_tunnel_createnum(i);
39441 +
39442 + if(error) break;
39443 + }
39444 + return 0;
39445 +}
39446 +
39447 +int
39448 +ipsec_tunnel_deletenum(int vifnum)
39449 +{
39450 + struct net_device *dev_ipsec;
39451 +
39452 + if(vifnum > IPSEC_NUM_IFMAX) {
39453 + return -ENOENT;
39454 + }
39455 +
39456 + dev_ipsec = ipsecdevices[vifnum];
39457 + if(dev_ipsec == NULL) {
39458 + return -ENOENT;
39459 + }
39460 +
39461 + /* release reference */
39462 + ipsecdevices[vifnum]=NULL;
39463 + ipsec_dev_put(dev_ipsec);
39464 +
39465 + KLIPS_PRINT(debug_tunnel, "Unregistering %s (refcnt=%d)\n",
39466 + dev_ipsec->name,
39467 + atomic_read(&dev_ipsec->refcnt));
39468 + unregister_netdev(dev_ipsec);
39469 + KLIPS_PRINT(debug_tunnel, "Unregisted %s\n", dev_ipsec->name);
39470 +#ifdef alloc_netdev
39471 + free_netdev(dev_ipsec);
39472 +#else
39473 +#ifndef NETDEV_23
39474 + kfree(dev_ipsec->name);
39475 + dev_ipsec->name=NULL;
39476 +#endif /* !NETDEV_23 */
39477 + kfree(dev_ipsec->priv);
39478 +#endif /* alloc_netdev */
39479 + dev_ipsec->priv=NULL;
39480 +
39481 + return 0;
39482 +}
39483 +
39484 +
39485 +struct net_device *
39486 +ipsec_tunnel_get_device(int vifnum)
39487 +{
39488 + struct net_device *nd;
39489 +
39490 + if(vifnum < ipsecdevices_max) {
39491 + nd = ipsecdevices[vifnum];
39492 +
39493 + if(nd) dev_hold(nd);
39494 + return nd;
39495 + } else {
39496 + return NULL;
39497 + }
39498 +}
39499 +
39500 +/* void */
39501 +int
39502 +ipsec_tunnel_cleanup_devices(void)
39503 +{
39504 + int error = 0;
39505 + int i;
39506 + struct net_device *dev_ipsec;
39507 +
39508 + for(i = 0; i < IPSEC_NUM_IF; i++) {
39509 + dev_ipsec = ipsecdevices[i];
39510 + if(dev_ipsec == NULL) {
39511 + continue;
39512 + }
39513 +
39514 + /* release reference */
39515 + ipsecdevices[i]=NULL;
39516 + ipsec_dev_put(dev_ipsec);
39517 +
39518 + KLIPS_PRINT(debug_tunnel, "Unregistering %s (refcnt=%d)\n",
39519 + dev_ipsec->name,
39520 + atomic_read(&dev_ipsec->refcnt));
39521 + unregister_netdev(dev_ipsec);
39522 + KLIPS_PRINT(debug_tunnel, "Unregisted %s\n", dev_ipsec->name);
39523 +#ifdef alloc_netdev
39524 + free_netdev(dev_ipsec);
39525 +#else
39526 +#ifndef NETDEV_23
39527 + kfree(dev_ipsec->name);
39528 + dev_ipsec->name=NULL;
39529 +#endif /* !NETDEV_23 */
39530 + kfree(dev_ipsec->priv);
39531 +#endif /* alloc_netdev */
39532 + dev_ipsec->priv=NULL;
39533 + }
39534 + return error;
39535 +}
39536 +
39537 +// ------------------------------------------------------------------------
39538 +// this handles creating and managing state for xmit path
39539 +
39540 +static spinlock_t ixs_cache_lock = SPIN_LOCK_UNLOCKED;
39541 +#ifdef HAVE_KMEM_CACHE_MACRO
39542 +static struct kmem_cache *ixs_cache_allocator = NULL;
39543 +#else
39544 +static kmem_cache_t *ixs_cache_allocator = NULL;
39545 +#endif
39546 +static unsigned ixs_cache_allocated_count = 0;
39547 +
39548 +#if !defined(MODULE_PARM) && defined(module_param)
39549 +/*
39550 + * As of 2.6.17 MODULE_PARM no longer exists, use module_param instead.
39551 + */
39552 +#define MODULE_PARM(a,b) module_param(a,int,0644)
39553 +#endif
39554 +
39555 +int ipsec_ixs_cache_allocated_count_max = 1000;
39556 +MODULE_PARM(ipsec_ixs_cache_allocated_count_max, "i");
39557 +MODULE_PARM_DESC(ipsec_ixs_cache_allocated_count_max,
39558 + "Maximum outstanding transmit packets");
39559 +
39560 +int
39561 +ipsec_xmit_state_cache_init (void)
39562 +{
39563 + if (ixs_cache_allocator)
39564 + return -EBUSY;
39565 +
39566 + spin_lock_init(&ixs_cache_lock);
39567 +#ifdef HAVE_KMEM_CACHE_MACRO
39568 + /* ixs_cache_allocator = KMEM_CACHE(ipsec_ixs,0); */
39569 + ixs_cache_allocator = kmem_cache_create ("ipsec_ixs",
39570 + sizeof (struct ipsec_xmit_state), 0,
39571 + 0, NULL);
39572 +#else
39573 + ixs_cache_allocator = kmem_cache_create ("ipsec_ixs",
39574 + sizeof (struct ipsec_xmit_state), 0,
39575 + 0, NULL, NULL);
39576 +#endif
39577 + if (! ixs_cache_allocator)
39578 + return -ENOMEM;
39579 +
39580 + return 0;
39581 +}
39582 +
39583 +void
39584 +ipsec_xmit_state_cache_cleanup (void)
39585 +{
39586 + if (unlikely (ixs_cache_allocated_count))
39587 + printk ("ipsec: deleting ipsec_ixs kmem_cache while in use\n");
39588 +
39589 + if (ixs_cache_allocator) {
39590 + kmem_cache_destroy (ixs_cache_allocator);
39591 + ixs_cache_allocator = NULL;
39592 + }
39593 + ixs_cache_allocated_count = 0;
39594 +}
39595 +
39596 +struct ipsec_xmit_state *
39597 +ipsec_xmit_state_new (void)
39598 +{
39599 + struct ipsec_xmit_state *ixs;
39600 +
39601 + spin_lock_bh (&ixs_cache_lock);
39602 +
39603 + if (ixs_cache_allocated_count >= ipsec_ixs_cache_allocated_count_max) {
39604 + spin_unlock_bh (&ixs_cache_lock);
39605 + KLIPS_PRINT(debug_tunnel,
39606 + "klips_debug:ipsec_xmit_state_new: "
39607 + "exceeded maximum outstanding TX packet cnt %d\n",
39608 + ixs_cache_allocated_count);
39609 + return NULL;
39610 + }
39611 +
39612 + ixs = kmem_cache_alloc (ixs_cache_allocator, GFP_ATOMIC);
39613 +
39614 + if (likely (ixs != NULL))
39615 + ixs_cache_allocated_count++;
39616 +
39617 + spin_unlock_bh (&ixs_cache_lock);
39618 +
39619 + if (unlikely (NULL == ixs))
39620 + goto bail;
39621 +
39622 + // initialize the object
39623 +#if 1 /* optimised to only clear the required bits */
39624 + memset((caddr_t)ixs, 0, sizeof(*ixs));
39625 +#else
39626 + ixs->pass = 0;
39627 + ixs->state = 0;
39628 + ixs->next_state = 0;
39629 + ixs->ipsp = NULL;
39630 + ixs->sa_len = 0;
39631 + ixs->stats = NULL;
39632 + ixs->ips.ips_ident_s.data = NULL;
39633 + ixs->ips.ips_ident_d.data = NULL;
39634 + ixs->outgoing_said.proto = 0;
39635 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
39636 + ixs->natt_type = 0, ixs->natt_head = 0;
39637 + ixs->natt_sport = 0, ixs->natt_dport = 0;
39638 +#endif
39639 + ixs->tot_headroom = 0;
39640 + ixs->tot_tailroom = 0;
39641 + ixs->eroute = NULL;
39642 + ixs->hard_header_stripped = 0;
39643 + ixs->hard_header_len = 0;
39644 + ixs->cur_mtu = 0; /* FIXME: can we do something better ? */
39645 +
39646 + ixs->oskb = NULL;
39647 + ixs->saved_header = NULL; /* saved copy of the hard header */
39648 + ixs->route = NULL;
39649 +#endif /* memset */
39650 +
39651 +bail:
39652 + return ixs;
39653 +}
39654 +
39655 +void
39656 +ipsec_xmit_state_delete (struct ipsec_xmit_state *ixs)
39657 +{
39658 + if (unlikely (! ixs))
39659 + return;
39660 +
39661 + spin_lock_bh (&ixs_cache_lock);
39662 +
39663 + ixs_cache_allocated_count--;
39664 + kmem_cache_free (ixs_cache_allocator, ixs);
39665 +
39666 + spin_unlock_bh (&ixs_cache_lock);
39667 +}
39668 +
39669 +/*
39670 + * Local Variables:
39671 + * c-style: linux
39672 + * End:
39673 + */
39674 --- /dev/null Tue Mar 11 13:02:56 2003
39675 +++ linux/net/ipsec/ipsec_xform.c Mon Feb 9 13:51:03 2004
39676 @@ -0,0 +1,69 @@
39677 +/*
39678 + * Common routines for IPSEC transformations.
39679 + * Copyright (C) 1996, 1997 John Ioannidis.
39680 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
39681 + *
39682 + * This program is free software; you can redistribute it and/or modify it
39683 + * under the terms of the GNU General Public License as published by the
39684 + * Free Software Foundation; either version 2 of the License, or (at your
39685 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
39686 + *
39687 + * This program is distributed in the hope that it will be useful, but
39688 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
39689 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
39690 + * for more details.
39691 + *
39692 + * RCSID $Id: ipsec_xform.c,v 1.65 2005/04/29 05:10:22 mcr Exp $
39693 + */
39694 +
39695 +#ifndef AUTOCONF_INCLUDED
39696 +#include <linux/config.h>
39697 +#endif
39698 +#include <linux/version.h>
39699 +#include <linux/kernel.h> /* printk() */
39700 +
39701 +#include "freeswan/ipsec_param.h"
39702 +
39703 +#ifdef MALLOC_SLAB
39704 +# include <linux/slab.h> /* kmalloc() */
39705 +#else /* MALLOC_SLAB */
39706 +# include <linux/malloc.h> /* kmalloc() */
39707 +#endif /* MALLOC_SLAB */
39708 +#include <linux/errno.h> /* error codes */
39709 +#include <linux/types.h> /* size_t */
39710 +#include <linux/interrupt.h> /* mark_bh */
39711 +
39712 +#include <linux/netdevice.h> /* struct device, and other headers */
39713 +#include <linux/etherdevice.h> /* eth_type_trans */
39714 +#include <linux/ip.h> /* struct iphdr */
39715 +#include <linux/skbuff.h>
39716 +#include <linux/random.h> /* get_random_bytes() */
39717 +#include <freeswan.h>
39718 +#ifdef SPINLOCK
39719 +# ifdef SPINLOCK_23
39720 +# include <linux/spinlock.h> /* *lock* */
39721 +# else /* SPINLOCK_23 */
39722 +# include <asm/spinlock.h> /* *lock* */
39723 +# endif /* SPINLOCK_23 */
39724 +#endif /* SPINLOCK */
39725 +
39726 +#include <net/ip.h>
39727 +
39728 +#include "freeswan/radij.h"
39729 +#include "freeswan/ipsec_encap.h"
39730 +#include "freeswan/ipsec_radij.h"
39731 +#include "freeswan/ipsec_xform.h"
39732 +#include "freeswan/ipsec_ipe4.h"
39733 +#include "freeswan/ipsec_ah.h"
39734 +#include "freeswan/ipsec_esp.h"
39735 +
39736 +#include <openswan/pfkeyv2.h>
39737 +#include <openswan/pfkey.h>
39738 +
39739 +/*
39740 + *
39741 + * Local Variables:
39742 + * c-file-style: "linux"
39743 + * End:
39744 + *
39745 + */
39746 --- /dev/null Tue Mar 11 13:02:56 2003
39747 +++ linux/net/ipsec/ipsec_xmit.c Mon Feb 9 13:51:03 2004
39748 @@ -0,0 +1,2273 @@
39749 +/*
39750 + * IPSEC Transmit code.
39751 + * Copyright (C) 1996, 1997 John Ioannidis.
39752 + * Copyright (C) 1998-2003 Richard Guy Briggs.
39753 + * Copyright (C) 2004-2005 Michael Richardson <mcr@xelerance.com>
39754 + *
39755 + * OCF/receive state machine written by
39756 + * David McCullough <dmccullough@cyberguard.com>
39757 + * Copyright (C) 2004-2005 Intel Corporation. All Rights Reserved.
39758 + *
39759 + * This program is free software; you can redistribute it and/or modify it
39760 + * under the terms of the GNU General Public License as published by the
39761 + * Free Software Foundation; either version 2 of the License, or (at your
39762 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
39763 + *
39764 + * This program is distributed in the hope that it will be useful, but
39765 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
39766 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
39767 + * for more details.
39768 + */
39769 +
39770 +#define __NO_VERSION__
39771 +#include <linux/module.h>
39772 +#ifndef AUTOCONF_INCLUDED
39773 +#include <linux/config.h>
39774 +#endif /* for CONFIG_IP_FORWARD */
39775 +#include <linux/version.h>
39776 +#include <linux/kernel.h> /* printk() */
39777 +
39778 +#include "openswan/ipsec_param.h"
39779 +
39780 +
39781 +#ifdef MALLOC_SLAB
39782 +# include <linux/slab.h> /* kmalloc() */
39783 +#else /* MALLOC_SLAB */
39784 +# include <linux/malloc.h> /* kmalloc() */
39785 +#endif /* MALLOC_SLAB */
39786 +#include <linux/errno.h> /* error codes */
39787 +#include <linux/types.h> /* size_t */
39788 +#include <linux/interrupt.h> /* mark_bh */
39789 +
39790 +#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
39791 +#include <linux/etherdevice.h> /* eth_type_trans */
39792 +#include <linux/ip.h> /* struct iphdr */
39793 +
39794 +#include <net/tcp.h>
39795 +#include <net/udp.h>
39796 +#include <linux/skbuff.h>
39797 +
39798 +#include <asm/uaccess.h>
39799 +#include <asm/checksum.h>
39800 +#include <openswan.h>
39801 +#ifdef NET_21
39802 +# define MSS_HACK_ /* experimental */
39803 +# include <linux/in6.h>
39804 +# include <net/dst.h>
39805 +# define proto_priv cb
39806 +#endif /* NET_21 */
39807 +
39808 +#include <net/icmp.h> /* icmp_send() */
39809 +#include <net/ip.h>
39810 +#ifdef NETDEV_23
39811 +# include <linux/netfilter_ipv4.h>
39812 +#endif /* NETDEV_23 */
39813 +
39814 +#include <linux/if_arp.h>
39815 +#ifdef MSS_HACK
39816 +# include <net/tcp.h> /* TCP options */
39817 +#endif /* MSS_HACK */
39818 +
39819 +#include "openswan/ipsec_kern24.h"
39820 +#include "openswan/radij.h"
39821 +#include "openswan/ipsec_life.h"
39822 +#include "openswan/ipsec_xform.h"
39823 +#include "openswan/ipsec_eroute.h"
39824 +#include "openswan/ipsec_encap.h"
39825 +#include "openswan/ipsec_radij.h"
39826 +#include "openswan/ipsec_xmit.h"
39827 +#include "openswan/ipsec_sa.h"
39828 +#include "openswan/ipsec_tunnel.h"
39829 +#include "openswan/ipsec_ipe4.h"
39830 +#include "openswan/ipsec_ah.h"
39831 +#include "openswan/ipsec_esp.h"
39832 +
39833 +#ifdef CONFIG_KLIPS_IPCOMP
39834 +#include "openswan/ipcomp.h"
39835 +#endif /* CONFIG_KLIPS_IPCOMP */
39836 +
39837 +#include <openswan/pfkeyv2.h>
39838 +#include <openswan/pfkey.h>
39839 +
39840 +#include "openswan/ipsec_proto.h"
39841 +#include "openswan/ipsec_alg.h"
39842 +#include "ipsec_ocf.h"
39843 +
39844 +
39845 +/*
39846 + * Stupid kernel API differences in APIs. Not only do some
39847 + * kernels not have ip_select_ident, but some have differing APIs,
39848 + * and SuSE has one with one parameter, but no way of checking to
39849 + * see what is really what.
39850 + */
39851 +
39852 +#ifdef SUSE_LINUX_2_4_19_IS_STUPID
39853 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
39854 +#else
39855 +
39856 +/* simplest case, nothing */
39857 +#if !defined(IP_SELECT_IDENT)
39858 +#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
39859 +#endif
39860 +
39861 +/* kernels > 2.3.37-ish */
39862 +#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
39863 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
39864 +#endif
39865 +
39866 +/* kernels > 2.4.2 */
39867 +#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
39868 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
39869 +#endif
39870 +
39871 +#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
39872 +
39873 +
39874 +
39875 +#if defined(CONFIG_KLIPS_AH)
39876 +#if defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMAC_SHA1)
39877 +static __u32 zeroes[64];
39878 +#endif
39879 +#endif
39880 +
39881 +int ipsec_xmit_trap_count = 0;
39882 +int ipsec_xmit_trap_sendcount = 0;
39883 +
39884 +#ifdef CONFIG_KLIPS_DEBUG
39885 +#define dmp(_x,_y,_z) if(debug_xmit && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
39886 +#else /* CONFIG_KLIPS_DEBUG */
39887 +#define dmp(_x, _y, _z)
39888 +#endif /* CONFIG_KLIPS_DEBUG */
39889 +
39890 +
39891 +#if !defined(SKB_COPY_EXPAND) || defined(KLIPS_UNIT_TESTS)
39892 +/*
39893 + * This is mostly skbuff.c:skb_copy().
39894 + */
39895 +struct sk_buff *
39896 +skb_copy_expand(const struct sk_buff *skb, int headroom,
39897 + int tailroom, int priority)
39898 +{
39899 + struct sk_buff *n;
39900 + unsigned long offset;
39901 +
39902 + /*
39903 + * Do sanity checking
39904 + */
39905 + if((headroom < 0) || (tailroom < 0) || ((headroom+tailroom) < 0)) {
39906 + printk(KERN_WARNING
39907 + "klips_error:skb_copy_expand: "
39908 + "Illegal negative head,tailroom %d,%d\n",
39909 + headroom,
39910 + tailroom);
39911 + return NULL;
39912 + }
39913 + /*
39914 + * Allocate the copy buffer
39915 + */
39916 +
39917 +#ifndef NET_21
39918 + IS_SKB(skb);
39919 +#endif /* !NET_21 */
39920 +
39921 +
39922 + n=alloc_skb(skb->end - skb->head + headroom + tailroom, priority);
39923 +
39924 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
39925 + "klips_debug:skb_copy_expand: "
39926 + "allocating %d bytes, head=0p%p data=0p%p tail=0p%p end=0p%p end-head=%d tail-data=%d\n",
39927 + skb->end - skb->head + headroom + tailroom,
39928 + skb->head,
39929 + skb->data,
39930 + skb->tail,
39931 + skb->end,
39932 + skb->end - skb->head,
39933 + skb->tail - skb->data);
39934 +
39935 + if(n==NULL)
39936 + return NULL;
39937 +
39938 + /*
39939 + * Shift between the two data areas in bytes
39940 + */
39941 +
39942 + /* Set the data pointer */
39943 + skb_reserve(n,skb->data-skb->head+headroom);
39944 + /* Set the tail pointer and length */
39945 + if(skb_tailroom(n) < skb->len) {
39946 + printk(KERN_WARNING "klips_error:skb_copy_expand: "
39947 + "tried to skb_put %ld, %d available. This should never happen, please report.\n",
39948 + (unsigned long int)skb->len,
39949 + skb_tailroom(n));
39950 + ipsec_kfree_skb(n);
39951 + return NULL;
39952 + }
39953 + skb_put(n,skb->len);
39954 +
39955 + offset=n->head + headroom - skb->head;
39956 +
39957 + /* Copy the bytes */
39958 + memcpy(n->head + headroom, skb->head,skb->end-skb->head);
39959 +#ifdef NET_21
39960 + n->csum=skb->csum;
39961 + n->priority=skb->priority;
39962 + n->dst=dst_clone(skb->dst);
39963 + if(skb->nh.raw)
39964 + n->nh.raw=skb->nh.raw+offset;
39965 +#ifndef NETDEV_23
39966 + n->is_clone=0;
39967 +#endif /* NETDEV_23 */
39968 + atomic_set(&n->users, 1);
39969 + n->destructor = NULL;
39970 +#ifdef HAVE_SOCK_SECURITY
39971 + n->security=skb->security;
39972 +#endif
39973 +#else /* NET_21 */
39974 + n->link3=NULL;
39975 + n->when=skb->when;
39976 + if(skb->ip_hdr)
39977 + n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
39978 + n->saddr=skb->saddr;
39979 + n->daddr=skb->daddr;
39980 + n->raddr=skb->raddr;
39981 + n->seq=skb->seq;
39982 + n->end_seq=skb->end_seq;
39983 + n->ack_seq=skb->ack_seq;
39984 + n->acked=skb->acked;
39985 + n->free=1;
39986 + n->arp=skb->arp;
39987 + n->tries=0;
39988 + n->lock=0;
39989 + n->users=0;
39990 +#endif /* NET_21 */
39991 + n->protocol=skb->protocol;
39992 + n->list=NULL;
39993 + n->sk=NULL;
39994 + n->dev=skb->dev;
39995 + if(skb->h.raw)
39996 + n->h.raw=skb->h.raw+offset;
39997 + if(skb->mac.raw)
39998 + n->mac.raw=skb->mac.raw+offset;
39999 + memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
40000 +#ifndef NETDEV_23
40001 + n->used=skb->used;
40002 +#endif /* !NETDEV_23 */
40003 + n->pkt_type=skb->pkt_type;
40004 + n->stamp=skb->stamp;
40005 +
40006 +#ifndef NET_21
40007 + IS_SKB(n);
40008 +#endif /* !NET_21 */
40009 + return n;
40010 +}
40011 +#endif /* !SKB_COPY_EXPAND */
40012 +
40013 +#ifdef CONFIG_KLIPS_DEBUG
40014 +void
40015 +ipsec_print_ip(struct iphdr *ip)
40016 +{
40017 + char buf[ADDRTOA_BUF];
40018 +
40019 + printk(KERN_INFO "klips_debug: IP:");
40020 + printk(" ihl:%d", ip->ihl << 2);
40021 + printk(" ver:%d", ip->version);
40022 + printk(" tos:%d", ip->tos);
40023 + printk(" tlen:%d", ntohs(ip->tot_len));
40024 + printk(" id:%d", ntohs(ip->id));
40025 + printk(" %s%s%sfrag_off:%d",
40026 + ip->frag_off & __constant_htons(IP_CE) ? "CE " : "",
40027 + ip->frag_off & __constant_htons(IP_DF) ? "DF " : "",
40028 + ip->frag_off & __constant_htons(IP_MF) ? "MF " : "",
40029 + (ntohs(ip->frag_off) & IP_OFFSET) << 3);
40030 + printk(" ttl:%d", ip->ttl);
40031 + printk(" proto:%d", ip->protocol);
40032 + if(ip->protocol == IPPROTO_UDP)
40033 + printk(" (UDP)");
40034 + if(ip->protocol == IPPROTO_TCP)
40035 + printk(" (TCP)");
40036 + if(ip->protocol == IPPROTO_ICMP)
40037 + printk(" (ICMP)");
40038 + if(ip->protocol == IPPROTO_ESP)
40039 + printk(" (ESP)");
40040 + if(ip->protocol == IPPROTO_AH)
40041 + printk(" (AH)");
40042 + if(ip->protocol == IPPROTO_COMP)
40043 + printk(" (COMP)");
40044 + printk(" chk:%d", ntohs(ip->check));
40045 + addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf));
40046 + printk(" saddr:%s", buf);
40047 + if(ip->protocol == IPPROTO_UDP)
40048 + printk(":%d",
40049 + ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
40050 + if(ip->protocol == IPPROTO_TCP)
40051 + printk(":%d",
40052 + ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
40053 + addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf));
40054 + printk(" daddr:%s", buf);
40055 + if(ip->protocol == IPPROTO_UDP)
40056 + printk(":%d",
40057 + ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
40058 + if(ip->protocol == IPPROTO_TCP)
40059 + printk(":%d",
40060 + ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
40061 + if(ip->protocol == IPPROTO_ICMP)
40062 + printk(" type:code=%d:%d",
40063 + ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type,
40064 + ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code);
40065 + printk("\n");
40066 +
40067 + if(sysctl_ipsec_debug_verbose) {
40068 + __u8 *c;
40069 + int len = ntohs(ip->tot_len) - ip->ihl*4;
40070 +
40071 + c = ((__u8*)ip) + ip->ihl*4;
40072 + ipsec_dmp_block("ip_print", c, len);
40073 + }
40074 +}
40075 +#endif /* CONFIG_KLIPS_DEBUG */
40076 +
40077 +#ifdef MSS_HACK
40078 +/*
40079 + * Issues:
40080 + * 1) Fragments arriving in the tunnel should probably be rejected.
40081 + * 2) How does this affect syncookies, mss_cache, dst cache ?
40082 + * 3) Path MTU discovery handling needs to be reviewed. For example,
40083 + * if we receive an ICMP 'packet too big' message from an intermediate
40084 + * router specifying it's next hop MTU, our stack may process this and
40085 + * adjust the MSS without taking our AH/ESP overheads into account.
40086 + */
40087 +
40088 +
40089 +/*
40090 + * Recaclulate checksum using differences between changed datum,
40091 + * borrowed from netfilter.
40092 + */
40093 +DEBUG_NO_STATIC u_int16_t
40094 +ipsec_fast_csum(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
40095 +{
40096 + u_int32_t diffs[] = { oldvalinv, newval };
40097 + return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
40098 + oldcheck^0xFFFF));
40099 +}
40100 +
40101 +/*
40102 + * Determine effective MSS.
40103 + *
40104 + * Note that we assume that there is always an MSS option for our own
40105 + * SYN segments, which is mentioned in tcp_syn_build_options(), kernel 2.2.x.
40106 + * This could change, and we should probably parse TCP options instead.
40107 + *
40108 + */
40109 +DEBUG_NO_STATIC u_int8_t
40110 +ipsec_adjust_mss(struct sk_buff *skb, struct tcphdr *tcph, u_int16_t mtu)
40111 +{
40112 + u_int16_t oldmss, newmss;
40113 + u_int32_t *mssp;
40114 + struct sock *sk = skb->sk;
40115 +
40116 + newmss = tcp_sync_mss(sk, mtu);
40117 + printk(KERN_INFO "klips: setting mss to %u\n", newmss);
40118 + mssp = (u_int32_t *)tcph + sizeof(struct tcphdr) / sizeof(u_int32_t);
40119 + oldmss = ntohl(*mssp) & 0x0000FFFF;
40120 + *mssp = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | newmss);
40121 + tcph->check = ipsec_fast_csum(htons(~oldmss),
40122 + htons(newmss), tcph->check);
40123 + return 1;
40124 +}
40125 +#endif /* MSS_HACK */
40126 +
40127 +#ifdef CONFIG_KLIPS_DEBUG
40128 +DEBUG_NO_STATIC char *
40129 +ipsec_xmit_err(int err)
40130 +{
40131 + static char tmp[32];
40132 + switch ((int) err) {
40133 + case IPSEC_XMIT_STOLEN: return("IPSEC_XMIT_STOLEN");
40134 + case IPSEC_XMIT_PASS: return("IPSEC_XMIT_PASS");
40135 + case IPSEC_XMIT_OK: return("IPSEC_XMIT_OK");
40136 + case IPSEC_XMIT_ERRMEMALLOC: return("IPSEC_XMIT_ERRMEMALLOC");
40137 + case IPSEC_XMIT_ESP_BADALG: return("IPSEC_XMIT_ESP_BADALG");
40138 + case IPSEC_XMIT_BADPROTO: return("IPSEC_XMIT_BADPROTO");
40139 + case IPSEC_XMIT_ESP_PUSHPULLERR:return("IPSEC_XMIT_ESP_PUSHPULLERR");
40140 + case IPSEC_XMIT_BADLEN: return("IPSEC_XMIT_BADLEN");
40141 + case IPSEC_XMIT_AH_BADALG: return("IPSEC_XMIT_AH_BADALG");
40142 + case IPSEC_XMIT_SAIDNOTFOUND: return("IPSEC_XMIT_SAIDNOTFOUND");
40143 + case IPSEC_XMIT_SAIDNOTLIVE: return("IPSEC_XMIT_SAIDNOTLIVE");
40144 + case IPSEC_XMIT_REPLAYROLLED: return("IPSEC_XMIT_REPLAYROLLED");
40145 + case IPSEC_XMIT_LIFETIMEFAILED: return("IPSEC_XMIT_LIFETIMEFAILED");
40146 + case IPSEC_XMIT_CANNOTFRAG: return("IPSEC_XMIT_CANNOTFRAG");
40147 + case IPSEC_XMIT_MSSERR: return("IPSEC_XMIT_MSSERR");
40148 + case IPSEC_XMIT_ERRSKBALLOC: return("IPSEC_XMIT_ERRSKBALLOC");
40149 + case IPSEC_XMIT_ENCAPFAIL: return("IPSEC_XMIT_ENCAPFAIL");
40150 + case IPSEC_XMIT_NODEV: return("IPSEC_XMIT_NODEV");
40151 + case IPSEC_XMIT_NOPRIVDEV: return("IPSEC_XMIT_NOPRIVDEV");
40152 + case IPSEC_XMIT_NOPHYSDEV: return("IPSEC_XMIT_NOPHYSDEV");
40153 + case IPSEC_XMIT_NOSKB: return("IPSEC_XMIT_NOSKB");
40154 + case IPSEC_XMIT_NOIPV6: return("IPSEC_XMIT_NOIPV6");
40155 + case IPSEC_XMIT_NOIPOPTIONS: return("IPSEC_XMIT_NOIPOPTIONS");
40156 + case IPSEC_XMIT_TTLEXPIRED: return("IPSEC_XMIT_TTLEXPIRED");
40157 + case IPSEC_XMIT_BADHHLEN: return("IPSEC_XMIT_BADHHLEN");
40158 + case IPSEC_XMIT_PUSHPULLERR: return("IPSEC_XMIT_PUSHPULLERR");
40159 + case IPSEC_XMIT_ROUTEERR: return("IPSEC_XMIT_ROUTEERR");
40160 + case IPSEC_XMIT_RECURSDETECT: return("IPSEC_XMIT_RECURSDETECT");
40161 + case IPSEC_XMIT_IPSENDFAILURE: return("IPSEC_XMIT_IPSENDFAILURE");
40162 + case IPSEC_XMIT_ESPUDP: return("IPSEC_XMIT_ESPUDP");
40163 + case IPSEC_XMIT_ESPUDP_BADTYPE: return("IPSEC_XMIT_ESPUDP_BADTYPE");
40164 + case IPSEC_XMIT_PENDING: return("IPSEC_XMIT_PENDING");
40165 + }
40166 + snprintf(tmp, sizeof(tmp), "%d", err);
40167 + return tmp;
40168 +}
40169 +#endif
40170 +
40171 +/*
40172 + * Sanity checks
40173 + */
40174 +enum ipsec_xmit_value
40175 +ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs)
40176 +{
40177 +
40178 + if (ixs->dev == NULL) {
40179 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
40180 + "klips_error:ipsec_xmit_sanity_check_dev: "
40181 + "No device associated with skb!\n" );
40182 + return IPSEC_XMIT_NODEV;
40183 + }
40184 +
40185 + ixs->prv = ixs->dev->priv;
40186 + if (ixs->prv == NULL) {
40187 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
40188 + "klips_error:ipsec_xmit_sanity_check_dev: "
40189 + "Device has no private structure!\n" );
40190 + return IPSEC_XMIT_NOPRIVDEV;
40191 + }
40192 +
40193 + ixs->physdev = ixs->prv->dev;
40194 + if (ixs->physdev == NULL) {
40195 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
40196 + "klips_error:ipsec_xmit_sanity_check_dev: "
40197 + "Device is not attached to physical device!\n" );
40198 + return IPSEC_XMIT_NOPHYSDEV;
40199 + }
40200 +
40201 + ixs->physmtu = ixs->physdev->mtu;
40202 + ixs->cur_mtu = ixs->physdev->mtu;
40203 + ixs->stats = (struct net_device_stats *) &(ixs->prv->mystats);
40204 +
40205 + return IPSEC_XMIT_OK;
40206 +}
40207 +
40208 +enum ipsec_xmit_value
40209 +ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs)
40210 +{
40211 + /*
40212 + * Return if there is nothing to do. (Does this ever happen?) XXX
40213 + */
40214 + if (ixs->skb == NULL) {
40215 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
40216 + "klips_error:ipsec_xmit_sanity_check_skb: "
40217 + "Nothing to do!\n" );
40218 + return IPSEC_XMIT_NOSKB;
40219 + }
40220 +
40221 + /* if skb was cloned (most likely due to a packet sniffer such as
40222 + tcpdump being momentarily attached to the interface), make
40223 + a copy of our own to modify */
40224 + if(skb_cloned(ixs->skb)) {
40225 + if
40226 +#ifdef SKB_COW_NEW
40227 + (skb_cow(ixs->skb, skb_headroom(ixs->skb)) != 0)
40228 +#else /* SKB_COW_NEW */
40229 + ((ixs->skb = skb_cow(ixs->skb, skb_headroom(ixs->skb))) == NULL)
40230 +#endif /* SKB_COW_NEW */
40231 + {
40232 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
40233 + "klips_error:ipsec_xmit_sanity_check_skb: "
40234 + "skb_cow failed to allocate buffer, dropping.\n" );
40235 + ixs->stats->tx_dropped++;
40236 + return IPSEC_XMIT_ERRSKBALLOC;
40237 + }
40238 + }
40239 +
40240 + ixs->iph = ip_hdr(ixs->skb);
40241 +
40242 + /* sanity check for IP version as we can't handle IPv6 right now */
40243 + if (ixs->iph->version != 4) {
40244 + KLIPS_PRINT(debug_tunnel,
40245 + "klips_debug:ipsec_xmit_sanity_check_skb: "
40246 + "found IP Version %d but cannot process other IP versions than v4.\n",
40247 + ixs->iph->version); /* XXX */
40248 + ixs->stats->tx_dropped++;
40249 + return IPSEC_XMIT_NOIPV6;
40250 + }
40251 +
40252 +#if IPSEC_DISALLOW_IPOPTIONS
40253 + if ((ixs->iph->ihl << 2) != sizeof (struct iphdr)) {
40254 + KLIPS_PRINT(debug_tunnel,
40255 + "klips_debug:ipsec_xmit_sanity_check_skb: "
40256 + "cannot process IP header options yet. May be mal-formed packet.\n"); /* XXX */
40257 + ixs->stats->tx_dropped++;
40258 + return IPSEC_XMIT_NOIPOPTIONS;
40259 + }
40260 +#endif /* IPSEC_DISALLOW_IPOPTIONS */
40261 +
40262 +#ifndef NET_21
40263 + if (ixs->iph->ttl <= 0) {
40264 + /* Tell the sender its packet died... */
40265 + ICMP_SEND(ixs->skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, ixs->physdev);
40266 +
40267 + KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_xmit_sanity_check_skb: "
40268 + "TTL=0, too many hops!\n");
40269 + ixs->stats->tx_dropped++;
40270 + return IPSEC_XMIT_TTLEXPIRED;
40271 + }
40272 +#endif /* !NET_21 */
40273 +
40274 + return IPSEC_XMIT_OK;
40275 +}
40276 +
40277 +
40278 +enum ipsec_xmit_value
40279 +ipsec_xmit_encap_init(struct ipsec_xmit_state *ixs)
40280 +{
40281 + ixs->blocksize = 8;
40282 + ixs->headroom = 0;
40283 + ixs->tailroom = 0;
40284 + ixs->authlen = 0;
40285 +
40286 +#ifdef CONFIG_KLIPS_ALG
40287 + ixs->ixt_e = NULL;
40288 + ixs->ixt_a = NULL;
40289 +#endif /* CONFIG_KLIPS_ALG */
40290 +
40291 + ixs->iphlen = ixs->iph->ihl << 2;
40292 + ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
40293 + ixs->sa_len = KLIPS_SATOT(debug_tunnel, &ixs->ipsp->ips_said, 0, ixs->sa_txt, SATOT_BUF);
40294 + KLIPS_PRINT(debug_tunnel & DB_TN_OXFS,
40295 + "klips_debug:ipsec_xmit_encap_once: "
40296 + "calling output for <%s%s%s>, SA:%s\n",
40297 + IPS_XFORM_NAME(ixs->ipsp),
40298 + ixs->sa_len ? ixs->sa_txt : " (error)");
40299 + switch(ixs->ipsp->ips_said.proto) {
40300 +#ifdef CONFIG_KLIPS_AH
40301 + case IPPROTO_AH:
40302 + ixs->headroom += sizeof(struct ahhdr);
40303 + break;
40304 +#endif /* CONFIG_KLIPS_AH */
40305 +#ifdef CONFIG_KLIPS_ESP
40306 + case IPPROTO_ESP:
40307 +#ifdef CONFIG_KLIPS_OCF
40308 + /*
40309 + * this needs cleaning up for sure - DM
40310 + */
40311 + if (ixs->ipsp->ocf_in_use) {
40312 + switch (ixs->ipsp->ips_encalg) {
40313 + case ESP_DES:
40314 + case ESP_3DES:
40315 + ixs->blocksize = 8;
40316 + ixs->headroom += ESP_HEADER_LEN + 8 /* ivsize */;
40317 + break;
40318 + case ESP_AES:
40319 + ixs->blocksize = 16;
40320 + ixs->headroom += ESP_HEADER_LEN + 16 /* ivsize */;
40321 + break;
40322 + default:
40323 + ixs->stats->tx_errors++;
40324 + return IPSEC_XMIT_ESP_BADALG;
40325 + }
40326 + } else
40327 +#endif
40328 +#ifdef CONFIG_KLIPS_ALG
40329 + if ((ixs->ixt_e=ixs->ipsp->ips_alg_enc)) {
40330 + ixs->blocksize = ixs->ixt_e->ixt_common.ixt_blocksize;
40331 + ixs->headroom += ESP_HEADER_LEN + ixs->ixt_e->ixt_common.ixt_support.ias_ivlen/8;
40332 + } else
40333 +#endif /* CONFIG_KLIPS_ALG */
40334 + {
40335 + ixs->stats->tx_errors++;
40336 + return IPSEC_XMIT_ESP_BADALG;
40337 + }
40338 +#ifdef CONFIG_KLIPS_OCF
40339 + if (ixs->ipsp->ocf_in_use) {
40340 + switch (ixs->ipsp->ips_authalg) {
40341 + case AH_MD5:
40342 + case AH_SHA:
40343 + ixs->authlen = AHHMAC_HASHLEN;
40344 + break;
40345 + case AH_NONE:
40346 + break;
40347 + }
40348 + } else
40349 +#endif /* CONFIG_KLIPS_OCF */
40350 +#ifdef CONFIG_KLIPS_ALG
40351 +
40352 + ixs->ixt_a=ixs->ipsp->ips_alg_auth;
40353 + if (ixs->ixt_a) {
40354 + ixs->tailroom += AHHMAC_HASHLEN;
40355 + ixs->authlen = AHHMAC_HASHLEN;
40356 + } else
40357 +#endif /* CONFIG_KLIPS_ALG */
40358 + switch(ixs->ipsp->ips_authalg) {
40359 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
40360 + case AH_MD5:
40361 + ixs->authlen = AHHMAC_HASHLEN;
40362 + break;
40363 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
40364 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
40365 + case AH_SHA:
40366 + ixs->authlen = AHHMAC_HASHLEN;
40367 + break;
40368 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
40369 + case AH_NONE:
40370 + break;
40371 + default:
40372 + ixs->stats->tx_errors++;
40373 + return IPSEC_XMIT_ESP_BADALG;
40374 + }
40375 + ixs->tailroom += ixs->blocksize != 1 ?
40376 + ((ixs->blocksize - ((ixs->pyldsz + 2) % ixs->blocksize)) % ixs->blocksize) + 2 :
40377 + ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
40378 + ixs->tailroom += ixs->authlen;
40379 + break;
40380 +#endif /* !CONFIG_KLIPS_ESP */
40381 +#ifdef CONFIG_KLIPS_IPIP
40382 + case IPPROTO_IPIP:
40383 + ixs->headroom += sizeof(struct iphdr);
40384 + ixs->iphlen = sizeof(struct iphdr);
40385 + break;
40386 +#endif /* !CONFIG_KLIPS_IPIP */
40387 +#ifdef CONFIG_KLIPS_IPCOMP
40388 + case IPPROTO_COMP:
40389 + break;
40390 +#endif /* CONFIG_KLIPS_IPCOMP */
40391 + default:
40392 + ixs->stats->tx_errors++;
40393 + return IPSEC_XMIT_BADPROTO;
40394 + }
40395 +
40396 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
40397 + "klips_debug:ipsec_xmit_encap_once: "
40398 + "pushing %d bytes, putting %d, proto %d.\n",
40399 + ixs->headroom, ixs->tailroom, ixs->ipsp->ips_said.proto);
40400 + if(skb_headroom(ixs->skb) < ixs->headroom) {
40401 + printk(KERN_WARNING
40402 + "klips_error:ipsec_xmit_encap_once: "
40403 + "tried to skb_push headroom=%d, %d available. This should never happen, please report.\n",
40404 + ixs->headroom, skb_headroom(ixs->skb));
40405 + ixs->stats->tx_errors++;
40406 + return IPSEC_XMIT_ESP_PUSHPULLERR;
40407 + }
40408 +
40409 + ixs->dat = skb_push(ixs->skb, ixs->headroom);
40410 + ixs->ilen = ixs->skb->len - ixs->tailroom;
40411 + if(skb_tailroom(ixs->skb) < ixs->tailroom) {
40412 + printk(KERN_WARNING
40413 + "klips_error:ipsec_xmit_encap_once: "
40414 + "tried to skb_put %d, %d available. This should never happen, please report.\n",
40415 + ixs->tailroom, skb_tailroom(ixs->skb));
40416 + ixs->stats->tx_errors++;
40417 + return IPSEC_XMIT_ESP_PUSHPULLERR;
40418 + }
40419 + skb_put(ixs->skb, ixs->tailroom);
40420 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
40421 + "klips_debug:ipsec_xmit_encap_once: "
40422 + "head,tailroom: %d,%d before xform.\n",
40423 + skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
40424 + ixs->len = ixs->skb->len;
40425 + if(ixs->len > 0xfff0) {
40426 + printk(KERN_WARNING "klips_error:ipsec_xmit_encap_once: "
40427 + "tot_len (%d) > 65520. This should never happen, please report.\n",
40428 + ixs->len);
40429 + ixs->stats->tx_errors++;
40430 + return IPSEC_XMIT_BADLEN;
40431 + }
40432 + memmove((void *)ixs->dat, (void *)(ixs->dat + ixs->headroom), ixs->iphlen);
40433 + ixs->iph = (struct iphdr *)ixs->dat;
40434 + ixs->iph->tot_len = htons(ixs->skb->len);
40435 +
40436 + return IPSEC_XMIT_OK;
40437 +}
40438 +
40439 +
40440 +/*
40441 + * work out which state to proceed to next
40442 + */
40443 +
40444 +enum ipsec_xmit_value
40445 +ipsec_xmit_encap_select(struct ipsec_xmit_state *ixs)
40446 +{
40447 + switch (ixs->ipsp->ips_said.proto) {
40448 +#ifdef CONFIG_KLIPS_ESP
40449 + case IPPROTO_ESP:
40450 + ixs->next_state = IPSEC_XSM_ESP;
40451 + break;
40452 +#endif
40453 +#ifdef CONFIG_KLIPS_AH
40454 + case IPPROTO_AH:
40455 + ixs->next_state = IPSEC_XSM_AH;
40456 + break;
40457 +#endif
40458 +#ifdef CONFIG_KLIPS_IPIP
40459 + case IPPROTO_IPIP:
40460 + ixs->next_state = IPSEC_XSM_IPIP;
40461 + break;
40462 +#endif
40463 +#ifdef CONFIG_KLIPS_IPCOMP
40464 + case IPPROTO_COMP:
40465 + ixs->next_state = IPSEC_XSM_IPCOMP;
40466 + break;
40467 +#endif
40468 + default:
40469 + ixs->stats->tx_errors++;
40470 + return IPSEC_XMIT_BADPROTO;
40471 + }
40472 + return IPSEC_XMIT_OK;
40473 +}
40474 +
40475 +
40476 +#ifdef CONFIG_KLIPS_ESP
40477 +
40478 +enum ipsec_xmit_value
40479 +ipsec_xmit_esp(struct ipsec_xmit_state *ixs)
40480 +{
40481 + int i;
40482 + unsigned char *pad;
40483 + int padlen = 0;
40484 +
40485 + ixs->espp = (struct esphdr *)(ixs->dat + ixs->iphlen);
40486 +#ifdef NET_21
40487 + skb_set_transport_header(ixs->skb, ipsec_skb_offset(ixs->skb, ixs->espp));
40488 +#endif /* NET_21 */
40489 + ixs->espp->esp_spi = ixs->ipsp->ips_said.spi;
40490 + ixs->espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
40491 +
40492 + ixs->idat = ixs->dat + ixs->iphlen + ixs->headroom;
40493 + ixs->ilen = ixs->len - (ixs->iphlen + ixs->headroom + ixs->authlen);
40494 +
40495 + /* Self-describing padding */
40496 + pad = &ixs->dat[ixs->len - ixs->tailroom];
40497 + padlen = ixs->tailroom - 2 - ixs->authlen;
40498 + for (i = 0; i < padlen; i++) {
40499 + pad[i] = i + 1;
40500 + }
40501 + ixs->dat[ixs->len - ixs->authlen - 2] = padlen;
40502 +
40503 + ixs->dat[ixs->len - ixs->authlen - 1] = ixs->iph->protocol;
40504 + ixs->iph->protocol = IPPROTO_ESP;
40505 +
40506 +#ifdef CONFIG_KLIPS_OCF
40507 + if (ixs->ipsp->ocf_in_use)
40508 + return(ipsec_ocf_xmit(ixs));
40509 +#endif
40510 +
40511 +#ifdef CONFIG_KLIPS_ALG
40512 + if (!ixs->ixt_e) {
40513 + ixs->stats->tx_errors++;
40514 + return IPSEC_XMIT_ESP_BADALG;
40515 + }
40516 +
40517 +#ifdef CONFIG_KLIPS_DEBUG
40518 + if(debug_tunnel & DB_TN_ENCAP) {
40519 + dmp("pre-encrypt", ixs->dat, ixs->len);
40520 + }
40521 +#endif
40522 +
40523 + /*
40524 + * Do all operations here:
40525 + * copy IV->ESP, encrypt, update ips IV
40526 + *
40527 + */
40528 + {
40529 + int ret;
40530 + memcpy(ixs->espp->esp_iv,
40531 + ixs->ipsp->ips_iv,
40532 + ixs->ipsp->ips_iv_size);
40533 + ret=ipsec_alg_esp_encrypt(ixs->ipsp,
40534 + ixs->idat, ixs->ilen, ixs->espp->esp_iv,
40535 + IPSEC_ALG_ENCRYPT);
40536 +
40537 + prng_bytes(&ipsec_prng,
40538 + (char *)ixs->ipsp->ips_iv,
40539 + ixs->ipsp->ips_iv_size);
40540 + }
40541 + return IPSEC_XMIT_OK;
40542 +#else
40543 + return IPSEC_XMIT_ESP_BADALG;
40544 +#endif /* CONFIG_KLIPS_ALG */
40545 +}
40546 +
40547 +
40548 +enum ipsec_xmit_value
40549 +ipsec_xmit_esp_ah(struct ipsec_xmit_state *ixs)
40550 +{
40551 +#if defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMAC_SHA1)
40552 + __u8 hash[AH_AMAX];
40553 +#endif
40554 +#if defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMAC_SHA1)
40555 + union {
40556 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
40557 + MD5_CTX md5;
40558 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
40559 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
40560 + SHA1_CTX sha1;
40561 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
40562 + } tctx;
40563 +#endif /* defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMAC_SHA1) */
40564 +
40565 +#ifdef CONFIG_KLIPS_OCF
40566 + if (ixs->ipsp->ocf_in_use) {
40567 + /* we should never be here using OCF */
40568 + ixs->stats->tx_errors++;
40569 + return IPSEC_XMIT_AH_BADALG;
40570 + } else
40571 +#endif
40572 +#ifdef CONFIG_KLIPS_ALG
40573 + if (ixs->ixt_a) {
40574 + ipsec_alg_sa_esp_hash(ixs->ipsp,
40575 + (caddr_t)ixs->espp, ixs->len - ixs->iphlen - ixs->authlen,
40576 + &(ixs->dat[ixs->len - ixs->authlen]), ixs->authlen);
40577 +
40578 + } else
40579 +#endif /* CONFIG_KLIPS_ALG */
40580 + switch(ixs->ipsp->ips_authalg) {
40581 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
40582 + case AH_MD5:
40583 + dmp("espp", (char*)ixs->espp, ixs->len - ixs->iphlen - ixs->authlen);
40584 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
40585 + dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
40586 + osMD5Update(&tctx.md5, (caddr_t)ixs->espp, ixs->len - ixs->iphlen - ixs->authlen);
40587 + dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
40588 + osMD5Final(hash, &tctx.md5);
40589 + dmp("ictx hash", (char*)&hash, sizeof(hash));
40590 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
40591 + dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
40592 + osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
40593 + dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
40594 + osMD5Final(hash, &tctx.md5);
40595 + dmp("octx hash", (char*)&hash, sizeof(hash));
40596 + memcpy(&(ixs->dat[ixs->len - ixs->authlen]), hash, ixs->authlen);
40597 +
40598 + /* paranoid */
40599 + memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
40600 + memset((caddr_t)hash, 0, sizeof(*hash));
40601 + break;
40602 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
40603 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
40604 + case AH_SHA:
40605 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
40606 + SHA1Update(&tctx.sha1, (caddr_t)ixs->espp, ixs->len - ixs->iphlen - ixs->authlen);
40607 + SHA1Final(hash, &tctx.sha1);
40608 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
40609 + SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
40610 + SHA1Final(hash, &tctx.sha1);
40611 + memcpy(&(ixs->dat[ixs->len - ixs->authlen]), hash, ixs->authlen);
40612 +
40613 + /* paranoid */
40614 + memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
40615 + memset((caddr_t)hash, 0, sizeof(*hash));
40616 + break;
40617 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
40618 + case AH_NONE:
40619 + break;
40620 + default:
40621 + ixs->stats->tx_errors++;
40622 + return IPSEC_XMIT_AH_BADALG;
40623 + }
40624 + return IPSEC_XMIT_OK;
40625 +}
40626 +
40627 +#endif /* CONFIG_KLIPS_ESP */
40628 +
40629 +
40630 +
40631 +#ifdef CONFIG_KLIPS_AH
40632 +
40633 +enum ipsec_xmit_value
40634 +ipsec_xmit_ah(struct ipsec_xmit_state *ixs)
40635 +{
40636 + struct iphdr ipo;
40637 + struct ahhdr *ahp;
40638 +#if defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMAC_SHA1)
40639 + __u8 hash[AH_AMAX];
40640 +#endif
40641 +#if defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMAC_SHA1)
40642 + union {
40643 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
40644 + MD5_CTX md5;
40645 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
40646 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
40647 + SHA1_CTX sha1;
40648 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
40649 + } tctx;
40650 +#endif /* defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMAC_SHA1) */
40651 +
40652 + ahp = (struct ahhdr *)(ixs->dat + ixs->iphlen);
40653 +#ifdef NET_21
40654 + skb_set_transport_header(ixs->skb, ipsec_skb_offset(ixs->skb, ahp));
40655 +#endif /* NET_21 */
40656 + ahp->ah_spi = ixs->ipsp->ips_said.spi;
40657 + ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
40658 + ahp->ah_rv = 0;
40659 + ahp->ah_nh = ixs->iph->protocol;
40660 + ahp->ah_hl = (ixs->headroom >> 2) - sizeof(__u64)/sizeof(__u32);
40661 + ixs->iph->protocol = IPPROTO_AH;
40662 + dmp("ahp", (char*)ahp, sizeof(*ahp));
40663 +
40664 +#ifdef CONFIG_KLIPS_OCF
40665 + if (ixs->ipsp->ocf_in_use)
40666 + return(ipsec_ocf_xmit(ixs));
40667 +#endif
40668 +
40669 + ipo = *ixs->iph;
40670 + ipo.tos = 0;
40671 + ipo.frag_off = 0;
40672 + ipo.ttl = 0;
40673 + ipo.check = 0;
40674 + dmp("ipo", (char*)&ipo, sizeof(ipo));
40675 +
40676 + switch(ixs->ipsp->ips_authalg) {
40677 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
40678 + case AH_MD5:
40679 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
40680 + dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
40681 + osMD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
40682 + dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
40683 + osMD5Update(&tctx.md5, (unsigned char *)ahp, ixs->headroom - sizeof(ahp->ah_data));
40684 + dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
40685 + osMD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
40686 + dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
40687 + osMD5Update(&tctx.md5, ixs->dat + ixs->iphlen + ixs->headroom, ixs->len - ixs->iphlen - ixs->headroom);
40688 + dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
40689 + osMD5Final(hash, &tctx.md5);
40690 + dmp("ictx hash", (char*)&hash, sizeof(hash));
40691 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
40692 + dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
40693 + osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
40694 + dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
40695 + osMD5Final(hash, &tctx.md5);
40696 + dmp("octx hash", (char*)&hash, sizeof(hash));
40697 +
40698 + memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
40699 +
40700 + /* paranoid */
40701 + memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
40702 + memset((caddr_t)hash, 0, sizeof(*hash));
40703 + break;
40704 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
40705 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
40706 + case AH_SHA:
40707 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
40708 + SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
40709 + SHA1Update(&tctx.sha1, (unsigned char *)ahp, ixs->headroom - sizeof(ahp->ah_data));
40710 + SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
40711 + SHA1Update(&tctx.sha1, ixs->dat + ixs->iphlen + ixs->headroom, ixs->len - ixs->iphlen - ixs->headroom);
40712 + SHA1Final(hash, &tctx.sha1);
40713 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
40714 + SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
40715 + SHA1Final(hash, &tctx.sha1);
40716 +
40717 + memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
40718 +
40719 + /* paranoid */
40720 + memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
40721 + memset((caddr_t)hash, 0, sizeof(*hash));
40722 + break;
40723 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
40724 + default:
40725 + ixs->stats->tx_errors++;
40726 + return IPSEC_XMIT_AH_BADALG;
40727 + }
40728 + return IPSEC_XMIT_OK;
40729 +}
40730 +
40731 +#endif /* CONFIG_KLIPS_AH */
40732 +
40733 +
40734 +#ifdef CONFIG_KLIPS_IPIP
40735 +
40736 +enum ipsec_xmit_value
40737 +ipsec_xmit_ipip(struct ipsec_xmit_state *ixs)
40738 +{
40739 + ixs->iph->version = 4;
40740 + switch(sysctl_ipsec_tos) {
40741 + case 0:
40742 +#ifdef NET_21
40743 + ixs->iph->tos = ip_hdr(ixs->skb)->tos;
40744 +#else /* NET_21 */
40745 + ixs->iph->tos = ixs->skb->ip_hdr->tos;
40746 +#endif /* NET_21 */
40747 + break;
40748 + case 1:
40749 + ixs->iph->tos = 0;
40750 + break;
40751 + default:
40752 + break;
40753 + }
40754 + ixs->iph->ttl = SYSCTL_IPSEC_DEFAULT_TTL;
40755 + ixs->iph->frag_off = 0;
40756 + ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
40757 + ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
40758 + ixs->iph->protocol = IPPROTO_IPIP;
40759 + ixs->iph->ihl = sizeof(struct iphdr) >> 2;
40760 +
40761 + KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
40762 +
40763 + ixs->newdst = (__u32)ixs->iph->daddr;
40764 + ixs->newsrc = (__u32)ixs->iph->saddr;
40765 +
40766 +#ifdef NET_21
40767 + skb_set_transport_header(ixs->skb, ipsec_skb_offset(ixs->skb, ip_hdr(ixs->skb)));
40768 +#endif /* NET_21 */
40769 + return IPSEC_XMIT_OK;
40770 +}
40771 +
40772 +#endif /* CONFIG_KLIPS_IPIP */
40773 +
40774 +
40775 +#ifdef CONFIG_KLIPS_IPCOMP
40776 +
40777 +enum ipsec_xmit_value
40778 +ipsec_xmit_ipcomp(struct ipsec_xmit_state *ixs)
40779 +{
40780 +#ifdef CONFIG_KLIPS_DEBUG
40781 + unsigned int old_tot_len;
40782 +#endif
40783 + int flags = 0;
40784 +
40785 +#ifdef CONFIG_KLIPS_DEBUG
40786 + old_tot_len = ntohs(ixs->iph->tot_len);
40787 +#endif /* CONFIG_KLIPS_DEBUG */
40788 +
40789 + ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
40790 + ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
40791 +
40792 +#ifdef NET_21
40793 + ixs->iph = ip_hdr(ixs->skb);
40794 +#else /* NET_21 */
40795 + ixs->iph = ixs->skb->ip_hdr;
40796 +#endif /* NET_21 */
40797 +
40798 + ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
40799 +
40800 +#ifdef CONFIG_KLIPS_DEBUG
40801 + if (debug_tunnel & DB_TN_CROUT)
40802 + {
40803 + if (old_tot_len > ntohs(ixs->iph->tot_len))
40804 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
40805 + "klips_debug:ipsec_xmit_encap_once: "
40806 + "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
40807 + old_tot_len, ntohs(ixs->iph->tot_len),
40808 + ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
40809 + ntohl(ixs->ipsp->ips_said.spi),
40810 + (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
40811 + else
40812 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
40813 + "klips_debug:ipsec_xmit_encap_once: "
40814 + "packet did not compress (flags = %d).\n",
40815 + flags);
40816 + }
40817 +#endif /* CONFIG_KLIPS_DEBUG */
40818 + return IPSEC_XMIT_OK;
40819 +}
40820 +
40821 +#endif /* CONFIG_KLIPS_IPCOMP */
40822 +
40823 +
40824 +
40825 +/*
40826 + * upon entry to this function, ixs->skb should be setup
40827 + * as follows:
40828 + *
40829 + * data = beginning of IP packet <- differs from ipsec_rcv().
40830 + * nh.raw = beginning of IP packet.
40831 + * h.raw = data after the IP packet.
40832 + *
40833 + */
40834 +enum ipsec_xmit_value
40835 +ipsec_xmit_cont(struct ipsec_xmit_state *ixs)
40836 +{
40837 +#ifdef NET_21
40838 + skb_set_network_header(ixs->skb, ipsec_skb_offset(ixs->skb, ixs->skb->data));
40839 +#else /* NET_21 */
40840 + ixs->skb->ip_hdr = ixs->skb->h.iph = (struct iphdr *) ixs->skb->data;
40841 +#endif /* NET_21 */
40842 + ixs->iph->check = 0;
40843 + ixs->iph->check = ip_fast_csum((unsigned char *)ixs->iph, ixs->iph->ihl);
40844 +
40845 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
40846 + "klips_debug:ipsec_xmit_encap_once: "
40847 + "after <%s%s%s>, SA:%s:\n",
40848 + IPS_XFORM_NAME(ixs->ipsp),
40849 + ixs->sa_len ? ixs->sa_txt : " (error)");
40850 + KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
40851 +
40852 + ixs->ipsp->ips_life.ipl_bytes.ipl_count += ixs->len;
40853 + ixs->ipsp->ips_life.ipl_bytes.ipl_last = ixs->len;
40854 +
40855 + if(!ixs->ipsp->ips_life.ipl_usetime.ipl_count) {
40856 + ixs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
40857 + }
40858 + ixs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
40859 + ixs->ipsp->ips_life.ipl_packets.ipl_count++;
40860 +
40861 + ixs->ipsp = ixs->ipsp->ips_next;
40862 +
40863 + /*
40864 + * start again if we have more work to do
40865 + */
40866 + if (ixs->ipsp)
40867 + ixs->next_state = IPSEC_XSM_ENCAP_INIT;
40868 +
40869 + return IPSEC_XMIT_OK;
40870 +}
40871 +
40872 +
40873 +/*
40874 + * If the IP packet (iph) is a carrying TCP/UDP, then set the encaps
40875 + * source and destination ports to those from the TCP/UDP header.
40876 + */
40877 +void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er)
40878 +{
40879 + struct udphdr *udp;
40880 +
40881 + switch (iph->protocol) {
40882 + case IPPROTO_UDP:
40883 + case IPPROTO_TCP:
40884 + /*
40885 + * The ports are at the same offsets in a TCP and UDP
40886 + * header so hack it ...
40887 + */
40888 + udp = (struct udphdr*)(((char*)iph)+(iph->ihl<<2));
40889 + er->sen_sport = udp->source;
40890 + er->sen_dport = udp->dest;
40891 + break;
40892 + default:
40893 + er->sen_sport = 0;
40894 + er->sen_dport = 0;
40895 + break;
40896 + }
40897 +}
40898 +
40899 +/*
40900 + * A TRAP eroute is installed and we want to replace it with a HOLD
40901 + * eroute.
40902 + */
40903 +static int create_hold_eroute(struct eroute *origtrap,
40904 + struct sk_buff * skb, struct iphdr * iph,
40905 + uint32_t eroute_pid)
40906 +{
40907 + struct eroute hold_eroute;
40908 + ip_said hold_said;
40909 + struct sk_buff *first, *last;
40910 + int error;
40911 +
40912 + first = last = NULL;
40913 + memset((caddr_t)&hold_eroute, 0, sizeof(hold_eroute));
40914 + memset((caddr_t)&hold_said, 0, sizeof(hold_said));
40915 +
40916 + hold_said.proto = IPPROTO_INT;
40917 + hold_said.spi = htonl(SPI_HOLD);
40918 + hold_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
40919 +
40920 + hold_eroute.er_eaddr.sen_len = sizeof(struct sockaddr_encap);
40921 + hold_eroute.er_emask.sen_len = sizeof(struct sockaddr_encap);
40922 + hold_eroute.er_eaddr.sen_family = AF_ENCAP;
40923 + hold_eroute.er_emask.sen_family = AF_ENCAP;
40924 + hold_eroute.er_eaddr.sen_type = SENT_IP4;
40925 + hold_eroute.er_emask.sen_type = 255;
40926 +
40927 + hold_eroute.er_eaddr.sen_ip_src.s_addr = iph->saddr;
40928 + hold_eroute.er_eaddr.sen_ip_dst.s_addr = iph->daddr;
40929 + hold_eroute.er_emask.sen_ip_src.s_addr = INADDR_BROADCAST;
40930 + hold_eroute.er_emask.sen_ip_dst.s_addr = INADDR_BROADCAST;
40931 + hold_eroute.er_emask.sen_sport = 0;
40932 + hold_eroute.er_emask.sen_dport = 0;
40933 + hold_eroute.er_pid = eroute_pid;
40934 + hold_eroute.er_count = 0;
40935 + hold_eroute.er_lasttime = jiffies/HZ;
40936 +
40937 + /*
40938 + * if it wasn't captured by a wildcard, then don't record it as
40939 + * a wildcard.
40940 + */
40941 + if(origtrap->er_eaddr.sen_proto != 0) {
40942 + hold_eroute.er_eaddr.sen_proto = iph->protocol;
40943 +
40944 + if((iph->protocol == IPPROTO_TCP ||
40945 + iph->protocol == IPPROTO_UDP) &&
40946 + (origtrap->er_eaddr.sen_sport != 0 ||
40947 + origtrap->er_eaddr.sen_dport != 0)) {
40948 +
40949 + if(origtrap->er_eaddr.sen_sport != 0)
40950 + hold_eroute.er_emask.sen_sport = ~0;
40951 +
40952 + if(origtrap->er_eaddr.sen_dport != 0)
40953 + hold_eroute.er_emask.sen_dport = ~0;
40954 +
40955 + ipsec_extract_ports(iph, &hold_eroute.er_eaddr);
40956 + }
40957 + }
40958 +
40959 +#ifdef CONFIG_KLIPS_DEBUG
40960 + if (debug_pfkey) {
40961 + char buf1[64], buf2[64];
40962 + subnettoa(hold_eroute.er_eaddr.sen_ip_src,
40963 + hold_eroute.er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
40964 + subnettoa(hold_eroute.er_eaddr.sen_ip_dst,
40965 + hold_eroute.er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
40966 + KLIPS_PRINT(debug_pfkey,
40967 + "klips_debug:ipsec_tunnel_start_xmit: "
40968 + "calling breakeroute and makeroute for %s:%d->%s:%d %d HOLD eroute.\n",
40969 + buf1, ntohs(hold_eroute.er_eaddr.sen_sport),
40970 + buf2, ntohs(hold_eroute.er_eaddr.sen_dport),
40971 + hold_eroute.er_eaddr.sen_proto);
40972 + }
40973 +#endif /* CONFIG_KLIPS_DEBUG */
40974 +
40975 + if (ipsec_breakroute(&(hold_eroute.er_eaddr), &(hold_eroute.er_emask),
40976 + &first, &last)) {
40977 + KLIPS_PRINT(debug_pfkey,
40978 + "klips_debug:ipsec_tunnel_start_xmit: "
40979 + "HOLD breakeroute found nothing.\n");
40980 + } else {
40981 + KLIPS_PRINT(debug_pfkey,
40982 + "klips_debug:ipsec_tunnel_start_xmit: "
40983 + "HOLD breakroute deleted %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u %u\n",
40984 + NIPQUAD(hold_eroute.er_eaddr.sen_ip_src),
40985 + ntohs(hold_eroute.er_eaddr.sen_sport),
40986 + NIPQUAD(hold_eroute.er_eaddr.sen_ip_dst),
40987 + ntohs(hold_eroute.er_eaddr.sen_dport),
40988 + hold_eroute.er_eaddr.sen_proto);
40989 + }
40990 + if (first != NULL)
40991 + kfree_skb(first);
40992 + if (last != NULL)
40993 + kfree_skb(last);
40994 +
40995 + error = ipsec_makeroute(&(hold_eroute.er_eaddr),
40996 + &(hold_eroute.er_emask),
40997 + hold_said, eroute_pid, skb, NULL, NULL);
40998 + if (error) {
40999 + KLIPS_PRINT(debug_pfkey,
41000 + "klips_debug:ipsec_tunnel_start_xmit: "
41001 + "HOLD makeroute returned %d, failed.\n", error);
41002 + } else {
41003 + KLIPS_PRINT(debug_pfkey,
41004 + "klips_debug:ipsec_tunnel_start_xmit: "
41005 + "HOLD makeroute call successful.\n");
41006 + }
41007 + return (error == 0);
41008 +}
41009 +
41010 +/*
41011 + * upon entry to this function, ixs->skb should be setup
41012 + * as follows:
41013 + *
41014 + * data = beginning of IP packet <- differs from ipsec_rcv().
41015 + * nh.raw = beginning of IP packet.
41016 + * h.raw = data after the IP packet.
41017 + *
41018 + */
41019 +enum ipsec_xmit_value
41020 +ipsec_xmit_init1(struct ipsec_xmit_state *ixs)
41021 +{
41022 + ixs->newdst = ixs->orgdst = ixs->iph->daddr;
41023 + ixs->newsrc = ixs->orgsrc = ixs->iph->saddr;
41024 + ixs->orgedst = ixs->outgoing_said.dst.u.v4.sin_addr.s_addr;
41025 + ixs->iphlen = ixs->iph->ihl << 2;
41026 + ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
41027 + ixs->max_headroom = ixs->max_tailroom = 0;
41028 +
41029 + if (ixs->outgoing_said.proto == IPPROTO_INT) {
41030 + switch (ntohl(ixs->outgoing_said.spi)) {
41031 + case SPI_DROP:
41032 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41033 + "klips_debug:ipsec_xmit_encap_bundle: "
41034 + "shunt SA of DROP or no eroute: dropping.\n");
41035 + ixs->stats->tx_dropped++;
41036 + break;
41037 +
41038 + case SPI_REJECT:
41039 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41040 + "klips_debug:ipsec_xmit_encap_bundle: "
41041 + "shunt SA of REJECT: notifying and dropping.\n");
41042 + ICMP_SEND(ixs->skb,
41043 + ICMP_DEST_UNREACH,
41044 + ICMP_PKT_FILTERED,
41045 + 0,
41046 + ixs->physdev);
41047 + ixs->stats->tx_dropped++;
41048 + break;
41049 +
41050 + case SPI_PASS:
41051 +#ifdef NET_21
41052 + ixs->pass = 1;
41053 +#endif /* NET_21 */
41054 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41055 + "klips_debug:ipsec_xmit_encap_bundle: "
41056 + "PASS: calling dev_queue_xmit\n");
41057 + return IPSEC_XMIT_PASS;
41058 +
41059 + case SPI_HOLD:
41060 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41061 + "klips_debug:ipsec_xmit_encap_bundle: "
41062 + "shunt SA of HOLD: this does not make sense here, dropping.\n");
41063 + ixs->stats->tx_dropped++;
41064 + break;
41065 +
41066 + case SPI_TRAP:
41067 + case SPI_TRAPSUBNET:
41068 + {
41069 + struct sockaddr_in src, dst;
41070 +#ifdef CONFIG_KLIPS_DEBUG
41071 + char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF];
41072 +#endif /* CONFIG_KLIPS_DEBUG */
41073 +
41074 + /* Signal all listening KMds with a PF_KEY ACQUIRE */
41075 +
41076 + memset(&src, 0, sizeof(src));
41077 + memset(&dst, 0, sizeof(dst));
41078 + src.sin_family = AF_INET;
41079 + dst.sin_family = AF_INET;
41080 + src.sin_addr.s_addr = ixs->iph->saddr;
41081 + dst.sin_addr.s_addr = ixs->iph->daddr;
41082 +
41083 + ixs->ips.ips_transport_protocol = 0;
41084 + src.sin_port = 0;
41085 + dst.sin_port = 0;
41086 +
41087 + if(ixs->eroute->er_eaddr.sen_proto != 0) {
41088 + ixs->ips.ips_transport_protocol = ixs->iph->protocol;
41089 +
41090 + if(ixs->eroute->er_eaddr.sen_sport != 0) {
41091 + src.sin_port =
41092 + (ixs->iph->protocol == IPPROTO_UDP
41093 + ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->source
41094 + : (ixs->iph->protocol == IPPROTO_TCP
41095 + ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->source
41096 + : 0));
41097 + }
41098 + if(ixs->eroute->er_eaddr.sen_dport != 0) {
41099 + dst.sin_port =
41100 + (ixs->iph->protocol == IPPROTO_UDP
41101 + ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->dest
41102 + : (ixs->iph->protocol == IPPROTO_TCP
41103 + ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->dest
41104 + : 0));
41105 + }
41106 + }
41107 +
41108 + ixs->ips.ips_addr_s = (struct sockaddr*)(&src);
41109 + ixs->ips.ips_addr_d = (struct sockaddr*)(&dst);
41110 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41111 + "klips_debug:ipsec_xmit_encap_bundle: "
41112 + "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n",
41113 + addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_addr, 0, bufsrc, sizeof(bufsrc)) <= ADDRTOA_BUF ? bufsrc : "BAD_ADDR",
41114 + ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_port),
41115 + addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_addr, 0, bufdst, sizeof(bufdst)) <= ADDRTOA_BUF ? bufdst : "BAD_ADDR",
41116 + ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_port),
41117 + ixs->ips.ips_said.proto);
41118 +
41119 + /* increment count of total traps needed */
41120 + ipsec_xmit_trap_count++;
41121 +
41122 + if (pfkey_acquire(&ixs->ips) == 0) {
41123 +
41124 + /* note that we succeeded */
41125 + ipsec_xmit_trap_sendcount++;
41126 +
41127 + if (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)) {
41128 + /*
41129 + * The spinlock is to prevent any other
41130 + * process from accessing or deleting
41131 + * the eroute while we are using and
41132 + * updating it.
41133 + */
41134 + spin_lock_bh(&eroute_lock);
41135 + ixs->eroute = ipsec_findroute(&ixs->matcher);
41136 + if(ixs->eroute) {
41137 + ixs->eroute->er_said.spi = htonl(SPI_HOLD);
41138 + ixs->eroute->er_first = ixs->skb;
41139 + ixs->skb = NULL;
41140 + }
41141 + spin_unlock_bh(&eroute_lock);
41142 + } else if (create_hold_eroute(ixs->eroute,
41143 + ixs->skb,
41144 + ixs->iph,
41145 + ixs->eroute_pid)) {
41146 + ixs->skb = NULL;
41147 + }
41148 + /* whether or not the above succeeded, we continue */
41149 +
41150 + }
41151 + ixs->stats->tx_dropped++;
41152 + }
41153 + default:
41154 + /* XXX what do we do with an unknown shunt spi? */
41155 + break;
41156 + } /* switch (ntohl(ixs->outgoing_said.spi)) */
41157 + return IPSEC_XMIT_STOLEN;
41158 + } /* if (ixs->outgoing_said.proto == IPPROTO_INT) */
41159 +
41160 + ixs->ipsp = ipsec_sa_getbyid(&ixs->outgoing_said);
41161 + ixs->sa_len = KLIPS_SATOT(debug_tunnel, &ixs->outgoing_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
41162 +
41163 + if (ixs->ipsp == NULL) {
41164 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41165 + "klips_debug:ipsec_xmit_encap_bundle: "
41166 + "no ipsec_sa for SA%s: outgoing packet with no SA, dropped.\n",
41167 + ixs->sa_len ? ixs->sa_txt : " (error)");
41168 + if(ixs->stats) {
41169 + ixs->stats->tx_dropped++;
41170 + }
41171 + return IPSEC_XMIT_SAIDNOTFOUND;
41172 + }
41173 +
41174 + return IPSEC_XMIT_OK;
41175 +}
41176 +
41177 +enum ipsec_xmit_value
41178 +ipsec_xmit_init2(struct ipsec_xmit_state *ixs)
41179 +{
41180 + enum ipsec_xmit_value bundle_stat = IPSEC_XMIT_OK;
41181 + struct ipsec_sa *saved_ipsp;
41182 +#ifdef CONFIG_KLIPS_ALG
41183 + ixs->blocksize = 8;
41184 + ixs->ixt_e = NULL;
41185 + ixs->ixt_a = NULL;
41186 +#endif /* CONFIG_KLIPS_ALG */
41187 +
41188 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41189 + "klips_debug:ipsec_xmit_encap_bundle_2: "
41190 + "found ipsec_sa -- SA:<%s%s%s> %s\n",
41191 + IPS_XFORM_NAME(ixs->ipsp),
41192 + ixs->sa_len ? ixs->sa_txt : " (error)");
41193 +
41194 + /*
41195 + * How much headroom do we need to be able to apply
41196 + * all the grouped transforms?
41197 + */
41198 + saved_ipsp = ixs->ipsp; /* save the head of the ipsec_sa chain */
41199 + while (ixs->ipsp) {
41200 + if (debug_tunnel & DB_TN_XMIT) {
41201 + ixs->sa_len = KLIPS_SATOT(debug_tunnel, &ixs->ipsp->ips_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
41202 + if(ixs->sa_len == 0) {
41203 + strcpy(ixs->sa_txt, "(error)");
41204 + }
41205 + } else {
41206 + *ixs->sa_txt = 0;
41207 + ixs->sa_len = 0;
41208 + }
41209 +
41210 + /* If it is in larval state, drop the packet, we cannot process yet. */
41211 + if(ixs->ipsp->ips_state == K_SADB_SASTATE_LARVAL) {
41212 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41213 + "klips_debug:ipsec_xmit_encap_bundle_2: "
41214 + "ipsec_sa in larval state for SA:<%s%s%s> %s, cannot be used yet, dropping packet.\n",
41215 + IPS_XFORM_NAME(ixs->ipsp),
41216 + ixs->sa_len ? ixs->sa_txt : " (error)");
41217 + if(ixs->stats) {
41218 + ixs->stats->tx_errors++;
41219 + }
41220 + bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
41221 + goto cleanup;
41222 + }
41223 +
41224 + if(ixs->ipsp->ips_state == K_SADB_SASTATE_DEAD) {
41225 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41226 + "klips_debug:ipsec_xmit_encap_bundle_2: "
41227 + "ipsec_sa in dead state for SA:<%s%s%s> %s, can no longer be used, dropping packet.\n",
41228 + IPS_XFORM_NAME(ixs->ipsp),
41229 + ixs->sa_len ? ixs->sa_txt : " (error)");
41230 + ixs->stats->tx_errors++;
41231 + bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
41232 + goto cleanup;
41233 + }
41234 +
41235 + /* If the replay window counter == -1, expire SA, it will roll */
41236 + if(ixs->ipsp->ips_replaywin && ixs->ipsp->ips_replaywin_lastseq == -1) {
41237 + pfkey_expire(ixs->ipsp, 1);
41238 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41239 + "klips_debug:ipsec_xmit_encap_bundle_2: "
41240 + "replay window counter rolled for SA:<%s%s%s> %s, packet dropped, expiring SA.\n",
41241 + IPS_XFORM_NAME(ixs->ipsp),
41242 + ixs->sa_len ? ixs->sa_txt : " (error)");
41243 + ipsec_sa_rm(ixs->ipsp);
41244 + ixs->stats->tx_errors++;
41245 + bundle_stat = IPSEC_XMIT_REPLAYROLLED;
41246 + goto cleanup;
41247 + }
41248 +
41249 + /*
41250 + * if this is the first time we are using this SA, mark start time,
41251 + * and offset hard/soft counters by "now" for later checking.
41252 + */
41253 +#if 0
41254 + if(ixs->ipsp->ips_life.ipl_usetime.count == 0) {
41255 + ixs->ipsp->ips_life.ipl_usetime.count = jiffies;
41256 + ixs->ipsp->ips_life.ipl_usetime.hard += jiffies;
41257 + ixs->ipsp->ips_life.ipl_usetime.soft += jiffies;
41258 + }
41259 +#endif
41260 +
41261 +
41262 + if(ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_bytes, "bytes", ixs->sa_txt,
41263 + ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
41264 + ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_addtime, "addtime",ixs->sa_txt,
41265 + ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
41266 + ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_usetime, "usetime",ixs->sa_txt,
41267 + ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
41268 + ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_packets, "packets",ixs->sa_txt,
41269 + ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied) {
41270 +
41271 + ipsec_sa_rm(ixs->ipsp);
41272 + ixs->stats->tx_errors++;
41273 + bundle_stat = IPSEC_XMIT_LIFETIMEFAILED;
41274 + goto cleanup;
41275 + }
41276 +
41277 +
41278 + ixs->headroom = ixs->tailroom = 0;
41279 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
41280 + "klips_debug:ipsec_xmit_encap_bundle_2: "
41281 + "calling room for <%s%s%s>, SA:%s\n",
41282 + IPS_XFORM_NAME(ixs->ipsp),
41283 + ixs->sa_len ? ixs->sa_txt : " (error)");
41284 + switch(ixs->ipsp->ips_said.proto) {
41285 +#ifdef CONFIG_KLIPS_AH
41286 + case IPPROTO_AH:
41287 + ixs->headroom += sizeof(struct ahhdr);
41288 + break;
41289 +#endif /* CONFIG_KLIPS_AH */
41290 +
41291 +#ifdef CONFIG_KLIPS_ESP
41292 + case IPPROTO_ESP:
41293 +#ifdef CONFIG_KLIPS_OCF
41294 + /*
41295 + * this needs cleaning up for sure - DM
41296 + */
41297 + if (ixs->ipsp->ocf_in_use) {
41298 + switch (ixs->ipsp->ips_encalg) {
41299 + case ESP_DES:
41300 + case ESP_3DES:
41301 + ixs->blocksize = 8;
41302 + ixs->headroom += ESP_HEADER_LEN + 8 /* ivsize */;
41303 + break;
41304 + case ESP_AES:
41305 + ixs->blocksize = 16;
41306 + ixs->headroom += ESP_HEADER_LEN + 16 /* ivsize */;
41307 + break;
41308 + default:
41309 + ixs->stats->tx_errors++;
41310 + bundle_stat = IPSEC_XMIT_ESP_BADALG;
41311 + goto cleanup;
41312 + }
41313 + } else
41314 +#endif /* CONFIG_KLIPS_OCF */
41315 +#ifdef CONFIG_KLIPS_ALG
41316 + ixs->ixt_e=ixs->ipsp->ips_alg_enc;
41317 + if (ixs->ixt_e) {
41318 + ixs->blocksize = ixs->ixt_e->ixt_common.ixt_blocksize;
41319 + ixs->headroom += ESP_HEADER_LEN + ixs->ixt_e->ixt_common.ixt_support.ias_ivlen/8;
41320 + } else
41321 +#endif /* CONFIG_KLIPS_ALG */
41322 + {
41323 + ixs->stats->tx_errors++;
41324 + bundle_stat = IPSEC_XMIT_ESP_BADALG;
41325 + goto cleanup;
41326 + }
41327 +#ifdef CONFIG_KLIPS_OCF
41328 + if (ixs->ipsp->ocf_in_use) {
41329 + switch (ixs->ipsp->ips_authalg) {
41330 + case AH_MD5:
41331 + case AH_SHA:
41332 + ixs->tailroom += AHHMAC_HASHLEN;
41333 + break;
41334 + case AH_NONE:
41335 + break;
41336 + }
41337 + } else
41338 +#endif /* CONFIG_KLIPS_OCF */
41339 +#ifdef CONFIG_KLIPS_ALG
41340 + if ((ixs->ixt_a=ixs->ipsp->ips_alg_auth)) {
41341 + ixs->tailroom += AHHMAC_HASHLEN;
41342 + } else
41343 +#endif /* CONFIG_KLIPS_ALG */
41344 + switch(ixs->ipsp->ips_authalg) {
41345 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
41346 + case AH_MD5:
41347 + ixs->tailroom += AHHMAC_HASHLEN;
41348 + break;
41349 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
41350 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
41351 + case AH_SHA:
41352 + ixs->tailroom += AHHMAC_HASHLEN;
41353 + break;
41354 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
41355 + case AH_NONE:
41356 + break;
41357 + default:
41358 + ixs->stats->tx_errors++;
41359 + bundle_stat = IPSEC_XMIT_AH_BADALG;
41360 + goto cleanup;
41361 + }
41362 + ixs->tailroom += ixs->blocksize != 1 ?
41363 + ((ixs->blocksize - ((ixs->pyldsz + 2) % ixs->blocksize)) % ixs->blocksize) + 2 :
41364 + ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
41365 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
41366 + if ((ixs->ipsp->ips_natt_type) && (!ixs->natt_type)) {
41367 + ixs->natt_type = ixs->ipsp->ips_natt_type;
41368 + ixs->natt_sport = ixs->ipsp->ips_natt_sport;
41369 + ixs->natt_dport = ixs->ipsp->ips_natt_dport;
41370 + switch (ixs->natt_type) {
41371 + case ESPINUDP_WITH_NON_IKE:
41372 + ixs->natt_head = sizeof(struct udphdr)+(2*sizeof(__u32));
41373 + break;
41374 +
41375 + case ESPINUDP_WITH_NON_ESP:
41376 + ixs->natt_head = sizeof(struct udphdr);
41377 + break;
41378 +
41379 + default:
41380 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT
41381 + , "klips_xmit: invalid nat-t type %d"
41382 + , ixs->natt_type);
41383 + bundle_stat = IPSEC_XMIT_ESPUDP_BADTYPE;
41384 + goto cleanup;
41385 +
41386 + break;
41387 + }
41388 + ixs->tailroom += ixs->natt_head;
41389 + }
41390 +#endif
41391 + break;
41392 +#endif /* CONFIG_KLIPS_ESP */
41393 +#ifdef CONFIG_KLIPS_IPIP
41394 + case IPPROTO_IPIP:
41395 + ixs->headroom += sizeof(struct iphdr);
41396 + break;
41397 +#endif /* !CONFIG_KLIPS_IPIP */
41398 + case IPPROTO_COMP:
41399 +#ifdef CONFIG_KLIPS_IPCOMP
41400 + /*
41401 + We can't predict how much the packet will
41402 + shrink without doing the actual compression.
41403 + We could do it here, if we were the first
41404 + encapsulation in the chain. That might save
41405 + us a skb_copy_expand, since we might fit
41406 + into the existing skb then. However, this
41407 + would be a bit unclean (and this hack has
41408 + bit us once), so we better not do it. After
41409 + all, the skb_copy_expand is cheap in
41410 + comparison to the actual compression.
41411 + At least we know the packet will not grow.
41412 + */
41413 + break;
41414 +#endif /* CONFIG_KLIPS_IPCOMP */
41415 + default:
41416 + ixs->stats->tx_errors++;
41417 + bundle_stat = IPSEC_XMIT_BADPROTO;
41418 + goto cleanup;
41419 + }
41420 + ixs->ipsp = ixs->ipsp->ips_next;
41421 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
41422 + "klips_debug:ipsec_xmit_encap_bundle_2: "
41423 + "Required head,tailroom: %d,%d\n",
41424 + ixs->headroom, ixs->tailroom);
41425 + ixs->max_headroom += ixs->headroom;
41426 + ixs->max_tailroom += ixs->tailroom;
41427 + ixs->pyldsz += (ixs->headroom + ixs->tailroom);
41428 + }
41429 + ixs->ipsp = saved_ipsp; /* restore the head of the ipsec_sa chain */
41430 +
41431 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
41432 + "klips_debug:ipsec_xmit_encap_bundle_2: "
41433 + "existing head,tailroom: %d,%d before applying xforms with head,tailroom: %d,%d .\n",
41434 + skb_headroom(ixs->skb), skb_tailroom(ixs->skb),
41435 + ixs->max_headroom, ixs->max_tailroom);
41436 +
41437 + ixs->tot_headroom += ixs->max_headroom;
41438 + ixs->tot_tailroom += ixs->max_tailroom;
41439 +
41440 + ixs->mtudiff = ixs->cur_mtu + ixs->tot_headroom + ixs->tot_tailroom - ixs->physmtu;
41441 +
41442 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
41443 + "klips_debug:ipsec_xmit_encap_bundle_2: "
41444 + "mtu:%d physmtu:%d tothr:%d tottr:%d mtudiff:%d ippkttotlen:%d\n",
41445 + ixs->cur_mtu, ixs->physmtu,
41446 + ixs->tot_headroom, ixs->tot_tailroom, ixs->mtudiff, ntohs(ixs->iph->tot_len));
41447 + if(ixs->cur_mtu == 0 || ixs->mtudiff > 0) {
41448 + int newmtu = ixs->physmtu - (ixs->tot_headroom + ((ixs->tot_tailroom + 2) & ~7) + 5);
41449 +
41450 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
41451 + "klips_info:ipsec_xmit_encap_bundle_2: "
41452 + "dev %s mtu of %d decreased by %d to %d\n",
41453 + ixs->dev ? ixs->dev->name : "ifX",
41454 + ixs->cur_mtu,
41455 + ixs->cur_mtu - newmtu,
41456 + newmtu);
41457 + ixs->cur_mtu = newmtu;
41458 +
41459 + /* this would seem to adjust the MTU of the route as well */
41460 +#if 0
41461 + ixs->skb->dst->pmtu = ixs->prv->mtu; /* RGB */
41462 +#endif /* 0 */
41463 + }
41464 +
41465 + /*
41466 + If the sender is doing PMTU discovery, and the
41467 + packet doesn't fit within ixs->prv->mtu, notify him
41468 + (unless it was an ICMP packet, or it was not the
41469 + zero-offset packet) and send it anyways.
41470 +
41471 + Note: buggy firewall configuration may prevent the
41472 + ICMP packet from getting back.
41473 + */
41474 + if(sysctl_ipsec_icmp
41475 + && ixs->cur_mtu < ntohs(ixs->iph->tot_len)
41476 + && (ixs->iph->frag_off & __constant_htons(IP_DF)) ) {
41477 + int notify = ixs->iph->protocol != IPPROTO_ICMP
41478 + && (ixs->iph->frag_off & __constant_htons(IP_OFFSET)) == 0;
41479 +
41480 +#ifdef IPSEC_obey_DF
41481 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
41482 + "klips_debug:ipsec_xmit_encap_bundle_2: "
41483 + "fragmentation needed and DF set; %sdropping packet\n",
41484 + notify ? "sending ICMP and " : "");
41485 + if (notify)
41486 + ICMP_SEND(ixs->skb,
41487 + ICMP_DEST_UNREACH,
41488 + ICMP_FRAG_NEEDED,
41489 + ixs->cur_mtu,
41490 + ixs->physdev);
41491 + ixs->stats->tx_errors++;
41492 + bundle_stat = IPSEC_XMIT_CANNOTFRAG;
41493 + goto cleanup;
41494 +#else /* IPSEC_obey_DF */
41495 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
41496 + "klips_debug:ipsec_xmit_encap_bundle_2: "
41497 + "fragmentation needed and DF set; %spassing packet\n",
41498 + notify ? "sending ICMP and " : "");
41499 + if (notify)
41500 + ICMP_SEND(ixs->skb,
41501 + ICMP_DEST_UNREACH,
41502 + ICMP_FRAG_NEEDED,
41503 + ixs->cur_mtu,
41504 + ixs->physdev);
41505 +#endif /* IPSEC_obey_DF */
41506 + }
41507 +
41508 +#ifdef MSS_HACK
41509 + /*
41510 + * If this is a transport mode TCP packet with
41511 + * SYN set, determine an effective MSS based on
41512 + * AH/ESP overheads determined above.
41513 + */
41514 + if (ixs->iph->protocol == IPPROTO_TCP
41515 + && ixs->outgoing_said.proto != IPPROTO_IPIP) {
41516 + struct tcphdr *tcph = ixs->skb->h.th;
41517 + if (tcph->syn && !tcph->ack) {
41518 + if(!ipsec_adjust_mss(ixs->skb, tcph, ixs->cur_mtu)) {
41519 + printk(KERN_WARNING
41520 + "klips_warning:ipsec_xmit_encap_bundle_2: "
41521 + "ipsec_adjust_mss() failed\n");
41522 + ixs->stats->tx_errors++;
41523 + bundle_stat = IPSEC_XMIT_MSSERR;
41524 + goto cleanup;
41525 + }
41526 + }
41527 + }
41528 +#endif /* MSS_HACK */
41529 +
41530 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
41531 + if ((ixs->natt_type) && (ixs->outgoing_said.proto != IPPROTO_IPIP)) {
41532 + /**
41533 + * NAT-Traversal and Transport Mode:
41534 + * we need to force destination address to sane value
41535 + */
41536 +
41537 + struct sockaddr_in *sv4=(struct sockaddr_in *)ixs->ipsp->ips_addr_d;
41538 + __u32 natt_d = sv4->sin_addr.s_addr;
41539 + struct iphdr *ipp = ixs->iph;
41540 +
41541 + /* set the destination address to what it needs to be for the
41542 + * NAT encapsulation.
41543 + */
41544 + KLIPS_PRINT(debug_tunnel,
41545 + "xmit: setting ND=%08x\n", natt_d);
41546 + ipp->daddr = natt_d;
41547 + ipp->check = 0;
41548 + ipp->check = ip_fast_csum((unsigned char *)ipp, ipp->ihl);
41549 + }
41550 +#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
41551 +
41552 + if(!ixs->hard_header_stripped && ixs->hard_header_len>0) {
41553 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41554 + "klips_debug:ipsec_xmit_encap_bundle_2: "
41555 + "allocating %d bytes for hardheader.\n",
41556 + ixs->hard_header_len);
41557 + if((ixs->saved_header = kmalloc(ixs->hard_header_len, GFP_ATOMIC)) == NULL) {
41558 + printk(KERN_WARNING "klips_debug:ipsec_xmit_encap_bundle_2: "
41559 + "Failed, tried to allocate %d bytes for temp hard_header.\n",
41560 + ixs->hard_header_len);
41561 + ixs->stats->tx_errors++;
41562 + bundle_stat = IPSEC_XMIT_ERRMEMALLOC;
41563 + goto cleanup;
41564 + }
41565 + {
41566 + int i;
41567 + for (i = 0; i < ixs->hard_header_len; i++) {
41568 + ixs->saved_header[i] = ixs->skb->data[i];
41569 + }
41570 + }
41571 + if(ixs->skb->len < ixs->hard_header_len) {
41572 + printk(KERN_WARNING "klips_error:ipsec_xmit_encap_bundle_2: "
41573 + "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
41574 + ixs->hard_header_len, (int)(ixs->skb->len));
41575 + ixs->stats->tx_errors++;
41576 + bundle_stat = IPSEC_XMIT_ESP_PUSHPULLERR;
41577 + goto cleanup;
41578 + }
41579 + skb_pull(ixs->skb, ixs->hard_header_len);
41580 + ixs->hard_header_stripped = 1;
41581 +
41582 +/* ixs->iph = (struct iphdr *) (ixs->skb->data); */
41583 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
41584 + "klips_debug:ipsec_xmit_encap_bundle_2: "
41585 + "head,tailroom: %d,%d after hard_header stripped.\n",
41586 + skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
41587 + KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, ixs->iph);
41588 + } else {
41589 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
41590 + "klips_debug:ipsec_xmit_encap_bundle_2: "
41591 + "hard header already stripped.\n");
41592 + }
41593 +
41594 + ixs->ll_headroom = (ixs->hard_header_len + 15) & ~15;
41595 +
41596 + if ((skb_headroom(ixs->skb) >= ixs->max_headroom + 2 * ixs->ll_headroom) &&
41597 + (skb_tailroom(ixs->skb) >= ixs->max_tailroom)
41598 +#ifndef NET_21
41599 + && ixs->skb->free
41600 +#endif /* !NET_21 */
41601 + ) {
41602 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
41603 + "klips_debug:ipsec_xmit_encap_bundle_2: "
41604 + "data fits in existing skb\n");
41605 + } else {
41606 + struct sk_buff* tskb;
41607 +
41608 + if(!ixs->oskb) {
41609 + ixs->oskb = ixs->skb;
41610 + }
41611 +
41612 + tskb = skb_copy_expand(ixs->skb,
41613 + /* The need for 2 * link layer length here remains unexplained...RGB */
41614 + ixs->max_headroom + 2 * ixs->ll_headroom,
41615 + ixs->max_tailroom,
41616 + GFP_ATOMIC);
41617 +
41618 + if(tskb && ixs->skb->sk) {
41619 + skb_set_owner_w(tskb, ixs->skb->sk);
41620 + }
41621 +
41622 + if(ixs->skb != ixs->oskb) {
41623 + ipsec_kfree_skb(ixs->skb);
41624 + }
41625 + ixs->skb = tskb;
41626 + if (!ixs->skb) {
41627 + printk(KERN_WARNING
41628 + "klips_debug:ipsec_xmit_encap_bundle_2: "
41629 + "Failed, tried to allocate %d head and %d tailroom\n",
41630 + ixs->max_headroom, ixs->max_tailroom);
41631 + ixs->stats->tx_errors++;
41632 + bundle_stat = IPSEC_XMIT_ERRSKBALLOC;
41633 + goto cleanup;
41634 + }
41635 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
41636 + "klips_debug:ipsec_xmit_encap_bundle_2: "
41637 + "head,tailroom: %d,%d after allocation\n",
41638 + skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
41639 + }
41640 +
41641 +#ifdef CONFIG_KLIPS_DEBUG
41642 + if(debug_tunnel & DB_TN_ENCAP) {
41643 + ipsec_print_ip(ixs->iph);
41644 + }
41645 +#endif
41646 +
41647 +cleanup:
41648 + return bundle_stat;
41649 +}
41650 +
41651 +void
41652 +ipsec_xmit_cleanup(struct ipsec_xmit_state*ixs)
41653 +{
41654 + if(ixs->dev) {
41655 +#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
41656 + netif_wake_queue(ixs->dev);
41657 +#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
41658 + ixs->dev->tbusy = 0;
41659 +#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
41660 + }
41661 +
41662 + if(ixs->saved_header) {
41663 + kfree(ixs->saved_header);
41664 + ixs->saved_header = NULL;
41665 + }
41666 + if(ixs->skb) {
41667 + dev_kfree_skb(ixs->skb);
41668 + ixs->skb=NULL;
41669 + }
41670 + if(ixs->oskb) {
41671 + dev_kfree_skb(ixs->oskb);
41672 + ixs->oskb=NULL;
41673 + }
41674 + if (ixs->ips.ips_ident_s.data) {
41675 + kfree(ixs->ips.ips_ident_s.data);
41676 + ixs->ips.ips_ident_s.data=NULL;
41677 + }
41678 + if (ixs->ips.ips_ident_d.data) {
41679 + kfree(ixs->ips.ips_ident_d.data);
41680 + ixs->ips.ips_ident_d.data=NULL;
41681 + }
41682 +}
41683 +
41684 +#ifdef NETDEV_23
41685 +static inline int ipsec_xmit_send2(struct sk_buff *skb)
41686 +{
41687 +#ifdef NETDEV_25 /* 2.6 kernels */
41688 + return dst_output(skb);
41689 +#else
41690 + return ip_send(skb);
41691 +#endif
41692 +}
41693 +#endif /* NETDEV_23 */
41694 +
41695 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
41696 +enum ipsec_xmit_value ipsec_nat_encap(struct ipsec_xmit_state *ixs)
41697 +{
41698 + if (ixs->natt_type && ixs->natt_head) {
41699 + struct iphdr *ipp = ip_hdr(ixs->skb);
41700 + struct udphdr *udp;
41701 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41702 + "klips_debug:ipsec_tunnel_start_xmit: "
41703 + "encapsuling packet into UDP (NAT-Traversal) (%d %d)\n",
41704 + ixs->natt_type, ixs->natt_head);
41705 +
41706 + ixs->iphlen = ipp->ihl << 2;
41707 + ipp->tot_len =
41708 + htons(ntohs(ipp->tot_len) + ixs->natt_head);
41709 + if(skb_tailroom(ixs->skb) < ixs->natt_head) {
41710 + printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
41711 + "tried to skb_put %d, %d available. "
41712 + "This should never happen, please report.\n",
41713 + ixs->natt_head,
41714 + skb_tailroom(ixs->skb));
41715 + ixs->stats->tx_errors++;
41716 + return IPSEC_XMIT_ESPUDP;
41717 + }
41718 + skb_put(ixs->skb, ixs->natt_head);
41719 +
41720 + udp = (struct udphdr *)((char *)ipp + ixs->iphlen);
41721 +
41722 + /* move ESP hdr after UDP hdr */
41723 + memmove((void *)((char *)udp + ixs->natt_head),
41724 + (void *)(udp),
41725 + ntohs(ipp->tot_len) - ixs->iphlen - ixs->natt_head);
41726 +
41727 +#if 0
41728 + /* set IP destination address (matters in transport mode) */
41729 + {
41730 + struct sockaddr_in *d = (struct sockaddr_in *)ixs->ipsp->ips_addr_d;
41731 + ipp->daddr = d->sin_addr.s_addr;
41732 + }
41733 +#endif
41734 +
41735 + /* clear UDP & Non-IKE Markers (if any) */
41736 + memset(udp, 0, ixs->natt_head);
41737 +
41738 + /* fill UDP with usefull informations ;-) */
41739 + udp->source = htons(ixs->natt_sport);
41740 + udp->dest = htons(ixs->natt_dport);
41741 + udp->len = htons(ntohs(ipp->tot_len) - ixs->iphlen);
41742 +
41743 + /* set protocol */
41744 + ipp->protocol = IPPROTO_UDP;
41745 +
41746 + /* fix IP checksum */
41747 + ipp->check = 0;
41748 + ipp->check = ip_fast_csum((unsigned char *)ipp, ipp->ihl);
41749 + }
41750 + return IPSEC_XMIT_OK;
41751 +}
41752 +#endif
41753 +
41754 +
41755 +/* avoid forward reference complain on <2.5 */
41756 +struct flowi;
41757 +
41758 +enum ipsec_xmit_value
41759 +ipsec_xmit_send(struct ipsec_xmit_state*ixs, struct flowi *fl)
41760 +{
41761 + int error;
41762 +
41763 +#ifdef NETDEV_25
41764 + fl->nl_u.ip4_u.daddr = ip_hdr(ixs->skb)->daddr;
41765 + fl->nl_u.ip4_u.saddr = ixs->pass ? 0 : ip_hdr(ixs->skb)->saddr;
41766 + fl->nl_u.ip4_u.tos = RT_TOS(ip_hdr(ixs->skb)->tos);
41767 + fl->proto = ip_hdr(ixs->skb)->protocol;
41768 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24)
41769 + error = ip_route_output_key(&ixs->route, &fl);
41770 +#else
41771 + error = ip_route_output_key(&init_net, &ixs->route, fl);
41772 +#endif
41773 + if (error) {
41774 +
41775 +#else
41776 + /*skb_orphan(ixs->skb);*/
41777 + if((error = ip_route_output(&ixs->route,
41778 + ip_hdr(ixs->skb)->daddr,
41779 + ixs->pass ? 0 : ip_hdr(ixs->skb)->saddr,
41780 + RT_TOS(ip_hdr(ixs->skb)->tos),
41781 + /* mcr->rgb: should this be 0 instead? */
41782 + ixs->physdev->iflink))) {
41783 +#endif
41784 + ixs->stats->tx_errors++;
41785 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41786 + "klips_debug:ipsec_xmit_send: "
41787 + "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
41788 + error,
41789 + ixs->route->u.dst.dev->name);
41790 + return IPSEC_XMIT_ROUTEERR;
41791 + }
41792 +
41793 + if(ixs->dev == ixs->route->u.dst.dev) {
41794 + ip_rt_put(ixs->route);
41795 + /* This is recursion, drop it. */
41796 + ixs->stats->tx_errors++;
41797 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41798 + "klips_debug:ipsec_xmit_send: "
41799 + "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
41800 + ixs->dev->name);
41801 + return IPSEC_XMIT_RECURSDETECT;
41802 + }
41803 +
41804 + dst_release(ixs->skb->dst);
41805 + ixs->skb->dst = &ixs->route->u.dst;
41806 + if(ixs->stats) {
41807 + ixs->stats->tx_bytes += ixs->skb->len;
41808 + }
41809 +
41810 + if(ixs->skb->len < skb_network_header(ixs->skb) - ixs->skb->data) {
41811 + if(ixs->stats) {
41812 + ixs->stats->tx_errors++;
41813 + }
41814 + printk(KERN_WARNING
41815 + "klips_error:ipsec_xmit_send: "
41816 + "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
41817 + (unsigned long)(skb_network_header(ixs->skb) - ixs->skb->data),
41818 + ixs->skb->len);
41819 + return IPSEC_XMIT_PUSHPULLERR;
41820 + }
41821 + __skb_pull(ixs->skb, skb_network_header(ixs->skb) - ixs->skb->data);
41822 + if(!ixs->pass) {
41823 + ipsec_nf_reset(ixs->skb);
41824 + }
41825 +
41826 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41827 + "klips_debug:ipsec_xmit_send: "
41828 + "...done, calling ip_send() on device:%s\n",
41829 + ixs->skb->dev ? ixs->skb->dev->name : "NULL");
41830 + KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ip_hdr(ixs->skb));
41831 +#ifdef NETDEV_23 /* 2.4 kernels */
41832 + {
41833 + int err;
41834 +
41835 +/* XXX huh, we include linux/netfilter_ipv4.h where NF_IP_LOCAL_OUT is defined as 3 */
41836 +#ifndef NF_IP_LOCAL_OUT
41837 +#warning I dont understand why NF_IP_LOCAL_OUT is undefined when including linux/netfilter_ipv4.h
41838 +#define NF_IP_LOCAL_OUT 3
41839 +#endif
41840 + err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL,
41841 + ixs->route->u.dst.dev,
41842 + ipsec_xmit_send2);
41843 + if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
41844 + if(net_ratelimit())
41845 + printk(KERN_ERR
41846 + "klips_error:ipsec_xmit_send: "
41847 + "ip_send() failed, err=%d\n",
41848 + -err);
41849 + if(ixs->stats) {
41850 + ixs->stats->tx_errors++;
41851 + ixs->stats->tx_aborted_errors++;
41852 + }
41853 + ixs->skb = NULL;
41854 + return IPSEC_XMIT_IPSENDFAILURE;
41855 + }
41856 + }
41857 +#else /* NETDEV_23 */ /* 2.2 kernels */
41858 + ip_send(ixs->skb);
41859 +#endif /* NETDEV_23 */
41860 + if(ixs->stats) {
41861 + ixs->stats->tx_packets++;
41862 + }
41863 +
41864 + ixs->skb = NULL;
41865 +
41866 + return IPSEC_XMIT_OK;
41867 +}
41868 +
41869 +#ifdef NETDEV_25
41870 +enum ipsec_xmit_value
41871 +ipsec_tunnel_send(struct ipsec_xmit_state *ixs)
41872 +{
41873 + struct flowi fl;
41874 + memset(&fl, 0, sizeof(fl));
41875 +
41876 + /* new route/dst cache code from James Morris */
41877 + ixs->skb->dev = ixs->physdev;
41878 + fl.oif = ixs->physdev->iflink;
41879 +
41880 + return ipsec_xmit_send(ixs, &fl);
41881 +}
41882 +#else
41883 +enum ipsec_xmit_value
41884 +ipsec_tunnel_send(struct ipsec_xmit_state *ixs)
41885 +{
41886 + return ipsec_xmit_send(ixs, NULL);
41887 +}
41888 +#endif
41889 +
41890 +
41891 +/*
41892 + * here is a state machine to handle encapsulation
41893 + * basically we keep getting re-entered until processing is
41894 + * complete. For the simple case we step down the states and finish.
41895 + * each state is ideally some logical part of the process. If a state
41896 + * can pend (ie., require async processing to complete), then this
41897 + * should be the part of last action before it returns IPSEC_RCV_PENDING
41898 + *
41899 + * Any particular action may alter the next_state in ixs to move us to
41900 + * a state other than the preferred "next_state", but this is the
41901 + * exception and is highlighted when it is done.
41902 + *
41903 + * prototypes for state action
41904 + */
41905 +
41906 +struct {
41907 + enum ipsec_xmit_value (*action)(struct ipsec_xmit_state *ixs);
41908 + int next_state;
41909 +} xmit_state_table[] = {
41910 + [IPSEC_XSM_INIT1] = {ipsec_xmit_init1, IPSEC_XSM_INIT2 },
41911 + [IPSEC_XSM_INIT2] = {ipsec_xmit_init2, IPSEC_XSM_ENCAP_INIT },
41912 + [IPSEC_XSM_ENCAP_INIT] = {ipsec_xmit_encap_init, IPSEC_XSM_ENCAP_SELECT },
41913 + [IPSEC_XSM_ENCAP_SELECT]= {ipsec_xmit_encap_select,IPSEC_XSM_DONE },
41914 +
41915 +#ifdef CONFIG_KLIPS_ESP
41916 + [IPSEC_XSM_ESP] = {ipsec_xmit_esp, IPSEC_XSM_ESP_AH },
41917 + [IPSEC_XSM_ESP_AH] = {ipsec_xmit_esp_ah, IPSEC_XSM_CONT },
41918 +#endif
41919 +
41920 +#ifdef CONFIG_KLIPS_AH
41921 + [IPSEC_XSM_AH] = {ipsec_xmit_ah, IPSEC_XSM_CONT },
41922 +#endif
41923 +
41924 +#ifdef CONFIG_KLIPS_IPIP
41925 + [IPSEC_XSM_IPIP] = {ipsec_xmit_ipip, IPSEC_XSM_CONT },
41926 +#endif
41927 +
41928 +#ifdef CONFIG_KLIPS_IPCOMP
41929 + [IPSEC_XSM_IPCOMP] = {ipsec_xmit_ipcomp, IPSEC_XSM_CONT },
41930 +#endif
41931 +
41932 + [IPSEC_XSM_CONT] = {ipsec_xmit_cont, IPSEC_XSM_DONE },
41933 + [IPSEC_XSM_DONE] = {NULL, IPSEC_XSM_DONE},
41934 +};
41935 +
41936 +
41937 +
41938 +void
41939 +ipsec_xsm(struct ipsec_xmit_state *ixs)
41940 +{
41941 + enum ipsec_xmit_value stat = IPSEC_XMIT_ENCAPFAIL;
41942 +
41943 + if (ixs == NULL) {
41944 + KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_xsm: ixs == NULL.\n");
41945 + return;
41946 + }
41947 +
41948 + /*
41949 + * make sure nothing is removed from underneath us
41950 + */
41951 + spin_lock_bh(&tdb_lock);
41952 +
41953 + /*
41954 + * if we have a valid said, then we must check it here to ensure it
41955 + * hasn't gone away while we were waiting for a task to complete
41956 + */
41957 +
41958 + if (ixs->ipsp && ipsec_sa_getbyid(&ixs->outgoing_said) == NULL) {
41959 + KLIPS_PRINT(debug_tunnel,
41960 + "klips_debug:ipsec_xsm: "
41961 + "no ipsec_sa for SA:%s: outgoing packet with no SA dropped\n",
41962 + ixs->sa_len ? ixs->sa_txt : " (error)");
41963 + if (ixs->stats)
41964 + ixs->stats->tx_dropped++;
41965 +
41966 + /* drop through and cleanup */
41967 + stat = IPSEC_XMIT_SAIDNOTFOUND;
41968 + ixs->state = IPSEC_XSM_DONE;
41969 + }
41970 +
41971 + while (ixs->state != IPSEC_XSM_DONE) {
41972 +
41973 + ixs->next_state = xmit_state_table[ixs->state].next_state;
41974 +
41975 + stat = xmit_state_table[ixs->state].action(ixs);
41976 +
41977 + if (stat == IPSEC_XMIT_OK) {
41978 + /* some functions change the next state, see the state table */
41979 + ixs->state = ixs->next_state;
41980 + } else if (stat == IPSEC_XMIT_PENDING) {
41981 + /*
41982 + * things are on hold until we return here in the next/new state
41983 + * we check our SA is valid when we return
41984 + */
41985 + spin_unlock_bh(&tdb_lock);
41986 + return;
41987 + } else {
41988 + /* bad result, force state change to done */
41989 + KLIPS_PRINT(debug_tunnel,
41990 + "klips_debug:ipsec_xsm: "
41991 + "processing completed due to %s.\n",
41992 + ipsec_xmit_err(stat));
41993 + ixs->state = IPSEC_XSM_DONE;
41994 + }
41995 + }
41996 +
41997 + /*
41998 + * all done with anything needing locks
41999 + */
42000 + spin_unlock_bh(&tdb_lock);
42001 +
42002 + /* we are done with this SA */
42003 + if (ixs->ipsp) {
42004 + ipsec_sa_put(ixs->ipsp);
42005 + ixs->ipsp = NULL;
42006 + }
42007 +
42008 + /*
42009 + * let the caller continue with their processing
42010 + */
42011 + ixs->xsm_complete(ixs, stat);
42012 +}
42013 +
42014 +
42015 +/*
42016 + *
42017 + * Local Variables:
42018 + * c-file-style: "linux"
42019 + * End:
42020 + *
42021 + */
42022 --- /dev/null Tue Mar 11 13:02:56 2003
42023 +++ linux/net/ipsec/match586.S Mon Feb 9 13:51:03 2004
42024 @@ -0,0 +1,357 @@
42025 +/* match.s -- Pentium-optimized version of longest_match()
42026 + * Written for zlib 1.1.2
42027 + * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
42028 + *
42029 + * This is free software; you can redistribute it and/or modify it
42030 + * under the terms of the GNU General Public License.
42031 + */
42032 +
42033 +#ifndef NO_UNDERLINE
42034 +#define match_init _ipcomp_match_init
42035 +#define longest_match _ipcomp_longest_match
42036 +#else
42037 +#define match_init ipcomp_match_init
42038 +#define longest_match ipcomp_longest_match
42039 +#endif
42040 +
42041 +#define MAX_MATCH (258)
42042 +#define MIN_MATCH (3)
42043 +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
42044 +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
42045 +
42046 +/* stack frame offsets */
42047 +
42048 +#define wmask 0 /* local copy of s->wmask */
42049 +#define window 4 /* local copy of s->window */
42050 +#define windowbestlen 8 /* s->window + bestlen */
42051 +#define chainlenscanend 12 /* high word: current chain len */
42052 + /* low word: last bytes sought */
42053 +#define scanstart 16 /* first two bytes of string */
42054 +#define scanalign 20 /* dword-misalignment of string */
42055 +#define nicematch 24 /* a good enough match size */
42056 +#define bestlen 28 /* size of best match so far */
42057 +#define scan 32 /* ptr to string wanting match */
42058 +
42059 +#define LocalVarsSize (36)
42060 +/* saved ebx 36 */
42061 +/* saved edi 40 */
42062 +/* saved esi 44 */
42063 +/* saved ebp 48 */
42064 +/* return address 52 */
42065 +#define deflatestate 56 /* the function arguments */
42066 +#define curmatch 60
42067 +
42068 +/* Offsets for fields in the deflate_state structure. These numbers
42069 + * are calculated from the definition of deflate_state, with the
42070 + * assumption that the compiler will dword-align the fields. (Thus,
42071 + * changing the definition of deflate_state could easily cause this
42072 + * program to crash horribly, without so much as a warning at
42073 + * compile time. Sigh.)
42074 + */
42075 +#define dsWSize 36
42076 +#define dsWMask 44
42077 +#define dsWindow 48
42078 +#define dsPrev 56
42079 +#define dsMatchLen 88
42080 +#define dsPrevMatch 92
42081 +#define dsStrStart 100
42082 +#define dsMatchStart 104
42083 +#define dsLookahead 108
42084 +#define dsPrevLen 112
42085 +#define dsMaxChainLen 116
42086 +#define dsGoodMatch 132
42087 +#define dsNiceMatch 136
42088 +
42089 +
42090 +.file "match.S"
42091 +
42092 +.globl match_init, longest_match
42093 +
42094 +.text
42095 +
42096 +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
42097 +
42098 +longest_match:
42099 +
42100 +/* Save registers that the compiler may be using, and adjust %esp to */
42101 +/* make room for our stack frame. */
42102 +
42103 + pushl %ebp
42104 + pushl %edi
42105 + pushl %esi
42106 + pushl %ebx
42107 + subl $LocalVarsSize, %esp
42108 +
42109 +/* Retrieve the function arguments. %ecx will hold cur_match */
42110 +/* throughout the entire function. %edx will hold the pointer to the */
42111 +/* deflate_state structure during the function's setup (before */
42112 +/* entering the main loop). */
42113 +
42114 + movl deflatestate(%esp), %edx
42115 + movl curmatch(%esp), %ecx
42116 +
42117 +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
42118 +
42119 + movl dsNiceMatch(%edx), %eax
42120 + movl dsLookahead(%edx), %ebx
42121 + cmpl %eax, %ebx
42122 + jl LookaheadLess
42123 + movl %eax, %ebx
42124 +LookaheadLess: movl %ebx, nicematch(%esp)
42125 +
42126 +/* register Bytef *scan = s->window + s->strstart; */
42127 +
42128 + movl dsWindow(%edx), %esi
42129 + movl %esi, window(%esp)
42130 + movl dsStrStart(%edx), %ebp
42131 + lea (%esi,%ebp), %edi
42132 + movl %edi, scan(%esp)
42133 +
42134 +/* Determine how many bytes the scan ptr is off from being */
42135 +/* dword-aligned. */
42136 +
42137 + movl %edi, %eax
42138 + negl %eax
42139 + andl $3, %eax
42140 + movl %eax, scanalign(%esp)
42141 +
42142 +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
42143 +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
42144 +
42145 + movl dsWSize(%edx), %eax
42146 + subl $MIN_LOOKAHEAD, %eax
42147 + subl %eax, %ebp
42148 + jg LimitPositive
42149 + xorl %ebp, %ebp
42150 +LimitPositive:
42151 +
42152 +/* unsigned chain_length = s->max_chain_length; */
42153 +/* if (s->prev_length >= s->good_match) { */
42154 +/* chain_length >>= 2; */
42155 +/* } */
42156 +
42157 + movl dsPrevLen(%edx), %eax
42158 + movl dsGoodMatch(%edx), %ebx
42159 + cmpl %ebx, %eax
42160 + movl dsMaxChainLen(%edx), %ebx
42161 + jl LastMatchGood
42162 + shrl $2, %ebx
42163 +LastMatchGood:
42164 +
42165 +/* chainlen is decremented once beforehand so that the function can */
42166 +/* use the sign flag instead of the zero flag for the exit test. */
42167 +/* It is then shifted into the high word, to make room for the scanend */
42168 +/* scanend value, which it will always accompany. */
42169 +
42170 + decl %ebx
42171 + shll $16, %ebx
42172 +
42173 +/* int best_len = s->prev_length; */
42174 +
42175 + movl dsPrevLen(%edx), %eax
42176 + movl %eax, bestlen(%esp)
42177 +
42178 +/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
42179 +
42180 + addl %eax, %esi
42181 + movl %esi, windowbestlen(%esp)
42182 +
42183 +/* register ush scan_start = *(ushf*)scan; */
42184 +/* register ush scan_end = *(ushf*)(scan+best_len-1); */
42185 +
42186 + movw (%edi), %bx
42187 + movw %bx, scanstart(%esp)
42188 + movw -1(%edi,%eax), %bx
42189 + movl %ebx, chainlenscanend(%esp)
42190 +
42191 +/* Posf *prev = s->prev; */
42192 +/* uInt wmask = s->w_mask; */
42193 +
42194 + movl dsPrev(%edx), %edi
42195 + movl dsWMask(%edx), %edx
42196 + mov %edx, wmask(%esp)
42197 +
42198 +/* Jump into the main loop. */
42199 +
42200 + jmp LoopEntry
42201 +
42202 +.balign 16
42203 +
42204 +/* do {
42205 + * match = s->window + cur_match;
42206 + * if (*(ushf*)(match+best_len-1) != scan_end ||
42207 + * *(ushf*)match != scan_start) continue;
42208 + * [...]
42209 + * } while ((cur_match = prev[cur_match & wmask]) > limit
42210 + * && --chain_length != 0);
42211 + *
42212 + * Here is the inner loop of the function. The function will spend the
42213 + * majority of its time in this loop, and majority of that time will
42214 + * be spent in the first ten instructions.
42215 + *
42216 + * Within this loop:
42217 + * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
42218 + * %ecx = curmatch
42219 + * %edx = curmatch & wmask
42220 + * %esi = windowbestlen - i.e., (window + bestlen)
42221 + * %edi = prev
42222 + * %ebp = limit
42223 + *
42224 + * Two optimization notes on the choice of instructions:
42225 + *
42226 + * The first instruction uses a 16-bit address, which costs an extra,
42227 + * unpairable cycle. This is cheaper than doing a 32-bit access and
42228 + * zeroing the high word, due to the 3-cycle misalignment penalty which
42229 + * would occur half the time. This also turns out to be cheaper than
42230 + * doing two separate 8-bit accesses, as the memory is so rarely in the
42231 + * L1 cache.
42232 + *
42233 + * The window buffer, however, apparently spends a lot of time in the
42234 + * cache, and so it is faster to retrieve the word at the end of the
42235 + * match string with two 8-bit loads. The instructions that test the
42236 + * word at the beginning of the match string, however, are executed
42237 + * much less frequently, and there it was cheaper to use 16-bit
42238 + * instructions, which avoided the necessity of saving off and
42239 + * subsequently reloading one of the other registers.
42240 + */
42241 +LookupLoop:
42242 + /* 1 U & V */
42243 + movw (%edi,%edx,2), %cx /* 2 U pipe */
42244 + movl wmask(%esp), %edx /* 2 V pipe */
42245 + cmpl %ebp, %ecx /* 3 U pipe */
42246 + jbe LeaveNow /* 3 V pipe */
42247 + subl $0x00010000, %ebx /* 4 U pipe */
42248 + js LeaveNow /* 4 V pipe */
42249 +LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */
42250 + andl %ecx, %edx /* 5 V pipe */
42251 + cmpb %bl, %al /* 6 U pipe */
42252 + jnz LookupLoop /* 6 V pipe */
42253 + movb (%esi,%ecx), %ah
42254 + cmpb %bh, %ah
42255 + jnz LookupLoop
42256 + movl window(%esp), %eax
42257 + movw (%eax,%ecx), %ax
42258 + cmpw scanstart(%esp), %ax
42259 + jnz LookupLoop
42260 +
42261 +/* Store the current value of chainlen. */
42262 +
42263 + movl %ebx, chainlenscanend(%esp)
42264 +
42265 +/* Point %edi to the string under scrutiny, and %esi to the string we */
42266 +/* are hoping to match it up with. In actuality, %esi and %edi are */
42267 +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
42268 +/* initialized to -(MAX_MATCH_8 - scanalign). */
42269 +
42270 + movl window(%esp), %esi
42271 + movl scan(%esp), %edi
42272 + addl %ecx, %esi
42273 + movl scanalign(%esp), %eax
42274 + movl $(-MAX_MATCH_8), %edx
42275 + lea MAX_MATCH_8(%edi,%eax), %edi
42276 + lea MAX_MATCH_8(%esi,%eax), %esi
42277 +
42278 +/* Test the strings for equality, 8 bytes at a time. At the end,
42279 + * adjust %edx so that it is offset to the exact byte that mismatched.
42280 + *
42281 + * We already know at this point that the first three bytes of the
42282 + * strings match each other, and they can be safely passed over before
42283 + * starting the compare loop. So what this code does is skip over 0-3
42284 + * bytes, as much as necessary in order to dword-align the %edi
42285 + * pointer. (%esi will still be misaligned three times out of four.)
42286 + *
42287 + * It should be confessed that this loop usually does not represent
42288 + * much of the total running time. Replacing it with a more
42289 + * straightforward "rep cmpsb" would not drastically degrade
42290 + * performance.
42291 + */
42292 +LoopCmps:
42293 + movl (%esi,%edx), %eax
42294 + movl (%edi,%edx), %ebx
42295 + xorl %ebx, %eax
42296 + jnz LeaveLoopCmps
42297 + movl 4(%esi,%edx), %eax
42298 + movl 4(%edi,%edx), %ebx
42299 + xorl %ebx, %eax
42300 + jnz LeaveLoopCmps4
42301 + addl $8, %edx
42302 + jnz LoopCmps
42303 + jmp LenMaximum
42304 +LeaveLoopCmps4: addl $4, %edx
42305 +LeaveLoopCmps: testl $0x0000FFFF, %eax
42306 + jnz LenLower
42307 + addl $2, %edx
42308 + shrl $16, %eax
42309 +LenLower: subb $1, %al
42310 + adcl $0, %edx
42311 +
42312 +/* Calculate the length of the match. If it is longer than MAX_MATCH, */
42313 +/* then automatically accept it as the best possible match and leave. */
42314 +
42315 + lea (%edi,%edx), %eax
42316 + movl scan(%esp), %edi
42317 + subl %edi, %eax
42318 + cmpl $MAX_MATCH, %eax
42319 + jge LenMaximum
42320 +
42321 +/* If the length of the match is not longer than the best match we */
42322 +/* have so far, then forget it and return to the lookup loop. */
42323 +
42324 + movl deflatestate(%esp), %edx
42325 + movl bestlen(%esp), %ebx
42326 + cmpl %ebx, %eax
42327 + jg LongerMatch
42328 + movl chainlenscanend(%esp), %ebx
42329 + movl windowbestlen(%esp), %esi
42330 + movl dsPrev(%edx), %edi
42331 + movl wmask(%esp), %edx
42332 + andl %ecx, %edx
42333 + jmp LookupLoop
42334 +
42335 +/* s->match_start = cur_match; */
42336 +/* best_len = len; */
42337 +/* if (len >= nice_match) break; */
42338 +/* scan_end = *(ushf*)(scan+best_len-1); */
42339 +
42340 +LongerMatch: movl nicematch(%esp), %ebx
42341 + movl %eax, bestlen(%esp)
42342 + movl %ecx, dsMatchStart(%edx)
42343 + cmpl %ebx, %eax
42344 + jge LeaveNow
42345 + movl window(%esp), %esi
42346 + addl %eax, %esi
42347 + movl %esi, windowbestlen(%esp)
42348 + movl chainlenscanend(%esp), %ebx
42349 + movw -1(%edi,%eax), %bx
42350 + movl dsPrev(%edx), %edi
42351 + movl %ebx, chainlenscanend(%esp)
42352 + movl wmask(%esp), %edx
42353 + andl %ecx, %edx
42354 + jmp LookupLoop
42355 +
42356 +/* Accept the current string, with the maximum possible length. */
42357 +
42358 +LenMaximum: movl deflatestate(%esp), %edx
42359 + movl $MAX_MATCH, bestlen(%esp)
42360 + movl %ecx, dsMatchStart(%edx)
42361 +
42362 +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
42363 +/* return s->lookahead; */
42364 +
42365 +LeaveNow:
42366 + movl deflatestate(%esp), %edx
42367 + movl bestlen(%esp), %ebx
42368 + movl dsLookahead(%edx), %eax
42369 + cmpl %eax, %ebx
42370 + jg LookaheadRet
42371 + movl %ebx, %eax
42372 +LookaheadRet:
42373 +
42374 +/* Restore the stack and return from whence we came. */
42375 +
42376 + addl $LocalVarsSize, %esp
42377 + popl %ebx
42378 + popl %esi
42379 + popl %edi
42380 + popl %ebp
42381 +match_init: ret
42382 --- /dev/null Tue Mar 11 13:02:56 2003
42383 +++ linux/net/ipsec/match686.S Mon Feb 9 13:51:03 2004
42384 @@ -0,0 +1,330 @@
42385 +/* match.s -- Pentium-Pro-optimized version of longest_match()
42386 + * Written for zlib 1.1.2
42387 + * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
42388 + *
42389 + * This is free software; you can redistribute it and/or modify it
42390 + * under the terms of the GNU General Public License.
42391 + */
42392 +
42393 +#ifndef NO_UNDERLINE
42394 +#define match_init _ipcomp_match_init
42395 +#define longest_match _ipcomp_longest_match
42396 +#else
42397 +#define match_init ipcomp_match_init
42398 +#define longest_match ipcomp_longest_match
42399 +#endif
42400 +
42401 +#define MAX_MATCH (258)
42402 +#define MIN_MATCH (3)
42403 +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
42404 +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
42405 +
42406 +/* stack frame offsets */
42407 +
42408 +#define chainlenwmask 0 /* high word: current chain len */
42409 + /* low word: s->wmask */
42410 +#define window 4 /* local copy of s->window */
42411 +#define windowbestlen 8 /* s->window + bestlen */
42412 +#define scanstart 16 /* first two bytes of string */
42413 +#define scanend 12 /* last two bytes of string */
42414 +#define scanalign 20 /* dword-misalignment of string */
42415 +#define nicematch 24 /* a good enough match size */
42416 +#define bestlen 28 /* size of best match so far */
42417 +#define scan 32 /* ptr to string wanting match */
42418 +
42419 +#define LocalVarsSize (36)
42420 +/* saved ebx 36 */
42421 +/* saved edi 40 */
42422 +/* saved esi 44 */
42423 +/* saved ebp 48 */
42424 +/* return address 52 */
42425 +#define deflatestate 56 /* the function arguments */
42426 +#define curmatch 60
42427 +
42428 +/* Offsets for fields in the deflate_state structure. These numbers
42429 + * are calculated from the definition of deflate_state, with the
42430 + * assumption that the compiler will dword-align the fields. (Thus,
42431 + * changing the definition of deflate_state could easily cause this
42432 + * program to crash horribly, without so much as a warning at
42433 + * compile time. Sigh.)
42434 + */
42435 +#define dsWSize 36
42436 +#define dsWMask 44
42437 +#define dsWindow 48
42438 +#define dsPrev 56
42439 +#define dsMatchLen 88
42440 +#define dsPrevMatch 92
42441 +#define dsStrStart 100
42442 +#define dsMatchStart 104
42443 +#define dsLookahead 108
42444 +#define dsPrevLen 112
42445 +#define dsMaxChainLen 116
42446 +#define dsGoodMatch 132
42447 +#define dsNiceMatch 136
42448 +
42449 +
42450 +.file "match.S"
42451 +
42452 +.globl match_init, longest_match
42453 +
42454 +.text
42455 +
42456 +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
42457 +
42458 +longest_match:
42459 +
42460 +/* Save registers that the compiler may be using, and adjust %esp to */
42461 +/* make room for our stack frame. */
42462 +
42463 + pushl %ebp
42464 + pushl %edi
42465 + pushl %esi
42466 + pushl %ebx
42467 + subl $LocalVarsSize, %esp
42468 +
42469 +/* Retrieve the function arguments. %ecx will hold cur_match */
42470 +/* throughout the entire function. %edx will hold the pointer to the */
42471 +/* deflate_state structure during the function's setup (before */
42472 +/* entering the main loop). */
42473 +
42474 + movl deflatestate(%esp), %edx
42475 + movl curmatch(%esp), %ecx
42476 +
42477 +/* uInt wmask = s->w_mask; */
42478 +/* unsigned chain_length = s->max_chain_length; */
42479 +/* if (s->prev_length >= s->good_match) { */
42480 +/* chain_length >>= 2; */
42481 +/* } */
42482 +
42483 + movl dsPrevLen(%edx), %eax
42484 + movl dsGoodMatch(%edx), %ebx
42485 + cmpl %ebx, %eax
42486 + movl dsWMask(%edx), %eax
42487 + movl dsMaxChainLen(%edx), %ebx
42488 + jl LastMatchGood
42489 + shrl $2, %ebx
42490 +LastMatchGood:
42491 +
42492 +/* chainlen is decremented once beforehand so that the function can */
42493 +/* use the sign flag instead of the zero flag for the exit test. */
42494 +/* It is then shifted into the high word, to make room for the wmask */
42495 +/* value, which it will always accompany. */
42496 +
42497 + decl %ebx
42498 + shll $16, %ebx
42499 + orl %eax, %ebx
42500 + movl %ebx, chainlenwmask(%esp)
42501 +
42502 +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
42503 +
42504 + movl dsNiceMatch(%edx), %eax
42505 + movl dsLookahead(%edx), %ebx
42506 + cmpl %eax, %ebx
42507 + jl LookaheadLess
42508 + movl %eax, %ebx
42509 +LookaheadLess: movl %ebx, nicematch(%esp)
42510 +
42511 +/* register Bytef *scan = s->window + s->strstart; */
42512 +
42513 + movl dsWindow(%edx), %esi
42514 + movl %esi, window(%esp)
42515 + movl dsStrStart(%edx), %ebp
42516 + lea (%esi,%ebp), %edi
42517 + movl %edi, scan(%esp)
42518 +
42519 +/* Determine how many bytes the scan ptr is off from being */
42520 +/* dword-aligned. */
42521 +
42522 + movl %edi, %eax
42523 + negl %eax
42524 + andl $3, %eax
42525 + movl %eax, scanalign(%esp)
42526 +
42527 +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
42528 +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
42529 +
42530 + movl dsWSize(%edx), %eax
42531 + subl $MIN_LOOKAHEAD, %eax
42532 + subl %eax, %ebp
42533 + jg LimitPositive
42534 + xorl %ebp, %ebp
42535 +LimitPositive:
42536 +
42537 +/* int best_len = s->prev_length; */
42538 +
42539 + movl dsPrevLen(%edx), %eax
42540 + movl %eax, bestlen(%esp)
42541 +
42542 +/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
42543 +
42544 + addl %eax, %esi
42545 + movl %esi, windowbestlen(%esp)
42546 +
42547 +/* register ush scan_start = *(ushf*)scan; */
42548 +/* register ush scan_end = *(ushf*)(scan+best_len-1); */
42549 +/* Posf *prev = s->prev; */
42550 +
42551 + movzwl (%edi), %ebx
42552 + movl %ebx, scanstart(%esp)
42553 + movzwl -1(%edi,%eax), %ebx
42554 + movl %ebx, scanend(%esp)
42555 + movl dsPrev(%edx), %edi
42556 +
42557 +/* Jump into the main loop. */
42558 +
42559 + movl chainlenwmask(%esp), %edx
42560 + jmp LoopEntry
42561 +
42562 +.balign 16
42563 +
42564 +/* do {
42565 + * match = s->window + cur_match;
42566 + * if (*(ushf*)(match+best_len-1) != scan_end ||
42567 + * *(ushf*)match != scan_start) continue;
42568 + * [...]
42569 + * } while ((cur_match = prev[cur_match & wmask]) > limit
42570 + * && --chain_length != 0);
42571 + *
42572 + * Here is the inner loop of the function. The function will spend the
42573 + * majority of its time in this loop, and majority of that time will
42574 + * be spent in the first ten instructions.
42575 + *
42576 + * Within this loop:
42577 + * %ebx = scanend
42578 + * %ecx = curmatch
42579 + * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
42580 + * %esi = windowbestlen - i.e., (window + bestlen)
42581 + * %edi = prev
42582 + * %ebp = limit
42583 + */
42584 +LookupLoop:
42585 + andl %edx, %ecx
42586 + movzwl (%edi,%ecx,2), %ecx
42587 + cmpl %ebp, %ecx
42588 + jbe LeaveNow
42589 + subl $0x00010000, %edx
42590 + js LeaveNow
42591 +LoopEntry: movzwl -1(%esi,%ecx), %eax
42592 + cmpl %ebx, %eax
42593 + jnz LookupLoop
42594 + movl window(%esp), %eax
42595 + movzwl (%eax,%ecx), %eax
42596 + cmpl scanstart(%esp), %eax
42597 + jnz LookupLoop
42598 +
42599 +/* Store the current value of chainlen. */
42600 +
42601 + movl %edx, chainlenwmask(%esp)
42602 +
42603 +/* Point %edi to the string under scrutiny, and %esi to the string we */
42604 +/* are hoping to match it up with. In actuality, %esi and %edi are */
42605 +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
42606 +/* initialized to -(MAX_MATCH_8 - scanalign). */
42607 +
42608 + movl window(%esp), %esi
42609 + movl scan(%esp), %edi
42610 + addl %ecx, %esi
42611 + movl scanalign(%esp), %eax
42612 + movl $(-MAX_MATCH_8), %edx
42613 + lea MAX_MATCH_8(%edi,%eax), %edi
42614 + lea MAX_MATCH_8(%esi,%eax), %esi
42615 +
42616 +/* Test the strings for equality, 8 bytes at a time. At the end,
42617 + * adjust %edx so that it is offset to the exact byte that mismatched.
42618 + *
42619 + * We already know at this point that the first three bytes of the
42620 + * strings match each other, and they can be safely passed over before
42621 + * starting the compare loop. So what this code does is skip over 0-3
42622 + * bytes, as much as necessary in order to dword-align the %edi
42623 + * pointer. (%esi will still be misaligned three times out of four.)
42624 + *
42625 + * It should be confessed that this loop usually does not represent
42626 + * much of the total running time. Replacing it with a more
42627 + * straightforward "rep cmpsb" would not drastically degrade
42628 + * performance.
42629 + */
42630 +LoopCmps:
42631 + movl (%esi,%edx), %eax
42632 + xorl (%edi,%edx), %eax
42633 + jnz LeaveLoopCmps
42634 + movl 4(%esi,%edx), %eax
42635 + xorl 4(%edi,%edx), %eax
42636 + jnz LeaveLoopCmps4
42637 + addl $8, %edx
42638 + jnz LoopCmps
42639 + jmp LenMaximum
42640 +LeaveLoopCmps4: addl $4, %edx
42641 +LeaveLoopCmps: testl $0x0000FFFF, %eax
42642 + jnz LenLower
42643 + addl $2, %edx
42644 + shrl $16, %eax
42645 +LenLower: subb $1, %al
42646 + adcl $0, %edx
42647 +
42648 +/* Calculate the length of the match. If it is longer than MAX_MATCH, */
42649 +/* then automatically accept it as the best possible match and leave. */
42650 +
42651 + lea (%edi,%edx), %eax
42652 + movl scan(%esp), %edi
42653 + subl %edi, %eax
42654 + cmpl $MAX_MATCH, %eax
42655 + jge LenMaximum
42656 +
42657 +/* If the length of the match is not longer than the best match we */
42658 +/* have so far, then forget it and return to the lookup loop. */
42659 +
42660 + movl deflatestate(%esp), %edx
42661 + movl bestlen(%esp), %ebx
42662 + cmpl %ebx, %eax
42663 + jg LongerMatch
42664 + movl windowbestlen(%esp), %esi
42665 + movl dsPrev(%edx), %edi
42666 + movl scanend(%esp), %ebx
42667 + movl chainlenwmask(%esp), %edx
42668 + jmp LookupLoop
42669 +
42670 +/* s->match_start = cur_match; */
42671 +/* best_len = len; */
42672 +/* if (len >= nice_match) break; */
42673 +/* scan_end = *(ushf*)(scan+best_len-1); */
42674 +
42675 +LongerMatch: movl nicematch(%esp), %ebx
42676 + movl %eax, bestlen(%esp)
42677 + movl %ecx, dsMatchStart(%edx)
42678 + cmpl %ebx, %eax
42679 + jge LeaveNow
42680 + movl window(%esp), %esi
42681 + addl %eax, %esi
42682 + movl %esi, windowbestlen(%esp)
42683 + movzwl -1(%edi,%eax), %ebx
42684 + movl dsPrev(%edx), %edi
42685 + movl %ebx, scanend(%esp)
42686 + movl chainlenwmask(%esp), %edx
42687 + jmp LookupLoop
42688 +
42689 +/* Accept the current string, with the maximum possible length. */
42690 +
42691 +LenMaximum: movl deflatestate(%esp), %edx
42692 + movl $MAX_MATCH, bestlen(%esp)
42693 + movl %ecx, dsMatchStart(%edx)
42694 +
42695 +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
42696 +/* return s->lookahead; */
42697 +
42698 +LeaveNow:
42699 + movl deflatestate(%esp), %edx
42700 + movl bestlen(%esp), %ebx
42701 + movl dsLookahead(%edx), %eax
42702 + cmpl %eax, %ebx
42703 + jg LookaheadRet
42704 + movl %ebx, %eax
42705 +LookaheadRet:
42706 +
42707 +/* Restore the stack and return from whence we came. */
42708 +
42709 + addl $LocalVarsSize, %esp
42710 + popl %ebx
42711 + popl %esi
42712 + popl %edi
42713 + popl %ebp
42714 +match_init: ret
42715 --- /dev/null Tue Mar 11 13:02:56 2003
42716 +++ linux/net/ipsec/pfkey_v2.c Mon Feb 9 13:51:03 2004
42717 @@ -0,0 +1,1587 @@
42718 +/*
42719 + * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F
42720 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
42721 + *
42722 + * This program is free software; you can redistribute it and/or modify it
42723 + * under the terms of the GNU General Public License as published by the
42724 + * Free Software Foundation; either version 2 of the License, or (at your
42725 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
42726 + *
42727 + * This program is distributed in the hope that it will be useful, but
42728 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
42729 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
42730 + * for more details.
42731 + *
42732 + */
42733 +
42734 +/*
42735 + * Template from /usr/src/linux-2.0.36/net/unix/af_unix.c.
42736 + * Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c.
42737 + */
42738 +
42739 +#define __NO_VERSION__
42740 +#include <linux/module.h>
42741 +#include <linux/version.h>
42742 +#ifndef AUTOCONF_INCLUDED
42743 +# include <linux/config.h>
42744 +#endif
42745 +#include <linux/kernel.h>
42746 +
42747 +#include "openswan/ipsec_param.h"
42748 +
42749 +#include <linux/major.h>
42750 +#include <linux/signal.h>
42751 +#include <linux/sched.h>
42752 +#include <linux/errno.h>
42753 +#include <linux/string.h>
42754 +#include <linux/stat.h>
42755 +#include <linux/socket.h>
42756 +#include <linux/un.h>
42757 +#include <linux/fcntl.h>
42758 +#include <linux/termios.h>
42759 +#include <linux/socket.h>
42760 +#include <linux/sockios.h>
42761 +#include <linux/net.h> /* struct socket */
42762 +#include <linux/in.h>
42763 +#include <linux/fs.h>
42764 +#ifdef MALLOC_SLAB
42765 +# include <linux/slab.h> /* kmalloc() */
42766 +#else /* MALLOC_SLAB */
42767 +# include <linux/malloc.h> /* kmalloc() */
42768 +#endif /* MALLOC_SLAB */
42769 +#ifdef CONFIG_X86
42770 +# include <asm/segment.h>
42771 +#endif
42772 +#include <linux/skbuff.h>
42773 +#include <linux/netdevice.h>
42774 +#include <net/sock.h> /* struct sock */
42775 +#include <net/protocol.h>
42776 +/* #include <net/tcp.h> */
42777 +#include <net/af_unix.h>
42778 +#ifdef CONFIG_PROC_FS
42779 +# include <linux/proc_fs.h>
42780 +#endif /* CONFIG_PROC_FS */
42781 +#ifdef HAVE_SEQ_FILE
42782 +# include <linux/seq_file.h>
42783 +#endif
42784 +
42785 +#include <linux/types.h>
42786 +
42787 +#include <openswan.h>
42788 +
42789 +#include "openswan/radij.h"
42790 +#include "openswan/ipsec_encap.h"
42791 +#include "openswan/ipsec_sa.h"
42792 +
42793 +#include <openswan/pfkeyv2.h>
42794 +#include <openswan/pfkey.h>
42795 +
42796 +#include "openswan/ipsec_proto.h"
42797 +#include "openswan/ipsec_kern24.h"
42798 +#include "openswan/ipsec_sysctl.h"
42799 +
42800 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
42801 +
42802 +#if 0
42803 +#ifndef SOCKOPS_WRAPPED
42804 +#define SOCKOPS_WRAPPED(name) name
42805 +#endif /* SOCKOPS_WRAPPED */
42806 +#endif
42807 +
42808 +extern struct proto_ops SOCKOPS_WRAPPED(pfkey_ops);
42809 +
42810 +#ifdef NET_26
42811 +static rwlock_t pfkey_sock_lock = RW_LOCK_UNLOCKED;
42812 +HLIST_HEAD(pfkey_sock_list);
42813 +static DECLARE_WAIT_QUEUE_HEAD(pfkey_sock_wait);
42814 +static atomic_t pfkey_sock_users = ATOMIC_INIT(0);
42815 +#else
42816 +struct sock *pfkey_sock_list = NULL;
42817 +#endif
42818 +
42819 +struct supported_list *pfkey_supported_list[K_SADB_SATYPE_MAX+1];
42820 +
42821 +struct socket_list *pfkey_open_sockets = NULL;
42822 +struct socket_list *pfkey_registered_sockets[K_SADB_SATYPE_MAX+1];
42823 +
42824 +int pfkey_msg_interp(struct sock *, struct sadb_msg *);
42825 +
42826 +#ifdef NET_26_24_SKALLOC
42827 +DEBUG_NO_STATIC int pfkey_create(struct net *net, struct socket *sock, int protocol);
42828 +#else
42829 +DEBUG_NO_STATIC int pfkey_create(struct socket *sock, int protocol);
42830 +#endif
42831 +DEBUG_NO_STATIC int pfkey_shutdown(struct socket *sock, int mode);
42832 +DEBUG_NO_STATIC int pfkey_release(struct socket *sock);
42833 +
42834 +#ifdef NET_26
42835 +DEBUG_NO_STATIC int pfkey_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len);
42836 +DEBUG_NO_STATIC int pfkey_recvmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg
42837 + , size_t size, int flags);
42838 +#else
42839 +DEBUG_NO_STATIC int pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm);
42840 +DEBUG_NO_STATIC int pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm);
42841 +#endif
42842 +
42843 +struct net_proto_family pfkey_family_ops = {
42844 + .owner = THIS_MODULE,
42845 + .family = PF_KEY,
42846 + .create = pfkey_create
42847 +};
42848 +
42849 +struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = {
42850 + owner: THIS_MODULE,
42851 + family: PF_KEY,
42852 + release: pfkey_release,
42853 + bind: sock_no_bind,
42854 + connect: sock_no_connect,
42855 + socketpair: sock_no_socketpair,
42856 + accept: sock_no_accept,
42857 + getname: sock_no_getname,
42858 + poll: datagram_poll,
42859 + ioctl: sock_no_ioctl,
42860 + listen: sock_no_listen,
42861 + shutdown: pfkey_shutdown,
42862 + setsockopt: sock_no_setsockopt,
42863 + getsockopt: sock_no_getsockopt,
42864 + sendmsg: pfkey_sendmsg,
42865 + recvmsg: pfkey_recvmsg,
42866 + mmap: sock_no_mmap,
42867 +};
42868 +
42869 +#include <linux/smp_lock.h>
42870 +SOCKOPS_WRAP(pfkey, PF_KEY);
42871 +
42872 +#ifdef NET_26
42873 +static void pfkey_sock_list_grab(void)
42874 +{
42875 + write_lock_bh(&pfkey_sock_lock);
42876 +
42877 + if (atomic_read(&pfkey_sock_users)) {
42878 + DECLARE_WAITQUEUE(wait, current);
42879 +
42880 + add_wait_queue_exclusive(&pfkey_sock_wait, &wait);
42881 + for(;;) {
42882 + set_current_state(TASK_UNINTERRUPTIBLE);
42883 + if (atomic_read(&pfkey_sock_users) == 0)
42884 + break;
42885 + write_unlock_bh(&pfkey_sock_lock);
42886 + schedule();
42887 + write_lock_bh(&pfkey_sock_lock);
42888 + }
42889 +
42890 + __set_current_state(TASK_RUNNING);
42891 + remove_wait_queue(&pfkey_sock_wait, &wait);
42892 + }
42893 +}
42894 +
42895 +static __inline__ void pfkey_sock_list_ungrab(void)
42896 +{
42897 + write_unlock_bh(&pfkey_sock_lock);
42898 + wake_up(&pfkey_sock_wait);
42899 +}
42900 +
42901 +static __inline__ void pfkey_lock_sock_list(void)
42902 +{
42903 + /* read_lock() synchronizes us to pfkey_table_grab */
42904 +
42905 + read_lock(&pfkey_sock_lock);
42906 + atomic_inc(&pfkey_sock_users);
42907 + read_unlock(&pfkey_sock_lock);
42908 +}
42909 +
42910 +static __inline__ void pfkey_unlock_sock_list(void)
42911 +{
42912 + if (atomic_dec_and_test(&pfkey_sock_users))
42913 + wake_up(&pfkey_sock_wait);
42914 +}
42915 +#endif
42916 +
42917 +int
42918 +pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets)
42919 +{
42920 + struct socket_list *socket_listp,*prev;
42921 +
42922 + if(!socketp) {
42923 + KLIPS_PRINT(debug_pfkey,
42924 + "klips_debug:pfkey_list_remove_socket: "
42925 + "NULL socketp handed in, failed.\n");
42926 + return -EINVAL;
42927 + }
42928 +
42929 + if(!sockets) {
42930 + KLIPS_PRINT(debug_pfkey,
42931 + "klips_debug:pfkey_list_remove_socket: "
42932 + "NULL sockets list handed in, failed.\n");
42933 + return -EINVAL;
42934 + }
42935 +
42936 + socket_listp = *sockets;
42937 + prev = NULL;
42938 +
42939 + KLIPS_PRINT(debug_pfkey,
42940 + "klips_debug:pfkey_list_remove_socket: "
42941 + "removing sock=0p%p\n",
42942 + socketp);
42943 +
42944 + while(socket_listp != NULL) {
42945 + if(socket_listp->socketp == socketp) {
42946 + if(prev != NULL) {
42947 + prev->next = socket_listp->next;
42948 + } else {
42949 + *sockets = socket_listp->next;
42950 + }
42951 +
42952 + kfree((void*)socket_listp);
42953 +
42954 + break;
42955 + }
42956 + prev = socket_listp;
42957 + socket_listp = socket_listp->next;
42958 + }
42959 +
42960 + return 0;
42961 +}
42962 +
42963 +int
42964 +pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets)
42965 +{
42966 + struct socket_list *socket_listp;
42967 +
42968 + if(!socketp) {
42969 + KLIPS_PRINT(debug_pfkey,
42970 + "klips_debug:pfkey_list_insert_socket: "
42971 + "NULL socketp handed in, failed.\n");
42972 + return -EINVAL;
42973 + }
42974 +
42975 + if(!sockets) {
42976 + KLIPS_PRINT(debug_pfkey,
42977 + "klips_debug:pfkey_list_insert_socket: "
42978 + "NULL sockets list handed in, failed.\n");
42979 + return -EINVAL;
42980 + }
42981 +
42982 + KLIPS_PRINT(debug_pfkey,
42983 + "klips_debug:pfkey_list_insert_socket: "
42984 + "allocating %lu bytes for socketp=0p%p\n",
42985 + (unsigned long) sizeof(struct socket_list),
42986 + socketp);
42987 +
42988 + if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) {
42989 + KLIPS_PRINT(debug_pfkey,
42990 + "klips_debug:pfkey_list_insert_socket: "
42991 + "memory allocation error.\n");
42992 + return -ENOMEM;
42993 + }
42994 +
42995 + socket_listp->socketp = socketp;
42996 + socket_listp->next = *sockets;
42997 + *sockets = socket_listp;
42998 +
42999 + return 0;
43000 +}
43001 +
43002 +int
43003 +pfkey_list_remove_supported(struct ipsec_alg_supported *supported, struct supported_list **supported_list)
43004 +{
43005 + struct supported_list *supported_listp = *supported_list, *prev = NULL;
43006 +
43007 + if(!supported) {
43008 + KLIPS_PRINT(debug_pfkey,
43009 + "klips_debug:pfkey_list_remove_supported: "
43010 + "NULL supported handed in, failed.\n");
43011 + return -EINVAL;
43012 + }
43013 +
43014 + if(!supported_list) {
43015 + KLIPS_PRINT(debug_pfkey,
43016 + "klips_debug:pfkey_list_remove_supported: "
43017 + "NULL supported_list handed in, failed.\n");
43018 + return -EINVAL;
43019 + }
43020 +
43021 + KLIPS_PRINT(debug_pfkey,
43022 + "klips_debug:pfkey_list_remove_supported: "
43023 + "removing supported=0p%p\n",
43024 + supported);
43025 +
43026 + while(supported_listp != NULL) {
43027 + if(supported_listp->supportedp == supported) {
43028 + if(prev != NULL) {
43029 + prev->next = supported_listp->next;
43030 + } else {
43031 + *supported_list = supported_listp->next;
43032 + }
43033 +
43034 + kfree((void*)supported_listp);
43035 +
43036 + break;
43037 + }
43038 + prev = supported_listp;
43039 + supported_listp = supported_listp->next;
43040 + }
43041 +
43042 + return 0;
43043 +}
43044 +
43045 +int
43046 +pfkey_list_insert_supported(struct ipsec_alg_supported *supported
43047 + , struct supported_list **supported_list)
43048 +{
43049 + struct supported_list *supported_listp;
43050 +
43051 + if(!supported) {
43052 + KLIPS_PRINT(debug_pfkey,
43053 + "klips_debug:pfkey_list_insert_supported: "
43054 + "NULL supported handed in, failed.\n");
43055 + return -EINVAL;
43056 + }
43057 +
43058 + if(!supported_list) {
43059 + KLIPS_PRINT(debug_pfkey,
43060 + "klips_debug:pfkey_list_insert_supported: "
43061 + "NULL supported_list handed in, failed.\n");
43062 + return -EINVAL;
43063 + }
43064 +
43065 + KLIPS_PRINT(debug_pfkey,
43066 + "klips_debug:pfkey_list_insert_supported: "
43067 + "allocating %lu bytes for incoming, supported=0p%p, supported_list=0p%p\n",
43068 + (unsigned long) sizeof(struct supported_list),
43069 + supported,
43070 + supported_list);
43071 +
43072 + supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL);
43073 +
43074 + if(supported_listp == NULL)
43075 + {
43076 + KLIPS_PRINT(debug_pfkey,
43077 + "klips_debug:pfkey_list_insert_supported: "
43078 + "memory allocation error.\n");
43079 + return -ENOMEM;
43080 + }
43081 +
43082 + supported_listp->supportedp = supported;
43083 + supported_listp->next = *supported_list;
43084 + *supported_list = supported_listp;
43085 + KLIPS_PRINT(debug_pfkey,
43086 + "klips_debug:pfkey_list_insert_supported: "
43087 + "outgoing, supported=0p%p, supported_list=0p%p\n",
43088 + supported,
43089 + supported_list);
43090 +
43091 + return 0;
43092 +}
43093 +
43094 +#ifdef NET_26
43095 +DEBUG_NO_STATIC void
43096 +pfkey_insert_socket(struct sock *sk)
43097 +{
43098 + KLIPS_PRINT(debug_pfkey,
43099 + "klips_debug:pfkey_insert_socket: "
43100 + "sk=0p%p\n",
43101 + sk);
43102 + pfkey_sock_list_grab();
43103 + sk_add_node(sk, &pfkey_sock_list);
43104 + pfkey_sock_list_ungrab();
43105 +}
43106 +
43107 +DEBUG_NO_STATIC void
43108 +pfkey_remove_socket(struct sock *sk)
43109 +{
43110 + KLIPS_PRINT(debug_pfkey,
43111 + "klips_debug:pfkey_remove_socket: 0p%p\n", sk);
43112 + pfkey_sock_list_grab();
43113 + sk_del_node_init(sk);
43114 + pfkey_sock_list_ungrab();
43115 + return;
43116 +}
43117 +#else
43118 +
43119 +DEBUG_NO_STATIC void
43120 +pfkey_insert_socket(struct sock *sk)
43121 +{
43122 + KLIPS_PRINT(debug_pfkey,
43123 + "klips_debug:pfkey_insert_socket: "
43124 + "sk=0p%p\n",
43125 + sk);
43126 + cli();
43127 + sk->next=pfkey_sock_list;
43128 + pfkey_sock_list=sk;
43129 + sti();
43130 +}
43131 +DEBUG_NO_STATIC void
43132 +pfkey_remove_socket(struct sock *sk)
43133 +{
43134 + struct sock **s;
43135 +
43136 + s = NULL;
43137 + KLIPS_PRINT(debug_pfkey,
43138 + "klips_debug:pfkey_remove_socket: .\n");
43139 +
43140 + cli();
43141 + s=&pfkey_sock_list;
43142 +
43143 + while(*s!=NULL) {
43144 + if(*s==sk) {
43145 + *s=sk->next;
43146 + sk->next=NULL;
43147 + sti();
43148 + KLIPS_PRINT(debug_pfkey,
43149 + "klips_debug:pfkey_remove_socket: "
43150 + "succeeded.\n");
43151 + return;
43152 + }
43153 + s=&((*s)->next);
43154 + }
43155 + sti();
43156 +
43157 + KLIPS_PRINT(debug_pfkey,
43158 + "klips_debug:pfkey_remove_socket: "
43159 + "not found.\n");
43160 + return;
43161 +}
43162 +#endif
43163 +
43164 +DEBUG_NO_STATIC void
43165 +pfkey_destroy_socket(struct sock *sk)
43166 +{
43167 + struct sk_buff *skb;
43168 +
43169 + KLIPS_PRINT(debug_pfkey,
43170 + "klips_debug:pfkey_destroy_socket: 0p%p\n",sk);
43171 + pfkey_remove_socket(sk);
43172 +
43173 + KLIPS_PRINT(debug_pfkey,
43174 + "klips_debug:pfkey_destroy_socket: "
43175 + "pfkey_remove_socket called, sk=0p%p\n",sk);
43176 +
43177 + KLIPS_PRINT(debug_pfkey,
43178 + "klips_debug:pfkey_destroy_socket: "
43179 + "sk(0p%p)->(&0p%p)receive_queue.{next=0p%p,prev=0p%p}.\n",
43180 + sk,
43181 + &(sk->sk_receive_queue),
43182 + sk->sk_receive_queue.next,
43183 + sk->sk_receive_queue.prev);
43184 +
43185 + while(sk && ((skb=skb_dequeue(&(sk->sk_receive_queue)))!=NULL)) {
43186 +#ifdef CONFIG_KLIPS_DEBUG
43187 + if(debug_pfkey && sysctl_ipsec_debug_verbose) {
43188 + KLIPS_PRINT(debug_pfkey,
43189 + "klips_debug:pfkey_destroy_socket: "
43190 + "skb=0p%p dequeued.\n", skb);
43191 + printk(KERN_INFO "klips_debug:pfkey_destroy_socket: "
43192 + "pfkey_skb contents:");
43193 + printk(" next:0p%p", skb->next);
43194 + printk(" prev:0p%p", skb->prev);
43195 + printk(" sk:0p%p", skb->sk);
43196 + printk(" dev:0p%p", skb->dev);
43197 + if(skb->dev) {
43198 + if(skb->dev->name) {
43199 + printk(" dev->name:%s", skb->dev->name);
43200 + } else {
43201 + printk(" dev->name:NULL?");
43202 + }
43203 + } else {
43204 + printk(" dev:NULL");
43205 + }
43206 + printk(" h:0p%p", skb_transport_header(skb));
43207 + printk(" nh:0p%p", skb_network_header(skb));
43208 + printk(" mac:0p%p", skb_mac_header(skb));
43209 + printk(" dst:0p%p", skb->dst);
43210 + if(sysctl_ipsec_debug_verbose) {
43211 + int i;
43212 +
43213 + printk(" cb");
43214 + for(i=0; i<48; i++) {
43215 + printk(":%2x", skb->cb[i]);
43216 + }
43217 + }
43218 + printk(" len:%d", skb->len);
43219 + printk(" csum:%d", skb->csum);
43220 +#ifndef NETDEV_23
43221 + printk(" used:%d", skb->used);
43222 + printk(" is_clone:%d", skb->is_clone);
43223 +#endif /* NETDEV_23 */
43224 + printk(" cloned:%d", skb->cloned);
43225 + printk(" pkt_type:%d", skb->pkt_type);
43226 + printk(" ip_summed:%d", skb->ip_summed);
43227 + printk(" priority:%d", skb->priority);
43228 + printk(" protocol:%d", skb->protocol);
43229 +#ifdef HAVE_SOCK_SECURITY
43230 + printk(" security:%d", skb->security);
43231 +#endif
43232 + printk(" truesize:%d", skb->truesize);
43233 + printk(" head:0p%p", skb->head);
43234 + printk(" data:0p%p", skb->data);
43235 + printk(" tail:0p%p", skb_tail_pointer(skb));
43236 + printk(" end:0p%p", skb_end_pointer(skb));
43237 + if(sysctl_ipsec_debug_verbose) {
43238 + unsigned char* i;
43239 + printk(" data");
43240 + for(i = skb->head; i < skb_end_pointer(skb); i++) {
43241 + printk(":%2x", (unsigned char)(*(i)));
43242 + }
43243 + }
43244 + printk(" destructor:0p%p", skb->destructor);
43245 + printk("\n");
43246 + }
43247 +#endif /* CONFIG_KLIPS_DEBUG */
43248 + KLIPS_PRINT(debug_pfkey,
43249 + "klips_debug:pfkey_destroy_socket: "
43250 + "skb=0p%p freed.\n",
43251 + skb);
43252 + ipsec_kfree_skb(skb);
43253 + }
43254 +
43255 +#ifdef NET_26
43256 + sock_set_flag(sk, SOCK_DEAD);
43257 +#else
43258 + sk->dead = 1;
43259 +#endif
43260 + sk_free(sk);
43261 +
43262 + KLIPS_PRINT(debug_pfkey,
43263 + "klips_debug:pfkey_destroy_socket: destroyed.\n");
43264 +}
43265 +
43266 +int
43267 +pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg)
43268 +{
43269 + struct sock *sk;
43270 +
43271 + if(sock == NULL) {
43272 + KLIPS_PRINT(debug_pfkey,
43273 + "klips_debug:pfkey_upmsg: "
43274 + "NULL socket passed in.\n");
43275 + return -EINVAL;
43276 + }
43277 +
43278 + if(pfkey_msg == NULL) {
43279 + KLIPS_PRINT(debug_pfkey,
43280 + "klips_debug:pfkey_upmsg: "
43281 + "NULL pfkey_msg passed in.\n");
43282 + return -EINVAL;
43283 + }
43284 +
43285 + sk = sock->sk;
43286 + return pfkey_upmsgsk(sk, pfkey_msg);
43287 +}
43288 +int
43289 +pfkey_upmsgsk(struct sock *sk, struct sadb_msg *pfkey_msg)
43290 +{
43291 + int error = 0;
43292 + struct sk_buff * skb = NULL;
43293 +
43294 + if(sk == NULL) {
43295 + KLIPS_PRINT(debug_pfkey,
43296 + "klips_debug:pfkey_upmsg: "
43297 + "NULL sock passed in.\n");
43298 + return -EINVAL;
43299 + }
43300 +
43301 + KLIPS_PRINT(debug_pfkey,
43302 + "klips_debug:pfkey_upmsg: "
43303 + "allocating %d bytes...\n",
43304 + (int)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN));
43305 + if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) {
43306 + KLIPS_PRINT(debug_pfkey,
43307 + "klips_debug:pfkey_upmsg: "
43308 + "no buffers left to send up a message.\n");
43309 + return -ENOBUFS;
43310 + }
43311 + KLIPS_PRINT(debug_pfkey,
43312 + "klips_debug:pfkey_upmsg: "
43313 + "...allocated at 0p%p.\n",
43314 + skb);
43315 +
43316 + skb->dev = NULL;
43317 +
43318 + if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
43319 + printk(KERN_WARNING "klips_error:pfkey_upmsg: "
43320 + "tried to skb_put %ld, %d available. This should never happen, please report.\n",
43321 + (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN,
43322 + skb_tailroom(skb));
43323 + ipsec_kfree_skb(skb);
43324 + return -ENOBUFS;
43325 + }
43326 + skb_set_transport_header(skb, ipsec_skb_offset(skb, skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)));
43327 + memcpy(skb_transport_header(skb), pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
43328 +
43329 + if((error = sock_queue_rcv_skb(sk, skb)) < 0) {
43330 + skb->sk=NULL;
43331 + KLIPS_PRINT(debug_pfkey,
43332 + "klips_debug:pfkey_upmsg: "
43333 + "error=%d calling sock_queue_rcv_skb with skb=0p%p.\n",
43334 + error,
43335 + skb);
43336 + ipsec_kfree_skb(skb);
43337 + return error;
43338 + }
43339 + return error;
43340 +}
43341 +
43342 +#if defined(NET_26_12_SKALLOC) || defined(NET_26_24_SKALLOC)
43343 +
43344 +static struct proto key_proto = {
43345 + .name = "KEY",
43346 + .owner = THIS_MODULE,
43347 + .obj_size = sizeof(struct sock),
43348 +
43349 +};
43350 +#endif
43351 +#ifdef NET_26_24_SKALLOC
43352 +DEBUG_NO_STATIC int
43353 +pfkey_create(struct net *net, struct socket *sock, int protocol)
43354 +#else
43355 +DEBUG_NO_STATIC int
43356 +pfkey_create(struct socket *sock, int protocol)
43357 +#endif
43358 +{
43359 + struct sock *sk;
43360 +
43361 + if(sock == NULL) {
43362 + KLIPS_PRINT(debug_pfkey,
43363 + "klips_debug:pfkey_create: "
43364 + "socket NULL.\n");
43365 + return -EINVAL;
43366 + }
43367 +
43368 + KLIPS_PRINT(debug_pfkey,
43369 + "klips_debug:pfkey_create: "
43370 + "sock=0p%p type:%d state:%d flags:%ld protocol:%d\n",
43371 + sock,
43372 + sock->type,
43373 + (unsigned int)(sock->state),
43374 + sock->flags, protocol);
43375 +
43376 + if(sock->type != SOCK_RAW) {
43377 + KLIPS_PRINT(debug_pfkey,
43378 + "klips_debug:pfkey_create: "
43379 + "only SOCK_RAW supported.\n");
43380 + return -ESOCKTNOSUPPORT;
43381 + }
43382 +
43383 + if(protocol != PF_KEY_V2) {
43384 + KLIPS_PRINT(debug_pfkey,
43385 + "klips_debug:pfkey_create: "
43386 + "protocol not PF_KEY_V2.\n");
43387 + return -EPROTONOSUPPORT;
43388 + }
43389 +
43390 + if((current->uid != 0)) {
43391 + KLIPS_PRINT(debug_pfkey,
43392 + "klips_debug:pfkey_create: "
43393 + "must be root to open pfkey sockets.\n");
43394 + return -EACCES;
43395 + }
43396 +
43397 + sock->state = SS_UNCONNECTED;
43398 +
43399 + KLIPS_INC_USE;
43400 +
43401 +#ifdef NET_26
43402 +#ifdef NET_26_24_SKALLOC
43403 + sk=(struct sock *)sk_alloc(net, PF_KEY, GFP_KERNEL, &key_proto);
43404 +#else
43405 +#ifdef NET_26_12_SKALLOC
43406 + sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1);
43407 +#else
43408 + sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1, NULL);
43409 +#endif
43410 +#endif
43411 +#else
43412 + /* 2.4 interface */
43413 + sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1);
43414 +#endif
43415 +
43416 + if(sk == NULL)
43417 + {
43418 + KLIPS_PRINT(debug_pfkey,
43419 + "klips_debug:pfkey_create: "
43420 + "Out of memory trying to allocate.\n");
43421 + KLIPS_DEC_USE;
43422 + return -ENOMEM;
43423 + }
43424 +
43425 + sock_init_data(sock, sk);
43426 +
43427 + sk->sk_destruct = NULL;
43428 + sk->sk_reuse = 1;
43429 + sock->ops = &SOCKOPS_WRAPPED(pfkey_ops);
43430 +
43431 + sk->sk_family = PF_KEY;
43432 +/* sk->num = protocol; */
43433 + sk->sk_protocol = protocol;
43434 + key_pid(sk) = current->pid;
43435 + KLIPS_PRINT(debug_pfkey,
43436 + "klips_debug:pfkey_create: "
43437 + "sock->fasync_list=0p%p sk->sleep=0p%p.\n",
43438 + sock->fasync_list,
43439 + sk->sk_sleep);
43440 +
43441 + pfkey_insert_socket(sk);
43442 + pfkey_list_insert_socket(sock, &pfkey_open_sockets);
43443 +
43444 + KLIPS_PRINT(debug_pfkey,
43445 + "klips_debug:pfkey_create: "
43446 + "Socket sock=0p%p sk=0p%p initialised.\n", sock, sk);
43447 + return 0;
43448 +}
43449 +
43450 +DEBUG_NO_STATIC int
43451 +#ifdef NETDEV_23
43452 +pfkey_release(struct socket *sock)
43453 +#else /* NETDEV_23 */
43454 +pfkey_release(struct socket *sock, struct socket *peersock)
43455 +#endif /* NETDEV_23 */
43456 +{
43457 + struct sock *sk;
43458 + int i;
43459 +
43460 + if(sock==NULL) {
43461 + KLIPS_PRINT(debug_pfkey,
43462 + "klips_debug:pfkey_release: "
43463 + "No socket attached.\n");
43464 + return 0; /* -EINVAL; */
43465 + }
43466 +
43467 + sk=sock->sk;
43468 +
43469 + /* May not have data attached */
43470 + if(sk==NULL) {
43471 + KLIPS_PRINT(debug_pfkey,
43472 + "klips_debug:pfkey_release: "
43473 + "No sk attached to sock=0p%p.\n", sock);
43474 + return 0; /* -EINVAL; */
43475 + }
43476 +
43477 + KLIPS_PRINT(debug_pfkey,
43478 + "klips_debug:pfkey_release: "
43479 + "sock=0p%p sk=0p%p\n", sock, sk);
43480 +
43481 + if(sock_flag(sk, SOCK_DEAD))
43482 + if(sk->sk_state_change) {
43483 + sk->sk_state_change(sk);
43484 + }
43485 +
43486 + sock->sk = NULL;
43487 +
43488 + /* Try to flush out this socket. Throw out buffers at least */
43489 + pfkey_destroy_socket(sk);
43490 + pfkey_list_remove_socket(sock, &pfkey_open_sockets);
43491 + for(i = K_SADB_SATYPE_UNSPEC; i <= K_SADB_SATYPE_MAX; i++) {
43492 + pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i]));
43493 + }
43494 +
43495 + KLIPS_DEC_USE;
43496 + KLIPS_PRINT(debug_pfkey,
43497 + "klips_debug:pfkey_release: "
43498 + "succeeded.\n");
43499 +
43500 + return 0;
43501 +}
43502 +
43503 +DEBUG_NO_STATIC int
43504 +pfkey_shutdown(struct socket *sock, int mode)
43505 +{
43506 + struct sock *sk;
43507 +
43508 + if(sock == NULL) {
43509 + KLIPS_PRINT(debug_pfkey,
43510 + "klips_debug:pfkey_shutdown: "
43511 + "NULL socket passed in.\n");
43512 + return -EINVAL;
43513 + }
43514 +
43515 + sk=sock->sk;
43516 +
43517 + if(sk == NULL) {
43518 + KLIPS_PRINT(debug_pfkey,
43519 + "klips_debug:pfkey_shutdown: "
43520 + "No sock attached to socket.\n");
43521 + return -EINVAL;
43522 + }
43523 +
43524 + KLIPS_PRINT(debug_pfkey,
43525 + "klips_debug:pfkey_shutdown: "
43526 + "mode=%x.\n", mode);
43527 + mode++;
43528 +
43529 + if(mode&SEND_SHUTDOWN) {
43530 + sk->sk_shutdown|=SEND_SHUTDOWN;
43531 + sk->sk_state_change(sk);
43532 + }
43533 +
43534 + if(mode&RCV_SHUTDOWN) {
43535 + sk->sk_shutdown|=RCV_SHUTDOWN;
43536 + sk->sk_state_change(sk);
43537 + }
43538 + return 0;
43539 +}
43540 +
43541 +/*
43542 + * Send PF_KEY data down.
43543 + */
43544 +
43545 +DEBUG_NO_STATIC int
43546 +#ifdef NET_26
43547 +pfkey_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
43548 +#else
43549 +pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
43550 +#endif
43551 +{
43552 + struct sock *sk;
43553 + int error = 0;
43554 + struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL;
43555 +
43556 + if(sock == NULL) {
43557 + KLIPS_PRINT(debug_pfkey,
43558 + "klips_debug:pfkey_sendmsg: "
43559 + "Null socket passed in.\n");
43560 + SENDERR(EINVAL);
43561 + }
43562 +
43563 + sk = sock->sk;
43564 +
43565 + if(sk == NULL) {
43566 + KLIPS_PRINT(debug_pfkey,
43567 + "klips_debug:pfkey_sendmsg: "
43568 + "Null sock passed in.\n");
43569 + SENDERR(EINVAL);
43570 + }
43571 +
43572 + if(msg == NULL) {
43573 + KLIPS_PRINT(debug_pfkey,
43574 + "klips_debug:pfkey_sendmsg: "
43575 + "Null msghdr passed in.\n");
43576 + SENDERR(EINVAL);
43577 + }
43578 +
43579 + KLIPS_PRINT(debug_pfkey,
43580 + "klips_debug:pfkey_sendmsg: .\n");
43581 + if(sk->sk_err) {
43582 + error = sock_error(sk);
43583 + KLIPS_PRINT(debug_pfkey,
43584 + "klips_debug:pfkey_sendmsg: "
43585 + "sk->err is non-zero, returns %d.\n",
43586 + error);
43587 + SENDERR(-error);
43588 + }
43589 +
43590 + if((current->uid != 0)) {
43591 + KLIPS_PRINT(debug_pfkey,
43592 + "klips_debug:pfkey_sendmsg: "
43593 + "must be root to send messages to pfkey sockets.\n");
43594 + SENDERR(EACCES);
43595 + }
43596 +
43597 + if(msg->msg_control)
43598 + {
43599 + KLIPS_PRINT(debug_pfkey,
43600 + "klips_debug:pfkey_sendmsg: "
43601 + "can't set flags or set msg_control.\n");
43602 + SENDERR(EINVAL);
43603 + }
43604 +
43605 + if(sk->sk_shutdown & SEND_SHUTDOWN) {
43606 + KLIPS_PRINT(debug_pfkey,
43607 + "klips_debug:pfkey_sendmsg: "
43608 + "shutdown.\n");
43609 + send_sig(SIGPIPE, current, 0);
43610 + SENDERR(EPIPE);
43611 + }
43612 +
43613 + if(len < sizeof(struct sadb_msg)) {
43614 + KLIPS_PRINT(debug_pfkey,
43615 + "klips_debug:pfkey_sendmsg: "
43616 + "bogus msg len of %d, too small.\n", (int)len);
43617 + SENDERR(EMSGSIZE);
43618 + }
43619 +
43620 + KLIPS_PRINT(debug_pfkey,
43621 + "klips_debug:pfkey_sendmsg: "
43622 + "allocating %d bytes for downward message.\n",
43623 + (int)len);
43624 + if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) {
43625 + KLIPS_PRINT(debug_pfkey,
43626 + "klips_debug:pfkey_sendmsg: "
43627 + "memory allocation error.\n");
43628 + SENDERR(ENOBUFS);
43629 + }
43630 +
43631 + memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len);
43632 +
43633 + if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
43634 + KLIPS_PRINT(1 || debug_pfkey,
43635 + "klips_debug:pfkey_sendmsg: "
43636 + "not PF_KEY_V2 msg, found %d, should be %d.\n",
43637 + pfkey_msg->sadb_msg_version,
43638 + PF_KEY_V2);
43639 + kfree((void*)pfkey_msg);
43640 + return -EINVAL;
43641 + }
43642 +
43643 + if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
43644 + KLIPS_PRINT(debug_pfkey,
43645 + "klips_debug:pfkey_sendmsg: "
43646 + "bogus msg len of %d, not %d byte aligned.\n",
43647 + (int)len, (int)IPSEC_PFKEYv2_ALIGN);
43648 + SENDERR(EMSGSIZE);
43649 + }
43650 +
43651 + if(pfkey_msg->sadb_msg_reserved) {
43652 + KLIPS_PRINT(debug_pfkey,
43653 + "klips_debug:pfkey_sendmsg: "
43654 + "reserved field must be zero, set to %d.\n",
43655 + pfkey_msg->sadb_msg_reserved);
43656 + SENDERR(EINVAL);
43657 + }
43658 +
43659 + if((pfkey_msg->sadb_msg_type > K_SADB_MAX) || (!pfkey_msg->sadb_msg_type)){
43660 + KLIPS_PRINT(debug_pfkey,
43661 + "klips_debug:pfkey_sendmsg: "
43662 + "msg type too large or small:%d.\n",
43663 + pfkey_msg->sadb_msg_type);
43664 + SENDERR(EINVAL);
43665 + }
43666 +
43667 + KLIPS_PRINT(debug_pfkey,
43668 + "klips_debug:pfkey_sendmsg: "
43669 + "msg sent for parsing.\n");
43670 +
43671 + if((error = pfkey_msg_interp(sk, pfkey_msg))) {
43672 + struct socket_list *pfkey_socketsp;
43673 +
43674 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
43675 + "pfkey_msg_parse returns %d.\n",
43676 + error);
43677 +
43678 + if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) {
43679 + KLIPS_PRINT(debug_pfkey,
43680 + "klips_debug:pfkey_sendmsg: "
43681 + "memory allocation error.\n");
43682 + SENDERR(ENOBUFS);
43683 + }
43684 + memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg));
43685 + pfkey_reply->sadb_msg_errno = -error;
43686 + pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
43687 +
43688 + for(pfkey_socketsp = pfkey_open_sockets;
43689 + pfkey_socketsp;
43690 + pfkey_socketsp = pfkey_socketsp->next) {
43691 + int error_upmsg = 0;
43692 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
43693 + "sending up error=%d message=0p%p to socket=0p%p.\n",
43694 + error,
43695 + pfkey_reply,
43696 + pfkey_socketsp->socketp);
43697 + if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
43698 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
43699 + "sending up error message to socket=0p%p failed with error=%d.\n",
43700 + pfkey_socketsp->socketp,
43701 + error_upmsg);
43702 + /* pfkey_msg_free(&pfkey_reply); */
43703 + /* SENDERR(-error); */
43704 + }
43705 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
43706 + "sending up error message to socket=0p%p succeeded.\n",
43707 + pfkey_socketsp->socketp);
43708 + }
43709 +
43710 + pfkey_msg_free(&pfkey_reply);
43711 +
43712 + SENDERR(-error);
43713 + }
43714 +
43715 + errlab:
43716 + if (pfkey_msg) {
43717 + kfree((void*)pfkey_msg);
43718 + }
43719 +
43720 + if(error) {
43721 + return error;
43722 + } else {
43723 + return len;
43724 + }
43725 +}
43726 +
43727 +/*
43728 + * Receive PF_KEY data up.
43729 + */
43730 +
43731 +DEBUG_NO_STATIC int
43732 +#ifdef NET_26
43733 +pfkey_recvmsg(struct kiocb *kiocb
43734 + , struct socket *sock
43735 + , struct msghdr *msg
43736 + , size_t size
43737 + , int flags)
43738 +#else
43739 +pfkey_recvmsg(struct socket *sock
43740 + , struct msghdr *msg
43741 + , int size, int flags
43742 + , struct scm_cookie *scm)
43743 +#endif
43744 +{
43745 + struct sock *sk;
43746 + int noblock = flags & MSG_DONTWAIT;
43747 + struct sk_buff *skb;
43748 + int error;
43749 +
43750 + if(sock == NULL) {
43751 + KLIPS_PRINT(debug_pfkey,
43752 + "klips_debug:pfkey_recvmsg: "
43753 + "Null socket passed in.\n");
43754 + return -EINVAL;
43755 + }
43756 +
43757 + sk = sock->sk;
43758 +
43759 + if(sk == NULL) {
43760 + KLIPS_PRINT(debug_pfkey,
43761 + "klips_debug:pfkey_recvmsg: "
43762 + "Null sock passed in for sock=0p%p.\n", sock);
43763 + return -EINVAL;
43764 + }
43765 +
43766 + if(msg == NULL) {
43767 + KLIPS_PRINT(debug_pfkey,
43768 + "klips_debug:pfkey_recvmsg: "
43769 + "Null msghdr passed in for sock=0p%p, sk=0p%p.\n",
43770 + sock, sk);
43771 + return -EINVAL;
43772 + }
43773 +
43774 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
43775 + "klips_debug:pfkey_recvmsg: sock=0p%p sk=0p%p msg=0p%p size=%d.\n",
43776 + sock, sk, msg, (int)size);
43777 + if(flags & ~MSG_PEEK) {
43778 + KLIPS_PRINT(debug_pfkey,
43779 + "klips_debug:pfkey_sendmsg: "
43780 + "flags (%d) other than MSG_PEEK not supported.\n",
43781 + flags);
43782 + return -EOPNOTSUPP;
43783 + }
43784 +
43785 + msg->msg_namelen = 0; /* sizeof(*ska); */
43786 +
43787 + if(sk->sk_err) {
43788 + KLIPS_PRINT(debug_pfkey,
43789 + "klips_debug:pfkey_sendmsg: "
43790 + "sk->sk_err=%d.\n", sk->sk_err);
43791 + return sock_error(sk);
43792 + }
43793 +
43794 + if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) {
43795 + return error;
43796 + }
43797 +
43798 + if(size > skb->len) {
43799 + size = skb->len;
43800 + }
43801 + else if(size <skb->len) {
43802 + msg->msg_flags |= MSG_TRUNC;
43803 + }
43804 +
43805 + skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
43806 +#ifdef HAVE_KERNEL_TSTAMP
43807 + sk->sk_stamp = skb->tstamp;
43808 +#elif defined(HAVE_TSTAMP)
43809 + sk->sk_stamp.tv_sec = skb->tstamp.off_sec;
43810 + sk->sk_stamp.tv_usec = skb->tstamp.off_usec;
43811 +#else
43812 + sk->sk_stamp=skb->stamp;
43813 +#endif
43814 +
43815 + skb_free_datagram(sk, skb);
43816 + return size;
43817 +}
43818 +
43819 +#ifdef CONFIG_PROC_FS
43820 +#ifndef PROC_FS_2325
43821 +DEBUG_NO_STATIC
43822 +#endif /* PROC_FS_2325 */
43823 +int
43824 +pfkey_get_info(char *buffer, char **start, off_t offset, int length
43825 +#ifndef PROC_NO_DUMMY
43826 +, int dummy
43827 +#endif /* !PROC_NO_DUMMY */
43828 +#ifdef PROC_EOF_DATA
43829 +, int *eof
43830 +, void *data
43831 +#endif
43832 +)
43833 +{
43834 + const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */
43835 +#ifdef NET_26
43836 + struct hlist_node *node;
43837 +#endif
43838 + off_t begin=0;
43839 + int len=0;
43840 + struct sock *sk;
43841 +
43842 +#ifdef CONFIG_KLIPS_DEBUG
43843 + if(!sysctl_ipsec_debug_verbose) {
43844 +#endif /* CONFIG_KLIPS_DEBUG */
43845 + len += ipsec_snprintf(buffer, length,
43846 + " sock pid socket next prev e n p sndbf Flags Type St\n");
43847 +#ifdef CONFIG_KLIPS_DEBUG
43848 + } else {
43849 + len += ipsec_snprintf(buffer, length,
43850 + " sock pid d sleep socket next prev e r z n p sndbf stamp Flags Type St\n");
43851 + }
43852 +#endif /* CONFIG_KLIPS_DEBUG */
43853 +
43854 + sk_for_each(sk, node, &pfkey_sock_list) {
43855 +
43856 +#ifdef CONFIG_KLIPS_DEBUG
43857 + if(!sysctl_ipsec_debug_verbose) {
43858 +#endif /* CONFIG_KLIPS_DEBUG */
43859 + len += ipsec_snprintf(buffer+len, length-len,
43860 + "%8p %5d %8p %d %d %5d %08lX %8X %2X\n",
43861 + sk,
43862 + key_pid(sk),
43863 + sk->sk_socket,
43864 + sk->sk_err,
43865 + sk->sk_protocol,
43866 + sk->sk_sndbuf,
43867 + sk->sk_socket->flags,
43868 + sk->sk_socket->type,
43869 + sk->sk_socket->state);
43870 +#ifdef CONFIG_KLIPS_DEBUG
43871 + } else {
43872 + struct timeval t;
43873 + grab_socket_timeval(t, *sk);
43874 + len += ipsec_snprintf(buffer+len, length-len,
43875 + "%8p %5d %d %8p %8p %d %d %d %d %5d %d.%06d %08lX %8X %2X\n",
43876 + sk,
43877 + key_pid(sk),
43878 + sock_flag(sk, SOCK_DEAD),
43879 + sk->sk_sleep,
43880 + sk->sk_socket,
43881 + sk->sk_err,
43882 + sk->sk_reuse,
43883 +#ifdef HAVE_SOCK_ZAPPED
43884 + sock_flag(sk, SOCK_ZAPPED),
43885 +#else
43886 + sk->sk_zapped,
43887 +#endif
43888 + sk->sk_protocol,
43889 + sk->sk_sndbuf,
43890 + (unsigned int)t.tv_sec,
43891 + (unsigned int)t.tv_usec,
43892 + sk->sk_socket->flags,
43893 + sk->sk_socket->type,
43894 + sk->sk_socket->state);
43895 + }
43896 +#endif /* CONFIG_KLIPS_DEBUG */
43897 +
43898 + if (len >= max_content) {
43899 + /* we've done all that can fit -- stop loop */
43900 + len = max_content; /* truncate crap */
43901 + break;
43902 + } else {
43903 + const off_t pos = begin + len; /* file position of end of what we've generated */
43904 +
43905 + if (pos <= offset) {
43906 + /* all is before first interesting character:
43907 + * discard, but note where we are.
43908 + */
43909 + len = 0;
43910 + begin = pos;
43911 + }
43912 + }
43913 + }
43914 +
43915 + *start = buffer + (offset - begin); /* Start of wanted data */
43916 + return len - (offset - begin);
43917 +}
43918 +
43919 +#ifndef PROC_FS_2325
43920 +DEBUG_NO_STATIC
43921 +#endif /* PROC_FS_2325 */
43922 +int
43923 +pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length
43924 +#ifndef PROC_NO_DUMMY
43925 +, int dummy
43926 +#endif /* !PROC_NO_DUMMY */
43927 +#ifdef PROC_EOF_DATA
43928 +, int *eof
43929 +, void *data
43930 +#endif
43931 +)
43932 +{
43933 + /* limit of useful snprintf output */
43934 + const int max_content = length > 0? length-1 : 0;
43935 + off_t begin=0;
43936 + int len=0;
43937 + int satype;
43938 + struct supported_list *ps;
43939 +
43940 + len += ipsec_snprintf(buffer, length,
43941 + "satype exttype alg_id ivlen minbits maxbits name\n");
43942 +
43943 + for(satype = K_SADB_SATYPE_UNSPEC; satype <= K_SADB_SATYPE_MAX; satype++) {
43944 + ps = pfkey_supported_list[satype];
43945 + while(ps) {
43946 + struct ipsec_alg_supported *alg = ps->supportedp;
43947 + const char *n = alg->ias_name;
43948 + if(n == NULL) n = "unknown";
43949 +
43950 + len += ipsec_snprintf(buffer+len, length-len,
43951 + " %2d %2d %2d %3d %3d %3d %20s\n",
43952 + satype,
43953 + alg->ias_exttype,
43954 + alg->ias_id,
43955 + alg->ias_ivlen,
43956 + alg->ias_keyminbits,
43957 + alg->ias_keymaxbits,
43958 + n);
43959 +
43960 + if (len >= max_content) {
43961 + /* we've done all that can fit -- stop loop */
43962 + len = max_content; /* truncate crap */
43963 + break;
43964 + } else {
43965 + const off_t pos = begin + len; /* file position of end of what we've generated */
43966 +
43967 + if (pos <= offset) {
43968 + /* all is before first interesting character:
43969 + * discard, but note where we are.
43970 + */
43971 + len = 0;
43972 + begin = pos;
43973 + }
43974 + }
43975 +
43976 + ps = ps->next;
43977 + }
43978 + }
43979 + *start = buffer + (offset - begin); /* Start of wanted data */
43980 + return len - (offset - begin);
43981 +}
43982 +
43983 +#ifndef PROC_FS_2325
43984 +DEBUG_NO_STATIC
43985 +#endif /* PROC_FS_2325 */
43986 +int
43987 +pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length
43988 +#ifndef PROC_NO_DUMMY
43989 +, int dummy
43990 +#endif /* !PROC_NO_DUMMY */
43991 +#ifdef PROC_EOF_DATA
43992 +, int *eof
43993 +, void *data
43994 +#endif
43995 +)
43996 +{
43997 + const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */
43998 + off_t begin=0;
43999 + int len=0;
44000 + int satype;
44001 + struct socket_list *pfkey_sockets;
44002 +
44003 + len += ipsec_snprintf(buffer, length,
44004 + "satype socket pid sk\n");
44005 +
44006 + for(satype = K_SADB_SATYPE_UNSPEC; satype <= K_SADB_SATYPE_MAX; satype++) {
44007 + pfkey_sockets = pfkey_registered_sockets[satype];
44008 + while(pfkey_sockets) {
44009 + len += ipsec_snprintf(buffer+len, length-len,
44010 + " %2d %8p %5d %8p\n",
44011 + satype,
44012 + pfkey_sockets->socketp,
44013 + key_pid(pfkey_sockets->socketp->sk),
44014 + pfkey_sockets->socketp->sk);
44015 +
44016 + if (len >= max_content) {
44017 + /* we've done all that can fit -- stop loop (could stop two) */
44018 + len = max_content; /* truncate crap */
44019 + break;
44020 + } else {
44021 + const off_t pos = begin + len; /* file position of end of what we've generated */
44022 +
44023 + if (pos <= offset) {
44024 + /* all is before first interesting character:
44025 + * discard, but note where we are.
44026 + */
44027 + len = 0;
44028 + begin = pos;
44029 + }
44030 + }
44031 +
44032 + pfkey_sockets = pfkey_sockets->next;
44033 + }
44034 + }
44035 + *start = buffer + (offset - begin); /* Start of wanted data */
44036 + return len - (offset - begin);
44037 +}
44038 +
44039 +#ifndef PROC_FS_2325
44040 +struct proc_dir_entry proc_net_pfkey =
44041 +{
44042 + 0,
44043 + 6, "pf_key",
44044 + S_IFREG | S_IRUGO, 1, 0, 0,
44045 + 0, &proc_net_inode_operations,
44046 + pfkey_get_info
44047 +};
44048 +struct proc_dir_entry proc_net_pfkey_supported =
44049 +{
44050 + 0,
44051 + 16, "pf_key_supported",
44052 + S_IFREG | S_IRUGO, 1, 0, 0,
44053 + 0, &proc_net_inode_operations,
44054 + pfkey_supported_get_info
44055 +};
44056 +struct proc_dir_entry proc_net_pfkey_registered =
44057 +{
44058 + 0,
44059 + 17, "pf_key_registered",
44060 + S_IFREG | S_IRUGO, 1, 0, 0,
44061 + 0, &proc_net_inode_operations,
44062 + pfkey_registered_get_info
44063 +};
44064 +#endif /* !PROC_FS_2325 */
44065 +#endif /* CONFIG_PROC_FS */
44066 +
44067 +DEBUG_NO_STATIC int
44068 +supported_add_all(int satype, struct ipsec_alg_supported supported[], int size)
44069 +{
44070 + int i;
44071 + int error = 0;
44072 +
44073 + KLIPS_PRINT(debug_pfkey,
44074 + "klips_debug:init_pfkey: "
44075 + "sizeof(supported_init_<satype=%d>)[%d]/sizeof(struct ipsec_alg_supported)[%d]=%d.\n",
44076 + satype,
44077 + size,
44078 + (int)sizeof(struct ipsec_alg_supported),
44079 + (int)(size/sizeof(struct ipsec_alg_supported)));
44080 +
44081 + for(i = 0; i < size / sizeof(struct ipsec_alg_supported); i++) {
44082 +
44083 + const char *n = supported[i].ias_name;
44084 + if(n == NULL) n="unknown";
44085 +
44086 + KLIPS_PRINT(debug_pfkey,
44087 + "klips_debug:init_pfkey: "
44088 + "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d name=%s.\n",
44089 + i,
44090 + satype,
44091 + supported[i].ias_exttype,
44092 + supported[i].ias_id,
44093 + supported[i].ias_ivlen,
44094 + supported[i].ias_keyminbits,
44095 + supported[i].ias_keymaxbits,
44096 + n);
44097 +
44098 + error |= pfkey_list_insert_supported(&(supported[i]),
44099 + &(pfkey_supported_list[satype]));
44100 + }
44101 + return error;
44102 +}
44103 +
44104 +DEBUG_NO_STATIC int
44105 +supported_remove_all(int satype)
44106 +{
44107 + int error = 0;
44108 + struct ipsec_alg_supported*supportedp;
44109 +
44110 + while(pfkey_supported_list[satype]) {
44111 + const char *n;
44112 + supportedp = pfkey_supported_list[satype]->supportedp;
44113 +
44114 + n = supportedp->ias_name;
44115 + if(n == NULL) n="unknown";
44116 +
44117 + KLIPS_PRINT(debug_pfkey,
44118 + "klips_debug:init_pfkey: "
44119 + "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d name=%s.\n",
44120 + satype,
44121 + supportedp->ias_exttype,
44122 + supportedp->ias_id,
44123 + supportedp->ias_ivlen,
44124 + supportedp->ias_keyminbits,
44125 + supportedp->ias_keymaxbits, n);
44126 +
44127 + error |= pfkey_list_remove_supported(supportedp,
44128 + &(pfkey_supported_list[satype]));
44129 + }
44130 + return error;
44131 +}
44132 +
44133 +int
44134 +pfkey_init(void)
44135 +{
44136 + int error = 0;
44137 + int i;
44138 +#ifdef HAVE_PROC_DIR_ENTRY
44139 + struct proc_dir_entry* entry;
44140 +#endif
44141 +
44142 +
44143 + static struct ipsec_alg_supported supported_init_ah[] = {
44144 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
44145 + {K_SADB_EXT_SUPPORTED_AUTH, K_SADB_AALG_MD5HMAC, 0, 128, 128},
44146 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
44147 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
44148 + {K_SADB_EXT_SUPPORTED_AUTH, K_SADB_AALG_SHA1HMAC, 0, 160, 160}
44149 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
44150 + };
44151 + static struct ipsec_alg_supported supported_init_esp[] = {
44152 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
44153 + {K_SADB_EXT_SUPPORTED_AUTH, K_SADB_AALG_MD5HMAC, 0, 128, 128},
44154 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
44155 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
44156 + {K_SADB_EXT_SUPPORTED_AUTH, K_SADB_AALG_SHA1HMAC, 0, 160, 160},
44157 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
44158 +#ifdef CONFIG_KLIPS_ENC_3DES
44159 + {K_SADB_EXT_SUPPORTED_ENCRYPT, K_SADB_EALG_3DESCBC, 64, 168, 168},
44160 +#endif /* CONFIG_KLIPS_ENC_3DES */
44161 + };
44162 + static struct ipsec_alg_supported supported_init_ipip[] = {
44163 + {K_SADB_EXT_SUPPORTED_ENCRYPT, K_SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32}
44164 +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
44165 + , {K_SADB_EXT_SUPPORTED_ENCRYPT, K_SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32}
44166 + , {K_SADB_EXT_SUPPORTED_ENCRYPT, K_SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128}
44167 + , {K_SADB_EXT_SUPPORTED_ENCRYPT, K_SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128}
44168 +#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
44169 + };
44170 +#ifdef CONFIG_KLIPS_IPCOMP
44171 + static struct ipsec_alg_supported supported_init_ipcomp[] = {
44172 + {K_SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1}
44173 + };
44174 +#endif /* CONFIG_KLIPS_IPCOMP */
44175 +
44176 +#if 0
44177 + printk(KERN_INFO
44178 + "klips_info:pfkey_init: "
44179 + "FreeS/WAN: initialising PF_KEYv2 domain sockets.\n");
44180 +#endif
44181 +
44182 + for(i = K_SADB_SATYPE_UNSPEC; i <= K_SADB_SATYPE_MAX; i++) {
44183 + pfkey_registered_sockets[i] = NULL;
44184 + pfkey_supported_list[i] = NULL;
44185 + }
44186 +
44187 + error |= supported_add_all(K_SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah));
44188 + error |= supported_add_all(K_SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp));
44189 +#ifdef CONFIG_KLIPS_IPCOMP
44190 + error |= supported_add_all(K_SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp));
44191 +#endif /* CONFIG_KLIPS_IPCOMP */
44192 + error |= supported_add_all(K_SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip));
44193 +
44194 + error |= sock_register(&pfkey_family_ops);
44195 +
44196 +#ifdef CONFIG_PROC_FS
44197 +# ifndef PROC_FS_2325
44198 +# ifdef PROC_FS_21
44199 + error |= proc_register(proc_net, &proc_net_pfkey);
44200 + error |= proc_register(proc_net, &proc_net_pfkey_supported);
44201 + error |= proc_register(proc_net, &proc_net_pfkey_registered);
44202 +# else /* PROC_FS_21 */
44203 + error |= proc_register_dynamic(&proc_net, &proc_net_pfkey);
44204 + error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_supported);
44205 + error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_registered);
44206 +# endif /* PROC_FS_21 */
44207 +# else /* !PROC_FS_2325 */
44208 +# if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
44209 + proc_net_create ("pf_key", 0, pfkey_get_info);
44210 + proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info);
44211 + proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info);
44212 +# else
44213 + entry = create_proc_entry ("pf_key", 0, init_net.proc_net);
44214 + entry->read_proc = pfkey_get_info;
44215 + entry = create_proc_entry ("pf_key_supported", 0, init_net.proc_net);
44216 + entry->read_proc = pfkey_supported_get_info;
44217 + entry = create_proc_entry ("pf_key_registered", 0, init_net.proc_net);
44218 + entry->read_proc = pfkey_registered_get_info;
44219 +# endif
44220 +# endif /* !PROC_FS_2325 */
44221 +#endif /* CONFIG_PROC_FS */
44222 +
44223 + return error;
44224 +}
44225 +
44226 +int
44227 +pfkey_cleanup(void)
44228 +{
44229 + int error = 0;
44230 +
44231 + printk(KERN_INFO "klips_info:pfkey_cleanup: "
44232 + "shutting down PF_KEY domain sockets.\n");
44233 +#ifdef VOID_SOCK_UNREGISTER
44234 + sock_unregister(PF_KEY);
44235 +#else
44236 + error |= sock_unregister(PF_KEY);
44237 +#endif
44238 +
44239 + error |= supported_remove_all(K_SADB_SATYPE_AH);
44240 + error |= supported_remove_all(K_SADB_SATYPE_ESP);
44241 +#ifdef CONFIG_KLIPS_IPCOMP
44242 + error |= supported_remove_all(K_SADB_X_SATYPE_COMP);
44243 +#endif /* CONFIG_KLIPS_IPCOMP */
44244 + error |= supported_remove_all(K_SADB_X_SATYPE_IPIP);
44245 +
44246 +#ifdef CONFIG_PROC_FS
44247 +# ifndef PROC_FS_2325
44248 + if (proc_net_unregister(proc_net_pfkey.low_ino) != 0)
44249 + printk("klips_debug:pfkey_cleanup: "
44250 + "cannot unregister /proc/net/pf_key\n");
44251 + if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0)
44252 + printk("klips_debug:pfkey_cleanup: "
44253 + "cannot unregister /proc/net/pf_key_supported\n");
44254 + if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0)
44255 + printk("klips_debug:pfkey_cleanup: "
44256 + "cannot unregister /proc/net/pf_key_registered\n");
44257 +# else /* !PROC_FS_2325 */
44258 +# if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
44259 + proc_net_remove ("pf_key");
44260 + proc_net_remove ("pf_key_supported");
44261 + proc_net_remove ("pf_key_registered");
44262 +# else
44263 + proc_net_remove (&init_net, "pf_key");
44264 + proc_net_remove (&init_net, "pf_key_supported");
44265 + proc_net_remove (&init_net, "pf_key_registered");
44266 +# endif
44267 +
44268 +# endif /* !PROC_FS_2325 */
44269 +#endif /* CONFIG_PROC_FS */
44270 +
44271 + /* other module unloading cleanup happens here */
44272 + return error;
44273 +}
44274 +
44275 +#ifdef MODULE
44276 +#if 0
44277 +int
44278 +init_module(void)
44279 +{
44280 + pfkey_init();
44281 + return 0;
44282 +}
44283 +
44284 +void
44285 +cleanup_module(void)
44286 +{
44287 + pfkey_cleanup();
44288 +}
44289 +#endif /* 0 */
44290 +#else /* MODULE */
44291 +struct net_protocol;
44292 +void pfkey_proto_init(struct net_protocol *pro)
44293 +{
44294 + pfkey_init();
44295 +}
44296 +#endif /* MODULE */
44297 +
44298 +/*
44299 + *
44300 + * Local Variables:
44301 + * c-file-style: "linux"
44302 + * End:
44303 + *
44304 + */
44305 --- /dev/null Tue Mar 11 13:02:56 2003
44306 +++ linux/net/ipsec/pfkey_v2_build.c Mon Feb 9 13:51:03 2004
44307 @@ -0,0 +1,1452 @@
44308 +/*
44309 + * RFC2367 PF_KEYv2 Key management API message parser
44310 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
44311 + *
44312 + * This program is free software; you can redistribute it and/or modify it
44313 + * under the terms of the GNU General Public License as published by the
44314 + * Free Software Foundation; either version 2 of the License, or (at your
44315 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
44316 + *
44317 + * This program is distributed in the hope that it will be useful, but
44318 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
44319 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
44320 + * for more details.
44321 + *
44322 + * RCSID $Id: pfkey_v2_build.c,v 1.53 2005/11/09 00:30:37 mcr Exp $
44323 + */
44324 +
44325 +/*
44326 + * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
44327 + */
44328 +
44329 +char pfkey_v2_build_c_version[] = "$Id: pfkey_v2_build.c,v 1.53 2005/11/09 00:30:37 mcr Exp $";
44330 +
44331 +/*
44332 + * Some ugly stuff to allow consistent debugging code for use in the
44333 + * kernel and in user space
44334 +*/
44335 +
44336 +#if defined(__KERNEL__) && defined(linux)
44337 +
44338 +# include <linux/kernel.h> /* for printk */
44339 +
44340 +# include "openswan/ipsec_kversion.h" /* for malloc switch */
44341 +# ifdef MALLOC_SLAB
44342 +# include <linux/slab.h> /* kmalloc() */
44343 +# else /* MALLOC_SLAB */
44344 +# include <linux/malloc.h> /* kmalloc() */
44345 +# endif /* MALLOC_SLAB */
44346 +# include <linux/errno.h> /* error codes */
44347 +# include <linux/types.h> /* size_t */
44348 +# include <linux/interrupt.h> /* mark_bh */
44349 +
44350 +# include <linux/netdevice.h> /* struct device, and other headers */
44351 +# include <linux/etherdevice.h> /* eth_type_trans */
44352 +# include <linux/ip.h> /* struct iphdr */
44353 +# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
44354 +# include <linux/ipv6.h> /* struct ipv6hdr */
44355 +# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
44356 +
44357 +# define MALLOC(size) kmalloc(size, GFP_ATOMIC)
44358 +# define FREE(obj) kfree(obj)
44359 +# include <openswan.h>
44360 +#else /* __KERNEL__ */
44361 +
44362 +# include <sys/types.h>
44363 +# include <sys/errno.h>
44364 +# include <netinet/in.h>
44365 +# include <stdlib.h>
44366 +# include <stdio.h>
44367 +# include <string.h> /* memset */
44368 +
44369 +# include <openswan.h>
44370 +
44371 +#endif /* __KERNEL__ */
44372 +
44373 +#include <openswan/pfkeyv2.h>
44374 +#include <openswan/pfkey.h>
44375 +
44376 +#ifdef __KERNEL__
44377 +#include "openswan/radij.h" /* rd_nodes */
44378 +#include "openswan/ipsec_encap.h" /* sockaddr_encap */
44379 +#endif /* __KERNEL__ */
44380 +
44381 +
44382 +#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
44383 +#include "openswan/pfkey_debug.h"
44384 +
44385 +
44386 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
44387 +
44388 +void
44389 +pfkey_extensions_init(struct sadb_ext *extensions[K_SADB_EXT_MAX + 1])
44390 +{
44391 + int i;
44392 +
44393 + for (i = 0; i != K_SADB_EXT_MAX + 1; i++) {
44394 + extensions[i] = NULL;
44395 + }
44396 +}
44397 +
44398 +void
44399 +pfkey_extensions_free(struct sadb_ext *extensions[K_SADB_EXT_MAX + 1])
44400 +{
44401 + int i;
44402 +
44403 + if(!extensions) {
44404 + return;
44405 + }
44406 +
44407 + if(extensions[0]) {
44408 + memset(extensions[0], 0, sizeof(struct sadb_msg));
44409 + FREE(extensions[0]);
44410 + extensions[0] = NULL;
44411 + }
44412 +
44413 + for (i = 1; i != K_SADB_EXT_MAX + 1; i++) {
44414 + if(extensions[i]) {
44415 + memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
44416 + FREE(extensions[i]);
44417 + extensions[i] = NULL;
44418 + }
44419 + }
44420 +}
44421 +
44422 +void
44423 +pfkey_msg_free(struct sadb_msg **pfkey_msg)
44424 +{
44425 + if(*pfkey_msg) {
44426 + memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
44427 + FREE(*pfkey_msg);
44428 + *pfkey_msg = NULL;
44429 + }
44430 +}
44431 +
44432 +/* Default extension builders taken from the KLIPS code */
44433 +
44434 +int
44435 +pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
44436 + uint8_t msg_type,
44437 + uint8_t satype,
44438 + uint8_t msg_errno,
44439 + uint32_t seq,
44440 + uint32_t pid)
44441 +{
44442 + int error = 0;
44443 + struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext;
44444 +
44445 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44446 + "pfkey_msg_hdr_build:\n");
44447 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44448 + "pfkey_msg_hdr_build: "
44449 + "on_entry &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
44450 + &pfkey_ext,
44451 + pfkey_ext,
44452 + *pfkey_ext);
44453 + /* sanity checks... */
44454 + if(pfkey_msg) {
44455 + ERROR("pfkey_msg_hdr_build: "
44456 + "why is pfkey_msg already pointing to something?\n");
44457 + SENDERR(EINVAL);
44458 + }
44459 +
44460 + if(!msg_type) {
44461 + ERROR("pfkey_msg_hdr_build: "
44462 + "msg type not set, must be non-zero..\n");
44463 + SENDERR(EINVAL);
44464 + }
44465 +
44466 + if(msg_type > K_SADB_MAX) {
44467 + ERROR("pfkey_msg_hdr_build: "
44468 + "msg type too large:%d.\n",
44469 + msg_type);
44470 + SENDERR(EINVAL);
44471 + }
44472 +
44473 + if(satype > K_SADB_SATYPE_MAX) {
44474 + ERROR("pfkey_msg_hdr_build: "
44475 + "satype %d > max %d\n",
44476 + satype, SADB_SATYPE_MAX);
44477 + SENDERR(EINVAL);
44478 + }
44479 +
44480 + pfkey_msg = (struct sadb_msg*)MALLOC(sizeof(struct sadb_msg));
44481 + *pfkey_ext = (struct sadb_ext*)pfkey_msg;
44482 +
44483 + if(pfkey_msg == NULL) {
44484 + ERROR("pfkey_msg_hdr_build: "
44485 + "memory allocation failed\n");
44486 + SENDERR(ENOMEM);
44487 + }
44488 + memset(pfkey_msg, 0, sizeof(struct sadb_msg));
44489 +
44490 + pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
44491 +
44492 + pfkey_msg->sadb_msg_type = msg_type;
44493 + pfkey_msg->sadb_msg_satype = satype;
44494 +
44495 + pfkey_msg->sadb_msg_version = PF_KEY_V2;
44496 + pfkey_msg->sadb_msg_errno = msg_errno;
44497 + pfkey_msg->sadb_msg_reserved = 0;
44498 + pfkey_msg->sadb_msg_seq = seq;
44499 + pfkey_msg->sadb_msg_pid = pid;
44500 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44501 + "pfkey_msg_hdr_build: "
44502 + "on_exit &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
44503 + &pfkey_ext,
44504 + pfkey_ext,
44505 + *pfkey_ext);
44506 +errlab:
44507 + return error;
44508 +}
44509 +
44510 +
44511 +int
44512 +pfkey_sa_builds(struct sadb_ext **pfkey_ext,
44513 + struct sadb_builds sab)
44514 +{
44515 + int error = 0;
44516 + struct k_sadb_sa *pfkey_sa = (struct k_sadb_sa *)*pfkey_ext;
44517 +
44518 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44519 + "pfkey_sa_build: "
44520 + "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n",
44521 + ntohl(sab.sa_base.sadb_sa_spi), /* in network order */
44522 + sab.sa_base.sadb_sa_replay,
44523 + sab.sa_base.sadb_sa_state,
44524 + sab.sa_base.sadb_sa_auth,
44525 + sab.sa_base.sadb_sa_encrypt,
44526 + sab.sa_base.sadb_sa_flags);
44527 + /* sanity checks... */
44528 + if(pfkey_sa) {
44529 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44530 + "pfkey_sa_build: "
44531 + "why is pfkey_sa already pointing to something?\n");
44532 + SENDERR(EINVAL);
44533 + }
44534 +
44535 + if(sab.sa_base.sadb_sa_exttype != SADB_EXT_SA &&
44536 + sab.sa_base.sadb_sa_exttype != K_SADB_X_EXT_SA2) {
44537 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44538 + "pfkey_sa_build: "
44539 + "invalid exttype=%d.\n",
44540 + sab.sa_base.sadb_sa_exttype);
44541 + SENDERR(EINVAL);
44542 + }
44543 +
44544 + if(sab.sa_base.sadb_sa_replay > 64) {
44545 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44546 + "pfkey_sa_build: "
44547 + "replay window size: %d -- must be 0 <= size <= 64\n",
44548 + sab.sa_base.sadb_sa_replay);
44549 + SENDERR(EINVAL);
44550 + }
44551 +
44552 + if(sab.sa_base.sadb_sa_auth > SADB_AALG_MAX) {
44553 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44554 + "pfkey_sa_build: "
44555 + "auth=%d > SADB_AALG_MAX=%d.\n",
44556 + sab.sa_base.sadb_sa_auth,
44557 + SADB_AALG_MAX);
44558 + SENDERR(EINVAL);
44559 + }
44560 +
44561 +#if K_SADB_EALG_MAX < 255
44562 + if(sab.sa_base.sadb_sa_encrypt > K_SADB_EALG_MAX) {
44563 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44564 + "pfkey_sa_build: "
44565 + "encrypt=%d > K_SADB_EALG_MAX=%d.\n",
44566 + sab.sa_base.sadb_sa_encrypt,
44567 + K_SADB_EALG_MAX);
44568 + SENDERR(EINVAL);
44569 + }
44570 +#endif
44571 +
44572 + if(sab.sa_base.sadb_sa_state > K_SADB_SASTATE_MAX) {
44573 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44574 + "pfkey_sa_build: "
44575 + "sa_state=%d exceeds MAX=%d.\n",
44576 + sab.sa_base.sadb_sa_state,
44577 + K_SADB_SASTATE_MAX);
44578 + SENDERR(EINVAL);
44579 + }
44580 +
44581 + if(sab.sa_base.sadb_sa_state == K_SADB_SASTATE_DEAD) {
44582 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44583 + "pfkey_sa_build: "
44584 + "sa_state=%d is DEAD=%d is not allowed.\n",
44585 + sab.sa_base.sadb_sa_state,
44586 + K_SADB_SASTATE_DEAD);
44587 + SENDERR(EINVAL);
44588 + }
44589 +
44590 + if((IPSEC_SAREF_NULL != sab.sa_base.sadb_x_sa_ref) && (sab.sa_base.sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
44591 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44592 + "pfkey_sa_build: "
44593 + "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
44594 + sab.sa_base.sadb_x_sa_ref,
44595 + IPSEC_SAREF_NULL,
44596 + IPSEC_SA_REF_TABLE_NUM_ENTRIES);
44597 + SENDERR(EINVAL);
44598 + }
44599 +
44600 + pfkey_sa = (struct k_sadb_sa*)MALLOC(sizeof(struct k_sadb_sa));
44601 + *pfkey_ext = (struct sadb_ext*)pfkey_sa;
44602 +
44603 + if(pfkey_sa == NULL) {
44604 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44605 + "pfkey_sa_build: "
44606 + "memory allocation failed\n");
44607 + SENDERR(ENOMEM);
44608 + }
44609 + memset(pfkey_sa, 0, sizeof(struct k_sadb_sa));
44610 +
44611 + *pfkey_sa = sab.sa_base;
44612 + pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN;
44613 +
44614 +errlab:
44615 + return error;
44616 +}
44617 +
44618 +int
44619 +pfkey_sa_build(struct sadb_ext ** pfkey_ext,
44620 + uint16_t exttype,
44621 + uint32_t spi,
44622 + uint8_t replay_window,
44623 + uint8_t sa_state,
44624 + uint8_t auth,
44625 + uint8_t encrypt,
44626 + uint32_t flags)
44627 +{
44628 + struct sadb_builds sab;
44629 +
44630 + memset(&sab, 0, sizeof(sab));
44631 + sab.sa_base.sadb_sa_exttype = exttype;
44632 + sab.sa_base.sadb_sa_spi = spi;
44633 + sab.sa_base.sadb_sa_replay = replay_window;
44634 + sab.sa_base.sadb_sa_state = sa_state;
44635 + sab.sa_base.sadb_sa_auth = auth;
44636 + sab.sa_base.sadb_sa_encrypt = encrypt;
44637 + sab.sa_base.sadb_sa_flags = flags;
44638 + sab.sa_base.sadb_x_sa_ref = IPSEC_SAREF_NULL;
44639 +
44640 + return pfkey_sa_builds(pfkey_ext, sab);
44641 +}
44642 +
44643 +int
44644 +pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
44645 + uint16_t exttype,
44646 + uint32_t allocations,
44647 + uint64_t bytes,
44648 + uint64_t addtime,
44649 + uint64_t usetime,
44650 + uint32_t packets)
44651 +{
44652 + int error = 0;
44653 + struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext;
44654 +
44655 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44656 + "pfkey_lifetime_build:\n");
44657 + /* sanity checks... */
44658 + if(pfkey_lifetime) {
44659 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44660 + "pfkey_lifetime_build: "
44661 + "why is pfkey_lifetime already pointing to something?\n");
44662 + SENDERR(EINVAL);
44663 + }
44664 +
44665 + if(exttype != SADB_EXT_LIFETIME_CURRENT &&
44666 + exttype != SADB_EXT_LIFETIME_HARD &&
44667 + exttype != SADB_EXT_LIFETIME_SOFT) {
44668 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44669 + "pfkey_lifetime_build: "
44670 + "invalid exttype=%d.\n",
44671 + exttype);
44672 + SENDERR(EINVAL);
44673 + }
44674 +
44675 + pfkey_lifetime = (struct sadb_lifetime*)MALLOC(sizeof(struct sadb_lifetime));
44676 + *pfkey_ext = (struct sadb_ext*) pfkey_lifetime;
44677 +
44678 + if(pfkey_lifetime == NULL) {
44679 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44680 + "pfkey_lifetime_build: "
44681 + "memory allocation failed\n");
44682 + SENDERR(ENOMEM);
44683 + }
44684 + memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime));
44685 +
44686 + pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN;
44687 + pfkey_lifetime->sadb_lifetime_exttype = exttype;
44688 + pfkey_lifetime->sadb_lifetime_allocations = allocations;
44689 + pfkey_lifetime->sadb_lifetime_bytes = bytes;
44690 + pfkey_lifetime->sadb_lifetime_addtime = addtime;
44691 + pfkey_lifetime->sadb_lifetime_usetime = usetime;
44692 +#ifdef NOT_YET
44693 + /* XXX it is defined in struct sadb_lifetime, but not found?? */
44694 + pfkey_lifetime->sadb_x_lifetime_packets = packets;
44695 +#endif
44696 +
44697 +errlab:
44698 + return error;
44699 +}
44700 +
44701 +int
44702 +pfkey_address_build(struct sadb_ext** pfkey_ext,
44703 + uint16_t exttype,
44704 + uint8_t proto,
44705 + uint8_t prefixlen,
44706 + struct sockaddr* address)
44707 +{
44708 + int error = 0;
44709 + int saddr_len = 0;
44710 + char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/];
44711 + struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext;
44712 +
44713 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44714 + "pfkey_address_build: "
44715 + "exttype=%d proto=%d prefixlen=%d\n",
44716 + exttype,
44717 + proto,
44718 + prefixlen);
44719 + /* sanity checks... */
44720 + if(pfkey_address) {
44721 + ERROR("pfkey_address_build: "
44722 + "why is pfkey_address already pointing to something?\n");
44723 + SENDERR(EINVAL);
44724 + }
44725 +
44726 + if (!address) {
44727 + ERROR("pfkey_address_build: " "address is NULL\n");
44728 + SENDERR(EINVAL);
44729 + }
44730 +
44731 + switch(exttype) {
44732 + case SADB_EXT_ADDRESS_SRC:
44733 + case SADB_EXT_ADDRESS_DST:
44734 + case SADB_EXT_ADDRESS_PROXY:
44735 + case K_SADB_X_EXT_ADDRESS_DST2:
44736 + case K_SADB_X_EXT_ADDRESS_SRC_FLOW:
44737 + case K_SADB_X_EXT_ADDRESS_DST_FLOW:
44738 + case K_SADB_X_EXT_ADDRESS_SRC_MASK:
44739 + case K_SADB_X_EXT_ADDRESS_DST_MASK:
44740 +#ifdef NAT_TRAVERSAL
44741 + case K_SADB_X_EXT_NAT_T_OA:
44742 +#endif
44743 + break;
44744 + default:
44745 + ERROR("pfkey_address_build: "
44746 + "unrecognised ext_type=%d.\n",
44747 + exttype);
44748 + SENDERR(EINVAL);
44749 + }
44750 +
44751 + switch(address->sa_family) {
44752 + case AF_INET:
44753 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44754 + "pfkey_address_build: "
44755 + "found address family AF_INET.\n");
44756 + saddr_len = sizeof(struct sockaddr_in);
44757 + sprintf(ipaddr_txt, "%d.%d.%d.%d:%d"
44758 + , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 0) & 0xFF
44759 + , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 8) & 0xFF
44760 + , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF
44761 + , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF
44762 + , ntohs(((struct sockaddr_in*)address)->sin_port));
44763 + break;
44764 + case AF_INET6:
44765 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44766 + "pfkey_address_build: "
44767 + "found address family AF_INET6.\n");
44768 + saddr_len = sizeof(struct sockaddr_in6);
44769 + sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x"
44770 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0])
44771 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1])
44772 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2])
44773 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3])
44774 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4])
44775 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5])
44776 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6])
44777 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7])
44778 + , ntohs(((struct sockaddr_in6*)address)->sin6_port));
44779 + break;
44780 + default:
44781 + ERROR("pfkey_address_build: "
44782 + "address->sa_family=%d not supported.\n",
44783 + address->sa_family);
44784 + SENDERR(EPFNOSUPPORT);
44785 + }
44786 +
44787 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44788 + "pfkey_address_build: "
44789 + "found address=%s.\n",
44790 + ipaddr_txt);
44791 + if(prefixlen != 0) {
44792 + ERROR("pfkey_address_build: "
44793 + "address prefixes not supported yet.\n");
44794 + SENDERR(EAFNOSUPPORT); /* not supported yet */
44795 + }
44796 +
44797 + /* allocate some memory for the extension */
44798 + pfkey_address = (struct sadb_address*)
44799 + MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN));
44800 + *pfkey_ext = (struct sadb_ext*)pfkey_address;
44801 +
44802 + if(pfkey_address == NULL ) {
44803 + ERROR("pfkey_lifetime_build: "
44804 + "memory allocation failed\n");
44805 + SENDERR(ENOMEM);
44806 + }
44807 + memset(pfkey_address,
44808 + 0,
44809 + ALIGN_N(sizeof(struct sadb_address) + saddr_len,
44810 + IPSEC_PFKEYv2_ALIGN));
44811 +
44812 + pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len,
44813 + IPSEC_PFKEYv2_ALIGN);
44814 +
44815 + pfkey_address->sadb_address_exttype = exttype;
44816 + pfkey_address->sadb_address_proto = proto;
44817 + pfkey_address->sadb_address_prefixlen = prefixlen;
44818 + pfkey_address->sadb_address_reserved = 0;
44819 +
44820 + memcpy((char*)pfkey_address + sizeof(struct sadb_address),
44821 + address,
44822 + saddr_len);
44823 +
44824 +#if 0
44825 + for(i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) {
44826 + pfkey_address_s_ska.sin_zero[i] = 0;
44827 + }
44828 +#endif
44829 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44830 + "pfkey_address_build: "
44831 + "successful created len: %d.\n", pfkey_address->sadb_address_len);
44832 +
44833 + errlab:
44834 + return error;
44835 +}
44836 +
44837 +int
44838 +pfkey_key_build(struct sadb_ext** pfkey_ext,
44839 + uint16_t exttype,
44840 + uint16_t key_bits,
44841 + unsigned char * key)
44842 +{
44843 + int error = 0;
44844 + struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext;
44845 +
44846 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44847 + "pfkey_key_build:\n");
44848 + /* sanity checks... */
44849 + if(pfkey_key) {
44850 + ERROR("pfkey_key_build: "
44851 + "why is pfkey_key already pointing to something?\n");
44852 + SENDERR(EINVAL);
44853 + }
44854 +
44855 + if(!key_bits) {
44856 + ERROR("pfkey_key_build: "
44857 + "key_bits is zero, it must be non-zero.\n");
44858 + SENDERR(EINVAL);
44859 + }
44860 +
44861 + if( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) {
44862 + ERROR("pfkey_key_build: "
44863 + "unsupported extension type=%d.\n",
44864 + exttype);
44865 + SENDERR(EINVAL);
44866 + }
44867 +
44868 + pfkey_key = (struct sadb_key*)
44869 + MALLOC(sizeof(struct sadb_key) +
44870 + DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
44871 +
44872 + *pfkey_ext = (struct sadb_ext*)pfkey_key;
44873 +
44874 + if(pfkey_key == NULL) {
44875 + ERROR("pfkey_key_build: "
44876 + "memory allocation failed\n");
44877 + SENDERR(ENOMEM);
44878 + }
44879 + memset(pfkey_key,
44880 + 0,
44881 + sizeof(struct sadb_key) +
44882 + DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
44883 +
44884 + pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits,
44885 + 64);
44886 + pfkey_key->sadb_key_exttype = exttype;
44887 + pfkey_key->sadb_key_bits = key_bits;
44888 + pfkey_key->sadb_key_reserved = 0;
44889 + memcpy((char*)pfkey_key + sizeof(struct sadb_key),
44890 + key,
44891 + DIVUP(key_bits, 8));
44892 +
44893 +errlab:
44894 + return error;
44895 +}
44896 +
44897 +int
44898 +pfkey_ident_build(struct sadb_ext** pfkey_ext,
44899 + uint16_t exttype,
44900 + uint16_t ident_type,
44901 + uint64_t ident_id,
44902 + uint8_t ident_len,
44903 + char* ident_string)
44904 +{
44905 + int error = 0;
44906 + struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext;
44907 + int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
44908 +
44909 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44910 + "pfkey_ident_build:\n");
44911 + /* sanity checks... */
44912 + if(pfkey_ident) {
44913 + ERROR("pfkey_ident_build: "
44914 + "why is pfkey_ident already pointing to something?\n");
44915 + SENDERR(EINVAL);
44916 + }
44917 +
44918 + if( ! ((exttype == SADB_EXT_IDENTITY_SRC) ||
44919 + (exttype == SADB_EXT_IDENTITY_DST))) {
44920 + ERROR("pfkey_ident_build: "
44921 + "unsupported extension type=%d.\n",
44922 + exttype);
44923 + SENDERR(EINVAL);
44924 + }
44925 +
44926 + if((ident_type == SADB_IDENTTYPE_RESERVED)) {
44927 + ERROR("pfkey_ident_build: "
44928 + "ident_type must be non-zero.\n");
44929 + SENDERR(EINVAL);
44930 + }
44931 +
44932 + if(ident_type > SADB_IDENTTYPE_MAX) {
44933 + ERROR("pfkey_ident_build: "
44934 + "identtype=%d out of range.\n",
44935 + ident_type);
44936 + SENDERR(EINVAL);
44937 + }
44938 +
44939 + if(((ident_type == SADB_IDENTTYPE_PREFIX) ||
44940 + (ident_type == SADB_IDENTTYPE_FQDN)) &&
44941 + !ident_string) {
44942 + ERROR("pfkey_ident_build: "
44943 + "string required to allocate size of extension.\n");
44944 + SENDERR(EINVAL);
44945 + }
44946 +
44947 +#if 0
44948 + if((ident_type == SADB_IDENTTYPE_USERFQDN) ) {
44949 + }
44950 +#endif
44951 +
44952 + pfkey_ident = (struct sadb_ident*)
44953 + MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN);
44954 +
44955 + *pfkey_ext = (struct sadb_ext*)pfkey_ident;
44956 +
44957 + if(pfkey_ident == NULL) {
44958 + ERROR("pfkey_ident_build: "
44959 + "memory allocation failed\n");
44960 + SENDERR(ENOMEM);
44961 + }
44962 + memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN);
44963 +
44964 + pfkey_ident->sadb_ident_len = ident_len;
44965 + pfkey_ident->sadb_ident_exttype = exttype;
44966 + pfkey_ident->sadb_ident_type = ident_type;
44967 + pfkey_ident->sadb_ident_reserved = 0;
44968 + pfkey_ident->sadb_ident_id = ident_id;
44969 + memcpy((char*)pfkey_ident + sizeof(struct sadb_ident),
44970 + ident_string,
44971 + data_len);
44972 +
44973 +errlab:
44974 + return error;
44975 +}
44976 +
44977 +int
44978 +pfkey_sens_build(struct sadb_ext** pfkey_ext,
44979 + uint32_t dpd,
44980 + uint8_t sens_level,
44981 + uint8_t sens_len,
44982 + uint64_t* sens_bitmap,
44983 + uint8_t integ_level,
44984 + uint8_t integ_len,
44985 + uint64_t* integ_bitmap)
44986 +{
44987 + int error = 0;
44988 + struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext;
44989 + int i;
44990 + uint64_t* bitmap;
44991 +
44992 + DEBUGGING(PF_KEY_DEBUG_BUILD,
44993 + "pfkey_sens_build:\n");
44994 + /* sanity checks... */
44995 + if(pfkey_sens) {
44996 + ERROR("pfkey_sens_build: "
44997 + "why is pfkey_sens already pointing to something?\n");
44998 + SENDERR(EINVAL);
44999 + }
45000 +
45001 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45002 + "pfkey_sens_build: "
45003 + "Sorry, I can't build exttype=%d yet.\n",
45004 + (*pfkey_ext)->sadb_ext_type);
45005 + SENDERR(EINVAL); /* don't process these yet */
45006 +
45007 + pfkey_sens = (struct sadb_sens*)
45008 + MALLOC(sizeof(struct sadb_sens) +
45009 + (sens_len + integ_len) * sizeof(uint64_t));
45010 +
45011 + *pfkey_ext = (struct sadb_ext*)pfkey_sens;
45012 +
45013 + if(pfkey_sens == NULL) {
45014 + ERROR("pfkey_sens_build: "
45015 + "memory allocation failed\n");
45016 + SENDERR(ENOMEM);
45017 + }
45018 + memset(pfkey_sens,
45019 + 0,
45020 + sizeof(struct sadb_sens) +
45021 + (sens_len + integ_len) * sizeof(uint64_t));
45022 +
45023 + pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) +
45024 + (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN;
45025 + pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY;
45026 + pfkey_sens->sadb_sens_dpd = dpd;
45027 + pfkey_sens->sadb_sens_sens_level = sens_level;
45028 + pfkey_sens->sadb_sens_sens_len = sens_len;
45029 + pfkey_sens->sadb_sens_integ_level = integ_level;
45030 + pfkey_sens->sadb_sens_integ_len = integ_len;
45031 + pfkey_sens->sadb_sens_reserved = 0;
45032 +
45033 + bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens));
45034 + for(i = 0; i < sens_len; i++) {
45035 + *bitmap = sens_bitmap[i];
45036 + bitmap++;
45037 + }
45038 + for(i = 0; i < integ_len; i++) {
45039 + *bitmap = integ_bitmap[i];
45040 + bitmap++;
45041 + }
45042 +
45043 +errlab:
45044 + return error;
45045 +}
45046 +
45047 +int
45048 +pfkey_prop_build(struct sadb_ext** pfkey_ext,
45049 + uint8_t replay,
45050 + unsigned int comb_num,
45051 + struct sadb_comb* comb)
45052 +{
45053 + int error = 0;
45054 + int i;
45055 + struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext;
45056 + struct sadb_comb *combp;
45057 +
45058 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45059 + "pfkey_prop_build:\n");
45060 + /* sanity checks... */
45061 + if(pfkey_prop) {
45062 + ERROR("pfkey_prop_build: "
45063 + "why is pfkey_prop already pointing to something?\n");
45064 + SENDERR(EINVAL);
45065 + }
45066 +
45067 + pfkey_prop = (struct sadb_prop*)
45068 + MALLOC(sizeof(struct sadb_prop) +
45069 + comb_num * sizeof(struct sadb_comb));
45070 +
45071 + *pfkey_ext = (struct sadb_ext*)pfkey_prop;
45072 +
45073 + if(pfkey_prop == NULL) {
45074 + ERROR("pfkey_prop_build: "
45075 + "memory allocation failed\n");
45076 + SENDERR(ENOMEM);
45077 + }
45078 + memset(pfkey_prop,
45079 + 0,
45080 + sizeof(struct sadb_prop) +
45081 + comb_num * sizeof(struct sadb_comb));
45082 +
45083 + pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
45084 + comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN;
45085 +
45086 + pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
45087 + pfkey_prop->sadb_prop_replay = replay;
45088 +
45089 + for(i=0; i<3; i++) {
45090 + pfkey_prop->sadb_prop_reserved[i] = 0;
45091 + }
45092 +
45093 + combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop));
45094 + for(i = 0; i < comb_num; i++) {
45095 + memcpy (combp, &(comb[i]), sizeof(struct sadb_comb));
45096 + combp++;
45097 + }
45098 +
45099 +#if 0
45100 + uint8_t sadb_comb_auth;
45101 + uint8_t sadb_comb_encrypt;
45102 + uint16_t sadb_comb_flags;
45103 + uint16_t sadb_comb_auth_minbits;
45104 + uint16_t sadb_comb_auth_maxbits;
45105 + uint16_t sadb_comb_encrypt_minbits;
45106 + uint16_t sadb_comb_encrypt_maxbits;
45107 + uint32_t sadb_comb_reserved;
45108 + uint32_t sadb_comb_soft_allocations;
45109 + uint32_t sadb_comb_hard_allocations;
45110 + uint64_t sadb_comb_soft_bytes;
45111 + uint64_t sadb_comb_hard_bytes;
45112 + uint64_t sadb_comb_soft_addtime;
45113 + uint64_t sadb_comb_hard_addtime;
45114 + uint64_t sadb_comb_soft_usetime;
45115 + uint64_t sadb_comb_hard_usetime;
45116 + uint32_t sadb_comb_soft_packets;
45117 + uint32_t sadb_comb_hard_packets;
45118 +#endif
45119 +errlab:
45120 + return error;
45121 +}
45122 +
45123 +int
45124 +pfkey_supported_build(struct sadb_ext** pfkey_ext,
45125 + uint16_t exttype,
45126 + unsigned int alg_num,
45127 + struct sadb_alg* alg)
45128 +{
45129 + int error = 0;
45130 + unsigned int i;
45131 + struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext;
45132 + struct sadb_alg *pfkey_alg;
45133 +
45134 + /* sanity checks... */
45135 + if(pfkey_supported) {
45136 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45137 + "pfkey_supported_build: "
45138 + "why is pfkey_supported already pointing to something?\n");
45139 + SENDERR(EINVAL);
45140 + }
45141 +
45142 + if( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) {
45143 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45144 + "pfkey_supported_build: "
45145 + "unsupported extension type=%d.\n",
45146 + exttype);
45147 + SENDERR(EINVAL);
45148 + }
45149 +
45150 + pfkey_supported = (struct sadb_supported*)
45151 + MALLOC(sizeof(struct sadb_supported) +
45152 + alg_num *
45153 + sizeof(struct sadb_alg));
45154 +
45155 + *pfkey_ext = (struct sadb_ext*)pfkey_supported;
45156 +
45157 + if(pfkey_supported == NULL) {
45158 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45159 + "pfkey_supported_build: "
45160 + "memory allocation failed\n");
45161 + SENDERR(ENOMEM);
45162 + }
45163 + memset(pfkey_supported,
45164 + 0,
45165 + sizeof(struct sadb_supported) +
45166 + alg_num *
45167 + sizeof(struct sadb_alg));
45168 +
45169 + pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) +
45170 + alg_num *
45171 + sizeof(struct sadb_alg)) /
45172 + IPSEC_PFKEYv2_ALIGN;
45173 + pfkey_supported->sadb_supported_exttype = exttype;
45174 + pfkey_supported->sadb_supported_reserved = 0;
45175 +
45176 + pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported));
45177 + for(i = 0; i < alg_num; i++) {
45178 + memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg));
45179 + pfkey_alg->sadb_alg_reserved = 0;
45180 + pfkey_alg++;
45181 + }
45182 +
45183 +#if 0
45184 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45185 + "pfkey_supported_build: "
45186 + "Sorry, I can't build exttype=%d yet.\n",
45187 + (*pfkey_ext)->sadb_ext_type);
45188 + SENDERR(EINVAL); /* don't process these yet */
45189 +
45190 + uint8_t sadb_alg_id;
45191 + uint8_t sadb_alg_ivlen;
45192 + uint16_t sadb_alg_minbits;
45193 + uint16_t sadb_alg_maxbits;
45194 + uint16_t sadb_alg_reserved;
45195 +#endif
45196 +errlab:
45197 + return error;
45198 +}
45199 +
45200 +int
45201 +pfkey_spirange_build(struct sadb_ext** pfkey_ext,
45202 + uint16_t exttype,
45203 + uint32_t min, /* in network order */
45204 + uint32_t max) /* in network order */
45205 +{
45206 + int error = 0;
45207 + struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext;
45208 +
45209 + /* sanity checks... */
45210 + if(pfkey_spirange) {
45211 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45212 + "pfkey_spirange_build: "
45213 + "why is pfkey_spirange already pointing to something?\n");
45214 + SENDERR(EINVAL);
45215 + }
45216 +
45217 + if(ntohl(max) < ntohl(min)) {
45218 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45219 + "pfkey_spirange_build: "
45220 + "minspi=%08x must be < maxspi=%08x.\n",
45221 + ntohl(min),
45222 + ntohl(max));
45223 + SENDERR(EINVAL);
45224 + }
45225 +
45226 + if(ntohl(min) <= 255) {
45227 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45228 + "pfkey_spirange_build: "
45229 + "minspi=%08x must be > 255.\n",
45230 + ntohl(min));
45231 + SENDERR(EEXIST);
45232 + }
45233 +
45234 + pfkey_spirange = (struct sadb_spirange*)
45235 + MALLOC(sizeof(struct sadb_spirange));
45236 +
45237 + *pfkey_ext = (struct sadb_ext*)pfkey_spirange;
45238 +
45239 + if(pfkey_spirange == NULL) {
45240 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45241 + "pfkey_spirange_build: "
45242 + "memory allocation failed\n");
45243 + SENDERR(ENOMEM);
45244 + }
45245 + memset(pfkey_spirange,
45246 + 0,
45247 + sizeof(struct sadb_spirange));
45248 +
45249 + pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN;
45250 +
45251 + pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
45252 + pfkey_spirange->sadb_spirange_min = min;
45253 + pfkey_spirange->sadb_spirange_max = max;
45254 + pfkey_spirange->sadb_spirange_reserved = 0;
45255 + errlab:
45256 + return error;
45257 +}
45258 +
45259 +int
45260 +pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext)
45261 +{
45262 + int error = 0;
45263 + struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext;
45264 +
45265 + /* sanity checks... */
45266 + if(pfkey_x_kmprivate) {
45267 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45268 + "pfkey_x_kmprivate_build: "
45269 + "why is pfkey_x_kmprivate already pointing to something?\n");
45270 + SENDERR(EINVAL);
45271 + }
45272 +
45273 + pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
45274 +
45275 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45276 + "pfkey_x_kmprivate_build: "
45277 + "Sorry, I can't build exttype=%d yet.\n",
45278 + (*pfkey_ext)->sadb_ext_type);
45279 + SENDERR(EINVAL); /* don't process these yet */
45280 +
45281 + pfkey_x_kmprivate = (struct sadb_x_kmprivate*)
45282 + MALLOC(sizeof(struct sadb_x_kmprivate));
45283 +
45284 + *pfkey_ext = (struct sadb_ext*)pfkey_x_kmprivate;
45285 +
45286 + if(pfkey_x_kmprivate == NULL) {
45287 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45288 + "pfkey_x_kmprivate_build: "
45289 + "memory allocation failed\n");
45290 + SENDERR(ENOMEM);
45291 + }
45292 + memset(pfkey_x_kmprivate,
45293 + 0,
45294 + sizeof(struct sadb_x_kmprivate));
45295 +
45296 + pfkey_x_kmprivate->sadb_x_kmprivate_len =
45297 + sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN;
45298 +
45299 + pfkey_x_kmprivate->sadb_x_kmprivate_exttype = K_SADB_X_EXT_KMPRIVATE;
45300 + pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
45301 +errlab:
45302 + return error;
45303 +}
45304 +
45305 +int
45306 +pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
45307 + uint8_t satype)
45308 +{
45309 + int error = 0;
45310 + int i;
45311 + struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext;
45312 +
45313 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45314 + "pfkey_x_satype_build:\n");
45315 + /* sanity checks... */
45316 + if(pfkey_x_satype) {
45317 + ERROR("pfkey_x_satype_build: "
45318 + "why is pfkey_x_satype already pointing to something?\n");
45319 + SENDERR(EINVAL);
45320 + }
45321 +
45322 + if(!satype) {
45323 + ERROR("pfkey_x_satype_build: "
45324 + "SA type not set, must be non-zero.\n");
45325 + SENDERR(EINVAL);
45326 + }
45327 +
45328 + if(satype > K_SADB_SATYPE_MAX) {
45329 + ERROR("pfkey_x_satype_build: "
45330 + "satype %d > max %d\n",
45331 + satype, K_SADB_SATYPE_MAX);
45332 + SENDERR(EINVAL);
45333 + }
45334 +
45335 + pfkey_x_satype = (struct sadb_x_satype*)
45336 + MALLOC(sizeof(struct sadb_x_satype));
45337 +
45338 + *pfkey_ext = (struct sadb_ext*)pfkey_x_satype;
45339 + if(pfkey_x_satype == NULL) {
45340 + ERROR("pfkey_x_satype_build: "
45341 + "memory allocation failed\n");
45342 + SENDERR(ENOMEM);
45343 + }
45344 + memset(pfkey_x_satype,
45345 + 0,
45346 + sizeof(struct sadb_x_satype));
45347 +
45348 + pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN;
45349 +
45350 + pfkey_x_satype->sadb_x_satype_exttype = K_SADB_X_EXT_SATYPE2;
45351 + pfkey_x_satype->sadb_x_satype_satype = satype;
45352 + for(i=0; i<3; i++) {
45353 + pfkey_x_satype->sadb_x_satype_reserved[i] = 0;
45354 + }
45355 +
45356 +errlab:
45357 + return error;
45358 +}
45359 +
45360 +int
45361 +pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
45362 + uint32_t tunnel,
45363 + uint32_t netlink,
45364 + uint32_t xform,
45365 + uint32_t eroute,
45366 + uint32_t spi,
45367 + uint32_t radij,
45368 + uint32_t esp,
45369 + uint32_t ah,
45370 + uint32_t rcv,
45371 + uint32_t pfkey,
45372 + uint32_t ipcomp,
45373 + uint32_t verbose)
45374 +{
45375 + int error = 0;
45376 + int i;
45377 + struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext;
45378 +
45379 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45380 + "pfkey_x_debug_build:\n");
45381 + /* sanity checks... */
45382 + if(pfkey_x_debug) {
45383 + ERROR("pfkey_x_debug_build: "
45384 + "why is pfkey_x_debug already pointing to something?\n");
45385 + SENDERR(EINVAL);
45386 + }
45387 +
45388 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45389 + "pfkey_x_debug_build: "
45390 + "tunnel=%x netlink=%x xform=%x eroute=%x spi=%x radij=%x esp=%x ah=%x rcv=%x pfkey=%x ipcomp=%x verbose=%x?\n",
45391 + tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose);
45392 +
45393 + pfkey_x_debug = (struct sadb_x_debug*)
45394 + MALLOC(sizeof(struct sadb_x_debug));
45395 +
45396 + *pfkey_ext = (struct sadb_ext*)pfkey_x_debug;
45397 +
45398 + if(pfkey_x_debug == NULL) {
45399 + ERROR("pfkey_x_debug_build: "
45400 + "memory allocation failed\n");
45401 + SENDERR(ENOMEM);
45402 + }
45403 +#if 0
45404 + memset(pfkey_x_debug,
45405 + 0,
45406 + sizeof(struct sadb_x_debug));
45407 +#endif
45408 +
45409 + pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN;
45410 + pfkey_x_debug->sadb_x_debug_exttype = K_SADB_X_EXT_DEBUG;
45411 +
45412 + pfkey_x_debug->sadb_x_debug_tunnel = tunnel;
45413 + pfkey_x_debug->sadb_x_debug_netlink = netlink;
45414 + pfkey_x_debug->sadb_x_debug_xform = xform;
45415 + pfkey_x_debug->sadb_x_debug_eroute = eroute;
45416 + pfkey_x_debug->sadb_x_debug_spi = spi;
45417 + pfkey_x_debug->sadb_x_debug_radij = radij;
45418 + pfkey_x_debug->sadb_x_debug_esp = esp;
45419 + pfkey_x_debug->sadb_x_debug_ah = ah;
45420 + pfkey_x_debug->sadb_x_debug_rcv = rcv;
45421 + pfkey_x_debug->sadb_x_debug_pfkey = pfkey;
45422 + pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp;
45423 + pfkey_x_debug->sadb_x_debug_verbose = verbose;
45424 +
45425 + for(i=0; i<4; i++) {
45426 + pfkey_x_debug->sadb_x_debug_reserved[i] = 0;
45427 + }
45428 +
45429 +errlab:
45430 + return error;
45431 +}
45432 +
45433 +int
45434 +pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
45435 + uint8_t type)
45436 +{
45437 + int error = 0;
45438 + int i;
45439 + struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)*pfkey_ext;
45440 +
45441 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45442 + "pfkey_x_nat_t_type_build:\n");
45443 + /* sanity checks... */
45444 + if(pfkey_x_nat_t_type) {
45445 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45446 + "pfkey_x_nat_t_type_build: "
45447 + "why is pfkey_x_nat_t_type already pointing to something?\n");
45448 + SENDERR(EINVAL);
45449 + }
45450 +
45451 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45452 + "pfkey_x_nat_t_type_build: "
45453 + "type=%d\n", type);
45454 +
45455 + pfkey_x_nat_t_type = (struct sadb_x_nat_t_type*)
45456 + MALLOC(sizeof(struct sadb_x_nat_t_type));
45457 +
45458 + *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_type;
45459 +
45460 + if(pfkey_x_nat_t_type == NULL) {
45461 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45462 + "pfkey_x_nat_t_type_build: "
45463 + "memory allocation failed\n");
45464 + SENDERR(ENOMEM);
45465 + }
45466 +
45467 + pfkey_x_nat_t_type->sadb_x_nat_t_type_len = sizeof(struct sadb_x_nat_t_type) / IPSEC_PFKEYv2_ALIGN;
45468 + pfkey_x_nat_t_type->sadb_x_nat_t_type_exttype = K_SADB_X_EXT_NAT_T_TYPE;
45469 + pfkey_x_nat_t_type->sadb_x_nat_t_type_type = type;
45470 + for(i=0; i<3; i++) {
45471 + pfkey_x_nat_t_type->sadb_x_nat_t_type_reserved[i] = 0;
45472 + }
45473 +
45474 +errlab:
45475 + return error;
45476 +}
45477 +
45478 +int
45479 +pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
45480 + uint16_t exttype,
45481 + uint16_t port)
45482 +{
45483 + int error = 0;
45484 + struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)*pfkey_ext;
45485 +
45486 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45487 + "pfkey_x_nat_t_port_build:\n");
45488 + /* sanity checks... */
45489 + if(pfkey_x_nat_t_port) {
45490 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45491 + "pfkey_x_nat_t_port_build: "
45492 + "why is pfkey_x_nat_t_port already pointing to something?\n");
45493 + SENDERR(EINVAL);
45494 + }
45495 +
45496 + switch(exttype) {
45497 + case K_SADB_X_EXT_NAT_T_SPORT:
45498 + case K_SADB_X_EXT_NAT_T_DPORT:
45499 + break;
45500 + default:
45501 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45502 + "pfkey_nat_t_port_build: "
45503 + "unrecognised ext_type=%d.\n",
45504 + exttype);
45505 + SENDERR(EINVAL);
45506 + }
45507 +
45508 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45509 + "pfkey_x_nat_t_port_build: "
45510 + "ext=%d, port=%d\n", exttype, port);
45511 +
45512 + pfkey_x_nat_t_port = (struct sadb_x_nat_t_port*)
45513 + MALLOC(sizeof(struct sadb_x_nat_t_port));
45514 +
45515 + *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_port;
45516 +
45517 + if(pfkey_x_nat_t_port == NULL) {
45518 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45519 + "pfkey_x_nat_t_port_build: "
45520 + "memory allocation failed\n");
45521 + SENDERR(ENOMEM);
45522 + }
45523 +
45524 + pfkey_x_nat_t_port->sadb_x_nat_t_port_len = sizeof(struct sadb_x_nat_t_port) / IPSEC_PFKEYv2_ALIGN;
45525 + pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype = exttype;
45526 + pfkey_x_nat_t_port->sadb_x_nat_t_port_port = port;
45527 + pfkey_x_nat_t_port->sadb_x_nat_t_port_reserved = 0;
45528 +
45529 +errlab:
45530 + return error;
45531 +}
45532 +
45533 +int pfkey_x_protocol_build(struct sadb_ext **pfkey_ext,
45534 + uint8_t protocol)
45535 +{
45536 + int error = 0;
45537 + struct sadb_protocol * p = (struct sadb_protocol *)*pfkey_ext;
45538 + DEBUGGING(PF_KEY_DEBUG_BUILD,"pfkey_x_protocol_build: protocol=%u\n", protocol);
45539 + /* sanity checks... */
45540 + if (p != 0) {
45541 + ERROR("pfkey_x_protocol_build: bogus protocol pointer\n");
45542 + SENDERR(EINVAL);
45543 + }
45544 + if ((p = (struct sadb_protocol*)MALLOC(sizeof(*p))) == 0) {
45545 + ERROR("pfkey_build: memory allocation failed\n");
45546 + SENDERR(ENOMEM);
45547 + }
45548 + *pfkey_ext = (struct sadb_ext *)p;
45549 + p->sadb_protocol_len = sizeof(*p) / IPSEC_PFKEYv2_ALIGN;
45550 + p->sadb_protocol_exttype = K_SADB_X_EXT_PROTOCOL;
45551 + p->sadb_protocol_proto = protocol;
45552 + p->sadb_protocol_flags = 0;
45553 + p->sadb_protocol_reserved2 = 0;
45554 + errlab:
45555 + return error;
45556 +}
45557 +
45558 +int pfkey_outif_build(struct sadb_ext **pfkey_ext,
45559 + uint16_t outif)
45560 +{
45561 + int error = 0;
45562 + struct sadb_x_plumbif * p = (struct sadb_x_plumbif *)*pfkey_ext;
45563 +
45564 + if ((p = (struct sadb_x_plumbif*)MALLOC(sizeof(*p))) == 0) {
45565 + ERROR("pfkey_build: memory allocation failed\n");
45566 + SENDERR(ENOMEM);
45567 + }
45568 + *pfkey_ext = (struct sadb_ext *)p;
45569 +
45570 + p->sadb_x_outif_len = IPSEC_PFKEYv2_WORDS(sizeof(*p));
45571 + p->sadb_x_outif_exttype = K_SADB_X_EXT_PLUMBIF;
45572 + p->sadb_x_outif_ifnum = outif;
45573 +
45574 + errlab:
45575 + return error;
45576 +}
45577 +
45578 +
45579 +int pfkey_saref_build(struct sadb_ext **pfkey_ext,
45580 + IPsecSAref_t in, IPsecSAref_t out)
45581 +{
45582 + int error = 0;
45583 + struct sadb_x_saref* s;
45584 +
45585 + /* +4 because sadb_x_saref is not a multiple of 8 bytes */
45586 +
45587 + if ((s = (struct sadb_x_saref*)MALLOC(sizeof(*s)+4)) == 0) {
45588 + ERROR("pfkey_build: memory allocation failed\n");
45589 + SENDERR(ENOMEM);
45590 + }
45591 + *pfkey_ext = (struct sadb_ext *)s;
45592 +
45593 + s->sadb_x_saref_len = IPSEC_PFKEYv2_WORDS(sizeof(*s));
45594 + s->sadb_x_saref_exttype = K_SADB_X_EXT_SAREF;
45595 + s->sadb_x_saref_me = in;
45596 + s->sadb_x_saref_him = out;
45597 +
45598 + errlab:
45599 + return error;
45600 +}
45601 +
45602 +
45603 +#if defined(I_DONT_THINK_THIS_WILL_BE_USEFUL) && I_DONT_THINK_THIS_WILL_BE_USEFUL
45604 +int (*ext_default_builders[K_SADB_EXT_MAX +1])(struct sadb_msg*, struct sadb_ext*)
45605 + =
45606 +{
45607 + NULL, /* pfkey_msg_build, */
45608 + pfkey_sa_build,
45609 + pfkey_lifetime_build,
45610 + pfkey_lifetime_build,
45611 + pfkey_lifetime_build,
45612 + pfkey_address_build,
45613 + pfkey_address_build,
45614 + pfkey_address_build,
45615 + pfkey_key_build,
45616 + pfkey_key_build,
45617 + pfkey_ident_build,
45618 + pfkey_ident_build,
45619 + pfkey_sens_build,
45620 + pfkey_prop_build,
45621 + pfkey_supported_build,
45622 + pfkey_supported_build,
45623 + pfkey_spirange_build,
45624 + pfkey_x_kmprivate_build,
45625 + pfkey_x_satype_build,
45626 + pfkey_sa_build,
45627 + pfkey_address_build,
45628 + pfkey_address_build,
45629 + pfkey_address_build,
45630 + pfkey_address_build,
45631 + pfkey_address_build,
45632 + pfkey_x_ext_debug_build
45633 +};
45634 +#endif
45635 +
45636 +int
45637 +pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir)
45638 +{
45639 + int error = 0;
45640 + unsigned ext;
45641 + unsigned total_size;
45642 + struct sadb_ext *pfkey_ext;
45643 + pfkey_ext_track extensions_seen = 0;
45644 +#ifndef __KERNEL__
45645 + struct sadb_ext *extensions_check[K_SADB_EXT_MAX + 1];
45646 +#endif
45647 +
45648 + if(!extensions[0]) {
45649 + ERROR("pfkey_msg_build: "
45650 + "extensions[0] must be specified (struct sadb_msg).\n");
45651 + SENDERR(EINVAL);
45652 + }
45653 +
45654 + /* figure out the total size for all the requested extensions */
45655 + total_size = IPSEC_PFKEYv2_WORDS(sizeof(struct sadb_msg));
45656 + for(ext = 1; ext <= K_SADB_EXT_MAX; ext++) {
45657 + if(extensions[ext]) {
45658 + total_size += (extensions[ext])->sadb_ext_len;
45659 + }
45660 + }
45661 +
45662 + /* allocate that much space */
45663 + *pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN);
45664 + if(*pfkey_msg == NULL) {
45665 + ERROR("pfkey_msg_build: "
45666 + "memory allocation failed\n");
45667 + SENDERR(ENOMEM);
45668 + }
45669 +
45670 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45671 + "pfkey_msg_build: "
45672 + "pfkey_msg=0p%p allocated %lu bytes, &(extensions[0])=0p%p\n",
45673 + *pfkey_msg,
45674 + (unsigned long)(total_size * IPSEC_PFKEYv2_ALIGN),
45675 + &(extensions[0]));
45676 +
45677 + memcpy(*pfkey_msg,
45678 + extensions[0],
45679 + sizeof(struct sadb_msg));
45680 + (*pfkey_msg)->sadb_msg_len = total_size;
45681 + (*pfkey_msg)->sadb_msg_reserved = 0;
45682 + extensions_seen = 1 ;
45683 +
45684 + /*
45685 + * point pfkey_ext to immediately after the space for the header,
45686 + * i.e. at the first extension location.
45687 + */
45688 + pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg));
45689 +
45690 + for(ext = 1; ext <= K_SADB_EXT_MAX; ext++) {
45691 + /* copy from extension[ext] to buffer */
45692 + if(extensions[ext]) {
45693 + /* Is this type of extension permitted for this type of message? */
45694 + if(!pfkey_permitted_extension(dir,(*pfkey_msg)->sadb_msg_type,ext)) {
45695 + ERROR("ext type %d not permitted for %d/%d (build)\n",
45696 + ext,
45697 + dir,(*pfkey_msg)->sadb_msg_type);
45698 + SENDERR(EINVAL);
45699 + }
45700 +
45701 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45702 + "pfkey_msg_build: "
45703 + "copying %lu bytes from extensions[%u] (type=%d)\n",
45704 + (unsigned long)(extensions[ext]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN),
45705 + ext,
45706 + extensions[ext]->sadb_ext_type);
45707 +
45708 + {
45709 + char *pfkey_ext_c = (char *)pfkey_ext;
45710 +
45711 + pfkey_ext_c += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN;
45712 +
45713 +#if 0
45714 + printf("memcpy(%p,%p,%d) -> %p %p:%p\n", pfkey_ext,
45715 + extensions[ext],
45716 + (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN,
45717 + pfkey_ext_c, (*pfkey_msg), (char *)(*pfkey_msg)+(total_size*IPSEC_PFKEYv2_ALIGN));
45718 +#endif
45719 + memcpy(pfkey_ext,
45720 + extensions[ext],
45721 + (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
45722 + pfkey_ext = (struct sadb_ext *)pfkey_ext_c;
45723 + }
45724 +
45725 + /* Mark that we have seen this extension */
45726 + pfkey_mark_extension(ext,&extensions_seen);
45727 + }
45728 + }
45729 +
45730 + if(pfkey_extensions_missing(dir,(*pfkey_msg)->sadb_msg_type,extensions_seen)) {
45731 + ERROR("required extensions missing. seen=%08llx\n", (unsigned long long)extensions_seen);
45732 + SENDERR(EINVAL);
45733 + }
45734 +
45735 +#ifndef __KERNEL__
45736 +/*
45737 + * this is silly, there is no need to reparse the message that we just built.
45738 + *
45739 + */
45740 + if((error = pfkey_msg_parse(*pfkey_msg,NULL,extensions_check, dir))) {
45741 + ERROR("pfkey_msg_build: "
45742 + "Trouble parsing newly built pfkey message, error=%d.\n",
45743 + error);
45744 + SENDERR(-error);
45745 + }
45746 +#endif
45747 +
45748 +errlab:
45749 +
45750 + return error;
45751 +}
45752 +
45753 +/*
45754 + *
45755 + * Local Variables:
45756 + * c-file-style: "linux"
45757 + * End:
45758 + *
45759 + */
45760 --- /dev/null Tue Mar 11 13:02:56 2003
45761 +++ linux/net/ipsec/pfkey_v2_debug.c Mon Feb 9 13:51:03 2004
45762 @@ -0,0 +1,144 @@
45763 +/*
45764 + * @(#) pfkey version 2 debugging messages
45765 + *
45766 + * Copyright (C) 2001 Richard Guy Briggs <rgb@openswan.org>
45767 + * and Michael Richardson <mcr@openswan.org>
45768 + *
45769 + * This program is free software; you can redistribute it and/or modify it
45770 + * under the terms of the GNU General Public License as published by the
45771 + * Free Software Foundation; either version 2 of the License, or (at your
45772 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
45773 + *
45774 + * This program is distributed in the hope that it will be useful, but
45775 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
45776 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
45777 + * for more details.
45778 + *
45779 + * RCSID $Id: pfkey_v2_debug.c,v 1.11 2005/04/06 17:45:16 mcr Exp $
45780 + *
45781 + */
45782 +
45783 +#ifdef __KERNEL__
45784 +
45785 +# include <linux/kernel.h> /* for printk */
45786 +
45787 +# include "openswan/ipsec_kversion.h" /* for malloc switch */
45788 +# ifdef MALLOC_SLAB
45789 +# include <linux/slab.h> /* kmalloc() */
45790 +# else /* MALLOC_SLAB */
45791 +# include <linux/malloc.h> /* kmalloc() */
45792 +# endif /* MALLOC_SLAB */
45793 +# include <linux/errno.h> /* error codes */
45794 +# include <linux/types.h> /* size_t */
45795 +# include <linux/interrupt.h> /* mark_bh */
45796 +
45797 +# include <linux/netdevice.h> /* struct device, and other headers */
45798 +# include <linux/etherdevice.h> /* eth_type_trans */
45799 +extern int debug_pfkey;
45800 +
45801 +#else /* __KERNEL__ */
45802 +
45803 +#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
45804 +# include <sys/types.h>
45805 +#else
45806 +# include <sys/types.h>
45807 +# include <linux/types.h>
45808 +# include <linux/errno.h>
45809 +#endif
45810 +
45811 +#endif /* __KERNEL__ */
45812 +
45813 +#include "openswan.h"
45814 +#include "openswan/pfkeyv2.h"
45815 +#include "openswan/pfkey.h"
45816 +
45817 +/*
45818 + * This file provides ASCII translations of PF_KEY magic numbers.
45819 + *
45820 + */
45821 +
45822 +static char *pfkey_sadb_ext_strings[]={
45823 + "reserved", /* K_SADB_EXT_RESERVED 0 */
45824 + "security-association", /* K_SADB_EXT_SA 1 */
45825 + "lifetime-current", /* K_SADB_EXT_LIFETIME_CURRENT 2 */
45826 + "lifetime-hard", /* K_SADB_EXT_LIFETIME_HARD 3 */
45827 + "lifetime-soft", /* K_SADB_EXT_LIFETIME_SOFT 4 */
45828 + "source-address", /* K_SADB_EXT_ADDRESS_SRC 5 */
45829 + "destination-address", /* K_SADB_EXT_ADDRESS_DST 6 */
45830 + "proxy-address", /* K_SADB_EXT_ADDRESS_PROXY 7 */
45831 + "authentication-key", /* K_SADB_EXT_KEY_AUTH 8 */
45832 + "cipher-key", /* K_SADB_EXT_KEY_ENCRYPT 9 */
45833 + "source-identity", /* K_SADB_EXT_IDENTITY_SRC 10 */
45834 + "destination-identity", /* K_SADB_EXT_IDENTITY_DST 11 */
45835 + "sensitivity-label", /* K_SADB_EXT_SENSITIVITY 12 */
45836 + "proposal", /* K_SADB_EXT_PROPOSAL 13 */
45837 + "supported-auth", /* K_SADB_EXT_SUPPORTED_AUTH 14 */
45838 + "supported-cipher", /* K_SADB_EXT_SUPPORTED_ENCRYPT 15 */
45839 + "spi-range", /* K_SADB_EXT_SPIRANGE 16 */
45840 + "X-kmpprivate", /* K_SADB_X_EXT_KMPRIVATE 17 */
45841 + "X-satype2", /* K_SADB_X_EXT_SATYPE2 18 */
45842 + "X-security-association", /* K_SADB_X_EXT_SA2 19 */
45843 + "X-destination-address2", /* K_SADB_X_EXT_ADDRESS_DST2 20 */
45844 + "X-source-flow-address", /* K_SADB_X_EXT_ADDRESS_SRC_FLOW 21 */
45845 + "X-dest-flow-address", /* K_SADB_X_EXT_ADDRESS_DST_FLOW 22 */
45846 + "X-source-mask", /* K_SADB_X_EXT_ADDRESS_SRC_MASK 23 */
45847 + "X-dest-mask", /* K_SADB_X_EXT_ADDRESS_DST_MASK 24 */
45848 + "X-set-debug", /* K_SADB_X_EXT_DEBUG 25 */
45849 + /* NAT_TRAVERSAL */
45850 + "X-ext-protocol", /* K_SADB_X_EXT_PROTOCOL 26 */
45851 + "X-NAT-T-type", /* K_SADB_X_EXT_NAT_T_TYPE 27 */
45852 + "X-NAT-T-sport", /* K_SADB_X_EXT_NAT_T_SPORT 28 */
45853 + "X-NAT-T-dport", /* K_SADB_X_EXT_NAT_T_DPORT 29 */
45854 + "X-NAT-T-OA", /* K_SADB_X_EXT_NAT_T_OA 30 */
45855 + "X-plumbif", /* K_SADB_X_EXT_PLUMBIF 31 */
45856 + "X-saref", /* K_SADB_X_EXT_SAREF 32 */
45857 +};
45858 +
45859 +const char *
45860 +pfkey_v2_sadb_ext_string(int ext)
45861 +{
45862 + if(ext <= K_SADB_EXT_MAX) {
45863 + return pfkey_sadb_ext_strings[ext];
45864 + } else {
45865 + return "unknown-ext";
45866 + }
45867 +}
45868 +
45869 +
45870 +static char *pfkey_sadb_type_strings[]={
45871 + "reserved", /* K_SADB_RESERVED */
45872 + "getspi", /* K_SADB_GETSPI */
45873 + "update", /* K_SADB_UPDATE */
45874 + "add", /* K_SADB_ADD */
45875 + "delete", /* K_SADB_DELETE */
45876 + "get", /* K_SADB_GET */
45877 + "acquire", /* K_SADB_ACQUIRE */
45878 + "register", /* K_SADB_REGISTER */
45879 + "expire", /* K_SADB_EXPIRE */
45880 + "flush", /* K_SADB_FLUSH */
45881 + "dump", /* K_SADB_DUMP */
45882 + "x-promisc", /* K_SADB_X_PROMISC */
45883 + "x-pchange", /* K_SADB_X_PCHANGE */
45884 + "x-groupsa", /* K_SADB_X_GRPSA */
45885 + "x-addflow(eroute)", /* K_SADB_X_ADDFLOW */
45886 + "x-delflow(eroute)", /* K_SADB_X_DELFLOW */
45887 + "x-debug", /* K_SADB_X_DEBUG */
45888 +};
45889 +
45890 +const char *
45891 +pfkey_v2_sadb_type_string(int sadb_type)
45892 +{
45893 + if(sadb_type <= K_SADB_MAX) {
45894 + return pfkey_sadb_type_strings[sadb_type];
45895 + } else {
45896 + return "unknown-sadb-type";
45897 + }
45898 +}
45899 +
45900 +/*
45901 + *
45902 + * Local Variables:
45903 + * c-file-style: "linux"
45904 + * End:
45905 + *
45906 + */
45907 --- /dev/null Tue Mar 11 13:02:56 2003
45908 +++ linux/net/ipsec/pfkey_v2_ext_bits.c Mon Feb 9 13:51:03 2004
45909 @@ -0,0 +1,814 @@
45910 +/*
45911 + * RFC2367 PF_KEYv2 Key management API message parser
45912 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
45913 + *
45914 + * This program is free software; you can redistribute it and/or modify it
45915 + * under the terms of the GNU General Public License as published by the
45916 + * Free Software Foundation; either version 2 of the License, or (at your
45917 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
45918 + *
45919 + * This program is distributed in the hope that it will be useful, but
45920 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
45921 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
45922 + * for more details.
45923 + *
45924 + * RCSID $Id: pfkey_v2_ext_bits.c,v 1.22 2005/05/11 01:45:31 mcr Exp $
45925 + */
45926 +
45927 +/*
45928 + * Template from klips/net/ipsec/ipsec/ipsec_parse.c.
45929 + */
45930 +
45931 +char pfkey_v2_ext_bits_c_version[] = "$Id: pfkey_v2_ext_bits.c,v 1.22 2005/05/11 01:45:31 mcr Exp $";
45932 +
45933 +/*
45934 + * Some ugly stuff to allow consistent debugging code for use in the
45935 + * kernel and in user space
45936 +*/
45937 +
45938 +#if defined(__KERNEL__) && defined(linux)
45939 +
45940 +# include <linux/kernel.h> /* for printk */
45941 +
45942 +# include "openswan/ipsec_kversion.h" /* for malloc switch */
45943 +# ifdef MALLOC_SLAB
45944 +# include <linux/slab.h> /* kmalloc() */
45945 +# else /* MALLOC_SLAB */
45946 +# include <linux/malloc.h> /* kmalloc() */
45947 +# endif /* MALLOC_SLAB */
45948 +# include <linux/errno.h> /* error codes */
45949 +# include <linux/types.h> /* size_t */
45950 +# include <linux/interrupt.h> /* mark_bh */
45951 +
45952 +# include <linux/netdevice.h> /* struct device, and other headers */
45953 +# include <linux/etherdevice.h> /* eth_type_trans */
45954 +# include <linux/ip.h> /* struct iphdr */
45955 +# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
45956 +# include <linux/ipv6.h>
45957 +# endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
45958 +
45959 +#else /* __KERNEL__ */
45960 +
45961 +# include <sys/types.h>
45962 +# include <sys/errno.h>
45963 +# include <stdio.h>
45964 +#endif
45965 +
45966 +#include <openswan.h>
45967 +#include <openswan/pfkeyv2.h>
45968 +#include <openswan/pfkey.h>
45969 +
45970 +#include "openswan/pfkey_debug.h"
45971 +
45972 +
45973 +pfkey_ext_track extensions_bitmaps[2/*in/out*/][2/*perm/req*/][K_SADB_MAX+1]={
45974 +
45975 +/* INBOUND EXTENSIONS */
45976 +{
45977 +
45978 +/* PERMITTED IN */
45979 +{
45980 +/* K_SADB_RESERVED */
45981 +0
45982 +,
45983 +/* SADB_GETSPI */
45984 +1ULL<<SADB_EXT_RESERVED
45985 +| 1ULL<<SADB_EXT_ADDRESS_SRC
45986 +| 1ULL<<SADB_EXT_ADDRESS_DST
45987 +| 1ULL<<SADB_EXT_ADDRESS_PROXY
45988 +| 1ULL<<SADB_EXT_SPIRANGE
45989 +,
45990 +/* SADB_UPDATE */
45991 +1ULL<<SADB_EXT_RESERVED
45992 +| 1ULL<<SADB_EXT_SA
45993 +| 1ULL<<SADB_EXT_LIFETIME_CURRENT
45994 +| 1ULL<<SADB_EXT_LIFETIME_HARD
45995 +| 1ULL<<SADB_EXT_LIFETIME_SOFT
45996 +| 1ULL<<SADB_EXT_ADDRESS_SRC
45997 +| 1ULL<<SADB_EXT_ADDRESS_DST
45998 +| 1ULL<<SADB_EXT_ADDRESS_PROXY
45999 +| 1ULL<<SADB_EXT_KEY_AUTH
46000 +| 1ULL<<SADB_EXT_KEY_ENCRYPT
46001 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46002 +| 1ULL<<SADB_EXT_IDENTITY_DST
46003 +| 1ULL<<SADB_EXT_SENSITIVITY
46004 +| 1ULL<<K_SADB_X_EXT_NAT_T_SPORT
46005 +| 1ULL<<K_SADB_X_EXT_NAT_T_DPORT
46006 +,
46007 +/* SADB_ADD */
46008 +1ULL<<SADB_EXT_RESERVED
46009 +| 1ULL<<SADB_EXT_SA
46010 +| 1ULL<<SADB_EXT_LIFETIME_HARD
46011 +| 1ULL<<SADB_EXT_LIFETIME_SOFT
46012 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46013 +| 1ULL<<SADB_EXT_ADDRESS_DST
46014 +| 1ULL<<SADB_EXT_ADDRESS_PROXY
46015 +| 1ULL<<SADB_EXT_KEY_AUTH
46016 +| 1ULL<<SADB_EXT_KEY_ENCRYPT
46017 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46018 +| 1ULL<<SADB_EXT_IDENTITY_DST
46019 +| 1ULL<<SADB_EXT_SENSITIVITY
46020 +| 1ULL<<K_SADB_X_EXT_NAT_T_TYPE
46021 +| 1ULL<<K_SADB_X_EXT_NAT_T_SPORT
46022 +| 1ULL<<K_SADB_X_EXT_NAT_T_DPORT
46023 +| 1ULL<<K_SADB_X_EXT_NAT_T_OA
46024 +| 1ULL<<K_SADB_X_EXT_PLUMBIF
46025 +| 1ULL<<K_SADB_X_EXT_SAREF
46026 +,
46027 +/* SADB_DELETE */
46028 +1ULL<<SADB_EXT_RESERVED
46029 +| 1ULL<<SADB_EXT_SA
46030 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46031 +| 1ULL<<SADB_EXT_ADDRESS_DST
46032 +,
46033 +/* SADB_GET */
46034 +1ULL<<SADB_EXT_RESERVED
46035 +| 1ULL<<SADB_EXT_SA
46036 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46037 +| 1ULL<<SADB_EXT_ADDRESS_DST
46038 +,
46039 +/* SADB_ACQUIRE */
46040 +1ULL<<SADB_EXT_RESERVED
46041 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46042 +| 1ULL<<SADB_EXT_ADDRESS_DST
46043 +| 1ULL<<SADB_EXT_ADDRESS_PROXY
46044 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46045 +| 1ULL<<SADB_EXT_IDENTITY_DST
46046 +| 1ULL<<SADB_EXT_SENSITIVITY
46047 +| 1ULL<<SADB_EXT_PROPOSAL
46048 +,
46049 +/* K_SADB_REGISTER */
46050 +1ULL<<K_SADB_EXT_RESERVED
46051 +,
46052 +/* K_SADB_EXPIRE */
46053 +0
46054 +,
46055 +/* K_SADB_FLUSH */
46056 +1ULL<<K_SADB_EXT_RESERVED
46057 +,
46058 +/* K_SADB_DUMP */
46059 +1ULL<<K_SADB_EXT_RESERVED
46060 +,
46061 +/* SADB_X_PROMISC */
46062 +1ULL<<SADB_EXT_RESERVED
46063 +| 1ULL<<SADB_EXT_SA
46064 +| 1ULL<<SADB_EXT_LIFETIME_CURRENT
46065 +| 1ULL<<SADB_EXT_LIFETIME_HARD
46066 +| 1ULL<<SADB_EXT_LIFETIME_SOFT
46067 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46068 +| 1ULL<<SADB_EXT_ADDRESS_DST
46069 +| 1ULL<<SADB_EXT_ADDRESS_PROXY
46070 +| 1ULL<<SADB_EXT_KEY_AUTH
46071 +| 1ULL<<SADB_EXT_KEY_ENCRYPT
46072 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46073 +| 1ULL<<SADB_EXT_IDENTITY_DST
46074 +| 1ULL<<SADB_EXT_SENSITIVITY
46075 +| 1ULL<<SADB_EXT_PROPOSAL
46076 +| 1ULL<<SADB_EXT_SUPPORTED_AUTH
46077 +| 1ULL<<SADB_EXT_SUPPORTED_ENCRYPT
46078 +| 1ULL<<SADB_EXT_SPIRANGE
46079 +| 1ULL<<K_SADB_X_EXT_KMPRIVATE
46080 +| 1ULL<<K_SADB_X_EXT_SATYPE2
46081 +| 1ULL<<K_SADB_X_EXT_SA2
46082 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST2
46083 +,
46084 +/* SADB_X_PCHANGE */
46085 +1ULL<<SADB_EXT_RESERVED
46086 +| 1ULL<<SADB_EXT_SA
46087 +| 1ULL<<SADB_EXT_LIFETIME_CURRENT
46088 +| 1ULL<<SADB_EXT_LIFETIME_HARD
46089 +| 1ULL<<SADB_EXT_LIFETIME_SOFT
46090 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46091 +| 1ULL<<SADB_EXT_ADDRESS_DST
46092 +| 1ULL<<SADB_EXT_ADDRESS_PROXY
46093 +| 1ULL<<SADB_EXT_KEY_AUTH
46094 +| 1ULL<<SADB_EXT_KEY_ENCRYPT
46095 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46096 +| 1ULL<<SADB_EXT_IDENTITY_DST
46097 +| 1ULL<<SADB_EXT_SENSITIVITY
46098 +| 1ULL<<SADB_EXT_PROPOSAL
46099 +| 1ULL<<SADB_EXT_SUPPORTED_AUTH
46100 +| 1ULL<<SADB_EXT_SUPPORTED_ENCRYPT
46101 +| 1ULL<<SADB_EXT_SPIRANGE
46102 +| 1ULL<<K_SADB_X_EXT_KMPRIVATE
46103 +| 1ULL<<K_SADB_X_EXT_SATYPE2
46104 +| 1ULL<<K_SADB_X_EXT_SA2
46105 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST2
46106 +,
46107 +/* SADB_X_GRPSA */
46108 +1ULL<<SADB_EXT_RESERVED
46109 +| 1ULL<<SADB_EXT_SA
46110 +| 1ULL<<SADB_EXT_ADDRESS_DST
46111 +| 1ULL<<K_SADB_X_EXT_SATYPE2
46112 +| 1ULL<<K_SADB_X_EXT_SA2
46113 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST2
46114 +,
46115 +/* SADB_X_ADDFLOW */
46116 +1ULL<<SADB_EXT_RESERVED
46117 +| 1ULL<<SADB_EXT_SA
46118 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46119 +| 1ULL<<SADB_EXT_ADDRESS_DST
46120 +| 1ULL<<K_SADB_X_EXT_ADDRESS_SRC_FLOW
46121 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST_FLOW
46122 +| 1ULL<<K_SADB_X_EXT_ADDRESS_SRC_MASK
46123 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST_MASK
46124 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46125 +| 1ULL<<SADB_EXT_IDENTITY_DST
46126 +| 1ULL<<K_SADB_X_EXT_PROTOCOL
46127 +,
46128 +/* SADB_X_DELFLOW */
46129 +1ULL<<SADB_EXT_RESERVED
46130 +| 1ULL<<SADB_EXT_SA
46131 +| 1ULL<<K_SADB_X_EXT_ADDRESS_SRC_FLOW
46132 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST_FLOW
46133 +| 1ULL<<K_SADB_X_EXT_ADDRESS_SRC_MASK
46134 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST_MASK
46135 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46136 +| 1ULL<<SADB_EXT_IDENTITY_DST
46137 +| 1ULL<<K_SADB_X_EXT_PROTOCOL
46138 +,
46139 +/* SADB_X_DEBUG */
46140 +1ULL<<SADB_EXT_RESERVED
46141 +| 1ULL<<K_SADB_X_EXT_DEBUG
46142 +,
46143 +/* SADB_X_NAT_T_NEW_MAPPING */
46144 +1ULL<<SADB_EXT_RESERVED
46145 +| 1ULL<<SADB_EXT_SA
46146 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46147 +| 1ULL<<SADB_EXT_ADDRESS_DST
46148 +| 1ULL<<K_SADB_X_EXT_NAT_T_SPORT
46149 +| 1ULL<<K_SADB_X_EXT_NAT_T_DPORT
46150 +,
46151 +/* SADB_X_PLUMBIF */
46152 +1ULL<<SADB_EXT_RESERVED
46153 +| 1ULL<<K_SADB_X_EXT_PLUMBIF
46154 +,
46155 +/* SADB_X_UNPLUMBIF */
46156 +1ULL<<SADB_EXT_RESERVED
46157 +| 1ULL<<K_SADB_X_EXT_PLUMBIF
46158 +},
46159 +
46160 +/* REQUIRED IN */
46161 +{
46162 +/* K_SADB_RESERVED */
46163 +0
46164 +,
46165 +/* K_SADB_GETSPI */
46166 +1ULL<<K_SADB_EXT_RESERVED
46167 +| 1ULL<<K_SADB_EXT_ADDRESS_SRC
46168 +| 1ULL<<K_SADB_EXT_ADDRESS_DST
46169 +| 1ULL<<K_SADB_EXT_SPIRANGE
46170 +,
46171 +/* K_SADB_UPDATE */
46172 +1ULL<<K_SADB_EXT_RESERVED
46173 +| 1ULL<<K_SADB_EXT_SA
46174 +| 1ULL<<K_SADB_EXT_ADDRESS_SRC
46175 +| 1ULL<<K_SADB_EXT_ADDRESS_DST
46176 +/*| 1ULL<<K_SADB_EXT_KEY_AUTH*/
46177 +/*| 1ULL<<K_SADB_EXT_KEY_ENCRYPT*/
46178 +,
46179 +/* K_SADB_ADD */
46180 +1ULL<<K_SADB_EXT_RESERVED
46181 +| 1ULL<<K_SADB_EXT_SA
46182 +| 1ULL<<K_SADB_EXT_ADDRESS_SRC
46183 +| 1ULL<<K_SADB_EXT_ADDRESS_DST
46184 +/*| 1ULL<<K_SADB_EXT_KEY_AUTH*/
46185 +/*| 1ULL<<K_SADB_EXT_KEY_ENCRYPT*/
46186 +,
46187 +/* K_SADB_DELETE */
46188 +1ULL<<K_SADB_EXT_RESERVED
46189 +| 1ULL<<K_SADB_EXT_SA
46190 +| 1ULL<<K_SADB_EXT_ADDRESS_SRC
46191 +| 1ULL<<K_SADB_EXT_ADDRESS_DST
46192 +,
46193 +/* K_SADB_GET */
46194 +1ULL<<K_SADB_EXT_RESERVED
46195 +| 1ULL<<K_SADB_EXT_SA
46196 +| 1ULL<<K_SADB_EXT_ADDRESS_SRC
46197 +| 1ULL<<K_SADB_EXT_ADDRESS_DST
46198 +,
46199 +/* K_SADB_ACQUIRE */
46200 +1ULL<<K_SADB_EXT_RESERVED
46201 +| 1ULL<<K_SADB_EXT_ADDRESS_SRC
46202 +| 1ULL<<K_SADB_EXT_ADDRESS_DST
46203 +| 1ULL<<K_SADB_EXT_PROPOSAL
46204 +,
46205 +/* K_SADB_REGISTER */
46206 +1ULL<<K_SADB_EXT_RESERVED
46207 +,
46208 +/* K_SADB_EXPIRE */
46209 +0
46210 +,
46211 +/* K_SADB_FLUSH */
46212 +1ULL<<K_SADB_EXT_RESERVED
46213 +,
46214 +/* K_SADB_DUMP */
46215 +1ULL<<K_SADB_EXT_RESERVED
46216 +,
46217 +/* SADB_X_PROMISC */
46218 +1ULL<<SADB_EXT_RESERVED
46219 +| 1ULL<<SADB_EXT_SA
46220 +| 1ULL<<SADB_EXT_LIFETIME_CURRENT
46221 +| 1ULL<<SADB_EXT_LIFETIME_HARD
46222 +| 1ULL<<SADB_EXT_LIFETIME_SOFT
46223 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46224 +| 1ULL<<SADB_EXT_ADDRESS_DST
46225 +| 1ULL<<SADB_EXT_ADDRESS_PROXY
46226 +| 1ULL<<SADB_EXT_KEY_AUTH
46227 +| 1ULL<<SADB_EXT_KEY_ENCRYPT
46228 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46229 +| 1ULL<<SADB_EXT_IDENTITY_DST
46230 +| 1ULL<<SADB_EXT_SENSITIVITY
46231 +| 1ULL<<SADB_EXT_PROPOSAL
46232 +| 1ULL<<SADB_EXT_SUPPORTED_AUTH
46233 +| 1ULL<<SADB_EXT_SUPPORTED_ENCRYPT
46234 +| 1ULL<<SADB_EXT_SPIRANGE
46235 +| 1ULL<<K_SADB_X_EXT_KMPRIVATE
46236 +| 1ULL<<K_SADB_X_EXT_SATYPE2
46237 +| 1ULL<<K_SADB_X_EXT_SA2
46238 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST2
46239 +,
46240 +/* SADB_X_PCHANGE */
46241 +1ULL<<SADB_EXT_RESERVED
46242 +| 1ULL<<SADB_EXT_SA
46243 +| 1ULL<<SADB_EXT_LIFETIME_CURRENT
46244 +| 1ULL<<SADB_EXT_LIFETIME_HARD
46245 +| 1ULL<<SADB_EXT_LIFETIME_SOFT
46246 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46247 +| 1ULL<<SADB_EXT_ADDRESS_DST
46248 +| 1ULL<<SADB_EXT_ADDRESS_PROXY
46249 +| 1ULL<<SADB_EXT_KEY_AUTH
46250 +| 1ULL<<SADB_EXT_KEY_ENCRYPT
46251 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46252 +| 1ULL<<SADB_EXT_IDENTITY_DST
46253 +| 1ULL<<SADB_EXT_SENSITIVITY
46254 +| 1ULL<<SADB_EXT_PROPOSAL
46255 +| 1ULL<<SADB_EXT_SUPPORTED_AUTH
46256 +| 1ULL<<SADB_EXT_SUPPORTED_ENCRYPT
46257 +| 1ULL<<SADB_EXT_SPIRANGE
46258 +| 1ULL<<K_SADB_X_EXT_KMPRIVATE
46259 +| 1ULL<<K_SADB_X_EXT_SATYPE2
46260 +| 1ULL<<K_SADB_X_EXT_SA2
46261 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST2
46262 +,
46263 +/* SADB_X_GRPSA */
46264 +1ULL<<SADB_EXT_RESERVED
46265 +| 1ULL<<SADB_EXT_SA
46266 +| 1ULL<<SADB_EXT_ADDRESS_DST
46267 +/*| 1ULL<<K_SADB_X_EXT_SATYPE2*/
46268 +/*| 1ULL<<K_SADB_X_EXT_SA2*/
46269 +/*| 1ULL<<K_SADB_X_EXT_ADDRESS_DST2*/
46270 +,
46271 +/* SADB_X_ADDFLOW */
46272 +1ULL<<SADB_EXT_RESERVED
46273 +| 1ULL<<SADB_EXT_SA
46274 +| 1ULL<<SADB_EXT_ADDRESS_DST
46275 +| 1ULL<<K_SADB_X_EXT_ADDRESS_SRC_FLOW
46276 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST_FLOW
46277 +| 1ULL<<K_SADB_X_EXT_ADDRESS_SRC_MASK
46278 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST_MASK
46279 +,
46280 +/* SADB_X_DELFLOW */
46281 +1ULL<<SADB_EXT_RESERVED
46282 +/*| 1ULL<<SADB_EXT_SA*/
46283 +#if 0 /* SADB_X_CLREROUTE doesn't need all these... */
46284 +| 1ULL<<K_SADB_X_EXT_ADDRESS_SRC_FLOW
46285 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST_FLOW
46286 +| 1ULL<<K_SADB_X_EXT_ADDRESS_SRC_MASK
46287 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST_MASK
46288 +#endif
46289 +,
46290 +/* SADB_X_DEBUG */
46291 +1ULL<<SADB_EXT_RESERVED
46292 +| 1ULL<<K_SADB_X_EXT_DEBUG
46293 +,
46294 +/* SADB_X_NAT_T_NEW_MAPPING */
46295 +1ULL<<SADB_EXT_RESERVED
46296 +| 1ULL<<SADB_EXT_SA
46297 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46298 +| 1ULL<<SADB_EXT_ADDRESS_DST
46299 +| 1ULL<<K_SADB_X_EXT_NAT_T_SPORT
46300 +| 1ULL<<K_SADB_X_EXT_NAT_T_DPORT
46301 +,
46302 +/* SADB_X_PLUMBIF */
46303 +1ULL<<SADB_EXT_RESERVED
46304 +| 1ULL<<K_SADB_X_EXT_PLUMBIF
46305 +,
46306 +/* SADB_X_UNPLUMBIF */
46307 +1ULL<<SADB_EXT_RESERVED
46308 +| 1ULL<<K_SADB_X_EXT_PLUMBIF
46309 +}
46310 +
46311 +},
46312 +
46313 +/* OUTBOUND EXTENSIONS */
46314 +{
46315 +
46316 +/* PERMITTED OUT */
46317 +{
46318 +/* K_SADB_RESERVED */
46319 +0
46320 +,
46321 +/* SADB_GETSPI */
46322 +1ULL<<SADB_EXT_RESERVED
46323 +| 1ULL<<SADB_EXT_SA
46324 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46325 +| 1ULL<<SADB_EXT_ADDRESS_DST
46326 +,
46327 +/* SADB_UPDATE */
46328 +1ULL<<SADB_EXT_RESERVED
46329 +| 1ULL<<SADB_EXT_SA
46330 +| 1ULL<<SADB_EXT_LIFETIME_CURRENT
46331 +| 1ULL<<SADB_EXT_LIFETIME_HARD
46332 +| 1ULL<<SADB_EXT_LIFETIME_SOFT
46333 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46334 +| 1ULL<<SADB_EXT_ADDRESS_DST
46335 +| 1ULL<<SADB_EXT_ADDRESS_PROXY
46336 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46337 +| 1ULL<<SADB_EXT_IDENTITY_DST
46338 +| 1ULL<<SADB_EXT_SENSITIVITY
46339 +| 1ULL<<K_SADB_X_EXT_NAT_T_SPORT
46340 +| 1ULL<<K_SADB_X_EXT_NAT_T_DPORT
46341 +,
46342 +/* SADB_ADD */
46343 +1ULL<<SADB_EXT_RESERVED
46344 +| 1ULL<<SADB_EXT_SA
46345 +| 1ULL<<SADB_EXT_LIFETIME_HARD
46346 +| 1ULL<<SADB_EXT_LIFETIME_SOFT
46347 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46348 +| 1ULL<<SADB_EXT_ADDRESS_DST
46349 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46350 +| 1ULL<<SADB_EXT_IDENTITY_DST
46351 +| 1ULL<<SADB_EXT_SENSITIVITY
46352 +| 1ULL<<K_SADB_X_EXT_NAT_T_TYPE
46353 +| 1ULL<<K_SADB_X_EXT_NAT_T_SPORT
46354 +| 1ULL<<K_SADB_X_EXT_NAT_T_DPORT
46355 +| 1ULL<<K_SADB_X_EXT_NAT_T_OA
46356 +| 1ULL<<K_SADB_X_EXT_PLUMBIF
46357 +| 1ULL<<K_SADB_X_EXT_SAREF
46358 +,
46359 +/* SADB_DELETE */
46360 +1ULL<<SADB_EXT_RESERVED
46361 +| 1ULL<<SADB_EXT_SA
46362 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46363 +| 1ULL<<SADB_EXT_ADDRESS_DST
46364 +,
46365 +/* SADB_GET */
46366 +1ULL<<SADB_EXT_RESERVED
46367 +| 1ULL<<SADB_EXT_SA
46368 +| 1ULL<<SADB_EXT_LIFETIME_CURRENT
46369 +| 1ULL<<SADB_EXT_LIFETIME_HARD
46370 +| 1ULL<<SADB_EXT_LIFETIME_SOFT
46371 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46372 +| 1ULL<<SADB_EXT_ADDRESS_DST
46373 +| 1ULL<<SADB_EXT_ADDRESS_PROXY
46374 +| 1ULL<<SADB_EXT_KEY_AUTH
46375 +| 1ULL<<SADB_EXT_KEY_ENCRYPT
46376 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46377 +| 1ULL<<SADB_EXT_IDENTITY_DST
46378 +| 1ULL<<SADB_EXT_SENSITIVITY
46379 +| 1ULL<<K_SADB_X_EXT_NAT_T_TYPE
46380 +| 1ULL<<K_SADB_X_EXT_NAT_T_SPORT
46381 +| 1ULL<<K_SADB_X_EXT_NAT_T_DPORT
46382 +| 1ULL<<K_SADB_X_EXT_NAT_T_OA
46383 +,
46384 +/* SADB_ACQUIRE */
46385 +1ULL<<SADB_EXT_RESERVED
46386 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46387 +| 1ULL<<SADB_EXT_ADDRESS_DST
46388 +| 1ULL<<SADB_EXT_ADDRESS_PROXY
46389 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46390 +| 1ULL<<SADB_EXT_IDENTITY_DST
46391 +| 1ULL<<SADB_EXT_SENSITIVITY
46392 +| 1ULL<<SADB_EXT_PROPOSAL
46393 +,
46394 +/* SADB_REGISTER */
46395 +1ULL<<SADB_EXT_RESERVED
46396 +| 1ULL<<SADB_EXT_SUPPORTED_AUTH
46397 +| 1ULL<<SADB_EXT_SUPPORTED_ENCRYPT
46398 +,
46399 +/* SADB_EXPIRE */
46400 +1ULL<<SADB_EXT_RESERVED
46401 +| 1ULL<<SADB_EXT_SA
46402 +| 1ULL<<SADB_EXT_LIFETIME_CURRENT
46403 +| 1ULL<<SADB_EXT_LIFETIME_HARD
46404 +| 1ULL<<SADB_EXT_LIFETIME_SOFT
46405 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46406 +| 1ULL<<SADB_EXT_ADDRESS_DST
46407 +,
46408 +/* SADB_FLUSH */
46409 +1ULL<<SADB_EXT_RESERVED
46410 +,
46411 +/* SADB_DUMP */
46412 +1ULL<<SADB_EXT_RESERVED
46413 +| 1ULL<<SADB_EXT_SA
46414 +| 1ULL<<SADB_EXT_LIFETIME_CURRENT
46415 +| 1ULL<<SADB_EXT_LIFETIME_HARD
46416 +| 1ULL<<SADB_EXT_LIFETIME_SOFT
46417 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46418 +| 1ULL<<SADB_EXT_ADDRESS_DST
46419 +| 1ULL<<SADB_EXT_ADDRESS_PROXY
46420 +| 1ULL<<SADB_EXT_KEY_AUTH
46421 +| 1ULL<<SADB_EXT_KEY_ENCRYPT
46422 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46423 +| 1ULL<<SADB_EXT_IDENTITY_DST
46424 +| 1ULL<<SADB_EXT_SENSITIVITY
46425 +| 1ULL<<K_SADB_X_EXT_NAT_T_TYPE
46426 +| 1ULL<<K_SADB_X_EXT_NAT_T_SPORT
46427 +| 1ULL<<K_SADB_X_EXT_NAT_T_DPORT
46428 +| 1ULL<<K_SADB_X_EXT_NAT_T_OA
46429 +,
46430 +/* SADB_X_PROMISC */
46431 +1ULL<<SADB_EXT_RESERVED
46432 +| 1ULL<<SADB_EXT_SA
46433 +| 1ULL<<SADB_EXT_LIFETIME_CURRENT
46434 +| 1ULL<<SADB_EXT_LIFETIME_HARD
46435 +| 1ULL<<SADB_EXT_LIFETIME_SOFT
46436 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46437 +| 1ULL<<SADB_EXT_ADDRESS_DST
46438 +| 1ULL<<SADB_EXT_ADDRESS_PROXY
46439 +| 1ULL<<SADB_EXT_KEY_AUTH
46440 +| 1ULL<<SADB_EXT_KEY_ENCRYPT
46441 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46442 +| 1ULL<<SADB_EXT_IDENTITY_DST
46443 +| 1ULL<<SADB_EXT_SENSITIVITY
46444 +| 1ULL<<SADB_EXT_PROPOSAL
46445 +| 1ULL<<SADB_EXT_SUPPORTED_AUTH
46446 +| 1ULL<<SADB_EXT_SUPPORTED_ENCRYPT
46447 +| 1ULL<<SADB_EXT_SPIRANGE
46448 +| 1ULL<<K_SADB_X_EXT_KMPRIVATE
46449 +| 1ULL<<K_SADB_X_EXT_SATYPE2
46450 +| 1ULL<<K_SADB_X_EXT_SA2
46451 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST2
46452 +,
46453 +/* SADB_X_PCHANGE */
46454 +1ULL<<SADB_EXT_RESERVED
46455 +| 1ULL<<SADB_EXT_SA
46456 +| 1ULL<<SADB_EXT_LIFETIME_CURRENT
46457 +| 1ULL<<SADB_EXT_LIFETIME_HARD
46458 +| 1ULL<<SADB_EXT_LIFETIME_SOFT
46459 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46460 +| 1ULL<<SADB_EXT_ADDRESS_DST
46461 +| 1ULL<<SADB_EXT_ADDRESS_PROXY
46462 +| 1ULL<<SADB_EXT_KEY_AUTH
46463 +| 1ULL<<SADB_EXT_KEY_ENCRYPT
46464 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46465 +| 1ULL<<SADB_EXT_IDENTITY_DST
46466 +| 1ULL<<SADB_EXT_SENSITIVITY
46467 +| 1ULL<<SADB_EXT_PROPOSAL
46468 +| 1ULL<<SADB_EXT_SUPPORTED_AUTH
46469 +| 1ULL<<SADB_EXT_SUPPORTED_ENCRYPT
46470 +| 1ULL<<SADB_EXT_SPIRANGE
46471 +| 1ULL<<K_SADB_X_EXT_KMPRIVATE
46472 +| 1ULL<<K_SADB_X_EXT_SATYPE2
46473 +| 1ULL<<K_SADB_X_EXT_SA2
46474 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST2
46475 +,
46476 +/* SADB_X_GRPSA */
46477 +1ULL<<SADB_EXT_RESERVED
46478 +| 1ULL<<SADB_EXT_SA
46479 +| 1ULL<<SADB_EXT_ADDRESS_DST
46480 +| 1ULL<<K_SADB_X_EXT_SATYPE2
46481 +| 1ULL<<K_SADB_X_EXT_SA2
46482 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST2
46483 +,
46484 +/* SADB_X_ADDFLOW */
46485 +1ULL<<SADB_EXT_RESERVED
46486 +| 1ULL<<SADB_EXT_SA
46487 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46488 +| 1ULL<<SADB_EXT_ADDRESS_DST
46489 +| 1ULL<<K_SADB_X_EXT_ADDRESS_SRC_FLOW
46490 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST_FLOW
46491 +| 1ULL<<K_SADB_X_EXT_ADDRESS_SRC_MASK
46492 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST_MASK
46493 +| 1ULL<<K_SADB_X_EXT_PROTOCOL
46494 +,
46495 +/* SADB_X_DELFLOW */
46496 +1ULL<<SADB_EXT_RESERVED
46497 +| 1ULL<<SADB_EXT_SA
46498 +| 1ULL<<K_SADB_X_EXT_ADDRESS_SRC_FLOW
46499 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST_FLOW
46500 +| 1ULL<<K_SADB_X_EXT_ADDRESS_SRC_MASK
46501 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST_MASK
46502 +| 1ULL<<K_SADB_X_EXT_PROTOCOL
46503 +,
46504 +/* SADB_X_DEBUG */
46505 +1ULL<<SADB_EXT_RESERVED
46506 +| 1ULL<<K_SADB_X_EXT_DEBUG
46507 +,
46508 +/* SADB_X_NAT_T_NEW_MAPPING */
46509 +1ULL<<SADB_EXT_RESERVED
46510 +| 1ULL<<SADB_EXT_SA
46511 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46512 +| 1ULL<<SADB_EXT_ADDRESS_DST
46513 +| 1ULL<<K_SADB_X_EXT_NAT_T_SPORT
46514 +| 1ULL<<K_SADB_X_EXT_NAT_T_DPORT
46515 +,
46516 +/* SADB_X_PLUMBIF */
46517 +1ULL<<SADB_EXT_RESERVED
46518 +| 1ULL<<K_SADB_X_EXT_PLUMBIF
46519 +,
46520 +/* SADB_X_UNPLUMBIF */
46521 +1ULL<<SADB_EXT_RESERVED
46522 +| 1ULL<<K_SADB_X_EXT_PLUMBIF
46523 +},
46524 +
46525 +/* REQUIRED OUT */
46526 +{
46527 +/* K_SADB_RESERVED */
46528 +0
46529 +,
46530 +/* SADB_GETSPI */
46531 +1ULL<<SADB_EXT_RESERVED
46532 +| 1ULL<<SADB_EXT_SA
46533 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46534 +| 1ULL<<SADB_EXT_ADDRESS_DST
46535 +,
46536 +/* SADB_UPDATE */
46537 +1ULL<<SADB_EXT_RESERVED
46538 +| 1ULL<<SADB_EXT_SA
46539 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46540 +| 1ULL<<SADB_EXT_ADDRESS_DST
46541 +,
46542 +/* SADB_ADD */
46543 +1ULL<<SADB_EXT_RESERVED
46544 +| 1ULL<<SADB_EXT_SA
46545 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46546 +| 1ULL<<SADB_EXT_ADDRESS_DST
46547 +,
46548 +/* SADB_DELETE */
46549 +1ULL<<SADB_EXT_RESERVED
46550 +| 1ULL<<SADB_EXT_SA
46551 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46552 +| 1ULL<<SADB_EXT_ADDRESS_DST
46553 +,
46554 +/* SADB_GET */
46555 +1ULL<<SADB_EXT_RESERVED
46556 +| 1ULL<<SADB_EXT_SA
46557 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46558 +| 1ULL<<SADB_EXT_ADDRESS_DST
46559 +/* | 1ULL<<SADB_EXT_KEY_AUTH */
46560 +/* | 1ULL<<SADB_EXT_KEY_ENCRYPT */
46561 +,
46562 +/* SADB_ACQUIRE */
46563 +1ULL<<SADB_EXT_RESERVED
46564 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46565 +| 1ULL<<SADB_EXT_ADDRESS_DST
46566 +| 1ULL<<SADB_EXT_PROPOSAL
46567 +,
46568 +/* SADB_REGISTER */
46569 +1ULL<<SADB_EXT_RESERVED
46570 +/* | 1ULL<<SADB_EXT_SUPPORTED_AUTH
46571 + | 1ULL<<SADB_EXT_SUPPORTED_ENCRYPT */
46572 +,
46573 +/* SADB_EXPIRE */
46574 +1ULL<<SADB_EXT_RESERVED
46575 +| 1ULL<<SADB_EXT_SA
46576 +| 1ULL<<SADB_EXT_LIFETIME_CURRENT
46577 +/* | 1ULL<<SADB_EXT_LIFETIME_HARD
46578 + | 1ULL<<SADB_EXT_LIFETIME_SOFT */
46579 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46580 +| 1ULL<<SADB_EXT_ADDRESS_DST
46581 +,
46582 +/* SADB_FLUSH */
46583 +1ULL<<SADB_EXT_RESERVED
46584 +,
46585 +/* SADB_DUMP */
46586 +1ULL<<SADB_EXT_RESERVED
46587 +| 1ULL<<SADB_EXT_SA
46588 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46589 +| 1ULL<<SADB_EXT_ADDRESS_DST
46590 +| 1ULL<<SADB_EXT_KEY_AUTH
46591 +| 1ULL<<SADB_EXT_KEY_ENCRYPT
46592 +,
46593 +/* SADB_X_PROMISC */
46594 +1ULL<<SADB_EXT_RESERVED
46595 +| 1ULL<<SADB_EXT_SA
46596 +| 1ULL<<SADB_EXT_LIFETIME_CURRENT
46597 +| 1ULL<<SADB_EXT_LIFETIME_HARD
46598 +| 1ULL<<SADB_EXT_LIFETIME_SOFT
46599 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46600 +| 1ULL<<SADB_EXT_ADDRESS_DST
46601 +| 1ULL<<SADB_EXT_ADDRESS_PROXY
46602 +| 1ULL<<SADB_EXT_KEY_AUTH
46603 +| 1ULL<<SADB_EXT_KEY_ENCRYPT
46604 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46605 +| 1ULL<<SADB_EXT_IDENTITY_DST
46606 +| 1ULL<<SADB_EXT_SENSITIVITY
46607 +| 1ULL<<SADB_EXT_PROPOSAL
46608 +| 1ULL<<SADB_EXT_SUPPORTED_AUTH
46609 +| 1ULL<<SADB_EXT_SUPPORTED_ENCRYPT
46610 +| 1ULL<<SADB_EXT_SPIRANGE
46611 +| 1ULL<<K_SADB_X_EXT_KMPRIVATE
46612 +| 1ULL<<K_SADB_X_EXT_SATYPE2
46613 +| 1ULL<<K_SADB_X_EXT_SA2
46614 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST2
46615 +,
46616 +/* SADB_X_PCHANGE */
46617 +1ULL<<SADB_EXT_RESERVED
46618 +| 1ULL<<SADB_EXT_SA
46619 +| 1ULL<<SADB_EXT_LIFETIME_CURRENT
46620 +| 1ULL<<SADB_EXT_LIFETIME_HARD
46621 +| 1ULL<<SADB_EXT_LIFETIME_SOFT
46622 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46623 +| 1ULL<<SADB_EXT_ADDRESS_DST
46624 +| 1ULL<<SADB_EXT_ADDRESS_PROXY
46625 +| 1ULL<<SADB_EXT_KEY_AUTH
46626 +| 1ULL<<SADB_EXT_KEY_ENCRYPT
46627 +| 1ULL<<SADB_EXT_IDENTITY_SRC
46628 +| 1ULL<<SADB_EXT_IDENTITY_DST
46629 +| 1ULL<<SADB_EXT_SENSITIVITY
46630 +| 1ULL<<SADB_EXT_PROPOSAL
46631 +| 1ULL<<SADB_EXT_SUPPORTED_AUTH
46632 +| 1ULL<<SADB_EXT_SUPPORTED_ENCRYPT
46633 +| 1ULL<<SADB_EXT_SPIRANGE
46634 +| 1ULL<<K_SADB_X_EXT_KMPRIVATE
46635 +| 1ULL<<K_SADB_X_EXT_SATYPE2
46636 +| 1ULL<<K_SADB_X_EXT_SA2
46637 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST2
46638 +,
46639 +/* SADB_X_GRPSA */
46640 +1ULL<<SADB_EXT_RESERVED
46641 +| 1ULL<<SADB_EXT_SA
46642 +| 1ULL<<SADB_EXT_ADDRESS_DST
46643 +,
46644 +/* SADB_X_ADDFLOW */
46645 +1ULL<<SADB_EXT_RESERVED
46646 +| 1ULL<<SADB_EXT_SA
46647 +| 1ULL<<SADB_EXT_ADDRESS_DST
46648 +| 1ULL<<K_SADB_X_EXT_ADDRESS_SRC_FLOW
46649 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST_FLOW
46650 +| 1ULL<<K_SADB_X_EXT_ADDRESS_SRC_MASK
46651 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST_MASK
46652 +,
46653 +/* SADB_X_DELFLOW */
46654 +1ULL<<SADB_EXT_RESERVED
46655 +/*| 1ULL<<SADB_EXT_SA*/
46656 +| 1ULL<<K_SADB_X_EXT_ADDRESS_SRC_FLOW
46657 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST_FLOW
46658 +| 1ULL<<K_SADB_X_EXT_ADDRESS_SRC_MASK
46659 +| 1ULL<<K_SADB_X_EXT_ADDRESS_DST_MASK
46660 +,
46661 +/* SADB_X_DEBUG */
46662 +1ULL<<SADB_EXT_RESERVED
46663 +| 1ULL<<K_SADB_X_EXT_DEBUG
46664 +,
46665 +/* SADB_X_NAT_T_NEW_MAPPING */
46666 +1ULL<<SADB_EXT_RESERVED
46667 +| 1ULL<<SADB_EXT_SA
46668 +| 1ULL<<SADB_EXT_ADDRESS_SRC
46669 +| 1ULL<<SADB_EXT_ADDRESS_DST
46670 +| 1ULL<<K_SADB_X_EXT_NAT_T_SPORT
46671 +| 1ULL<<K_SADB_X_EXT_NAT_T_DPORT
46672 +,
46673 +/* SADB_X_PLUMBIF */
46674 +1ULL<<SADB_EXT_RESERVED
46675 +| 1ULL<<K_SADB_X_EXT_PLUMBIF
46676 +,
46677 +/* SADB_X_UNPLUMBIF */
46678 +1ULL<<SADB_EXT_RESERVED
46679 +| 1ULL<<K_SADB_X_EXT_PLUMBIF
46680 +}
46681 +}
46682 +};
46683 +
46684 +int pfkey_required_extension(enum pfkey_ext_required inout,
46685 + enum sadb_msg_t sadb_operation,
46686 + enum sadb_extension_t exttype)
46687 +{
46688 + return (extensions_bitmaps[inout][EXT_BITS_REQ][sadb_operation] & (1ULL<<exttype)) != 0;
46689 +}
46690 +
46691 +int pfkey_permitted_extension(enum pfkey_ext_required inout,
46692 + enum sadb_msg_t sadb_operation,
46693 + enum sadb_extension_t exttype)
46694 +{
46695 + return (extensions_bitmaps[inout][EXT_BITS_PERM][sadb_operation] & (1ULL<<exttype)) != 0;
46696 +}
46697 +
46698 +
46699 +int pfkey_extensions_missing(enum pfkey_ext_required inout,
46700 + enum sadb_msg_t sadb_operation,
46701 + pfkey_ext_track extensions_seen)
46702 +
46703 +{
46704 + pfkey_ext_track req = extensions_bitmaps[inout][EXT_BITS_REQ][sadb_operation];
46705 +
46706 + if((extensions_seen & req) != req) {
46707 + ERROR("extensions for op: %d seen: %08llx required %08llx, missing: %08llx\n",
46708 + sadb_operation,
46709 + (unsigned long long)extensions_seen,
46710 + (unsigned long long)req,
46711 + (unsigned long long)req & ~(req & extensions_seen));
46712 + return 1;
46713 + }
46714 + return 0;
46715 +}
46716 +
46717 +/*
46718 + *
46719 + * Local Variables:
46720 + * c-file-style: "linux"
46721 + * End:
46722 + *
46723 + */
46724 --- /dev/null Tue Mar 11 13:02:56 2003
46725 +++ linux/net/ipsec/pfkey_v2_ext_process.c Mon Feb 9 13:51:03 2004
46726 @@ -0,0 +1,880 @@
46727 +/*
46728 + * @(#) RFC2367 PF_KEYv2 Key management API message parser
46729 + * Copyright (C) 1998-2003 Richard Guy Briggs.
46730 + * Copyright (C) 2004-2006 Michael Richardson <mcr@xelerance.com>
46731 + *
46732 + * This program is free software; you can redistribute it and/or modify it
46733 + * under the terms of the GNU General Public License as published by the
46734 + * Free Software Foundation; either version 2 of the License, or (at your
46735 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
46736 + *
46737 + * This program is distributed in the hope that it will be useful, but
46738 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
46739 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
46740 + * for more details.
46741 + *
46742 + */
46743 +
46744 +/*
46745 + * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
46746 + */
46747 +
46748 +#ifndef AUTOCONF_INCLUDED
46749 +#include <linux/config.h>
46750 +#endif
46751 +#include <linux/version.h>
46752 +#include <linux/kernel.h> /* printk() */
46753 +
46754 +#include "openswan/ipsec_param.h"
46755 +
46756 +#ifdef MALLOC_SLAB
46757 +# include <linux/slab.h> /* kmalloc() */
46758 +#else /* MALLOC_SLAB */
46759 +# include <linux/malloc.h> /* kmalloc() */
46760 +#endif /* MALLOC_SLAB */
46761 +#include <linux/errno.h> /* error codes */
46762 +#include <linux/types.h> /* size_t */
46763 +#include <linux/interrupt.h> /* mark_bh */
46764 +
46765 +#include <linux/netdevice.h> /* struct device, and other headers */
46766 +#include <linux/etherdevice.h> /* eth_type_trans */
46767 +#include <linux/ip.h> /* struct iphdr */
46768 +#include <linux/skbuff.h>
46769 +
46770 +#include <openswan.h>
46771 +
46772 +#include <klips-crypto/des.h>
46773 +
46774 +#ifdef SPINLOCK
46775 +# ifdef SPINLOCK_23
46776 +# include <linux/spinlock.h> /* *lock* */
46777 +# else /* SPINLOCK_23 */
46778 +# include <asm/spinlock.h> /* *lock* */
46779 +# endif /* SPINLOCK_23 */
46780 +#endif /* SPINLOCK */
46781 +#ifdef NET_21
46782 +# include <linux/in6.h>
46783 +# define IS_MYADDR RTN_LOCAL
46784 +#endif
46785 +
46786 +#include <net/ip.h>
46787 +#ifdef NETLINK_SOCK
46788 +# include <linux/netlink.h>
46789 +#else
46790 +# include <net/netlink.h>
46791 +#endif
46792 +
46793 +#include <linux/random.h> /* get_random_bytes() */
46794 +
46795 +#include "openswan/radij.h"
46796 +#include "openswan/ipsec_encap.h"
46797 +#include "openswan/ipsec_sa.h"
46798 +
46799 +#include "openswan/ipsec_radij.h"
46800 +#include "openswan/ipsec_xform.h"
46801 +#include "openswan/ipsec_ah.h"
46802 +#include "openswan/ipsec_esp.h"
46803 +#include "openswan/ipsec_tunnel.h"
46804 +#include "openswan/ipsec_rcv.h"
46805 +#include "openswan/ipcomp.h"
46806 +
46807 +#include <openswan/pfkeyv2.h>
46808 +#include <openswan/pfkey.h>
46809 +
46810 +#include "openswan/ipsec_proto.h"
46811 +#include "openswan/ipsec_alg.h"
46812 +
46813 +#ifdef CONFIG_KLIPS_OCF
46814 +#include "ipsec_ocf.h"
46815 +#endif
46816 +
46817 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
46818 +
46819 +/* returns 0 on success */
46820 +int
46821 +pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
46822 +{
46823 + struct k_sadb_sa *k_pfkey_sa = (struct k_sadb_sa *)pfkey_ext;
46824 + struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
46825 + int error = 0;
46826 + struct ipsec_sa* ipsp;
46827 +
46828 + KLIPS_PRINT(debug_pfkey,
46829 + "klips_debug:pfkey_sa_process: .\n");
46830 +
46831 + if(!extr || !extr->ips) {
46832 + KLIPS_PRINT(debug_pfkey,
46833 + "klips_debug:pfkey_sa_process: "
46834 + "extr or extr->ips is NULL, fatal\n");
46835 + SENDERR(EINVAL);
46836 + }
46837 +
46838 + switch(pfkey_ext->sadb_ext_type) {
46839 + case K_SADB_EXT_SA:
46840 + ipsp = extr->ips;
46841 + break;
46842 + case K_SADB_X_EXT_SA2:
46843 + if(extr->ips2 == NULL) {
46844 + extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
46845 + }
46846 + if(extr->ips2 == NULL) {
46847 + SENDERR(-error);
46848 + }
46849 + ipsp = extr->ips2;
46850 + break;
46851 + default:
46852 + KLIPS_PRINT(debug_pfkey,
46853 + "klips_debug:pfkey_sa_process: "
46854 + "invalid exttype=%d.\n",
46855 + pfkey_ext->sadb_ext_type);
46856 + SENDERR(EINVAL);
46857 + }
46858 +
46859 + ipsp->ips_said.spi = pfkey_sa->sadb_sa_spi;
46860 + ipsp->ips_replaywin = pfkey_sa->sadb_sa_replay;
46861 + ipsp->ips_state = pfkey_sa->sadb_sa_state;
46862 + ipsp->ips_flags = pfkey_sa->sadb_sa_flags;
46863 + ipsp->ips_replaywin_lastseq = ipsp->ips_replaywin_bitmap = 0;
46864 +
46865 + if(k_pfkey_sa->sadb_sa_len > sizeof(struct sadb_sa)/IPSEC_PFKEYv2_ALIGN) {
46866 + ipsp->ips_ref = k_pfkey_sa->sadb_x_sa_ref;
46867 + }
46868 +
46869 + switch(ipsp->ips_said.proto) {
46870 + case IPPROTO_AH:
46871 + ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
46872 + ipsp->ips_encalg = K_SADB_EALG_NONE;
46873 +#ifdef CONFIG_KLIPS_OCF
46874 + if (ipsec_ocf_sa_init(ipsp, ipsp->ips_authalg, 0))
46875 + break;
46876 +#endif
46877 + break;
46878 + case IPPROTO_ESP:
46879 + ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
46880 + ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
46881 +#ifdef CONFIG_KLIPS_OCF
46882 + if (ipsec_ocf_sa_init(ipsp, ipsp->ips_authalg, ipsp->ips_encalg))
46883 + break;
46884 +#endif
46885 +#ifdef CONFIG_KLIPS_ALG
46886 + ipsec_alg_sa_init(ipsp);
46887 +#endif
46888 + break;
46889 + case IPPROTO_IPIP:
46890 + ipsp->ips_authalg = AH_NONE;
46891 + ipsp->ips_encalg = ESP_NONE;
46892 + break;
46893 +#ifdef CONFIG_KLIPS_IPCOMP
46894 + case IPPROTO_COMP:
46895 + ipsp->ips_authalg = AH_NONE;
46896 + ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
46897 + break;
46898 +#endif /* CONFIG_KLIPS_IPCOMP */
46899 + case IPPROTO_INT:
46900 + ipsp->ips_authalg = AH_NONE;
46901 + ipsp->ips_encalg = ESP_NONE;
46902 + break;
46903 + case 0:
46904 + break;
46905 + default:
46906 + KLIPS_PRINT(debug_pfkey,
46907 + "klips_debug:pfkey_sa_process: "
46908 + "unknown proto=%d.\n",
46909 + ipsp->ips_said.proto);
46910 + SENDERR(EINVAL);
46911 + }
46912 +
46913 +errlab:
46914 + return error;
46915 +}
46916 +
46917 +int
46918 +pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
46919 +{
46920 + int error = 0;
46921 + struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
46922 +
46923 + KLIPS_PRINT(debug_pfkey,
46924 + "klips_debug:pfkey_lifetime_process: .\n");
46925 +
46926 + if(!extr || !extr->ips) {
46927 + KLIPS_PRINT(debug_pfkey,
46928 + "klips_debug:pfkey_lifetime_process: "
46929 + "extr or extr->ips is NULL, fatal\n");
46930 + SENDERR(EINVAL);
46931 + }
46932 +
46933 + switch(pfkey_lifetime->sadb_lifetime_exttype) {
46934 + case K_SADB_EXT_LIFETIME_CURRENT:
46935 + KLIPS_PRINT(debug_pfkey,
46936 + "klips_debug:pfkey_lifetime_process: "
46937 + "lifetime_current not supported yet.\n");
46938 + SENDERR(EINVAL);
46939 + break;
46940 + case K_SADB_EXT_LIFETIME_HARD:
46941 + ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_allocations,
46942 + pfkey_lifetime->sadb_lifetime_allocations);
46943 +
46944 + ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_bytes,
46945 + pfkey_lifetime->sadb_lifetime_bytes);
46946 +
46947 + ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_addtime,
46948 + pfkey_lifetime->sadb_lifetime_addtime);
46949 +
46950 + ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_usetime,
46951 + pfkey_lifetime->sadb_lifetime_usetime);
46952 +
46953 + break;
46954 +
46955 + case K_SADB_EXT_LIFETIME_SOFT:
46956 + ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_allocations,
46957 + pfkey_lifetime->sadb_lifetime_allocations);
46958 +
46959 + ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_bytes,
46960 + pfkey_lifetime->sadb_lifetime_bytes);
46961 +
46962 + ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_addtime,
46963 + pfkey_lifetime->sadb_lifetime_addtime);
46964 +
46965 + ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_usetime,
46966 + pfkey_lifetime->sadb_lifetime_usetime);
46967 +
46968 + break;
46969 + default:
46970 + KLIPS_PRINT(debug_pfkey,
46971 + "klips_debug:pfkey_lifetime_process: "
46972 + "invalid exttype=%d.\n",
46973 + pfkey_ext->sadb_ext_type);
46974 + SENDERR(EINVAL);
46975 + }
46976 +
46977 +errlab:
46978 + return error;
46979 +}
46980 +
46981 +int
46982 +pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
46983 +{
46984 + int error = 0;
46985 + int saddr_len = 0;
46986 + char ipaddr_txt[ADDRTOA_BUF];
46987 + unsigned char **sap;
46988 + unsigned short * portp = 0;
46989 + struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
46990 + struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
46991 + struct ipsec_sa* ipsp;
46992 +
46993 + KLIPS_PRINT(debug_pfkey,
46994 + "klips_debug:pfkey_address_process:\n");
46995 +
46996 + if(!extr || !extr->ips) {
46997 + KLIPS_PRINT(debug_pfkey,
46998 + "klips_debug:pfkey_address_process: "
46999 + "extr or extr->ips is NULL, fatal\n");
47000 + SENDERR(EINVAL);
47001 + }
47002 +
47003 + switch(s->sa_family) {
47004 + case AF_INET:
47005 + saddr_len = sizeof(struct sockaddr_in);
47006 + if (debug_pfkey)
47007 + addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt));
47008 + KLIPS_PRINT(debug_pfkey,
47009 + "klips_debug:pfkey_address_process: "
47010 + "found address family=%d, AF_INET, %s.\n",
47011 + s->sa_family,
47012 + ipaddr_txt);
47013 + break;
47014 +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
47015 + case AF_INET6:
47016 + saddr_len = sizeof(struct sockaddr_in6);
47017 + break;
47018 +#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
47019 + default:
47020 + KLIPS_PRINT(debug_pfkey,
47021 + "klips_debug:pfkey_address_process: "
47022 + "s->sa_family=%d not supported.\n",
47023 + s->sa_family);
47024 + SENDERR(EPFNOSUPPORT);
47025 + }
47026 +
47027 + switch(pfkey_address->sadb_address_exttype) {
47028 + case K_SADB_EXT_ADDRESS_SRC:
47029 + KLIPS_PRINT(debug_pfkey,
47030 + "klips_debug:pfkey_address_process: "
47031 + "found src address.\n");
47032 + sap = (unsigned char **)&(extr->ips->ips_addr_s);
47033 + extr->ips->ips_addr_s_size = saddr_len;
47034 + break;
47035 + case K_SADB_EXT_ADDRESS_DST:
47036 + KLIPS_PRINT(debug_pfkey,
47037 + "klips_debug:pfkey_address_process: "
47038 + "found dst address.\n");
47039 + sap = (unsigned char **)&(extr->ips->ips_addr_d);
47040 + extr->ips->ips_addr_d_size = saddr_len;
47041 + break;
47042 + case K_SADB_EXT_ADDRESS_PROXY:
47043 + KLIPS_PRINT(debug_pfkey,
47044 + "klips_debug:pfkey_address_process: "
47045 + "found proxy address.\n");
47046 + sap = (unsigned char **)&(extr->ips->ips_addr_p);
47047 + extr->ips->ips_addr_p_size = saddr_len;
47048 + break;
47049 + case K_SADB_X_EXT_ADDRESS_DST2:
47050 + KLIPS_PRINT(debug_pfkey,
47051 + "klips_debug:pfkey_address_process: "
47052 + "found 2nd dst address.\n");
47053 + if(extr->ips2 == NULL) {
47054 + extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
47055 + }
47056 + if(extr->ips2 == NULL) {
47057 + SENDERR(-error);
47058 + }
47059 + sap = (unsigned char **)&(extr->ips2->ips_addr_d);
47060 + extr->ips2->ips_addr_d_size = saddr_len;
47061 + break;
47062 + case K_SADB_X_EXT_ADDRESS_SRC_FLOW:
47063 + KLIPS_PRINT(debug_pfkey,
47064 + "klips_debug:pfkey_address_process: "
47065 + "found src flow address.\n");
47066 + if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
47067 + SENDERR(ENOMEM);
47068 + }
47069 + sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src);
47070 + portp = &(extr->eroute->er_eaddr.sen_sport);
47071 + break;
47072 + case K_SADB_X_EXT_ADDRESS_DST_FLOW:
47073 + KLIPS_PRINT(debug_pfkey,
47074 + "klips_debug:pfkey_address_process: "
47075 + "found dst flow address.\n");
47076 + if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
47077 + SENDERR(ENOMEM);
47078 + }
47079 + sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst);
47080 + portp = &(extr->eroute->er_eaddr.sen_dport);
47081 + break;
47082 + case K_SADB_X_EXT_ADDRESS_SRC_MASK:
47083 + KLIPS_PRINT(debug_pfkey,
47084 + "klips_debug:pfkey_address_process: "
47085 + "found src mask address.\n");
47086 + if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
47087 + SENDERR(ENOMEM);
47088 + }
47089 + sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src);
47090 + portp = &(extr->eroute->er_emask.sen_sport);
47091 + break;
47092 + case K_SADB_X_EXT_ADDRESS_DST_MASK:
47093 + KLIPS_PRINT(debug_pfkey,
47094 + "klips_debug:pfkey_address_process: "
47095 + "found dst mask address.\n");
47096 + if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
47097 + SENDERR(ENOMEM);
47098 + }
47099 + sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst);
47100 + portp = &(extr->eroute->er_emask.sen_dport);
47101 + break;
47102 +#ifdef NAT_TRAVERSAL
47103 + case K_SADB_X_EXT_NAT_T_OA:
47104 + KLIPS_PRINT(debug_pfkey,
47105 + "klips_debug:pfkey_address_process: "
47106 + "found NAT-OA address.\n");
47107 + sap = (unsigned char **)&(extr->ips->ips_natt_oa);
47108 + extr->ips->ips_natt_oa_size = saddr_len;
47109 + break;
47110 +#endif
47111 + default:
47112 + KLIPS_PRINT(debug_pfkey,
47113 + "klips_debug:pfkey_address_process: "
47114 + "unrecognised ext_type=%d.\n",
47115 + pfkey_address->sadb_address_exttype);
47116 + SENDERR(EINVAL);
47117 + }
47118 +
47119 + switch(pfkey_address->sadb_address_exttype) {
47120 + case K_SADB_EXT_ADDRESS_SRC:
47121 + case K_SADB_EXT_ADDRESS_DST:
47122 + case K_SADB_EXT_ADDRESS_PROXY:
47123 + case K_SADB_X_EXT_ADDRESS_DST2:
47124 +#ifdef NAT_TRAVERSAL
47125 + case K_SADB_X_EXT_NAT_T_OA:
47126 +#endif
47127 + KLIPS_PRINT(debug_pfkey,
47128 + "klips_debug:pfkey_address_process: "
47129 + "allocating %d bytes for saddr.\n",
47130 + saddr_len);
47131 + if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) {
47132 + SENDERR(ENOMEM);
47133 + }
47134 + memcpy(*sap, s, saddr_len);
47135 + break;
47136 + default:
47137 + if(s->sa_family != AF_INET) {
47138 + KLIPS_PRINT(debug_pfkey,
47139 + "klips_debug:pfkey_address_process: "
47140 + "s->sa_family=%d not supported.\n",
47141 + s->sa_family);
47142 + SENDERR(EPFNOSUPPORT);
47143 + }
47144 + {
47145 + *(struct in_addr *)sap = ((struct sockaddr_in *)s)->sin_addr;
47146 + }
47147 +
47148 + if (portp != 0)
47149 + *portp = ((struct sockaddr_in*)s)->sin_port;
47150 +#ifdef CONFIG_KLIPS_DEBUG
47151 + if(extr->eroute) {
47152 + char buf1[64], buf2[64];
47153 + if (debug_pfkey) {
47154 + subnettoa(extr->eroute->er_eaddr.sen_ip_src,
47155 + extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
47156 + subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
47157 + extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
47158 + KLIPS_PRINT(debug_pfkey,
47159 + "klips_debug:pfkey_address_parse: "
47160 + "extr->eroute set to %s:%d->%s:%d\n",
47161 + buf1,
47162 + ntohs(extr->eroute->er_eaddr.sen_sport),
47163 + buf2,
47164 + ntohs(extr->eroute->er_eaddr.sen_dport));
47165 + }
47166 + }
47167 +#endif /* CONFIG_KLIPS_DEBUG */
47168 + }
47169 +
47170 + ipsp = extr->ips;
47171 + switch(pfkey_address->sadb_address_exttype) {
47172 + case K_SADB_X_EXT_ADDRESS_DST2:
47173 + ipsp = extr->ips2;
47174 + case K_SADB_EXT_ADDRESS_DST:
47175 + if(s->sa_family == AF_INET) {
47176 + ipsp->ips_said.dst.u.v4.sin_addr.s_addr = ((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr.s_addr;
47177 + ipsp->ips_said.dst.u.v4.sin_family = AF_INET;
47178 + if (debug_pfkey)
47179 + addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
47180 + 0,
47181 + ipaddr_txt,
47182 + sizeof(ipaddr_txt));
47183 + KLIPS_PRINT(debug_pfkey,
47184 + "klips_debug:pfkey_address_process: "
47185 + "ips_said.dst set to %s.\n",
47186 + ipaddr_txt);
47187 + } else {
47188 + KLIPS_PRINT(debug_pfkey,
47189 + "klips_debug:pfkey_address_process: "
47190 + "uh, ips_said.dst doesn't do address family=%d yet, said will be invalid.\n",
47191 + s->sa_family);
47192 + }
47193 + default:
47194 + break;
47195 + }
47196 +
47197 + /* XXX check if port!=0 */
47198 +
47199 + KLIPS_PRINT(debug_pfkey,
47200 + "klips_debug:pfkey_address_process: successful.\n");
47201 + errlab:
47202 + return error;
47203 +}
47204 +
47205 +int
47206 +pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
47207 +{
47208 + int error = 0;
47209 + struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
47210 +
47211 + KLIPS_PRINT(debug_pfkey,
47212 + "klips_debug:pfkey_key_process: .\n");
47213 +
47214 + if(!extr || !extr->ips) {
47215 + KLIPS_PRINT(debug_pfkey,
47216 + "klips_debug:pfkey_key_process: "
47217 + "extr or extr->ips is NULL, fatal\n");
47218 + SENDERR(EINVAL);
47219 + }
47220 +
47221 + switch(pfkey_key->sadb_key_exttype) {
47222 + case K_SADB_EXT_KEY_AUTH:
47223 + KLIPS_PRINT(debug_pfkey,
47224 + "klips_debug:pfkey_key_process: "
47225 + "allocating %d bytes for authkey.\n",
47226 + DIVUP(pfkey_key->sadb_key_bits, 8));
47227 + if(!(extr->ips->ips_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
47228 + KLIPS_PRINT(debug_pfkey,
47229 + "klips_debug:pfkey_key_process: "
47230 + "memory allocation error.\n");
47231 + SENDERR(ENOMEM);
47232 + }
47233 + extr->ips->ips_key_bits_a = pfkey_key->sadb_key_bits;
47234 + extr->ips->ips_key_a_size = DIVUP(pfkey_key->sadb_key_bits, 8);
47235 + memcpy(extr->ips->ips_key_a,
47236 + (char*)pfkey_key + sizeof(struct sadb_key),
47237 + extr->ips->ips_key_a_size);
47238 + break;
47239 + case K_SADB_EXT_KEY_ENCRYPT: /* Key(s) */
47240 + KLIPS_PRINT(debug_pfkey,
47241 + "klips_debug:pfkey_key_process: "
47242 + "allocating %d bytes for enckey.\n",
47243 + DIVUP(pfkey_key->sadb_key_bits, 8));
47244 + if(!(extr->ips->ips_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
47245 + KLIPS_PRINT(debug_pfkey,
47246 + "klips_debug:pfkey_key_process: "
47247 + "memory allocation error.\n");
47248 + SENDERR(ENOMEM);
47249 + }
47250 + extr->ips->ips_key_bits_e = pfkey_key->sadb_key_bits;
47251 + extr->ips->ips_key_e_size = DIVUP(pfkey_key->sadb_key_bits, 8);
47252 + memcpy(extr->ips->ips_key_e,
47253 + (char*)pfkey_key + sizeof(struct sadb_key),
47254 + extr->ips->ips_key_e_size);
47255 + break;
47256 + default:
47257 + SENDERR(EINVAL);
47258 + }
47259 +
47260 + KLIPS_PRINT(debug_pfkey,
47261 + "klips_debug:pfkey_key_process: "
47262 + "success.\n");
47263 +errlab:
47264 + return error;
47265 +}
47266 +
47267 +int
47268 +pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
47269 +{
47270 + int error = 0;
47271 + struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
47272 + int data_len;
47273 +
47274 + KLIPS_PRINT(debug_pfkey,
47275 + "klips_debug:pfkey_ident_process: .\n");
47276 +
47277 + if(!extr || !extr->ips) {
47278 + KLIPS_PRINT(debug_pfkey,
47279 + "klips_debug:pfkey_ident_process: "
47280 + "extr or extr->ips is NULL, fatal\n");
47281 + SENDERR(EINVAL);
47282 + }
47283 +
47284 + switch(pfkey_ident->sadb_ident_exttype) {
47285 + case K_SADB_EXT_IDENTITY_SRC:
47286 + data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
47287 +
47288 + extr->ips->ips_ident_s.type = pfkey_ident->sadb_ident_type;
47289 + extr->ips->ips_ident_s.id = pfkey_ident->sadb_ident_id;
47290 + extr->ips->ips_ident_s.len = pfkey_ident->sadb_ident_len;
47291 + if(data_len) {
47292 + KLIPS_PRINT(debug_pfkey,
47293 + "klips_debug:pfkey_ident_process: "
47294 + "allocating %d bytes for ident_s.\n",
47295 + data_len);
47296 + if(!(extr->ips->ips_ident_s.data
47297 + = kmalloc(data_len, GFP_KERNEL))) {
47298 + SENDERR(ENOMEM);
47299 + }
47300 + memcpy(extr->ips->ips_ident_s.data,
47301 + (char*)pfkey_ident + sizeof(struct sadb_ident),
47302 + data_len);
47303 + } else {
47304 + extr->ips->ips_ident_s.data = NULL;
47305 + }
47306 + break;
47307 + case K_SADB_EXT_IDENTITY_DST: /* Identity(ies) */
47308 + data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
47309 +
47310 + extr->ips->ips_ident_d.type = pfkey_ident->sadb_ident_type;
47311 + extr->ips->ips_ident_d.id = pfkey_ident->sadb_ident_id;
47312 + extr->ips->ips_ident_d.len = pfkey_ident->sadb_ident_len;
47313 + if(data_len) {
47314 + KLIPS_PRINT(debug_pfkey,
47315 + "klips_debug:pfkey_ident_process: "
47316 + "allocating %d bytes for ident_d.\n",
47317 + data_len);
47318 + if(!(extr->ips->ips_ident_d.data
47319 + = kmalloc(data_len, GFP_KERNEL))) {
47320 + SENDERR(ENOMEM);
47321 + }
47322 + memcpy(extr->ips->ips_ident_d.data,
47323 + (char*)pfkey_ident + sizeof(struct sadb_ident),
47324 + data_len);
47325 + } else {
47326 + extr->ips->ips_ident_d.data = NULL;
47327 + }
47328 + break;
47329 + default:
47330 + SENDERR(EINVAL);
47331 + }
47332 +errlab:
47333 + return error;
47334 +}
47335 +
47336 +int
47337 +pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
47338 +{
47339 + int error = 0;
47340 +
47341 + KLIPS_PRINT(debug_pfkey,
47342 + "klips_debug:pfkey_sens_process: "
47343 + "Sorry, I can't process exttype=%d yet.\n",
47344 + pfkey_ext->sadb_ext_type);
47345 + SENDERR(EINVAL); /* don't process these yet */
47346 + errlab:
47347 + return error;
47348 +}
47349 +
47350 +int
47351 +pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
47352 +{
47353 + int error = 0;
47354 +
47355 + KLIPS_PRINT(debug_pfkey,
47356 + "klips_debug:pfkey_prop_process: "
47357 + "Sorry, I can't process exttype=%d yet.\n",
47358 + pfkey_ext->sadb_ext_type);
47359 + SENDERR(EINVAL); /* don't process these yet */
47360 +
47361 + errlab:
47362 + return error;
47363 +}
47364 +
47365 +int
47366 +pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
47367 +{
47368 + int error = 0;
47369 +
47370 + KLIPS_PRINT(debug_pfkey,
47371 + "klips_debug:pfkey_supported_process: "
47372 + "Sorry, I can't process exttype=%d yet.\n",
47373 + pfkey_ext->sadb_ext_type);
47374 + SENDERR(EINVAL); /* don't process these yet */
47375 +
47376 +errlab:
47377 + return error;
47378 +}
47379 +
47380 +int
47381 +pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
47382 +{
47383 + int error = 0;
47384 +
47385 + KLIPS_PRINT(debug_pfkey,
47386 + "klips_debug:pfkey_spirange_process: .\n");
47387 +/* errlab: */
47388 + return error;
47389 +}
47390 +
47391 +int
47392 +pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
47393 +{
47394 + int error = 0;
47395 +
47396 + KLIPS_PRINT(debug_pfkey,
47397 + "klips_debug:pfkey_x_kmprivate_process: "
47398 + "Sorry, I can't process exttype=%d yet.\n",
47399 + pfkey_ext->sadb_ext_type);
47400 + SENDERR(EINVAL); /* don't process these yet */
47401 +
47402 +errlab:
47403 + return error;
47404 +}
47405 +
47406 +int
47407 +pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
47408 +{
47409 + int error = 0;
47410 + struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
47411 +
47412 + KLIPS_PRINT(debug_pfkey,
47413 + "pfkey_x_satype_process: .\n");
47414 +
47415 + if(!extr || !extr->ips) {
47416 + KLIPS_PRINT(debug_pfkey,
47417 + "pfkey_x_satype_process: "
47418 + "extr or extr->ips is NULL, fatal\n");
47419 + SENDERR(EINVAL);
47420 + }
47421 +
47422 + if(extr->ips2 == NULL) {
47423 + extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
47424 + }
47425 + if(extr->ips2 == NULL) {
47426 + SENDERR(-error);
47427 + }
47428 + if(!(extr->ips2->ips_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
47429 + KLIPS_ERROR(debug_pfkey,
47430 + "pfkey_x_satype_process: "
47431 + "proto lookup from satype=%d failed.\n",
47432 + pfkey_x_satype->sadb_x_satype_satype);
47433 + SENDERR(EINVAL);
47434 + }
47435 + KLIPS_PRINT(debug_pfkey,
47436 + "pfkey_x_satype_process: "
47437 + "protocol==%d decoded from satype==%d(%s).\n",
47438 + extr->ips2->ips_said.proto,
47439 + pfkey_x_satype->sadb_x_satype_satype,
47440 + satype2name(pfkey_x_satype->sadb_x_satype_satype));
47441 +
47442 +errlab:
47443 + return error;
47444 +}
47445 +
47446 +
47447 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
47448 +int
47449 +pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
47450 +{
47451 + int error = 0;
47452 + struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)pfkey_ext;
47453 +
47454 + if(!pfkey_x_nat_t_type) {
47455 + printk("klips_debug:pfkey_x_nat_t_type_process: "
47456 + "null pointer passed in\n");
47457 + SENDERR(EINVAL);
47458 + }
47459 +
47460 + KLIPS_PRINT(debug_pfkey,
47461 + "klips_debug:pfkey_x_nat_t_type_process: %d.\n",
47462 + pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
47463 +
47464 + if(!extr || !extr->ips) {
47465 + KLIPS_PRINT(debug_pfkey,
47466 + "klips_debug:pfkey_nat_t_type_process: "
47467 + "extr or extr->ips is NULL, fatal\n");
47468 + SENDERR(EINVAL);
47469 + }
47470 +
47471 + switch(pfkey_x_nat_t_type->sadb_x_nat_t_type_type) {
47472 + case ESPINUDP_WITH_NON_IKE: /* with Non-IKE (older version) */
47473 + case ESPINUDP_WITH_NON_ESP: /* with Non-ESP */
47474 +
47475 + extr->ips->ips_natt_type = pfkey_x_nat_t_type->sadb_x_nat_t_type_type;
47476 + break;
47477 + default:
47478 + KLIPS_PRINT(debug_pfkey,
47479 + "klips_debug:pfkey_x_nat_t_type_process: "
47480 + "unknown type %d.\n",
47481 + pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
47482 + SENDERR(EINVAL);
47483 + break;
47484 + }
47485 +
47486 +errlab:
47487 + return error;
47488 +}
47489 +
47490 +int
47491 +pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
47492 +{
47493 + int error = 0;
47494 + struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)pfkey_ext;
47495 +
47496 + if(!pfkey_x_nat_t_port) {
47497 + printk("klips_debug:pfkey_x_nat_t_port_process: "
47498 + "null pointer passed in\n");
47499 + SENDERR(EINVAL);
47500 + }
47501 +
47502 + KLIPS_PRINT(debug_pfkey,
47503 + "klips_debug:pfkey_x_nat_t_port_process: %d/%d.\n",
47504 + pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype,
47505 + pfkey_x_nat_t_port->sadb_x_nat_t_port_port);
47506 +
47507 + if(!extr || !extr->ips) {
47508 + KLIPS_PRINT(debug_pfkey,
47509 + "klips_debug:pfkey_nat_t_type_process: "
47510 + "extr or extr->ips is NULL, fatal\n");
47511 + SENDERR(EINVAL);
47512 + }
47513 +
47514 + switch(pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype) {
47515 + case K_SADB_X_EXT_NAT_T_SPORT:
47516 + extr->ips->ips_natt_sport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
47517 + break;
47518 + case K_SADB_X_EXT_NAT_T_DPORT:
47519 + extr->ips->ips_natt_dport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
47520 + break;
47521 + default:
47522 + KLIPS_PRINT(debug_pfkey,
47523 + "klips_debug:pfkey_x_nat_t_port_process: "
47524 + "unknown exttype %d.\n",
47525 + pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype);
47526 + SENDERR(EINVAL);
47527 + break;
47528 + }
47529 +
47530 +errlab:
47531 + return error;
47532 +}
47533 +#endif
47534 +
47535 +int
47536 +pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
47537 +{
47538 + int error = 0;
47539 + struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
47540 +
47541 + if(!pfkey_x_debug) {
47542 + printk("klips_debug:pfkey_x_debug_process: "
47543 + "null pointer passed in\n");
47544 + SENDERR(EINVAL);
47545 + }
47546 +
47547 + KLIPS_PRINT(debug_pfkey,
47548 + "klips_debug:pfkey_x_debug_process: .\n");
47549 +
47550 +#ifdef CONFIG_KLIPS_DEBUG
47551 + if(pfkey_x_debug->sadb_x_debug_netlink >>
47552 + (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) {
47553 + pfkey_x_debug->sadb_x_debug_netlink &=
47554 + ~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1));
47555 + debug_tunnel |= pfkey_x_debug->sadb_x_debug_tunnel;
47556 + debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink;
47557 + debug_xform |= pfkey_x_debug->sadb_x_debug_xform;
47558 + debug_eroute |= pfkey_x_debug->sadb_x_debug_eroute;
47559 + debug_spi |= pfkey_x_debug->sadb_x_debug_spi;
47560 + debug_radij |= pfkey_x_debug->sadb_x_debug_radij;
47561 + debug_esp |= pfkey_x_debug->sadb_x_debug_esp;
47562 + debug_ah |= pfkey_x_debug->sadb_x_debug_ah;
47563 + debug_rcv |= pfkey_x_debug->sadb_x_debug_rcv;
47564 + debug_pfkey |= pfkey_x_debug->sadb_x_debug_pfkey;
47565 +#ifdef CONFIG_KLIPS_IPCOMP
47566 + sysctl_ipsec_debug_ipcomp |= pfkey_x_debug->sadb_x_debug_ipcomp;
47567 +#endif /* CONFIG_KLIPS_IPCOMP */
47568 + sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose;
47569 + KLIPS_PRINT(debug_pfkey,
47570 + "klips_debug:pfkey_x_debug_process: "
47571 + "set\n");
47572 + } else {
47573 + KLIPS_PRINT(debug_pfkey,
47574 + "klips_debug:pfkey_x_debug_process: "
47575 + "unset\n");
47576 + debug_tunnel &= pfkey_x_debug->sadb_x_debug_tunnel;
47577 + debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink;
47578 + debug_xform &= pfkey_x_debug->sadb_x_debug_xform;
47579 + debug_eroute &= pfkey_x_debug->sadb_x_debug_eroute;
47580 + debug_spi &= pfkey_x_debug->sadb_x_debug_spi;
47581 + debug_radij &= pfkey_x_debug->sadb_x_debug_radij;
47582 + debug_esp &= pfkey_x_debug->sadb_x_debug_esp;
47583 + debug_ah &= pfkey_x_debug->sadb_x_debug_ah;
47584 + debug_rcv &= pfkey_x_debug->sadb_x_debug_rcv;
47585 + debug_pfkey &= pfkey_x_debug->sadb_x_debug_pfkey;
47586 +#ifdef CONFIG_KLIPS_IPCOMP
47587 + sysctl_ipsec_debug_ipcomp &= pfkey_x_debug->sadb_x_debug_ipcomp;
47588 +#endif /* CONFIG_KLIPS_IPCOMP */
47589 + sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose;
47590 + }
47591 +#else /* CONFIG_KLIPS_DEBUG */
47592 + printk("klips_debug:pfkey_x_debug_process: "
47593 + "debugging not enabled\n");
47594 + SENDERR(EINVAL);
47595 +#endif /* CONFIG_KLIPS_DEBUG */
47596 +
47597 +errlab:
47598 + return error;
47599 +}
47600 +
47601 +/*
47602 + * Local variables:
47603 + * c-file-style: "linux"
47604 + * End:
47605 + *
47606 + */
47607 --- /dev/null Tue Mar 11 13:02:56 2003
47608 +++ linux/net/ipsec/pfkey_v2_parse.c Mon Feb 9 13:51:03 2004
47609 @@ -0,0 +1,1597 @@
47610 +/*
47611 + * RFC2367 PF_KEYv2 Key management API message parser
47612 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
47613 + *
47614 + * This program is free software; you can redistribute it and/or modify it
47615 + * under the terms of the GNU General Public License as published by the
47616 + * Free Software Foundation; either version 2 of the License, or (at your
47617 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
47618 + *
47619 + * This program is distributed in the hope that it will be useful, but
47620 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
47621 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
47622 + * for more details.
47623 + *
47624 + * RCSID $Id: pfkey_v2_parse.c,v 1.65 2005/04/06 17:46:05 mcr Exp $
47625 + */
47626 +
47627 +/*
47628 + * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
47629 + */
47630 +
47631 +char pfkey_v2_parse_c_version[] = "$Id: pfkey_v2_parse.c,v 1.65 2005/04/06 17:46:05 mcr Exp $";
47632 +
47633 +/*
47634 + * Some ugly stuff to allow consistent debugging code for use in the
47635 + * kernel and in user space
47636 +*/
47637 +
47638 +#ifdef __KERNEL__
47639 +
47640 +# include <linux/kernel.h> /* for printk */
47641 +
47642 +#include "openswan/ipsec_kversion.h" /* for malloc switch */
47643 +
47644 +# ifdef MALLOC_SLAB
47645 +# include <linux/slab.h> /* kmalloc() */
47646 +# else /* MALLOC_SLAB */
47647 +# include <linux/malloc.h> /* kmalloc() */
47648 +# endif /* MALLOC_SLAB */
47649 +# include <linux/errno.h> /* error codes */
47650 +# include <linux/types.h> /* size_t */
47651 +# include <linux/interrupt.h> /* mark_bh */
47652 +
47653 +# include <linux/netdevice.h> /* struct device, and other headers */
47654 +# include <linux/etherdevice.h> /* eth_type_trans */
47655 +# include <linux/ip.h> /* struct iphdr */
47656 +# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
47657 +# include <linux/ipv6.h> /* struct ipv6hdr */
47658 +# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
47659 +extern int debug_pfkey;
47660 +
47661 +# include <openswan.h>
47662 +
47663 +#include "openswan/ipsec_encap.h"
47664 +
47665 +#else /* __KERNEL__ */
47666 +
47667 +# include <sys/types.h>
47668 +# include <sys/errno.h>
47669 +# include <stdio.h>
47670 +
47671 +# include <openswan.h>
47672 +# include "constants.h"
47673 +
47674 +#endif /* __KERNEL__ */
47675 +
47676 +
47677 +#include <openswan/pfkeyv2.h>
47678 +#include <openswan/pfkey.h>
47679 +
47680 +#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
47681 +
47682 +/*
47683 + * how to handle debugging for pfkey.
47684 + */
47685 +#include <openswan/pfkey_debug.h>
47686 +
47687 +unsigned int pfkey_lib_debug = PF_KEY_DEBUG_PARSE_NONE;
47688 +int (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
47689 +int (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
47690 +
47691 +
47692 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
47693 +
47694 +struct satype_tbl {
47695 + uint8_t proto;
47696 + uint8_t satype;
47697 + char* name;
47698 +} static satype_tbl[] = {
47699 +#ifdef __KERNEL__
47700 + { IPPROTO_ESP, K_SADB_SATYPE_ESP, "ESP" },
47701 + { IPPROTO_AH, K_SADB_SATYPE_AH, "AH" },
47702 + { IPPROTO_IPIP, K_SADB_X_SATYPE_IPIP, "IPIP" },
47703 +#ifdef CONFIG_KLIPS_IPCOMP
47704 + { IPPROTO_COMP, K_SADB_X_SATYPE_COMP, "COMP" },
47705 +#endif /* CONFIG_KLIPS_IPCOMP */
47706 + { IPPROTO_INT, K_SADB_X_SATYPE_INT, "INT" },
47707 +#else /* __KERNEL__ */
47708 + { SA_ESP, K_SADB_SATYPE_ESP, "ESP" },
47709 + { SA_AH, K_SADB_SATYPE_AH, "AH" },
47710 + { SA_IPIP, K_SADB_X_SATYPE_IPIP, "IPIP" },
47711 + { SA_COMP, K_SADB_X_SATYPE_COMP, "COMP" },
47712 + { SA_INT, K_SADB_X_SATYPE_INT, "INT" },
47713 +#endif /* __KERNEL__ */
47714 + { 0, 0, "UNKNOWN" }
47715 +};
47716 +
47717 +uint8_t
47718 +satype2proto(uint8_t satype)
47719 +{
47720 + int i =0;
47721 +
47722 + while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
47723 + i++;
47724 + }
47725 + return satype_tbl[i].proto;
47726 +}
47727 +
47728 +uint8_t
47729 +proto2satype(uint8_t proto)
47730 +{
47731 + int i = 0;
47732 +
47733 + while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
47734 + i++;
47735 + }
47736 + return satype_tbl[i].satype;
47737 +}
47738 +
47739 +char*
47740 +satype2name(uint8_t satype)
47741 +{
47742 + int i = 0;
47743 +
47744 + while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
47745 + i++;
47746 + }
47747 + return satype_tbl[i].name;
47748 +}
47749 +
47750 +char*
47751 +proto2name(uint8_t proto)
47752 +{
47753 + int i = 0;
47754 +
47755 + while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
47756 + i++;
47757 + }
47758 + return satype_tbl[i].name;
47759 +}
47760 +
47761 +/* Default extension parsers taken from the KLIPS code */
47762 +
47763 +DEBUG_NO_STATIC int
47764 +pfkey_sa_parse(struct sadb_ext *pfkey_ext)
47765 +{
47766 + int error = 0;
47767 + struct k_sadb_sa *pfkey_sa = (struct k_sadb_sa *)pfkey_ext;
47768 +
47769 + /* sanity checks... */
47770 + if(!pfkey_sa) {
47771 + ERROR("pfkey_sa_parse: "
47772 + "NULL pointer passed in.\n");
47773 + SENDERR(EINVAL);
47774 + }
47775 +
47776 +
47777 +
47778 + if(pfkey_sa->sadb_sa_len !=sizeof(struct k_sadb_sa)/IPSEC_PFKEYv2_ALIGN
47779 + && pfkey_sa->sadb_sa_len!=sizeof(struct sadb_sa)/IPSEC_PFKEYv2_ALIGN) {
47780 + ERROR(
47781 + "pfkey_sa_parse: "
47782 + "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n",
47783 + pfkey_sa->sadb_sa_len,
47784 + (int)sizeof(struct k_sadb_sa));
47785 + SENDERR(EINVAL);
47786 + }
47787 +
47788 +#if K_SADB_EALG_MAX < 255
47789 + if(pfkey_sa->sadb_sa_encrypt > K_SADB_EALG_MAX) {
47790 + ERROR(
47791 + "pfkey_sa_parse: "
47792 + "pfkey_sa->sadb_sa_encrypt=%d > K_SADB_EALG_MAX=%d.\n",
47793 + pfkey_sa->sadb_sa_encrypt,
47794 + K_SADB_EALG_MAX);
47795 + SENDERR(EINVAL);
47796 + }
47797 +#endif
47798 +
47799 +#if K_SADB_AALG_MAX < 255
47800 + if(pfkey_sa->sadb_sa_auth > K_SADB_AALG_MAX) {
47801 + ERROR(
47802 + "pfkey_sa_parse: "
47803 + "pfkey_sa->sadb_sa_auth=%d > K_SADB_AALG_MAX=%d.\n",
47804 + pfkey_sa->sadb_sa_auth,
47805 + K_SADB_AALG_MAX);
47806 + SENDERR(EINVAL);
47807 + }
47808 +#endif
47809 +
47810 +#if K_SADB_SASTATE_MAX < 255
47811 + if(pfkey_sa->sadb_sa_state > K_SADB_SASTATE_MAX) {
47812 + ERROR(
47813 + "pfkey_sa_parse: "
47814 + "state=%d exceeds MAX=%d.\n",
47815 + pfkey_sa->sadb_sa_state,
47816 + K_SADB_SASTATE_MAX);
47817 + SENDERR(EINVAL);
47818 + }
47819 +#endif
47820 +
47821 + if(pfkey_sa->sadb_sa_state == K_SADB_SASTATE_DEAD) {
47822 + ERROR(
47823 + "pfkey_sa_parse: "
47824 + "state=%d is DEAD=%d.\n",
47825 + pfkey_sa->sadb_sa_state,
47826 + K_SADB_SASTATE_DEAD);
47827 + SENDERR(EINVAL);
47828 + }
47829 +
47830 + if(pfkey_sa->sadb_sa_replay > 64) {
47831 + ERROR(
47832 + "pfkey_sa_parse: "
47833 + "replay window size: %d -- must be 0 <= size <= 64\n",
47834 + pfkey_sa->sadb_sa_replay);
47835 + SENDERR(EINVAL);
47836 + }
47837 +
47838 + if(! ((pfkey_sa->sadb_sa_exttype == K_SADB_EXT_SA) ||
47839 + (pfkey_sa->sadb_sa_exttype == K_SADB_X_EXT_SA2)))
47840 + {
47841 + ERROR(
47842 + "pfkey_sa_parse: "
47843 + "unknown exttype=%d, expecting K_SADB_EXT_SA=%d or K_SADB_X_EXT_SA2=%d.\n",
47844 + pfkey_sa->sadb_sa_exttype,
47845 + K_SADB_EXT_SA,
47846 + K_SADB_X_EXT_SA2);
47847 + SENDERR(EINVAL);
47848 + }
47849 +
47850 + if(pfkey_sa->sadb_sa_len > sizeof(struct sadb_sa)/IPSEC_PFKEYv2_ALIGN) {
47851 + if(pfkey_sa->sadb_x_sa_ref == IPSEC_SAREF_NULL ||
47852 + pfkey_sa->sadb_x_sa_ref == ~(IPSEC_SAREF_NULL))
47853 + {
47854 + pfkey_sa->sadb_x_sa_ref = IPSEC_SAREF_NULL;
47855 + }
47856 + }
47857 +
47858 + if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref)
47859 + && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH)))
47860 + {
47861 + ERROR(
47862 + "pfkey_sa_parse: "
47863 + "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
47864 + pfkey_sa->sadb_x_sa_ref,
47865 + IPSEC_SAREF_NULL,
47866 + IPSEC_SA_REF_TABLE_NUM_ENTRIES);
47867 + SENDERR(EINVAL);
47868 + }
47869 +
47870 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
47871 + "pfkey_sa_parse: "
47872 + "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n",
47873 + pfkey_sa->sadb_sa_len,
47874 + pfkey_sa->sadb_sa_exttype,
47875 + pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype),
47876 + (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi),
47877 + pfkey_sa->sadb_sa_replay,
47878 + pfkey_sa->sadb_sa_state,
47879 + pfkey_sa->sadb_sa_auth,
47880 + pfkey_sa->sadb_sa_encrypt,
47881 + pfkey_sa->sadb_sa_flags,
47882 + pfkey_sa->sadb_x_sa_ref);
47883 +
47884 + errlab:
47885 + return error;
47886 +}
47887 +
47888 +DEBUG_NO_STATIC int
47889 +pfkey_lifetime_parse(struct sadb_ext *pfkey_ext)
47890 +{
47891 + int error = 0;
47892 + struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
47893 +
47894 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
47895 + "pfkey_lifetime_parse:enter\n");
47896 + /* sanity checks... */
47897 + if(!pfkey_lifetime) {
47898 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
47899 + "pfkey_lifetime_parse: "
47900 + "NULL pointer passed in.\n");
47901 + SENDERR(EINVAL);
47902 + }
47903 +
47904 + if(pfkey_lifetime->sadb_lifetime_len !=
47905 + sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) {
47906 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
47907 + "pfkey_lifetime_parse: "
47908 + "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n",
47909 + pfkey_lifetime->sadb_lifetime_len,
47910 + (int)sizeof(struct sadb_lifetime));
47911 + SENDERR(EINVAL);
47912 + }
47913 +
47914 + if((pfkey_lifetime->sadb_lifetime_exttype != K_SADB_EXT_LIFETIME_HARD) &&
47915 + (pfkey_lifetime->sadb_lifetime_exttype != K_SADB_EXT_LIFETIME_SOFT) &&
47916 + (pfkey_lifetime->sadb_lifetime_exttype != K_SADB_EXT_LIFETIME_CURRENT)) {
47917 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
47918 + "pfkey_lifetime_parse: "
47919 + "unexpected ext_type=%d.\n",
47920 + pfkey_lifetime->sadb_lifetime_exttype);
47921 + SENDERR(EINVAL);
47922 + }
47923 +
47924 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
47925 + "pfkey_lifetime_parse: "
47926 + "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u.\n",
47927 + pfkey_lifetime->sadb_lifetime_exttype,
47928 + pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype),
47929 + pfkey_lifetime->sadb_lifetime_allocations,
47930 + (unsigned)pfkey_lifetime->sadb_lifetime_bytes,
47931 + (unsigned)pfkey_lifetime->sadb_lifetime_addtime,
47932 + (unsigned)pfkey_lifetime->sadb_lifetime_usetime);
47933 +errlab:
47934 + return error;
47935 +}
47936 +
47937 +DEBUG_NO_STATIC int
47938 +pfkey_address_parse(struct sadb_ext *pfkey_ext)
47939 +{
47940 + int error = 0;
47941 + int saddr_len = 0;
47942 + struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
47943 + struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
47944 + char ipaddr_txt[ADDRTOT_BUF];
47945 +
47946 + /* sanity checks... */
47947 + if(!pfkey_address) {
47948 + ERROR(
47949 + "pfkey_address_parse: "
47950 + "NULL pointer passed in.\n");
47951 + SENDERR(EINVAL);
47952 + }
47953 +
47954 + if(pfkey_address->sadb_address_len <
47955 + (sizeof(struct sadb_address) + sizeof(struct sockaddr))/
47956 + IPSEC_PFKEYv2_ALIGN) {
47957 + ERROR("pfkey_address_parse: "
47958 + "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
47959 + pfkey_address->sadb_address_len,
47960 + (int)sizeof(struct sadb_address),
47961 + (int)sizeof(struct sockaddr));
47962 + SENDERR(EINVAL);
47963 + }
47964 +
47965 + if(pfkey_address->sadb_address_reserved) {
47966 + ERROR("pfkey_address_parse: "
47967 + "res=%d, must be zero.\n",
47968 + pfkey_address->sadb_address_reserved);
47969 + SENDERR(EINVAL);
47970 + }
47971 +
47972 + switch(pfkey_address->sadb_address_exttype) {
47973 + case K_SADB_EXT_ADDRESS_SRC:
47974 + case K_SADB_EXT_ADDRESS_DST:
47975 + case K_SADB_EXT_ADDRESS_PROXY:
47976 + case K_SADB_X_EXT_ADDRESS_DST2:
47977 + case K_SADB_X_EXT_ADDRESS_SRC_FLOW:
47978 + case K_SADB_X_EXT_ADDRESS_DST_FLOW:
47979 + case K_SADB_X_EXT_ADDRESS_SRC_MASK:
47980 + case K_SADB_X_EXT_ADDRESS_DST_MASK:
47981 +#ifdef NAT_TRAVERSAL
47982 + case K_SADB_X_EXT_NAT_T_OA:
47983 +#endif
47984 + break;
47985 + default:
47986 + ERROR(
47987 + "pfkey_address_parse: "
47988 + "unexpected ext_type=%d.\n",
47989 + pfkey_address->sadb_address_exttype);
47990 + SENDERR(ENODEV);
47991 + }
47992 +
47993 + switch(s->sa_family) {
47994 + case AF_INET:
47995 + saddr_len = sizeof(struct sockaddr_in);
47996 + sprintf(ipaddr_txt, "%d.%d.%d.%d"
47997 + , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 0) & 0xFF
47998 + , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 8) & 0xFF
47999 + , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF
48000 + , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF);
48001 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
48002 + "pfkey_address_parse: "
48003 + "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n",
48004 + pfkey_address->sadb_address_exttype,
48005 + pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
48006 + s->sa_family,
48007 + ipaddr_txt,
48008 + pfkey_address->sadb_address_proto,
48009 + ntohs(((struct sockaddr_in*)s)->sin_port));
48010 + break;
48011 + case AF_INET6:
48012 + saddr_len = sizeof(struct sockaddr_in6);
48013 + sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x"
48014 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0])
48015 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1])
48016 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2])
48017 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3])
48018 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4])
48019 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5])
48020 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6])
48021 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7]));
48022 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
48023 + "pfkey_address_parse: "
48024 + "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n",
48025 + pfkey_address->sadb_address_exttype,
48026 + pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
48027 + s->sa_family,
48028 + ipaddr_txt,
48029 + pfkey_address->sadb_address_proto,
48030 + ((struct sockaddr_in6*)s)->sin6_port);
48031 + break;
48032 + default:
48033 + ERROR(
48034 + "pfkey_address_parse: "
48035 + "s->sa_family=%d not supported.\n",
48036 + s->sa_family);
48037 + SENDERR(EPFNOSUPPORT);
48038 + }
48039 +
48040 + if(pfkey_address->sadb_address_len !=
48041 + DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) {
48042 + ERROR(
48043 + "pfkey_address_parse: "
48044 + "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
48045 + pfkey_address->sadb_address_len,
48046 + (int)sizeof(struct sadb_address),
48047 + saddr_len);
48048 + SENDERR(EINVAL);
48049 + }
48050 +
48051 + if(pfkey_address->sadb_address_prefixlen != 0) {
48052 + ERROR(
48053 + "pfkey_address_parse: "
48054 + "address prefixes not supported yet.\n");
48055 + SENDERR(EAFNOSUPPORT); /* not supported yet */
48056 + }
48057 +
48058 + /* XXX check if port!=0 */
48059 +
48060 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
48061 + "pfkey_address_parse: successful.\n");
48062 + errlab:
48063 + return error;
48064 +}
48065 +
48066 +DEBUG_NO_STATIC int
48067 +pfkey_key_parse(struct sadb_ext *pfkey_ext)
48068 +{
48069 + int error = 0;
48070 + struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
48071 +
48072 + /* sanity checks... */
48073 +
48074 + if(!pfkey_key) {
48075 + ERROR(
48076 + "pfkey_key_parse: "
48077 + "NULL pointer passed in.\n");
48078 + SENDERR(EINVAL);
48079 + }
48080 +
48081 + if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) {
48082 + ERROR(
48083 + "pfkey_key_parse: "
48084 + "size wrong ext_len=%d, key_ext_len=%d.\n",
48085 + pfkey_key->sadb_key_len,
48086 + (int)sizeof(struct sadb_key));
48087 + SENDERR(EINVAL);
48088 + }
48089 +
48090 + if(!pfkey_key->sadb_key_bits) {
48091 + ERROR(
48092 + "pfkey_key_parse: "
48093 + "key length set to zero, must be non-zero.\n");
48094 + SENDERR(EINVAL);
48095 + }
48096 +
48097 + if(pfkey_key->sadb_key_len !=
48098 + DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits,
48099 + PFKEYBITS)) {
48100 + ERROR(
48101 + "pfkey_key_parse: "
48102 + "key length=%d does not agree with extension length=%d.\n",
48103 + pfkey_key->sadb_key_bits,
48104 + pfkey_key->sadb_key_len);
48105 + SENDERR(EINVAL);
48106 + }
48107 +
48108 + if(pfkey_key->sadb_key_reserved) {
48109 + ERROR(
48110 + "pfkey_key_parse: "
48111 + "res=%d, must be zero.\n",
48112 + pfkey_key->sadb_key_reserved);
48113 + SENDERR(EINVAL);
48114 + }
48115 +
48116 + if(! ( (pfkey_key->sadb_key_exttype == K_SADB_EXT_KEY_AUTH) ||
48117 + (pfkey_key->sadb_key_exttype == K_SADB_EXT_KEY_ENCRYPT))) {
48118 + ERROR(
48119 + "pfkey_key_parse: "
48120 + "expecting extension type AUTH or ENCRYPT, got %d.\n",
48121 + pfkey_key->sadb_key_exttype);
48122 + SENDERR(EINVAL);
48123 + }
48124 +
48125 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
48126 + "pfkey_key_parse: "
48127 + "success, found len=%d exttype=%d(%s) bits=%d reserved=%d.\n",
48128 + pfkey_key->sadb_key_len,
48129 + pfkey_key->sadb_key_exttype,
48130 + pfkey_v2_sadb_ext_string(pfkey_key->sadb_key_exttype),
48131 + pfkey_key->sadb_key_bits,
48132 + pfkey_key->sadb_key_reserved);
48133 +
48134 +errlab:
48135 + return error;
48136 +}
48137 +
48138 +DEBUG_NO_STATIC int
48139 +pfkey_ident_parse(struct sadb_ext *pfkey_ext)
48140 +{
48141 + int error = 0;
48142 + struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
48143 +
48144 + /* sanity checks... */
48145 + if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
48146 + ERROR(
48147 + "pfkey_ident_parse: "
48148 + "size wrong ext_len=%d, key_ext_len=%d.\n",
48149 + pfkey_ident->sadb_ident_len,
48150 + (int)sizeof(struct sadb_ident));
48151 + SENDERR(EINVAL);
48152 + }
48153 +
48154 + if(pfkey_ident->sadb_ident_type > K_SADB_IDENTTYPE_MAX) {
48155 + ERROR(
48156 + "pfkey_ident_parse: "
48157 + "ident_type=%d out of range, must be less than %d.\n",
48158 + pfkey_ident->sadb_ident_type,
48159 + K_SADB_IDENTTYPE_MAX);
48160 + SENDERR(EINVAL);
48161 + }
48162 +
48163 + if(pfkey_ident->sadb_ident_reserved) {
48164 + ERROR(
48165 + "pfkey_ident_parse: "
48166 + "res=%d, must be zero.\n",
48167 + pfkey_ident->sadb_ident_reserved);
48168 + SENDERR(EINVAL);
48169 + }
48170 +
48171 + /* string terminator/padding must be zero */
48172 + if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
48173 + if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) {
48174 + ERROR(
48175 + "pfkey_ident_parse: "
48176 + "string padding must be zero, last is 0x%02x.\n",
48177 + *((char*)pfkey_ident +
48178 + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1));
48179 + SENDERR(EINVAL);
48180 + }
48181 + }
48182 +
48183 + if( ! ((pfkey_ident->sadb_ident_exttype == K_SADB_EXT_IDENTITY_SRC) ||
48184 + (pfkey_ident->sadb_ident_exttype == K_SADB_EXT_IDENTITY_DST))) {
48185 + ERROR(
48186 + "pfkey_key_parse: "
48187 + "expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n",
48188 + pfkey_ident->sadb_ident_exttype);
48189 + SENDERR(EINVAL);
48190 + }
48191 +
48192 +errlab:
48193 + return error;
48194 +}
48195 +
48196 +DEBUG_NO_STATIC int
48197 +pfkey_sens_parse(struct sadb_ext *pfkey_ext)
48198 +{
48199 + int error = 0;
48200 + struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext;
48201 +
48202 + /* sanity checks... */
48203 + if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) {
48204 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48205 + "pfkey_sens_parse: "
48206 + "size wrong ext_len=%d, key_ext_len=%d.\n",
48207 + pfkey_sens->sadb_sens_len,
48208 + (int)sizeof(struct sadb_sens));
48209 + SENDERR(EINVAL);
48210 + }
48211 +
48212 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48213 + "pfkey_sens_parse: "
48214 + "Sorry, I can't parse exttype=%d yet.\n",
48215 + pfkey_ext->sadb_ext_type);
48216 +#if 0
48217 + SENDERR(EINVAL); /* don't process these yet */
48218 +#endif
48219 +
48220 +errlab:
48221 + return error;
48222 +}
48223 +
48224 +DEBUG_NO_STATIC int
48225 +pfkey_prop_parse(struct sadb_ext *pfkey_ext)
48226 +{
48227 + int error = 0;
48228 + int i, num_comb;
48229 + struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext;
48230 + struct k_sadb_comb *k_pfkey_comb = (struct k_sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop));
48231 +
48232 + /* sanity checks... */
48233 + if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) ||
48234 + (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) {
48235 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48236 + "pfkey_prop_parse: "
48237 + "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n",
48238 + pfkey_prop->sadb_prop_len,
48239 + (int)sizeof(struct sadb_prop),
48240 + (int)sizeof(struct sadb_comb));
48241 + SENDERR(EINVAL);
48242 + }
48243 +
48244 + if(pfkey_prop->sadb_prop_replay > 64) {
48245 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48246 + "pfkey_prop_parse: "
48247 + "replay window size: %d -- must be 0 <= size <= 64\n",
48248 + pfkey_prop->sadb_prop_replay);
48249 + SENDERR(EINVAL);
48250 + }
48251 +
48252 + for(i=0; i<3; i++) {
48253 + if(pfkey_prop->sadb_prop_reserved[i]) {
48254 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48255 + "pfkey_prop_parse: "
48256 + "res[%d]=%d, must be zero.\n",
48257 + i, pfkey_prop->sadb_prop_reserved[i]);
48258 + SENDERR(EINVAL);
48259 + }
48260 + }
48261 +
48262 + num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb);
48263 +
48264 + for(i = 0; i < num_comb; i++) {
48265 + struct sadb_comb *pfkey_comb = (struct sadb_comb *)k_pfkey_comb;
48266 + if(pfkey_comb->sadb_comb_auth > K_SADB_AALG_MAX) {
48267 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48268 + "pfkey_prop_parse: "
48269 + "pfkey_comb[%d]->sadb_comb_auth=%d > K_SADB_AALG_MAX=%d.\n",
48270 + i,
48271 + pfkey_comb->sadb_comb_auth,
48272 + K_SADB_AALG_MAX);
48273 + SENDERR(EINVAL);
48274 + }
48275 +
48276 + if(pfkey_comb->sadb_comb_auth) {
48277 + if(!pfkey_comb->sadb_comb_auth_minbits) {
48278 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48279 + "pfkey_prop_parse: "
48280 + "pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n",
48281 + i);
48282 + SENDERR(EINVAL);
48283 + }
48284 + if(!pfkey_comb->sadb_comb_auth_maxbits) {
48285 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48286 + "pfkey_prop_parse: "
48287 + "pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n",
48288 + i);
48289 + SENDERR(EINVAL);
48290 + }
48291 + if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) {
48292 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48293 + "pfkey_prop_parse: "
48294 + "pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n",
48295 + i,
48296 + pfkey_comb->sadb_comb_auth_minbits,
48297 + pfkey_comb->sadb_comb_auth_maxbits);
48298 + SENDERR(EINVAL);
48299 + }
48300 + } else {
48301 + if(pfkey_comb->sadb_comb_auth_minbits) {
48302 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48303 + "pfkey_prop_parse: "
48304 + "pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n",
48305 + i,
48306 + pfkey_comb->sadb_comb_auth_minbits);
48307 + SENDERR(EINVAL);
48308 + }
48309 + if(pfkey_comb->sadb_comb_auth_maxbits) {
48310 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48311 + "pfkey_prop_parse: "
48312 + "pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n",
48313 + i,
48314 + pfkey_comb->sadb_comb_auth_maxbits);
48315 + SENDERR(EINVAL);
48316 + }
48317 + }
48318 +
48319 +#if K_SADB_EALG_MAX < 255
48320 + if(pfkey_comb->sadb_comb_encrypt > K_SADB_EALG_MAX) {
48321 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48322 + "pfkey_comb_parse: "
48323 + "pfkey_comb[%d]->sadb_comb_encrypt=%d > K_SADB_EALG_MAX=%d.\n",
48324 + i,
48325 + pfkey_comb->sadb_comb_encrypt,
48326 + K_SADB_EALG_MAX);
48327 + SENDERR(EINVAL);
48328 + }
48329 +#endif
48330 +
48331 + if(pfkey_comb->sadb_comb_encrypt) {
48332 + if(!pfkey_comb->sadb_comb_encrypt_minbits) {
48333 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48334 + "pfkey_prop_parse: "
48335 + "pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n",
48336 + i);
48337 + SENDERR(EINVAL);
48338 + }
48339 + if(!pfkey_comb->sadb_comb_encrypt_maxbits) {
48340 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48341 + "pfkey_prop_parse: "
48342 + "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n",
48343 + i);
48344 + SENDERR(EINVAL);
48345 + }
48346 + if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) {
48347 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48348 + "pfkey_prop_parse: "
48349 + "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n",
48350 + i,
48351 + pfkey_comb->sadb_comb_encrypt_minbits,
48352 + pfkey_comb->sadb_comb_encrypt_maxbits);
48353 + SENDERR(EINVAL);
48354 + }
48355 + } else {
48356 + if(pfkey_comb->sadb_comb_encrypt_minbits) {
48357 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48358 + "pfkey_prop_parse: "
48359 + "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n",
48360 + i,
48361 + pfkey_comb->sadb_comb_encrypt_minbits);
48362 + SENDERR(EINVAL);
48363 + }
48364 + if(pfkey_comb->sadb_comb_encrypt_maxbits) {
48365 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48366 + "pfkey_prop_parse: "
48367 + "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n",
48368 + i,
48369 + pfkey_comb->sadb_comb_encrypt_maxbits);
48370 + SENDERR(EINVAL);
48371 + }
48372 + }
48373 +
48374 + /* XXX do sanity check on flags */
48375 +
48376 + if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) {
48377 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48378 + "pfkey_prop_parse: "
48379 + "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n",
48380 + i,
48381 + pfkey_comb->sadb_comb_soft_allocations,
48382 + pfkey_comb->sadb_comb_hard_allocations);
48383 + SENDERR(EINVAL);
48384 + }
48385 +
48386 + if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) {
48387 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48388 + "pfkey_prop_parse: "
48389 + "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n",
48390 + i,
48391 + (unsigned long long int)pfkey_comb->sadb_comb_soft_bytes,
48392 + (unsigned long long int)pfkey_comb->sadb_comb_hard_bytes);
48393 + SENDERR(EINVAL);
48394 + }
48395 +
48396 + if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) {
48397 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48398 + "pfkey_prop_parse: "
48399 + "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n",
48400 + i,
48401 + (unsigned long long int)pfkey_comb->sadb_comb_soft_addtime,
48402 + (unsigned long long int)pfkey_comb->sadb_comb_hard_addtime);
48403 + SENDERR(EINVAL);
48404 + }
48405 +
48406 + if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) {
48407 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48408 + "pfkey_prop_parse: "
48409 + "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n",
48410 + i,
48411 + (unsigned long long int)pfkey_comb->sadb_comb_soft_usetime,
48412 + (unsigned long long int)pfkey_comb->sadb_comb_hard_usetime);
48413 + SENDERR(EINVAL);
48414 + }
48415 +
48416 +#ifdef COMB_PACKETS
48417 + if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) {
48418 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48419 + "pfkey_prop_parse: "
48420 + "pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n",
48421 + i,
48422 + k_pfkey_comb->sadb_x_comb_soft_packets,
48423 + k_pfkey_comb->sadb_x_comb_hard_packets);
48424 + SENDERR(EINVAL);
48425 + }
48426 +#endif
48427 +
48428 + pfkey_comb++;
48429 + }
48430 +
48431 +errlab:
48432 + return error;
48433 +}
48434 +
48435 +DEBUG_NO_STATIC int
48436 +pfkey_supported_parse(struct sadb_ext *pfkey_ext)
48437 +{
48438 + int error = 0;
48439 + unsigned int i, num_alg;
48440 + struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext;
48441 + struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported));
48442 +
48443 + /* sanity checks... */
48444 + if((pfkey_supported->sadb_supported_len <
48445 + sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) ||
48446 + (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) -
48447 + sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) {
48448 +
48449 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48450 + "pfkey_supported_parse: "
48451 + "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n",
48452 + pfkey_supported->sadb_supported_len,
48453 + (int)sizeof(struct sadb_supported),
48454 + (int)sizeof(struct sadb_alg));
48455 + SENDERR(EINVAL);
48456 + }
48457 +
48458 + if(pfkey_supported->sadb_supported_reserved) {
48459 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48460 + "pfkey_supported_parse: "
48461 + "res=%d, must be zero.\n",
48462 + pfkey_supported->sadb_supported_reserved);
48463 + SENDERR(EINVAL);
48464 + }
48465 +
48466 + num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg);
48467 +
48468 + for(i = 0; i < num_alg; i++) {
48469 + /* process algo description */
48470 + if(pfkey_alg->sadb_alg_reserved) {
48471 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48472 + "pfkey_supported_parse: "
48473 + "alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n",
48474 + i,
48475 + pfkey_alg->sadb_alg_id,
48476 + pfkey_alg->sadb_alg_ivlen,
48477 + pfkey_alg->sadb_alg_minbits,
48478 + pfkey_alg->sadb_alg_maxbits,
48479 + pfkey_alg->sadb_alg_reserved);
48480 + SENDERR(EINVAL);
48481 + }
48482 +
48483 + /* XXX can alg_id auth/enc be determined from info given?
48484 + Yes, but OpenBSD's method does not iteroperate with rfc2367.
48485 + rgb, 2000-04-06 */
48486 +
48487 + switch(pfkey_supported->sadb_supported_exttype) {
48488 + case K_SADB_EXT_SUPPORTED_AUTH:
48489 + if(pfkey_alg->sadb_alg_id > K_SADB_AALG_MAX) {
48490 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48491 + "pfkey_supported_parse: "
48492 + "alg[%d], alg_id=%d > K_SADB_AALG_MAX=%d, fatal.\n",
48493 + i,
48494 + pfkey_alg->sadb_alg_id,
48495 + K_SADB_AALG_MAX);
48496 + SENDERR(EINVAL);
48497 + }
48498 + break;
48499 + case SADB_EXT_SUPPORTED_ENCRYPT:
48500 +#if K_SADB_EALG_MAX < 255
48501 + if(pfkey_alg->sadb_alg_id > K_SADB_EALG_MAX) {
48502 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48503 + "pfkey_supported_parse: "
48504 + "alg[%d], alg_id=%d > K_SADB_EALG_MAX=%d, fatal.\n",
48505 + i,
48506 + pfkey_alg->sadb_alg_id,
48507 + K_SADB_EALG_MAX);
48508 + SENDERR(EINVAL);
48509 + }
48510 +#endif
48511 + break;
48512 + default:
48513 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48514 + "pfkey_supported_parse: "
48515 + "alg[%d], alg_id=%d > K_SADB_EALG_MAX=%d, fatal.\n",
48516 + i,
48517 + pfkey_alg->sadb_alg_id,
48518 + K_SADB_EALG_MAX);
48519 + SENDERR(EINVAL);
48520 + }
48521 + pfkey_alg++;
48522 + }
48523 +
48524 + errlab:
48525 + return error;
48526 +}
48527 +
48528 +DEBUG_NO_STATIC int
48529 +pfkey_spirange_parse(struct sadb_ext *pfkey_ext)
48530 +{
48531 + int error = 0;
48532 + struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext;
48533 +
48534 + /* sanity checks... */
48535 + if(pfkey_spirange->sadb_spirange_len !=
48536 + sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) {
48537 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48538 + "pfkey_spirange_parse: "
48539 + "size wrong ext_len=%d, key_ext_len=%d.\n",
48540 + pfkey_spirange->sadb_spirange_len,
48541 + (int)sizeof(struct sadb_spirange));
48542 + SENDERR(EINVAL);
48543 + }
48544 +
48545 + if(pfkey_spirange->sadb_spirange_reserved) {
48546 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48547 + "pfkey_spirange_parse: "
48548 + "reserved=%d must be set to zero.\n",
48549 + pfkey_spirange->sadb_spirange_reserved);
48550 + SENDERR(EINVAL);
48551 + }
48552 +
48553 + if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) {
48554 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48555 + "pfkey_spirange_parse: "
48556 + "minspi=%08x must be < maxspi=%08x.\n",
48557 + ntohl(pfkey_spirange->sadb_spirange_min),
48558 + ntohl(pfkey_spirange->sadb_spirange_max));
48559 + SENDERR(EINVAL);
48560 + }
48561 +
48562 + if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) {
48563 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48564 + "pfkey_spirange_parse: "
48565 + "minspi=%08x must be > 255.\n",
48566 + ntohl(pfkey_spirange->sadb_spirange_min));
48567 + SENDERR(EEXIST);
48568 + }
48569 +
48570 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
48571 + "pfkey_spirange_parse: "
48572 + "ext_len=%u ext_type=%u(%s) min=%u max=%u res=%u.\n",
48573 + pfkey_spirange->sadb_spirange_len,
48574 + pfkey_spirange->sadb_spirange_exttype,
48575 + pfkey_v2_sadb_ext_string(pfkey_spirange->sadb_spirange_exttype),
48576 + pfkey_spirange->sadb_spirange_min,
48577 + pfkey_spirange->sadb_spirange_max,
48578 + pfkey_spirange->sadb_spirange_reserved);
48579 + errlab:
48580 + return error;
48581 +}
48582 +
48583 +DEBUG_NO_STATIC int
48584 +pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext)
48585 +{
48586 + int error = 0;
48587 + struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext;
48588 +
48589 + /* sanity checks... */
48590 + if(pfkey_x_kmprivate->sadb_x_kmprivate_len <
48591 + sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) {
48592 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48593 + "pfkey_x_kmprivate_parse: "
48594 + "size wrong ext_len=%d, key_ext_len=%d.\n",
48595 + pfkey_x_kmprivate->sadb_x_kmprivate_len,
48596 + (int)sizeof(struct sadb_x_kmprivate));
48597 + SENDERR(EINVAL);
48598 + }
48599 +
48600 + if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) {
48601 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48602 + "pfkey_x_kmprivate_parse: "
48603 + "reserved=%d must be set to zero.\n",
48604 + pfkey_x_kmprivate->sadb_x_kmprivate_reserved);
48605 + SENDERR(EINVAL);
48606 + }
48607 +
48608 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48609 + "pfkey_x_kmprivate_parse: "
48610 + "Sorry, I can't parse exttype=%d yet.\n",
48611 + pfkey_ext->sadb_ext_type);
48612 + SENDERR(EINVAL); /* don't process these yet */
48613 +
48614 +errlab:
48615 + return error;
48616 +}
48617 +
48618 +DEBUG_NO_STATIC int
48619 +pfkey_x_satype_parse(struct sadb_ext *pfkey_ext)
48620 +{
48621 + int error = 0;
48622 + int i;
48623 + struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
48624 +
48625 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
48626 + "pfkey_x_satype_parse: enter\n");
48627 + /* sanity checks... */
48628 + if(pfkey_x_satype->sadb_x_satype_len !=
48629 + sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) {
48630 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48631 + "pfkey_x_satype_parse: "
48632 + "size wrong ext_len=%d, key_ext_len=%d.\n",
48633 + pfkey_x_satype->sadb_x_satype_len,
48634 + (int)sizeof(struct sadb_x_satype));
48635 + SENDERR(EINVAL);
48636 + }
48637 +
48638 + if(!pfkey_x_satype->sadb_x_satype_satype) {
48639 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48640 + "pfkey_x_satype_parse: "
48641 + "satype is zero, must be non-zero.\n");
48642 + SENDERR(EINVAL);
48643 + }
48644 +
48645 + if(pfkey_x_satype->sadb_x_satype_satype > K_SADB_SATYPE_MAX) {
48646 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48647 + "pfkey_x_satype_parse: "
48648 + "satype %d > max %d, invalid.\n",
48649 + pfkey_x_satype->sadb_x_satype_satype, K_SADB_SATYPE_MAX);
48650 + SENDERR(EINVAL);
48651 + }
48652 +
48653 + if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
48654 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48655 + "pfkey_x_satype_parse: "
48656 + "proto lookup from satype=%d failed.\n",
48657 + pfkey_x_satype->sadb_x_satype_satype);
48658 + SENDERR(EINVAL);
48659 + }
48660 +
48661 + for(i = 0; i < 3; i++) {
48662 + if(pfkey_x_satype->sadb_x_satype_reserved[i]) {
48663 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48664 + "pfkey_x_satype_parse: "
48665 + "reserved[%d]=%d must be set to zero.\n",
48666 + i, pfkey_x_satype->sadb_x_satype_reserved[i]);
48667 + SENDERR(EINVAL);
48668 + }
48669 + }
48670 +
48671 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
48672 + "pfkey_x_satype_parse: "
48673 + "len=%u ext=%u(%s) satype=%u(%s) res=%u,%u,%u.\n",
48674 + pfkey_x_satype->sadb_x_satype_len,
48675 + pfkey_x_satype->sadb_x_satype_exttype,
48676 + pfkey_v2_sadb_ext_string(pfkey_x_satype->sadb_x_satype_exttype),
48677 + pfkey_x_satype->sadb_x_satype_satype,
48678 + satype2name(pfkey_x_satype->sadb_x_satype_satype),
48679 + pfkey_x_satype->sadb_x_satype_reserved[0],
48680 + pfkey_x_satype->sadb_x_satype_reserved[1],
48681 + pfkey_x_satype->sadb_x_satype_reserved[2]);
48682 +errlab:
48683 + return error;
48684 +}
48685 +
48686 +DEBUG_NO_STATIC int
48687 +pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext)
48688 +{
48689 + int error = 0;
48690 + int i;
48691 + struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
48692 +
48693 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
48694 + "pfkey_x_debug_parse: enter\n");
48695 + /* sanity checks... */
48696 + if(pfkey_x_debug->sadb_x_debug_len !=
48697 + sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) {
48698 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48699 + "pfkey_x_debug_parse: "
48700 + "size wrong ext_len=%d, key_ext_len=%d.\n",
48701 + pfkey_x_debug->sadb_x_debug_len,
48702 + (int)sizeof(struct sadb_x_debug));
48703 + SENDERR(EINVAL);
48704 + }
48705 +
48706 + for(i = 0; i < 4; i++) {
48707 + if(pfkey_x_debug->sadb_x_debug_reserved[i]) {
48708 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48709 + "pfkey_x_debug_parse: "
48710 + "reserved[%d]=%d must be set to zero.\n",
48711 + i, pfkey_x_debug->sadb_x_debug_reserved[i]);
48712 + SENDERR(EINVAL);
48713 + }
48714 + }
48715 +
48716 +errlab:
48717 + return error;
48718 +}
48719 +
48720 +DEBUG_NO_STATIC int
48721 +pfkey_x_ext_protocol_parse(struct sadb_ext *pfkey_ext)
48722 +{
48723 + int error = 0;
48724 + struct sadb_protocol *p = (struct sadb_protocol *)pfkey_ext;
48725 +
48726 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_protocol_parse:\n");
48727 + /* sanity checks... */
48728 +
48729 + if (p->sadb_protocol_len != sizeof(*p)/IPSEC_PFKEYv2_ALIGN) {
48730 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48731 + "pfkey_x_protocol_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
48732 + p->sadb_protocol_len, (int)sizeof(*p));
48733 + SENDERR(EINVAL);
48734 + }
48735 +
48736 + if (p->sadb_protocol_reserved2 != 0) {
48737 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48738 + "pfkey_protocol_parse: res=%d, must be zero.\n",
48739 + p->sadb_protocol_reserved2);
48740 + SENDERR(EINVAL);
48741 + }
48742 +
48743 + errlab:
48744 + return error;
48745 +}
48746 +
48747 +#ifdef NAT_TRAVERSAL
48748 +DEBUG_NO_STATIC int
48749 +pfkey_x_ext_nat_t_type_parse(struct sadb_ext *pfkey_ext)
48750 +{
48751 + return 0;
48752 +}
48753 +DEBUG_NO_STATIC int
48754 +pfkey_x_ext_nat_t_port_parse(struct sadb_ext *pfkey_ext)
48755 +{
48756 + return 0;
48757 +}
48758 +#endif
48759 +
48760 +DEBUG_NO_STATIC int
48761 +pfkey_x_ext_outif_parse(struct sadb_ext *pfkey_ext)
48762 +{
48763 + int error = 0;
48764 + struct sadb_x_plumbif *p = (struct sadb_x_plumbif *)pfkey_ext;
48765 +
48766 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_outif_parse:\n");
48767 + /* sanity checks... */
48768 +
48769 + if (p->sadb_x_outif_len != IPSEC_PFKEYv2_WORDS(sizeof(*p))) {
48770 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48771 + "pfkey_x_outif_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
48772 + p->sadb_x_outif_len, (int)sizeof(*p));
48773 + SENDERR(EINVAL);
48774 + }
48775 +
48776 + errlab:
48777 + return error;
48778 +}
48779 +
48780 +DEBUG_NO_STATIC int
48781 +pfkey_x_ext_saref_parse(struct sadb_ext *pfkey_ext)
48782 +{
48783 + int error = 0;
48784 + struct sadb_x_saref *p = (struct sadb_x_saref *)pfkey_ext;
48785 +
48786 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_saref_parse:\n");
48787 + /* sanity checks... */
48788 +
48789 + if (p->sadb_x_saref_len != IPSEC_PFKEYv2_WORDS(sizeof(*p))) {
48790 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48791 + "pfkey_x_saref_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
48792 + p->sadb_x_saref_len, (int)sizeof(*p));
48793 + SENDERR(EINVAL);
48794 + }
48795 +
48796 + errlab:
48797 + return error;
48798 +}
48799 +
48800 +
48801 +#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME};
48802 +
48803 +DEFINEPARSER(pfkey_sa_parse);
48804 +DEFINEPARSER(pfkey_lifetime_parse);
48805 +DEFINEPARSER(pfkey_address_parse);
48806 +DEFINEPARSER(pfkey_key_parse);
48807 +DEFINEPARSER(pfkey_ident_parse);
48808 +DEFINEPARSER(pfkey_sens_parse);
48809 +DEFINEPARSER(pfkey_prop_parse);
48810 +DEFINEPARSER(pfkey_supported_parse);
48811 +DEFINEPARSER(pfkey_spirange_parse);
48812 +DEFINEPARSER(pfkey_x_kmprivate_parse);
48813 +DEFINEPARSER(pfkey_x_satype_parse);
48814 +DEFINEPARSER(pfkey_x_ext_debug_parse);
48815 +DEFINEPARSER(pfkey_x_ext_protocol_parse);
48816 +#ifdef NAT_TRAVERSAL
48817 +DEFINEPARSER(pfkey_x_ext_nat_t_type_parse);
48818 +DEFINEPARSER(pfkey_x_ext_nat_t_port_parse);
48819 +#endif
48820 +DEFINEPARSER(pfkey_x_ext_outif_parse);
48821 +DEFINEPARSER(pfkey_x_ext_saref_parse);
48822 +
48823 +struct pf_key_ext_parsers_def *ext_default_parsers[]=
48824 +{
48825 + NULL, /* pfkey_msg_parse, */
48826 + &pfkey_sa_parse_def,
48827 + &pfkey_lifetime_parse_def,
48828 + &pfkey_lifetime_parse_def,
48829 + &pfkey_lifetime_parse_def,
48830 + &pfkey_address_parse_def,
48831 + &pfkey_address_parse_def,
48832 + &pfkey_address_parse_def,
48833 + &pfkey_key_parse_def,
48834 + &pfkey_key_parse_def,
48835 + &pfkey_ident_parse_def,
48836 + &pfkey_ident_parse_def,
48837 + &pfkey_sens_parse_def,
48838 + &pfkey_prop_parse_def,
48839 + &pfkey_supported_parse_def,
48840 + &pfkey_supported_parse_def,
48841 + &pfkey_spirange_parse_def,
48842 + &pfkey_x_kmprivate_parse_def,
48843 + &pfkey_x_satype_parse_def,
48844 + &pfkey_sa_parse_def,
48845 + &pfkey_address_parse_def,
48846 + &pfkey_address_parse_def,
48847 + &pfkey_address_parse_def,
48848 + &pfkey_address_parse_def,
48849 + &pfkey_address_parse_def,
48850 + &pfkey_x_ext_debug_parse_def,
48851 + &pfkey_x_ext_protocol_parse_def,
48852 +#ifdef NAT_TRAVERSAL
48853 + &pfkey_x_ext_nat_t_type_parse_def,
48854 + &pfkey_x_ext_nat_t_port_parse_def,
48855 + &pfkey_x_ext_nat_t_port_parse_def,
48856 + &pfkey_address_parse_def,
48857 +#else
48858 + NULL,NULL,NULL,NULL,
48859 +#endif
48860 + &pfkey_x_ext_outif_parse_def,
48861 + &pfkey_x_ext_saref_parse_def,
48862 +};
48863 +
48864 +int
48865 +pfkey_msg_parse(struct sadb_msg *pfkey_msg,
48866 + struct pf_key_ext_parsers_def *ext_parsers[],
48867 + struct sadb_ext *extensions[],
48868 + int dir)
48869 +{
48870 + int error = 0;
48871 + int remain;
48872 + struct sadb_ext *pfkey_ext;
48873 + pfkey_ext_track extensions_seen = 0;
48874 +
48875 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
48876 + "pfkey_msg_parse: "
48877 + "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
48878 + pfkey_msg->sadb_msg_version,
48879 + pfkey_msg->sadb_msg_type,
48880 + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
48881 + pfkey_msg->sadb_msg_errno,
48882 + pfkey_msg->sadb_msg_satype,
48883 + satype2name(pfkey_msg->sadb_msg_satype),
48884 + pfkey_msg->sadb_msg_len,
48885 + pfkey_msg->sadb_msg_reserved,
48886 + pfkey_msg->sadb_msg_seq,
48887 + pfkey_msg->sadb_msg_pid);
48888 +
48889 + if(ext_parsers == NULL) ext_parsers = ext_default_parsers;
48890 +
48891 + pfkey_extensions_init(extensions);
48892 +
48893 + remain = pfkey_msg->sadb_msg_len;
48894 + remain -= IPSEC_PFKEYv2_WORDS(sizeof(struct sadb_msg));
48895 +
48896 + pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg +
48897 + sizeof(struct sadb_msg));
48898 +
48899 + extensions[0] = (struct sadb_ext *) pfkey_msg;
48900 +
48901 +
48902 + if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
48903 + ERROR("pfkey_msg_parse: "
48904 + "not PF_KEY_V2 msg, found %d, should be %d.\n",
48905 + pfkey_msg->sadb_msg_version,
48906 + PF_KEY_V2);
48907 + SENDERR(EINVAL);
48908 + }
48909 +
48910 + if(!pfkey_msg->sadb_msg_type) {
48911 + ERROR("pfkey_msg_parse: "
48912 + "msg type not set, must be non-zero..\n");
48913 + SENDERR(EINVAL);
48914 + }
48915 +
48916 + if(pfkey_msg->sadb_msg_type > K_SADB_MAX) {
48917 + ERROR("pfkey_msg_parse: "
48918 + "msg type=%d > max=%d.\n",
48919 + pfkey_msg->sadb_msg_type,
48920 + K_SADB_MAX);
48921 + SENDERR(EINVAL);
48922 + }
48923 +
48924 + switch(pfkey_msg->sadb_msg_type) {
48925 + case K_SADB_GETSPI:
48926 + case K_SADB_UPDATE:
48927 + case K_SADB_ADD:
48928 + case K_SADB_DELETE:
48929 + case K_SADB_GET:
48930 + case K_SADB_X_GRPSA:
48931 + case K_SADB_X_ADDFLOW:
48932 + if(!satype2proto(pfkey_msg->sadb_msg_satype)) {
48933 + ERROR("pfkey_msg_parse: "
48934 + "satype %d conversion to proto failed for msg_type %d (%s).\n",
48935 + pfkey_msg->sadb_msg_satype,
48936 + pfkey_msg->sadb_msg_type,
48937 + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
48938 + SENDERR(EINVAL);
48939 + } else {
48940 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48941 + "pfkey_msg_parse: "
48942 + "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n",
48943 + pfkey_msg->sadb_msg_satype,
48944 + satype2name(pfkey_msg->sadb_msg_satype),
48945 + satype2proto(pfkey_msg->sadb_msg_satype),
48946 + pfkey_msg->sadb_msg_type,
48947 + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
48948 + }
48949 + case K_SADB_ACQUIRE:
48950 + case K_SADB_REGISTER:
48951 + case K_SADB_EXPIRE:
48952 + if(!pfkey_msg->sadb_msg_satype) {
48953 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48954 + "pfkey_msg_parse: "
48955 + "satype is zero, must be non-zero for msg_type %d(%s).\n",
48956 + pfkey_msg->sadb_msg_type,
48957 + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
48958 + SENDERR(EINVAL);
48959 + }
48960 + default:
48961 + break;
48962 + }
48963 +
48964 + /* errno must not be set in downward messages */
48965 + /* this is not entirely true... a response to an ACQUIRE could return an error */
48966 + if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != K_SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) {
48967 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
48968 + "pfkey_msg_parse: "
48969 + "errno set to %d.\n",
48970 + pfkey_msg->sadb_msg_errno);
48971 + SENDERR(EINVAL);
48972 + }
48973 +
48974 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
48975 + "pfkey_msg_parse: "
48976 + "remain=%d\n",
48977 + remain
48978 + );
48979 +
48980 + extensions_seen = 1;
48981 +
48982 + while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) {
48983 + /* Is there enough message left to support another extension header? */
48984 + if(remain < pfkey_ext->sadb_ext_len) {
48985 + ERROR("pfkey_msg_parse: "
48986 + "remain %d less than ext len %d.\n",
48987 + remain, pfkey_ext->sadb_ext_len);
48988 + SENDERR(EINVAL);
48989 + }
48990 +
48991 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
48992 + "pfkey_msg_parse: "
48993 + "parsing ext type=%d(%s) remain=%d.\n",
48994 + pfkey_ext->sadb_ext_type,
48995 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
48996 + remain);
48997 +
48998 + /* Is the extension header type valid? */
48999 + if((pfkey_ext->sadb_ext_type > K_SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) {
49000 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49001 + "pfkey_msg_parse: "
49002 + "ext type %d(%s) invalid, K_SADB_EXT_MAX=%d.\n",
49003 + pfkey_ext->sadb_ext_type,
49004 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
49005 + K_SADB_EXT_MAX);
49006 + SENDERR(EINVAL);
49007 + }
49008 +
49009 + /* Have we already seen this type of extension? */
49010 + if(extensions[pfkey_ext->sadb_ext_type] != NULL)
49011 + {
49012 + ERROR("pfkey_msg_parse: "
49013 + "ext type %d(%s) already seen.\n",
49014 + pfkey_ext->sadb_ext_type,
49015 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
49016 + SENDERR(EINVAL);
49017 + }
49018 +
49019 + /* Do I even know about this type of extension? */
49020 + if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) {
49021 + ERROR("pfkey_msg_parse: "
49022 + "ext type %d(%s) unknown, ignoring.\n",
49023 + pfkey_ext->sadb_ext_type,
49024 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
49025 + goto next_ext;
49026 + }
49027 +
49028 + /* Is this type of extension permitted for this type of message? */
49029 + if(!pfkey_permitted_extension(dir,pfkey_msg->sadb_msg_type,pfkey_ext->sadb_ext_type)) {
49030 + ERROR("ext type %d(%s) not permitted (parse)\n",
49031 + pfkey_ext->sadb_ext_type,
49032 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
49033 + SENDERR(EINVAL);
49034 + }
49035 +
49036 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
49037 + "pfkey_msg_parse: "
49038 + "remain=%d ext_type=%d(%s) ext_len=%d parsing ext 0p%p with parser %s.\n",
49039 + remain,
49040 + pfkey_ext->sadb_ext_type,
49041 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
49042 + pfkey_ext->sadb_ext_len,
49043 + pfkey_ext,
49044 + ext_parsers[pfkey_ext->sadb_ext_type]->parser_name);
49045 +
49046 + /* Parse the extension */
49047 + if((error =
49048 + (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) {
49049 + ERROR("pfkey_msg_parse: "
49050 + "extension parsing for type %d(%s) failed with error %d.\n",
49051 + pfkey_ext->sadb_ext_type,
49052 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
49053 + error);
49054 + SENDERR(-error);
49055 + }
49056 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
49057 + "pfkey_msg_parse: "
49058 + "Extension %d(%s) parsed.\n",
49059 + pfkey_ext->sadb_ext_type,
49060 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
49061 +
49062 + /* Mark that we have seen this extension and remember the header location */
49063 + extensions[pfkey_ext->sadb_ext_type] = pfkey_ext;
49064 + pfkey_mark_extension(pfkey_ext->sadb_ext_type,&extensions_seen);
49065 +
49066 + next_ext:
49067 + /* Calculate how much message remains */
49068 + remain -= pfkey_ext->sadb_ext_len;
49069 +
49070 + if(!remain) {
49071 + break;
49072 + }
49073 + /* Find the next extension header */
49074 + pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext +
49075 + pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
49076 + }
49077 +
49078 + if(remain) {
49079 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49080 + "pfkey_msg_parse: "
49081 + "unexpected remainder of %d.\n",
49082 + remain);
49083 + /* why is there still something remaining? */
49084 + SENDERR(EINVAL);
49085 + }
49086 +
49087 + /* don't check further if it is an error return message since it
49088 + may not have a body */
49089 + if(pfkey_msg->sadb_msg_errno) {
49090 + SENDERR(-error);
49091 + }
49092 +
49093 + if(pfkey_extensions_missing(dir,pfkey_msg->sadb_msg_type,extensions_seen)) {
49094 + ERROR("required extensions missing.seen=%08llx.\n",(unsigned long long)extensions_seen);
49095 + SENDERR(EINVAL);
49096 + }
49097 +
49098 + if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == K_SADB_X_DELFLOW)
49099 + && ((extensions_seen & K_SADB_X_EXT_ADDRESS_DELFLOW)
49100 + != K_SADB_X_EXT_ADDRESS_DELFLOW)
49101 + && (((extensions_seen & (1<<SADB_EXT_SA)) != (1<<SADB_EXT_SA))
49102 + || ((((struct k_sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_flags
49103 + & SADB_X_SAFLAGS_CLEARFLOW)
49104 + != SADB_X_SAFLAGS_CLEARFLOW))) {
49105 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49106 + "pfkey_msg_parse: "
49107 + "required SADB_X_DELFLOW extensions missing: either %16llx must be present or %16llx must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n",
49108 + (unsigned long long)K_SADB_X_EXT_ADDRESS_DELFLOW
49109 + - (extensions_seen & K_SADB_X_EXT_ADDRESS_DELFLOW),
49110 + (unsigned long long)(1<<SADB_EXT_SA) - (extensions_seen & (1<<SADB_EXT_SA)));
49111 + SENDERR(EINVAL);
49112 + }
49113 +
49114 + switch(pfkey_msg->sadb_msg_type) {
49115 + case K_SADB_ADD:
49116 + case K_SADB_UPDATE:
49117 + /* check maturity */
49118 + if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state !=
49119 + K_SADB_SASTATE_MATURE) {
49120 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49121 + "pfkey_msg_parse: "
49122 + "state=%d for add or update should be MATURE=%d.\n",
49123 + ((struct k_sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
49124 + K_SADB_SASTATE_MATURE);
49125 + SENDERR(EINVAL);
49126 + }
49127 +
49128 + /* check AH and ESP */
49129 + switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) {
49130 + case SADB_SATYPE_AH:
49131 + if(!(((struct k_sadb_sa*)extensions[SADB_EXT_SA]) &&
49132 + ((struct k_sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth !=
49133 + SADB_AALG_NONE)) {
49134 + ERROR("pfkey_msg_parse: "
49135 + "auth alg is zero, must be non-zero for AH SAs.\n");
49136 + SENDERR(EINVAL);
49137 + }
49138 + if(((struct k_sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt !=
49139 + SADB_EALG_NONE) {
49140 + ERROR("pfkey_msg_parse: "
49141 + "AH handed encalg=%d, must be zero.\n",
49142 + ((struct k_sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt);
49143 + SENDERR(EINVAL);
49144 + }
49145 + break;
49146 + case SADB_SATYPE_ESP:
49147 + if(!(((struct k_sadb_sa*)extensions[SADB_EXT_SA]) &&
49148 + ((struct k_sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
49149 + SADB_EALG_NONE)) {
49150 + ERROR("pfkey_msg_parse: "
49151 + "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n",
49152 + ((struct k_sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
49153 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
49154 + SENDERR(EINVAL);
49155 + }
49156 + if((((struct k_sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt ==
49157 + SADB_EALG_NULL) &&
49158 + (((struct k_sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth ==
49159 + SADB_AALG_NONE) ) {
49160 + ERROR("pfkey_msg_parse: "
49161 + "ESP handed encNULL+authNONE, illegal combination.\n");
49162 + SENDERR(EINVAL);
49163 + }
49164 + break;
49165 + case K_SADB_X_SATYPE_COMP:
49166 + if(!(((struct k_sadb_sa*)extensions[SADB_EXT_SA]) &&
49167 + ((struct k_sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
49168 + SADB_EALG_NONE)) {
49169 + ERROR("pfkey_msg_parse: "
49170 + "encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n",
49171 + ((struct k_sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
49172 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
49173 + SENDERR(EINVAL);
49174 + }
49175 + if(((struct k_sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth !=
49176 + SADB_AALG_NONE) {
49177 + ERROR("pfkey_msg_parse: "
49178 + "COMP handed auth=%d, must be zero.\n",
49179 + ((struct k_sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth);
49180 + SENDERR(EINVAL);
49181 + }
49182 + break;
49183 + default:
49184 + break;
49185 + }
49186 + if(ntohl(((struct k_sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) {
49187 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49188 + "pfkey_msg_parse: "
49189 + "spi=%08x must be > 255.\n",
49190 + ntohl(((struct k_sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi));
49191 + SENDERR(EINVAL);
49192 + }
49193 + default:
49194 + break;
49195 + }
49196 +
49197 +errlab:
49198 + return error;
49199 +}
49200 +
49201 +/*
49202 + * Local variables:
49203 + * c-file-style: "linux"
49204 + * End:
49205 + *
49206 + */
49207 --- /dev/null Tue Mar 11 13:02:56 2003
49208 +++ linux/net/ipsec/pfkey_v2_parser.c Mon Feb 9 13:51:03 2004
49209 @@ -0,0 +1,3063 @@
49210 +/*
49211 + * @(#) RFC2367 PF_KEYv2 Key management API message parser
49212 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
49213 + *
49214 + * OCF support written by David McCullough <dmccullough@cyberguard.com>
49215 + * Copyright (C) 2004-2005 Intel Corporation. All Rights Reserved.
49216 + *
49217 + * This program is free software; you can redistribute it and/or modify it
49218 + * under the terms of the GNU General Public License as published by the
49219 + * Free Software Foundation; either version 2 of the License, or (at your
49220 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
49221 + *
49222 + * This program is distributed in the hope that it will be useful, but
49223 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
49224 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
49225 + * for more details.
49226 + *
49227 + */
49228 +
49229 +/*
49230 + * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
49231 + */
49232 +
49233 +
49234 +#ifndef AUTOCONF_INCLUDED
49235 +#include <linux/config.h>
49236 +#endif
49237 +#include <linux/version.h>
49238 +#include <linux/kernel.h> /* printk() */
49239 +
49240 +#include "openswan/ipsec_param.h"
49241 +
49242 +#ifdef MALLOC_SLAB
49243 +# include <linux/slab.h> /* kmalloc() */
49244 +#else /* MALLOC_SLAB */
49245 +# include <linux/malloc.h> /* kmalloc() */
49246 +#endif /* MALLOC_SLAB */
49247 +#include <linux/errno.h> /* error codes */
49248 +#include <linux/types.h> /* size_t */
49249 +#include <linux/interrupt.h> /* mark_bh */
49250 +
49251 +#include <linux/netdevice.h> /* struct device, and other headers */
49252 +#include <linux/etherdevice.h> /* eth_type_trans */
49253 +#include <linux/ip.h> /* struct iphdr */
49254 +#include <linux/skbuff.h>
49255 +
49256 +#include <openswan.h>
49257 +
49258 +#include <klips-crypto/des.h>
49259 +
49260 +#ifdef SPINLOCK
49261 +# ifdef SPINLOCK_23
49262 +# include <linux/spinlock.h> /* *lock* */
49263 +# else /* SPINLOCK_23 */
49264 +# include <asm/spinlock.h> /* *lock* */
49265 +# endif /* SPINLOCK_23 */
49266 +#endif /* SPINLOCK */
49267 +#ifdef NET_21
49268 +# include <net/route.h> /* inet_addr_type */
49269 +# include <linux/in6.h>
49270 +# define IS_MYADDR RTN_LOCAL
49271 +#endif
49272 +
49273 +#include <net/ip.h>
49274 +#ifdef NETLINK_SOCK
49275 +# include <linux/netlink.h>
49276 +#else
49277 +# include <net/netlink.h>
49278 +#endif
49279 +
49280 +#include <linux/random.h> /* get_random_bytes() */
49281 +
49282 +#include "openswan/radij.h"
49283 +#include "openswan/ipsec_encap.h"
49284 +#include "openswan/ipsec_sa.h"
49285 +
49286 +#include "openswan/ipsec_radij.h"
49287 +#include "openswan/ipsec_xform.h"
49288 +#include "openswan/ipsec_ah.h"
49289 +#include "openswan/ipsec_esp.h"
49290 +#include "openswan/ipsec_tunnel.h"
49291 +#include "openswan/ipsec_mast.h"
49292 +#include "openswan/ipsec_rcv.h"
49293 +#include "openswan/ipcomp.h"
49294 +
49295 +#include <openswan/pfkeyv2.h>
49296 +#include <openswan/pfkey.h>
49297 +
49298 +#include "openswan/ipsec_proto.h"
49299 +#include "openswan/ipsec_alg.h"
49300 +
49301 +#include "openswan/ipsec_kern24.h"
49302 +
49303 +#include "ipsec_ocf.h"
49304 +
49305 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
49306 +
49307 +struct sklist_t {
49308 + struct socket *sk;
49309 + struct sklist_t* next;
49310 +} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev;
49311 +
49312 +__u32 pfkey_msg_seq = 0;
49313 +
49314 +
49315 +#if 0
49316 +#define DUMP_SAID dump_said(&extr->ips->ips_said, __LINE__)
49317 +#define DUMP_SAID2 dump_said(&extr.ips->ips_said, __LINE__)
49318 +static void dump_said(ip_said *s, int line)
49319 +{
49320 + char msa[SATOT_BUF];
49321 + size_t msa_len;
49322 +
49323 + msa_len = satot(s, 0, msa, sizeof(msa));
49324 +
49325 + printk("line: %d msa: %s\n", line, msa);
49326 +}
49327 +#endif
49328 +
49329 +
49330 +int
49331 +pfkey_alloc_eroute(struct eroute** eroute)
49332 +{
49333 + int error = 0;
49334 + if(*eroute) {
49335 + KLIPS_PRINT(debug_pfkey,
49336 + "klips_debug:pfkey_alloc_eroute: "
49337 + "eroute struct already allocated\n");
49338 + SENDERR(EEXIST);
49339 + }
49340 +
49341 + if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) {
49342 + KLIPS_PRINT(debug_pfkey,
49343 + "klips_debug:pfkey_alloc_eroute: "
49344 + "memory allocation error\n");
49345 + SENDERR(ENOMEM);
49346 + }
49347 +
49348 + KLIPS_PRINT(debug_pfkey,
49349 + "klips_debug:pfkey_alloc_eroute: "
49350 + "allocating %lu bytes for an eroute at 0p%p\n",
49351 + (unsigned long) sizeof(**eroute), *eroute);
49352 +
49353 + memset((caddr_t)*eroute, 0, sizeof(**eroute));
49354 + (*eroute)->er_eaddr.sen_len =
49355 + (*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap);
49356 + (*eroute)->er_eaddr.sen_family =
49357 + (*eroute)->er_emask.sen_family = AF_ENCAP;
49358 + (*eroute)->er_eaddr.sen_type = SENT_IP4;
49359 + (*eroute)->er_emask.sen_type = 255;
49360 + (*eroute)->er_pid = 0;
49361 + (*eroute)->er_count = 0;
49362 + (*eroute)->er_lasttime = jiffies/HZ;
49363 +
49364 + errlab:
49365 + return(error);
49366 +}
49367 +
49368 +DEBUG_NO_STATIC int
49369 +pfkey_x_protocol_process(struct sadb_ext *pfkey_ext,
49370 + struct pfkey_extracted_data *extr)
49371 +{
49372 + int error = 0;
49373 + struct sadb_protocol * p = (struct sadb_protocol *)pfkey_ext;
49374 +
49375 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_protocol_process: %p\n", extr);
49376 +
49377 + if (extr == 0) {
49378 + KLIPS_PRINT(debug_pfkey,
49379 + "klips_debug:pfkey_x_protocol_process:"
49380 + "extr is NULL, fatal\n");
49381 + SENDERR(EINVAL);
49382 + }
49383 + if (extr->eroute == 0) {
49384 + KLIPS_PRINT(debug_pfkey,
49385 + "klips_debug:pfkey_x_protocol_process:"
49386 + "extr->eroute is NULL, fatal\n");
49387 + SENDERR(EINVAL);
49388 + }
49389 +
49390 + extr->eroute->er_eaddr.sen_proto = p->sadb_protocol_proto;
49391 + extr->eroute->er_emask.sen_proto = p->sadb_protocol_proto ? ~0:0;
49392 + KLIPS_PRINT(debug_pfkey,
49393 + "klips_debug:pfkey_x_protocol_process: protocol = %d.\n",
49394 + p->sadb_protocol_proto);
49395 + errlab:
49396 + return error;
49397 +}
49398 +
49399 +DEBUG_NO_STATIC int
49400 +pfkey_ipsec_sa_init(struct ipsec_sa *ipsp)
49401 +{
49402 + int rc;
49403 + KLIPS_PRINT(debug_pfkey, "Calling SA_INIT\n");
49404 + rc = ipsec_sa_init(ipsp);
49405 + return rc;
49406 +}
49407 +
49408 +int
49409 +pfkey_safe_build(int error, struct sadb_ext *extensions[K_SADB_MAX+1])
49410 +{
49411 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: "
49412 + "error=%d\n",
49413 + error);
49414 + if (!error) {
49415 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
49416 + "success.\n");
49417 + return 1;
49418 + } else {
49419 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
49420 + "caught error %d\n",
49421 + error);
49422 + pfkey_extensions_free(extensions);
49423 + return 0;
49424 + }
49425 +}
49426 +
49427 +
49428 +DEBUG_NO_STATIC int
49429 +pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
49430 +{
49431 + int error = 0;
49432 + ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L);
49433 + int found_avail = 0;
49434 + struct ipsec_sa *ipsq;
49435 + char sa[SATOT_BUF];
49436 + size_t sa_len;
49437 + struct sadb_ext *extensions_reply[K_SADB_EXT_MAX+1];
49438 + struct sadb_msg *pfkey_reply = NULL;
49439 + struct socket_list *pfkey_socketsp;
49440 + uint8_t satype = ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_satype;
49441 +
49442 + KLIPS_PRINT(debug_pfkey,
49443 + "klips_debug:pfkey_getspi_parse: .\n");
49444 +
49445 + pfkey_extensions_init(extensions_reply);
49446 +
49447 + if(extr == NULL || extr->ips == NULL) {
49448 + KLIPS_PRINT(debug_pfkey,
49449 + "klips_debug:pfkey_getspi_parse: "
49450 + "error, extr or extr->ipsec_sa pointer NULL\n");
49451 + SENDERR(EINVAL);
49452 + }
49453 +
49454 + if(extensions[K_SADB_EXT_SPIRANGE]) {
49455 + minspi = ((struct sadb_spirange *)extensions[K_SADB_EXT_SPIRANGE])->sadb_spirange_min;
49456 + maxspi = ((struct sadb_spirange *)extensions[K_SADB_EXT_SPIRANGE])->sadb_spirange_max;
49457 + }
49458 +
49459 + if(maxspi == minspi) {
49460 + extr->ips->ips_said.spi = maxspi;
49461 + ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
49462 + if(ipsq != NULL) {
49463 + sa_len = KLIPS_SATOT(debug_pfkey, &extr->ips->ips_said, 0, sa, sizeof(sa));
49464 + ipsec_sa_put(ipsq);
49465 + KLIPS_PRINT(debug_pfkey,
49466 + "klips_debug:pfkey_getspi_parse: "
49467 + "EMT_GETSPI found an old ipsec_sa for SA: %s, delete it first.\n",
49468 + sa_len ? sa : " (error)");
49469 + SENDERR(EEXIST);
49470 + } else {
49471 + found_avail = 1;
49472 + }
49473 + } else {
49474 + int i = 0;
49475 + __u32 rand_val;
49476 + __u32 spi_diff;
49477 + while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) {
49478 + prng_bytes(&ipsec_prng, (char *) &(rand_val),
49479 + ( (spi_diff < (2^8)) ? 1 :
49480 + ( (spi_diff < (2^16)) ? 2 :
49481 + ( (spi_diff < (2^24)) ? 3 :
49482 + 4 ) ) ) );
49483 + extr->ips->ips_said.spi = htonl(ntohl(minspi) +
49484 + (rand_val %
49485 + (spi_diff + 1)));
49486 + i++;
49487 + ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
49488 + if(ipsq == NULL) {
49489 + found_avail = 1;
49490 + } else {
49491 + ipsec_sa_put(ipsq);
49492 + }
49493 + }
49494 + }
49495 +
49496 + sa_len = KLIPS_SATOT(debug_pfkey, &extr->ips->ips_said, 0, sa, sizeof(sa));
49497 +
49498 + if (!found_avail) {
49499 + KLIPS_PRINT(debug_pfkey,
49500 + "klips_debug:pfkey_getspi_parse: "
49501 + "found an old ipsec_sa for SA: %s, delete it first.\n",
49502 + sa_len ? sa : " (error)");
49503 + SENDERR(EEXIST);
49504 + }
49505 +
49506 + if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) {
49507 + extr->ips->ips_flags |= EMT_INBOUND;
49508 + }
49509 +
49510 + KLIPS_PRINT(debug_pfkey,
49511 + "klips_debug:pfkey_getspi_parse: "
49512 + "existing ipsec_sa not found (this is good) for SA: %s, %s-bound, allocating.\n",
49513 + sa_len ? sa : " (error)",
49514 + extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
49515 +
49516 + /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
49517 + extr->ips->ips_rcvif = NULL;
49518 + extr->ips->ips_life.ipl_addtime.ipl_count = jiffies/HZ;
49519 +
49520 + extr->ips->ips_state = K_SADB_SASTATE_LARVAL;
49521 +
49522 + if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
49523 + extr->ips->ips_life.ipl_allocations.ipl_count += 1;
49524 + }
49525 +
49526 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
49527 + K_SADB_GETSPI,
49528 + satype,
49529 + 0,
49530 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_seq,
49531 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_pid),
49532 + extensions_reply)
49533 + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[K_SADB_EXT_SA],
49534 + K_SADB_EXT_SA,
49535 + extr->ips->ips_said.spi,
49536 + 0,
49537 + K_SADB_SASTATE_LARVAL,
49538 + 0,
49539 + 0,
49540 + 0),
49541 + extensions_reply)
49542 +
49543 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_EXT_ADDRESS_SRC],
49544 + K_SADB_EXT_ADDRESS_SRC,
49545 + 0, /*extr->ips->ips_said.proto,*/
49546 + 0,
49547 + extr->ips->ips_addr_s),
49548 + extensions_reply)
49549 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_EXT_ADDRESS_DST],
49550 + K_SADB_EXT_ADDRESS_DST,
49551 + 0, /*extr->ips->ips_said.proto,*/
49552 + 0,
49553 + extr->ips->ips_addr_d),
49554 + extensions_reply) )) {
49555 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
49556 + "failed to build the getspi reply message extensions\n");
49557 + goto errlab;
49558 + }
49559 +
49560 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
49561 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
49562 + "failed to build the getspi reply message\n");
49563 + SENDERR(-error);
49564 + }
49565 + for(pfkey_socketsp = pfkey_open_sockets;
49566 + pfkey_socketsp;
49567 + pfkey_socketsp = pfkey_socketsp->next) {
49568 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
49569 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
49570 + "sending up getspi reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
49571 + satype,
49572 + satype2name(satype),
49573 + pfkey_socketsp->socketp,
49574 + error);
49575 + SENDERR(-error);
49576 + }
49577 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
49578 + "sending up getspi reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
49579 + satype,
49580 + satype2name(satype),
49581 + pfkey_socketsp->socketp);
49582 + }
49583 +
49584 + if((error = ipsec_sa_add(extr->ips))) {
49585 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
49586 + "failed to add the larval SA=%s with error=%d.\n",
49587 + sa_len ? sa : " (error)",
49588 + error);
49589 + SENDERR(-error);
49590 + }
49591 + extr->ips = NULL;
49592 +
49593 + KLIPS_PRINT(debug_pfkey,
49594 + "klips_debug:pfkey_getspi_parse: "
49595 + "successful for SA: %s\n",
49596 + sa_len ? sa : " (error)");
49597 +
49598 + errlab:
49599 + if (pfkey_reply) {
49600 + pfkey_msg_free(&pfkey_reply);
49601 + }
49602 + pfkey_extensions_free(extensions_reply);
49603 + return error;
49604 +}
49605 +
49606 +DEBUG_NO_STATIC int
49607 +pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
49608 +{
49609 + int error = 0;
49610 + struct ipsec_sa* ipsq;
49611 + char sa[SATOT_BUF];
49612 + size_t sa_len;
49613 + struct sadb_ext *extensions_reply[K_SADB_EXT_MAX+1];
49614 + struct sadb_msg *pfkey_reply = NULL;
49615 + struct socket_list *pfkey_socketsp;
49616 + uint8_t satype = ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_satype;
49617 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
49618 + struct ipsec_sa *nat_t_ips_saved = NULL;
49619 +#endif
49620 + KLIPS_PRINT(debug_pfkey,
49621 + "klips_debug:pfkey_update_parse: .\n");
49622 +
49623 + pfkey_extensions_init(extensions_reply);
49624 +
49625 + if(((struct sadb_sa*)extensions[K_SADB_EXT_SA])->sadb_sa_state != K_SADB_SASTATE_MATURE) {
49626 + KLIPS_PRINT(debug_pfkey,
49627 + "klips_debug:pfkey_update_parse: "
49628 + "error, sa_state=%d must be MATURE=%d\n",
49629 + ((struct sadb_sa*)extensions[K_SADB_EXT_SA])->sadb_sa_state,
49630 + K_SADB_SASTATE_MATURE);
49631 + SENDERR(EINVAL);
49632 + }
49633 +
49634 + if(extr == NULL || extr->ips == NULL) {
49635 + KLIPS_PRINT(debug_pfkey,
49636 + "klips_debug:pfkey_update_parse: "
49637 + "error, extr or extr->ips pointer NULL\n");
49638 + SENDERR(EINVAL);
49639 + }
49640 +
49641 + sa_len = KLIPS_SATOT(debug_pfkey, &extr->ips->ips_said, 0, sa, sizeof(sa));
49642 +
49643 + spin_lock_bh(&tdb_lock);
49644 +
49645 + ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
49646 + if (ipsq == NULL) {
49647 + spin_unlock_bh(&tdb_lock);
49648 + KLIPS_PRINT(debug_pfkey,
49649 + "klips_debug:pfkey_update_parse: "
49650 + "reserved ipsec_sa for SA: %s not found. Call K_SADB_GETSPI first or call K_SADB_ADD instead.\n",
49651 + sa_len ? sa : " (error)");
49652 + SENDERR(ENOENT);
49653 + }
49654 +
49655 + if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) {
49656 + extr->ips->ips_flags |= EMT_INBOUND;
49657 + }
49658 +
49659 + KLIPS_PRINT(debug_pfkey,
49660 + "klips_debug:pfkey_update_parse: "
49661 + "existing ipsec_sa found (this is good) for SA: %s, %s-bound, updating.\n",
49662 + sa_len ? sa : " (error)",
49663 + extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
49664 +
49665 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
49666 + if (extr->ips->ips_natt_sport || extr->ips->ips_natt_dport) {
49667 + KLIPS_PRINT(debug_pfkey,
49668 + "klips_debug:pfkey_update_parse: only updating NAT-T ports "
49669 + "(%u:%u -> %u:%u)\n",
49670 + ipsq->ips_natt_sport, ipsq->ips_natt_dport,
49671 + extr->ips->ips_natt_sport, extr->ips->ips_natt_dport);
49672 +
49673 + if (extr->ips->ips_natt_sport) {
49674 + ipsq->ips_natt_sport = extr->ips->ips_natt_sport;
49675 + if (ipsq->ips_addr_s->sa_family == AF_INET) {
49676 + ((struct sockaddr_in *)(ipsq->ips_addr_s))->sin_port = htons(extr->ips->ips_natt_sport);
49677 + }
49678 + }
49679 +
49680 + if (extr->ips->ips_natt_dport) {
49681 + ipsq->ips_natt_dport = extr->ips->ips_natt_dport;
49682 + if (ipsq->ips_addr_d->sa_family == AF_INET) {
49683 + ((struct sockaddr_in *)(ipsq->ips_addr_d))->sin_port = htons(extr->ips->ips_natt_dport);
49684 + }
49685 + }
49686 +
49687 + nat_t_ips_saved = extr->ips;
49688 + extr->ips = ipsq;
49689 + }
49690 + else
49691 +#endif
49692 + {
49693 + /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
49694 + extr->ips->ips_rcvif = NULL;
49695 + if ((error = pfkey_ipsec_sa_init(extr->ips))) {
49696 + ipsec_sa_put(ipsq);
49697 + spin_unlock_bh(&tdb_lock);
49698 + KLIPS_PRINT(debug_pfkey,
49699 + "klips_debug:pfkey_update_parse: "
49700 + "not successful for SA: %s, deleting.\n",
49701 + sa_len ? sa : " (error)");
49702 + SENDERR(-error);
49703 + }
49704 +
49705 + extr->ips->ips_life.ipl_addtime.ipl_count = ipsq->ips_life.ipl_addtime.ipl_count;
49706 +
49707 + /* this will call delchain-equivalent if refcount=>0 */
49708 + ipsec_sa_put(ipsq);
49709 + }
49710 +
49711 + spin_unlock_bh(&tdb_lock);
49712 +
49713 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
49714 + K_SADB_UPDATE,
49715 + satype,
49716 + 0,
49717 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_seq,
49718 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_pid),
49719 + extensions_reply)
49720 + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[K_SADB_EXT_SA],
49721 + K_SADB_EXT_SA,
49722 + extr->ips->ips_said.spi,
49723 + extr->ips->ips_replaywin,
49724 + extr->ips->ips_state,
49725 + extr->ips->ips_authalg,
49726 + extr->ips->ips_encalg,
49727 + extr->ips->ips_flags),
49728 + extensions_reply)
49729 + /* The 3 lifetime extentions should only be sent if non-zero. */
49730 + && (extensions[K_SADB_EXT_LIFETIME_HARD]
49731 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[K_SADB_EXT_LIFETIME_HARD],
49732 + K_SADB_EXT_LIFETIME_HARD,
49733 + extr->ips->ips_life.ipl_allocations.ipl_hard,
49734 + extr->ips->ips_life.ipl_bytes.ipl_hard,
49735 + extr->ips->ips_life.ipl_addtime.ipl_hard,
49736 + extr->ips->ips_life.ipl_usetime.ipl_hard,
49737 + extr->ips->ips_life.ipl_packets.ipl_hard),
49738 + extensions_reply) : 1)
49739 + && (extensions[K_SADB_EXT_LIFETIME_SOFT]
49740 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[K_SADB_EXT_LIFETIME_SOFT],
49741 + K_SADB_EXT_LIFETIME_SOFT,
49742 + extr->ips->ips_life.ipl_allocations.ipl_count,
49743 + extr->ips->ips_life.ipl_bytes.ipl_count,
49744 + extr->ips->ips_life.ipl_addtime.ipl_count,
49745 + extr->ips->ips_life.ipl_usetime.ipl_count,
49746 + extr->ips->ips_life.ipl_packets.ipl_count),
49747 + extensions_reply) : 1)
49748 + && (extr->ips->ips_life.ipl_allocations.ipl_count
49749 + || extr->ips->ips_life.ipl_bytes.ipl_count
49750 + || extr->ips->ips_life.ipl_addtime.ipl_count
49751 + || extr->ips->ips_life.ipl_usetime.ipl_count
49752 + || extr->ips->ips_life.ipl_packets.ipl_count
49753 +
49754 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[K_SADB_EXT_LIFETIME_CURRENT],
49755 + K_SADB_EXT_LIFETIME_CURRENT,
49756 + extr->ips->ips_life.ipl_allocations.ipl_count,
49757 + extr->ips->ips_life.ipl_bytes.ipl_count,
49758 + extr->ips->ips_life.ipl_addtime.ipl_count,
49759 + extr->ips->ips_life.ipl_usetime.ipl_count,
49760 + extr->ips->ips_life.ipl_packets.ipl_count),
49761 + extensions_reply) : 1)
49762 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_EXT_ADDRESS_SRC],
49763 + K_SADB_EXT_ADDRESS_SRC,
49764 + 0, /*extr->ips->ips_said.proto,*/
49765 + 0,
49766 + extr->ips->ips_addr_s),
49767 + extensions_reply)
49768 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_EXT_ADDRESS_DST],
49769 + K_SADB_EXT_ADDRESS_DST,
49770 + 0, /*extr->ips->ips_said.proto,*/
49771 + 0,
49772 + extr->ips->ips_addr_d),
49773 + extensions_reply)
49774 + && (extr->ips->ips_ident_s.data
49775 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[K_SADB_EXT_IDENTITY_SRC],
49776 + K_SADB_EXT_IDENTITY_SRC,
49777 + extr->ips->ips_ident_s.type,
49778 + extr->ips->ips_ident_s.id,
49779 + extr->ips->ips_ident_s.len,
49780 + extr->ips->ips_ident_s.data),
49781 + extensions_reply) : 1)
49782 + && (extr->ips->ips_ident_d.data
49783 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[K_SADB_EXT_IDENTITY_DST],
49784 + K_SADB_EXT_IDENTITY_DST,
49785 + extr->ips->ips_ident_d.type,
49786 + extr->ips->ips_ident_d.id,
49787 + extr->ips->ips_ident_d.len,
49788 + extr->ips->ips_ident_d.data),
49789 + extensions_reply) : 1)
49790 +#if 0
49791 + /* FIXME: This won't work yet because I have not finished
49792 + it. */
49793 + && (extr->ips->ips_sens_
49794 + ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[K_SADB_EXT_SENSITIVITY],
49795 + extr->ips->ips_sens_dpd,
49796 + extr->ips->ips_sens_sens_level,
49797 + extr->ips->ips_sens_sens_len,
49798 + extr->ips->ips_sens_sens_bitmap,
49799 + extr->ips->ips_sens_integ_level,
49800 + extr->ips->ips_sens_integ_len,
49801 + extr->ips->ips_sens_integ_bitmap),
49802 + extensions_reply) : 1)
49803 +#endif
49804 + )) {
49805 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
49806 + "failed to build the update reply message extensions\n");
49807 + SENDERR(-error);
49808 + }
49809 +
49810 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
49811 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
49812 + "failed to build the update reply message\n");
49813 + SENDERR(-error);
49814 + }
49815 + for(pfkey_socketsp = pfkey_open_sockets;
49816 + pfkey_socketsp;
49817 + pfkey_socketsp = pfkey_socketsp->next) {
49818 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
49819 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
49820 + "sending up update reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
49821 + satype,
49822 + satype2name(satype),
49823 + pfkey_socketsp->socketp,
49824 + error);
49825 + SENDERR(-error);
49826 + }
49827 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
49828 + "sending up update reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
49829 + satype,
49830 + satype2name(satype),
49831 + pfkey_socketsp->socketp);
49832 + }
49833 +
49834 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
49835 + if (nat_t_ips_saved) {
49836 + /**
49837 + * As we _really_ update existing SA, we keep tdbq and need to delete
49838 + * parsed ips (nat_t_ips_saved, was extr->ips).
49839 + *
49840 + * goto errlab with extr->ips = nat_t_ips_saved will free it.
49841 + */
49842 +
49843 + extr->ips = nat_t_ips_saved;
49844 +
49845 + error = 0;
49846 + KLIPS_PRINT(debug_pfkey,
49847 + "klips_debug:pfkey_update_parse (NAT-T ports): "
49848 + "successful for SA: %s\n",
49849 + sa_len ? sa : " (error)");
49850 +
49851 + goto errlab;
49852 + }
49853 +#endif
49854 +
49855 + if((error = ipsec_sa_add(extr->ips))) {
49856 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
49857 + "failed to update the mature SA=%s with error=%d.\n",
49858 + sa_len ? sa : " (error)",
49859 + error);
49860 + SENDERR(-error);
49861 + }
49862 + extr->ips = NULL;
49863 +
49864 + KLIPS_PRINT(debug_pfkey,
49865 + "klips_debug:pfkey_update_parse: "
49866 + "successful for SA: %s\n",
49867 + sa_len ? sa : " (error)");
49868 +
49869 + errlab:
49870 + if (pfkey_reply) {
49871 + pfkey_msg_free(&pfkey_reply);
49872 + }
49873 + pfkey_extensions_free(extensions_reply);
49874 + return error;
49875 +}
49876 +
49877 +DEBUG_NO_STATIC int
49878 +pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
49879 +{
49880 + int error = 0;
49881 + struct ipsec_sa* ipsq;
49882 + char sa[SATOT_BUF];
49883 + size_t sa_len;
49884 + struct sadb_ext *extensions_reply[K_SADB_EXT_MAX+1];
49885 + struct sadb_msg *pfkey_reply = NULL;
49886 + struct socket_list *pfkey_socketsp;
49887 + uint8_t satype = ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_satype;
49888 +
49889 + KLIPS_PRINT(debug_pfkey,
49890 + "klips_debug:pfkey_add_parse: .\n");
49891 +
49892 + pfkey_extensions_init(extensions_reply);
49893 +
49894 + if(((struct sadb_sa*)extensions[K_SADB_EXT_SA])->sadb_sa_state != K_SADB_SASTATE_MATURE) {
49895 + KLIPS_PRINT(debug_pfkey,
49896 + "klips_debug:pfkey_add_parse: "
49897 + "error, sa_state=%d must be MATURE=%d\n",
49898 + ((struct sadb_sa*)extensions[K_SADB_EXT_SA])->sadb_sa_state,
49899 + K_SADB_SASTATE_MATURE);
49900 + SENDERR(EINVAL);
49901 + }
49902 +
49903 + if(!extr || !extr->ips) {
49904 + KLIPS_PRINT(debug_pfkey,
49905 + "klips_debug:pfkey_add_parse: "
49906 + "extr or extr->ips pointer NULL\n");
49907 + SENDERR(EINVAL);
49908 + }
49909 +
49910 + sa_len = KLIPS_SATOT(debug_pfkey, &extr->ips->ips_said, 0, sa, sizeof(sa));
49911 +
49912 + ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
49913 + if(ipsq != NULL) {
49914 + ipsec_sa_put(ipsq);
49915 + KLIPS_PRINT(debug_pfkey,
49916 + "klips_debug:pfkey_add_parse: "
49917 + "found an old ipsec_sa for SA%s, delete it first.\n",
49918 + sa_len ? sa : " (error)");
49919 + SENDERR(EEXIST);
49920 + }
49921 +
49922 + if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) {
49923 + extr->ips->ips_flags |= EMT_INBOUND;
49924 + }
49925 +
49926 + KLIPS_PRINT(debug_pfkey,
49927 + "klips_debug:pfkey_add_parse: "
49928 + "existing ipsec_sa not found (this is good) for SA%s, %s-bound, allocating.\n",
49929 + sa_len ? sa : " (error)",
49930 + extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
49931 +
49932 + /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
49933 + extr->ips->ips_rcvif = NULL;
49934 +
49935 + if ((error = ipsec_sa_init(extr->ips))) {
49936 + KLIPS_ERROR(debug_pfkey,
49937 + "pfkey_add_parse: "
49938 + "not successful for SA: %s, deleting.\n",
49939 + sa_len ? sa : " (error)");
49940 + SENDERR(-error);
49941 + }
49942 +
49943 + if(extr->sarefme!=IPSEC_SAREF_NULL
49944 + && extr->ips->ips_ref==IPSEC_SAREF_NULL) {
49945 + extr->ips->ips_ref=extr->sarefme;
49946 + }
49947 +
49948 + if(extr->sarefhim!=IPSEC_SAREF_NULL
49949 + && extr->ips->ips_refhim==IPSEC_SAREF_NULL) {
49950 + extr->ips->ips_refhim=extr->sarefhim;
49951 + }
49952 +
49953 + /* attach it to the SAref table */
49954 + if((error = ipsec_sa_intern(extr->ips)) != 0) {
49955 + KLIPS_ERROR(debug_pfkey,
49956 + "pfkey_add_parse: "
49957 + "failed to intern SA as SAref#%lu\n"
49958 + , (unsigned long)extr->ips->ips_ref);
49959 + SENDERR(-error);
49960 + }
49961 +
49962 + extr->ips->ips_life.ipl_addtime.ipl_count = jiffies / HZ;
49963 + if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
49964 + extr->ips->ips_life.ipl_allocations.ipl_count += 1;
49965 + }
49966 +
49967 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
49968 + K_SADB_ADD,
49969 + satype,
49970 + 0,
49971 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_seq,
49972 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_pid),
49973 + extensions_reply)
49974 + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[K_SADB_EXT_SA],
49975 + K_SADB_EXT_SA,
49976 + extr->ips->ips_said.spi,
49977 + extr->ips->ips_replaywin,
49978 + extr->ips->ips_state,
49979 + extr->ips->ips_authalg,
49980 + extr->ips->ips_encalg,
49981 + extr->ips->ips_flags),
49982 + extensions_reply)
49983 + && pfkey_safe_build(error = pfkey_saref_build(&extensions_reply[K_SADB_X_EXT_SAREF],
49984 + extr->ips->ips_ref,
49985 + extr->ips->ips_refhim),
49986 + extensions_reply)
49987 + /* The 3 lifetime extentions should only be sent if non-zero. */
49988 + && (extensions[K_SADB_EXT_LIFETIME_HARD]
49989 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[K_SADB_EXT_LIFETIME_HARD],
49990 + K_SADB_EXT_LIFETIME_HARD,
49991 + extr->ips->ips_life.ipl_allocations.ipl_hard,
49992 + extr->ips->ips_life.ipl_bytes.ipl_hard,
49993 + extr->ips->ips_life.ipl_addtime.ipl_hard,
49994 + extr->ips->ips_life.ipl_usetime.ipl_hard,
49995 + extr->ips->ips_life.ipl_packets.ipl_hard),
49996 + extensions_reply) : 1)
49997 + && (extensions[K_SADB_EXT_LIFETIME_SOFT]
49998 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[K_SADB_EXT_LIFETIME_SOFT],
49999 + K_SADB_EXT_LIFETIME_SOFT,
50000 + extr->ips->ips_life.ipl_allocations.ipl_soft,
50001 + extr->ips->ips_life.ipl_bytes.ipl_soft,
50002 + extr->ips->ips_life.ipl_addtime.ipl_soft,
50003 + extr->ips->ips_life.ipl_usetime.ipl_soft,
50004 + extr->ips->ips_life.ipl_packets.ipl_soft),
50005 + extensions_reply) : 1)
50006 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_EXT_ADDRESS_SRC],
50007 + K_SADB_EXT_ADDRESS_SRC,
50008 + 0, /*extr->ips->ips_said.proto,*/
50009 + 0,
50010 + extr->ips->ips_addr_s),
50011 + extensions_reply)
50012 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_EXT_ADDRESS_DST],
50013 + K_SADB_EXT_ADDRESS_DST,
50014 + 0, /*extr->ips->ips_said.proto,*/
50015 + 0,
50016 + extr->ips->ips_addr_d),
50017 + extensions_reply)
50018 + && (extr->ips->ips_ident_s.data
50019 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[K_SADB_EXT_IDENTITY_SRC],
50020 + K_SADB_EXT_IDENTITY_SRC,
50021 + extr->ips->ips_ident_s.type,
50022 + extr->ips->ips_ident_s.id,
50023 + extr->ips->ips_ident_s.len,
50024 + extr->ips->ips_ident_s.data),
50025 + extensions_reply) : 1)
50026 + && (extr->ips->ips_ident_d.data
50027 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[K_SADB_EXT_IDENTITY_DST],
50028 + K_SADB_EXT_IDENTITY_DST,
50029 + extr->ips->ips_ident_d.type,
50030 + extr->ips->ips_ident_d.id,
50031 + extr->ips->ips_ident_d.len,
50032 + extr->ips->ips_ident_d.data),
50033 + extensions_reply) : 1)
50034 +#if 0
50035 + /* FIXME: This won't work yet because I have not finished
50036 + it. */
50037 + && (extr->ips->ips_sens_
50038 + ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[K_SADB_EXT_SENSITIVITY],
50039 + extr->ips->ips_sens_dpd,
50040 + extr->ips->ips_sens_sens_level,
50041 + extr->ips->ips_sens_sens_len,
50042 + extr->ips->ips_sens_sens_bitmap,
50043 + extr->ips->ips_sens_integ_level,
50044 + extr->ips->ips_sens_integ_len,
50045 + extr->ips->ips_sens_integ_bitmap),
50046 + extensions_reply) : 1)
50047 +#endif
50048 + )) {
50049 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
50050 + "failed to build the add reply message extensions\n");
50051 + SENDERR(-error);
50052 + }
50053 +
50054 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
50055 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
50056 + "failed to build the add reply message\n");
50057 + SENDERR(-error);
50058 + }
50059 + for(pfkey_socketsp = pfkey_open_sockets;
50060 + pfkey_socketsp;
50061 + pfkey_socketsp = pfkey_socketsp->next) {
50062 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
50063 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
50064 + "sending up add reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
50065 + satype,
50066 + satype2name(satype),
50067 + pfkey_socketsp->socketp,
50068 + error);
50069 + SENDERR(-error);
50070 + }
50071 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
50072 + "sending up add reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
50073 + satype,
50074 + satype2name(satype),
50075 + pfkey_socketsp->socketp);
50076 + }
50077 +
50078 + if(extr->outif != 0 && extr->outif != -1) {
50079 + extr->ips->ips_out = ipsec_mast_get_device(extr->outif);
50080 + extr->ips->ips_transport_direct = ipsec_mast_is_transport(extr->outif);
50081 + }
50082 +
50083 + if((error = ipsec_sa_add(extr->ips))) {
50084 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
50085 + "failed to add the mature SA=%s with error=%d.\n",
50086 + sa_len ? sa : " (error)",
50087 + error);
50088 + SENDERR(-error);
50089 + }
50090 + ipsec_sa_put(extr->ips);
50091 + extr->ips = NULL;
50092 +
50093 + KLIPS_PRINT(debug_pfkey,
50094 + "klips_debug:pfkey_add_parse: "
50095 + "successful for SA: %s\n",
50096 + sa_len ? sa : " (error)");
50097 +
50098 + errlab:
50099 + if (pfkey_reply) {
50100 + pfkey_msg_free(&pfkey_reply);
50101 + }
50102 + pfkey_extensions_free(extensions_reply);
50103 + return error;
50104 +}
50105 +
50106 +DEBUG_NO_STATIC int
50107 +pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
50108 +{
50109 + struct ipsec_sa *ipsp;
50110 + char sa[SATOT_BUF];
50111 + size_t sa_len;
50112 + int error = 0;
50113 + struct sadb_ext *extensions_reply[K_SADB_EXT_MAX+1];
50114 + struct sadb_msg *pfkey_reply = NULL;
50115 + struct socket_list *pfkey_socketsp;
50116 + uint8_t satype = ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_satype;
50117 + IPsecSAref_t ref;
50118 + struct sadb_builds sab;
50119 +
50120 + KLIPS_PRINT(debug_pfkey,
50121 + "klips_debug:pfkey_delete_parse: .\n");
50122 +
50123 + pfkey_extensions_init(extensions_reply);
50124 +
50125 + if(!extr || !extr->ips) {
50126 + KLIPS_PRINT(debug_pfkey,
50127 + "klips_debug:pfkey_delete_parse: "
50128 + "extr or extr->ips pointer NULL, fatal\n");
50129 + SENDERR(EINVAL);
50130 + }
50131 +
50132 + sa_len = KLIPS_SATOT(debug_pfkey, &extr->ips->ips_said, 0, sa, sizeof(sa));
50133 +
50134 + spin_lock_bh(&tdb_lock);
50135 +
50136 + ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
50137 + if (ipsp == NULL) {
50138 + spin_unlock_bh(&tdb_lock);
50139 + KLIPS_PRINT(debug_pfkey,
50140 + "klips_debug:pfkey_delete_parse: "
50141 + "ipsec_sa not found for SA:%s, could not delete.\n",
50142 + sa_len ? sa : " (error)");
50143 + SENDERR(ESRCH);
50144 + }
50145 +
50146 + /* remove it from SAref tables */
50147 + ref = ipsp->ips_ref;
50148 + ipsec_sa_untern(ipsp);
50149 + ipsec_sa_rm(ipsp);
50150 +
50151 + /* this will call delchain-equivalent if refcount -> 0
50152 + * noting that get() above, added to ref count */
50153 + ipsec_sa_put(ipsp);
50154 + spin_unlock_bh(&tdb_lock);
50155 +
50156 + memset(&sab, 0, sizeof(sab));
50157 + sab.sa_base.sadb_sa_exttype = K_SADB_EXT_SA;
50158 + sab.sa_base.sadb_sa_spi = extr->ips->ips_said.spi;
50159 + sab.sa_base.sadb_sa_replay = 0;
50160 + sab.sa_base.sadb_sa_state = 0;
50161 + sab.sa_base.sadb_sa_auth = 0;
50162 + sab.sa_base.sadb_sa_encrypt = 0;
50163 + sab.sa_base.sadb_sa_flags = 0;
50164 + sab.sa_base.sadb_x_sa_ref = ref;
50165 +
50166 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
50167 + K_SADB_DELETE,
50168 + satype,
50169 + 0,
50170 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_seq,
50171 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_pid),
50172 + extensions_reply)
50173 + && pfkey_safe_build(error = pfkey_sa_builds(&extensions_reply[K_SADB_EXT_SA], sab),
50174 + extensions_reply)
50175 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_EXT_ADDRESS_SRC],
50176 + K_SADB_EXT_ADDRESS_SRC,
50177 + 0, /*extr->ips->ips_said.proto,*/
50178 + 0,
50179 + extr->ips->ips_addr_s),
50180 + extensions_reply)
50181 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_EXT_ADDRESS_DST],
50182 + K_SADB_EXT_ADDRESS_DST,
50183 + 0, /*extr->ips->ips_said.proto,*/
50184 + 0,
50185 + extr->ips->ips_addr_d),
50186 + extensions_reply)
50187 + )) {
50188 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
50189 + "failed to build the delete reply message extensions\n");
50190 + SENDERR(-error);
50191 + }
50192 +
50193 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
50194 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
50195 + "failed to build the delete reply message\n");
50196 + SENDERR(-error);
50197 + }
50198 + for(pfkey_socketsp = pfkey_open_sockets;
50199 + pfkey_socketsp;
50200 + pfkey_socketsp = pfkey_socketsp->next) {
50201 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
50202 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
50203 + "sending up delete reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
50204 + satype,
50205 + satype2name(satype),
50206 + pfkey_socketsp->socketp,
50207 + error);
50208 + SENDERR(-error);
50209 + }
50210 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
50211 + "sending up delete reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
50212 + satype,
50213 + satype2name(satype),
50214 + pfkey_socketsp->socketp);
50215 + }
50216 +
50217 + errlab:
50218 + if (pfkey_reply) {
50219 + pfkey_msg_free(&pfkey_reply);
50220 + }
50221 + pfkey_extensions_free(extensions_reply);
50222 + return error;
50223 +}
50224 +
50225 +DEBUG_NO_STATIC int
50226 +pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
50227 +{
50228 + int error = 0;
50229 + struct ipsec_sa *ipsp;
50230 + char sa[SATOT_BUF];
50231 + size_t sa_len;
50232 + struct sadb_ext *extensions_reply[K_SADB_EXT_MAX+1];
50233 + struct sadb_msg *pfkey_reply = NULL;
50234 +
50235 + KLIPS_PRINT(debug_pfkey,
50236 + "klips_debug:pfkey_get_parse: .\n");
50237 +
50238 + pfkey_extensions_init(extensions_reply);
50239 +
50240 + if(!extr || !extr->ips) {
50241 + KLIPS_PRINT(debug_pfkey,
50242 + "klips_debug:pfkey_get_parse: "
50243 + "extr or extr->ips pointer NULL, fatal\n");
50244 + SENDERR(EINVAL);
50245 + }
50246 +
50247 + sa_len = KLIPS_SATOT(debug_pfkey, &extr->ips->ips_said, 0, sa, sizeof(sa));
50248 +
50249 + spin_lock_bh(&tdb_lock);
50250 +
50251 + ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
50252 + if (ipsp == NULL) {
50253 + spin_unlock_bh(&tdb_lock);
50254 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
50255 + "ipsec_sa not found for SA=%s, could not get.\n",
50256 + sa_len ? sa : " (error)");
50257 + SENDERR(ESRCH);
50258 + }
50259 +
50260 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
50261 + K_SADB_GET,
50262 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_satype,
50263 + 0,
50264 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_seq,
50265 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_pid),
50266 + extensions_reply)
50267 + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[K_SADB_EXT_SA],
50268 + K_SADB_EXT_SA,
50269 + extr->ips->ips_said.spi,
50270 + extr->ips->ips_replaywin,
50271 + extr->ips->ips_state,
50272 + extr->ips->ips_authalg,
50273 + extr->ips->ips_encalg,
50274 + extr->ips->ips_flags),
50275 + extensions_reply)
50276 + /* The 3 lifetime extentions should only be sent if non-zero. */
50277 + && (ipsp->ips_life.ipl_allocations.ipl_count
50278 + || ipsp->ips_life.ipl_bytes.ipl_count
50279 + || ipsp->ips_life.ipl_addtime.ipl_count
50280 + || ipsp->ips_life.ipl_usetime.ipl_count
50281 + || ipsp->ips_life.ipl_packets.ipl_count
50282 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[K_SADB_EXT_LIFETIME_CURRENT],
50283 + K_SADB_EXT_LIFETIME_CURRENT,
50284 + ipsp->ips_life.ipl_allocations.ipl_count,
50285 + ipsp->ips_life.ipl_bytes.ipl_count,
50286 + ipsp->ips_life.ipl_addtime.ipl_count,
50287 + ipsp->ips_life.ipl_usetime.ipl_count,
50288 + ipsp->ips_life.ipl_packets.ipl_count),
50289 + extensions_reply) : 1)
50290 + && (ipsp->ips_life.ipl_allocations.ipl_hard
50291 + || ipsp->ips_life.ipl_bytes.ipl_hard
50292 + || ipsp->ips_life.ipl_addtime.ipl_hard
50293 + || ipsp->ips_life.ipl_usetime.ipl_hard
50294 + || ipsp->ips_life.ipl_packets.ipl_hard
50295 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[K_SADB_EXT_LIFETIME_HARD],
50296 + K_SADB_EXT_LIFETIME_HARD,
50297 + ipsp->ips_life.ipl_allocations.ipl_hard,
50298 + ipsp->ips_life.ipl_bytes.ipl_hard,
50299 + ipsp->ips_life.ipl_addtime.ipl_hard,
50300 + ipsp->ips_life.ipl_usetime.ipl_hard,
50301 + ipsp->ips_life.ipl_packets.ipl_hard),
50302 + extensions_reply) : 1)
50303 + && (ipsp->ips_life.ipl_allocations.ipl_soft
50304 + || ipsp->ips_life.ipl_bytes.ipl_soft
50305 + || ipsp->ips_life.ipl_addtime.ipl_soft
50306 + || ipsp->ips_life.ipl_usetime.ipl_soft
50307 + || ipsp->ips_life.ipl_packets.ipl_soft
50308 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[K_SADB_EXT_LIFETIME_SOFT],
50309 + K_SADB_EXT_LIFETIME_SOFT,
50310 + ipsp->ips_life.ipl_allocations.ipl_soft,
50311 + ipsp->ips_life.ipl_bytes.ipl_soft,
50312 + ipsp->ips_life.ipl_addtime.ipl_soft,
50313 + ipsp->ips_life.ipl_usetime.ipl_soft,
50314 + ipsp->ips_life.ipl_packets.ipl_soft),
50315 + extensions_reply) : 1)
50316 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_EXT_ADDRESS_SRC],
50317 + K_SADB_EXT_ADDRESS_SRC,
50318 + 0, /*extr->ips->ips_said.proto,*/
50319 + 0,
50320 + extr->ips->ips_addr_s),
50321 + extensions_reply)
50322 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_EXT_ADDRESS_DST],
50323 + K_SADB_EXT_ADDRESS_DST,
50324 + 0, /*extr->ips->ips_said.proto,*/
50325 + 0,
50326 + extr->ips->ips_addr_d),
50327 + extensions_reply)
50328 + && (extr->ips->ips_addr_p
50329 + ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_EXT_ADDRESS_PROXY],
50330 + K_SADB_EXT_ADDRESS_PROXY,
50331 + 0, /*extr->ips->ips_said.proto,*/
50332 + 0,
50333 + extr->ips->ips_addr_p),
50334 + extensions_reply) : 1)
50335 +#if 0
50336 + /* FIXME: This won't work yet because the keys are not
50337 + stored directly in the ipsec_sa. They are stored as
50338 + contexts. */
50339 + && (extr->ips->ips_key_a_size
50340 + ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[K_SADB_EXT_KEY_AUTH],
50341 + K_SADB_EXT_KEY_AUTH,
50342 + extr->ips->ips_key_a_size * 8,
50343 + extr->ips->ips_key_a),
50344 + extensions_reply) : 1)
50345 + /* FIXME: This won't work yet because the keys are not
50346 + stored directly in the ipsec_sa. They are stored as
50347 + key schedules. */
50348 + && (extr->ips->ips_key_e_size
50349 + ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[K_SADB_EXT_KEY_ENCRYPT],
50350 + K_SADB_EXT_KEY_ENCRYPT,
50351 + extr->ips->ips_key_e_size * 8,
50352 + extr->ips->ips_key_e),
50353 + extensions_reply) : 1)
50354 +#endif
50355 + && (extr->ips->ips_ident_s.data
50356 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[K_SADB_EXT_IDENTITY_SRC],
50357 + K_SADB_EXT_IDENTITY_SRC,
50358 + extr->ips->ips_ident_s.type,
50359 + extr->ips->ips_ident_s.id,
50360 + extr->ips->ips_ident_s.len,
50361 + extr->ips->ips_ident_s.data),
50362 + extensions_reply) : 1)
50363 + && (extr->ips->ips_ident_d.data
50364 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[K_SADB_EXT_IDENTITY_DST],
50365 + K_SADB_EXT_IDENTITY_DST,
50366 + extr->ips->ips_ident_d.type,
50367 + extr->ips->ips_ident_d.id,
50368 + extr->ips->ips_ident_d.len,
50369 + extr->ips->ips_ident_d.data),
50370 + extensions_reply) : 1)
50371 +#if 0
50372 + /* FIXME: This won't work yet because I have not finished
50373 + it. */
50374 + && (extr->ips->ips_sens_
50375 + ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[K_SADB_EXT_SENSITIVITY],
50376 + extr->ips->ips_sens_dpd,
50377 + extr->ips->ips_sens_sens_level,
50378 + extr->ips->ips_sens_sens_len,
50379 + extr->ips->ips_sens_sens_bitmap,
50380 + extr->ips->ips_sens_integ_level,
50381 + extr->ips->ips_sens_integ_len,
50382 + extr->ips->ips_sens_integ_bitmap),
50383 + extensions_reply) : 1)
50384 +#endif
50385 + )) {
50386 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
50387 + "failed to build the get reply message extensions\n");
50388 + ipsec_sa_put(ipsp);
50389 + spin_unlock_bh(&tdb_lock);
50390 + SENDERR(-error);
50391 + }
50392 +
50393 + ipsec_sa_put(ipsp);
50394 + spin_unlock_bh(&tdb_lock);
50395 +
50396 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
50397 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
50398 + "failed to build the get reply message\n");
50399 + SENDERR(-error);
50400 + }
50401 +
50402 + if((error = pfkey_upmsg(sk->sk_socket, pfkey_reply))) {
50403 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
50404 + "failed to send the get reply message\n");
50405 + SENDERR(-error);
50406 + }
50407 +
50408 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
50409 + "succeeded in sending get reply message.\n");
50410 +
50411 + errlab:
50412 + if (pfkey_reply) {
50413 + pfkey_msg_free(&pfkey_reply);
50414 + }
50415 + pfkey_extensions_free(extensions_reply);
50416 + return error;
50417 +}
50418 +
50419 +DEBUG_NO_STATIC int
50420 +pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
50421 +{
50422 + int error = 0;
50423 + struct socket_list *pfkey_socketsp;
50424 + uint8_t satype = ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_satype;
50425 +
50426 + KLIPS_PRINT(debug_pfkey,
50427 + "klips_debug:pfkey_acquire_parse: .\n");
50428 +
50429 + /* XXX I don't know if we want an upper bound, since userspace may
50430 + want to register itself for an satype > K_SADB_SATYPE_MAX. */
50431 + if((satype == 0) || (satype > K_SADB_SATYPE_MAX)) {
50432 + KLIPS_PRINT(debug_pfkey,
50433 + "klips_debug:pfkey_acquire_parse: "
50434 + "SATYPE=%d invalid.\n",
50435 + satype);
50436 + SENDERR(EINVAL);
50437 + }
50438 +
50439 + if(!(pfkey_registered_sockets[satype])) {
50440 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
50441 + "no sockets registered for SAtype=%d(%s).\n",
50442 + satype,
50443 + satype2name(satype));
50444 + SENDERR(EPROTONOSUPPORT);
50445 + }
50446 +
50447 + for(pfkey_socketsp = pfkey_registered_sockets[satype];
50448 + pfkey_socketsp;
50449 + pfkey_socketsp = pfkey_socketsp->next) {
50450 + if((error = pfkey_upmsg(pfkey_socketsp->socketp,
50451 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])))) {
50452 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
50453 + "sending up acquire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
50454 + satype,
50455 + satype2name(satype),
50456 + pfkey_socketsp->socketp,
50457 + error);
50458 + SENDERR(-error);
50459 + }
50460 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
50461 + "sending up acquire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
50462 + satype,
50463 + satype2name(satype),
50464 + pfkey_socketsp->socketp);
50465 + }
50466 +
50467 + errlab:
50468 + return error;
50469 +}
50470 +
50471 +DEBUG_NO_STATIC int
50472 +pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
50473 +{
50474 + int error = 0;
50475 + uint8_t satype = ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_satype;
50476 +
50477 + KLIPS_PRINT(debug_pfkey,
50478 + "klips_debug:pfkey_register_parse: .\n");
50479 +
50480 + /* XXX I don't know if we want an upper bound, since userspace may
50481 + want to register itself for an satype > K_SADB_SATYPE_MAX. */
50482 + if((satype == 0) || (satype > K_SADB_SATYPE_MAX)) {
50483 + KLIPS_PRINT(debug_pfkey,
50484 + "klips_debug:pfkey_register_parse: "
50485 + "SATYPE=%d invalid.\n",
50486 + satype);
50487 + SENDERR(EINVAL);
50488 + }
50489 +
50490 + if(!pfkey_list_insert_socket(sk->sk_socket,
50491 + &(pfkey_registered_sockets[satype]))) {
50492 + KLIPS_PRINT(debug_pfkey,
50493 + "klips_debug:pfkey_register_parse: "
50494 + "SATYPE=%02d(%s) successfully registered by KMd (pid=%d).\n",
50495 + satype,
50496 + satype2name(satype),
50497 + key_pid(sk));
50498 + };
50499 +
50500 + /* send up register msg with supported SATYPE algos */
50501 +
50502 + error=pfkey_register_reply(satype, (struct sadb_msg*)extensions[K_SADB_EXT_RESERVED]);
50503 + errlab:
50504 + return error;
50505 +}
50506 +
50507 +int
50508 +pfkey_register_reply(int satype, struct sadb_msg *sadb_msg)
50509 +{
50510 + struct sadb_ext *extensions_reply[K_SADB_EXT_MAX+1];
50511 + struct sadb_msg *pfkey_reply = NULL;
50512 + struct socket_list *pfkey_socketsp;
50513 + struct supported_list *pfkey_supported_listp;
50514 + unsigned int alg_num_a = 0, alg_num_e = 0;
50515 + struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL;
50516 + int error = 0;
50517 +
50518 + pfkey_extensions_init(extensions_reply);
50519 +
50520 + if((satype == 0) || (satype > K_SADB_SATYPE_MAX)) {
50521 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
50522 + "SAtype=%d unspecified or unknown.\n",
50523 + satype);
50524 + SENDERR(EINVAL);
50525 + }
50526 + if(!(pfkey_registered_sockets[satype])) {
50527 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
50528 + "no sockets registered for SAtype=%d(%s).\n",
50529 + satype,
50530 + satype2name(satype));
50531 + SENDERR(EPROTONOSUPPORT);
50532 + }
50533 + /* send up register msg with supported SATYPE algos */
50534 + pfkey_supported_listp = pfkey_supported_list[satype];
50535 + KLIPS_PRINT(debug_pfkey,
50536 + "klips_debug:pfkey_register_reply: "
50537 + "pfkey_supported_list[%d]=0p%p\n",
50538 + satype,
50539 + pfkey_supported_list[satype]);
50540 + while(pfkey_supported_listp) {
50541 + KLIPS_PRINT(debug_pfkey,
50542 + "klips_debug:pfkey_register_reply: "
50543 + "checking supported=0p%p\n",
50544 + pfkey_supported_listp);
50545 + if(pfkey_supported_listp->supportedp->ias_exttype == K_SADB_EXT_SUPPORTED_AUTH) {
50546 + KLIPS_PRINT(debug_pfkey,
50547 + "klips_debug:pfkey_register_reply: "
50548 + "adding auth alg.\n");
50549 + alg_num_a++;
50550 + }
50551 + if(pfkey_supported_listp->supportedp->ias_exttype == K_SADB_EXT_SUPPORTED_ENCRYPT) {
50552 + KLIPS_PRINT(debug_pfkey,
50553 + "klips_debug:pfkey_register_reply: "
50554 + "adding encrypt alg.\n");
50555 + alg_num_e++;
50556 + }
50557 + pfkey_supported_listp = pfkey_supported_listp->next;
50558 + }
50559 +
50560 + if(alg_num_a) {
50561 + KLIPS_PRINT(debug_pfkey,
50562 + "klips_debug:pfkey_register_reply: "
50563 + "allocating %lu bytes for auth algs.\n",
50564 + (unsigned long) (alg_num_a * sizeof(struct sadb_alg)));
50565 + if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
50566 + KLIPS_PRINT(debug_pfkey,
50567 + "klips_debug:pfkey_register_reply: "
50568 + "auth alg memory allocation error\n");
50569 + SENDERR(ENOMEM);
50570 + }
50571 + alg_ap = alg_a;
50572 + }
50573 +
50574 + if(alg_num_e) {
50575 + KLIPS_PRINT(debug_pfkey,
50576 + "klips_debug:pfkey_register_reply: "
50577 + "allocating %lu bytes for enc algs.\n",
50578 + (unsigned long) (alg_num_e * sizeof(struct sadb_alg)));
50579 + if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
50580 + KLIPS_PRINT(debug_pfkey,
50581 + "klips_debug:pfkey_register_reply: "
50582 + "enc alg memory allocation error\n");
50583 + SENDERR(ENOMEM);
50584 + }
50585 + alg_ep = alg_e;
50586 + }
50587 +
50588 + pfkey_supported_listp = pfkey_supported_list[satype];
50589 + while(pfkey_supported_listp) {
50590 + if(alg_num_a) {
50591 + if(pfkey_supported_listp->supportedp->ias_exttype == K_SADB_EXT_SUPPORTED_AUTH) {
50592 + alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->ias_id;
50593 + alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->ias_ivlen;
50594 + alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->ias_keyminbits;
50595 + alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->ias_keymaxbits;
50596 + alg_ap->sadb_alg_reserved = 0;
50597 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
50598 + "klips_debug:pfkey_register_reply: "
50599 + "adding auth=0p%p\n",
50600 + alg_ap);
50601 + alg_ap++;
50602 + }
50603 + }
50604 + if(alg_num_e) {
50605 + if(pfkey_supported_listp->supportedp->ias_exttype == K_SADB_EXT_SUPPORTED_ENCRYPT) {
50606 + alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->ias_id;
50607 + alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->ias_ivlen;
50608 + alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->ias_keyminbits;
50609 + alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->ias_keymaxbits;
50610 + alg_ep->sadb_alg_reserved = 0;
50611 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
50612 + "klips_debug:pfkey_register_reply: "
50613 + "adding encrypt=0p%p\n",
50614 + alg_ep);
50615 + alg_ep++;
50616 + }
50617 + }
50618 + KLIPS_PRINT(debug_pfkey,
50619 + "klips_debug:pfkey_register_reply: "
50620 + "found satype=%d(%s) exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
50621 + satype,
50622 + satype2name(satype),
50623 + pfkey_supported_listp->supportedp->ias_exttype,
50624 + pfkey_supported_listp->supportedp->ias_id,
50625 + pfkey_supported_listp->supportedp->ias_ivlen,
50626 + pfkey_supported_listp->supportedp->ias_keyminbits,
50627 + pfkey_supported_listp->supportedp->ias_keymaxbits);
50628 + pfkey_supported_listp = pfkey_supported_listp->next;
50629 + }
50630 +
50631 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
50632 + K_SADB_REGISTER,
50633 + satype,
50634 + 0,
50635 + sadb_msg? sadb_msg->sadb_msg_seq : ++pfkey_msg_seq,
50636 + sadb_msg? sadb_msg->sadb_msg_pid: current->pid),
50637 + extensions_reply) &&
50638 + (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[K_SADB_EXT_SUPPORTED_AUTH],
50639 + K_SADB_EXT_SUPPORTED_AUTH,
50640 + alg_num_a,
50641 + alg_a),
50642 + extensions_reply) : 1) &&
50643 + (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[K_SADB_EXT_SUPPORTED_ENCRYPT],
50644 + K_SADB_EXT_SUPPORTED_ENCRYPT,
50645 + alg_num_e,
50646 + alg_e),
50647 + extensions_reply) : 1))) {
50648 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
50649 + "failed to build the register message extensions_reply\n");
50650 + SENDERR(-error);
50651 + }
50652 +
50653 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
50654 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
50655 + "failed to build the register message\n");
50656 + SENDERR(-error);
50657 + }
50658 + /* this should go to all registered sockets for that satype only */
50659 + for(pfkey_socketsp = pfkey_registered_sockets[satype];
50660 + pfkey_socketsp;
50661 + pfkey_socketsp = pfkey_socketsp->next) {
50662 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
50663 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
50664 + "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
50665 + satype,
50666 + satype2name(satype),
50667 + pfkey_socketsp->socketp,
50668 + error);
50669 + SENDERR(-error);
50670 + }
50671 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
50672 + "sending up register message for satype=%d(%s) to socket=0p%p succeeded.\n",
50673 + satype,
50674 + satype2name(satype),
50675 + pfkey_socketsp->socketp);
50676 + }
50677 +
50678 + errlab:
50679 + if(alg_a) {
50680 + kfree(alg_a);
50681 + }
50682 + if(alg_e) {
50683 + kfree(alg_e);
50684 + }
50685 +
50686 + if (pfkey_reply) {
50687 + pfkey_msg_free(&pfkey_reply);
50688 + }
50689 + pfkey_extensions_free(extensions_reply);
50690 + return error;
50691 +}
50692 +
50693 +DEBUG_NO_STATIC int
50694 +pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
50695 +{
50696 + int error = 0;
50697 + struct socket_list *pfkey_socketsp;
50698 +#ifdef CONFIG_KLIPS_DEBUG
50699 + uint8_t satype = ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_satype;
50700 +#endif /* CONFIG_KLIPS_DEBUG */
50701 +
50702 + KLIPS_PRINT(debug_pfkey,
50703 + "klips_debug:pfkey_expire_parse: .\n");
50704 +
50705 + if(pfkey_open_sockets) {
50706 + for(pfkey_socketsp = pfkey_open_sockets;
50707 + pfkey_socketsp;
50708 + pfkey_socketsp = pfkey_socketsp->next) {
50709 + if((error = pfkey_upmsg(pfkey_socketsp->socketp,
50710 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])))) {
50711 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
50712 + "sending up expire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
50713 + satype,
50714 + satype2name(satype),
50715 + pfkey_socketsp->socketp,
50716 + error);
50717 + SENDERR(-error);
50718 + }
50719 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
50720 + "sending up expire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
50721 + satype,
50722 + satype2name(satype),
50723 + pfkey_socketsp->socketp);
50724 + }
50725 + }
50726 +
50727 + errlab:
50728 + return error;
50729 +}
50730 +
50731 +
50732 +/*
50733 + *
50734 + * flush all SAs from the table
50735 + */
50736 +DEBUG_NO_STATIC int
50737 +pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
50738 +{
50739 + int error = 0;
50740 + struct socket_list *pfkey_socketsp;
50741 + uint8_t satype = ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_satype;
50742 + uint8_t proto = 0;
50743 +
50744 + KLIPS_PRINT(debug_pfkey,
50745 + "klips_debug:pfkey_flush_parse: "
50746 + "flushing type %d SAs\n",
50747 + satype);
50748 +
50749 + if(satype && !(proto = satype2proto(satype))) {
50750 + KLIPS_PRINT(debug_pfkey,
50751 + "klips_debug:pfkey_flush_parse: "
50752 + "satype %d lookup failed.\n",
50753 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_satype);
50754 + SENDERR(EINVAL);
50755 + }
50756 +
50757 + if ((error = ipsec_sadb_cleanup(proto))) {
50758 + SENDERR(-error);
50759 + }
50760 +
50761 + if(pfkey_open_sockets) {
50762 + for(pfkey_socketsp = pfkey_open_sockets;
50763 + pfkey_socketsp;
50764 + pfkey_socketsp = pfkey_socketsp->next) {
50765 + if((error = pfkey_upmsg(pfkey_socketsp->socketp,
50766 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])))) {
50767 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
50768 + "sending up flush reply message for satype=%d(%s) (proto=%d) to socket=0p%p failed with error=%d.\n",
50769 + satype,
50770 + satype2name(satype),
50771 + proto,
50772 + pfkey_socketsp->socketp,
50773 + error);
50774 + SENDERR(-error);
50775 + }
50776 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
50777 + "sending up flush reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
50778 + satype,
50779 + satype2name(satype),
50780 + pfkey_socketsp->socketp);
50781 + }
50782 + }
50783 +
50784 + errlab:
50785 + return error;
50786 +}
50787 +
50788 +DEBUG_NO_STATIC int
50789 +pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
50790 +{
50791 + int error = 0;
50792 +
50793 + KLIPS_PRINT(debug_pfkey,
50794 + "klips_debug:pfkey_dump_parse: .\n");
50795 +
50796 + SENDERR(ENOSYS);
50797 + errlab:
50798 + return error;
50799 +}
50800 +
50801 +DEBUG_NO_STATIC int
50802 +pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
50803 +{
50804 + int error = 0;
50805 +
50806 + KLIPS_PRINT(debug_pfkey,
50807 + "klips_debug:pfkey_promisc_parse: .\n");
50808 +
50809 + SENDERR(ENOSYS);
50810 + errlab:
50811 + return error;
50812 +}
50813 +
50814 +DEBUG_NO_STATIC int
50815 +pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
50816 +{
50817 + int error = 0;
50818 +
50819 + KLIPS_PRINT(debug_pfkey,
50820 + "klips_debug:pfkey_x_pchange_parse: .\n");
50821 +
50822 + SENDERR(ENOSYS);
50823 + errlab:
50824 + return error;
50825 +}
50826 +
50827 +DEBUG_NO_STATIC int
50828 +pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
50829 +{
50830 + struct ipsec_sa *ips1p, *ips2p, *ipsp;
50831 + struct sadb_ext *extensions_reply[K_SADB_EXT_MAX+1];
50832 + struct sadb_msg *pfkey_reply = NULL;
50833 + struct socket_list *pfkey_socketsp;
50834 + uint8_t satype = ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_satype;
50835 + char sa1[SATOT_BUF], sa2[SATOT_BUF];
50836 + size_t sa_len1, sa_len2 = 0;
50837 + int error = 0;
50838 +
50839 + KLIPS_PRINT(debug_pfkey,
50840 + "klips_debug:pfkey_x_grpsa_parse: .\n");
50841 +
50842 + pfkey_extensions_init(extensions_reply);
50843 +
50844 + if(extr == NULL || extr->ips == NULL) {
50845 + KLIPS_PRINT(debug_pfkey,
50846 + "klips_debug:pfkey_x_grpsa_parse: "
50847 + "extr or extr->ips is NULL, fatal.\n");
50848 + SENDERR(EINVAL);
50849 + }
50850 +
50851 + sa_len1 = KLIPS_SATOT(debug_pfkey, &extr->ips->ips_said, 0, sa1, sizeof(sa1));
50852 + if(extr->ips2 != NULL) {
50853 + sa_len2 = KLIPS_SATOT(debug_pfkey, &extr->ips2->ips_said, 0, sa2, sizeof(sa2));
50854 + }
50855 +
50856 + spin_lock_bh(&tdb_lock);
50857 +
50858 + ips1p = ipsec_sa_getbyid(&(extr->ips->ips_said));
50859 + if(ips1p == NULL) {
50860 + spin_unlock_bh(&tdb_lock);
50861 + KLIPS_ERROR(debug_pfkey,
50862 + "klips_debug:pfkey_x_grpsa_parse: "
50863 + "reserved ipsec_sa for SA1: %s not found. Call K_SADB_ADD/UPDATE first.\n",
50864 + sa_len1 ? sa1 : " (error)");
50865 + SENDERR(ENOENT);
50866 + }
50867 +
50868 + if(extr->ips2) { /* GRPSA */
50869 +
50870 + /* group ips2p to be after ips1p */
50871 +
50872 + ips2p = ipsec_sa_getbyid(&(extr->ips2->ips_said));
50873 + if(ips2p == NULL) {
50874 + ipsec_sa_put(ips1p);
50875 + spin_unlock_bh(&tdb_lock);
50876 + KLIPS_PRINT(debug_pfkey,
50877 + "klips_debug:pfkey_x_grpsa_parse: "
50878 + "reserved ipsec_sa for SA2: %s not found. Call K_SADB_ADD/UPDATE first.\n",
50879 + sa_len2 ? sa2 : " (error)");
50880 + SENDERR(ENOENT);
50881 + }
50882 +
50883 + /* userspace puts things in inner to outer order */
50884 + if(ips2p->ips_flags & EMT_INBOUND) {
50885 + struct ipsec_sa *t;
50886 +
50887 + /* exchange ips and ips2 */
50888 + t = ips1p;
50889 + ips1p = ips2p;
50890 + ips2p = t;
50891 + }
50892 +
50893 + /* Is ips1p already linked? */
50894 + if(ips1p->ips_next) {
50895 + ipsec_sa_put(ips1p);
50896 + ipsec_sa_put(ips2p);
50897 + spin_unlock_bh(&tdb_lock);
50898 + KLIPS_ERROR(debug_pfkey,
50899 + "klips_debug:pfkey_x_grpsa_parse: "
50900 + "ipsec_sa for SA: %s is already linked.\n",
50901 + sa_len1 ? sa1 : " (error)");
50902 + SENDERR(EEXIST);
50903 + }
50904 +
50905 + /* Is extr->ips already linked to extr->ips2? */
50906 + ipsp = ips2p;
50907 + while(ipsp) {
50908 + if(ipsp == ips1p) {
50909 + ipsec_sa_put(ips1p);
50910 + ipsec_sa_put(ips2p);
50911 + spin_unlock_bh(&tdb_lock);
50912 + KLIPS_ERROR(debug_pfkey,
50913 + "klips_debug:pfkey_x_grpsa_parse: "
50914 + "ipsec_sa for SA: %s is already linked to %s.\n",
50915 + sa_len1 ? sa1 : " (error)",
50916 + sa_len2 ? sa2 : " (error)");
50917 + SENDERR(EEXIST);
50918 + }
50919 + ipsp = ipsp->ips_next;
50920 + }
50921 +
50922 + /* link 'em */
50923 + KLIPS_PRINT(debug_pfkey,
50924 + "klips_debug:pfkey_x_grpsa_parse: "
50925 + "linking ipsec_sa SA: %s with %s.\n",
50926 + sa_len1 ? sa1 : " (error)",
50927 + sa_len2 ? sa2 : " (error)");
50928 + ips1p->ips_next = ips2p;
50929 + } else { /* UNGRPSA */
50930 + while(ips1p) {
50931 + struct ipsec_sa *ipsn;
50932 +
50933 + /* take the reference to next */
50934 + ipsn = ips1p->ips_next;
50935 + ips1p->ips_next = NULL;
50936 +
50937 + /* drop reference to current */
50938 + ipsec_sa_put(ips1p);
50939 +
50940 + ips1p = ipsn;
50941 + }
50942 +
50943 + /* note: we have dropped reference to ips1p, and
50944 + * it is now NULL
50945 + */
50946 + KLIPS_PRINT(debug_pfkey,
50947 + "klips_debug:pfkey_x_grpsa_parse: "
50948 + "unlinking ipsec_sa SA: %s.\n",
50949 + sa_len1 ? sa1 : " (error)");
50950 + }
50951 +
50952 + spin_unlock_bh(&tdb_lock);
50953 +
50954 + /* MCR: not only is this ugly to read, and impossible
50955 + * to debug through, but it's also really inefficient.
50956 + * XXX simplify me.
50957 + */
50958 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
50959 + K_SADB_X_GRPSA,
50960 + satype,
50961 + 0,
50962 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_seq,
50963 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_pid),
50964 + extensions_reply)
50965 + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[K_SADB_EXT_SA],
50966 + K_SADB_EXT_SA,
50967 + extr->ips->ips_said.spi,
50968 + extr->ips->ips_replaywin,
50969 + extr->ips->ips_state,
50970 + extr->ips->ips_authalg,
50971 + extr->ips->ips_encalg,
50972 + extr->ips->ips_flags),
50973 + extensions_reply)
50974 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_EXT_ADDRESS_DST],
50975 + K_SADB_EXT_ADDRESS_DST,
50976 + 0, /*extr->ips->ips_said.proto,*/
50977 + 0,
50978 + extr->ips->ips_addr_d),
50979 + extensions_reply)
50980 + && (extr->ips2
50981 + ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[K_SADB_X_EXT_SATYPE2],
50982 + ((struct sadb_x_satype*)extensions[K_SADB_X_EXT_SATYPE2])->sadb_x_satype_satype
50983 + /* proto2satype(extr->ips2->ips_said.proto) */),
50984 + extensions_reply)
50985 + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[K_SADB_X_EXT_SA2],
50986 + K_SADB_X_EXT_SA2,
50987 + extr->ips2->ips_said.spi,
50988 + extr->ips2->ips_replaywin,
50989 + extr->ips2->ips_state,
50990 + extr->ips2->ips_authalg,
50991 + extr->ips2->ips_encalg,
50992 + extr->ips2->ips_flags),
50993 + extensions_reply)
50994 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_X_EXT_ADDRESS_DST2],
50995 + K_SADB_X_EXT_ADDRESS_DST2,
50996 + 0, /*extr->ips->ips_said.proto,*/
50997 + 0,
50998 + extr->ips2->ips_addr_d),
50999 + extensions_reply) ) : 1 )
51000 + )) {
51001 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
51002 + "failed to build the x_grpsa reply message extensions\n");
51003 + SENDERR(-error);
51004 + }
51005 +
51006 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
51007 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
51008 + "failed to build the x_grpsa reply message\n");
51009 + SENDERR(-error);
51010 + }
51011 +
51012 + for(pfkey_socketsp = pfkey_open_sockets;
51013 + pfkey_socketsp;
51014 + pfkey_socketsp = pfkey_socketsp->next) {
51015 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
51016 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
51017 + "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
51018 + satype,
51019 + satype2name(satype),
51020 + pfkey_socketsp->socketp,
51021 + error);
51022 + SENDERR(-error);
51023 + }
51024 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
51025 + "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
51026 + satype,
51027 + satype2name(satype),
51028 + pfkey_socketsp->socketp);
51029 + }
51030 +
51031 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
51032 + "succeeded in sending x_grpsa reply message.\n");
51033 +
51034 + errlab:
51035 + if (pfkey_reply) {
51036 + pfkey_msg_free(&pfkey_reply);
51037 + }
51038 + pfkey_extensions_free(extensions_reply);
51039 + return error;
51040 +}
51041 +
51042 +DEBUG_NO_STATIC int
51043 +pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
51044 +{
51045 + int error = 0;
51046 +#ifdef CONFIG_KLIPS_DEBUG
51047 + char buf1[64], buf2[64];
51048 +#endif /* CONFIG_KLIPS_DEBUG */
51049 + struct sadb_ext *extensions_reply[K_SADB_EXT_MAX+1];
51050 + struct sadb_msg *pfkey_reply = NULL;
51051 + struct socket_list *pfkey_socketsp;
51052 + uint8_t satype = ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_satype;
51053 + ip_address srcflow, dstflow, srcmask, dstmask;
51054 +
51055 + KLIPS_PRINT(debug_pfkey,
51056 + "klips_debug:pfkey_x_addflow_parse: .\n");
51057 +
51058 + pfkey_extensions_init(extensions_reply);
51059 +
51060 + memset((caddr_t)&srcflow, 0, sizeof(srcflow));
51061 + memset((caddr_t)&dstflow, 0, sizeof(dstflow));
51062 + memset((caddr_t)&srcmask, 0, sizeof(srcmask));
51063 + memset((caddr_t)&dstmask, 0, sizeof(dstmask));
51064 +
51065 + if(!extr || !(extr->ips) || !(extr->eroute)) {
51066 + KLIPS_PRINT(debug_pfkey,
51067 + "klips_debug:pfkey_x_addflow_parse: "
51068 + "missing extr, ipsec_sa or eroute data.\n");
51069 + SENDERR(EINVAL);
51070 + }
51071 +
51072 + srcflow.u.v4.sin_family = AF_INET;
51073 + dstflow.u.v4.sin_family = AF_INET;
51074 + srcmask.u.v4.sin_family = AF_INET;
51075 + dstmask.u.v4.sin_family = AF_INET;
51076 + srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
51077 + dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
51078 + srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
51079 + dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
51080 +
51081 +#ifdef CONFIG_KLIPS_DEBUG
51082 + if (debug_pfkey) {
51083 + subnettoa(extr->eroute->er_eaddr.sen_ip_src,
51084 + extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
51085 + subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
51086 + extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
51087 + KLIPS_PRINT(debug_pfkey,
51088 + "klips_debug:pfkey_x_addflow_parse: "
51089 + "calling breakeroute and/or makeroute for %s->%s\n",
51090 + buf1, buf2);
51091 + }
51092 +#endif /* CONFIG_KLIPS_DEBUG */
51093 + if(extr->ips->ips_flags & SADB_X_SAFLAGS_INFLOW) {
51094 +/* if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) */
51095 + struct ipsec_sa *ipsp, *ipsq;
51096 + char sa[SATOT_BUF];
51097 + size_t sa_len;
51098 +
51099 + ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
51100 + if(ipsq == NULL) {
51101 + KLIPS_PRINT(debug_pfkey,
51102 + "klips_debug:pfkey_x_addflow_parse: "
51103 + "ipsec_sa not found, cannot set incoming policy.\n");
51104 + SENDERR(ENOENT);
51105 + }
51106 +
51107 + ipsp = ipsq;
51108 + while(ipsp && ipsp->ips_said.proto != IPPROTO_IPIP) {
51109 + ipsp = ipsp->ips_next;
51110 + }
51111 +
51112 + if(ipsp == NULL) {
51113 + ipsec_sa_put(ipsq);
51114 + KLIPS_PRINT(debug_pfkey,
51115 + "klips_debug:pfkey_x_addflow_parse: "
51116 + "SA chain does not have an IPIP SA, cannot set incoming policy.\n");
51117 + SENDERR(ENOENT);
51118 + }
51119 +
51120 + sa_len = KLIPS_SATOT(debug_pfkey, &extr->ips->ips_said, 0, sa, sizeof(sa));
51121 +
51122 + ipsp->ips_flags |= SADB_X_SAFLAGS_INFLOW;
51123 + ipsp->ips_flow_s = srcflow;
51124 + ipsp->ips_flow_d = dstflow;
51125 + ipsp->ips_mask_s = srcmask;
51126 + ipsp->ips_mask_d = dstmask;
51127 +
51128 + ipsec_sa_put(ipsq);
51129 +
51130 + KLIPS_PRINT(debug_pfkey,
51131 + "klips_debug:pfkey_x_addflow_parse: "
51132 + "inbound eroute, setting incoming policy information in IPIP ipsec_sa for SA: %s.\n",
51133 + sa_len ? sa : " (error)");
51134 + } else {
51135 + struct sk_buff *first = NULL, *last = NULL;
51136 +
51137 + if(extr->ips->ips_flags & SADB_X_SAFLAGS_REPLACEFLOW) {
51138 + KLIPS_PRINT(debug_pfkey,
51139 + "klips_debug:pfkey_x_addflow_parse: "
51140 + "REPLACEFLOW flag set, calling breakeroute.\n");
51141 + if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr),
51142 + &(extr->eroute->er_emask),
51143 + &first, &last))) {
51144 + KLIPS_PRINT(debug_pfkey,
51145 + "klips_debug:pfkey_x_addflow_parse: "
51146 + "breakeroute returned %d. first=0p%p, last=0p%p\n",
51147 + error,
51148 + first,
51149 + last);
51150 + if(first != NULL) {
51151 + ipsec_kfree_skb(first);
51152 + }
51153 + if(last != NULL) {
51154 + ipsec_kfree_skb(last);
51155 + }
51156 + SENDERR(-error);
51157 + }
51158 + }
51159 +
51160 + KLIPS_PRINT(debug_pfkey,
51161 + "klips_debug:pfkey_x_addflow_parse: "
51162 + "calling makeroute.\n");
51163 +
51164 + if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr),
51165 + &(extr->eroute->er_emask),
51166 + extr->ips->ips_said,
51167 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_pid,
51168 + NULL,
51169 + &(extr->ips->ips_ident_s),
51170 + &(extr->ips->ips_ident_d)))) {
51171 + KLIPS_PRINT(debug_pfkey,
51172 + "klips_debug:pfkey_x_addflow_parse: "
51173 + "makeroute returned %d.\n", error);
51174 + SENDERR(-error);
51175 + }
51176 + if(first != NULL) {
51177 + KLIPS_PRINT(debug_eroute,
51178 + "klips_debug:pfkey_x_addflow_parse: "
51179 + "first=0p%p HOLD packet re-injected.\n",
51180 + first);
51181 + dst_output(first);
51182 + }
51183 + if(last != NULL) {
51184 + KLIPS_PRINT(debug_eroute,
51185 + "klips_debug:pfkey_x_addflow_parse: "
51186 + "last=0p%p HOLD packet re-injected.\n",
51187 + last);
51188 + dst_output(last);
51189 + }
51190 + }
51191 +
51192 + KLIPS_PRINT(debug_pfkey,
51193 + "klips_debug:pfkey_x_addflow_parse: "
51194 + "makeroute call successful.\n");
51195 +
51196 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
51197 + K_SADB_X_ADDFLOW,
51198 + satype,
51199 + 0,
51200 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_seq,
51201 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_pid),
51202 + extensions_reply)
51203 + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[K_SADB_EXT_SA],
51204 + K_SADB_EXT_SA,
51205 + extr->ips->ips_said.spi,
51206 + extr->ips->ips_replaywin,
51207 + extr->ips->ips_state,
51208 + extr->ips->ips_authalg,
51209 + extr->ips->ips_encalg,
51210 + extr->ips->ips_flags),
51211 + extensions_reply)
51212 + && (extensions[K_SADB_EXT_ADDRESS_SRC]
51213 + ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_EXT_ADDRESS_SRC],
51214 + K_SADB_EXT_ADDRESS_SRC,
51215 + 0, /*extr->ips->ips_said.proto,*/
51216 + 0,
51217 + extr->ips->ips_addr_s),
51218 + extensions_reply) : 1)
51219 + && (extensions[K_SADB_EXT_ADDRESS_DST]
51220 + ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_EXT_ADDRESS_DST],
51221 + K_SADB_EXT_ADDRESS_DST,
51222 + 0, /*extr->ips->ips_said.proto,*/
51223 + 0,
51224 + extr->ips->ips_addr_d),
51225 + extensions_reply) : 1)
51226 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_X_EXT_ADDRESS_SRC_FLOW],
51227 + K_SADB_X_EXT_ADDRESS_SRC_FLOW,
51228 + 0, /*extr->ips->ips_said.proto,*/
51229 + 0,
51230 + (struct sockaddr*)&srcflow),
51231 + extensions_reply)
51232 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_X_EXT_ADDRESS_DST_FLOW],
51233 + K_SADB_X_EXT_ADDRESS_DST_FLOW,
51234 + 0, /*extr->ips->ips_said.proto,*/
51235 + 0,
51236 + (struct sockaddr*)&dstflow),
51237 + extensions_reply)
51238 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_X_EXT_ADDRESS_SRC_MASK],
51239 + K_SADB_X_EXT_ADDRESS_SRC_MASK,
51240 + 0, /*extr->ips->ips_said.proto,*/
51241 + 0,
51242 + (struct sockaddr*)&srcmask),
51243 + extensions_reply)
51244 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_X_EXT_ADDRESS_DST_MASK],
51245 + K_SADB_X_EXT_ADDRESS_DST_MASK,
51246 + 0, /*extr->ips->ips_said.proto,*/
51247 + 0,
51248 + (struct sockaddr*)&dstmask),
51249 + extensions_reply)
51250 + )) {
51251 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
51252 + "failed to build the x_addflow reply message extensions\n");
51253 + SENDERR(-error);
51254 + }
51255 +
51256 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
51257 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
51258 + "failed to build the x_addflow reply message\n");
51259 + SENDERR(-error);
51260 + }
51261 +
51262 + for(pfkey_socketsp = pfkey_open_sockets;
51263 + pfkey_socketsp;
51264 + pfkey_socketsp = pfkey_socketsp->next) {
51265 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
51266 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
51267 + "sending up x_addflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
51268 + satype,
51269 + satype2name(satype),
51270 + pfkey_socketsp->socketp,
51271 + error);
51272 + SENDERR(-error);
51273 + }
51274 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
51275 + "sending up x_addflow reply message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
51276 + satype,
51277 + satype2name(satype),
51278 + extr->ips->ips_said.proto,
51279 + pfkey_socketsp->socketp);
51280 + }
51281 +
51282 + KLIPS_PRINT(debug_pfkey,
51283 + "klips_debug:pfkey_x_addflow_parse: "
51284 + "extr->ips cleaned up and freed.\n");
51285 +
51286 + errlab:
51287 + if (pfkey_reply) {
51288 + pfkey_msg_free(&pfkey_reply);
51289 + }
51290 + pfkey_extensions_free(extensions_reply);
51291 + return error;
51292 +}
51293 +
51294 +DEBUG_NO_STATIC int
51295 +pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
51296 +{
51297 + int error = 0;
51298 +#ifdef CONFIG_KLIPS_DEBUG
51299 + char buf1[64], buf2[64];
51300 +#endif /* CONFIG_KLIPS_DEBUG */
51301 + struct sadb_ext *extensions_reply[K_SADB_EXT_MAX+1];
51302 + struct sadb_msg *pfkey_reply = NULL;
51303 + struct socket_list *pfkey_socketsp;
51304 + uint8_t satype = ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_satype;
51305 + ip_address srcflow, dstflow, srcmask, dstmask;
51306 +
51307 + KLIPS_PRINT(debug_pfkey,
51308 + "klips_debug:pfkey_x_delflow_parse: .\n");
51309 +
51310 + pfkey_extensions_init(extensions_reply);
51311 +
51312 + memset((caddr_t)&srcflow, 0, sizeof(srcflow));
51313 + memset((caddr_t)&dstflow, 0, sizeof(dstflow));
51314 + memset((caddr_t)&srcmask, 0, sizeof(srcmask));
51315 + memset((caddr_t)&dstmask, 0, sizeof(dstmask));
51316 +
51317 + if(!extr || !(extr->ips)) {
51318 + KLIPS_PRINT(debug_pfkey,
51319 + "klips_debug:pfkey_x_delflow_parse: "
51320 + "extr, or extr->ips is NULL, fatal\n");
51321 + SENDERR(EINVAL);
51322 + }
51323 +
51324 + if(extr->ips->ips_flags & SADB_X_SAFLAGS_CLEARFLOW) {
51325 + KLIPS_PRINT(debug_pfkey,
51326 + "klips_debug:pfkey_x_delflow_parse: "
51327 + "CLEARFLOW flag set, calling cleareroutes.\n");
51328 + if ((error = ipsec_cleareroutes())) {
51329 + KLIPS_PRINT(debug_pfkey,
51330 + "klips_debug:pfkey_x_delflow_parse: "
51331 + "cleareroutes returned %d.\n", error);
51332 + SENDERR(-error);
51333 + }
51334 + } else {
51335 + struct sk_buff *first = NULL, *last = NULL;
51336 +
51337 + if(!(extr->eroute)) {
51338 + KLIPS_PRINT(debug_pfkey,
51339 + "klips_debug:pfkey_x_delflow_parse: "
51340 + "extr->eroute is NULL, fatal.\n");
51341 + SENDERR(EINVAL);
51342 + }
51343 +
51344 + srcflow.u.v4.sin_family = AF_INET;
51345 + dstflow.u.v4.sin_family = AF_INET;
51346 + srcmask.u.v4.sin_family = AF_INET;
51347 + dstmask.u.v4.sin_family = AF_INET;
51348 + srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
51349 + dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
51350 + srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
51351 + dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
51352 +
51353 +#ifdef CONFIG_KLIPS_DEBUG
51354 + if (debug_pfkey) {
51355 + subnettoa(extr->eroute->er_eaddr.sen_ip_src,
51356 + extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
51357 + subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
51358 + extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
51359 + KLIPS_PRINT(debug_pfkey,
51360 + "klips_debug:pfkey_x_delflow_parse: "
51361 + "calling breakeroute for %s->%s\n",
51362 + buf1, buf2);
51363 + }
51364 +#endif /* CONFIG_KLIPS_DEBUG */
51365 + error = ipsec_breakroute(&(extr->eroute->er_eaddr),
51366 + &(extr->eroute->er_emask),
51367 + &first, &last);
51368 + if(error) {
51369 + KLIPS_PRINT(debug_pfkey,
51370 + "klips_debug:pfkey_x_delflow_parse: "
51371 + "breakeroute returned %d. first=0p%p, last=0p%p\n",
51372 + error,
51373 + first,
51374 + last);
51375 + }
51376 + if(first != NULL) {
51377 + ipsec_kfree_skb(first);
51378 + }
51379 + if(last != NULL) {
51380 + ipsec_kfree_skb(last);
51381 + }
51382 + if(error) {
51383 + SENDERR(-error);
51384 + }
51385 + }
51386 +
51387 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
51388 + K_SADB_X_DELFLOW,
51389 + satype,
51390 + 0,
51391 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_seq,
51392 + ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED])->sadb_msg_pid),
51393 + extensions_reply)
51394 + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[K_SADB_EXT_SA],
51395 + K_SADB_EXT_SA,
51396 + extr->ips->ips_said.spi,
51397 + extr->ips->ips_replaywin,
51398 + extr->ips->ips_state,
51399 + extr->ips->ips_authalg,
51400 + extr->ips->ips_encalg,
51401 + extr->ips->ips_flags),
51402 + extensions_reply)
51403 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_X_EXT_ADDRESS_SRC_FLOW],
51404 + K_SADB_X_EXT_ADDRESS_SRC_FLOW,
51405 + 0, /*extr->ips->ips_said.proto,*/
51406 + 0,
51407 + (struct sockaddr*)&srcflow),
51408 + extensions_reply)
51409 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_X_EXT_ADDRESS_DST_FLOW],
51410 + K_SADB_X_EXT_ADDRESS_DST_FLOW,
51411 + 0, /*extr->ips->ips_said.proto,*/
51412 + 0,
51413 + (struct sockaddr*)&dstflow),
51414 + extensions_reply)
51415 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_X_EXT_ADDRESS_SRC_MASK],
51416 + K_SADB_X_EXT_ADDRESS_SRC_MASK,
51417 + 0, /*extr->ips->ips_said.proto,*/
51418 + 0,
51419 + (struct sockaddr*)&srcmask),
51420 + extensions_reply)
51421 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[K_SADB_X_EXT_ADDRESS_DST_MASK],
51422 + K_SADB_X_EXT_ADDRESS_DST_MASK,
51423 + 0, /*extr->ips->ips_said.proto,*/
51424 + 0,
51425 + (struct sockaddr*)&dstmask),
51426 + extensions_reply)
51427 + )) {
51428 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
51429 + "failed to build the x_delflow reply message extensions\n");
51430 + SENDERR(-error);
51431 + }
51432 +
51433 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
51434 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
51435 + "failed to build the x_delflow reply message\n");
51436 + SENDERR(-error);
51437 + }
51438 +
51439 + for(pfkey_socketsp = pfkey_open_sockets;
51440 + pfkey_socketsp;
51441 + pfkey_socketsp = pfkey_socketsp->next) {
51442 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
51443 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
51444 + "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
51445 + satype,
51446 + satype2name(satype),
51447 + pfkey_socketsp->socketp,
51448 + error);
51449 + SENDERR(-error);
51450 + }
51451 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
51452 + "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
51453 + satype,
51454 + satype2name(satype),
51455 + pfkey_socketsp->socketp);
51456 + }
51457 +
51458 + KLIPS_PRINT(debug_pfkey,
51459 + "klips_debug:pfkey_x_delflow_parse: "
51460 + "extr->ips cleaned up and freed.\n");
51461 +
51462 + errlab:
51463 + if (pfkey_reply) {
51464 + pfkey_msg_free(&pfkey_reply);
51465 + }
51466 + pfkey_extensions_free(extensions_reply);
51467 + return error;
51468 +}
51469 +
51470 +DEBUG_NO_STATIC int
51471 +pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
51472 +{
51473 + int error = 0;
51474 +
51475 + KLIPS_PRINT(debug_pfkey,
51476 + "klips_debug:pfkey_x_msg_debug_parse: .\n");
51477 +
51478 +/* errlab:*/
51479 + return error;
51480 +}
51481 +
51482 +/* pfkey_expire expects the ipsec_sa table to be locked before being called. */
51483 +int
51484 +pfkey_expire(struct ipsec_sa *ipsp, int hard)
51485 +{
51486 + struct sadb_ext *extensions[K_SADB_EXT_MAX+1];
51487 + struct sadb_msg *pfkey_msg = NULL;
51488 + struct socket_list *pfkey_socketsp;
51489 + int error = 0;
51490 + uint8_t satype;
51491 +
51492 + pfkey_extensions_init(extensions);
51493 +
51494 + if(!(satype = proto2satype(ipsp->ips_said.proto))) {
51495 + KLIPS_PRINT(debug_pfkey,
51496 + "klips_debug:pfkey_expire: "
51497 + "satype lookup for protocol %d lookup failed.\n",
51498 + ipsp->ips_said.proto);
51499 + SENDERR(EINVAL);
51500 + }
51501 +
51502 + if(!pfkey_open_sockets) {
51503 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
51504 + "no sockets listening.\n");
51505 + SENDERR(EPROTONOSUPPORT);
51506 + }
51507 +
51508 + if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
51509 + K_SADB_EXPIRE,
51510 + satype,
51511 + 0,
51512 + ++pfkey_msg_seq,
51513 + 0),
51514 + extensions)
51515 + && pfkey_safe_build(error = pfkey_sa_build(&extensions[K_SADB_EXT_SA],
51516 + K_SADB_EXT_SA,
51517 + ipsp->ips_said.spi,
51518 + ipsp->ips_replaywin,
51519 + ipsp->ips_state,
51520 + ipsp->ips_authalg,
51521 + ipsp->ips_encalg,
51522 + ipsp->ips_flags),
51523 + extensions)
51524 + && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[K_SADB_EXT_LIFETIME_CURRENT],
51525 + K_SADB_EXT_LIFETIME_CURRENT,
51526 + ipsp->ips_life.ipl_allocations.ipl_count,
51527 + ipsp->ips_life.ipl_bytes.ipl_count,
51528 + ipsp->ips_life.ipl_addtime.ipl_count,
51529 + ipsp->ips_life.ipl_usetime.ipl_count,
51530 + ipsp->ips_life.ipl_packets.ipl_count),
51531 + extensions)
51532 + && (hard ?
51533 + pfkey_safe_build(error = pfkey_lifetime_build(&extensions[K_SADB_EXT_LIFETIME_HARD],
51534 + K_SADB_EXT_LIFETIME_HARD,
51535 + ipsp->ips_life.ipl_allocations.ipl_hard,
51536 + ipsp->ips_life.ipl_bytes.ipl_hard,
51537 + ipsp->ips_life.ipl_addtime.ipl_hard,
51538 + ipsp->ips_life.ipl_usetime.ipl_hard,
51539 + ipsp->ips_life.ipl_packets.ipl_hard),
51540 + extensions)
51541 + : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[K_SADB_EXT_LIFETIME_SOFT],
51542 + K_SADB_EXT_LIFETIME_SOFT,
51543 + ipsp->ips_life.ipl_allocations.ipl_soft,
51544 + ipsp->ips_life.ipl_bytes.ipl_soft,
51545 + ipsp->ips_life.ipl_addtime.ipl_soft,
51546 + ipsp->ips_life.ipl_usetime.ipl_soft,
51547 + ipsp->ips_life.ipl_packets.ipl_soft),
51548 + extensions))
51549 + && pfkey_safe_build(error = pfkey_address_build(&extensions[K_SADB_EXT_ADDRESS_SRC],
51550 + K_SADB_EXT_ADDRESS_SRC,
51551 + 0, /* ipsp->ips_said.proto, */
51552 + 0,
51553 + ipsp->ips_addr_s),
51554 + extensions)
51555 + && pfkey_safe_build(error = pfkey_address_build(&extensions[K_SADB_EXT_ADDRESS_DST],
51556 + K_SADB_EXT_ADDRESS_DST,
51557 + 0, /* ipsp->ips_said.proto, */
51558 + 0,
51559 + ipsp->ips_addr_d),
51560 + extensions))) {
51561 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
51562 + "failed to build the expire message extensions\n");
51563 + spin_unlock_bh(&tdb_lock);
51564 + goto errlab;
51565 + }
51566 +
51567 + if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
51568 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
51569 + "failed to build the expire message\n");
51570 + SENDERR(-error);
51571 + }
51572 +
51573 + for(pfkey_socketsp = pfkey_open_sockets;
51574 + pfkey_socketsp;
51575 + pfkey_socketsp = pfkey_socketsp->next) {
51576 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
51577 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
51578 + "sending up expire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
51579 + satype,
51580 + satype2name(satype),
51581 + pfkey_socketsp->socketp,
51582 + error);
51583 + SENDERR(-error);
51584 + }
51585 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
51586 + "sending up expire message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
51587 + satype,
51588 + satype2name(satype),
51589 + ipsp->ips_said.proto,
51590 + pfkey_socketsp->socketp);
51591 + }
51592 +
51593 + errlab:
51594 + if (pfkey_msg) {
51595 + pfkey_msg_free(&pfkey_msg);
51596 + }
51597 + pfkey_extensions_free(extensions);
51598 + return error;
51599 +}
51600 +
51601 +int
51602 +pfkey_acquire(struct ipsec_sa *ipsp)
51603 +{
51604 + struct sadb_ext *extensions[K_SADB_EXT_MAX+1];
51605 + struct sadb_msg *pfkey_msg = NULL;
51606 + struct socket_list *pfkey_socketsp;
51607 + int error = 0;
51608 + struct sadb_comb comb[] = {
51609 + /* auth; encrypt; flags; */
51610 + /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */
51611 + /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */
51612 + /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */
51613 + /* soft_packets; hard_packets; */
51614 + { K_SADB_AALG_MD5HMAC, K_SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
51615 + 128, 128, 168, 168,
51616 + 0, 0, 0, 0, 0,
51617 + 57600, 86400, 57600, 86400},
51618 + { K_SADB_AALG_SHA1HMAC, K_SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
51619 + 160, 160, 168, 168,
51620 + 0, 0, 0, 0, 0,
51621 + 57600, 86400, 57600, 86400},
51622 + };
51623 +
51624 + /* XXX This should not be hard-coded. It should be taken from the spdb */
51625 + uint8_t satype = K_SADB_SATYPE_ESP;
51626 +
51627 + pfkey_extensions_init(extensions);
51628 +
51629 + if((satype == 0) || (satype > K_SADB_SATYPE_MAX)) {
51630 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
51631 + "SAtype=%d unspecified or unknown.\n",
51632 + satype);
51633 + SENDERR(EINVAL);
51634 + }
51635 +
51636 + if(!(pfkey_registered_sockets[satype])) {
51637 + KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
51638 + "no sockets registered for SAtype=%d(%s).\n",
51639 + satype,
51640 + satype2name(satype));
51641 + SENDERR(EPROTONOSUPPORT);
51642 + }
51643 +
51644 + if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
51645 + K_SADB_ACQUIRE,
51646 + satype,
51647 + 0,
51648 + ++pfkey_msg_seq,
51649 + 0),
51650 + extensions)
51651 + && pfkey_safe_build(error = pfkey_address_build(&extensions[K_SADB_EXT_ADDRESS_SRC],
51652 + K_SADB_EXT_ADDRESS_SRC,
51653 + ipsp->ips_transport_protocol,
51654 + 0,
51655 + ipsp->ips_addr_s),
51656 + extensions)
51657 + && pfkey_safe_build(error = pfkey_address_build(&extensions[K_SADB_EXT_ADDRESS_DST],
51658 + K_SADB_EXT_ADDRESS_DST,
51659 + ipsp->ips_transport_protocol,
51660 + 0,
51661 + ipsp->ips_addr_d),
51662 + extensions)
51663 +#if 0
51664 + && (ipsp->ips_addr_p
51665 + ? pfkey_safe_build(error = pfkey_address_build(&extensions[K_SADB_EXT_ADDRESS_PROXY],
51666 + K_SADB_EXT_ADDRESS_PROXY,
51667 + ipsp->ips_transport_protocol,
51668 + 0,
51669 + ipsp->ips_addr_p),
51670 + extensions) : 1)
51671 +#endif
51672 + && (ipsp->ips_ident_s.type != SADB_IDENTTYPE_RESERVED
51673 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC],
51674 + K_SADB_EXT_IDENTITY_SRC,
51675 + ipsp->ips_ident_s.type,
51676 + ipsp->ips_ident_s.id,
51677 + ipsp->ips_ident_s.len,
51678 + ipsp->ips_ident_s.data),
51679 + extensions) : 1)
51680 +
51681 + && (ipsp->ips_ident_d.type != SADB_IDENTTYPE_RESERVED
51682 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions[K_SADB_EXT_IDENTITY_DST],
51683 + K_SADB_EXT_IDENTITY_DST,
51684 + ipsp->ips_ident_d.type,
51685 + ipsp->ips_ident_d.id,
51686 + ipsp->ips_ident_d.len,
51687 + ipsp->ips_ident_d.data),
51688 + extensions) : 1)
51689 +#if 0
51690 + /* FIXME: This won't work yet because I have not finished
51691 + it. */
51692 + && (ipsp->ips_sens_
51693 + ? pfkey_safe_build(error = pfkey_sens_build(&extensions[K_SADB_EXT_SENSITIVITY],
51694 + ipsp->ips_sens_dpd,
51695 + ipsp->ips_sens_sens_level,
51696 + ipsp->ips_sens_sens_len,
51697 + ipsp->ips_sens_sens_bitmap,
51698 + ipsp->ips_sens_integ_level,
51699 + ipsp->ips_sens_integ_len,
51700 + ipsp->ips_sens_integ_bitmap),
51701 + extensions) : 1)
51702 +#endif
51703 + && pfkey_safe_build(error = pfkey_prop_build(&extensions[K_SADB_EXT_PROPOSAL],
51704 + 64, /* replay */
51705 + sizeof(comb)/sizeof(struct sadb_comb),
51706 + &(comb[0])),
51707 + extensions)
51708 + )) {
51709 + KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
51710 + "failed to build the acquire message extensions\n");
51711 + SENDERR(-error);
51712 + }
51713 +
51714 + if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
51715 + KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
51716 + "failed to build the acquire message\n");
51717 + SENDERR(-error);
51718 + }
51719 +
51720 +#ifdef KLIPS_PFKEY_ACQUIRE_LOSSAGE
51721 +# if KLIPS_PFKEY_ACQUIRE_LOSSAGE > 0
51722 + if(sysctl_ipsec_regress_pfkey_lossage) {
51723 + return(0);
51724 + }
51725 +# endif
51726 +#endif
51727 +
51728 + /* this should go to all registered sockets for that satype only */
51729 + for(pfkey_socketsp = pfkey_registered_sockets[satype];
51730 + pfkey_socketsp;
51731 + pfkey_socketsp = pfkey_socketsp->next) {
51732 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
51733 + KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
51734 + "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
51735 + satype,
51736 + satype2name(satype),
51737 + pfkey_socketsp->socketp,
51738 + error);
51739 + SENDERR(-error);
51740 + }
51741 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
51742 + "sending up acquire message for satype=%d(%s) to socket=0p%p succeeded.\n",
51743 + satype,
51744 + satype2name(satype),
51745 + pfkey_socketsp->socketp);
51746 + }
51747 +
51748 + errlab:
51749 + if (pfkey_msg) {
51750 + pfkey_msg_free(&pfkey_msg);
51751 + }
51752 + pfkey_extensions_free(extensions);
51753 + return error;
51754 +}
51755 +
51756 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
51757 +int
51758 +pfkey_nat_t_new_mapping(struct ipsec_sa *ipsp, struct sockaddr *ipaddr,
51759 + __u16 sport)
51760 +{
51761 + struct sadb_ext *extensions[K_SADB_EXT_MAX+1];
51762 + struct sadb_msg *pfkey_msg = NULL;
51763 + struct socket_list *pfkey_socketsp;
51764 + int error = 0;
51765 + uint8_t satype = (ipsp->ips_said.proto==IPPROTO_ESP) ? K_SADB_SATYPE_ESP : 0;
51766 +
51767 + /* Construct K_SADB_X_NAT_T_NEW_MAPPING message */
51768 +
51769 + pfkey_extensions_init(extensions);
51770 +
51771 + if((satype == 0) || (satype > K_SADB_SATYPE_MAX)) {
51772 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
51773 + "SAtype=%d unspecified or unknown.\n",
51774 + satype);
51775 + SENDERR(EINVAL);
51776 + }
51777 +
51778 + if(!(pfkey_registered_sockets[satype])) {
51779 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
51780 + "no sockets registered for SAtype=%d(%s).\n",
51781 + satype,
51782 + satype2name(satype));
51783 + SENDERR(EPROTONOSUPPORT);
51784 + }
51785 +
51786 + if (!(pfkey_safe_build
51787 + (error = pfkey_msg_hdr_build(&extensions[0], K_SADB_X_NAT_T_NEW_MAPPING,
51788 + satype, 0, ++pfkey_msg_seq, 0), extensions)
51789 + /* SA */
51790 + && pfkey_safe_build
51791 + (error = pfkey_sa_build(&extensions[K_SADB_EXT_SA],
51792 + K_SADB_EXT_SA, ipsp->ips_said.spi, 0, 0, 0, 0, 0), extensions)
51793 + /* ADDRESS_SRC = old addr */
51794 + && pfkey_safe_build
51795 + (error = pfkey_address_build(&extensions[K_SADB_EXT_ADDRESS_SRC],
51796 + K_SADB_EXT_ADDRESS_SRC, ipsp->ips_said.proto, 0, ipsp->ips_addr_s),
51797 + extensions)
51798 + /* NAT_T_SPORT = old port */
51799 + && pfkey_safe_build
51800 + (error = pfkey_x_nat_t_port_build(&extensions[K_SADB_X_EXT_NAT_T_SPORT],
51801 + K_SADB_X_EXT_NAT_T_SPORT, ipsp->ips_natt_sport), extensions)
51802 + /* ADDRESS_DST = new addr */
51803 + && pfkey_safe_build
51804 + (error = pfkey_address_build(&extensions[K_SADB_EXT_ADDRESS_DST],
51805 + K_SADB_EXT_ADDRESS_DST, ipsp->ips_said.proto, 0, ipaddr), extensions)
51806 + /* NAT_T_DPORT = new port */
51807 + && pfkey_safe_build
51808 + (error = pfkey_x_nat_t_port_build(&extensions[K_SADB_X_EXT_NAT_T_DPORT],
51809 + K_SADB_X_EXT_NAT_T_DPORT, sport), extensions)
51810 + )) {
51811 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
51812 + "failed to build the nat_t_new_mapping message extensions\n");
51813 + SENDERR(-error);
51814 + }
51815 +
51816 + if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
51817 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
51818 + "failed to build the nat_t_new_mapping message\n");
51819 + SENDERR(-error);
51820 + }
51821 +
51822 + /* this should go to all registered sockets for that satype only */
51823 + for(pfkey_socketsp = pfkey_registered_sockets[satype];
51824 + pfkey_socketsp;
51825 + pfkey_socketsp = pfkey_socketsp->next) {
51826 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
51827 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
51828 + "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p failed with error=%d.\n",
51829 + satype,
51830 + satype2name(satype),
51831 + pfkey_socketsp->socketp,
51832 + error);
51833 + SENDERR(-error);
51834 + }
51835 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
51836 + "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p succeeded.\n",
51837 + satype,
51838 + satype2name(satype),
51839 + pfkey_socketsp->socketp);
51840 + }
51841 +
51842 + errlab:
51843 + if (pfkey_msg) {
51844 + pfkey_msg_free(&pfkey_msg);
51845 + }
51846 + pfkey_extensions_free(extensions);
51847 + return error;
51848 +}
51849 +
51850 +DEBUG_NO_STATIC int
51851 +pfkey_x_nat_t_new_mapping_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
51852 +{
51853 + /* K_SADB_X_NAT_T_NEW_MAPPING not used in kernel */
51854 + return -EINVAL;
51855 +}
51856 +#endif
51857 +
51858 +/*******************************
51859 + * EXTENSION PARSERS FOR KLIPS
51860 + ********************************/
51861 +
51862 +DEBUG_NO_STATIC int
51863 +pfkey_x_outif_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
51864 +{
51865 + struct sadb_x_plumbif *oif;
51866 +
51867 + oif = (struct sadb_x_plumbif *)pfkey_ext;
51868 +
51869 + extr->outif = oif->sadb_x_outif_ifnum;
51870 +
51871 + return 0;
51872 +}
51873 +
51874 +DEBUG_NO_STATIC int
51875 +pfkey_x_saref_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
51876 +{
51877 + struct sadb_x_saref *saf;
51878 +
51879 + saf = (struct sadb_x_saref *)pfkey_ext;
51880 +
51881 + extr->sarefme = saf->sadb_x_saref_me;
51882 + extr->sarefhim = saf->sadb_x_saref_him;
51883 +
51884 + return 0;
51885 +}
51886 +
51887 +DEBUG_NO_STATIC int (*ext_processors[K_SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) =
51888 +{
51889 + NULL, /* pfkey_msg_process, */
51890 + pfkey_sa_process,
51891 + pfkey_lifetime_process,
51892 + pfkey_lifetime_process,
51893 + pfkey_lifetime_process,
51894 + pfkey_address_process,
51895 + pfkey_address_process,
51896 + pfkey_address_process,
51897 + pfkey_key_process,
51898 + pfkey_key_process,
51899 + pfkey_ident_process,
51900 + pfkey_ident_process,
51901 + pfkey_sens_process,
51902 + pfkey_prop_process,
51903 + pfkey_supported_process,
51904 + pfkey_supported_process,
51905 + pfkey_spirange_process,
51906 + pfkey_x_kmprivate_process,
51907 + pfkey_x_satype_process,
51908 + pfkey_sa_process,
51909 + pfkey_address_process,
51910 + pfkey_address_process,
51911 + pfkey_address_process,
51912 + pfkey_address_process,
51913 + pfkey_address_process,
51914 + pfkey_x_debug_process,
51915 + pfkey_x_protocol_process,
51916 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
51917 + pfkey_x_nat_t_type_process,
51918 + pfkey_x_nat_t_port_process,
51919 + pfkey_x_nat_t_port_process,
51920 + pfkey_address_process,
51921 +#else
51922 + NULL, NULL, NULL, NULL,
51923 +#endif
51924 + pfkey_x_outif_process,
51925 + pfkey_x_saref_process,
51926 +};
51927 +
51928 +
51929 +/*******************************
51930 + * MESSAGE PARSERS FOR KLIPS
51931 + ********************************/
51932 +
51933 +DEBUG_NO_STATIC int
51934 +pfkey_x_simple_reply(struct sock *sk , struct sadb_ext *extensions[], int err)
51935 +{
51936 + struct sadb_msg *pfkey_reply = NULL;
51937 + int error = 0;
51938 + struct sadb_msg *m = ((struct sadb_msg*)extensions[K_SADB_EXT_RESERVED]);
51939 +
51940 + m->sadb_msg_errno = err;
51941 +
51942 + if ((error = pfkey_msg_build(&pfkey_reply, extensions, EXT_BITS_OUT))) {
51943 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
51944 + "failed to build the expire message\n");
51945 + SENDERR(-error);
51946 + }
51947 +
51948 + error = pfkey_upmsgsk(sk, pfkey_reply);
51949 +
51950 + if(error) {
51951 + KLIPS_ERROR(debug_pfkey, "pfkey_simple reply:"
51952 + "sending up simple reply to pid=%d error=%d.\n",
51953 + m->sadb_msg_pid, err);
51954 + }
51955 +
51956 +errlab:
51957 + if (pfkey_reply) {
51958 + pfkey_msg_free(&pfkey_reply);
51959 + }
51960 +
51961 + return error;
51962 +}
51963 +
51964 +/*
51965 + * this is a request to create a new device. Figure out which kind, and call appropriate
51966 + * routine in mast or tunnel code.
51967 + */
51968 +DEBUG_NO_STATIC int
51969 +pfkey_x_plumb_parse(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr)
51970 +{
51971 + unsigned int vifnum;
51972 + int err;
51973 +
51974 + vifnum = extr->outif;
51975 + if(vifnum > IPSECDEV_OFFSET) {
51976 + err = ipsec_tunnel_createnum(vifnum-IPSECDEV_OFFSET);
51977 + } else {
51978 + err = ipsec_mast_createnum(vifnum);
51979 + }
51980 +
51981 + return pfkey_x_simple_reply(sk, extensions, err);
51982 +}
51983 +
51984 +DEBUG_NO_STATIC int
51985 +pfkey_x_unplumb_parse(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr)
51986 +{
51987 + unsigned int vifnum;
51988 + int err;
51989 +
51990 + vifnum = extr->outif;
51991 + if(vifnum > IPSECDEV_OFFSET) {
51992 + err = ipsec_tunnel_deletenum(vifnum-IPSECDEV_OFFSET);
51993 + } else {
51994 + err = ipsec_mast_deletenum(vifnum);
51995 + }
51996 +
51997 + return pfkey_x_simple_reply(sk, extensions, err);
51998 +}
51999 +
52000 +
52001 +DEBUG_NO_STATIC int (*msg_parsers[K_SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr)
52002 + =
52003 +{
52004 + NULL, /* RESERVED */
52005 + pfkey_getspi_parse,
52006 + pfkey_update_parse,
52007 + pfkey_add_parse,
52008 + pfkey_delete_parse,
52009 + pfkey_get_parse,
52010 + pfkey_acquire_parse,
52011 + pfkey_register_parse,
52012 + pfkey_expire_parse,
52013 + pfkey_flush_parse,
52014 + pfkey_dump_parse,
52015 + pfkey_x_promisc_parse,
52016 + pfkey_x_pchange_parse,
52017 + pfkey_x_grpsa_parse,
52018 + pfkey_x_addflow_parse,
52019 + pfkey_x_delflow_parse,
52020 + pfkey_x_msg_debug_parse,
52021 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
52022 + pfkey_x_nat_t_new_mapping_parse,
52023 +#else
52024 + NULL,
52025 +#endif
52026 + pfkey_x_plumb_parse,
52027 + pfkey_x_unplumb_parse,
52028 +};
52029 +
52030 +int
52031 +pfkey_build_reply(struct sadb_msg *pfkey_msg,
52032 + struct pfkey_extracted_data *extr,
52033 + struct sadb_msg **pfkey_reply)
52034 +{
52035 + struct sadb_ext *extensions[K_SADB_EXT_MAX+1];
52036 + int error = 0;
52037 + int msg_type = pfkey_msg->sadb_msg_type;
52038 + int seq = pfkey_msg->sadb_msg_seq;
52039 +
52040 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
52041 + "building reply with type: %d\n",
52042 + msg_type);
52043 + pfkey_extensions_init(extensions);
52044 + if (!extr || !extr->ips) {
52045 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
52046 + "bad ipsec_sa passed\n");
52047 + return EINVAL; // TODO: should this not be negative?
52048 + }
52049 + error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0],
52050 + msg_type,
52051 + proto2satype(extr->ips->ips_said.proto),
52052 + 0,
52053 + seq,
52054 + pfkey_msg->sadb_msg_pid),
52055 + extensions);
52056 +
52057 + if(!error
52058 + && pfkey_required_extension(EXT_BITS_OUT, msg_type, K_SADB_EXT_SA)) {
52059 +
52060 + error = pfkey_sa_build(&extensions[K_SADB_EXT_SA],
52061 + K_SADB_EXT_SA,
52062 + extr->ips->ips_said.spi,
52063 + extr->ips->ips_replaywin,
52064 + extr->ips->ips_state,
52065 + extr->ips->ips_authalg,
52066 + extr->ips->ips_encalg,
52067 + extr->ips->ips_flags);
52068 + pfkey_safe_build(error, extensions);
52069 + }
52070 +
52071 + if(!error
52072 + && pfkey_required_extension(EXT_BITS_OUT, msg_type, K_SADB_X_EXT_SAREF)) {
52073 + error = pfkey_saref_build(&extensions[K_SADB_X_EXT_SAREF],
52074 + extr->ips->ips_ref,
52075 + extr->ips->ips_refhim);
52076 + pfkey_safe_build(error, extensions);
52077 + }
52078 +
52079 + if(!error
52080 + && pfkey_required_extension(EXT_BITS_OUT,msg_type,K_SADB_EXT_LIFETIME_CURRENT)) {
52081 + error = pfkey_lifetime_build(&extensions
52082 + [K_SADB_EXT_LIFETIME_CURRENT],
52083 + K_SADB_EXT_LIFETIME_CURRENT,
52084 + extr->ips->ips_life.ipl_allocations.ipl_count,
52085 + extr->ips->ips_life.ipl_bytes.ipl_count,
52086 + extr->ips->ips_life.ipl_addtime.ipl_count,
52087 + extr->ips->ips_life.ipl_usetime.ipl_count,
52088 + extr->ips->ips_life.ipl_packets.ipl_count);
52089 + pfkey_safe_build(error, extensions);
52090 + }
52091 +
52092 + if(!error
52093 + && pfkey_required_extension(EXT_BITS_OUT,msg_type,K_SADB_EXT_ADDRESS_SRC)) {
52094 + error = pfkey_address_build(&extensions[K_SADB_EXT_ADDRESS_SRC],
52095 + K_SADB_EXT_ADDRESS_SRC,
52096 + extr->ips->ips_said.proto,
52097 + 0,
52098 + extr->ips->ips_addr_s);
52099 + pfkey_safe_build(error, extensions);
52100 + }
52101 +
52102 + if(!error
52103 + && pfkey_required_extension(EXT_BITS_OUT,msg_type,K_SADB_EXT_ADDRESS_DST)) {
52104 + error = pfkey_address_build(&extensions[K_SADB_EXT_ADDRESS_DST],
52105 + K_SADB_EXT_ADDRESS_DST,
52106 + extr->ips->ips_said.proto,
52107 + 0,
52108 + extr->ips->ips_addr_d);
52109 + pfkey_safe_build(error, extensions);
52110 + }
52111 +
52112 + if (error == 0) {
52113 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
52114 + "building extensions failed\n");
52115 + return EINVAL;
52116 + }
52117 +
52118 + KLIPS_PRINT(debug_pfkey,
52119 + "klips_debug:pfkey_build_reply: "
52120 + "built extensions, proceed to build the message\n");
52121 + KLIPS_PRINT(debug_pfkey,
52122 + "klips_debug:pfkey_build_reply: "
52123 + "extensions[1]=0p%p\n",
52124 + extensions[1]);
52125 + error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT);
52126 + pfkey_extensions_free(extensions);
52127 +
52128 + return error;
52129 +}
52130 +
52131 +/*
52132 + * interpret a pfkey message for klips usage.
52133 + * it used to be that we provided a reply in a seperate buffer,
52134 + * but now we overwrite the request buffer and return it.
52135 + */
52136 +int
52137 +pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg)
52138 +{
52139 + int error = 0;
52140 + int i;
52141 + struct sadb_ext *extensions[K_SADB_EXT_MAX+1]; /* should be kalloc */
52142 + struct pfkey_extracted_data extr;
52143 +
52144 + memset(&extr, 0, sizeof(extr));
52145 +
52146 + pfkey_extensions_init(extensions);
52147 + KLIPS_PRINT(debug_pfkey,
52148 + "klips_debug:pfkey_msg_interp: "
52149 + "parsing message ver=%d, type=%d, errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
52150 + pfkey_msg->sadb_msg_version,
52151 + pfkey_msg->sadb_msg_type,
52152 + pfkey_msg->sadb_msg_errno,
52153 + pfkey_msg->sadb_msg_satype,
52154 + satype2name(pfkey_msg->sadb_msg_satype),
52155 + pfkey_msg->sadb_msg_len,
52156 + pfkey_msg->sadb_msg_reserved,
52157 + pfkey_msg->sadb_msg_seq,
52158 + pfkey_msg->sadb_msg_pid);
52159 +
52160 + extr.ips = ipsec_sa_alloc(&error); /* pass in error var by pointer */
52161 + if(extr.ips == NULL) {
52162 + KLIPS_PRINT(debug_pfkey,
52163 + "klips_debug:pfkey_msg_interp: "
52164 + "memory allocation error.\n");
52165 + SENDERR(-error);
52166 + }
52167 +
52168 + KLIPS_PRINT(debug_pfkey,
52169 + "klips_debug:pfkey_msg_interp: "
52170 + "allocated extr->ips=0p%p.\n",
52171 + extr.ips);
52172 +
52173 + if(pfkey_msg->sadb_msg_satype > K_SADB_SATYPE_MAX) {
52174 + KLIPS_PRINT(debug_pfkey,
52175 + "klips_debug:pfkey_msg_interp: "
52176 + "satype %d > max %d\n",
52177 + pfkey_msg->sadb_msg_satype,
52178 + K_SADB_SATYPE_MAX);
52179 + SENDERR(EINVAL);
52180 + }
52181 +
52182 + switch(pfkey_msg->sadb_msg_type) {
52183 + case K_SADB_GETSPI:
52184 + case K_SADB_UPDATE:
52185 + case K_SADB_ADD:
52186 + case K_SADB_DELETE:
52187 + case K_SADB_X_GRPSA:
52188 + case K_SADB_X_ADDFLOW:
52189 + if(!(extr.ips->ips_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) {
52190 + KLIPS_PRINT(debug_pfkey,
52191 + "klips_debug:pfkey_msg_interp: "
52192 + "satype %d lookup failed.\n",
52193 + pfkey_msg->sadb_msg_satype);
52194 + SENDERR(EINVAL);
52195 + } else {
52196 + KLIPS_PRINT(debug_pfkey,
52197 + "klips_debug:pfkey_msg_interp: "
52198 + "satype %d lookups to proto=%d.\n",
52199 + pfkey_msg->sadb_msg_satype,
52200 + extr.ips->ips_said.proto);
52201 + }
52202 + break;
52203 + default:
52204 + break;
52205 + }
52206 +
52207 + /* The NULL below causes the default extension parsers to be used */
52208 + /* Parse the extensions */
52209 + if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN)))
52210 + {
52211 + KLIPS_PRINT(debug_pfkey,
52212 + "klips_debug:pfkey_msg_interp: "
52213 + "message parsing failed with error %d.\n",
52214 + error);
52215 + SENDERR(-error);
52216 + }
52217 +
52218 + /* Process the extensions */
52219 + for(i=1; i <= K_SADB_EXT_MAX;i++) {
52220 + if(extensions[i] != NULL && ext_processors[i]!=NULL) {
52221 + KLIPS_PRINT(debug_pfkey,
52222 + "klips_debug:pfkey_msg_interp: "
52223 + "processing ext %d 0p%p with processor 0p%p.\n",
52224 + i, extensions[i], ext_processors[i]);
52225 + if((error = ext_processors[i](extensions[i], &extr))) {
52226 + KLIPS_PRINT(debug_pfkey,
52227 + "klips_debug:pfkey_msg_interp: "
52228 + "extension processing for type %d failed with error %d.\n",
52229 + i,
52230 + error);
52231 + SENDERR(-error);
52232 + }
52233 +
52234 + }
52235 +
52236 + }
52237 +
52238 + /* Parse the message types */
52239 + KLIPS_PRINT(debug_pfkey,
52240 + "klips_debug:pfkey_msg_interp: "
52241 + "parsing message type %d(%s) with msg_parser 0p%p.\n",
52242 + pfkey_msg->sadb_msg_type,
52243 + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
52244 + msg_parsers[pfkey_msg->sadb_msg_type]);
52245 + if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) {
52246 + KLIPS_PRINT(debug_pfkey,
52247 + "klips_debug:pfkey_msg_interp: "
52248 + "message parsing failed with error %d.\n",
52249 + error);
52250 + SENDERR(-error);
52251 + }
52252 +
52253 + errlab:
52254 + if(extr.ips != NULL) {
52255 + ipsec_sa_put(extr.ips);
52256 + }
52257 + if(extr.ips2 != NULL) {
52258 + ipsec_sa_put(extr.ips2);
52259 + }
52260 + if (extr.eroute != NULL) {
52261 + kfree(extr.eroute);
52262 + }
52263 + return(error);
52264 +}
52265 +
52266 +/*
52267 + *
52268 + * Local Variables:
52269 + * c-file-style: "linux"
52270 + * End:
52271 + *
52272 + */
52273 --- /dev/null Tue Mar 11 13:02:56 2003
52274 +++ linux/net/ipsec/prng.c Mon Feb 9 13:51:03 2004
52275 @@ -0,0 +1,202 @@
52276 +/*
52277 + * crypto-class pseudorandom number generator
52278 + * currently uses same algorithm as RC4(TM), from Schneier 2nd ed p397
52279 + * Copyright (C) 2002 Henry Spencer.
52280 + *
52281 + * This library is free software; you can redistribute it and/or modify it
52282 + * under the terms of the GNU Library General Public License as published by
52283 + * the Free Software Foundation; either version 2 of the License, or (at your
52284 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
52285 + *
52286 + * This library is distributed in the hope that it will be useful, but
52287 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
52288 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
52289 + * License for more details.
52290 + *
52291 + * RCSID $Id: prng.c,v 1.8 2005/08/25 01:20:21 paul Exp $
52292 + */
52293 +#include "openswan.h"
52294 +
52295 +/*
52296 + - prng_init - initialize PRNG from a key
52297 + */
52298 +void
52299 +prng_init(prng, key, keylen)
52300 +struct prng *prng;
52301 +const unsigned char *key;
52302 +size_t keylen;
52303 +{
52304 + unsigned char k[256];
52305 + int i, j;
52306 + unsigned const char *p;
52307 + unsigned const char *keyend = key + keylen;
52308 + unsigned char t;
52309 +
52310 + for (i = 0; i <= 255; i++)
52311 + prng->sbox[i] = i;
52312 + p = key;
52313 + for (i = 0; i <= 255; i++) {
52314 + k[i] = *p++;
52315 + if (p >= keyend)
52316 + p = key;
52317 + }
52318 + j = 0;
52319 + for (i = 0; i <= 255; i++) {
52320 + j = (j + prng->sbox[i] + k[i]) & 0xff;
52321 + t = prng->sbox[i];
52322 + prng->sbox[i] = prng->sbox[j];
52323 + prng->sbox[j] = t;
52324 + k[i] = 0; /* clear out key memory */
52325 + }
52326 + prng->i = 0;
52327 + prng->j = 0;
52328 + prng->count = 0;
52329 +}
52330 +
52331 +/*
52332 + - prng_bytes - get some pseudorandom bytes from PRNG
52333 + */
52334 +void
52335 +prng_bytes(prng, dst, dstlen)
52336 +struct prng *prng;
52337 +unsigned char *dst;
52338 +size_t dstlen;
52339 +{
52340 + int i, j, t;
52341 + unsigned char *p = dst;
52342 + size_t remain = dstlen;
52343 +# define MAXCOUNT 4000000000ul
52344 +
52345 + while (remain > 0) {
52346 + i = (prng->i + 1) & 0xff;
52347 + prng->i = i;
52348 + j = (prng->j + prng->sbox[i]) & 0xff;
52349 + prng->j = j;
52350 + t = prng->sbox[i];
52351 + prng->sbox[i] = prng->sbox[j];
52352 + prng->sbox[j] = t;
52353 + t = (t + prng->sbox[i]) & 0xff;
52354 + *p++ = prng->sbox[t];
52355 + remain--;
52356 + }
52357 + if (prng->count < MAXCOUNT - dstlen)
52358 + prng->count += dstlen;
52359 + else
52360 + prng->count = MAXCOUNT;
52361 +}
52362 +
52363 +/*
52364 + - prnt_count - how many bytes have been extracted from PRNG so far?
52365 + */
52366 +unsigned long
52367 +prng_count(prng)
52368 +struct prng *prng;
52369 +{
52370 + return prng->count;
52371 +}
52372 +
52373 +/*
52374 + - prng_final - clear out PRNG to ensure nothing left in memory
52375 + */
52376 +void
52377 +prng_final(prng)
52378 +struct prng *prng;
52379 +{
52380 + int i;
52381 +
52382 + for (i = 0; i <= 255; i++)
52383 + prng->sbox[i] = 0;
52384 + prng->i = 0;
52385 + prng->j = 0;
52386 + prng->count = 0; /* just for good measure */
52387 +}
52388 +
52389 +
52390 +
52391 +#ifdef PRNG_MAIN
52392 +
52393 +#include <stdio.h>
52394 +#include <stdlib.h>
52395 +
52396 +void regress();
52397 +
52398 +int
52399 +main(argc, argv)
52400 +int argc;
52401 +char *argv[];
52402 +{
52403 + struct prng pr;
52404 + unsigned char buf[100];
52405 + unsigned char *p;
52406 + size_t n;
52407 +
52408 + if (argc < 2) {
52409 + fprintf(stderr, "Usage: %s {key|-r}\n", argv[0]);
52410 + exit(2);
52411 + }
52412 +
52413 + if (strcmp(argv[1], "-r") == 0) {
52414 + regress();
52415 + fprintf(stderr, "regress() returned?!?\n");
52416 + exit(1);
52417 + }
52418 +
52419 + prng_init(&pr, argv[1], strlen(argv[1]));
52420 + prng_bytes(&pr, buf, 32);
52421 + printf("0x");
52422 + for (p = buf, n = 32; n > 0; p++, n--)
52423 + printf("%02x", *p);
52424 + printf("\n%lu bytes\n", prng_count(&pr));
52425 + prng_final(&pr);
52426 + exit(0);
52427 +}
52428 +
52429 +void
52430 +regress()
52431 +{
52432 + struct prng pr;
52433 + unsigned char buf[100];
52434 + unsigned char *p;
52435 + size_t n;
52436 + /* somewhat non-random sample key */
52437 + unsigned char key[] = "here we go gathering nuts in May";
52438 + /* first thirty bytes of output from that key */
52439 + unsigned char good[] = "\x3f\x02\x8e\x4a\x2a\xea\x23\x18\x92\x7c"
52440 + "\x09\x52\x83\x61\xaa\x26\xce\xbb\x9d\x71"
52441 + "\x71\xe5\x10\x22\xaf\x60\x54\x8d\x5b\x28";
52442 + int nzero, none;
52443 + int show = 0;
52444 +
52445 + prng_init(&pr, key, strlen(key));
52446 + prng_bytes(&pr, buf, sizeof(buf));
52447 + for (p = buf, n = sizeof(buf); n > 0; p++, n--) {
52448 + if (*p == 0)
52449 + nzero++;
52450 + if (*p == 255)
52451 + none++;
52452 + }
52453 + if (nzero > 3 || none > 3) {
52454 + fprintf(stderr, "suspiciously non-random output!\n");
52455 + show = 1;
52456 + }
52457 + if (memcmp(buf, good, strlen(good)) != 0) {
52458 + fprintf(stderr, "incorrect output!\n");
52459 + show = 1;
52460 + }
52461 + if (show) {
52462 + fprintf(stderr, "0x");
52463 + for (p = buf, n = sizeof(buf); n > 0; p++, n--)
52464 + fprintf(stderr, "%02x", *p);
52465 + fprintf(stderr, "\n");
52466 + exit(1);
52467 + }
52468 + if (prng_count(&pr) != sizeof(buf)) {
52469 + fprintf(stderr, "got %u bytes, but count is %lu\n",
52470 + sizeof(buf), prng_count(&pr));
52471 + exit(1);
52472 + }
52473 + prng_final(&pr);
52474 + exit(0);
52475 +}
52476 +
52477 +#endif /* PRNG_MAIN */
52478 --- /dev/null Tue Mar 11 13:02:56 2003
52479 +++ linux/net/ipsec/radij.c Mon Feb 9 13:51:03 2004
52480 @@ -0,0 +1,1013 @@
52481 +char radij_c_version[] = "RCSID $Id: radij.c,v 1.48 2005/04/29 05:10:22 mcr Exp $";
52482 +
52483 +/*
52484 + * This file is defived from ${SRC}/sys/net/radix.c of BSD 4.4lite
52485 + *
52486 + * Variable and procedure names have been modified so that they don't
52487 + * conflict with the original BSD code, as a small number of modifications
52488 + * have been introduced and we may want to reuse this code in BSD.
52489 + *
52490 + * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
52491 + * chi or a German ch sound (as `doch', not as in `milch'), or even a
52492 + * spanish j as in Juan. It is not as far back in the throat like
52493 + * the corresponding Hebrew sound, nor is it a soft breath like the English h.
52494 + * It has nothing to do with the Dutch ij sound.
52495 + *
52496 + * Here is the appropriate copyright notice:
52497 + */
52498 +
52499 +/*
52500 + * Copyright (c) 1988, 1989, 1993
52501 + * The Regents of the University of California. All rights reserved.
52502 + *
52503 + * Redistribution and use in source and binary forms, with or without
52504 + * modification, are permitted provided that the following conditions
52505 + * are met:
52506 + * 1. Redistributions of source code must retain the above copyright
52507 + * notice, this list of conditions and the following disclaimer.
52508 + * 2. Redistributions in binary form must reproduce the above copyright
52509 + * notice, this list of conditions and the following disclaimer in the
52510 + * documentation and/or other materials provided with the distribution.
52511 + * 3. All advertising materials mentioning features or use of this software
52512 + * must display the following acknowledgement:
52513 + * This product includes software developed by the University of
52514 + * California, Berkeley and its contributors.
52515 + * 4. Neither the name of the University nor the names of its contributors
52516 + * may be used to endorse or promote products derived from this software
52517 + * without specific prior written permission.
52518 + *
52519 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
52520 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52521 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52522 + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52523 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52524 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52525 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52526 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52527 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52528 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52529 + * SUCH DAMAGE.
52530 + *
52531 + * @(#)radix.c 8.2 (Berkeley) 1/4/94
52532 + */
52533 +
52534 +/*
52535 + * Routines to build and maintain radix trees for routing lookups.
52536 + */
52537 +
52538 +#ifndef AUTOCONF_INCLUDED
52539 +#include <linux/config.h>
52540 +#endif
52541 +#include <linux/version.h>
52542 +#include <linux/kernel.h> /* printk() */
52543 +
52544 +#include "openswan/ipsec_param.h"
52545 +
52546 +#ifdef MALLOC_SLAB
52547 +# include <linux/slab.h> /* kmalloc() */
52548 +#else /* MALLOC_SLAB */
52549 +# include <linux/malloc.h> /* kmalloc() */
52550 +#endif /* MALLOC_SLAB */
52551 +#include <linux/errno.h> /* error codes */
52552 +#include <linux/types.h> /* size_t */
52553 +#include <linux/interrupt.h> /* mark_bh */
52554 +
52555 +#include <linux/netdevice.h> /* struct device, and other headers */
52556 +#include <linux/etherdevice.h> /* eth_type_trans */
52557 +#include <linux/ip.h> /* struct iphdr */
52558 +#include <linux/skbuff.h>
52559 +#ifdef NET_21
52560 +# include <linux/in6.h>
52561 +#endif /* NET_21 */
52562 +
52563 +#include <net/ip.h>
52564 +
52565 +#include <openswan.h>
52566 +
52567 +#include "openswan/radij.h"
52568 +#include "openswan/ipsec_encap.h"
52569 +#include "openswan/ipsec_radij.h"
52570 +
52571 +int maj_keylen;
52572 +struct radij_mask *rj_mkfreelist;
52573 +struct radij_node_head *mask_rjhead;
52574 +static int gotOddMasks;
52575 +static char *maskedKey;
52576 +static char *rj_zeroes, *rj_ones;
52577 +
52578 +#define rj_masktop (mask_rjhead->rnh_treetop)
52579 +#ifdef Bcmp
52580 +# undef Bcmp
52581 +#endif /* Bcmp */
52582 +#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l))
52583 +/*
52584 + * The data structure for the keys is a radix tree with one way
52585 + * branching removed. The index rj_b at an internal node n represents a bit
52586 + * position to be tested. The tree is arranged so that all descendants
52587 + * of a node n have keys whose bits all agree up to position rj_b - 1.
52588 + * (We say the index of n is rj_b.)
52589 + *
52590 + * There is at least one descendant which has a one bit at position rj_b,
52591 + * and at least one with a zero there.
52592 + *
52593 + * A route is determined by a pair of key and mask. We require that the
52594 + * bit-wise logical and of the key and mask to be the key.
52595 + * We define the index of a route to associated with the mask to be
52596 + * the first bit number in the mask where 0 occurs (with bit number 0
52597 + * representing the highest order bit).
52598 + *
52599 + * We say a mask is normal if every bit is 0, past the index of the mask.
52600 + * If a node n has a descendant (k, m) with index(m) == index(n) == rj_b,
52601 + * and m is a normal mask, then the route applies to every descendant of n.
52602 + * If the index(m) < rj_b, this implies the trailing last few bits of k
52603 + * before bit b are all 0, (and hence consequently true of every descendant
52604 + * of n), so the route applies to all descendants of the node as well.
52605 + *
52606 + * The present version of the code makes no use of normal routes,
52607 + * but similar logic shows that a non-normal mask m such that
52608 + * index(m) <= index(n) could potentially apply to many children of n.
52609 + * Thus, for each non-host route, we attach its mask to a list at an internal
52610 + * node as high in the tree as we can go.
52611 + */
52612 +
52613 +struct radij_node *
52614 +rj_search(v_arg, head)
52615 + void *v_arg;
52616 + struct radij_node *head;
52617 +{
52618 + register struct radij_node *x;
52619 + register caddr_t v;
52620 +
52621 + for (x = head, v = v_arg; x->rj_b >= 0;) {
52622 + if (x->rj_bmask & v[x->rj_off])
52623 + x = x->rj_r;
52624 + else
52625 + x = x->rj_l;
52626 + }
52627 + return (x);
52628 +};
52629 +
52630 +struct radij_node *
52631 +rj_search_m(v_arg, head, m_arg)
52632 + struct radij_node *head;
52633 + void *v_arg, *m_arg;
52634 +{
52635 + register struct radij_node *x;
52636 + register caddr_t v = v_arg, m = m_arg;
52637 +
52638 + for (x = head; x->rj_b >= 0;) {
52639 + if ((x->rj_bmask & m[x->rj_off]) &&
52640 + (x->rj_bmask & v[x->rj_off]))
52641 + x = x->rj_r;
52642 + else
52643 + x = x->rj_l;
52644 + }
52645 + return x;
52646 +};
52647 +
52648 +int
52649 +rj_refines(m_arg, n_arg)
52650 + void *m_arg, *n_arg;
52651 +{
52652 + register caddr_t m = m_arg, n = n_arg;
52653 + register caddr_t lim, lim2 = lim = n + *(u_char *)n;
52654 + int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);
52655 + int masks_are_equal = 1;
52656 +
52657 + if (longer > 0)
52658 + lim -= longer;
52659 + while (n < lim) {
52660 + if (*n & ~(*m))
52661 + return 0;
52662 + if (*n++ != *m++)
52663 + masks_are_equal = 0;
52664 +
52665 + }
52666 + while (n < lim2)
52667 + if (*n++)
52668 + return 0;
52669 + if (masks_are_equal && (longer < 0))
52670 + for (lim2 = m - longer; m < lim2; )
52671 + if (*m++)
52672 + return 1;
52673 + return (!masks_are_equal);
52674 +}
52675 +
52676 +
52677 +struct radij_node *
52678 +rj_match(v_arg, head)
52679 + void *v_arg;
52680 + struct radij_node_head *head;
52681 +{
52682 + caddr_t v = v_arg;
52683 + register struct radij_node *t = head->rnh_treetop, *x;
52684 + register caddr_t cp = v, cp2, cp3;
52685 + caddr_t cplim, mstart;
52686 + struct radij_node *saved_t, *top = t;
52687 + int off = t->rj_off, vlen = *(u_char *)cp, matched_off;
52688 +
52689 + /*
52690 + * Open code rj_search(v, top) to avoid overhead of extra
52691 + * subroutine call.
52692 + */
52693 + for (; t->rj_b >= 0; ) {
52694 + if (t->rj_bmask & cp[t->rj_off])
52695 + t = t->rj_r;
52696 + else
52697 + t = t->rj_l;
52698 + }
52699 + /*
52700 + * See if we match exactly as a host destination
52701 + */
52702 + KLIPS_PRINT(debug_radij,
52703 + "klips_debug:rj_match: "
52704 + "* See if we match exactly as a host destination\n");
52705 +
52706 + cp += off; cp2 = t->rj_key + off; cplim = v + vlen;
52707 + for (; cp < cplim; cp++, cp2++)
52708 + if (*cp != *cp2)
52709 + goto on1;
52710 + /*
52711 + * This extra grot is in case we are explicitly asked
52712 + * to look up the default. Ugh!
52713 + */
52714 + if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey)
52715 + t = t->rj_dupedkey;
52716 + return t;
52717 +on1:
52718 + matched_off = cp - v;
52719 + saved_t = t;
52720 + KLIPS_PRINT(debug_radij,
52721 + "klips_debug:rj_match: "
52722 + "** try to match a leaf, t=0p%p\n", t);
52723 + do {
52724 + if (t->rj_mask) {
52725 + /*
52726 + * Even if we don't match exactly as a hosts;
52727 + * we may match if the leaf we wound up at is
52728 + * a route to a net.
52729 + */
52730 + cp3 = matched_off + t->rj_mask;
52731 + cp2 = matched_off + t->rj_key;
52732 + for (; cp < cplim; cp++)
52733 + if ((*cp2++ ^ *cp) & *cp3++)
52734 + break;
52735 + if (cp == cplim)
52736 + return t;
52737 + cp = matched_off + v;
52738 + }
52739 + } while ((t = t->rj_dupedkey));
52740 + t = saved_t;
52741 + /* start searching up the tree */
52742 + KLIPS_PRINT(debug_radij,
52743 + "klips_debug:rj_match: "
52744 + "*** start searching up the tree, t=0p%p\n",
52745 + t);
52746 + do {
52747 + register struct radij_mask *m;
52748 +
52749 + t = t->rj_p;
52750 + KLIPS_PRINT(debug_radij,
52751 + "klips_debug:rj_match: "
52752 + "**** t=0p%p\n",
52753 + t);
52754 + if ((m = t->rj_mklist)) {
52755 + /*
52756 + * After doing measurements here, it may
52757 + * turn out to be faster to open code
52758 + * rj_search_m here instead of always
52759 + * copying and masking.
52760 + */
52761 + /* off = min(t->rj_off, matched_off); */
52762 + off = t->rj_off;
52763 + if (matched_off < off)
52764 + off = matched_off;
52765 + mstart = maskedKey + off;
52766 + do {
52767 + cp2 = mstart;
52768 + cp3 = m->rm_mask + off;
52769 + KLIPS_PRINT(debug_radij,
52770 + "klips_debug:rj_match: "
52771 + "***** cp2=0p%p cp3=0p%p\n",
52772 + cp2, cp3);
52773 + for (cp = v + off; cp < cplim;)
52774 + *cp2++ = *cp++ & *cp3++;
52775 + x = rj_search(maskedKey, t);
52776 + while (x && x->rj_mask != m->rm_mask)
52777 + x = x->rj_dupedkey;
52778 + if (x &&
52779 + (Bcmp(mstart, x->rj_key + off,
52780 + vlen - off) == 0))
52781 + return x;
52782 + } while ((m = m->rm_mklist));
52783 + }
52784 + } while (t != top);
52785 + KLIPS_PRINT(debug_radij,
52786 + "klips_debug:rj_match: "
52787 + "***** not found.\n");
52788 + return 0;
52789 +};
52790 +
52791 +#ifdef RJ_DEBUG
52792 +int rj_nodenum;
52793 +struct radij_node *rj_clist;
52794 +int rj_saveinfo;
52795 +DEBUG_NO_STATIC void traverse(struct radij_node *);
52796 +#ifdef RJ_DEBUG2
52797 +int rj_debug = 1;
52798 +#else
52799 +int rj_debug = 0;
52800 +#endif /* RJ_DEBUG2 */
52801 +#endif /* RJ_DEBUG */
52802 +
52803 +struct radij_node *
52804 +rj_newpair(v, b, nodes)
52805 + void *v;
52806 + int b;
52807 + struct radij_node nodes[2];
52808 +{
52809 + register struct radij_node *tt = nodes, *t = tt + 1;
52810 + t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7);
52811 + t->rj_l = tt; t->rj_off = b >> 3;
52812 + tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t;
52813 + tt->rj_flags = t->rj_flags = RJF_ACTIVE;
52814 +#ifdef RJ_DEBUG
52815 + tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
52816 + tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
52817 +#endif /* RJ_DEBUG */
52818 + return t;
52819 +}
52820 +
52821 +struct radij_node *
52822 +rj_insert(v_arg, head, dupentry, nodes)
52823 + void *v_arg;
52824 + struct radij_node_head *head;
52825 + int *dupentry;
52826 + struct radij_node nodes[2];
52827 +{
52828 + caddr_t v = v_arg;
52829 + struct radij_node *top = head->rnh_treetop;
52830 + int head_off = top->rj_off, vlen = (int)*((u_char *)v);
52831 + register struct radij_node *t = rj_search(v_arg, top);
52832 + register caddr_t cp = v + head_off;
52833 + register int b;
52834 + struct radij_node *tt;
52835 + /*
52836 + *find first bit at which v and t->rj_key differ
52837 + */
52838 + {
52839 + register caddr_t cp2 = t->rj_key + head_off;
52840 + register int cmp_res;
52841 + caddr_t cplim = v + vlen;
52842 +
52843 + while (cp < cplim)
52844 + if (*cp2++ != *cp++)
52845 + goto on1;
52846 + *dupentry = 1;
52847 + return t;
52848 +on1:
52849 + *dupentry = 0;
52850 + cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
52851 + for (b = (cp - v) << 3; cmp_res; b--)
52852 + cmp_res >>= 1;
52853 + }
52854 + {
52855 + register struct radij_node *p, *x = top;
52856 + cp = v;
52857 + do {
52858 + p = x;
52859 + if (cp[x->rj_off] & x->rj_bmask)
52860 + x = x->rj_r;
52861 + else x = x->rj_l;
52862 + } while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */
52863 +#ifdef RJ_DEBUG
52864 + if (rj_debug)
52865 + printk("klips_debug:rj_insert: Going In:\n"), traverse(p);
52866 +#endif /* RJ_DEBUG */
52867 + t = rj_newpair(v_arg, b, nodes); tt = t->rj_l;
52868 + if ((cp[p->rj_off] & p->rj_bmask) == 0)
52869 + p->rj_l = t;
52870 + else
52871 + p->rj_r = t;
52872 + x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */
52873 + if ((cp[t->rj_off] & t->rj_bmask) == 0) {
52874 + t->rj_r = x;
52875 + } else {
52876 + t->rj_r = tt; t->rj_l = x;
52877 + }
52878 +#ifdef RJ_DEBUG
52879 + if (rj_debug)
52880 + printk("klips_debug:rj_insert: Coming out:\n"), traverse(p);
52881 +#endif /* RJ_DEBUG */
52882 + }
52883 + return (tt);
52884 +}
52885 +
52886 +struct radij_node *
52887 +rj_addmask(n_arg, search, skip)
52888 + int search, skip;
52889 + void *n_arg;
52890 +{
52891 + caddr_t netmask = (caddr_t)n_arg;
52892 + register struct radij_node *x;
52893 + register caddr_t cp, cplim;
52894 + register int b, mlen, j;
52895 + int maskduplicated;
52896 +
52897 + mlen = *(u_char *)netmask;
52898 + if (search) {
52899 + x = rj_search(netmask, rj_masktop);
52900 + mlen = *(u_char *)netmask;
52901 + if (Bcmp(netmask, x->rj_key, mlen) == 0)
52902 + return (x);
52903 + }
52904 + R_Malloc(x, struct radij_node *, maj_keylen + 2 * sizeof (*x));
52905 + if (x == 0)
52906 + return (0);
52907 + Bzero(x, maj_keylen + 2 * sizeof (*x));
52908 + cp = (caddr_t)(x + 2);
52909 + Bcopy(netmask, cp, mlen);
52910 + netmask = cp;
52911 + x = rj_insert(netmask, mask_rjhead, &maskduplicated, x);
52912 + /*
52913 + * Calculate index of mask.
52914 + */
52915 + cplim = netmask + mlen;
52916 + for (cp = netmask + skip; cp < cplim; cp++)
52917 + if (*(u_char *)cp != 0xff)
52918 + break;
52919 + b = (cp - netmask) << 3;
52920 + if (cp != cplim) {
52921 + if (*cp != 0) {
52922 + gotOddMasks = 1;
52923 + for (j = 0x80; j; b++, j >>= 1)
52924 + if ((j & *cp) == 0)
52925 + break;
52926 + }
52927 + }
52928 + x->rj_b = -1 - b;
52929 + return (x);
52930 +}
52931 +
52932 +#if 0
52933 +struct radij_node *
52934 +#endif
52935 +int
52936 +rj_addroute(v_arg, n_arg, head, treenodes)
52937 + void *v_arg, *n_arg;
52938 + struct radij_node_head *head;
52939 + struct radij_node treenodes[2];
52940 +{
52941 + caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
52942 + register struct radij_node *t, *x=NULL, *tt;
52943 + struct radij_node *saved_tt, *top = head->rnh_treetop;
52944 + short b = 0, b_leaf;
52945 + int mlen, keyduplicated;
52946 + caddr_t cplim;
52947 + struct radij_mask *m, **mp;
52948 +
52949 + /*
52950 + * In dealing with non-contiguous masks, there may be
52951 + * many different routes which have the same mask.
52952 + * We will find it useful to have a unique pointer to
52953 + * the mask to speed avoiding duplicate references at
52954 + * nodes and possibly save time in calculating indices.
52955 + */
52956 + if (netmask) {
52957 + x = rj_search(netmask, rj_masktop);
52958 + mlen = *(u_char *)netmask;
52959 + if (Bcmp(netmask, x->rj_key, mlen) != 0) {
52960 + x = rj_addmask(netmask, 0, top->rj_off);
52961 + if (x == 0)
52962 + return -ENOMEM; /* (0) rgb */
52963 + }
52964 + netmask = x->rj_key;
52965 + b = -1 - x->rj_b;
52966 + }
52967 + /*
52968 + * Deal with duplicated keys: attach node to previous instance
52969 + */
52970 + saved_tt = tt = rj_insert(v, head, &keyduplicated, treenodes);
52971 +#ifdef RJ_DEBUG
52972 + printk("addkey: duplicated: %d\n", keyduplicated);
52973 +#endif
52974 + if (keyduplicated) {
52975 + do {
52976 + if (tt->rj_mask == netmask)
52977 + return -EEXIST; /* -ENXIO; (0) rgb */
52978 + t = tt;
52979 + if (netmask == 0 ||
52980 + (tt->rj_mask && rj_refines(netmask, tt->rj_mask)))
52981 + break;
52982 + } while ((tt = tt->rj_dupedkey));
52983 + /*
52984 + * If the mask is not duplicated, we wouldn't
52985 + * find it among possible duplicate key entries
52986 + * anyway, so the above test doesn't hurt.
52987 + *
52988 + * We sort the masks for a duplicated key the same way as
52989 + * in a masklist -- most specific to least specific.
52990 + * This may require the unfortunate nuisance of relocating
52991 + * the head of the list.
52992 + */
52993 + if (tt && t == saved_tt) {
52994 + struct radij_node *xx = x;
52995 + /* link in at head of list */
52996 + (tt = treenodes)->rj_dupedkey = t;
52997 + tt->rj_flags = t->rj_flags;
52998 + tt->rj_p = x = t->rj_p;
52999 + if (x->rj_l == t) x->rj_l = tt; else x->rj_r = tt;
53000 + saved_tt = tt; x = xx;
53001 + } else {
53002 + (tt = treenodes)->rj_dupedkey = t->rj_dupedkey;
53003 + t->rj_dupedkey = tt;
53004 + }
53005 +#ifdef RJ_DEBUG
53006 + t=tt+1; tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
53007 + tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
53008 +#endif /* RJ_DEBUG */
53009 + t = saved_tt;
53010 + tt->rj_key = (caddr_t) v;
53011 + tt->rj_b = -1;
53012 + tt->rj_flags = t->rj_flags & ~RJF_ROOT;
53013 + }
53014 + /*
53015 + * Put mask in tree.
53016 + */
53017 + if (netmask) {
53018 + tt->rj_mask = netmask;
53019 + tt->rj_b = x->rj_b;
53020 + }
53021 + t = saved_tt->rj_p;
53022 + b_leaf = -1 - t->rj_b;
53023 + if (t->rj_r == saved_tt) x = t->rj_l; else x = t->rj_r;
53024 + /* Promote general routes from below */
53025 + if (x->rj_b < 0) {
53026 + if (x->rj_mask && (x->rj_b >= b_leaf) && x->rj_mklist == 0) {
53027 + MKGet(m);
53028 + if (m) {
53029 + Bzero(m, sizeof *m);
53030 + m->rm_b = x->rj_b;
53031 + m->rm_mask = x->rj_mask;
53032 + x->rj_mklist = t->rj_mklist = m;
53033 + }
53034 + }
53035 + } else if (x->rj_mklist) {
53036 + /*
53037 + * Skip over masks whose index is > that of new node
53038 + */
53039 + for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
53040 + if (m->rm_b >= b_leaf)
53041 + break;
53042 + t->rj_mklist = m; *mp = 0;
53043 + }
53044 + /* Add new route to highest possible ancestor's list */
53045 + if ((netmask == 0) || (b > t->rj_b )) {
53046 +#ifdef RJ_DEBUG
53047 + printk("klips:radij.c: netmask = %p or b(%d)>t->rjb(%d)\n", netmask, b, t->rj_b);
53048 +#endif
53049 + return 0; /* tt rgb */ /* can't lift at all */
53050 + }
53051 + b_leaf = tt->rj_b;
53052 + do {
53053 + x = t;
53054 + t = t->rj_p;
53055 + } while (b <= t->rj_b && x != top);
53056 + /*
53057 + * Search through routes associated with node to
53058 + * insert new route according to index.
53059 + * For nodes of equal index, place more specific
53060 + * masks first.
53061 + */
53062 + cplim = netmask + mlen;
53063 + for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) {
53064 + if (m->rm_b < b_leaf)
53065 + continue;
53066 + if (m->rm_b > b_leaf)
53067 + break;
53068 + if (m->rm_mask == netmask) {
53069 + m->rm_refs++;
53070 + tt->rj_mklist = m;
53071 +#ifdef RJ_DEBUG
53072 + printk("klips:radij.c: m->rm_mask %p == netmask\n", netmask);
53073 +#endif
53074 + return 0; /* tt rgb */
53075 + }
53076 + if (rj_refines(netmask, m->rm_mask))
53077 + break;
53078 + }
53079 + MKGet(m);
53080 + if (m == 0) {
53081 + printk("klips_debug:rj_addroute: "
53082 + "Mask for route not entered\n");
53083 + return 0; /* (tt) rgb */
53084 + }
53085 + Bzero(m, sizeof *m);
53086 + m->rm_b = b_leaf;
53087 + m->rm_mask = netmask;
53088 + m->rm_mklist = *mp;
53089 + *mp = m;
53090 + tt->rj_mklist = m;
53091 +#ifdef RJ_DEBUG
53092 + printk("klips:radij.c: addroute done\n");
53093 +#endif
53094 + return 0; /* tt rgb */
53095 +}
53096 +
53097 +int
53098 +rj_delete(v_arg, netmask_arg, head, node)
53099 + void *v_arg, *netmask_arg;
53100 + struct radij_node_head *head;
53101 + struct radij_node **node;
53102 +{
53103 + register struct radij_node *t, *p, *x, *tt;
53104 + struct radij_mask *m, *saved_m, **mp;
53105 + struct radij_node *dupedkey, *saved_tt, *top;
53106 + caddr_t v, netmask;
53107 + int b, head_off, vlen;
53108 +
53109 + v = v_arg;
53110 + netmask = netmask_arg;
53111 + x = head->rnh_treetop;
53112 + tt = rj_search(v, x);
53113 + head_off = x->rj_off;
53114 + vlen = *(u_char *)v;
53115 + saved_tt = tt;
53116 + top = x;
53117 + if (tt == 0 ||
53118 + Bcmp(v + head_off, tt->rj_key + head_off, vlen - head_off))
53119 + return -EFAULT; /* (0) rgb */
53120 + /*
53121 + * Delete our route from mask lists.
53122 + */
53123 + if ((dupedkey = tt->rj_dupedkey)) {
53124 + if (netmask)
53125 + netmask = rj_search(netmask, rj_masktop)->rj_key;
53126 + while (tt->rj_mask != netmask)
53127 + if ((tt = tt->rj_dupedkey) == 0)
53128 + return -ENOENT; /* -ENXIO; (0) rgb */
53129 + }
53130 + if (tt->rj_mask == 0 || (saved_m = m = tt->rj_mklist) == 0)
53131 + goto on1;
53132 + if (m->rm_mask != tt->rj_mask) {
53133 + printk("klips_debug:rj_delete: "
53134 + "inconsistent annotation\n");
53135 + goto on1;
53136 + }
53137 + if (--m->rm_refs >= 0)
53138 + goto on1;
53139 + b = -1 - tt->rj_b;
53140 + t = saved_tt->rj_p;
53141 + if (b > t->rj_b)
53142 + goto on1; /* Wasn't lifted at all */
53143 + do {
53144 + x = t;
53145 + t = t->rj_p;
53146 + } while (b <= t->rj_b && x != top);
53147 + for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
53148 + if (m == saved_m) {
53149 + *mp = m->rm_mklist;
53150 + MKFree(m);
53151 + break;
53152 + }
53153 + if (m == 0)
53154 + printk("klips_debug:rj_delete: "
53155 + "couldn't find our annotation\n");
53156 +on1:
53157 + /*
53158 + * Eliminate us from tree
53159 + */
53160 + if (tt->rj_flags & RJF_ROOT)
53161 + return -EFAULT; /* (0) rgb */
53162 +#ifdef RJ_DEBUG
53163 + /* Get us out of the creation list */
53164 + for (t = rj_clist; t && t->rj_ybro != tt; t = t->rj_ybro) {}
53165 + if (t) t->rj_ybro = tt->rj_ybro;
53166 +#endif /* RJ_DEBUG */
53167 + t = tt->rj_p;
53168 + if (dupedkey) {
53169 + if (tt == saved_tt) {
53170 + x = dupedkey; x->rj_p = t;
53171 + if (t->rj_l == tt) t->rj_l = x; else t->rj_r = x;
53172 + } else {
53173 + for (x = p = saved_tt; p && p->rj_dupedkey != tt;)
53174 + p = p->rj_dupedkey;
53175 + if (p) p->rj_dupedkey = tt->rj_dupedkey;
53176 + else printk("klips_debug:rj_delete: "
53177 + "couldn't find node that we started with\n");
53178 + }
53179 + t = tt + 1;
53180 + if (t->rj_flags & RJF_ACTIVE) {
53181 +#ifndef RJ_DEBUG
53182 + *++x = *t; p = t->rj_p;
53183 +#else
53184 + b = t->rj_info; *++x = *t; t->rj_info = b; p = t->rj_p;
53185 +#endif /* RJ_DEBUG */
53186 + if (p->rj_l == t) p->rj_l = x; else p->rj_r = x;
53187 + x->rj_l->rj_p = x; x->rj_r->rj_p = x;
53188 + }
53189 + goto out;
53190 + }
53191 + if (t->rj_l == tt) x = t->rj_r; else x = t->rj_l;
53192 + p = t->rj_p;
53193 + if (p->rj_r == t) p->rj_r = x; else p->rj_l = x;
53194 + x->rj_p = p;
53195 + /*
53196 + * Demote routes attached to us.
53197 + */
53198 + if (t->rj_mklist) {
53199 + if (x->rj_b >= 0) {
53200 + for (mp = &x->rj_mklist; (m = *mp);)
53201 + mp = &m->rm_mklist;
53202 + *mp = t->rj_mklist;
53203 + } else {
53204 + for (m = t->rj_mklist; m;) {
53205 + struct radij_mask *mm = m->rm_mklist;
53206 + if (m == x->rj_mklist && (--(m->rm_refs) < 0)) {
53207 + x->rj_mklist = 0;
53208 + MKFree(m);
53209 + } else
53210 + printk("klips_debug:rj_delete: "
53211 + "Orphaned Mask 0p%p at 0p%p\n", m, x);
53212 + m = mm;
53213 + }
53214 + }
53215 + }
53216 + /*
53217 + * We may be holding an active internal node in the tree.
53218 + */
53219 + x = tt + 1;
53220 + if (t != x) {
53221 +#ifndef RJ_DEBUG
53222 + *t = *x;
53223 +#else
53224 + b = t->rj_info; *t = *x; t->rj_info = b;
53225 +#endif /* RJ_DEBUG */
53226 + t->rj_l->rj_p = t; t->rj_r->rj_p = t;
53227 + p = x->rj_p;
53228 + if (p->rj_l == x) p->rj_l = t; else p->rj_r = t;
53229 + }
53230 +out:
53231 + tt->rj_flags &= ~RJF_ACTIVE;
53232 + tt[1].rj_flags &= ~RJF_ACTIVE;
53233 + *node = tt;
53234 + return 0; /* (tt) rgb */
53235 +}
53236 +
53237 +int
53238 +rj_walktree(h, f, w)
53239 + struct radij_node_head *h;
53240 + register int (*f)(struct radij_node *,void *);
53241 + void *w;
53242 +{
53243 + int error;
53244 + struct radij_node *base, *next;
53245 + register struct radij_node *rn;
53246 +
53247 + if(!h || !f /* || !w */) {
53248 + return -ENODATA;
53249 + }
53250 +
53251 + rn = h->rnh_treetop;
53252 + /*
53253 + * This gets complicated because we may delete the node
53254 + * while applying the function f to it, so we need to calculate
53255 + * the successor node in advance.
53256 + */
53257 + /* First time through node, go left */
53258 + while (rn->rj_b >= 0)
53259 + rn = rn->rj_l;
53260 + for (;;) {
53261 +#ifdef CONFIG_KLIPS_DEBUG
53262 + if(debug_radij) {
53263 + printk("klips_debug:rj_walktree: "
53264 + "for: rn=0p%p rj_b=%d rj_flags=%x",
53265 + rn,
53266 + rn->rj_b,
53267 + rn->rj_flags);
53268 + rn->rj_b >= 0 ?
53269 + printk(" node off=%x\n",
53270 + rn->rj_off) :
53271 + printk(" leaf key = %08x->%08x\n",
53272 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
53273 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
53274 + ;
53275 + }
53276 +#endif /* CONFIG_KLIPS_DEBUG */
53277 + base = rn;
53278 + /* If at right child go back up, otherwise, go right */
53279 + while (rn->rj_p->rj_r == rn && (rn->rj_flags & RJF_ROOT) == 0)
53280 + rn = rn->rj_p;
53281 + /* Find the next *leaf* since next node might vanish, too */
53282 + for (rn = rn->rj_p->rj_r; rn->rj_b >= 0;)
53283 + rn = rn->rj_l;
53284 + next = rn;
53285 +#ifdef CONFIG_KLIPS_DEBUG
53286 + if(debug_radij) {
53287 + printk("klips_debug:rj_walktree: "
53288 + "processing leaves, rn=0p%p rj_b=%d rj_flags=%x",
53289 + rn,
53290 + rn->rj_b,
53291 + rn->rj_flags);
53292 + rn->rj_b >= 0 ?
53293 + printk(" node off=%x\n",
53294 + rn->rj_off) :
53295 + printk(" leaf key = %08x->%08x\n",
53296 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
53297 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
53298 + ;
53299 + }
53300 +#endif /* CONFIG_KLIPS_DEBUG */
53301 + /* Process leaves */
53302 + while ((rn = base)) {
53303 + base = rn->rj_dupedkey;
53304 +#ifdef CONFIG_KLIPS_DEBUG
53305 + if(debug_radij) {
53306 + printk("klips_debug:rj_walktree: "
53307 + "while: base=0p%p rn=0p%p rj_b=%d rj_flags=%x",
53308 + base,
53309 + rn,
53310 + rn->rj_b,
53311 + rn->rj_flags);
53312 + rn->rj_b >= 0 ?
53313 + printk(" node off=%x\n",
53314 + rn->rj_off) :
53315 + printk(" leaf key = %08x->%08x\n",
53316 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
53317 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
53318 + ;
53319 + }
53320 +#endif /* CONFIG_KLIPS_DEBUG */
53321 + if (!(rn->rj_flags & RJF_ROOT) && (error = (*f)(rn, w)))
53322 + return (-error);
53323 + }
53324 + rn = next;
53325 + if (rn->rj_flags & RJF_ROOT)
53326 + return (0);
53327 + }
53328 + /* NOTREACHED */
53329 +}
53330 +
53331 +int
53332 +rj_inithead(head, off)
53333 + void **head;
53334 + int off;
53335 +{
53336 + register struct radij_node_head *rnh;
53337 + register struct radij_node *t, *tt, *ttt;
53338 + if (*head)
53339 + return (1);
53340 + R_Malloc(rnh, struct radij_node_head *, sizeof (*rnh));
53341 + if (rnh == NULL)
53342 + return (0);
53343 + Bzero(rnh, sizeof (*rnh));
53344 + *head = rnh;
53345 + t = rj_newpair(rj_zeroes, off, rnh->rnh_nodes);
53346 + ttt = rnh->rnh_nodes + 2;
53347 + t->rj_r = ttt;
53348 + t->rj_p = t;
53349 + tt = t->rj_l;
53350 + tt->rj_flags = t->rj_flags = RJF_ROOT | RJF_ACTIVE;
53351 + tt->rj_b = -1 - off;
53352 + *ttt = *tt;
53353 + ttt->rj_key = rj_ones;
53354 + rnh->rnh_addaddr = rj_addroute;
53355 + rnh->rnh_deladdr = rj_delete;
53356 + rnh->rnh_matchaddr = rj_match;
53357 + rnh->rnh_walktree = rj_walktree;
53358 + rnh->rnh_treetop = t;
53359 + return (1);
53360 +}
53361 +
53362 +void
53363 +rj_init()
53364 +{
53365 + char *cp, *cplim;
53366 +
53367 + if (maj_keylen == 0) {
53368 + printk("klips_debug:rj_init: "
53369 + "radij functions require maj_keylen be set\n");
53370 + return;
53371 + }
53372 + R_Malloc(rj_zeroes, char *, 3 * maj_keylen);
53373 + if (rj_zeroes == NULL)
53374 + panic("rj_init");
53375 + Bzero(rj_zeroes, 3 * maj_keylen);
53376 + rj_ones = cp = rj_zeroes + maj_keylen;
53377 + maskedKey = cplim = rj_ones + maj_keylen;
53378 + while (cp < cplim)
53379 + *cp++ = -1;
53380 + if (rj_inithead((void **)&mask_rjhead, 0) == 0)
53381 + panic("rj_init 2");
53382 +}
53383 +
53384 +void
53385 +rj_preorder(struct radij_node *rn, int l)
53386 +{
53387 + int i;
53388 +
53389 + if (rn == NULL){
53390 + printk("klips_debug:rj_preorder: "
53391 + "NULL pointer\n");
53392 + return;
53393 + }
53394 +
53395 + if (rn->rj_b >= 0){
53396 + rj_preorder(rn->rj_l, l+1);
53397 + rj_preorder(rn->rj_r, l+1);
53398 + printk("klips_debug:");
53399 + for (i=0; i<l; i++)
53400 + printk("*");
53401 + printk(" off = %d\n",
53402 + rn->rj_off);
53403 + } else {
53404 + printk("klips_debug:");
53405 + for (i=0; i<l; i++)
53406 + printk("@");
53407 + printk(" flags = %x",
53408 + (u_int)rn->rj_flags);
53409 + if (rn->rj_flags & RJF_ACTIVE) {
53410 + printk(" @key=0p%p",
53411 + rn->rj_key);
53412 + printk(" key = %08x->%08x",
53413 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
53414 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr));
53415 + printk(" @mask=0p%p",
53416 + rn->rj_mask);
53417 + if (rn->rj_mask)
53418 + printk(" mask = %08x->%08x",
53419 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_src.s_addr),
53420 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_dst.s_addr));
53421 + if (rn->rj_dupedkey)
53422 + printk(" dupedkey = 0p%p",
53423 + rn->rj_dupedkey);
53424 + }
53425 + printk("\n");
53426 + }
53427 +}
53428 +
53429 +#ifdef RJ_DEBUG
53430 +DEBUG_NO_STATIC void traverse(struct radij_node *p)
53431 +{
53432 + rj_preorder(p, 0);
53433 +}
53434 +#endif /* RJ_DEBUG */
53435 +
53436 +void
53437 +rj_dumptrees(void)
53438 +{
53439 + rj_preorder(rnh->rnh_treetop, 0);
53440 +}
53441 +
53442 +void
53443 +rj_free_mkfreelist(void)
53444 +{
53445 + struct radij_mask *mknp, *mknp2;
53446 +
53447 + mknp = rj_mkfreelist;
53448 + while(mknp)
53449 + {
53450 + mknp2 = mknp;
53451 + mknp = mknp->rm_mklist;
53452 + kfree(mknp2);
53453 + }
53454 +}
53455 +
53456 +int
53457 +radijcleartree(void)
53458 +{
53459 + return rj_walktree(rnh, ipsec_rj_walker_delete, NULL);
53460 +}
53461 +
53462 +int
53463 +radijcleanup(void)
53464 +{
53465 + int error = 0;
53466 +
53467 + error = radijcleartree();
53468 +
53469 + rj_free_mkfreelist();
53470 +
53471 +/* rj_walktree(mask_rjhead, ipsec_rj_walker_delete, NULL); */
53472 + if(mask_rjhead) {
53473 + kfree(mask_rjhead);
53474 + }
53475 +
53476 + if(rj_zeroes) {
53477 + kfree(rj_zeroes);
53478 + }
53479 +
53480 + if(rnh) {
53481 + kfree(rnh);
53482 + }
53483 +
53484 + return error;
53485 +}
53486 +
53487 +/*
53488 + *
53489 + * Local Variables:
53490 + * c-file-style: "linux"
53491 + * End:
53492 + *
53493 + */
53494 --- /dev/null Tue Mar 11 13:02:56 2003
53495 +++ linux/net/ipsec/rangetoa.c Mon Feb 9 13:51:03 2004
53496 @@ -0,0 +1,60 @@
53497 +/*
53498 + * convert binary form of address range to ASCII
53499 + * Copyright (C) 1998, 1999 Henry Spencer.
53500 + *
53501 + * This library is free software; you can redistribute it and/or modify it
53502 + * under the terms of the GNU Library General Public License as published by
53503 + * the Free Software Foundation; either version 2 of the License, or (at your
53504 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
53505 + *
53506 + * This library is distributed in the hope that it will be useful, but
53507 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
53508 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
53509 + * License for more details.
53510 + *
53511 + * RCSID $Id: rangetoa.c,v 1.9 2004/07/10 07:48:37 mcr Exp $
53512 + */
53513 +#include "openswan.h"
53514 +
53515 +/*
53516 + - rangetoa - convert address range to ASCII
53517 + */
53518 +size_t /* space needed for full conversion */
53519 +rangetoa(addrs, format, dst, dstlen)
53520 +struct in_addr addrs[2];
53521 +int format; /* character */
53522 +char *dst; /* need not be valid if dstlen is 0 */
53523 +size_t dstlen;
53524 +{
53525 + size_t len;
53526 + size_t rest;
53527 + int n;
53528 + char *p;
53529 +
53530 + switch (format) {
53531 + case 0:
53532 + break;
53533 + default:
53534 + return 0;
53535 + break;
53536 + }
53537 +
53538 + len = addrtoa(addrs[0], 0, dst, dstlen);
53539 + if (len < dstlen)
53540 + for (p = dst + len - 1, n = 3; len < dstlen && n > 0;
53541 + p++, len++, n--)
53542 + *p = '.';
53543 + else
53544 + p = NULL;
53545 + if (len < dstlen)
53546 + rest = dstlen - len;
53547 + else {
53548 + if (dstlen > 0)
53549 + *(dst + dstlen - 1) = '\0';
53550 + rest = 0;
53551 + }
53552 +
53553 + len += addrtoa(addrs[1], 0, p, rest);
53554 +
53555 + return len;
53556 +}
53557 --- /dev/null Tue Mar 11 13:02:56 2003
53558 +++ linux/net/ipsec/satot.c Mon Feb 9 13:51:03 2004
53559 @@ -0,0 +1,134 @@
53560 +/*
53561 + * convert from binary form of SA ID to text
53562 + * Copyright (C) 2000, 2001 Henry Spencer.
53563 + *
53564 + * This library is free software; you can redistribute it and/or modify it
53565 + * under the terms of the GNU Library General Public License as published by
53566 + * the Free Software Foundation; either version 2 of the License, or (at your
53567 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
53568 + *
53569 + * This library is distributed in the hope that it will be useful, but
53570 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
53571 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
53572 + * License for more details.
53573 + *
53574 + * RCSID $Id: satot.c,v 1.13 2004/07/10 07:48:37 mcr Exp $
53575 + */
53576 +#include "openswan.h"
53577 +
53578 +static struct typename {
53579 + char type;
53580 + char *name;
53581 +} typenames[] = {
53582 + { SA_AH, "ah" },
53583 + { SA_ESP, "esp" },
53584 + { SA_IPIP, "tun" },
53585 + { SA_COMP, "comp" },
53586 + { SA_INT, "int" },
53587 + { 0, NULL }
53588 +};
53589 +
53590 +/*
53591 + - satot - convert SA to text "ah507@1.2.3.4"
53592 + */
53593 +size_t /* space needed for full conversion */
53594 +satot(sa, format, dst, dstlen)
53595 +const ip_said *sa;
53596 +int format; /* character */
53597 +char *dst; /* need not be valid if dstlen is 0 */
53598 +size_t dstlen;
53599 +{
53600 + size_t len = 0; /* 0 means "not recognized yet" */
53601 + int base;
53602 + int showversion; /* use delimiter to show IP version? */
53603 + struct typename *tn;
53604 + char *p;
53605 + char *pre;
53606 + char buf[10+1+ULTOT_BUF+ADDRTOT_BUF];
53607 + char unk[10];
53608 +
53609 + switch (format) {
53610 + case 0:
53611 + base = 16;
53612 + showversion = 1;
53613 + break;
53614 + case 'f':
53615 + base = 17;
53616 + showversion = 1;
53617 + break;
53618 + case 'x':
53619 + base = 'x';
53620 + showversion = 0;
53621 + break;
53622 + case 'd':
53623 + base = 10;
53624 + showversion = 0;
53625 + break;
53626 + default:
53627 + return 0;
53628 + break;
53629 + }
53630 +
53631 + memset(buf, 0, sizeof(buf));
53632 +
53633 + pre = NULL;
53634 + for (tn = typenames; tn->name != NULL; tn++)
53635 + if (sa->proto == tn->type) {
53636 + pre = tn->name;
53637 + break; /* NOTE BREAK OUT */
53638 + }
53639 + if (pre == NULL) { /* unknown protocol */
53640 + strcpy(unk, "unk");
53641 + (void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk),
53642 + sizeof(unk)-strlen(unk));
53643 + pre = unk;
53644 + }
53645 +
53646 + if (strcmp(pre, PASSTHROUGHTYPE) == 0 &&
53647 + sa->spi == PASSTHROUGHSPI &&
53648 + isunspecaddr(&sa->dst)) {
53649 + strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ?
53650 + PASSTHROUGH4NAME :
53651 + PASSTHROUGH6NAME);
53652 + len = strlen(buf);
53653 + }
53654 +
53655 + if (sa->proto == SA_INT) {
53656 + char intunk[10];
53657 + switch (ntohl(sa->spi)) {
53658 + case SPI_PASS: p = "%pass"; break;
53659 + case SPI_DROP: p = "%drop"; break;
53660 + case SPI_REJECT: p = "%reject"; break;
53661 + case SPI_HOLD: p = "%hold"; break;
53662 + case SPI_TRAP: p = "%trap"; break;
53663 + case SPI_TRAPSUBNET: p = "%trapsubnet"; break;
53664 + default: snprintf(intunk, 10, "%%unk-%d", ntohl(sa->spi)); p = intunk; break;
53665 + }
53666 + if (p != NULL) {
53667 + strcpy(buf, p);
53668 + len = strlen(buf);
53669 + }
53670 + }
53671 +
53672 + if (len == 0) { /* general case needed */
53673 + strcpy(buf, pre);
53674 + len = strlen(buf);
53675 + if (showversion) {
53676 + *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' :
53677 + ':';
53678 + len++;
53679 + *(buf+len) = '\0';
53680 + }
53681 + len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len);
53682 + *(buf+len-1) = '@';
53683 + len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len);
53684 + *(buf+len) = '\0';
53685 + }
53686 +
53687 + if (dst != NULL) {
53688 + if (len > dstlen)
53689 + *(buf+dstlen-1) = '\0';
53690 + strcpy(dst, buf);
53691 + }
53692 + return len;
53693 +}
53694 --- /dev/null Tue Mar 11 13:02:56 2003
53695 +++ linux/net/ipsec/subnetof.c Mon Feb 9 13:51:03 2004
53696 @@ -0,0 +1,59 @@
53697 +/*
53698 + * minor network-address manipulation utilities
53699 + * Copyright (C) 1998, 1999 Henry Spencer.
53700 + *
53701 + * This library is free software; you can redistribute it and/or modify it
53702 + * under the terms of the GNU Library General Public License as published by
53703 + * the Free Software Foundation; either version 2 of the License, or (at your
53704 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
53705 + *
53706 + * This library is distributed in the hope that it will be useful, but
53707 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
53708 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
53709 + * License for more details.
53710 + *
53711 + * RCSID $Id: subnetof.c,v 1.8 2004/07/10 07:48:37 mcr Exp $
53712 + */
53713 +#include "openswan.h"
53714 +
53715 +/*
53716 + - subnetof - given address and mask, return subnet part
53717 + */
53718 +struct in_addr
53719 +subnetof(addr, mask)
53720 +struct in_addr addr;
53721 +struct in_addr mask;
53722 +{
53723 + struct in_addr result;
53724 +
53725 + result.s_addr = addr.s_addr & mask.s_addr;
53726 + return result;
53727 +}
53728 +
53729 +/*
53730 + - hostof - given address and mask, return host part
53731 + */
53732 +struct in_addr
53733 +hostof(addr, mask)
53734 +struct in_addr addr;
53735 +struct in_addr mask;
53736 +{
53737 + struct in_addr result;
53738 +
53739 + result.s_addr = addr.s_addr & ~mask.s_addr;
53740 + return result;
53741 +}
53742 +
53743 +/*
53744 + - broadcastof - given (network) address and mask, return broadcast address
53745 + */
53746 +struct in_addr
53747 +broadcastof(addr, mask)
53748 +struct in_addr addr;
53749 +struct in_addr mask;
53750 +{
53751 + struct in_addr result;
53752 +
53753 + result.s_addr = addr.s_addr | ~mask.s_addr;
53754 + return result;
53755 +}
53756 --- /dev/null Tue Mar 11 13:02:56 2003
53757 +++ linux/net/ipsec/subnettoa.c Mon Feb 9 13:51:03 2004
53758 @@ -0,0 +1,61 @@
53759 +/*
53760 + * convert binary form of subnet description to ASCII
53761 + * Copyright (C) 1998, 1999 Henry Spencer.
53762 + *
53763 + * This library is free software; you can redistribute it and/or modify it
53764 + * under the terms of the GNU Library General Public License as published by
53765 + * the Free Software Foundation; either version 2 of the License, or (at your
53766 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
53767 + *
53768 + * This library is distributed in the hope that it will be useful, but
53769 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
53770 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
53771 + * License for more details.
53772 + *
53773 + * RCSID $Id: subnettoa.c,v 1.11 2004/07/10 07:48:37 mcr Exp $
53774 + */
53775 +#include "openswan.h"
53776 +
53777 +/*
53778 + - subnettoa - convert address and mask to ASCII "addr/mask"
53779 + * Output expresses the mask as a bit count if possible, else dotted decimal.
53780 + */
53781 +size_t /* space needed for full conversion */
53782 +subnettoa(addr, mask, format, dst, dstlen)
53783 +struct in_addr addr;
53784 +struct in_addr mask;
53785 +int format; /* character */
53786 +char *dst; /* need not be valid if dstlen is 0 */
53787 +size_t dstlen;
53788 +{
53789 + size_t len;
53790 + size_t rest;
53791 + int n;
53792 + char *p;
53793 +
53794 + switch (format) {
53795 + case 0:
53796 + break;
53797 + default:
53798 + return 0;
53799 + break;
53800 + }
53801 +
53802 + len = addrtoa(addr, 0, dst, dstlen);
53803 + if (len < dstlen) {
53804 + dst[len - 1] = '/';
53805 + p = dst + len;
53806 + rest = dstlen - len;
53807 + } else {
53808 + p = NULL;
53809 + rest = 0;
53810 + }
53811 +
53812 + n = masktobits(mask);
53813 + if (n >= 0)
53814 + len += ultoa((unsigned long)n, 10, p, rest);
53815 + else
53816 + len += addrtoa(mask, 0, p, rest);
53817 +
53818 + return len;
53819 +}
53820 --- /dev/null Tue Mar 11 13:02:56 2003
53821 +++ linux/net/ipsec/sysctl_net_ipsec.c Mon Feb 9 13:51:03 2004
53822 @@ -0,0 +1,387 @@
53823 +/*
53824 + * sysctl interface to net IPSEC subsystem.
53825 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
53826 + *
53827 + * This program is free software; you can redistribute it and/or modify it
53828 + * under the terms of the GNU General Public License as published by the
53829 + * Free Software Foundation; either version 2 of the License, or (at your
53830 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
53831 + *
53832 + * This program is distributed in the hope that it will be useful, but
53833 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
53834 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
53835 + * for more details.
53836 + *
53837 + * RCSID $Id: sysctl_net_ipsec.c,v 1.17.10.2 2007/10/30 21:42:25 paul Exp $
53838 + */
53839 +
53840 +/* -*- linux-c -*-
53841 + *
53842 + * Initiated April 3, 1998, Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
53843 + */
53844 +
53845 +#include <linux/version.h>
53846 +#include <linux/mm.h>
53847 +#include <linux/sysctl.h>
53848 +
53849 +#include "openswan/ipsec_param.h"
53850 +
53851 +#ifdef CONFIG_SYSCTL
53852 +
53853 +#define NET_IPSEC 2112 /* Random number */
53854 +#ifdef CONFIG_KLIPS_DEBUG
53855 +extern int debug_ah;
53856 +extern int debug_esp;
53857 +extern int debug_mast;
53858 +extern int debug_tunnel;
53859 +extern int debug_xmit;
53860 +extern int debug_eroute;
53861 +extern int debug_spi;
53862 +extern int debug_radij;
53863 +extern int debug_netlink;
53864 +extern int debug_xform;
53865 +extern int debug_rcv;
53866 +extern int debug_pfkey;
53867 +extern int sysctl_ipsec_debug_verbose;
53868 +#ifdef CONFIG_KLIPS_IPCOMP
53869 +extern int sysctl_ipsec_debug_ipcomp;
53870 +#endif /* CONFIG_KLIPS_IPCOMP */
53871 +#endif /* CONFIG_KLIPS_DEBUG */
53872 +
53873 +extern int sysctl_ipsec_icmp;
53874 +extern int sysctl_ipsec_inbound_policy_check;
53875 +extern int sysctl_ipsec_tos;
53876 +int sysctl_ipsec_regress_pfkey_lossage;
53877 +
53878 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
53879 +#ifdef CONFIG_KLIPS_DEBUG
53880 + #define NET_IPSEC_DEBUG_AH CTL_UNNUMBERED
53881 + #define NET_IPSEC_DEBUG_ESP CTL_UNNUMBERED
53882 + #define NET_IPSEC_DEBUG_TUNNEL CTL_UNNUMBERED
53883 + #define NET_IPSEC_DEBUG_EROUTE CTL_UNNUMBERED
53884 + #define NET_IPSEC_DEBUG_SPI CTL_UNNUMBERED
53885 + #define NET_IPSEC_DEBUG_RADIJ CTL_UNNUMBERED
53886 + #define NET_IPSEC_DEBUG_NETLINK CTL_UNNUMBERED
53887 + #define NET_IPSEC_DEBUG_XFORM CTL_UNNUMBERED
53888 + #define NET_IPSEC_DEBUG_RCV CTL_UNNUMBERED
53889 + #define NET_IPSEC_DEBUG_PFKEY CTL_UNNUMBERED
53890 + #define NET_IPSEC_DEBUG_VERBOSE CTL_UNNUMBERED
53891 + #define NET_IPSEC_DEBUG_IPCOMP CTL_UNNUMBERED
53892 +#endif /* CONFIG_KLIPS_DEBUG */
53893 + #define NET_IPSEC_ICMP CTL_UNNUMBERED
53894 + #define NET_IPSEC_INBOUND_POLICY_CHECK CTL_UNNUMBERED
53895 + #define NET_IPSEC_TOS CTL_UNNUMBERED
53896 + #define NET_IPSEC_REGRESS_PFKEY_LOSSAGE CTL_UNNUMBERED
53897 + #define NET_IPSEC_DEBUG_MAST CTL_UNNUMBERED
53898 + #define NET_IPSEC_DEBUG_XMIT CTL_UNNUMBERED
53899 +#else
53900 +enum {
53901 +#ifdef CONFIG_KLIPS_DEBUG
53902 + NET_IPSEC_DEBUG_AH=1,
53903 + NET_IPSEC_DEBUG_ESP=2,
53904 + NET_IPSEC_DEBUG_TUNNEL=3,
53905 + NET_IPSEC_DEBUG_EROUTE=4,
53906 + NET_IPSEC_DEBUG_SPI=5,
53907 + NET_IPSEC_DEBUG_RADIJ=6,
53908 + NET_IPSEC_DEBUG_NETLINK=7,
53909 + NET_IPSEC_DEBUG_XFORM=8,
53910 + NET_IPSEC_DEBUG_RCV=9,
53911 + NET_IPSEC_DEBUG_PFKEY=10,
53912 + NET_IPSEC_DEBUG_VERBOSE=11,
53913 + NET_IPSEC_DEBUG_IPCOMP=12,
53914 +#endif /* CONFIG_KLIPS_DEBUG */
53915 + NET_IPSEC_ICMP=13,
53916 + NET_IPSEC_INBOUND_POLICY_CHECK=14,
53917 + NET_IPSEC_TOS=15,
53918 + NET_IPSEC_REGRESS_PFKEY_LOSSAGE=16,
53919 + NET_IPSEC_DEBUG_MAST=17,
53920 + NET_IPSEC_DEBUG_XMIT=18,
53921 +};
53922 +#endif
53923 +
53924 +static ctl_table ipsec_table[] = {
53925 +
53926 +#ifdef CONFIG_KLIPS_DEBUG
53927 +#ifdef CTL_TABLE_PARENT
53928 + { .ctl_name = NET_IPSEC_DEBUG_AH,
53929 + .procname = "debug_ah",
53930 + .data = &debug_ah,
53931 + .maxlen = sizeof(int),
53932 + .mode = 0644,
53933 + .child = NULL,
53934 + .proc_handler = &proc_dointvec,
53935 + },
53936 +
53937 + { .ctl_name = NET_IPSEC_DEBUG_ESP,
53938 + .procname = "debug_esp",
53939 + .data = &debug_esp,
53940 + .maxlen = sizeof(int),
53941 + .mode = 0644,
53942 + .child = NULL,
53943 + .proc_handler = &proc_dointvec,
53944 + },
53945 +
53946 + { .ctl_name = NET_IPSEC_DEBUG_MAST,
53947 + .procname = "debug_mast",
53948 + .data = &debug_mast,
53949 + .maxlen = sizeof(int),
53950 + .mode = 0644,
53951 + .child = NULL,
53952 + .proc_handler = &proc_dointvec,
53953 + },
53954 +
53955 + { .ctl_name = NET_IPSEC_DEBUG_TUNNEL,
53956 + .procname = "debug_tunnel",
53957 + .data = &debug_tunnel,
53958 + .maxlen = sizeof(int),
53959 + .mode = 0644,
53960 + .child = NULL,
53961 + .proc_handler = &proc_dointvec,
53962 + },
53963 +
53964 + { .ctl_name = NET_IPSEC_DEBUG_XMIT,
53965 + .procname = "debug_xmit",
53966 + .data = &debug_xmit,
53967 + .maxlen = sizeof(int),
53968 + .mode = 0644,
53969 + .child = NULL,
53970 + .proc_handler = &proc_dointvec,
53971 + },
53972 +
53973 + { .ctl_name = NET_IPSEC_DEBUG_EROUTE,
53974 + .procname = "debug_eroute",
53975 + .data = &debug_eroute,
53976 + .maxlen = sizeof(int),
53977 + .mode = 0644,
53978 + .child = NULL,
53979 + .proc_handler = &proc_dointvec,
53980 + },
53981 +
53982 + { .ctl_name = NET_IPSEC_DEBUG_SPI,
53983 + .procname = "debug_spi",
53984 + .data = &debug_spi,
53985 + .maxlen = sizeof(int),
53986 + .mode = 0644,
53987 + .child = NULL,
53988 + .proc_handler = &proc_dointvec,
53989 + },
53990 +
53991 + { .ctl_name = NET_IPSEC_DEBUG_RADIJ,
53992 + .procname = "debug_radij",
53993 + .data = &debug_radij,
53994 + .maxlen = sizeof(int),
53995 + .mode = 0644,
53996 + .child = NULL,
53997 + .proc_handler = &proc_dointvec,
53998 + },
53999 +
54000 + { .ctl_name = NET_IPSEC_DEBUG_NETLINK,
54001 + .procname = "debug_netlink",
54002 + .data = &debug_netlink,
54003 + .maxlen = sizeof(int),
54004 + .mode = 0644,
54005 + .child = NULL,
54006 + .proc_handler = &proc_dointvec,
54007 + },
54008 +
54009 + { .ctl_name = NET_IPSEC_DEBUG_XFORM,
54010 + .procname = "debug_xform",
54011 + .data = &debug_xform,
54012 + .maxlen = sizeof(int),
54013 + .mode = 0644,
54014 + .child = NULL,
54015 + .proc_handler = &proc_dointvec,
54016 + },
54017 +
54018 + { .ctl_name = NET_IPSEC_DEBUG_RCV,
54019 + .procname = "debug_rcv",
54020 + .data = &debug_rcv,
54021 + .maxlen = sizeof(int),
54022 + .mode = 0644,
54023 + .child = NULL,
54024 + .proc_handler = &proc_dointvec,
54025 + },
54026 +
54027 + { .ctl_name = NET_IPSEC_DEBUG_PFKEY,
54028 + .procname = "debug_pfkey",
54029 + .data = &debug_pfkey,
54030 + .maxlen = sizeof(int),
54031 + .mode = 0644,
54032 + .child = NULL,
54033 + .proc_handler = &proc_dointvec,
54034 + },
54035 +
54036 + { .ctl_name = NET_IPSEC_DEBUG_VERBOSE,
54037 + .procname = "debug_verbose",
54038 + .data = &sysctl_ipsec_debug_verbose,
54039 + .maxlen = sizeof(int),
54040 + .mode = 0644,
54041 + .child = NULL,
54042 + .proc_handler = &proc_dointvec,
54043 + },
54044 +#else
54045 + { NET_IPSEC_DEBUG_AH, "debug_ah", &debug_ah,
54046 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54047 + { NET_IPSEC_DEBUG_ESP, "debug_esp", &debug_esp,
54048 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54049 + { NET_IPSEC_DEBUG_MAST, "debug_mast", &debug_mast,
54050 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54051 + { NET_IPSEC_DEBUG_TUNNEL, "debug_tunnel", &debug_tunnel,
54052 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54053 + { NET_IPSEC_DEBUG_TUNNEL, "debug_xmit", &debug_xmit,
54054 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54055 + { NET_IPSEC_DEBUG_EROUTE, "debug_eroute", &debug_eroute,
54056 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54057 + { NET_IPSEC_DEBUG_SPI, "debug_spi", &debug_spi,
54058 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54059 + { NET_IPSEC_DEBUG_RADIJ, "debug_radij", &debug_radij,
54060 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54061 + { NET_IPSEC_DEBUG_NETLINK, "debug_netlink", &debug_netlink,
54062 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54063 + { NET_IPSEC_DEBUG_XFORM, "debug_xform", &debug_xform,
54064 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54065 + { NET_IPSEC_DEBUG_RCV, "debug_rcv", &debug_rcv,
54066 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54067 + { NET_IPSEC_DEBUG_PFKEY, "debug_pfkey", &debug_pfkey,
54068 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54069 + { NET_IPSEC_DEBUG_VERBOSE, "debug_verbose",&sysctl_ipsec_debug_verbose,
54070 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54071 +#endif /* CTL_TABLE_PARENT */
54072 +#endif /* CONFIG_KLIPS_DEBUG */
54073 +
54074 +#ifdef CONFIG_KLIPS_IPCOMP
54075 +#ifdef CTL_TABLE_PARENT
54076 + { .ctl_name = NET_IPSEC_DEBUG_IPCOMP,
54077 + .procname = "debug_ipcomp",
54078 + .data = &sysctl_ipsec_debug_ipcomp,
54079 + .maxlen = sizeof(int),
54080 + .mode = 0644,
54081 + .child = NULL,
54082 + .proc_handler = &proc_dointvec,
54083 + },
54084 +#else
54085 + { NET_IPSEC_DEBUG_IPCOMP, "debug_ipcomp", &sysctl_ipsec_debug_ipcomp,
54086 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54087 +#endif
54088 +#endif /* CONFIG_KLIPS_IPCOMP */
54089 +
54090 +#ifdef CONFIG_KLIPS_REGRESS
54091 +#ifdef CTL_TABLE_PARENT
54092 + {
54093 + .ctl_name = NET_IPSEC_REGRESS_PFKEY_LOSSAGE,
54094 + .procname = "pfkey_lossage",
54095 + .data = &sysctl_ipsec_regress_pfkey_lossage,
54096 + .maxlen = sizeof(int),
54097 + .mode = 0644,
54098 + .child = NULL,
54099 + .proc_handler = &proc_dointvec,
54100 + },
54101 +#else
54102 + { NET_IPSEC_REGRESS_PFKEY_LOSSAGE, "pfkey_lossage",
54103 + &sysctl_ipsec_regress_pfkey_lossage,
54104 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54105 +#endif /* CTL_TABLE_PARENT */
54106 +#endif /* CONFIG_KLIPS_REGRESS */
54107 +
54108 +#ifdef CTL_TABLE_PARENT
54109 + { .ctl_name = NET_IPSEC_ICMP,
54110 + .procname = "icmp",
54111 + .data = &sysctl_ipsec_icmp,
54112 + .maxlen = sizeof(int),
54113 + .mode = 0644,
54114 + .child = NULL,
54115 + .proc_handler = &proc_dointvec,
54116 + },
54117 +
54118 + { .ctl_name = NET_IPSEC_INBOUND_POLICY_CHECK,
54119 + .procname = "inbound_policy_check",
54120 + .data = &sysctl_ipsec_inbound_policy_check,
54121 + .maxlen = sizeof(int),
54122 + .mode = 0644,
54123 + .child = NULL,
54124 + .proc_handler = &proc_dointvec,
54125 + },
54126 +
54127 + { .ctl_name = NET_IPSEC_TOS,
54128 + .procname = "tos",
54129 + .data = &sysctl_ipsec_tos,
54130 + .maxlen = sizeof(int),
54131 + .mode = 0644,
54132 + .child = NULL,
54133 + .proc_handler = &proc_dointvec,
54134 + },
54135 + {0}
54136 +#else
54137 + { NET_IPSEC_ICMP, "icmp", &sysctl_ipsec_icmp,
54138 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54139 + { NET_IPSEC_INBOUND_POLICY_CHECK, "inbound_policy_check", &sysctl_ipsec_inbound_policy_check,
54140 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54141 + { NET_IPSEC_TOS, "tos", &sysctl_ipsec_tos,
54142 + sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
54143 + {0}
54144 +#endif
54145 +};
54146 +
54147 +static ctl_table ipsec_net_table[] = {
54148 +#ifdef CTL_TABLE_PARENT
54149 + { .ctl_name = NET_IPSEC,
54150 + .procname = "ipsec",
54151 + .data = NULL,
54152 + .maxlen = 0,
54153 + .mode = 0555,
54154 + .child = ipsec_table,
54155 + .proc_handler = NULL,
54156 + },
54157 + { 0 }
54158 +#else
54159 + { NET_IPSEC, "ipsec", NULL, 0, 0555, ipsec_table },
54160 + { 0 }
54161 +#endif
54162 +};
54163 +
54164 +static ctl_table ipsec_root_table[] = {
54165 +#ifdef CTL_TABLE_PARENT
54166 + { .ctl_name = CTL_NET,
54167 + .procname = "net",
54168 + .data = NULL,
54169 + .maxlen = 0,
54170 + .mode = 0555,
54171 + .child = ipsec_net_table,
54172 + .proc_handler = NULL,
54173 + },
54174 + { 0 }
54175 +#else
54176 + { CTL_NET, "net", NULL, 0, 0555, ipsec_net_table },
54177 + { 0 }
54178 +#endif
54179 +};
54180 +
54181 +static struct ctl_table_header *ipsec_table_header;
54182 +
54183 +int ipsec_sysctl_register(void)
54184 +{
54185 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
54186 + ipsec_table_header = register_sysctl_table(ipsec_root_table);
54187 +#else
54188 + ipsec_table_header = register_sysctl_table(ipsec_root_table, 0);
54189 +#endif
54190 + if (!ipsec_table_header) {
54191 + return -ENOMEM;
54192 + }
54193 + return 0;
54194 +}
54195 +
54196 +void ipsec_sysctl_unregister(void)
54197 +{
54198 + unregister_sysctl_table(ipsec_table_header);
54199 +}
54200 +
54201 +#endif /* CONFIG_SYSCTL */
54202 +
54203 +/*
54204 + *
54205 + * Local Variables:
54206 + * c-file-style: "linux"
54207 + * End:
54208 + *
54209 + */
54210 --- /dev/null Tue Mar 11 13:02:56 2003
54211 +++ linux/net/ipsec/trees.c Mon Feb 9 13:51:03 2004
54212 @@ -0,0 +1,1214 @@
54213 +/* trees.c -- output deflated data using Huffman coding
54214 + * Copyright (C) 1995-2002 Jean-loup Gailly
54215 + * For conditions of distribution and use, see copyright notice in zlib.h
54216 + */
54217 +
54218 +/*
54219 + * ALGORITHM
54220 + *
54221 + * The "deflation" process uses several Huffman trees. The more
54222 + * common source values are represented by shorter bit sequences.
54223 + *
54224 + * Each code tree is stored in a compressed form which is itself
54225 + * a Huffman encoding of the lengths of all the code strings (in
54226 + * ascending order by source values). The actual code strings are
54227 + * reconstructed from the lengths in the inflate process, as described
54228 + * in the deflate specification.
54229 + *
54230 + * REFERENCES
54231 + *
54232 + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
54233 + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
54234 + *
54235 + * Storer, James A.
54236 + * Data Compression: Methods and Theory, pp. 49-50.
54237 + * Computer Science Press, 1988. ISBN 0-7167-8156-5.
54238 + *
54239 + * Sedgewick, R.
54240 + * Algorithms, p290.
54241 + * Addison-Wesley, 1983. ISBN 0-201-06672-6.
54242 + */
54243 +
54244 +/* @(#) $Id: trees.c,v 1.4 2004/07/10 07:48:39 mcr Exp $ */
54245 +
54246 +/* #define GEN_TREES_H */
54247 +
54248 +#include "deflate.h"
54249 +
54250 +#ifdef DEBUG
54251 +# include <ctype.h>
54252 +#endif
54253 +
54254 +/* ===========================================================================
54255 + * Constants
54256 + */
54257 +
54258 +#define MAX_BL_BITS 7
54259 +/* Bit length codes must not exceed MAX_BL_BITS bits */
54260 +
54261 +#define END_BLOCK 256
54262 +/* end of block literal code */
54263 +
54264 +#define REP_3_6 16
54265 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */
54266 +
54267 +#define REPZ_3_10 17
54268 +/* repeat a zero length 3-10 times (3 bits of repeat count) */
54269 +
54270 +#define REPZ_11_138 18
54271 +/* repeat a zero length 11-138 times (7 bits of repeat count) */
54272 +
54273 +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
54274 + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
54275 +
54276 +local const int extra_dbits[D_CODES] /* extra bits for each distance code */
54277 + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
54278 +
54279 +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
54280 + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
54281 +
54282 +local const uch bl_order[BL_CODES]
54283 + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
54284 +/* The lengths of the bit length codes are sent in order of decreasing
54285 + * probability, to avoid transmitting the lengths for unused bit length codes.
54286 + */
54287 +
54288 +#define Buf_size (8 * 2*sizeof(char))
54289 +/* Number of bits used within bi_buf. (bi_buf might be implemented on
54290 + * more than 16 bits on some systems.)
54291 + */
54292 +
54293 +/* ===========================================================================
54294 + * Local data. These are initialized only once.
54295 + */
54296 +
54297 +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
54298 +
54299 +#if defined(GEN_TREES_H) || !defined(STDC)
54300 +/* non ANSI compilers may not accept trees.h */
54301 +
54302 +local ct_data static_ltree[L_CODES+2];
54303 +/* The static literal tree. Since the bit lengths are imposed, there is no
54304 + * need for the L_CODES extra codes used during heap construction. However
54305 + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
54306 + * below).
54307 + */
54308 +
54309 +local ct_data static_dtree[D_CODES];
54310 +/* The static distance tree. (Actually a trivial tree since all codes use
54311 + * 5 bits.)
54312 + */
54313 +
54314 +uch _dist_code[DIST_CODE_LEN];
54315 +/* Distance codes. The first 256 values correspond to the distances
54316 + * 3 .. 258, the last 256 values correspond to the top 8 bits of
54317 + * the 15 bit distances.
54318 + */
54319 +
54320 +uch _length_code[MAX_MATCH-MIN_MATCH+1];
54321 +/* length code for each normalized match length (0 == MIN_MATCH) */
54322 +
54323 +local int base_length[LENGTH_CODES];
54324 +/* First normalized length for each code (0 = MIN_MATCH) */
54325 +
54326 +local int base_dist[D_CODES];
54327 +/* First normalized distance for each code (0 = distance of 1) */
54328 +
54329 +#else
54330 +# include "trees.h"
54331 +#endif /* GEN_TREES_H */
54332 +
54333 +struct static_tree_desc_s {
54334 + const ct_data *static_tree; /* static tree or NULL */
54335 + const intf *extra_bits; /* extra bits for each code or NULL */
54336 + int extra_base; /* base index for extra_bits */
54337 + int elems; /* max number of elements in the tree */
54338 + int max_length; /* max bit length for the codes */
54339 +};
54340 +
54341 +local static_tree_desc static_l_desc =
54342 +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
54343 +
54344 +local static_tree_desc static_d_desc =
54345 +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
54346 +
54347 +local static_tree_desc static_bl_desc =
54348 +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
54349 +
54350 +/* ===========================================================================
54351 + * Local (static) routines in this file.
54352 + */
54353 +
54354 +local void tr_static_init OF((void));
54355 +local void init_block OF((deflate_state *s));
54356 +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
54357 +local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
54358 +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
54359 +local void build_tree OF((deflate_state *s, tree_desc *desc));
54360 +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
54361 +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
54362 +local int build_bl_tree OF((deflate_state *s));
54363 +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
54364 + int blcodes));
54365 +local void compress_block OF((deflate_state *s, const ct_data *ltree,
54366 + const ct_data *dtree));
54367 +local void set_data_type OF((deflate_state *s));
54368 +local unsigned bi_reverse OF((unsigned value, int length));
54369 +local void bi_windup OF((deflate_state *s));
54370 +local void bi_flush OF((deflate_state *s));
54371 +local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
54372 + int header));
54373 +
54374 +#ifdef GEN_TREES_H
54375 +local void gen_trees_header OF((void));
54376 +#endif
54377 +
54378 +#ifndef DEBUG
54379 +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
54380 + /* Send a code of the given tree. c and tree must not have side effects */
54381 +
54382 +#else /* DEBUG */
54383 +# define send_code(s, c, tree) \
54384 + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
54385 + send_bits(s, tree[c].Code, tree[c].Len); }
54386 +#endif
54387 +
54388 +/* ===========================================================================
54389 + * Output a short LSB first on the stream.
54390 + * IN assertion: there is enough room in pendingBuf.
54391 + */
54392 +#define put_short(s, w) { \
54393 + put_byte(s, (uch)((w) & 0xff)); \
54394 + put_byte(s, (uch)((ush)(w) >> 8)); \
54395 +}
54396 +
54397 +/* ===========================================================================
54398 + * Send a value on a given number of bits.
54399 + * IN assertion: length <= 16 and value fits in length bits.
54400 + */
54401 +#ifdef DEBUG
54402 +local void send_bits OF((deflate_state *s, int value, int length));
54403 +
54404 +local void send_bits(s, value, length)
54405 + deflate_state *s;
54406 + int value; /* value to send */
54407 + int length; /* number of bits */
54408 +{
54409 + Tracevv((stderr," l %2d v %4x ", length, value));
54410 + Assert(length > 0 && length <= 15, "invalid length");
54411 + s->bits_sent += (ulg)length;
54412 +
54413 + /* If not enough room in bi_buf, use (valid) bits from bi_buf and
54414 + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
54415 + * unused bits in value.
54416 + */
54417 + if (s->bi_valid > (int)Buf_size - length) {
54418 + s->bi_buf |= (value << s->bi_valid);
54419 + put_short(s, s->bi_buf);
54420 + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
54421 + s->bi_valid += length - Buf_size;
54422 + } else {
54423 + s->bi_buf |= value << s->bi_valid;
54424 + s->bi_valid += length;
54425 + }
54426 +}
54427 +#else /* !DEBUG */
54428 +
54429 +#define send_bits(s, value, length) \
54430 +{ int len = length;\
54431 + if (s->bi_valid > (int)Buf_size - len) {\
54432 + int val = value;\
54433 + s->bi_buf |= (val << s->bi_valid);\
54434 + put_short(s, s->bi_buf);\
54435 + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
54436 + s->bi_valid += len - Buf_size;\
54437 + } else {\
54438 + s->bi_buf |= (value) << s->bi_valid;\
54439 + s->bi_valid += len;\
54440 + }\
54441 +}
54442 +#endif /* DEBUG */
54443 +
54444 +
54445 +#define MAX(a,b) (a >= b ? a : b)
54446 +/* the arguments must not have side effects */
54447 +
54448 +/* ===========================================================================
54449 + * Initialize the various 'constant' tables.
54450 + */
54451 +local void tr_static_init()
54452 +{
54453 +#if defined(GEN_TREES_H) || !defined(STDC)
54454 + static int static_init_done = 0;
54455 + int n; /* iterates over tree elements */
54456 + int bits; /* bit counter */
54457 + int length; /* length value */
54458 + int code; /* code value */
54459 + int dist; /* distance index */
54460 + ush bl_count[MAX_BITS+1];
54461 + /* number of codes at each bit length for an optimal tree */
54462 +
54463 + if (static_init_done) return;
54464 +
54465 + /* For some embedded targets, global variables are not initialized: */
54466 + static_l_desc.static_tree = static_ltree;
54467 + static_l_desc.extra_bits = extra_lbits;
54468 + static_d_desc.static_tree = static_dtree;
54469 + static_d_desc.extra_bits = extra_dbits;
54470 + static_bl_desc.extra_bits = extra_blbits;
54471 +
54472 + /* Initialize the mapping length (0..255) -> length code (0..28) */
54473 + length = 0;
54474 + for (code = 0; code < LENGTH_CODES-1; code++) {
54475 + base_length[code] = length;
54476 + for (n = 0; n < (1<<extra_lbits[code]); n++) {
54477 + _length_code[length++] = (uch)code;
54478 + }
54479 + }
54480 + Assert (length == 256, "tr_static_init: length != 256");
54481 + /* Note that the length 255 (match length 258) can be represented
54482 + * in two different ways: code 284 + 5 bits or code 285, so we
54483 + * overwrite length_code[255] to use the best encoding:
54484 + */
54485 + _length_code[length-1] = (uch)code;
54486 +
54487 + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
54488 + dist = 0;
54489 + for (code = 0 ; code < 16; code++) {
54490 + base_dist[code] = dist;
54491 + for (n = 0; n < (1<<extra_dbits[code]); n++) {
54492 + _dist_code[dist++] = (uch)code;
54493 + }
54494 + }
54495 + Assert (dist == 256, "tr_static_init: dist != 256");
54496 + dist >>= 7; /* from now on, all distances are divided by 128 */
54497 + for ( ; code < D_CODES; code++) {
54498 + base_dist[code] = dist << 7;
54499 + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
54500 + _dist_code[256 + dist++] = (uch)code;
54501 + }
54502 + }
54503 + Assert (dist == 256, "tr_static_init: 256+dist != 512");
54504 +
54505 + /* Construct the codes of the static literal tree */
54506 + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
54507 + n = 0;
54508 + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
54509 + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
54510 + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
54511 + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
54512 + /* Codes 286 and 287 do not exist, but we must include them in the
54513 + * tree construction to get a canonical Huffman tree (longest code
54514 + * all ones)
54515 + */
54516 + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
54517 +
54518 + /* The static distance tree is trivial: */
54519 + for (n = 0; n < D_CODES; n++) {
54520 + static_dtree[n].Len = 5;
54521 + static_dtree[n].Code = bi_reverse((unsigned)n, 5);
54522 + }
54523 + static_init_done = 1;
54524 +
54525 +# ifdef GEN_TREES_H
54526 + gen_trees_header();
54527 +# endif
54528 +#endif /* defined(GEN_TREES_H) || !defined(STDC) */
54529 +}
54530 +
54531 +/* ===========================================================================
54532 + * Genererate the file trees.h describing the static trees.
54533 + */
54534 +#ifdef GEN_TREES_H
54535 +# ifndef DEBUG
54536 +# include <stdio.h>
54537 +# endif
54538 +
54539 +# define SEPARATOR(i, last, width) \
54540 + ((i) == (last)? "\n};\n\n" : \
54541 + ((i) % (width) == (width)-1 ? ",\n" : ", "))
54542 +
54543 +void gen_trees_header()
54544 +{
54545 + FILE *header = fopen("trees.h", "w");
54546 + int i;
54547 +
54548 + Assert (header != NULL, "Can't open trees.h");
54549 + fprintf(header,
54550 + "/* header created automatically with -DGEN_TREES_H */\n\n");
54551 +
54552 + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
54553 + for (i = 0; i < L_CODES+2; i++) {
54554 + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
54555 + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
54556 + }
54557 +
54558 + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
54559 + for (i = 0; i < D_CODES; i++) {
54560 + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
54561 + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
54562 + }
54563 +
54564 + fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
54565 + for (i = 0; i < DIST_CODE_LEN; i++) {
54566 + fprintf(header, "%2u%s", _dist_code[i],
54567 + SEPARATOR(i, DIST_CODE_LEN-1, 20));
54568 + }
54569 +
54570 + fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
54571 + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
54572 + fprintf(header, "%2u%s", _length_code[i],
54573 + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
54574 + }
54575 +
54576 + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
54577 + for (i = 0; i < LENGTH_CODES; i++) {
54578 + fprintf(header, "%1u%s", base_length[i],
54579 + SEPARATOR(i, LENGTH_CODES-1, 20));
54580 + }
54581 +
54582 + fprintf(header, "local const int base_dist[D_CODES] = {\n");
54583 + for (i = 0; i < D_CODES; i++) {
54584 + fprintf(header, "%5u%s", base_dist[i],
54585 + SEPARATOR(i, D_CODES-1, 10));
54586 + }
54587 +
54588 + fclose(header);
54589 +}
54590 +#endif /* GEN_TREES_H */
54591 +
54592 +/* ===========================================================================
54593 + * Initialize the tree data structures for a new zlib stream.
54594 + */
54595 +void _tr_init(s)
54596 + deflate_state *s;
54597 +{
54598 + tr_static_init();
54599 +
54600 + s->l_desc.dyn_tree = s->dyn_ltree;
54601 + s->l_desc.stat_desc = &static_l_desc;
54602 +
54603 + s->d_desc.dyn_tree = s->dyn_dtree;
54604 + s->d_desc.stat_desc = &static_d_desc;
54605 +
54606 + s->bl_desc.dyn_tree = s->bl_tree;
54607 + s->bl_desc.stat_desc = &static_bl_desc;
54608 +
54609 + s->bi_buf = 0;
54610 + s->bi_valid = 0;
54611 + s->last_eob_len = 8; /* enough lookahead for inflate */
54612 +#ifdef DEBUG
54613 + s->compressed_len = 0L;
54614 + s->bits_sent = 0L;
54615 +#endif
54616 +
54617 + /* Initialize the first block of the first file: */
54618 + init_block(s);
54619 +}
54620 +
54621 +/* ===========================================================================
54622 + * Initialize a new block.
54623 + */
54624 +local void init_block(s)
54625 + deflate_state *s;
54626 +{
54627 + int n; /* iterates over tree elements */
54628 +
54629 + /* Initialize the trees. */
54630 + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
54631 + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
54632 + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
54633 +
54634 + s->dyn_ltree[END_BLOCK].Freq = 1;
54635 + s->opt_len = s->static_len = 0L;
54636 + s->last_lit = s->matches = 0;
54637 +}
54638 +
54639 +#define SMALLEST 1
54640 +/* Index within the heap array of least frequent node in the Huffman tree */
54641 +
54642 +
54643 +/* ===========================================================================
54644 + * Remove the smallest element from the heap and recreate the heap with
54645 + * one less element. Updates heap and heap_len.
54646 + */
54647 +#define pqremove(s, tree, top) \
54648 +{\
54649 + top = s->heap[SMALLEST]; \
54650 + s->heap[SMALLEST] = s->heap[s->heap_len--]; \
54651 + pqdownheap(s, tree, SMALLEST); \
54652 +}
54653 +
54654 +/* ===========================================================================
54655 + * Compares to subtrees, using the tree depth as tie breaker when
54656 + * the subtrees have equal frequency. This minimizes the worst case length.
54657 + */
54658 +#define smaller(tree, n, m, depth) \
54659 + (tree[n].Freq < tree[m].Freq || \
54660 + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
54661 +
54662 +/* ===========================================================================
54663 + * Restore the heap property by moving down the tree starting at node k,
54664 + * exchanging a node with the smallest of its two sons if necessary, stopping
54665 + * when the heap property is re-established (each father smaller than its
54666 + * two sons).
54667 + */
54668 +local void pqdownheap(s, tree, k)
54669 + deflate_state *s;
54670 + ct_data *tree; /* the tree to restore */
54671 + int k; /* node to move down */
54672 +{
54673 + int v = s->heap[k];
54674 + int j = k << 1; /* left son of k */
54675 + while (j <= s->heap_len) {
54676 + /* Set j to the smallest of the two sons: */
54677 + if (j < s->heap_len &&
54678 + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
54679 + j++;
54680 + }
54681 + /* Exit if v is smaller than both sons */
54682 + if (smaller(tree, v, s->heap[j], s->depth)) break;
54683 +
54684 + /* Exchange v with the smallest son */
54685 + s->heap[k] = s->heap[j]; k = j;
54686 +
54687 + /* And continue down the tree, setting j to the left son of k */
54688 + j <<= 1;
54689 + }
54690 + s->heap[k] = v;
54691 +}
54692 +
54693 +/* ===========================================================================
54694 + * Compute the optimal bit lengths for a tree and update the total bit length
54695 + * for the current block.
54696 + * IN assertion: the fields freq and dad are set, heap[heap_max] and
54697 + * above are the tree nodes sorted by increasing frequency.
54698 + * OUT assertions: the field len is set to the optimal bit length, the
54699 + * array bl_count contains the frequencies for each bit length.
54700 + * The length opt_len is updated; static_len is also updated if stree is
54701 + * not null.
54702 + */
54703 +local void gen_bitlen(s, desc)
54704 + deflate_state *s;
54705 + tree_desc *desc; /* the tree descriptor */
54706 +{
54707 + ct_data *tree = desc->dyn_tree;
54708 + int max_code = desc->max_code;
54709 + const ct_data *stree = desc->stat_desc->static_tree;
54710 + const intf *extra = desc->stat_desc->extra_bits;
54711 + int base = desc->stat_desc->extra_base;
54712 + int max_length = desc->stat_desc->max_length;
54713 + int h; /* heap index */
54714 + int n, m; /* iterate over the tree elements */
54715 + int bits; /* bit length */
54716 + int xbits; /* extra bits */
54717 + ush f; /* frequency */
54718 + int overflow = 0; /* number of elements with bit length too large */
54719 +
54720 + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
54721 +
54722 + /* In a first pass, compute the optimal bit lengths (which may
54723 + * overflow in the case of the bit length tree).
54724 + */
54725 + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
54726 +
54727 + for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
54728 + n = s->heap[h];
54729 + bits = tree[tree[n].Dad].Len + 1;
54730 + if (bits > max_length) bits = max_length, overflow++;
54731 + tree[n].Len = (ush)bits;
54732 + /* We overwrite tree[n].Dad which is no longer needed */
54733 +
54734 + if (n > max_code) continue; /* not a leaf node */
54735 +
54736 + s->bl_count[bits]++;
54737 + xbits = 0;
54738 + if (n >= base) xbits = extra[n-base];
54739 + f = tree[n].Freq;
54740 + s->opt_len += (ulg)f * (bits + xbits);
54741 + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
54742 + }
54743 + if (overflow == 0) return;
54744 +
54745 + Trace((stderr,"\nbit length overflow\n"));
54746 + /* This happens for example on obj2 and pic of the Calgary corpus */
54747 +
54748 + /* Find the first bit length which could increase: */
54749 + do {
54750 + bits = max_length-1;
54751 + while (s->bl_count[bits] == 0) bits--;
54752 + s->bl_count[bits]--; /* move one leaf down the tree */
54753 + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
54754 + s->bl_count[max_length]--;
54755 + /* The brother of the overflow item also moves one step up,
54756 + * but this does not affect bl_count[max_length]
54757 + */
54758 + overflow -= 2;
54759 + } while (overflow > 0);
54760 +
54761 + /* Now recompute all bit lengths, scanning in increasing frequency.
54762 + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
54763 + * lengths instead of fixing only the wrong ones. This idea is taken
54764 + * from 'ar' written by Haruhiko Okumura.)
54765 + */
54766 + for (bits = max_length; bits != 0; bits--) {
54767 + n = s->bl_count[bits];
54768 + while (n != 0) {
54769 + m = s->heap[--h];
54770 + if (m > max_code) continue;
54771 + if (tree[m].Len != (unsigned) bits) {
54772 + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
54773 + s->opt_len += ((long)bits - (long)tree[m].Len)
54774 + *(long)tree[m].Freq;
54775 + tree[m].Len = (ush)bits;
54776 + }
54777 + n--;
54778 + }
54779 + }
54780 +}
54781 +
54782 +/* ===========================================================================
54783 + * Generate the codes for a given tree and bit counts (which need not be
54784 + * optimal).
54785 + * IN assertion: the array bl_count contains the bit length statistics for
54786 + * the given tree and the field len is set for all tree elements.
54787 + * OUT assertion: the field code is set for all tree elements of non
54788 + * zero code length.
54789 + */
54790 +local void gen_codes (tree, max_code, bl_count)
54791 + ct_data *tree; /* the tree to decorate */
54792 + int max_code; /* largest code with non zero frequency */
54793 + ushf *bl_count; /* number of codes at each bit length */
54794 +{
54795 + ush next_code[MAX_BITS+1]; /* next code value for each bit length */
54796 + ush code = 0; /* running code value */
54797 + int bits; /* bit index */
54798 + int n; /* code index */
54799 +
54800 + /* The distribution counts are first used to generate the code values
54801 + * without bit reversal.
54802 + */
54803 + for (bits = 1; bits <= MAX_BITS; bits++) {
54804 + next_code[bits] = code = (code + bl_count[bits-1]) << 1;
54805 + }
54806 + /* Check that the bit counts in bl_count are consistent. The last code
54807 + * must be all ones.
54808 + */
54809 + Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
54810 + "inconsistent bit counts");
54811 + Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
54812 +
54813 + for (n = 0; n <= max_code; n++) {
54814 + int len = tree[n].Len;
54815 + if (len == 0) continue;
54816 + /* Now reverse the bits */
54817 + tree[n].Code = bi_reverse(next_code[len]++, len);
54818 +
54819 + Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
54820 + n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
54821 + }
54822 +}
54823 +
54824 +/* ===========================================================================
54825 + * Construct one Huffman tree and assigns the code bit strings and lengths.
54826 + * Update the total bit length for the current block.
54827 + * IN assertion: the field freq is set for all tree elements.
54828 + * OUT assertions: the fields len and code are set to the optimal bit length
54829 + * and corresponding code. The length opt_len is updated; static_len is
54830 + * also updated if stree is not null. The field max_code is set.
54831 + */
54832 +local void build_tree(s, desc)
54833 + deflate_state *s;
54834 + tree_desc *desc; /* the tree descriptor */
54835 +{
54836 + ct_data *tree = desc->dyn_tree;
54837 + const ct_data *stree = desc->stat_desc->static_tree;
54838 + int elems = desc->stat_desc->elems;
54839 + int n, m; /* iterate over heap elements */
54840 + int max_code = -1; /* largest code with non zero frequency */
54841 + int node; /* new node being created */
54842 +
54843 + /* Construct the initial heap, with least frequent element in
54844 + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
54845 + * heap[0] is not used.
54846 + */
54847 + s->heap_len = 0, s->heap_max = HEAP_SIZE;
54848 +
54849 + for (n = 0; n < elems; n++) {
54850 + if (tree[n].Freq != 0) {
54851 + s->heap[++(s->heap_len)] = max_code = n;
54852 + s->depth[n] = 0;
54853 + } else {
54854 + tree[n].Len = 0;
54855 + }
54856 + }
54857 +
54858 + /* The pkzip format requires that at least one distance code exists,
54859 + * and that at least one bit should be sent even if there is only one
54860 + * possible code. So to avoid special checks later on we force at least
54861 + * two codes of non zero frequency.
54862 + */
54863 + while (s->heap_len < 2) {
54864 + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
54865 + tree[node].Freq = 1;
54866 + s->depth[node] = 0;
54867 + s->opt_len--; if (stree) s->static_len -= stree[node].Len;
54868 + /* node is 0 or 1 so it does not have extra bits */
54869 + }
54870 + desc->max_code = max_code;
54871 +
54872 + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
54873 + * establish sub-heaps of increasing lengths:
54874 + */
54875 + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
54876 +
54877 + /* Construct the Huffman tree by repeatedly combining the least two
54878 + * frequent nodes.
54879 + */
54880 + node = elems; /* next internal node of the tree */
54881 + do {
54882 + pqremove(s, tree, n); /* n = node of least frequency */
54883 + m = s->heap[SMALLEST]; /* m = node of next least frequency */
54884 +
54885 + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
54886 + s->heap[--(s->heap_max)] = m;
54887 +
54888 + /* Create a new node father of n and m */
54889 + tree[node].Freq = tree[n].Freq + tree[m].Freq;
54890 + s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
54891 + tree[n].Dad = tree[m].Dad = (ush)node;
54892 +#ifdef DUMP_BL_TREE
54893 + if (tree == s->bl_tree) {
54894 + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
54895 + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
54896 + }
54897 +#endif
54898 + /* and insert the new node in the heap */
54899 + s->heap[SMALLEST] = node++;
54900 + pqdownheap(s, tree, SMALLEST);
54901 +
54902 + } while (s->heap_len >= 2);
54903 +
54904 + s->heap[--(s->heap_max)] = s->heap[SMALLEST];
54905 +
54906 + /* At this point, the fields freq and dad are set. We can now
54907 + * generate the bit lengths.
54908 + */
54909 + gen_bitlen(s, (tree_desc *)desc);
54910 +
54911 + /* The field len is now set, we can generate the bit codes */
54912 + gen_codes ((ct_data *)tree, max_code, s->bl_count);
54913 +}
54914 +
54915 +/* ===========================================================================
54916 + * Scan a literal or distance tree to determine the frequencies of the codes
54917 + * in the bit length tree.
54918 + */
54919 +local void scan_tree (s, tree, max_code)
54920 + deflate_state *s;
54921 + ct_data *tree; /* the tree to be scanned */
54922 + int max_code; /* and its largest code of non zero frequency */
54923 +{
54924 + int n; /* iterates over all tree elements */
54925 + int prevlen = -1; /* last emitted length */
54926 + int curlen; /* length of current code */
54927 + int nextlen = tree[0].Len; /* length of next code */
54928 + int count = 0; /* repeat count of the current code */
54929 + int max_count = 7; /* max repeat count */
54930 + int min_count = 4; /* min repeat count */
54931 +
54932 + if (nextlen == 0) max_count = 138, min_count = 3;
54933 + tree[max_code+1].Len = (ush)0xffff; /* guard */
54934 +
54935 + for (n = 0; n <= max_code; n++) {
54936 + curlen = nextlen; nextlen = tree[n+1].Len;
54937 + if (++count < max_count && curlen == nextlen) {
54938 + continue;
54939 + } else if (count < min_count) {
54940 + s->bl_tree[curlen].Freq += count;
54941 + } else if (curlen != 0) {
54942 + if (curlen != prevlen) s->bl_tree[curlen].Freq++;
54943 + s->bl_tree[REP_3_6].Freq++;
54944 + } else if (count <= 10) {
54945 + s->bl_tree[REPZ_3_10].Freq++;
54946 + } else {
54947 + s->bl_tree[REPZ_11_138].Freq++;
54948 + }
54949 + count = 0; prevlen = curlen;
54950 + if (nextlen == 0) {
54951 + max_count = 138, min_count = 3;
54952 + } else if (curlen == nextlen) {
54953 + max_count = 6, min_count = 3;
54954 + } else {
54955 + max_count = 7, min_count = 4;
54956 + }
54957 + }
54958 +}
54959 +
54960 +/* ===========================================================================
54961 + * Send a literal or distance tree in compressed form, using the codes in
54962 + * bl_tree.
54963 + */
54964 +local void send_tree (s, tree, max_code)
54965 + deflate_state *s;
54966 + ct_data *tree; /* the tree to be scanned */
54967 + int max_code; /* and its largest code of non zero frequency */
54968 +{
54969 + int n; /* iterates over all tree elements */
54970 + int prevlen = -1; /* last emitted length */
54971 + int curlen; /* length of current code */
54972 + int nextlen = tree[0].Len; /* length of next code */
54973 + int count = 0; /* repeat count of the current code */
54974 + int max_count = 7; /* max repeat count */
54975 + int min_count = 4; /* min repeat count */
54976 +
54977 + /* tree[max_code+1].Len = -1; */ /* guard already set */
54978 + if (nextlen == 0) max_count = 138, min_count = 3;
54979 +
54980 + for (n = 0; n <= max_code; n++) {
54981 + curlen = nextlen; nextlen = tree[n+1].Len;
54982 + if (++count < max_count && curlen == nextlen) {
54983 + continue;
54984 + } else if (count < min_count) {
54985 + do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
54986 +
54987 + } else if (curlen != 0) {
54988 + if (curlen != prevlen) {
54989 + send_code(s, curlen, s->bl_tree); count--;
54990 + }
54991 + Assert(count >= 3 && count <= 6, " 3_6?");
54992 + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
54993 +
54994 + } else if (count <= 10) {
54995 + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
54996 +
54997 + } else {
54998 + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
54999 + }
55000 + count = 0; prevlen = curlen;
55001 + if (nextlen == 0) {
55002 + max_count = 138, min_count = 3;
55003 + } else if (curlen == nextlen) {
55004 + max_count = 6, min_count = 3;
55005 + } else {
55006 + max_count = 7, min_count = 4;
55007 + }
55008 + }
55009 +}
55010 +
55011 +/* ===========================================================================
55012 + * Construct the Huffman tree for the bit lengths and return the index in
55013 + * bl_order of the last bit length code to send.
55014 + */
55015 +local int build_bl_tree(s)
55016 + deflate_state *s;
55017 +{
55018 + int max_blindex; /* index of last bit length code of non zero freq */
55019 +
55020 + /* Determine the bit length frequencies for literal and distance trees */
55021 + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
55022 + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
55023 +
55024 + /* Build the bit length tree: */
55025 + build_tree(s, (tree_desc *)(&(s->bl_desc)));
55026 + /* opt_len now includes the length of the tree representations, except
55027 + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
55028 + */
55029 +
55030 + /* Determine the number of bit length codes to send. The pkzip format
55031 + * requires that at least 4 bit length codes be sent. (appnote.txt says
55032 + * 3 but the actual value used is 4.)
55033 + */
55034 + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
55035 + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
55036 + }
55037 + /* Update opt_len to include the bit length tree and counts */
55038 + s->opt_len += 3*(max_blindex+1) + 5+5+4;
55039 + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
55040 + s->opt_len, s->static_len));
55041 +
55042 + return max_blindex;
55043 +}
55044 +
55045 +/* ===========================================================================
55046 + * Send the header for a block using dynamic Huffman trees: the counts, the
55047 + * lengths of the bit length codes, the literal tree and the distance tree.
55048 + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
55049 + */
55050 +local void send_all_trees(s, lcodes, dcodes, blcodes)
55051 + deflate_state *s;
55052 + int lcodes, dcodes, blcodes; /* number of codes for each tree */
55053 +{
55054 + int rank; /* index in bl_order */
55055 +
55056 + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
55057 + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
55058 + "too many codes");
55059 + Tracev((stderr, "\nbl counts: "));
55060 + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
55061 + send_bits(s, dcodes-1, 5);
55062 + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
55063 + for (rank = 0; rank < blcodes; rank++) {
55064 + Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
55065 + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
55066 + }
55067 + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
55068 +
55069 + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
55070 + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
55071 +
55072 + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
55073 + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
55074 +}
55075 +
55076 +/* ===========================================================================
55077 + * Send a stored block
55078 + */
55079 +void _tr_stored_block(s, buf, stored_len, eof)
55080 + deflate_state *s;
55081 + charf *buf; /* input block */
55082 + ulg stored_len; /* length of input block */
55083 + int eof; /* true if this is the last block for a file */
55084 +{
55085 + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
55086 +#ifdef DEBUG
55087 + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
55088 + s->compressed_len += (stored_len + 4) << 3;
55089 +#endif
55090 + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
55091 +}
55092 +
55093 +/* ===========================================================================
55094 + * Send one empty static block to give enough lookahead for inflate.
55095 + * This takes 10 bits, of which 7 may remain in the bit buffer.
55096 + * The current inflate code requires 9 bits of lookahead. If the
55097 + * last two codes for the previous block (real code plus EOB) were coded
55098 + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
55099 + * the last real code. In this case we send two empty static blocks instead
55100 + * of one. (There are no problems if the previous block is stored or fixed.)
55101 + * To simplify the code, we assume the worst case of last real code encoded
55102 + * on one bit only.
55103 + */
55104 +void _tr_align(s)
55105 + deflate_state *s;
55106 +{
55107 + send_bits(s, STATIC_TREES<<1, 3);
55108 + send_code(s, END_BLOCK, static_ltree);
55109 +#ifdef DEBUG
55110 + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
55111 +#endif
55112 + bi_flush(s);
55113 + /* Of the 10 bits for the empty block, we have already sent
55114 + * (10 - bi_valid) bits. The lookahead for the last real code (before
55115 + * the EOB of the previous block) was thus at least one plus the length
55116 + * of the EOB plus what we have just sent of the empty static block.
55117 + */
55118 + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
55119 + send_bits(s, STATIC_TREES<<1, 3);
55120 + send_code(s, END_BLOCK, static_ltree);
55121 +#ifdef DEBUG
55122 + s->compressed_len += 10L;
55123 +#endif
55124 + bi_flush(s);
55125 + }
55126 + s->last_eob_len = 7;
55127 +}
55128 +
55129 +/* ===========================================================================
55130 + * Determine the best encoding for the current block: dynamic trees, static
55131 + * trees or store, and output the encoded block to the zip file.
55132 + */
55133 +void _tr_flush_block(s, buf, stored_len, eof)
55134 + deflate_state *s;
55135 + charf *buf; /* input block, or NULL if too old */
55136 + ulg stored_len; /* length of input block */
55137 + int eof; /* true if this is the last block for a file */
55138 +{
55139 + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
55140 + int max_blindex = 0; /* index of last bit length code of non zero freq */
55141 +
55142 + /* Build the Huffman trees unless a stored block is forced */
55143 + if (s->level > 0) {
55144 +
55145 + /* Check if the file is ascii or binary */
55146 + if (s->data_type == Z_UNKNOWN) set_data_type(s);
55147 +
55148 + /* Construct the literal and distance trees */
55149 + build_tree(s, (tree_desc *)(&(s->l_desc)));
55150 + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
55151 + s->static_len));
55152 +
55153 + build_tree(s, (tree_desc *)(&(s->d_desc)));
55154 + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
55155 + s->static_len));
55156 + /* At this point, opt_len and static_len are the total bit lengths of
55157 + * the compressed block data, excluding the tree representations.
55158 + */
55159 +
55160 + /* Build the bit length tree for the above two trees, and get the index
55161 + * in bl_order of the last bit length code to send.
55162 + */
55163 + max_blindex = build_bl_tree(s);
55164 +
55165 + /* Determine the best encoding. Compute first the block length in bytes*/
55166 + opt_lenb = (s->opt_len+3+7)>>3;
55167 + static_lenb = (s->static_len+3+7)>>3;
55168 +
55169 + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
55170 + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
55171 + s->last_lit));
55172 +
55173 + if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
55174 +
55175 + } else {
55176 + Assert(buf != (char*)0, "lost buf");
55177 + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
55178 + }
55179 +
55180 +#ifdef FORCE_STORED
55181 + if (buf != (char*)0) { /* force stored block */
55182 +#else
55183 + if (stored_len+4 <= opt_lenb && buf != (char*)0) {
55184 + /* 4: two words for the lengths */
55185 +#endif
55186 + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
55187 + * Otherwise we can't have processed more than WSIZE input bytes since
55188 + * the last block flush, because compression would have been
55189 + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
55190 + * transform a block into a stored block.
55191 + */
55192 + _tr_stored_block(s, buf, stored_len, eof);
55193 +
55194 +#ifdef FORCE_STATIC
55195 + } else if (static_lenb >= 0) { /* force static trees */
55196 +#else
55197 + } else if (static_lenb == opt_lenb) {
55198 +#endif
55199 + send_bits(s, (STATIC_TREES<<1)+eof, 3);
55200 + compress_block(s, static_ltree, static_dtree);
55201 +#ifdef DEBUG
55202 + s->compressed_len += 3 + s->static_len;
55203 +#endif
55204 + } else {
55205 + send_bits(s, (DYN_TREES<<1)+eof, 3);
55206 + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
55207 + max_blindex+1);
55208 + compress_block(s, s->dyn_ltree, s->dyn_dtree);
55209 +#ifdef DEBUG
55210 + s->compressed_len += 3 + s->opt_len;
55211 +#endif
55212 + }
55213 + Assert (s->compressed_len == s->bits_sent, "bad compressed size");
55214 + /* The above check is made mod 2^32, for files larger than 512 MB
55215 + * and uLong implemented on 32 bits.
55216 + */
55217 + init_block(s);
55218 +
55219 + if (eof) {
55220 + bi_windup(s);
55221 +#ifdef DEBUG
55222 + s->compressed_len += 7; /* align on byte boundary */
55223 +#endif
55224 + }
55225 + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
55226 + s->compressed_len-7*eof));
55227 +}
55228 +
55229 +/* ===========================================================================
55230 + * Save the match info and tally the frequency counts. Return true if
55231 + * the current block must be flushed.
55232 + */
55233 +int _tr_tally (s, dist, lc)
55234 + deflate_state *s;
55235 + unsigned dist; /* distance of matched string */
55236 + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
55237 +{
55238 + s->d_buf[s->last_lit] = (ush)dist;
55239 + s->l_buf[s->last_lit++] = (uch)lc;
55240 + if (dist == 0) {
55241 + /* lc is the unmatched char */
55242 + s->dyn_ltree[lc].Freq++;
55243 + } else {
55244 + s->matches++;
55245 + /* Here, lc is the match length - MIN_MATCH */
55246 + dist--; /* dist = match distance - 1 */
55247 + Assert((ush)dist < (ush)MAX_DIST(s) &&
55248 + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
55249 + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
55250 +
55251 + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
55252 + s->dyn_dtree[d_code(dist)].Freq++;
55253 + }
55254 +
55255 +#ifdef TRUNCATE_BLOCK
55256 + /* Try to guess if it is profitable to stop the current block here */
55257 + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
55258 + /* Compute an upper bound for the compressed length */
55259 + ulg out_length = (ulg)s->last_lit*8L;
55260 + ulg in_length = (ulg)((long)s->strstart - s->block_start);
55261 + int dcode;
55262 + for (dcode = 0; dcode < D_CODES; dcode++) {
55263 + out_length += (ulg)s->dyn_dtree[dcode].Freq *
55264 + (5L+extra_dbits[dcode]);
55265 + }
55266 + out_length >>= 3;
55267 + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
55268 + s->last_lit, in_length, out_length,
55269 + 100L - out_length*100L/in_length));
55270 + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
55271 + }
55272 +#endif
55273 + return (s->last_lit == s->lit_bufsize-1);
55274 + /* We avoid equality with lit_bufsize because of wraparound at 64K
55275 + * on 16 bit machines and because stored blocks are restricted to
55276 + * 64K-1 bytes.
55277 + */
55278 +}
55279 +
55280 +/* ===========================================================================
55281 + * Send the block data compressed using the given Huffman trees
55282 + */
55283 +local void compress_block(s, ltree, dtree)
55284 + deflate_state *s;
55285 + const ct_data *ltree; /* literal tree */
55286 + const ct_data *dtree; /* distance tree */
55287 +{
55288 + unsigned dist; /* distance of matched string */
55289 + int lc; /* match length or unmatched char (if dist == 0) */
55290 + unsigned lx = 0; /* running index in l_buf */
55291 + unsigned code; /* the code to send */
55292 + int extra; /* number of extra bits to send */
55293 +
55294 + if (s->last_lit != 0) do {
55295 + dist = s->d_buf[lx];
55296 + lc = s->l_buf[lx++];
55297 + if (dist == 0) {
55298 + send_code(s, lc, ltree); /* send a literal byte */
55299 + Tracecv(isgraph(lc), (stderr," '%c' ", lc));
55300 + } else {
55301 + /* Here, lc is the match length - MIN_MATCH */
55302 + code = _length_code[lc];
55303 + send_code(s, code+LITERALS+1, ltree); /* send the length code */
55304 + extra = extra_lbits[code];
55305 + if (extra != 0) {
55306 + lc -= base_length[code];
55307 + send_bits(s, lc, extra); /* send the extra length bits */
55308 + }
55309 + dist--; /* dist is now the match distance - 1 */
55310 + code = d_code(dist);
55311 + Assert (code < D_CODES, "bad d_code");
55312 +
55313 + send_code(s, code, dtree); /* send the distance code */
55314 + extra = extra_dbits[code];
55315 + if (extra != 0) {
55316 + dist -= base_dist[code];
55317 + send_bits(s, dist, extra); /* send the extra distance bits */
55318 + }
55319 + } /* literal or match pair ? */
55320 +
55321 + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
55322 + Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
55323 +
55324 + } while (lx < s->last_lit);
55325 +
55326 + send_code(s, END_BLOCK, ltree);
55327 + s->last_eob_len = ltree[END_BLOCK].Len;
55328 +}
55329 +
55330 +/* ===========================================================================
55331 + * Set the data type to ASCII or BINARY, using a crude approximation:
55332 + * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
55333 + * IN assertion: the fields freq of dyn_ltree are set and the total of all
55334 + * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
55335 + */
55336 +local void set_data_type(s)
55337 + deflate_state *s;
55338 +{
55339 + int n = 0;
55340 + unsigned ascii_freq = 0;
55341 + unsigned bin_freq = 0;
55342 + while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
55343 + while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
55344 + while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
55345 + s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
55346 +}
55347 +
55348 +/* ===========================================================================
55349 + * Reverse the first len bits of a code, using straightforward code (a faster
55350 + * method would use a table)
55351 + * IN assertion: 1 <= len <= 15
55352 + */
55353 +local unsigned bi_reverse(code, len)
55354 + unsigned code; /* the value to invert */
55355 + int len; /* its bit length */
55356 +{
55357 + register unsigned res = 0;
55358 + do {
55359 + res |= code & 1;
55360 + code >>= 1, res <<= 1;
55361 + } while (--len > 0);
55362 + return res >> 1;
55363 +}
55364 +
55365 +/* ===========================================================================
55366 + * Flush the bit buffer, keeping at most 7 bits in it.
55367 + */
55368 +local void bi_flush(s)
55369 + deflate_state *s;
55370 +{
55371 + if (s->bi_valid == 16) {
55372 + put_short(s, s->bi_buf);
55373 + s->bi_buf = 0;
55374 + s->bi_valid = 0;
55375 + } else if (s->bi_valid >= 8) {
55376 + put_byte(s, (Byte)s->bi_buf);
55377 + s->bi_buf >>= 8;
55378 + s->bi_valid -= 8;
55379 + }
55380 +}
55381 +
55382 +/* ===========================================================================
55383 + * Flush the bit buffer and align the output on a byte boundary
55384 + */
55385 +local void bi_windup(s)
55386 + deflate_state *s;
55387 +{
55388 + if (s->bi_valid > 8) {
55389 + put_short(s, s->bi_buf);
55390 + } else if (s->bi_valid > 0) {
55391 + put_byte(s, (Byte)s->bi_buf);
55392 + }
55393 + s->bi_buf = 0;
55394 + s->bi_valid = 0;
55395 +#ifdef DEBUG
55396 + s->bits_sent = (s->bits_sent+7) & ~7;
55397 +#endif
55398 +}
55399 +
55400 +/* ===========================================================================
55401 + * Copy a stored block, storing first the length and its
55402 + * one's complement if requested.
55403 + */
55404 +local void copy_block(s, buf, len, header)
55405 + deflate_state *s;
55406 + charf *buf; /* the input data */
55407 + unsigned len; /* its length */
55408 + int header; /* true if block header must be written */
55409 +{
55410 + bi_windup(s); /* align on byte boundary */
55411 + s->last_eob_len = 8; /* enough lookahead for inflate */
55412 +
55413 + if (header) {
55414 + put_short(s, (ush)len);
55415 + put_short(s, (ush)~len);
55416 +#ifdef DEBUG
55417 + s->bits_sent += 2*16;
55418 +#endif
55419 + }
55420 +#ifdef DEBUG
55421 + s->bits_sent += (ulg)len<<3;
55422 +#endif
55423 + while (len--) {
55424 + put_byte(s, *buf++);
55425 + }
55426 +}
55427 --- /dev/null Tue Mar 11 13:02:56 2003
55428 +++ linux/net/ipsec/trees.h Mon Feb 9 13:51:03 2004
55429 @@ -0,0 +1,128 @@
55430 +/* header created automatically with -DGEN_TREES_H */
55431 +
55432 +local const ct_data static_ltree[L_CODES+2] = {
55433 +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
55434 +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
55435 +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
55436 +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
55437 +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
55438 +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
55439 +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
55440 +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
55441 +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
55442 +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
55443 +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
55444 +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
55445 +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
55446 +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
55447 +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
55448 +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
55449 +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
55450 +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
55451 +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
55452 +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
55453 +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
55454 +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
55455 +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
55456 +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
55457 +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
55458 +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
55459 +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
55460 +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
55461 +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
55462 +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
55463 +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
55464 +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
55465 +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
55466 +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
55467 +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
55468 +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
55469 +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
55470 +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
55471 +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
55472 +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
55473 +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
55474 +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
55475 +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
55476 +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
55477 +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
55478 +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
55479 +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
55480 +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
55481 +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
55482 +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
55483 +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
55484 +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
55485 +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
55486 +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
55487 +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
55488 +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
55489 +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
55490 +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
55491 +};
55492 +
55493 +local const ct_data static_dtree[D_CODES] = {
55494 +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
55495 +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
55496 +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
55497 +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
55498 +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
55499 +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
55500 +};
55501 +
55502 +const uch _dist_code[DIST_CODE_LEN] = {
55503 + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
55504 + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
55505 +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
55506 +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
55507 +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
55508 +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
55509 +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
55510 +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
55511 +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
55512 +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
55513 +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
55514 +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
55515 +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
55516 +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
55517 +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
55518 +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
55519 +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
55520 +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
55521 +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
55522 +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
55523 +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
55524 +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
55525 +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
55526 +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
55527 +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
55528 +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
55529 +};
55530 +
55531 +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
55532 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
55533 +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
55534 +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
55535 +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
55536 +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
55537 +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
55538 +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
55539 +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
55540 +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
55541 +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
55542 +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
55543 +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
55544 +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
55545 +};
55546 +
55547 +local const int base_length[LENGTH_CODES] = {
55548 +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
55549 +64, 80, 96, 112, 128, 160, 192, 224, 0
55550 +};
55551 +
55552 +local const int base_dist[D_CODES] = {
55553 + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
55554 + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
55555 + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
55556 +};
55557 +
55558 --- /dev/null Tue Mar 11 13:02:56 2003
55559 +++ linux/net/ipsec/ultoa.c Mon Feb 9 13:51:03 2004
55560 @@ -0,0 +1,66 @@
55561 +/*
55562 + * convert unsigned long to ASCII
55563 + * Copyright (C) 1998, 1999 Henry Spencer.
55564 + *
55565 + * This library is free software; you can redistribute it and/or modify it
55566 + * under the terms of the GNU Library General Public License as published by
55567 + * the Free Software Foundation; either version 2 of the License, or (at your
55568 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
55569 + *
55570 + * This library is distributed in the hope that it will be useful, but
55571 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
55572 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
55573 + * License for more details.
55574 + *
55575 + * RCSID $Id: ultoa.c,v 1.10 2004/07/10 07:48:37 mcr Exp $
55576 + */
55577 +#include "openswan.h"
55578 +
55579 +/*
55580 + - ultoa - convert unsigned long to decimal ASCII
55581 + */
55582 +size_t /* length required for full conversion */
55583 +ultoa(n, base, dst, dstlen)
55584 +unsigned long n;
55585 +int base;
55586 +char *dst; /* need not be valid if dstlen is 0 */
55587 +size_t dstlen;
55588 +{
55589 + char buf[3*sizeof(unsigned long) + 1];
55590 + char *bufend = buf + sizeof(buf);
55591 + size_t len;
55592 + char *p;
55593 + static char hex[] = "0123456789abcdef";
55594 +
55595 + p = bufend;
55596 + *--p = '\0';
55597 + if (base == 10) {
55598 + do {
55599 + *--p = n%10 + '0';
55600 + n /= 10;
55601 + } while (n != 0);
55602 + } else if (base == 16) {
55603 + do {
55604 + *--p = hex[n&0xf];
55605 + n >>= 4;
55606 + } while (n != 0);
55607 + *--p = 'x';
55608 + *--p = '0';
55609 + } else if (base == 8) {
55610 + do {
55611 + *--p = (n&07) + '0';
55612 + n >>= 3;
55613 + } while (n != 0);
55614 + *--p = '0';
55615 + } else
55616 + *--p = '?';
55617 +
55618 + len = bufend - p;
55619 +
55620 + if (dstlen > 0) {
55621 + if (len > dstlen)
55622 + *(p + dstlen - 1) = '\0';
55623 + strcpy(dst, p);
55624 + }
55625 + return len;
55626 +}
55627 --- /dev/null Tue Mar 11 13:02:56 2003
55628 +++ linux/net/ipsec/ultot.c Mon Feb 9 13:51:03 2004
55629 @@ -0,0 +1,82 @@
55630 +/*
55631 + * convert unsigned long to text
55632 + * Copyright (C) 2000 Henry Spencer.
55633 + *
55634 + * This library is free software; you can redistribute it and/or modify it
55635 + * under the terms of the GNU Library General Public License as published by
55636 + * the Free Software Foundation; either version 2 of the License, or (at your
55637 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
55638 + *
55639 + * This library is distributed in the hope that it will be useful, but
55640 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
55641 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
55642 + * License for more details.
55643 + *
55644 + * RCSID $Id: ultot.c,v 1.5 2004/07/10 07:48:37 mcr Exp $
55645 + */
55646 +#include "openswan.h"
55647 +
55648 +/*
55649 + - ultot - convert unsigned long to text
55650 + */
55651 +size_t /* length required for full conversion */
55652 +ultot(n, base, dst, dstlen)
55653 +unsigned long n;
55654 +int base;
55655 +char *dst; /* need not be valid if dstlen is 0 */
55656 +size_t dstlen;
55657 +{
55658 + char buf[3*sizeof(unsigned long) + 1];
55659 + char *bufend = buf + sizeof(buf);
55660 + size_t len;
55661 + char *p;
55662 + static char hex[] = "0123456789abcdef";
55663 +# define HEX32 (32/4)
55664 +
55665 + p = bufend;
55666 + *--p = '\0';
55667 + switch (base) {
55668 + case 10:
55669 + case 'd':
55670 + do {
55671 + *--p = n%10 + '0';
55672 + n /= 10;
55673 + } while (n != 0);
55674 + break;
55675 + case 16:
55676 + case 17:
55677 + case 'x':
55678 + do {
55679 + *--p = hex[n&0xf];
55680 + n >>= 4;
55681 + } while (n != 0);
55682 + if (base == 17)
55683 + while (bufend - p < HEX32 + 1)
55684 + *--p = '0';
55685 + if (base == 'x') {
55686 + *--p = 'x';
55687 + *--p = '0';
55688 + }
55689 + break;
55690 + case 8:
55691 + case 'o':
55692 + do {
55693 + *--p = (n&07) + '0';
55694 + n >>= 3;
55695 + } while (n != 0);
55696 + if (base == 'o')
55697 + *--p = '0';
55698 + break;
55699 + default:
55700 + return 0;
55701 + break;
55702 + }
55703 +
55704 + len = bufend - p;
55705 + if (dstlen > 0) {
55706 + if (len > dstlen)
55707 + *(p + dstlen - 1) = '\0';
55708 + strcpy(dst, p);
55709 + }
55710 + return len;
55711 +}
55712 --- /dev/null Tue Mar 11 13:02:56 2003
55713 +++ linux/net/ipsec/version.c Mon Feb 9 13:51:03 2004
55714 @@ -0,0 +1,44 @@
55715 +/*
55716 + * return IPsec version information
55717 + * Copyright (C) 2001 Henry Spencer.
55718 + *
55719 + * This library is free software; you can redistribute it and/or modify it
55720 + * under the terms of the GNU Library General Public License as published by
55721 + * the Free Software Foundation; either version 2 of the License, or (at your
55722 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
55723 + *
55724 + * This library is distributed in the hope that it will be useful, but
55725 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
55726 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
55727 + * License for more details.
55728 + *
55729 + * RCSID $Id: version.in.c,v 1.2 2004/04/14 05:09:46 ken Exp $
55730 + */
55731 +
55732 +#ifdef __KERNEL__
55733 +#include <linux/netdevice.h>
55734 +#endif
55735 +
55736 +#include "openswan.h"
55737 +
55738 +#define V "2.6.16dr2" /* substituted in by Makefile */
55739 +static const char openswan_number[] = V;
55740 +static const char openswan_string[] = "Openswan " V;
55741 +
55742 +/*
55743 + - ipsec_version_code - return IPsec version number/code, as string
55744 + */
55745 +const char *
55746 +ipsec_version_code()
55747 +{
55748 + return openswan_number;
55749 +}
55750 +
55751 +/*
55752 + - ipsec_version_string - return full version string
55753 + */
55754 +const char *
55755 +ipsec_version_string()
55756 +{
55757 + return openswan_string;
55758 +}
55759 --- /dev/null Tue Mar 11 13:02:56 2003
55760 +++ linux/net/ipsec/zutil.c Mon Feb 9 13:51:03 2004
55761 @@ -0,0 +1,227 @@
55762 +/* zutil.c -- target dependent utility functions for the compression library
55763 + * Copyright (C) 1995-2002 Jean-loup Gailly.
55764 + * For conditions of distribution and use, see copyright notice in zlib.h
55765 + */
55766 +
55767 +/* @(#) $Id: zutil.c,v 1.5 2004/07/10 07:48:40 mcr Exp $ */
55768 +
55769 +#include <zlib/zutil.h>
55770 +
55771 +#define MY_ZCALLOC
55772 +
55773 +struct internal_state {int dummy;}; /* for buggy compilers */
55774 +
55775 +#ifndef STDC
55776 +extern void exit OF((int));
55777 +#endif
55778 +
55779 +const char *z_errmsg[10] = {
55780 +"need dictionary", /* Z_NEED_DICT 2 */
55781 +"stream end", /* Z_STREAM_END 1 */
55782 +"", /* Z_OK 0 */
55783 +"file error", /* Z_ERRNO (-1) */
55784 +"stream error", /* Z_STREAM_ERROR (-2) */
55785 +"data error", /* Z_DATA_ERROR (-3) */
55786 +"insufficient memory", /* Z_MEM_ERROR (-4) */
55787 +"buffer error", /* Z_BUF_ERROR (-5) */
55788 +"incompatible version",/* Z_VERSION_ERROR (-6) */
55789 +""};
55790 +
55791 +
55792 +const char * ZEXPORT zlibVersion()
55793 +{
55794 + return ZLIB_VERSION;
55795 +}
55796 +
55797 +#ifdef DEBUG
55798 +
55799 +# ifndef verbose
55800 +# define verbose 0
55801 +# endif
55802 +int z_verbose = verbose;
55803 +
55804 +void z_error (m)
55805 + char *m;
55806 +{
55807 + fprintf(stderr, "%s\n", m);
55808 + exit(1);
55809 +}
55810 +#endif
55811 +
55812 +/* exported to allow conversion of error code to string for compress() and
55813 + * uncompress()
55814 + */
55815 +const char * ZEXPORT zError(err)
55816 + int err;
55817 +{
55818 + return ERR_MSG(err);
55819 +}
55820 +
55821 +
55822 +#ifndef HAVE_MEMCPY
55823 +
55824 +void zmemcpy(dest, source, len)
55825 + Bytef* dest;
55826 + const Bytef* source;
55827 + uInt len;
55828 +{
55829 + if (len == 0) return;
55830 + do {
55831 + *dest++ = *source++; /* ??? to be unrolled */
55832 + } while (--len != 0);
55833 +}
55834 +
55835 +int zmemcmp(s1, s2, len)
55836 + const Bytef* s1;
55837 + const Bytef* s2;
55838 + uInt len;
55839 +{
55840 + uInt j;
55841 +
55842 + for (j = 0; j < len; j++) {
55843 + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
55844 + }
55845 + return 0;
55846 +}
55847 +
55848 +void zmemzero(dest, len)
55849 + Bytef* dest;
55850 + uInt len;
55851 +{
55852 + if (len == 0) return;
55853 + do {
55854 + *dest++ = 0; /* ??? to be unrolled */
55855 + } while (--len != 0);
55856 +}
55857 +#endif
55858 +
55859 +#ifdef __TURBOC__
55860 +#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
55861 +/* Small and medium model in Turbo C are for now limited to near allocation
55862 + * with reduced MAX_WBITS and MAX_MEM_LEVEL
55863 + */
55864 +# define MY_ZCALLOC
55865 +
55866 +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
55867 + * and farmalloc(64K) returns a pointer with an offset of 8, so we
55868 + * must fix the pointer. Warning: the pointer must be put back to its
55869 + * original form in order to free it, use zcfree().
55870 + */
55871 +
55872 +#define MAX_PTR 10
55873 +/* 10*64K = 640K */
55874 +
55875 +local int next_ptr = 0;
55876 +
55877 +typedef struct ptr_table_s {
55878 + voidpf org_ptr;
55879 + voidpf new_ptr;
55880 +} ptr_table;
55881 +
55882 +local ptr_table table[MAX_PTR];
55883 +/* This table is used to remember the original form of pointers
55884 + * to large buffers (64K). Such pointers are normalized with a zero offset.
55885 + * Since MSDOS is not a preemptive multitasking OS, this table is not
55886 + * protected from concurrent access. This hack doesn't work anyway on
55887 + * a protected system like OS/2. Use Microsoft C instead.
55888 + */
55889 +
55890 +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
55891 +{
55892 + voidpf buf = opaque; /* just to make some compilers happy */
55893 + ulg bsize = (ulg)items*size;
55894 +
55895 + /* If we allocate less than 65520 bytes, we assume that farmalloc
55896 + * will return a usable pointer which doesn't have to be normalized.
55897 + */
55898 + if (bsize < 65520L) {
55899 + buf = farmalloc(bsize);
55900 + if (*(ush*)&buf != 0) return buf;
55901 + } else {
55902 + buf = farmalloc(bsize + 16L);
55903 + }
55904 + if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
55905 + table[next_ptr].org_ptr = buf;
55906 +
55907 + /* Normalize the pointer to seg:0 */
55908 + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
55909 + *(ush*)&buf = 0;
55910 + table[next_ptr++].new_ptr = buf;
55911 + return buf;
55912 +}
55913 +
55914 +void zcfree (voidpf opaque, voidpf ptr)
55915 +{
55916 + int n;
55917 + if (*(ush*)&ptr != 0) { /* object < 64K */
55918 + farfree(ptr);
55919 + return;
55920 + }
55921 + /* Find the original pointer */
55922 + for (n = 0; n < next_ptr; n++) {
55923 + if (ptr != table[n].new_ptr) continue;
55924 +
55925 + farfree(table[n].org_ptr);
55926 + while (++n < next_ptr) {
55927 + table[n-1] = table[n];
55928 + }
55929 + next_ptr--;
55930 + return;
55931 + }
55932 + ptr = opaque; /* just to make some compilers happy */
55933 + Assert(0, "zcfree: ptr not found");
55934 +}
55935 +#endif
55936 +#endif /* __TURBOC__ */
55937 +
55938 +
55939 +#if defined(M_I86) && !defined(__32BIT__)
55940 +/* Microsoft C in 16-bit mode */
55941 +
55942 +# define MY_ZCALLOC
55943 +
55944 +#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
55945 +# define _halloc halloc
55946 +# define _hfree hfree
55947 +#endif
55948 +
55949 +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
55950 +{
55951 + if (opaque) opaque = 0; /* to make compiler happy */
55952 + return _halloc((long)items, size);
55953 +}
55954 +
55955 +void zcfree (voidpf opaque, voidpf ptr)
55956 +{
55957 + if (opaque) opaque = 0; /* to make compiler happy */
55958 + _hfree(ptr);
55959 +}
55960 +
55961 +#endif /* MSC */
55962 +
55963 +
55964 +#ifndef MY_ZCALLOC /* Any system without a special alloc function */
55965 +
55966 +#ifndef STDC
55967 +extern voidp calloc OF((uInt items, uInt size));
55968 +extern void free OF((voidpf ptr));
55969 +#endif
55970 +
55971 +voidpf zcalloc (opaque, items, size)
55972 + voidpf opaque;
55973 + unsigned items;
55974 + unsigned size;
55975 +{
55976 + if (opaque) items += size - size; /* make compiler happy */
55977 + return (voidpf)calloc(items, size);
55978 +}
55979 +
55980 +void zcfree (opaque, ptr)
55981 + voidpf opaque;
55982 + voidpf ptr;
55983 +{
55984 + free(ptr);
55985 + if (opaque) return; /* make compiler happy */
55986 +}
55987 +
55988 +#endif /* MY_ZCALLOC */
55989 --- swan26/net/ipv4/af_inet.c.orig Wed Jun 16 01:18:58 2004
55990 +++ swan26/net/ipv4/af_inet.c Fri Aug 13 23:09:27 2004
55991 @@ -1169,6 +1169,18 @@
55992 #if defined(CONFIG_IP_MROUTE)
55993 ip_mr_init();
55994 #endif
55995 +
55996 +#if defined(CONFIG_KLIPS)
55997 + {
55998 + extern int ipsec_klips_init(void);
55999 + /*
56000 + * Initialise AF_INET ESP and AH protocol support including
56001 + * e-routing and SA tables
56002 + */
56003 + ipsec_klips_init();
56004 + }
56005 +#endif /* CONFIG_IPSEC */
56006 +
56007 /*
56008 * Initialise per-cpu ipv4 mibs
56009 */
56010 --- /dev/null Fri May 10 13:59:54 2002
56011 +++ linux/net/ipsec/Makefile.ver Sun Jul 28 22:10:40 2002
56012 @@ -0,0 +1 @@
56013 +IPSECVERSION='2.6.16dr2'