]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/openswan-2.5.13.kernel-2.6-klips.patch
a7cd1276428079e64753a813a14cb69d3a1b0371
[ipfire-2.x.git] / src / patches / openswan-2.5.13.kernel-2.6-klips.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/crypto/aes.h Mon Feb 9 13:51:03 2004
119 @@ -0,0 +1,97 @@
120 +// I retain copyright in this code but I encourage its free use provided
121 +// that I don't carry any responsibility for the results. I am especially
122 +// happy to see it used in free and open source software. If you do use
123 +// it I would appreciate an acknowledgement of its origin in the code or
124 +// the product that results and I would also appreciate knowing a little
125 +// about the use to which it is being put. I am grateful to Frank Yellin
126 +// for some ideas that are used in this implementation.
127 +//
128 +// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
129 +//
130 +// This is an implementation of the AES encryption algorithm (Rijndael)
131 +// designed by Joan Daemen and Vincent Rijmen. This version is designed
132 +// to provide both fixed and dynamic block and key lengths and can also
133 +// run with either big or little endian internal byte order (see aes.h).
134 +// It inputs block and key lengths in bytes with the legal values being
135 +// 16, 24 and 32.
136 +
137 +/*
138 + * Modified by Jari Ruusu, May 1 2001
139 + * - Fixed some compile warnings, code was ok but gcc warned anyway.
140 + * - Changed basic types: byte -> unsigned char, word -> u_int32_t
141 + * - Major name space cleanup: Names visible to outside now begin
142 + * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
143 + * - Removed C++ and DLL support as part of name space cleanup.
144 + * - Eliminated unnecessary recomputation of tables. (actual bug fix)
145 + * - Merged precomputed constant tables to aes.c file.
146 + * - Removed data alignment restrictions for portability reasons.
147 + * - Made block and key lengths accept bit count (128/192/256)
148 + * as well byte count (16/24/32).
149 + * - Removed all error checks. This change also eliminated the need
150 + * to preinitialize the context struct to zero.
151 + * - Removed some totally unused constants.
152 + */
153 +
154 +#ifndef _AES_H
155 +#define _AES_H
156 +
157 +#if defined(__linux__) && defined(__KERNEL__)
158 +# include <linux/types.h>
159 +#else
160 +# include <sys/types.h>
161 +#endif
162 +
163 +// CONFIGURATION OPTIONS (see also aes.c)
164 +//
165 +// Define AES_BLOCK_SIZE to set the cipher block size (16, 24 or 32) or
166 +// leave this undefined for dynamically variable block size (this will
167 +// result in much slower code).
168 +// IMPORTANT NOTE: AES_BLOCK_SIZE is in BYTES (16, 24, 32 or undefined). If
169 +// left undefined a slower version providing variable block length is compiled
170 +
171 +#define AES_BLOCK_SIZE 16
172 +
173 +// The number of key schedule words for different block and key lengths
174 +// allowing for method of computation which requires the length to be a
175 +// multiple of the key length
176 +//
177 +// Nk = 4 6 8
178 +// -------------
179 +// Nb = 4 | 60 60 64
180 +// 6 | 96 90 96
181 +// 8 | 120 120 120
182 +
183 +#if !defined(AES_BLOCK_SIZE) || (AES_BLOCK_SIZE == 32)
184 +#define AES_KS_LENGTH 120
185 +#define AES_RC_LENGTH 29
186 +#else
187 +#define AES_KS_LENGTH 4 * AES_BLOCK_SIZE
188 +#define AES_RC_LENGTH (9 * AES_BLOCK_SIZE) / 8 - 8
189 +#endif
190 +
191 +typedef struct
192 +{
193 + u_int32_t aes_Nkey; // the number of words in the key input block
194 + u_int32_t aes_Nrnd; // the number of cipher rounds
195 + u_int32_t aes_e_key[AES_KS_LENGTH]; // the encryption key schedule
196 + u_int32_t aes_d_key[AES_KS_LENGTH]; // the decryption key schedule
197 +#if !defined(AES_BLOCK_SIZE)
198 + u_int32_t aes_Ncol; // the number of columns in the cipher state
199 +#endif
200 +} aes_context;
201 +
202 +// THE CIPHER INTERFACE
203 +
204 +#if !defined(AES_BLOCK_SIZE)
205 +extern void aes_set_blk(aes_context *, const int);
206 +#endif
207 +extern void aes_set_key(aes_context *, const unsigned char [], const int, const int);
208 +extern void aes_encrypt(const aes_context *, const unsigned char [], unsigned char []);
209 +extern void aes_decrypt(const aes_context *, const unsigned char [], unsigned char []);
210 +
211 +// The block length inputs to aes_set_block and aes_set_key are in numbers
212 +// of bytes or bits. The calls to subroutines must be made in the above
213 +// order but multiple calls can be made without repeating earlier calls
214 +// if their parameters have not changed.
215 +
216 +#endif // _AES_H
217 --- /dev/null Tue Mar 11 13:02:56 2003
218 +++ linux/include/crypto/aes_cbc.h Mon Feb 9 13:51:03 2004
219 @@ -0,0 +1,4 @@
220 +/* Glue header */
221 +#include "aes.h"
222 +int AES_set_key(aes_context *aes_ctx, const u_int8_t * key, int keysize);
223 +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);
224 --- /dev/null Tue Mar 11 13:02:56 2003
225 +++ linux/include/crypto/aes_xcbc_mac.h Mon Feb 9 13:51:03 2004
226 @@ -0,0 +1,12 @@
227 +#ifndef _AES_XCBC_MAC_H
228 +#define _AES_XCBC_MAC_H
229 +
230 +typedef u_int32_t aes_block[4];
231 +typedef struct {
232 + aes_context ctx_k1;
233 + aes_block k2;
234 + aes_block k3;
235 +} aes_context_mac;
236 +int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen);
237 +int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]);
238 +#endif /* _AES_XCBC_MAC_H */
239 --- /dev/null Tue Mar 11 13:02:56 2003
240 +++ linux/include/crypto/cbc_generic.h Mon Feb 9 13:51:03 2004
241 @@ -0,0 +1,110 @@
242 +#ifndef _CBC_GENERIC_H
243 +#define _CBC_GENERIC_H
244 +/*
245 + * CBC macro helpers
246 + *
247 + * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
248 + *
249 + * This program is free software; you can redistribute it and/or modify it
250 + * under the terms of the GNU General Public License as published by the
251 + * Free Software Foundation; either version 2 of the License, or (at your
252 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
253 + *
254 + * This program is distributed in the hope that it will be useful, but
255 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
256 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
257 + * for more details.
258 + *
259 + */
260 +
261 +/*
262 + * Heavily inspired in loop_AES
263 + */
264 +#define CBC_IMPL_BLK16(name, ctx_type, addr_type, enc_func, dec_func) \
265 +int name(ctx_type *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
266 + int ret=ilen, pos; \
267 + const u_int32_t *iv_i; \
268 + if ((ilen) % 16) return 0; \
269 + if (encrypt) { \
270 + pos=0; \
271 + while(pos<ilen) { \
272 + if (pos==0) \
273 + iv_i=(const u_int32_t*) iv; \
274 + else \
275 + iv_i=(const u_int32_t*) (out-16); \
276 + *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
277 + *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
278 + *((u_int32_t *)(&out[ 8])) = iv_i[2]^*((const u_int32_t *)(&in[ 8])); \
279 + *((u_int32_t *)(&out[12])) = iv_i[3]^*((const u_int32_t *)(&in[12])); \
280 + enc_func(ctx, (addr_type) out, (addr_type) out); \
281 + in+=16; \
282 + out+=16; \
283 + pos+=16; \
284 + } \
285 + } else { \
286 + pos=ilen-16; \
287 + in+=pos; \
288 + out+=pos; \
289 + while(pos>=0) { \
290 + dec_func(ctx, (const addr_type) in, (addr_type) out); \
291 + if (pos==0) \
292 + iv_i=(const u_int32_t*) (iv); \
293 + else \
294 + iv_i=(const u_int32_t*) (in-16); \
295 + *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
296 + *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
297 + *((u_int32_t *)(&out[ 8])) ^= iv_i[2]; \
298 + *((u_int32_t *)(&out[12])) ^= iv_i[3]; \
299 + in-=16; \
300 + out-=16; \
301 + pos-=16; \
302 + } \
303 + } \
304 + return ret; \
305 +}
306 +#define CBC_IMPL_BLK8(name, ctx_type, addr_type, enc_func, dec_func) \
307 +int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
308 + int ret=ilen, pos; \
309 + const u_int32_t *iv_i; \
310 + if ((ilen) % 8) return 0; \
311 + if (encrypt) { \
312 + pos=0; \
313 + while(pos<ilen) { \
314 + if (pos==0) \
315 + iv_i=(const u_int32_t*) iv; \
316 + else \
317 + iv_i=(const u_int32_t*) (out-8); \
318 + *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
319 + *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
320 + enc_func(ctx, (addr_type)out, (addr_type)out); \
321 + in+=8; \
322 + out+=8; \
323 + pos+=8; \
324 + } \
325 + } else { \
326 + pos=ilen-8; \
327 + in+=pos; \
328 + out+=pos; \
329 + while(pos>=0) { \
330 + dec_func(ctx, (const addr_type)in, (addr_type)out); \
331 + if (pos==0) \
332 + iv_i=(const u_int32_t*) (iv); \
333 + else \
334 + iv_i=(const u_int32_t*) (in-8); \
335 + *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
336 + *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
337 + in-=8; \
338 + out-=8; \
339 + pos-=8; \
340 + } \
341 + } \
342 + return ret; \
343 +}
344 +#define CBC_DECL(name, ctx_type) \
345 +int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt)
346 +/*
347 +Eg.:
348 +CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
349 +CBC_DECL(AES_cbc_encrypt, aes_context);
350 +*/
351 +#endif /* _CBC_GENERIC_H */
352 --- /dev/null Tue Mar 11 13:02:56 2003
353 +++ linux/include/crypto/des.h Mon Feb 9 13:51:03 2004
354 @@ -0,0 +1,286 @@
355 +/* crypto/des/des.org */
356 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
357 + * All rights reserved.
358 + *
359 + * This package is an SSL implementation written
360 + * by Eric Young (eay@cryptsoft.com).
361 + * The implementation was written so as to conform with Netscapes SSL.
362 + *
363 + * This library is free for commercial and non-commercial use as long as
364 + * the following conditions are aheared to. The following conditions
365 + * apply to all code found in this distribution, be it the RC4, RSA,
366 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
367 + * included with this distribution is covered by the same copyright terms
368 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
369 + *
370 + * Copyright remains Eric Young's, and as such any Copyright notices in
371 + * the code are not to be removed.
372 + * If this package is used in a product, Eric Young should be given attribution
373 + * as the author of the parts of the library used.
374 + * This can be in the form of a textual message at program startup or
375 + * in documentation (online or textual) provided with the package.
376 + *
377 + * Redistribution and use in source and binary forms, with or without
378 + * modification, are permitted provided that the following conditions
379 + * are met:
380 + * 1. Redistributions of source code must retain the copyright
381 + * notice, this list of conditions and the following disclaimer.
382 + * 2. Redistributions in binary form must reproduce the above copyright
383 + * notice, this list of conditions and the following disclaimer in the
384 + * documentation and/or other materials provided with the distribution.
385 + * 3. All advertising materials mentioning features or use of this software
386 + * must display the following acknowledgement:
387 + * "This product includes cryptographic software written by
388 + * Eric Young (eay@cryptsoft.com)"
389 + * The word 'cryptographic' can be left out if the rouines from the library
390 + * being used are not cryptographic related :-).
391 + * 4. If you include any Windows specific code (or a derivative thereof) from
392 + * the apps directory (application code) you must include an acknowledgement:
393 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
394 + *
395 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
396 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
397 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
398 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
399 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
400 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
401 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
402 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
403 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
404 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
405 + * SUCH DAMAGE.
406 + *
407 + * The licence and distribution terms for any publically available version or
408 + * derivative of this code cannot be changed. i.e. this code cannot simply be
409 + * copied and put under another distribution licence
410 + * [including the GNU Public Licence.]
411 + */
412 +
413 +/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
414 + *
415 + * Always modify des.org since des.h is automatically generated from
416 + * it during SSLeay configuration.
417 + *
418 + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
419 + */
420 +
421 +#ifndef HEADER_DES_H
422 +#define HEADER_DES_H
423 +
424 +#ifdef __cplusplus
425 +extern "C" {
426 +#endif
427 +
428 +
429 +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
430 + * %20 speed up (longs are 8 bytes, int's are 4). */
431 +/* Must be unsigned int on ia64/Itanium or DES breaks badly */
432 +
433 +#ifdef __KERNEL__
434 +#include <linux/types.h>
435 +#else
436 +#include <sys/types.h>
437 +#endif
438 +
439 +#ifndef DES_LONG
440 +#define DES_LONG u_int32_t
441 +#endif
442 +
443 +typedef unsigned char des_cblock[8];
444 +typedef struct { des_cblock ks; } des_key_schedule[16];
445 +
446 +#define DES_KEY_SZ (sizeof(des_cblock))
447 +#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
448 +
449 +#define DES_ENCRYPT 1
450 +#define DES_DECRYPT 0
451 +
452 +#define DES_CBC_MODE 0
453 +#define DES_PCBC_MODE 1
454 +
455 +#define des_ecb2_encrypt(i,o,k1,k2,e) \
456 + des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
457 +
458 +#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
459 + des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
460 +
461 +#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
462 + des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
463 +
464 +#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
465 + des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
466 +
467 +#define C_Block des_cblock
468 +#define Key_schedule des_key_schedule
469 +#ifdef KERBEROS
470 +#define ENCRYPT DES_ENCRYPT
471 +#define DECRYPT DES_DECRYPT
472 +#endif
473 +#define KEY_SZ DES_KEY_SZ
474 +#define string_to_key des_string_to_key
475 +#define read_pw_string des_read_pw_string
476 +#define random_key des_random_key
477 +#define pcbc_encrypt des_pcbc_encrypt
478 +#define set_key des_set_key
479 +#define key_sched des_key_sched
480 +#define ecb_encrypt des_ecb_encrypt
481 +#define cbc_encrypt des_cbc_encrypt
482 +#define ncbc_encrypt des_ncbc_encrypt
483 +#define xcbc_encrypt des_xcbc_encrypt
484 +#define cbc_cksum des_cbc_cksum
485 +#define quad_cksum des_quad_cksum
486 +
487 +/* For compatibility with the MIT lib - eay 20/05/92 */
488 +typedef des_key_schedule bit_64;
489 +#define des_fixup_key_parity des_set_odd_parity
490 +#define des_check_key_parity check_parity
491 +
492 +extern int des_check_key; /* defaults to false */
493 +extern int des_rw_mode; /* defaults to DES_PCBC_MODE */
494 +
495 +/* The next line is used to disable full ANSI prototypes, if your
496 + * compiler has problems with the prototypes, make sure this line always
497 + * evaluates to true :-) */
498 +#if defined(MSDOS) || defined(__STDC__)
499 +#undef NOPROTO
500 +#endif
501 +#ifndef NOPROTO
502 +char *des_options(void);
503 +void des_ecb3_encrypt(des_cblock *input,des_cblock *output,
504 + des_key_schedule ks1,des_key_schedule ks2,
505 + des_key_schedule ks3, int enc);
506 +DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output,
507 + long length,des_key_schedule schedule,des_cblock *ivec);
508 +void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
509 + des_key_schedule schedule,des_cblock *ivec,int enc);
510 +void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
511 + des_key_schedule schedule,des_cblock *ivec,int enc);
512 +void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
513 + des_key_schedule schedule,des_cblock *ivec,
514 + des_cblock *inw,des_cblock *outw,int enc);
515 +void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
516 + long length,des_key_schedule schedule,des_cblock *ivec,int enc);
517 +void des_ecb_encrypt(des_cblock *input,des_cblock *output,
518 + des_key_schedule ks,int enc);
519 +void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
520 +void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
521 +void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
522 + des_key_schedule ks2, des_key_schedule ks3);
523 +void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
524 + des_key_schedule ks2, des_key_schedule ks3);
525 +void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
526 + long length, des_key_schedule ks1, des_key_schedule ks2,
527 + des_key_schedule ks3, des_cblock *ivec, int enc);
528 +void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
529 + long length, des_key_schedule ks1, des_key_schedule ks2,
530 + des_key_schedule ks3, des_cblock *ivec, int *num, int enc);
531 +void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
532 + long length, des_key_schedule ks1, des_key_schedule ks2,
533 + des_key_schedule ks3, des_cblock *ivec, int *num);
534 +
535 +void des_xwhite_in2out(des_cblock (*des_key), des_cblock (*in_white),
536 + des_cblock (*out_white));
537 +
538 +int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
539 + des_cblock *iv);
540 +int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
541 + des_cblock *iv);
542 +char *des_fcrypt(const char *buf,const char *salt, char *ret);
543 +
544 +void des_ofb_encrypt(unsigned char *in,unsigned char *out,
545 + int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
546 +void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
547 + des_key_schedule schedule,des_cblock *ivec,int enc);
548 +DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output,
549 + long length,int out_count,des_cblock *seed);
550 +void des_random_seed(des_cblock key);
551 +void des_random_key(des_cblock ret);
552 +int des_read_password(des_cblock *key,char *prompt,int verify);
553 +int des_read_2passwords(des_cblock *key1,des_cblock *key2,
554 + char *prompt,int verify);
555 +int des_read_pw_string(char *buf,int length,char *prompt,int verify);
556 +void des_set_odd_parity(des_cblock *key);
557 +int des_is_weak_key(des_cblock *key);
558 +int des_set_key(des_cblock *key,des_key_schedule schedule);
559 +int des_key_sched(des_cblock *key,des_key_schedule schedule);
560 +void des_string_to_key(char *str,des_cblock *key);
561 +void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
562 +void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
563 + des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
564 +void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
565 + des_key_schedule schedule, des_cblock *ivec, int *num);
566 +int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify);
567 +
568 +/* Extra functions from Mark Murray <mark@grondar.za> */
569 +/* The following functions are not in the normal unix build or the
570 + * SSLeay build. When using the SSLeay build, use RAND_seed()
571 + * and RAND_bytes() instead. */
572 +int des_new_random_key(des_cblock *key);
573 +void des_init_random_number_generator(des_cblock *key);
574 +void des_set_random_generator_seed(des_cblock *key);
575 +void des_set_sequence_number(des_cblock new_sequence_number);
576 +void des_generate_random_block(des_cblock *block);
577 +
578 +#else
579 +
580 +char *des_options();
581 +void des_ecb3_encrypt();
582 +DES_LONG des_cbc_cksum();
583 +void des_cbc_encrypt();
584 +void des_ncbc_encrypt();
585 +void des_xcbc_encrypt();
586 +void des_cfb_encrypt();
587 +void des_ede3_cfb64_encrypt();
588 +void des_ede3_ofb64_encrypt();
589 +void des_ecb_encrypt();
590 +void des_encrypt();
591 +void des_encrypt2();
592 +void des_encrypt3();
593 +void des_decrypt3();
594 +void des_ede3_cbc_encrypt();
595 +int des_enc_read();
596 +int des_enc_write();
597 +char *des_fcrypt();
598 +#ifdef PERL5
599 +char *des_crypt();
600 +#else
601 +char *crypt();
602 +#endif
603 +void des_ofb_encrypt();
604 +void des_pcbc_encrypt();
605 +DES_LONG des_quad_cksum();
606 +void des_random_seed();
607 +void des_random_key();
608 +int des_read_password();
609 +int des_read_2passwords();
610 +int des_read_pw_string();
611 +void des_set_odd_parity();
612 +int des_is_weak_key();
613 +int des_set_key();
614 +int des_key_sched();
615 +void des_string_to_key();
616 +void des_string_to_2keys();
617 +void des_cfb64_encrypt();
618 +void des_ofb64_encrypt();
619 +int des_read_pw();
620 +void des_xwhite_in2out();
621 +
622 +/* Extra functions from Mark Murray <mark@grondar.za> */
623 +/* The following functions are not in the normal unix build or the
624 + * SSLeay build. When using the SSLeay build, use RAND_seed()
625 + * and RAND_bytes() instead. */
626 +#ifdef FreeBSD
627 +int des_new_random_key();
628 +void des_init_random_number_generator();
629 +void des_set_random_generator_seed();
630 +void des_set_sequence_number();
631 +void des_generate_random_block();
632 +#endif
633 +
634 +#endif
635 +
636 +#ifdef __cplusplus
637 +}
638 +#endif
639 +
640 +#endif
641 --- /dev/null Tue Mar 11 13:02:56 2003
642 +++ linux/include/crypto/ocf_assist.h Mon Feb 9 13:51:03 2004
643 @@ -0,0 +1,63 @@
644 +#ifndef _OCF_ASSIST_H
645 +#define _OCF_ASSIST_H 1
646 +/****************************************************************************/
647 +/* The various hw_assist functions return these bits */
648 +
649 +#define OCF_PROVIDES_AES 0x0001
650 +#define OCF_PROVIDES_DES_3DES 0x0002
651 +
652 +/****************************************************************************/
653 +#if !defined(OCF_ASSIST)
654 +/****************************************************************************/
655 +/*
656 + * stub it all out just in case
657 + */
658 +
659 +#define ocf_aes_assist() (0)
660 +#define ocf_aes_set_key(a1,a2,a3,a4)
661 +#define ocf_aes_cbc_encrypt(a1,a2,a3,a4,a5,a6)
662 +
663 +#define ocf_des_assist() (0)
664 +#define ocf_des_set_key(a, b)
665 +#define ocf_des_cbc_encrypt(a1,a2,a3,a4,a5,a6)
666 +#define ocf_des_encrypt(a1,a2,a3)
667 +#define ocf_des_ede3_cbc_encrypt(a1,a2,a3,a4,a5,a6,a7,a8)
668 +#define ocf_des_ncbc_encrypt(a1,a2,a3,a4,a5,a6)
669 +#define ocf_des_ecb_encrypt(a1,a2,a3,a4)
670 +
671 +/****************************************************************************/
672 +#else
673 +/****************************************************************************/
674 +
675 +#include <sys/types.h>
676 +#include "aes.h"
677 +#include "des.h"
678 +
679 +extern int ocf_aes_assist(void);
680 +extern void ocf_aes_set_key(aes_context *cx, const unsigned char in_key[],
681 + int n_bytes, const int f);
682 +extern int ocf_aes_cbc_encrypt(aes_context *ctx, u8 *input,
683 + u8 *output,
684 + long length,
685 + u8 *ivec, int enc);
686 +
687 +extern int ocf_des_assist(void);
688 +extern int ocf_des_set_key(des_cblock *key, des_key_schedule schedule);
689 +extern void ocf_des_cbc_encrypt(des_cblock *input, des_cblock *output,
690 + long length, des_key_schedule schedule,
691 + des_cblock *ivec, int enc);
692 +extern void ocf_des_encrypt(DES_LONG *data, des_key_schedule ks, int enc);
693 +extern void ocf_des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
694 + long length, des_key_schedule ks1,
695 + des_key_schedule ks2, des_key_schedule ks3,
696 + des_cblock *ivec, int enc);
697 +extern void ocf_des_ncbc_encrypt(des_cblock *input, des_cblock *output,
698 + long length, des_key_schedule schedule,
699 + des_cblock *ivec, int enc);
700 +extern void ocf_des_ecb_encrypt(des_cblock *input, des_cblock *output,
701 + des_key_schedule ks, int enc);
702 +
703 +/****************************************************************************/
704 +#endif /* !defined(OCF_ASSIST) */
705 +/****************************************************************************/
706 +#endif /* _OCF_ASSIST_H */
707 --- /dev/null Tue Mar 11 13:02:56 2003
708 +++ linux/include/des/des_locl.h Mon Feb 9 13:51:03 2004
709 @@ -0,0 +1,506 @@
710 +/* crypto/des/des_locl.org */
711 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
712 + * All rights reserved.
713 + *
714 + * This package is an SSL implementation written
715 + * by Eric Young (eay@cryptsoft.com).
716 + * The implementation was written so as to conform with Netscapes SSL.
717 + *
718 + * This library is free for commercial and non-commercial use as long as
719 + * the following conditions are aheared to. The following conditions
720 + * apply to all code found in this distribution, be it the RC4, RSA,
721 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
722 + * included with this distribution is covered by the same copyright terms
723 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
724 + *
725 + * Copyright remains Eric Young's, and as such any Copyright notices in
726 + * the code are not to be removed.
727 + * If this package is used in a product, Eric Young should be given attribution
728 + * as the author of the parts of the library used.
729 + * This can be in the form of a textual message at program startup or
730 + * in documentation (online or textual) provided with the package.
731 + *
732 + * Redistribution and use in source and binary forms, with or without
733 + * modification, are permitted provided that the following conditions
734 + * are met:
735 + * 1. Redistributions of source code must retain the copyright
736 + * notice, this list of conditions and the following disclaimer.
737 + * 2. Redistributions in binary form must reproduce the above copyright
738 + * notice, this list of conditions and the following disclaimer in the
739 + * documentation and/or other materials provided with the distribution.
740 + * 3. All advertising materials mentioning features or use of this software
741 + * must display the following acknowledgement:
742 + * "This product includes cryptographic software written by
743 + * Eric Young (eay@cryptsoft.com)"
744 + * The word 'cryptographic' can be left out if the rouines from the library
745 + * being used are not cryptographic related :-).
746 + * 4. If you include any Windows specific code (or a derivative thereof) from
747 + * the apps directory (application code) you must include an acknowledgement:
748 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
749 + *
750 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
751 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
752 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
753 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
754 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
755 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
756 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
757 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
758 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
759 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
760 + * SUCH DAMAGE.
761 + *
762 + * The licence and distribution terms for any publically available version or
763 + * derivative of this code cannot be changed. i.e. this code cannot simply be
764 + * copied and put under another distribution licence
765 + * [including the GNU Public Licence.]
766 + */
767 +
768 +/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
769 + *
770 + * Always modify des_locl.org since des_locl.h is automatically generated from
771 + * it during SSLeay configuration.
772 + *
773 + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
774 + */
775 +
776 +#ifndef HEADER_DES_LOCL_H
777 +#define HEADER_DES_LOCL_H
778 +
779 +#if defined(WIN32) || defined(WIN16)
780 +#ifndef MSDOS
781 +#define MSDOS
782 +#endif
783 +#endif
784 +
785 +#include "crypto/des.h"
786 +
787 +#ifndef DES_DEFAULT_OPTIONS
788 +/* the following is tweaked from a config script, that is why it is a
789 + * protected undef/define */
790 +#ifndef DES_PTR
791 +#define DES_PTR
792 +#endif
793 +
794 +/* This helps C compiler generate the correct code for multiple functional
795 + * units. It reduces register dependancies at the expense of 2 more
796 + * registers */
797 +#ifndef DES_RISC1
798 +#define DES_RISC1
799 +#endif
800 +
801 +#ifndef DES_RISC2
802 +#undef DES_RISC2
803 +#endif
804 +
805 +#if defined(DES_RISC1) && defined(DES_RISC2)
806 +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
807 +#endif
808 +
809 +/* Unroll the inner loop, this sometimes helps, sometimes hinders.
810 + * Very mucy CPU dependant */
811 +#ifndef DES_UNROLL
812 +#define DES_UNROLL
813 +#endif
814 +
815 +/* These default values were supplied by
816 + * Peter Gutman <pgut001@cs.auckland.ac.nz>
817 + * They are only used if nothing else has been defined */
818 +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
819 +/* Special defines which change the way the code is built depending on the
820 + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
821 + even newer MIPS CPU's, but at the moment one size fits all for
822 + optimization options. Older Sparc's work better with only UNROLL, but
823 + there's no way to tell at compile time what it is you're running on */
824 +
825 +#if defined( sun ) /* Newer Sparc's */
826 + #define DES_PTR
827 + #define DES_RISC1
828 + #define DES_UNROLL
829 +#elif defined( __ultrix ) /* Older MIPS */
830 + #define DES_PTR
831 + #define DES_RISC2
832 + #define DES_UNROLL
833 +#elif defined( __osf1__ ) /* Alpha */
834 + #define DES_PTR
835 + #define DES_RISC2
836 +#elif defined ( _AIX ) /* RS6000 */
837 + /* Unknown */
838 +#elif defined( __hpux ) /* HP-PA */
839 + /* Unknown */
840 +#elif defined( __aux ) /* 68K */
841 + /* Unknown */
842 +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
843 + #define DES_UNROLL
844 +#elif defined( __sgi ) /* Newer MIPS */
845 + #define DES_PTR
846 + #define DES_RISC2
847 + #define DES_UNROLL
848 +#elif defined( i386 ) /* x86 boxes, should be gcc */
849 + #define DES_PTR
850 + #define DES_RISC1
851 + #define DES_UNROLL
852 +#endif /* Systems-specific speed defines */
853 +#endif
854 +
855 +#endif /* DES_DEFAULT_OPTIONS */
856 +
857 +#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */
858 +#include <stdlib.h>
859 +#include <errno.h>
860 +#include <time.h>
861 +#include <io.h>
862 +#ifndef RAND
863 +#define RAND
864 +#endif
865 +#undef NOPROTO
866 +#endif
867 +
868 +#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
869 +#ifndef __KERNEL__
870 +#include <string.h>
871 +#else
872 +#include <linux/string.h>
873 +#endif
874 +#endif
875 +
876 +#ifndef RAND
877 +#define RAND
878 +#endif
879 +
880 +#ifdef linux
881 +#undef RAND
882 +#endif
883 +
884 +#ifdef MSDOS
885 +#define getpid() 2
886 +#define RAND
887 +#undef NOPROTO
888 +#endif
889 +
890 +#if defined(NOCONST)
891 +#define const
892 +#endif
893 +
894 +#ifdef __STDC__
895 +#undef NOPROTO
896 +#endif
897 +
898 +#define ITERATIONS 16
899 +#define HALF_ITERATIONS 8
900 +
901 +/* used in des_read and des_write */
902 +#define MAXWRITE (1024*16)
903 +#define BSIZE (MAXWRITE+4)
904 +
905 +#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \
906 + l|=((DES_LONG)(*((c)++)))<< 8L, \
907 + l|=((DES_LONG)(*((c)++)))<<16L, \
908 + l|=((DES_LONG)(*((c)++)))<<24L)
909 +
910 +/* NOTE - c is not incremented as per c2l */
911 +#define c2ln(c,l1,l2,n) { \
912 + c+=n; \
913 + l1=l2=0; \
914 + switch (n) { \
915 + case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
916 + case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
917 + case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
918 + case 5: l2|=((DES_LONG)(*(--(c)))); \
919 + case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
920 + case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
921 + case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
922 + case 1: l1|=((DES_LONG)(*(--(c)))); \
923 + } \
924 + }
925 +
926 +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
927 + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
928 + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
929 + *((c)++)=(unsigned char)(((l)>>24L)&0xff))
930 +
931 +/* replacements for htonl and ntohl since I have no idea what to do
932 + * when faced with machines with 8 byte longs. */
933 +#define HDRSIZE 4
934 +
935 +#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \
936 + l|=((DES_LONG)(*((c)++)))<<16L, \
937 + l|=((DES_LONG)(*((c)++)))<< 8L, \
938 + l|=((DES_LONG)(*((c)++))))
939 +
940 +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
941 + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
942 + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
943 + *((c)++)=(unsigned char)(((l) )&0xff))
944 +
945 +/* NOTE - c is not incremented as per l2c */
946 +#define l2cn(l1,l2,c,n) { \
947 + c+=n; \
948 + switch (n) { \
949 + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
950 + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
951 + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
952 + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
953 + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
954 + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
955 + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
956 + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
957 + } \
958 + }
959 +
960 +#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
961 +
962 +/* Don't worry about the LOAD_DATA() stuff, that is used by
963 + * fcrypt() to add it's little bit to the front */
964 +
965 +#ifdef DES_FCRYPT
966 +
967 +#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
968 + { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
969 +
970 +#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
971 + t=R^(R>>16L); \
972 + u=t&E0; t&=E1; \
973 + tmp=(u<<16); u^=R^s[S ]; u^=tmp; \
974 + tmp=(t<<16); t^=R^s[S+1]; t^=tmp
975 +#else
976 +#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
977 +#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
978 + u=R^s[S ]; \
979 + t=R^s[S+1]
980 +#endif
981 +
982 +/* The changes to this macro may help or hinder, depending on the
983 + * compiler and the achitecture. gcc2 always seems to do well :-).
984 + * Inspired by Dana How <how@isl.stanford.edu>
985 + * DO NOT use the alternative version on machines with 8 byte longs.
986 + * It does not seem to work on the Alpha, even when DES_LONG is 4
987 + * bytes, probably an issue of accessing non-word aligned objects :-( */
988 +#ifdef DES_PTR
989 +
990 +/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there
991 + * is no reason to not xor all the sub items together. This potentially
992 + * saves a register since things can be xored directly into L */
993 +
994 +#if defined(DES_RISC1) || defined(DES_RISC2)
995 +#ifdef DES_RISC1
996 +#define D_ENCRYPT(LL,R,S) { \
997 + unsigned int u1,u2,u3; \
998 + LOAD_DATA(R,S,u,t,E0,E1,u1); \
999 + u2=(int)u>>8L; \
1000 + u1=(int)u&0xfc; \
1001 + u2&=0xfc; \
1002 + t=ROTATE(t,4); \
1003 + u>>=16L; \
1004 + LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
1005 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
1006 + u3=(int)(u>>8L); \
1007 + u1=(int)u&0xfc; \
1008 + u3&=0xfc; \
1009 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
1010 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
1011 + u2=(int)t>>8L; \
1012 + u1=(int)t&0xfc; \
1013 + u2&=0xfc; \
1014 + t>>=16L; \
1015 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
1016 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
1017 + u3=(int)t>>8L; \
1018 + u1=(int)t&0xfc; \
1019 + u3&=0xfc; \
1020 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
1021 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }
1022 +#endif
1023 +#ifdef DES_RISC2
1024 +#define D_ENCRYPT(LL,R,S) { \
1025 + unsigned int u1,u2,s1,s2; \
1026 + LOAD_DATA(R,S,u,t,E0,E1,u1); \
1027 + u2=(int)u>>8L; \
1028 + u1=(int)u&0xfc; \
1029 + u2&=0xfc; \
1030 + t=ROTATE(t,4); \
1031 + LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
1032 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
1033 + s1=(int)(u>>16L); \
1034 + s2=(int)(u>>24L); \
1035 + s1&=0xfc; \
1036 + s2&=0xfc; \
1037 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
1038 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
1039 + u2=(int)t>>8L; \
1040 + u1=(int)t&0xfc; \
1041 + u2&=0xfc; \
1042 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
1043 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
1044 + s1=(int)(t>>16L); \
1045 + s2=(int)(t>>24L); \
1046 + s1&=0xfc; \
1047 + s2&=0xfc; \
1048 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
1049 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }
1050 +#endif
1051 +#else
1052 +#define D_ENCRYPT(LL,R,S) { \
1053 + LOAD_DATA_tmp(R,S,u,t,E0,E1); \
1054 + t=ROTATE(t,4); \
1055 + LL^= \
1056 + *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \
1057 + *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
1058 + *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
1059 + *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
1060 + *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \
1061 + *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
1062 + *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
1063 + *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }
1064 +#endif
1065 +
1066 +#else /* original version */
1067 +
1068 +#if defined(DES_RISC1) || defined(DES_RISC2)
1069 +#ifdef DES_RISC1
1070 +#define D_ENCRYPT(LL,R,S) {\
1071 + unsigned int u1,u2,u3; \
1072 + LOAD_DATA(R,S,u,t,E0,E1,u1); \
1073 + u>>=2L; \
1074 + t=ROTATE(t,6); \
1075 + u2=(int)u>>8L; \
1076 + u1=(int)u&0x3f; \
1077 + u2&=0x3f; \
1078 + u>>=16L; \
1079 + LL^=des_SPtrans[0][u1]; \
1080 + LL^=des_SPtrans[2][u2]; \
1081 + u3=(int)u>>8L; \
1082 + u1=(int)u&0x3f; \
1083 + u3&=0x3f; \
1084 + LL^=des_SPtrans[4][u1]; \
1085 + LL^=des_SPtrans[6][u3]; \
1086 + u2=(int)t>>8L; \
1087 + u1=(int)t&0x3f; \
1088 + u2&=0x3f; \
1089 + t>>=16L; \
1090 + LL^=des_SPtrans[1][u1]; \
1091 + LL^=des_SPtrans[3][u2]; \
1092 + u3=(int)t>>8L; \
1093 + u1=(int)t&0x3f; \
1094 + u3&=0x3f; \
1095 + LL^=des_SPtrans[5][u1]; \
1096 + LL^=des_SPtrans[7][u3]; }
1097 +#endif
1098 +#ifdef DES_RISC2
1099 +#define D_ENCRYPT(LL,R,S) {\
1100 + unsigned int u1,u2,s1,s2; \
1101 + LOAD_DATA(R,S,u,t,E0,E1,u1); \
1102 + u>>=2L; \
1103 + t=ROTATE(t,6); \
1104 + u2=(int)u>>8L; \
1105 + u1=(int)u&0x3f; \
1106 + u2&=0x3f; \
1107 + LL^=des_SPtrans[0][u1]; \
1108 + LL^=des_SPtrans[2][u2]; \
1109 + s1=(int)u>>16L; \
1110 + s2=(int)u>>24L; \
1111 + s1&=0x3f; \
1112 + s2&=0x3f; \
1113 + LL^=des_SPtrans[4][s1]; \
1114 + LL^=des_SPtrans[6][s2]; \
1115 + u2=(int)t>>8L; \
1116 + u1=(int)t&0x3f; \
1117 + u2&=0x3f; \
1118 + LL^=des_SPtrans[1][u1]; \
1119 + LL^=des_SPtrans[3][u2]; \
1120 + s1=(int)t>>16; \
1121 + s2=(int)t>>24L; \
1122 + s1&=0x3f; \
1123 + s2&=0x3f; \
1124 + LL^=des_SPtrans[5][s1]; \
1125 + LL^=des_SPtrans[7][s2]; }
1126 +#endif
1127 +
1128 +#else
1129 +
1130 +#define D_ENCRYPT(LL,R,S) {\
1131 + LOAD_DATA_tmp(R,S,u,t,E0,E1); \
1132 + t=ROTATE(t,4); \
1133 + LL^=\
1134 + des_SPtrans[0][(u>> 2L)&0x3f]^ \
1135 + des_SPtrans[2][(u>>10L)&0x3f]^ \
1136 + des_SPtrans[4][(u>>18L)&0x3f]^ \
1137 + des_SPtrans[6][(u>>26L)&0x3f]^ \
1138 + des_SPtrans[1][(t>> 2L)&0x3f]^ \
1139 + des_SPtrans[3][(t>>10L)&0x3f]^ \
1140 + des_SPtrans[5][(t>>18L)&0x3f]^ \
1141 + des_SPtrans[7][(t>>26L)&0x3f]; }
1142 +#endif
1143 +#endif
1144 +
1145 + /* IP and FP
1146 + * The problem is more of a geometric problem that random bit fiddling.
1147 + 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
1148 + 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
1149 + 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
1150 + 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
1151 +
1152 + 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
1153 + 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
1154 + 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
1155 + 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
1156 +
1157 + The output has been subject to swaps of the form
1158 + 0 1 -> 3 1 but the odd and even bits have been put into
1159 + 2 3 2 0
1160 + different words. The main trick is to remember that
1161 + t=((l>>size)^r)&(mask);
1162 + r^=t;
1163 + l^=(t<<size);
1164 + can be used to swap and move bits between words.
1165 +
1166 + So l = 0 1 2 3 r = 16 17 18 19
1167 + 4 5 6 7 20 21 22 23
1168 + 8 9 10 11 24 25 26 27
1169 + 12 13 14 15 28 29 30 31
1170 + becomes (for size == 2 and mask == 0x3333)
1171 + t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
1172 + 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
1173 + 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
1174 + 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
1175 +
1176 + Thanks for hints from Richard Outerbridge - he told me IP&FP
1177 + could be done in 15 xor, 10 shifts and 5 ands.
1178 + When I finally started to think of the problem in 2D
1179 + I first got ~42 operations without xors. When I remembered
1180 + how to use xors :-) I got it to its final state.
1181 + */
1182 +#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
1183 + (b)^=(t),\
1184 + (a)^=((t)<<(n)))
1185 +
1186 +#define IP(l,r) \
1187 + { \
1188 + register DES_LONG tt; \
1189 + PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
1190 + PERM_OP(l,r,tt,16,0x0000ffffL); \
1191 + PERM_OP(r,l,tt, 2,0x33333333L); \
1192 + PERM_OP(l,r,tt, 8,0x00ff00ffL); \
1193 + PERM_OP(r,l,tt, 1,0x55555555L); \
1194 + }
1195 +
1196 +#define FP(l,r) \
1197 + { \
1198 + register DES_LONG tt; \
1199 + PERM_OP(l,r,tt, 1,0x55555555L); \
1200 + PERM_OP(r,l,tt, 8,0x00ff00ffL); \
1201 + PERM_OP(l,r,tt, 2,0x33333333L); \
1202 + PERM_OP(r,l,tt,16,0x0000ffffL); \
1203 + PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
1204 + }
1205 +
1206 +extern const DES_LONG des_SPtrans[8][64];
1207 +
1208 +#ifndef NOPROTO
1209 +void fcrypt_body(DES_LONG *out,des_key_schedule ks,
1210 + DES_LONG Eswap0, DES_LONG Eswap1);
1211 +#else
1212 +void fcrypt_body();
1213 +#endif
1214 +
1215 +#endif
1216 --- /dev/null Tue Mar 11 13:02:56 2003
1217 +++ linux/include/des/des_ver.h Mon Feb 9 13:51:03 2004
1218 @@ -0,0 +1,60 @@
1219 +/* crypto/des/des_ver.h */
1220 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
1221 + * All rights reserved.
1222 + *
1223 + * This package is an SSL implementation written
1224 + * by Eric Young (eay@cryptsoft.com).
1225 + * The implementation was written so as to conform with Netscapes SSL.
1226 + *
1227 + * This library is free for commercial and non-commercial use as long as
1228 + * the following conditions are aheared to. The following conditions
1229 + * apply to all code found in this distribution, be it the RC4, RSA,
1230 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1231 + * included with this distribution is covered by the same copyright terms
1232 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1233 + *
1234 + * Copyright remains Eric Young's, and as such any Copyright notices in
1235 + * the code are not to be removed.
1236 + * If this package is used in a product, Eric Young should be given attribution
1237 + * as the author of the parts of the library used.
1238 + * This can be in the form of a textual message at program startup or
1239 + * in documentation (online or textual) provided with the package.
1240 + *
1241 + * Redistribution and use in source and binary forms, with or without
1242 + * modification, are permitted provided that the following conditions
1243 + * are met:
1244 + * 1. Redistributions of source code must retain the copyright
1245 + * notice, this list of conditions and the following disclaimer.
1246 + * 2. Redistributions in binary form must reproduce the above copyright
1247 + * notice, this list of conditions and the following disclaimer in the
1248 + * documentation and/or other materials provided with the distribution.
1249 + * 3. All advertising materials mentioning features or use of this software
1250 + * must display the following acknowledgement:
1251 + * "This product includes cryptographic software written by
1252 + * Eric Young (eay@cryptsoft.com)"
1253 + * The word 'cryptographic' can be left out if the rouines from the library
1254 + * being used are not cryptographic related :-).
1255 + * 4. If you include any Windows specific code (or a derivative thereof) from
1256 + * the apps directory (application code) you must include an acknowledgement:
1257 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1258 + *
1259 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1260 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1261 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1262 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1263 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1264 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1265 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1266 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1267 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1268 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1269 + * SUCH DAMAGE.
1270 + *
1271 + * The licence and distribution terms for any publically available version or
1272 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1273 + * copied and put under another distribution licence
1274 + * [including the GNU Public Licence.]
1275 + */
1276 +
1277 +extern char *DES_version; /* SSLeay version string */
1278 +extern char *libdes_version; /* old libdes version string */
1279 --- /dev/null Tue Mar 11 13:02:56 2003
1280 +++ linux/include/des/podd.h Mon Feb 9 13:51:03 2004
1281 @@ -0,0 +1,75 @@
1282 +/* crypto/des/podd.h */
1283 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
1284 + * All rights reserved.
1285 + *
1286 + * This package is an SSL implementation written
1287 + * by Eric Young (eay@cryptsoft.com).
1288 + * The implementation was written so as to conform with Netscapes SSL.
1289 + *
1290 + * This library is free for commercial and non-commercial use as long as
1291 + * the following conditions are aheared to. The following conditions
1292 + * apply to all code found in this distribution, be it the RC4, RSA,
1293 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1294 + * included with this distribution is covered by the same copyright terms
1295 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1296 + *
1297 + * Copyright remains Eric Young's, and as such any Copyright notices in
1298 + * the code are not to be removed.
1299 + * If this package is used in a product, Eric Young should be given attribution
1300 + * as the author of the parts of the library used.
1301 + * This can be in the form of a textual message at program startup or
1302 + * in documentation (online or textual) provided with the package.
1303 + *
1304 + * Redistribution and use in source and binary forms, with or without
1305 + * modification, are permitted provided that the following conditions
1306 + * are met:
1307 + * 1. Redistributions of source code must retain the copyright
1308 + * notice, this list of conditions and the following disclaimer.
1309 + * 2. Redistributions in binary form must reproduce the above copyright
1310 + * notice, this list of conditions and the following disclaimer in the
1311 + * documentation and/or other materials provided with the distribution.
1312 + * 3. All advertising materials mentioning features or use of this software
1313 + * must display the following acknowledgement:
1314 + * "This product includes cryptographic software written by
1315 + * Eric Young (eay@cryptsoft.com)"
1316 + * The word 'cryptographic' can be left out if the rouines from the library
1317 + * being used are not cryptographic related :-).
1318 + * 4. If you include any Windows specific code (or a derivative thereof) from
1319 + * the apps directory (application code) you must include an acknowledgement:
1320 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1321 + *
1322 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1323 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1324 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1325 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1326 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1327 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1328 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1329 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1330 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1331 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1332 + * SUCH DAMAGE.
1333 + *
1334 + * The licence and distribution terms for any publically available version or
1335 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1336 + * copied and put under another distribution licence
1337 + * [including the GNU Public Licence.]
1338 + */
1339 +
1340 +static const unsigned char odd_parity[256]={
1341 + 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
1342 + 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
1343 + 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
1344 + 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
1345 + 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
1346 + 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
1347 + 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
1348 +112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
1349 +128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
1350 +145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
1351 +161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
1352 +176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
1353 +193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
1354 +208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
1355 +224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
1356 +241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
1357 --- /dev/null Tue Mar 11 13:02:56 2003
1358 +++ linux/include/des/sk.h Mon Feb 9 13:51:03 2004
1359 @@ -0,0 +1,204 @@
1360 +/* crypto/des/sk.h */
1361 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
1362 + * All rights reserved.
1363 + *
1364 + * This package is an SSL implementation written
1365 + * by Eric Young (eay@cryptsoft.com).
1366 + * The implementation was written so as to conform with Netscapes SSL.
1367 + *
1368 + * This library is free for commercial and non-commercial use as long as
1369 + * the following conditions are aheared to. The following conditions
1370 + * apply to all code found in this distribution, be it the RC4, RSA,
1371 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1372 + * included with this distribution is covered by the same copyright terms
1373 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1374 + *
1375 + * Copyright remains Eric Young's, and as such any Copyright notices in
1376 + * the code are not to be removed.
1377 + * If this package is used in a product, Eric Young should be given attribution
1378 + * as the author of the parts of the library used.
1379 + * This can be in the form of a textual message at program startup or
1380 + * in documentation (online or textual) provided with the package.
1381 + *
1382 + * Redistribution and use in source and binary forms, with or without
1383 + * modification, are permitted provided that the following conditions
1384 + * are met:
1385 + * 1. Redistributions of source code must retain the copyright
1386 + * notice, this list of conditions and the following disclaimer.
1387 + * 2. Redistributions in binary form must reproduce the above copyright
1388 + * notice, this list of conditions and the following disclaimer in the
1389 + * documentation and/or other materials provided with the distribution.
1390 + * 3. All advertising materials mentioning features or use of this software
1391 + * must display the following acknowledgement:
1392 + * "This product includes cryptographic software written by
1393 + * Eric Young (eay@cryptsoft.com)"
1394 + * The word 'cryptographic' can be left out if the rouines from the library
1395 + * being used are not cryptographic related :-).
1396 + * 4. If you include any Windows specific code (or a derivative thereof) from
1397 + * the apps directory (application code) you must include an acknowledgement:
1398 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1399 + *
1400 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1401 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1402 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1403 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1404 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1405 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1406 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1407 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1408 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1409 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1410 + * SUCH DAMAGE.
1411 + *
1412 + * The licence and distribution terms for any publically available version or
1413 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1414 + * copied and put under another distribution licence
1415 + * [including the GNU Public Licence.]
1416 + */
1417 +
1418 +static const DES_LONG des_skb[8][64]={
1419 +{
1420 +/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
1421 +0x00000000L,0x00000010L,0x20000000L,0x20000010L,
1422 +0x00010000L,0x00010010L,0x20010000L,0x20010010L,
1423 +0x00000800L,0x00000810L,0x20000800L,0x20000810L,
1424 +0x00010800L,0x00010810L,0x20010800L,0x20010810L,
1425 +0x00000020L,0x00000030L,0x20000020L,0x20000030L,
1426 +0x00010020L,0x00010030L,0x20010020L,0x20010030L,
1427 +0x00000820L,0x00000830L,0x20000820L,0x20000830L,
1428 +0x00010820L,0x00010830L,0x20010820L,0x20010830L,
1429 +0x00080000L,0x00080010L,0x20080000L,0x20080010L,
1430 +0x00090000L,0x00090010L,0x20090000L,0x20090010L,
1431 +0x00080800L,0x00080810L,0x20080800L,0x20080810L,
1432 +0x00090800L,0x00090810L,0x20090800L,0x20090810L,
1433 +0x00080020L,0x00080030L,0x20080020L,0x20080030L,
1434 +0x00090020L,0x00090030L,0x20090020L,0x20090030L,
1435 +0x00080820L,0x00080830L,0x20080820L,0x20080830L,
1436 +0x00090820L,0x00090830L,0x20090820L,0x20090830L,
1437 +},{
1438 +/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
1439 +0x00000000L,0x02000000L,0x00002000L,0x02002000L,
1440 +0x00200000L,0x02200000L,0x00202000L,0x02202000L,
1441 +0x00000004L,0x02000004L,0x00002004L,0x02002004L,
1442 +0x00200004L,0x02200004L,0x00202004L,0x02202004L,
1443 +0x00000400L,0x02000400L,0x00002400L,0x02002400L,
1444 +0x00200400L,0x02200400L,0x00202400L,0x02202400L,
1445 +0x00000404L,0x02000404L,0x00002404L,0x02002404L,
1446 +0x00200404L,0x02200404L,0x00202404L,0x02202404L,
1447 +0x10000000L,0x12000000L,0x10002000L,0x12002000L,
1448 +0x10200000L,0x12200000L,0x10202000L,0x12202000L,
1449 +0x10000004L,0x12000004L,0x10002004L,0x12002004L,
1450 +0x10200004L,0x12200004L,0x10202004L,0x12202004L,
1451 +0x10000400L,0x12000400L,0x10002400L,0x12002400L,
1452 +0x10200400L,0x12200400L,0x10202400L,0x12202400L,
1453 +0x10000404L,0x12000404L,0x10002404L,0x12002404L,
1454 +0x10200404L,0x12200404L,0x10202404L,0x12202404L,
1455 +},{
1456 +/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
1457 +0x00000000L,0x00000001L,0x00040000L,0x00040001L,
1458 +0x01000000L,0x01000001L,0x01040000L,0x01040001L,
1459 +0x00000002L,0x00000003L,0x00040002L,0x00040003L,
1460 +0x01000002L,0x01000003L,0x01040002L,0x01040003L,
1461 +0x00000200L,0x00000201L,0x00040200L,0x00040201L,
1462 +0x01000200L,0x01000201L,0x01040200L,0x01040201L,
1463 +0x00000202L,0x00000203L,0x00040202L,0x00040203L,
1464 +0x01000202L,0x01000203L,0x01040202L,0x01040203L,
1465 +0x08000000L,0x08000001L,0x08040000L,0x08040001L,
1466 +0x09000000L,0x09000001L,0x09040000L,0x09040001L,
1467 +0x08000002L,0x08000003L,0x08040002L,0x08040003L,
1468 +0x09000002L,0x09000003L,0x09040002L,0x09040003L,
1469 +0x08000200L,0x08000201L,0x08040200L,0x08040201L,
1470 +0x09000200L,0x09000201L,0x09040200L,0x09040201L,
1471 +0x08000202L,0x08000203L,0x08040202L,0x08040203L,
1472 +0x09000202L,0x09000203L,0x09040202L,0x09040203L,
1473 +},{
1474 +/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
1475 +0x00000000L,0x00100000L,0x00000100L,0x00100100L,
1476 +0x00000008L,0x00100008L,0x00000108L,0x00100108L,
1477 +0x00001000L,0x00101000L,0x00001100L,0x00101100L,
1478 +0x00001008L,0x00101008L,0x00001108L,0x00101108L,
1479 +0x04000000L,0x04100000L,0x04000100L,0x04100100L,
1480 +0x04000008L,0x04100008L,0x04000108L,0x04100108L,
1481 +0x04001000L,0x04101000L,0x04001100L,0x04101100L,
1482 +0x04001008L,0x04101008L,0x04001108L,0x04101108L,
1483 +0x00020000L,0x00120000L,0x00020100L,0x00120100L,
1484 +0x00020008L,0x00120008L,0x00020108L,0x00120108L,
1485 +0x00021000L,0x00121000L,0x00021100L,0x00121100L,
1486 +0x00021008L,0x00121008L,0x00021108L,0x00121108L,
1487 +0x04020000L,0x04120000L,0x04020100L,0x04120100L,
1488 +0x04020008L,0x04120008L,0x04020108L,0x04120108L,
1489 +0x04021000L,0x04121000L,0x04021100L,0x04121100L,
1490 +0x04021008L,0x04121008L,0x04021108L,0x04121108L,
1491 +},{
1492 +/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
1493 +0x00000000L,0x10000000L,0x00010000L,0x10010000L,
1494 +0x00000004L,0x10000004L,0x00010004L,0x10010004L,
1495 +0x20000000L,0x30000000L,0x20010000L,0x30010000L,
1496 +0x20000004L,0x30000004L,0x20010004L,0x30010004L,
1497 +0x00100000L,0x10100000L,0x00110000L,0x10110000L,
1498 +0x00100004L,0x10100004L,0x00110004L,0x10110004L,
1499 +0x20100000L,0x30100000L,0x20110000L,0x30110000L,
1500 +0x20100004L,0x30100004L,0x20110004L,0x30110004L,
1501 +0x00001000L,0x10001000L,0x00011000L,0x10011000L,
1502 +0x00001004L,0x10001004L,0x00011004L,0x10011004L,
1503 +0x20001000L,0x30001000L,0x20011000L,0x30011000L,
1504 +0x20001004L,0x30001004L,0x20011004L,0x30011004L,
1505 +0x00101000L,0x10101000L,0x00111000L,0x10111000L,
1506 +0x00101004L,0x10101004L,0x00111004L,0x10111004L,
1507 +0x20101000L,0x30101000L,0x20111000L,0x30111000L,
1508 +0x20101004L,0x30101004L,0x20111004L,0x30111004L,
1509 +},{
1510 +/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
1511 +0x00000000L,0x08000000L,0x00000008L,0x08000008L,
1512 +0x00000400L,0x08000400L,0x00000408L,0x08000408L,
1513 +0x00020000L,0x08020000L,0x00020008L,0x08020008L,
1514 +0x00020400L,0x08020400L,0x00020408L,0x08020408L,
1515 +0x00000001L,0x08000001L,0x00000009L,0x08000009L,
1516 +0x00000401L,0x08000401L,0x00000409L,0x08000409L,
1517 +0x00020001L,0x08020001L,0x00020009L,0x08020009L,
1518 +0x00020401L,0x08020401L,0x00020409L,0x08020409L,
1519 +0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
1520 +0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
1521 +0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
1522 +0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
1523 +0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
1524 +0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
1525 +0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
1526 +0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
1527 +},{
1528 +/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
1529 +0x00000000L,0x00000100L,0x00080000L,0x00080100L,
1530 +0x01000000L,0x01000100L,0x01080000L,0x01080100L,
1531 +0x00000010L,0x00000110L,0x00080010L,0x00080110L,
1532 +0x01000010L,0x01000110L,0x01080010L,0x01080110L,
1533 +0x00200000L,0x00200100L,0x00280000L,0x00280100L,
1534 +0x01200000L,0x01200100L,0x01280000L,0x01280100L,
1535 +0x00200010L,0x00200110L,0x00280010L,0x00280110L,
1536 +0x01200010L,0x01200110L,0x01280010L,0x01280110L,
1537 +0x00000200L,0x00000300L,0x00080200L,0x00080300L,
1538 +0x01000200L,0x01000300L,0x01080200L,0x01080300L,
1539 +0x00000210L,0x00000310L,0x00080210L,0x00080310L,
1540 +0x01000210L,0x01000310L,0x01080210L,0x01080310L,
1541 +0x00200200L,0x00200300L,0x00280200L,0x00280300L,
1542 +0x01200200L,0x01200300L,0x01280200L,0x01280300L,
1543 +0x00200210L,0x00200310L,0x00280210L,0x00280310L,
1544 +0x01200210L,0x01200310L,0x01280210L,0x01280310L,
1545 +},{
1546 +/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
1547 +0x00000000L,0x04000000L,0x00040000L,0x04040000L,
1548 +0x00000002L,0x04000002L,0x00040002L,0x04040002L,
1549 +0x00002000L,0x04002000L,0x00042000L,0x04042000L,
1550 +0x00002002L,0x04002002L,0x00042002L,0x04042002L,
1551 +0x00000020L,0x04000020L,0x00040020L,0x04040020L,
1552 +0x00000022L,0x04000022L,0x00040022L,0x04040022L,
1553 +0x00002020L,0x04002020L,0x00042020L,0x04042020L,
1554 +0x00002022L,0x04002022L,0x00042022L,0x04042022L,
1555 +0x00000800L,0x04000800L,0x00040800L,0x04040800L,
1556 +0x00000802L,0x04000802L,0x00040802L,0x04040802L,
1557 +0x00002800L,0x04002800L,0x00042800L,0x04042800L,
1558 +0x00002802L,0x04002802L,0x00042802L,0x04042802L,
1559 +0x00000820L,0x04000820L,0x00040820L,0x04040820L,
1560 +0x00000822L,0x04000822L,0x00040822L,0x04040822L,
1561 +0x00002820L,0x04002820L,0x00042820L,0x04042820L,
1562 +0x00002822L,0x04002822L,0x00042822L,0x04042822L,
1563 +}};
1564 --- /dev/null Tue Mar 11 13:02:56 2003
1565 +++ linux/include/des/spr.h Mon Feb 9 13:51:03 2004
1566 @@ -0,0 +1,204 @@
1567 +/* crypto/des/spr.h */
1568 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
1569 + * All rights reserved.
1570 + *
1571 + * This package is an SSL implementation written
1572 + * by Eric Young (eay@cryptsoft.com).
1573 + * The implementation was written so as to conform with Netscapes SSL.
1574 + *
1575 + * This library is free for commercial and non-commercial use as long as
1576 + * the following conditions are aheared to. The following conditions
1577 + * apply to all code found in this distribution, be it the RC4, RSA,
1578 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1579 + * included with this distribution is covered by the same copyright terms
1580 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1581 + *
1582 + * Copyright remains Eric Young's, and as such any Copyright notices in
1583 + * the code are not to be removed.
1584 + * If this package is used in a product, Eric Young should be given attribution
1585 + * as the author of the parts of the library used.
1586 + * This can be in the form of a textual message at program startup or
1587 + * in documentation (online or textual) provided with the package.
1588 + *
1589 + * Redistribution and use in source and binary forms, with or without
1590 + * modification, are permitted provided that the following conditions
1591 + * are met:
1592 + * 1. Redistributions of source code must retain the copyright
1593 + * notice, this list of conditions and the following disclaimer.
1594 + * 2. Redistributions in binary form must reproduce the above copyright
1595 + * notice, this list of conditions and the following disclaimer in the
1596 + * documentation and/or other materials provided with the distribution.
1597 + * 3. All advertising materials mentioning features or use of this software
1598 + * must display the following acknowledgement:
1599 + * "This product includes cryptographic software written by
1600 + * Eric Young (eay@cryptsoft.com)"
1601 + * The word 'cryptographic' can be left out if the rouines from the library
1602 + * being used are not cryptographic related :-).
1603 + * 4. If you include any Windows specific code (or a derivative thereof) from
1604 + * the apps directory (application code) you must include an acknowledgement:
1605 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1606 + *
1607 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1608 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1609 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1610 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1611 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1612 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1613 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1614 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1615 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1616 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1617 + * SUCH DAMAGE.
1618 + *
1619 + * The licence and distribution terms for any publically available version or
1620 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1621 + * copied and put under another distribution licence
1622 + * [including the GNU Public Licence.]
1623 + */
1624 +
1625 +const DES_LONG des_SPtrans[8][64]={
1626 +{
1627 +/* nibble 0 */
1628 +0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
1629 +0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
1630 +0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
1631 +0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
1632 +0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
1633 +0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
1634 +0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
1635 +0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
1636 +0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
1637 +0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
1638 +0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
1639 +0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
1640 +0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
1641 +0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
1642 +0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
1643 +0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
1644 +},{
1645 +/* nibble 1 */
1646 +0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
1647 +0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
1648 +0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
1649 +0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
1650 +0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
1651 +0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
1652 +0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
1653 +0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
1654 +0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
1655 +0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
1656 +0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
1657 +0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
1658 +0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
1659 +0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
1660 +0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
1661 +0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
1662 +},{
1663 +/* nibble 2 */
1664 +0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
1665 +0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
1666 +0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
1667 +0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
1668 +0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
1669 +0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
1670 +0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
1671 +0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
1672 +0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
1673 +0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
1674 +0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
1675 +0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
1676 +0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
1677 +0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
1678 +0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
1679 +0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
1680 +},{
1681 +/* nibble 3 */
1682 +0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
1683 +0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
1684 +0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
1685 +0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
1686 +0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
1687 +0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
1688 +0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
1689 +0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
1690 +0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
1691 +0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
1692 +0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
1693 +0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
1694 +0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
1695 +0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
1696 +0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
1697 +0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
1698 +},{
1699 +/* nibble 4 */
1700 +0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
1701 +0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
1702 +0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
1703 +0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
1704 +0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
1705 +0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
1706 +0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
1707 +0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
1708 +0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
1709 +0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
1710 +0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
1711 +0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
1712 +0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
1713 +0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
1714 +0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
1715 +0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
1716 +},{
1717 +/* nibble 5 */
1718 +0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
1719 +0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
1720 +0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
1721 +0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
1722 +0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
1723 +0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
1724 +0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
1725 +0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
1726 +0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
1727 +0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
1728 +0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
1729 +0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
1730 +0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
1731 +0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
1732 +0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
1733 +0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
1734 +},{
1735 +/* nibble 6 */
1736 +0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
1737 +0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
1738 +0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
1739 +0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
1740 +0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
1741 +0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
1742 +0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
1743 +0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
1744 +0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
1745 +0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
1746 +0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
1747 +0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
1748 +0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
1749 +0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
1750 +0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
1751 +0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
1752 +},{
1753 +/* nibble 7 */
1754 +0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
1755 +0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
1756 +0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
1757 +0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
1758 +0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
1759 +0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
1760 +0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
1761 +0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
1762 +0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
1763 +0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
1764 +0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
1765 +0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
1766 +0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
1767 +0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
1768 +0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
1769 +0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
1770 +}};
1771 --- /dev/null Tue Mar 11 13:02:56 2003
1772 +++ linux/include/mast.h Mon Feb 9 13:51:03 2004
1773 @@ -0,0 +1,33 @@
1774 +struct mast_callbacks {
1775 + int (*packet_encap)(struct device *mast, void *context,
1776 + struct sk_buff *skb, int flowref);
1777 + int (*link_inquire)(struct device *mast, void *context);
1778 +};
1779 +
1780 +
1781 +struct device *mast_init (int family,
1782 + struct mast_callbacks *callbacks,
1783 + unsigned int flags,
1784 + unsigned int desired_unit,
1785 + unsigned int max_flowref,
1786 + void *context);
1787 +
1788 +int mast_destroy(struct device *mast);
1789 +
1790 +int mast_recv(struct device *mast, struct sk_buff *skb, int flowref);
1791 +
1792 +/* free this skb as being useless, increment failure count. */
1793 +int mast_toast(struct device *mast, struct sk_buff *skb, int flowref);
1794 +
1795 +int mast_linkstat (struct device *mast, int flowref,
1796 + int status);
1797 +
1798 +int mast_setreference (struct device *mast,
1799 + int defaultSA);
1800 +
1801 +int mast_setneighbor (struct device *mast,
1802 + struct sockaddr *source,
1803 + struct sockaddr *destination,
1804 + int flowref);
1805 +
1806 +
1807 --- /dev/null Tue Mar 11 13:02:56 2003
1808 +++ linux/include/openswan.h Mon Feb 9 13:51:03 2004
1809 @@ -0,0 +1,559 @@
1810 +#ifndef _OPENSWAN_H
1811 +/*
1812 + * header file for FreeS/WAN library functions
1813 + * Copyright (C) 1998, 1999, 2000 Henry Spencer.
1814 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
1815 + *
1816 + * This library is free software; you can redistribute it and/or modify it
1817 + * under the terms of the GNU Library General Public License as published by
1818 + * the Free Software Foundation; either version 2 of the License, or (at your
1819 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
1820 + *
1821 + * This library is distributed in the hope that it will be useful, but
1822 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1823 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
1824 + * License for more details.
1825 + *
1826 + * RCSID $Id: openswan.h,v 1.95 2005/08/25 01:24:40 paul Exp $
1827 + */
1828 +#define _OPENSWAN_H /* seen it, no need to see it again */
1829 +
1830 +/* you'd think this should be builtin to compiler... */
1831 +#ifndef TRUE
1832 +#define TRUE 1
1833 +#endif
1834 +
1835 +#ifndef FALSE
1836 +#define FALSE 0
1837 +#endif
1838 +
1839 +
1840 +
1841 +/*
1842 + * We've just got to have some datatypes defined... And annoyingly, just
1843 + * where we get them depends on whether we're in userland or not.
1844 + */
1845 +/* things that need to come from one place or the other, depending */
1846 +#if defined(linux)
1847 +#if defined(__KERNEL__)
1848 +#include <linux/types.h>
1849 +#include <linux/socket.h>
1850 +#include <linux/in.h>
1851 +#include <linux/in6.h>
1852 +#include <linux/string.h>
1853 +#include <linux/ctype.h>
1854 +#define user_assert(foo) /*nothing*/
1855 +#else
1856 +#include <sys/types.h>
1857 +#include <netinet/in.h>
1858 +#include <string.h>
1859 +#include <ctype.h>
1860 +#include <assert.h>
1861 +#define user_assert(foo) assert(foo)
1862 +#include <stdio.h>
1863 +
1864 +# define uint8_t u_int8_t
1865 +# define uint16_t u_int16_t
1866 +# define uint32_t u_int32_t
1867 +# define uint64_t u_int64_t
1868 +
1869 +
1870 +
1871 +#endif /* __KERNEL__ */
1872 +
1873 +#define DEBUG_NO_STATIC static
1874 +#include <openswan/ipsec_kversion.h>
1875 +#include <openswan/ipsec_param.h>
1876 +#endif /* linux */
1877 +
1878 +/*
1879 + * Yes Virginia, we have started a windows port.
1880 + */
1881 +#if defined(__CYGWIN32__)
1882 +#if !defined(WIN32_KERNEL)
1883 +/* get windows equivalents */
1884 +#include <stdio.h>
1885 +#include <string.h>
1886 +#include <win32/types.h>
1887 +#include <netinet/in.h>
1888 +#include <cygwin/socket.h>
1889 +#include <assert.h>
1890 +#define user_assert(foo) assert(foo)
1891 +#endif /* _KERNEL */
1892 +#endif /* WIN32 */
1893 +
1894 +/*
1895 + * Kovacs? A macosx port?
1896 + */
1897 +#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
1898 +#include <TargetConditionals.h>
1899 +#include <AvailabilityMacros.h>
1900 +#include <machine/types.h>
1901 +#include <machine/endian.h>
1902 +#include <stdint.h>
1903 +#include <stddef.h>
1904 +#include <stdio.h>
1905 +#include <time.h>
1906 +#include <sys/time.h>
1907 +#include <string.h>
1908 +#include <netinet/in.h>
1909 +#include <arpa/inet.h>
1910 +#include <tcpd.h>
1911 +#include <assert.h>
1912 +#define user_assert(foo) assert(foo)
1913 +#define __u32 unsigned int
1914 +#define __u8 unsigned char
1915 +#define s6_addr16 __u6_addr.__u6_addr16
1916 +#define DEBUG_NO_STATIC static
1917 +#endif
1918 +
1919 +/*
1920 + * FreeBSD
1921 + */
1922 +#if defined(__FreeBSD__)
1923 +# define DEBUG_NO_STATIC static
1924 +#include <sys/types.h>
1925 +#include <netinet/in.h>
1926 +#include <sys/socket.h>
1927 +#include <arpa/inet.h>
1928 +#include <string.h>
1929 +#include <assert.h>
1930 +#define user_assert(foo) assert(foo)
1931 +/* apparently this way to deal with an IPv6 address is not standard. */
1932 +#define s6_addr16 __u6_addr.__u6_addr16
1933 +#endif
1934 +
1935 +
1936 +#ifndef IPPROTO_COMP
1937 +# define IPPROTO_COMP 108
1938 +#endif /* !IPPROTO_COMP */
1939 +
1940 +#ifndef IPPROTO_INT
1941 +# define IPPROTO_INT 61
1942 +#endif /* !IPPROTO_INT */
1943 +
1944 +#if !defined(ESPINUDP_WITH_NON_IKE)
1945 +#define ESPINUDP_WITH_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
1946 +#define ESPINUDP_WITH_NON_ESP 2 /* draft-ietf-ipsec-nat-t-ike-02 */
1947 +#endif
1948 +
1949 +/*
1950 + * Basic data types for the address-handling functions.
1951 + * ip_address and ip_subnet are supposed to be opaque types; do not
1952 + * use their definitions directly, they are subject to change!
1953 + */
1954 +
1955 +/* first, some quick fakes in case we're on an old system with no IPv6 */
1956 +#if !defined(s6_addr16) && defined(__CYGWIN32__)
1957 +struct in6_addr {
1958 + union
1959 + {
1960 + u_int8_t u6_addr8[16];
1961 + u_int16_t u6_addr16[8];
1962 + u_int32_t u6_addr32[4];
1963 + } in6_u;
1964 +#define s6_addr in6_u.u6_addr8
1965 +#define s6_addr16 in6_u.u6_addr16
1966 +#define s6_addr32 in6_u.u6_addr32
1967 +};
1968 +struct sockaddr_in6 {
1969 + unsigned short int sin6_family; /* AF_INET6 */
1970 + __u16 sin6_port; /* Transport layer port # */
1971 + __u32 sin6_flowinfo; /* IPv6 flow information */
1972 + struct in6_addr sin6_addr; /* IPv6 address */
1973 + __u32 sin6_scope_id; /* scope id (new in RFC2553) */
1974 +};
1975 +#endif /* !s6_addr16 */
1976 +
1977 +/* then the main types */
1978 +typedef struct {
1979 + union {
1980 + struct sockaddr_in v4;
1981 + struct sockaddr_in6 v6;
1982 + } u;
1983 +} ip_address;
1984 +typedef struct {
1985 + ip_address addr;
1986 + int maskbits;
1987 +} ip_subnet;
1988 +
1989 +/* and the SA ID stuff */
1990 +#ifdef __KERNEL__
1991 +typedef __u32 ipsec_spi_t;
1992 +#else
1993 +typedef u_int32_t ipsec_spi_t;
1994 +#endif
1995 +typedef struct { /* to identify an SA, we need: */
1996 + ip_address dst; /* A. destination host */
1997 + ipsec_spi_t spi; /* B. 32-bit SPI, assigned by dest. host */
1998 +# define SPI_PASS 256 /* magic values... */
1999 +# define SPI_DROP 257 /* ...for use... */
2000 +# define SPI_REJECT 258 /* ...with SA_INT */
2001 +# define SPI_HOLD 259
2002 +# define SPI_TRAP 260
2003 +# define SPI_TRAPSUBNET 261
2004 + int proto; /* C. protocol */
2005 +# define SA_ESP 50 /* IPPROTO_ESP */
2006 +# define SA_AH 51 /* IPPROTO_AH */
2007 +# define SA_IPIP 4 /* IPPROTO_IPIP */
2008 +# define SA_COMP 108 /* IPPROTO_COMP */
2009 +# define SA_INT 61 /* IANA reserved for internal use */
2010 +} ip_said;
2011 +
2012 +/* misc */
2013 +typedef const char *err_t; /* error message, or NULL for success */
2014 +struct prng { /* pseudo-random-number-generator guts */
2015 + unsigned char sbox[256];
2016 + int i, j;
2017 + unsigned long count;
2018 +};
2019 +
2020 +
2021 +/*
2022 + * definitions for user space, taken from freeswan/ipsec_sa.h
2023 + */
2024 +typedef uint32_t IPsecSAref_t;
2025 +
2026 +/* Translation to/from nfmark.
2027 + *
2028 + * use bits 16-31. Leave bit 32 as a indicate that IPsec processing
2029 + * has already been done.
2030 + */
2031 +#define IPSEC_SA_REF_TABLE_IDX_WIDTH 15
2032 +#define IPSEC_SA_REF_TABLE_OFFSET 16
2033 +#define IPSEC_SA_REF_MAASK ((1<<IPSEC_SA_REF_TABLE_IDX_WIDTH)-1)
2034 +
2035 +#define IPsecSAref2NFmark(x) (((x)&IPSEC_SA_REF_MASK) << IPSEC_SA_REF_TABLE_OFFSET)
2036 +#define NFmark2IPsecSAref(x) (((x) >> IPSEC_SA_REF_TABLE_OFFSET)&IPSEC_SA_REF_MASK)
2037 +
2038 +#define IPSEC_SAREF_NULL ((IPsecSAref_t)0)
2039 +#define IPSEC_SAREF_NA ((IPsecSAref_t)0xffff0001)
2040 +
2041 +/* GCC magic for use in function definitions! */
2042 +#ifdef GCC_LINT
2043 +# define PRINTF_LIKE(n) __attribute__ ((format(printf, n, n+1)))
2044 +# define NEVER_RETURNS __attribute__ ((noreturn))
2045 +# define UNUSED __attribute__ ((unused))
2046 +# define BLANK_FORMAT " " /* GCC_LINT whines about empty formats */
2047 +#else
2048 +# define PRINTF_LIKE(n) /* ignore */
2049 +# define NEVER_RETURNS /* ignore */
2050 +# define UNUSED /* ignore */
2051 +# define BLANK_FORMAT ""
2052 +#endif
2053 +
2054 +
2055 +/*
2056 + * function to log stuff from libraries that may be used in multiple
2057 + * places.
2058 + */
2059 +typedef int (*openswan_keying_debug_func_t)(const char *message, ...);
2060 +
2061 +
2062 +
2063 +/*
2064 + * new IPv6-compatible functions
2065 + */
2066 +
2067 +/* text conversions */
2068 +err_t ttoul(const char *src, size_t srclen, int format, unsigned long *dst);
2069 +size_t ultot(unsigned long src, int format, char *buf, size_t buflen);
2070 +#define ULTOT_BUF (22+1) /* holds 64 bits in octal */
2071 +
2072 +/* looks up names in DNS */
2073 +err_t ttoaddr(const char *src, size_t srclen, int af, ip_address *dst);
2074 +
2075 +/* does not look up names in DNS */
2076 +err_t ttoaddr_num(const char *src, size_t srclen, int af, ip_address *dst);
2077 +
2078 +err_t tnatoaddr(const char *src, size_t srclen, int af, ip_address *dst);
2079 +size_t addrtot(const ip_address *src, int format, char *buf, size_t buflen);
2080 +/* RFC 1886 old IPv6 reverse-lookup format is the bulkiest */
2081 +#define ADDRTOT_BUF (32*2 + 3 + 1 + 3 + 1 + 1)
2082 +err_t ttosubnet(const char *src, size_t srclen, int af, ip_subnet *dst);
2083 +size_t subnettot(const ip_subnet *src, int format, char *buf, size_t buflen);
2084 +#define SUBNETTOT_BUF (ADDRTOT_BUF + 1 + 3)
2085 +size_t subnetporttot(const ip_subnet *src, int format, char *buf, size_t buflen);
2086 +#define SUBNETPROTOTOT_BUF (SUBNETTOTO_BUF + ULTOT_BUF)
2087 +err_t ttosa(const char *src, size_t srclen, ip_said *dst);
2088 +size_t satot(const ip_said *src, int format, char *bufptr, size_t buflen);
2089 +#define SATOT_BUF (5 + ULTOA_BUF + 1 + ADDRTOT_BUF)
2090 +err_t ttodata(const char *src, size_t srclen, int base, char *buf,
2091 + size_t buflen, size_t *needed);
2092 +err_t ttodatav(const char *src, size_t srclen, int base,
2093 + char *buf, size_t buflen, size_t *needed,
2094 + char *errp, size_t errlen, unsigned int flags);
2095 +#define TTODATAV_BUF 40 /* ttodatav's largest non-literal message */
2096 +#define TTODATAV_IGNORESPACE (1<<1) /* ignore spaces in base64 encodings*/
2097 +#define TTODATAV_SPACECOUNTS 0 /* do not ignore spaces in base64 */
2098 +
2099 +size_t datatot(const unsigned char *src, size_t srclen, int format
2100 + , char *buf, size_t buflen);
2101 +size_t keyblobtoid(const unsigned char *src, size_t srclen, char *dst,
2102 + size_t dstlen);
2103 +size_t splitkeytoid(const unsigned char *e, size_t elen, const unsigned char *m,
2104 + size_t mlen, char *dst, size_t dstlen);
2105 +#define KEYID_BUF 10 /* up to 9 text digits plus NUL */
2106 +err_t ttoprotoport(char *src, size_t src_len, u_int8_t *proto, u_int16_t *port,
2107 + int *has_port_wildcard);
2108 +
2109 +/* initializations */
2110 +void initsaid(const ip_address *addr, ipsec_spi_t spi, int proto, ip_said *dst);
2111 +err_t loopbackaddr(int af, ip_address *dst);
2112 +err_t unspecaddr(int af, ip_address *dst);
2113 +err_t anyaddr(int af, ip_address *dst);
2114 +err_t initaddr(const unsigned char *src, size_t srclen, int af, ip_address *dst);
2115 +err_t initsubnet(const ip_address *addr, int maskbits, int clash, ip_subnet *dst);
2116 +err_t addrtosubnet(const ip_address *addr, ip_subnet *dst);
2117 +
2118 +/* misc. conversions and related */
2119 +err_t rangetosubnet(const ip_address *from, const ip_address *to, ip_subnet *dst);
2120 +int addrtypeof(const ip_address *src);
2121 +int subnettypeof(const ip_subnet *src);
2122 +size_t addrlenof(const ip_address *src);
2123 +size_t addrbytesptr(const ip_address *src, const unsigned char **dst);
2124 +size_t addrbytesof(const ip_address *src, unsigned char *dst, size_t dstlen);
2125 +int masktocount(const ip_address *src);
2126 +void networkof(const ip_subnet *src, ip_address *dst);
2127 +void maskof(const ip_subnet *src, ip_address *dst);
2128 +
2129 +/* tests */
2130 +int sameaddr(const ip_address *a, const ip_address *b);
2131 +int addrcmp(const ip_address *a, const ip_address *b);
2132 +int samesubnet(const ip_subnet *a, const ip_subnet *b);
2133 +int addrinsubnet(const ip_address *a, const ip_subnet *s);
2134 +int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);
2135 +int subnetishost(const ip_subnet *s);
2136 +int samesaid(const ip_said *a, const ip_said *b);
2137 +int sameaddrtype(const ip_address *a, const ip_address *b);
2138 +int samesubnettype(const ip_subnet *a, const ip_subnet *b);
2139 +int isvalidsubnet(const ip_subnet *a);
2140 +int isanyaddr(const ip_address *src);
2141 +int isunspecaddr(const ip_address *src);
2142 +int isloopbackaddr(const ip_address *src);
2143 +
2144 +/* low-level grot */
2145 +int portof(const ip_address *src);
2146 +void setportof(int port, ip_address *dst);
2147 +struct sockaddr *sockaddrof(ip_address *src);
2148 +size_t sockaddrlenof(const ip_address *src);
2149 +
2150 +/* PRNG */
2151 +void prng_init(struct prng *prng, const unsigned char *key, size_t keylen);
2152 +void prng_bytes(struct prng *prng, unsigned char *dst, size_t dstlen);
2153 +unsigned long prng_count(struct prng *prng);
2154 +void prng_final(struct prng *prng);
2155 +
2156 +/* odds and ends */
2157 +const char *ipsec_version_code(void);
2158 +const char *ipsec_version_string(void);
2159 +const char **ipsec_copyright_notice(void);
2160 +
2161 +const char *dns_string_rr(int rr, char *buf, int bufsize);
2162 +const char *dns_string_datetime(time_t seconds,
2163 + char *buf,
2164 + int bufsize);
2165 +
2166 +
2167 +/*
2168 + * old functions, to be deleted eventually
2169 + */
2170 +
2171 +/* unsigned long */
2172 +const char * /* NULL for success, else string literal */
2173 +atoul(
2174 + const char *src,
2175 + size_t srclen, /* 0 means strlen(src) */
2176 + int base, /* 0 means figure it out */
2177 + unsigned long *resultp
2178 +);
2179 +size_t /* space needed for full conversion */
2180 +ultoa(
2181 + unsigned long n,
2182 + int base,
2183 + char *dst,
2184 + size_t dstlen
2185 +);
2186 +#define ULTOA_BUF 21 /* just large enough for largest result, */
2187 + /* assuming 64-bit unsigned long! */
2188 +
2189 +/* Internet addresses */
2190 +const char * /* NULL for success, else string literal */
2191 +atoaddr(
2192 + const char *src,
2193 + size_t srclen, /* 0 means strlen(src) */
2194 + struct in_addr *addr
2195 +);
2196 +size_t /* space needed for full conversion */
2197 +addrtoa(
2198 + struct in_addr addr,
2199 + int format, /* character; 0 means default */
2200 + char *dst,
2201 + size_t dstlen
2202 +);
2203 +#define ADDRTOA_BUF 16 /* just large enough for largest result */
2204 +
2205 +/* subnets */
2206 +const char * /* NULL for success, else string literal */
2207 +atosubnet(
2208 + const char *src,
2209 + size_t srclen, /* 0 means strlen(src) */
2210 + struct in_addr *addr,
2211 + struct in_addr *mask
2212 +);
2213 +size_t /* space needed for full conversion */
2214 +subnettoa(
2215 + struct in_addr addr,
2216 + struct in_addr mask,
2217 + int format, /* character; 0 means default */
2218 + char *dst,
2219 + size_t dstlen
2220 +);
2221 +#define SUBNETTOA_BUF 32 /* large enough for worst case result */
2222 +
2223 +/* ranges */
2224 +const char * /* NULL for success, else string literal */
2225 +atoasr(
2226 + const char *src,
2227 + size_t srclen, /* 0 means strlen(src) */
2228 + char *type, /* 'a', 's', 'r' */
2229 + struct in_addr *addrs /* two-element array */
2230 +);
2231 +size_t /* space needed for full conversion */
2232 +rangetoa(
2233 + struct in_addr *addrs, /* two-element array */
2234 + int format, /* character; 0 means default */
2235 + char *dst,
2236 + size_t dstlen
2237 +);
2238 +#define RANGETOA_BUF 34 /* large enough for worst case result */
2239 +
2240 +/* data types for SA conversion functions */
2241 +
2242 +/* generic data, e.g. keys */
2243 +const char * /* NULL for success, else string literal */
2244 +atobytes(
2245 + const char *src,
2246 + size_t srclen, /* 0 means strlen(src) */
2247 + char *dst,
2248 + size_t dstlen,
2249 + size_t *lenp /* NULL means don't bother telling me */
2250 +);
2251 +size_t /* 0 failure, else true size */
2252 +bytestoa(
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 +/* old versions of generic-data functions; deprecated */
2261 +size_t /* 0 failure, else true size */
2262 +atodata(
2263 + const char *src,
2264 + size_t srclen, /* 0 means strlen(src) */
2265 + char *dst,
2266 + size_t dstlen
2267 +);
2268 +size_t /* 0 failure, else true size */
2269 +datatoa(
2270 + const unsigned char *src,
2271 + size_t srclen,
2272 + int format, /* character; 0 means default */
2273 + char *dst,
2274 + size_t dstlen
2275 +);
2276 +
2277 +/* part extraction and special addresses */
2278 +struct in_addr
2279 +subnetof(
2280 + struct in_addr addr,
2281 + struct in_addr mask
2282 +);
2283 +struct in_addr
2284 +hostof(
2285 + struct in_addr addr,
2286 + struct in_addr mask
2287 +);
2288 +struct in_addr
2289 +broadcastof(
2290 + struct in_addr addr,
2291 + struct in_addr mask
2292 +);
2293 +
2294 +/* mask handling */
2295 +int
2296 +goodmask(
2297 + struct in_addr mask
2298 +);
2299 +int
2300 +masktobits(
2301 + struct in_addr mask
2302 +);
2303 +struct in_addr
2304 +bitstomask(
2305 + int n
2306 +);
2307 +
2308 +
2309 +
2310 +/*
2311 + * ENUM of klips debugging values. Not currently used in klips.
2312 + * debug flag is actually 32 -bits, but only one bit is ever used,
2313 + * so we can actually pack it all into a single 32-bit word.
2314 + */
2315 +enum klips_debug_flags {
2316 + KDF_VERBOSE = 0,
2317 + KDF_XMIT = 1,
2318 + KDF_NETLINK = 2, /* obsolete */
2319 + KDF_XFORM = 3,
2320 + KDF_EROUTE = 4,
2321 + KDF_SPI = 5,
2322 + KDF_RADIJ = 6,
2323 + KDF_ESP = 7,
2324 + KDF_AH = 8, /* obsolete */
2325 + KDF_RCV = 9,
2326 + KDF_TUNNEL = 10,
2327 + KDF_PFKEY = 11,
2328 + KDF_COMP = 12
2329 +};
2330 +
2331 +
2332 +/*
2333 + * Debugging levels for pfkey_lib_debug
2334 + */
2335 +#define PF_KEY_DEBUG_PARSE_NONE 0
2336 +#define PF_KEY_DEBUG_PARSE_PROBLEM 1
2337 +#define PF_KEY_DEBUG_PARSE_STRUCT 2
2338 +#define PF_KEY_DEBUG_PARSE_FLOW 4
2339 +#define PF_KEY_DEBUG_BUILD 8
2340 +#define PF_KEY_DEBUG_PARSE_MAX 15
2341 +
2342 +extern unsigned int pfkey_lib_debug; /* bits selecting what to report */
2343 +
2344 +/*
2345 + * pluto and lwdnsq need to know the maximum size of the commands to,
2346 + * and replies from lwdnsq.
2347 + */
2348 +
2349 +#define LWDNSQ_CMDBUF_LEN 1024
2350 +#define LWDNSQ_RESULT_LEN_MAX 4096
2351 +
2352 +
2353 +/* syntax for passthrough SA */
2354 +#ifndef PASSTHROUGHNAME
2355 +#define PASSTHROUGHNAME "%passthrough"
2356 +#define PASSTHROUGH4NAME "%passthrough4"
2357 +#define PASSTHROUGH6NAME "%passthrough6"
2358 +#define PASSTHROUGHIS "tun0@0.0.0.0"
2359 +#define PASSTHROUGH4IS "tun0@0.0.0.0"
2360 +#define PASSTHROUGH6IS "tun0@::"
2361 +#define PASSTHROUGHTYPE "tun"
2362 +#define PASSTHROUGHSPI 0
2363 +#define PASSTHROUGHDST 0
2364 +#endif
2365 +
2366 +
2367 +
2368 +#endif /* _OPENSWAN_H */
2369 --- /dev/null Tue Mar 11 13:02:56 2003
2370 +++ linux/include/openswan/ipcomp.h Mon Feb 9 13:51:03 2004
2371 @@ -0,0 +1,61 @@
2372 +/*
2373 + * IPCOMP zlib interface code.
2374 + * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
2375 + * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
2376 + *
2377 + * This program is free software; you can redistribute it and/or modify it
2378 + * under the terms of the GNU General Public License as published by the
2379 + * Free Software Foundation; either version 2 of the License, or (at your
2380 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2381 + *
2382 + * This program is distributed in the hope that it will be useful, but
2383 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2384 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2385 + * for more details.
2386 +
2387 + RCSID $Id: ipcomp.h,v 1.14 2004/07/10 19:08:41 mcr Exp $
2388 +
2389 + */
2390 +
2391 +/* SSS */
2392 +
2393 +#ifndef _IPCOMP_H
2394 +#define _IPCOMP_H
2395 +
2396 +/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
2397 +#ifndef IPCOMP_PREFIX
2398 +#define IPCOMP_PREFIX
2399 +#endif /* IPCOMP_PREFIX */
2400 +
2401 +#ifndef IPPROTO_COMP
2402 +#define IPPROTO_COMP 108
2403 +#endif /* IPPROTO_COMP */
2404 +
2405 +#ifdef CONFIG_KLIPS_DEBUG
2406 +extern int sysctl_ipsec_debug_ipcomp;
2407 +#endif /* CONFIG_KLIPS_DEBUG */
2408 +
2409 +struct ipcomphdr { /* IPCOMP header */
2410 + __u8 ipcomp_nh; /* Next header (protocol) */
2411 + __u8 ipcomp_flags; /* Reserved, must be 0 */
2412 + __u16 ipcomp_cpi; /* Compression Parameter Index */
2413 +};
2414 +
2415 +extern struct inet_protocol comp_protocol;
2416 +extern int sysctl_ipsec_debug_ipcomp;
2417 +
2418 +#define IPCOMP_UNCOMPRESSABLE 0x000000001
2419 +#define IPCOMP_COMPRESSIONERROR 0x000000002
2420 +#define IPCOMP_PARMERROR 0x000000004
2421 +#define IPCOMP_DECOMPRESSIONERROR 0x000000008
2422 +
2423 +#define IPCOMP_ADAPT_INITIAL_TRIES 8
2424 +#define IPCOMP_ADAPT_INITIAL_SKIP 4
2425 +#define IPCOMP_ADAPT_SUBSEQ_TRIES 2
2426 +#define IPCOMP_ADAPT_SUBSEQ_SKIP 8
2427 +
2428 +/* Function prototypes */
2429 +struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
2430 +struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
2431 +
2432 +#endif /* _IPCOMP_H */
2433 --- /dev/null Tue Mar 11 13:02:56 2003
2434 +++ linux/include/openswan/ipsec_ah.h Mon Feb 9 13:51:03 2004
2435 @@ -0,0 +1,202 @@
2436 +/*
2437 + * Authentication Header declarations
2438 + * Copyright (C) 1996, 1997 John Ioannidis.
2439 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
2440 + *
2441 + * This program is free software; you can redistribute it and/or modify it
2442 + * under the terms of the GNU General Public License as published by the
2443 + * Free Software Foundation; either version 2 of the License, or (at your
2444 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2445 + *
2446 + * This program is distributed in the hope that it will be useful, but
2447 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2448 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2449 + * for more details.
2450 + *
2451 + * RCSID $Id: ipsec_ah.h,v 1.26 2004/09/13 02:22:10 mcr Exp $
2452 + */
2453 +
2454 +#include "ipsec_md5h.h"
2455 +#include "ipsec_sha1.h"
2456 +
2457 +#ifndef IPPROTO_AH
2458 +#define IPPROTO_AH 51
2459 +#endif /* IPPROTO_AH */
2460 +
2461 +#include "ipsec_auth.h"
2462 +
2463 +#ifdef __KERNEL__
2464 +
2465 +#ifndef CONFIG_XFRM_ALTERNATE_STACK
2466 +extern struct inet_protocol ah_protocol;
2467 +#endif /* CONFIG_XFRM_ALTERNATE_STACK */
2468 +
2469 +struct options;
2470 +
2471 +struct ahhdr /* Generic AH header */
2472 +{
2473 + __u8 ah_nh; /* Next header (protocol) */
2474 + __u8 ah_hl; /* AH length, in 32-bit words */
2475 + __u16 ah_rv; /* reserved, must be 0 */
2476 + __u32 ah_spi; /* Security Parameters Index */
2477 + __u32 ah_rpl; /* Replay prevention */
2478 + __u8 ah_data[AHHMAC_HASHLEN];/* Authentication hash */
2479 +};
2480 +#define AH_BASIC_LEN 8 /* basic AH header is 8 bytes, nh,hl,rv,spi
2481 + * and the ah_hl, says how many bytes after that
2482 + * to cover. */
2483 +
2484 +extern struct xform_functions ah_xform_funcs[];
2485 +
2486 +#ifdef CONFIG_KLIPS_DEBUG
2487 +extern int debug_ah;
2488 +#endif /* CONFIG_KLIPS_DEBUG */
2489 +#endif /* __KERNEL__ */
2490 +
2491 +/*
2492 + * $Log: ipsec_ah.h,v $
2493 + * Revision 1.26 2004/09/13 02:22:10 mcr
2494 + * #define inet_protocol if necessary.
2495 + *
2496 + * Revision 1.25 2004/09/06 18:35:41 mcr
2497 + * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
2498 + * so adjust for that.
2499 + *
2500 + * Revision 1.24 2004/07/10 19:08:41 mcr
2501 + * CONFIG_IPSEC -> CONFIG_KLIPS.
2502 + *
2503 + * Revision 1.23 2004/04/05 19:55:04 mcr
2504 + * Moved from linux/include/freeswan/ipsec_ah.h,v
2505 + *
2506 + * Revision 1.22 2004/04/05 19:41:05 mcr
2507 + * merged alg-branch code.
2508 + *
2509 + * Revision 1.21 2003/12/13 19:10:16 mcr
2510 + * refactored rcv and xmit code - same as FS 2.05.
2511 + *
2512 + * Revision 1.22 2003/12/11 20:14:58 mcr
2513 + * refactored the xmit code, to move all encapsulation
2514 + * code into protocol functions. Note that all functions
2515 + * are essentially done by a single function, which is probably
2516 + * wrong.
2517 + * the rcv_functions structures are renamed xform_functions.
2518 + *
2519 + * Revision 1.21 2003/12/06 21:21:19 mcr
2520 + * split up receive path into per-transform files, for
2521 + * easier later removal.
2522 + *
2523 + * Revision 1.20.8.1 2003/12/22 15:25:52 jjo
2524 + * Merged algo-0.8.1-rc11-test1 into alg-branch
2525 + *
2526 + * Revision 1.20 2003/02/06 02:21:34 rgb
2527 + *
2528 + * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
2529 + * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
2530 + * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
2531 + *
2532 + * Revision 1.19 2002/09/16 21:19:13 mcr
2533 + * fixes for west-ah-icmp-01 - length of AH header must be
2534 + * calculated properly, and next_header field properly copied.
2535 + *
2536 + * Revision 1.18 2002/05/14 02:37:02 rgb
2537 + * Change reference from _TDB to _IPSA.
2538 + *
2539 + * Revision 1.17 2002/04/24 07:36:46 mcr
2540 + * Moved from ./klips/net/ipsec/ipsec_ah.h,v
2541 + *
2542 + * Revision 1.16 2002/02/20 01:27:06 rgb
2543 + * Ditched a pile of structs only used by the old Netlink interface.
2544 + *
2545 + * Revision 1.15 2001/12/11 02:35:57 rgb
2546 + * Change "struct net_device" to "struct device" for 2.2 compatibility.
2547 + *
2548 + * Revision 1.14 2001/11/26 09:23:47 rgb
2549 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
2550 + *
2551 + * Revision 1.13.2.1 2001/09/25 02:18:24 mcr
2552 + * replace "struct device" with "struct netdevice"
2553 + *
2554 + * Revision 1.13 2001/06/14 19:35:08 rgb
2555 + * Update copyright date.
2556 + *
2557 + * Revision 1.12 2000/09/12 03:21:20 rgb
2558 + * Cleared out unused htonq.
2559 + *
2560 + * Revision 1.11 2000/09/08 19:12:55 rgb
2561 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
2562 + *
2563 + * Revision 1.10 2000/01/21 06:13:10 rgb
2564 + * Tidied up spacing.
2565 + * Added macros for HMAC padding magic numbers.(kravietz)
2566 + *
2567 + * Revision 1.9 1999/12/07 18:16:23 rgb
2568 + * Fixed comments at end of #endif lines.
2569 + *
2570 + * Revision 1.8 1999/04/11 00:28:56 henry
2571 + * GPL boilerplate
2572 + *
2573 + * Revision 1.7 1999/04/06 04:54:25 rgb
2574 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
2575 + * patch shell fixes.
2576 + *
2577 + * Revision 1.6 1999/01/26 02:06:01 rgb
2578 + * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
2579 + *
2580 + * Revision 1.5 1999/01/22 06:17:49 rgb
2581 + * Updated macro comments.
2582 + * Added context types to support algorithm switch code.
2583 + * 64-bit clean-up -- converting 'u long long' to __u64.
2584 + *
2585 + * Revision 1.4 1998/07/14 15:54:56 rgb
2586 + * Add #ifdef __KERNEL__ to protect kernel-only structures.
2587 + *
2588 + * Revision 1.3 1998/06/30 18:05:16 rgb
2589 + * Comment out references to htonq.
2590 + *
2591 + * Revision 1.2 1998/06/25 19:33:46 rgb
2592 + * Add prototype for protocol receive function.
2593 + * Rearrange for more logical layout.
2594 + *
2595 + * Revision 1.1 1998/06/18 21:27:43 henry
2596 + * move sources from klips/src to klips/net/ipsec, to keep stupid
2597 + * kernel-build scripts happier in the presence of symlinks
2598 + *
2599 + * Revision 1.4 1998/05/18 22:28:43 rgb
2600 + * Disable key printing facilities from /proc/net/ipsec_*.
2601 + *
2602 + * Revision 1.3 1998/04/21 21:29:07 rgb
2603 + * Rearrange debug switches to change on the fly debug output from user
2604 + * space. Only kernel changes checked in at this time. radij.c was also
2605 + * changed to temporarily remove buggy debugging code in rj_delete causing
2606 + * an OOPS and hence, netlink device open errors.
2607 + *
2608 + * Revision 1.2 1998/04/12 22:03:17 rgb
2609 + * Updated ESP-3DES-HMAC-MD5-96,
2610 + * ESP-DES-HMAC-MD5-96,
2611 + * AH-HMAC-MD5-96,
2612 + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
2613 + * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
2614 + *
2615 + * Fixed eroute references in /proc/net/ipsec*.
2616 + *
2617 + * Started to patch module unloading memory leaks in ipsec_netlink and
2618 + * radij tree unloading.
2619 + *
2620 + * Revision 1.1 1998/04/09 03:05:55 henry
2621 + * sources moved up from linux/net/ipsec
2622 + *
2623 + * Revision 1.1.1.1 1998/04/08 05:35:02 henry
2624 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
2625 + *
2626 + * Revision 0.4 1997/01/15 01:28:15 ji
2627 + * Added definitions for new AH transforms.
2628 + *
2629 + * Revision 0.3 1996/11/20 14:35:48 ji
2630 + * Minor Cleanup.
2631 + * Rationalized debugging code.
2632 + *
2633 + * Revision 0.2 1996/11/02 00:18:33 ji
2634 + * First limited release.
2635 + *
2636 + *
2637 + */
2638 --- /dev/null Tue Mar 11 13:02:56 2003
2639 +++ linux/include/openswan/ipsec_alg.h Mon Feb 9 13:51:03 2004
2640 @@ -0,0 +1,248 @@
2641 +/*
2642 + * Modular extensions service and registration functions interface
2643 + *
2644 + * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
2645 + *
2646 + * ipsec_alg.h,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
2647 + *
2648 + */
2649 +/*
2650 + * This program is free software; you can redistribute it and/or modify it
2651 + * under the terms of the GNU General Public License as published by the
2652 + * Free Software Foundation; either version 2 of the License, or (at your
2653 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2654 + *
2655 + * This program is distributed in the hope that it will be useful, but
2656 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2657 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2658 + * for more details.
2659 + *
2660 + */
2661 +#ifndef IPSEC_ALG_H
2662 +#define IPSEC_ALG_H
2663 +
2664 +/*
2665 + * gcc >= 3.2 has removed __FUNCTION__, replaced by C99 __func__
2666 + * *BUT* its a compiler variable.
2667 + */
2668 +#if (__GNUC__ >= 3)
2669 +#ifndef __FUNCTION__
2670 +#define __FUNCTION__ __func__
2671 +#endif
2672 +#endif
2673 +
2674 +/* Version 0.8.1-0 */
2675 +#define IPSEC_ALG_VERSION 0x00080100
2676 +
2677 +#include <linux/types.h>
2678 +#include <linux/list.h>
2679 +#include <asm/atomic.h>
2680 +#include <openswan/pfkey.h>
2681 +
2682 +/*
2683 + * The following structs are used via pointers in ipsec_alg object to
2684 + * avoid ipsec_alg.h coupling with freeswan headers, thus simplifying
2685 + * module development
2686 + */
2687 +struct ipsec_sa;
2688 +struct esp;
2689 +
2690 +/**************************************
2691 + *
2692 + * Main registration object
2693 + *
2694 + *************************************/
2695 +#define IPSEC_ALG_VERSION_QUAD(v) \
2696 + (v>>24),((v>>16)&0xff),((v>>8)&0xff),(v&0xff)
2697 +/*
2698 + * Main ipsec_alg objects: "OOPrograming wannabe"
2699 + * Hierachy (carefully handled with _minimal_ cast'ing):
2700 + *
2701 + * ipsec_alg+
2702 + * +->ipsec_alg_enc (ixt_alg_type=SADB_EXT_SUPPORTED_ENCRYPT)
2703 + * +->ipsec_alg_auth (ixt_alg_type=SADB_EXT_SUPPORTED_AUTH)
2704 + */
2705 +
2706 +/***************************************************************
2707 + *
2708 + * INTERFACE object: struct ipsec_alg
2709 + *
2710 + ***************************************************************/
2711 +
2712 +#define ixt_alg_type ixt_support.ias_exttype
2713 +#define ixt_alg_id ixt_support.ias_id
2714 +
2715 +#define IPSEC_ALG_ST_SUPP 0x01
2716 +#define IPSEC_ALG_ST_REGISTERED 0x02
2717 +#define IPSEC_ALG_ST_EXCL 0x04
2718 +struct ipsec_alg {
2719 + unsigned ixt_version; /* only allow this version (or 'near')*/ \
2720 + struct list_head ixt_list; /* dlinked list */ \
2721 + struct module *ixt_module; /* THIS_MODULE */ \
2722 + unsigned ixt_state; /* state flags */ \
2723 + atomic_t ixt_refcnt; /* ref. count when pointed from ipsec_sa */ \
2724 + char ixt_name[16]; /* descriptive short name, eg. "3des" */ \
2725 + void *ixt_data; /* private for algo implementation */ \
2726 + uint8_t ixt_blocksize; /* blocksize in bytes */ \
2727 +
2728 + struct ipsec_alg_supported ixt_support;
2729 +};
2730 +/*
2731 + * Note the const in cbc_encrypt IV arg:
2732 + * some ciphers like to toast passed IV (eg. 3DES): make a local IV copy
2733 + */
2734 +struct ipsec_alg_enc {
2735 + struct ipsec_alg ixt_common;
2736 + unsigned ixt_e_keylen; /* raw key length in bytes */
2737 + unsigned ixt_e_ctx_size; /* sa_p->key_e_size */
2738 + int (*ixt_e_set_key)(struct ipsec_alg_enc *alg, __u8 *key_e, const __u8 *key, size_t keysize);
2739 + __u8 *(*ixt_e_new_key)(struct ipsec_alg_enc *alg, const __u8 *key, size_t keysize);
2740 + void (*ixt_e_destroy_key)(struct ipsec_alg_enc *alg, __u8 *key_e);
2741 + int (*ixt_e_cbc_encrypt)(struct ipsec_alg_enc *alg, __u8 *key_e, __u8 *in, int ilen, const __u8 *iv, int encrypt);
2742 +};
2743 +struct ipsec_alg_auth {
2744 + struct ipsec_alg ixt_common;
2745 + unsigned ixt_a_keylen; /* raw key length in bytes */
2746 + unsigned ixt_a_ctx_size; /* sa_p->key_a_size */
2747 + unsigned ixt_a_authlen; /* 'natural' auth. hash len (bytes) */
2748 + int (*ixt_a_hmac_set_key)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *key, int keylen);
2749 + int (*ixt_a_hmac_hash)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *dat, int len, __u8 *hash, int hashlen);
2750 +};
2751 +/*
2752 + * These are _copies_ of SADB_EXT_SUPPORTED_{AUTH,ENCRYPT},
2753 + * to avoid header coupling for true constants
2754 + * about headers ... "cp is your friend" --Linus
2755 + */
2756 +#define IPSEC_ALG_TYPE_AUTH 14
2757 +#define IPSEC_ALG_TYPE_ENCRYPT 15
2758 +
2759 +/***************************************************************
2760 + *
2761 + * INTERFACE for module loading,testing, and unloading
2762 + *
2763 + ***************************************************************/
2764 +/* - registration calls */
2765 +int register_ipsec_alg(struct ipsec_alg *);
2766 +int unregister_ipsec_alg(struct ipsec_alg *);
2767 +/* - optional (simple test) for algos */
2768 +int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int testparm);
2769 +/* inline wrappers (usefull for type validation */
2770 +static inline int register_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
2771 + return register_ipsec_alg((struct ipsec_alg*)ixt);
2772 +}
2773 +static inline int unregister_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
2774 + return unregister_ipsec_alg((struct ipsec_alg*)ixt);
2775 +}
2776 +static inline int register_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
2777 + return register_ipsec_alg((struct ipsec_alg*)ixt);
2778 +}
2779 +static inline int unregister_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
2780 + return unregister_ipsec_alg((struct ipsec_alg*)ixt);
2781 +}
2782 +
2783 +/*****************************************************************
2784 + *
2785 + * INTERFACE for ENC services: key creation, encrypt function
2786 + *
2787 + *****************************************************************/
2788 +
2789 +#define IPSEC_ALG_ENCRYPT 1
2790 +#define IPSEC_ALG_DECRYPT 0
2791 +
2792 +/* encryption key context creation function */
2793 +int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p);
2794 +/*
2795 + * ipsec_alg_esp_encrypt(): encrypt ilen bytes in idat returns
2796 + * 0 or ERR<0
2797 + */
2798 +int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 *idat, int ilen, const __u8 *iv, int action);
2799 +
2800 +/***************************************************************
2801 + *
2802 + * INTERFACE for AUTH services: key creation, hash functions
2803 + *
2804 + ***************************************************************/
2805 +int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p);
2806 +int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) ;
2807 +#define ipsec_alg_sa_esp_update(c,k,l) ipsec_alg_sa_esp_hash(c,k,l,NULL,0)
2808 +
2809 +/* only called from ipsec_init.c */
2810 +int ipsec_alg_init(void);
2811 +
2812 +/* algo module glue for static algos */
2813 +void ipsec_alg_static_init(void);
2814 +typedef int (*ipsec_alg_init_func_t) (void);
2815 +
2816 +/**********************************************
2817 + *
2818 + * INTERFACE for ipsec_sa init and wipe
2819 + *
2820 + **********************************************/
2821 +
2822 +/* returns true if ipsec_sa has ipsec_alg obj attached */
2823 +/*
2824 + * Initializes ipsec_sa's ipsec_alg object, using already loaded
2825 + * proto, authalg, encalg.; links ipsec_alg objects (enc, auth)
2826 + */
2827 +int ipsec_alg_sa_init(struct ipsec_sa *sa_p);
2828 +/*
2829 + * Destroys ipsec_sa's ipsec_alg object
2830 + * unlinking ipsec_alg objects
2831 + */
2832 +int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p);
2833 +
2834 +#define IPSEC_ALG_MODULE_INIT_MOD( func_name ) \
2835 + static int func_name(void); \
2836 + module_init(func_name); \
2837 + static int __init func_name(void)
2838 +#define IPSEC_ALG_MODULE_EXIT_MOD( func_name ) \
2839 + static void func_name(void); \
2840 + module_exit(func_name); \
2841 + static void __exit func_name(void)
2842 +
2843 +#define IPSEC_ALG_MODULE_INIT_STATIC( func_name ) \
2844 + extern int func_name(void); \
2845 + int func_name(void)
2846 +#define IPSEC_ALG_MODULE_EXIT_STATIC( func_name ) \
2847 + extern void func_name(void); \
2848 + void func_name(void)
2849 +
2850 +/**********************************************
2851 + *
2852 + * 2.2 backport for some 2.4 useful module stuff
2853 + *
2854 + **********************************************/
2855 +#ifdef MODULE
2856 +#ifndef THIS_MODULE
2857 +#define THIS_MODULE (&__this_module)
2858 +#endif
2859 +#ifndef module_init
2860 +typedef int (*__init_module_func_t)(void);
2861 +typedef void (*__cleanup_module_func_t)(void);
2862 +
2863 +#define module_init(x) \
2864 + int init_module(void) __attribute__((alias(#x))); \
2865 + static inline __init_module_func_t __init_module_inline(void) \
2866 + { return x; }
2867 +#define module_exit(x) \
2868 + void cleanup_module(void) __attribute__((alias(#x))); \
2869 + static inline __cleanup_module_func_t __cleanup_module_inline(void) \
2870 + { return x; }
2871 +#endif
2872 +#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_MOD( func_name )
2873 +#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_MOD( func_name )
2874 +
2875 +#else /* not MODULE */
2876 +#ifndef THIS_MODULE
2877 +#define THIS_MODULE NULL
2878 +#endif
2879 +/*
2880 + * I only want module_init() magic
2881 + * when algo.c file *is THE MODULE*, in all other
2882 + * cases, initialization is called explicitely from ipsec_alg_init()
2883 + */
2884 +#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_STATIC(func_name)
2885 +#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_STATIC(func_name)
2886 +#endif
2887 +
2888 +#endif /* IPSEC_ALG_H */
2889 --- /dev/null Tue Mar 11 13:02:56 2003
2890 +++ linux/include/openswan/ipsec_alg_3des.h Mon Feb 9 13:51:03 2004
2891 @@ -0,0 +1,12 @@
2892 +struct TripleDES_context {
2893 + des_key_schedule s1;
2894 + des_key_schedule s2;
2895 + des_key_schedule s3;
2896 +};
2897 +typedef struct TripleDES_context TripleDES_context;
2898 +
2899 +#define ESP_3DES_KEY_SZ 3*(sizeof(des_cblock))
2900 +#define ESP_3DES_CBC_BLK_LEN 8
2901 +
2902 +
2903 +
2904 --- /dev/null Tue Mar 11 13:02:56 2003
2905 +++ linux/include/openswan/ipsec_auth.h Mon Feb 9 13:51:03 2004
2906 @@ -0,0 +1,100 @@
2907 +/*
2908 + * Authentication Header declarations
2909 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
2910 + *
2911 + * This program is free software; you can redistribute it and/or modify it
2912 + * under the terms of the GNU General Public License as published by the
2913 + * Free Software Foundation; either version 2 of the License, or (at your
2914 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2915 + *
2916 + * This program is distributed in the hope that it will be useful, but
2917 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2918 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2919 + * for more details.
2920 + *
2921 + * RCSID $Id: ipsec_auth.h,v 1.3 2004/04/06 02:49:08 mcr Exp $
2922 + */
2923 +
2924 +#include "ipsec_md5h.h"
2925 +#include "ipsec_sha1.h"
2926 +
2927 +#ifndef IPSEC_AUTH_H
2928 +#define IPSEC_AUTH_H
2929 +
2930 +#define AH_FLENGTH 12 /* size of fixed part */
2931 +#define AHMD5_KMAX 64 /* MD5 max 512 bits key */
2932 +#define AHMD5_AMAX 12 /* MD5 96 bits of authenticator */
2933 +
2934 +#define AHMD596_KLEN 16 /* MD5 128 bits key */
2935 +#define AHSHA196_KLEN 20 /* SHA1 160 bits key */
2936 +
2937 +#define AHMD596_ALEN 16 /* MD5 128 bits authentication length */
2938 +#define AHSHA196_ALEN 20 /* SHA1 160 bits authentication length */
2939 +
2940 +#define AHMD596_BLKLEN 64 /* MD5 block length */
2941 +#define AHSHA196_BLKLEN 64 /* SHA1 block length */
2942 +#define AHSHA2_256_BLKLEN 64 /* SHA2-256 block length */
2943 +#define AHSHA2_384_BLKLEN 128 /* SHA2-384 block length (?) */
2944 +#define AHSHA2_512_BLKLEN 128 /* SHA2-512 block length */
2945 +
2946 +#define AH_BLKLEN_MAX 128 /* keep up to date! */
2947 +
2948 +
2949 +#define AH_AMAX AHSHA196_ALEN /* keep up to date! */
2950 +#define AHHMAC_HASHLEN 12 /* authenticator length of 96bits */
2951 +#define AHHMAC_RPLLEN 4 /* 32 bit replay counter */
2952 +
2953 +#define DB_AH_PKTRX 0x0001
2954 +#define DB_AH_PKTRX2 0x0002
2955 +#define DB_AH_DMP 0x0004
2956 +#define DB_AH_IPSA 0x0010
2957 +#define DB_AH_XF 0x0020
2958 +#define DB_AH_INAU 0x0040
2959 +#define DB_AH_REPLAY 0x0100
2960 +
2961 +#ifdef __KERNEL__
2962 +
2963 +/* General HMAC algorithm is described in RFC 2104 */
2964 +
2965 +#define HMAC_IPAD 0x36
2966 +#define HMAC_OPAD 0x5C
2967 +
2968 +struct md5_ctx {
2969 + MD5_CTX ictx; /* context after H(K XOR ipad) */
2970 + MD5_CTX octx; /* context after H(K XOR opad) */
2971 +};
2972 +
2973 +struct sha1_ctx {
2974 + SHA1_CTX ictx; /* context after H(K XOR ipad) */
2975 + SHA1_CTX octx; /* context after H(K XOR opad) */
2976 +};
2977 +
2978 +struct auth_alg {
2979 + void (*init)(void *ctx);
2980 + void (*update)(void *ctx, unsigned char *bytes, __u32 len);
2981 + void (*final)(unsigned char *hash, void *ctx);
2982 + int hashlen;
2983 +};
2984 +
2985 +struct options;
2986 +
2987 +#endif /* __KERNEL__ */
2988 +#endif /* IPSEC_AUTH_H */
2989 +
2990 +/*
2991 + * $Log: ipsec_auth.h,v $
2992 + * Revision 1.3 2004/04/06 02:49:08 mcr
2993 + * pullup of algo code from alg-branch.
2994 + *
2995 + * Revision 1.2 2004/04/05 19:55:04 mcr
2996 + * Moved from linux/include/freeswan/ipsec_auth.h,v
2997 + *
2998 + * Revision 1.1 2003/12/13 19:10:16 mcr
2999 + * refactored rcv and xmit code - same as FS 2.05.
3000 + *
3001 + * Revision 1.1 2003/12/06 21:21:19 mcr
3002 + * split up receive path into per-transform files, for
3003 + * easier later removal.
3004 + *
3005 + *
3006 + */
3007 --- /dev/null Tue Mar 11 13:02:56 2003
3008 +++ linux/include/openswan/ipsec_encap.h Mon Feb 9 13:51:03 2004
3009 @@ -0,0 +1,149 @@
3010 +/*
3011 + * declarations relevant to encapsulation-like operations
3012 + * Copyright (C) 1996, 1997 John Ioannidis.
3013 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
3014 + *
3015 + * This program is free software; you can redistribute it and/or modify it
3016 + * under the terms of the GNU General Public License as published by the
3017 + * Free Software Foundation; either version 2 of the License, or (at your
3018 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3019 + *
3020 + * This program is distributed in the hope that it will be useful, but
3021 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3022 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3023 + * for more details.
3024 + *
3025 + * RCSID $Id: ipsec_encap.h,v 1.19 2004/04/05 19:55:04 mcr Exp $
3026 + */
3027 +
3028 +#ifndef _IPSEC_ENCAP_H_
3029 +
3030 +#define SENT_IP4 16 /* data is two struct in_addr + proto + ports*/
3031 + /* (2 * sizeof(struct in_addr)) */
3032 + /* sizeof(struct sockaddr_encap)
3033 + - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */
3034 +
3035 +struct sockaddr_encap
3036 +{
3037 + __u8 sen_len; /* length */
3038 + __u8 sen_family; /* AF_ENCAP */
3039 + __u16 sen_type; /* see SENT_* */
3040 + union
3041 + {
3042 + struct /* SENT_IP4 */
3043 + {
3044 + struct in_addr Src;
3045 + struct in_addr Dst;
3046 + __u8 Proto;
3047 + __u16 Sport;
3048 + __u16 Dport;
3049 + } Sip4;
3050 + } Sen;
3051 +};
3052 +
3053 +#define sen_ip_src Sen.Sip4.Src
3054 +#define sen_ip_dst Sen.Sip4.Dst
3055 +#define sen_proto Sen.Sip4.Proto
3056 +#define sen_sport Sen.Sip4.Sport
3057 +#define sen_dport Sen.Sip4.Dport
3058 +
3059 +#ifndef AF_ENCAP
3060 +#define AF_ENCAP 26
3061 +#endif /* AF_ENCAP */
3062 +
3063 +#define _IPSEC_ENCAP_H_
3064 +#endif /* _IPSEC_ENCAP_H_ */
3065 +
3066 +/*
3067 + * $Log: ipsec_encap.h,v $
3068 + * Revision 1.19 2004/04/05 19:55:04 mcr
3069 + * Moved from linux/include/freeswan/ipsec_encap.h,v
3070 + *
3071 + * Revision 1.18 2003/10/31 02:27:05 mcr
3072 + * pulled up port-selector patches and sa_id elimination.
3073 + *
3074 + * Revision 1.17.30.1 2003/09/21 13:59:38 mcr
3075 + * pre-liminary X.509 patch - does not yet pass tests.
3076 + *
3077 + * Revision 1.17 2002/04/24 07:36:46 mcr
3078 + * Moved from ./klips/net/ipsec/ipsec_encap.h,v
3079 + *
3080 + * Revision 1.16 2001/11/26 09:23:47 rgb
3081 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3082 + *
3083 + * Revision 1.15.2.1 2001/09/25 02:18:54 mcr
3084 + * struct eroute moved to ipsec_eroute.h
3085 + *
3086 + * Revision 1.15 2001/09/14 16:58:36 rgb
3087 + * Added support for storing the first and last packets through a HOLD.
3088 + *
3089 + * Revision 1.14 2001/09/08 21:13:31 rgb
3090 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
3091 + *
3092 + * Revision 1.13 2001/06/14 19:35:08 rgb
3093 + * Update copyright date.
3094 + *
3095 + * Revision 1.12 2001/05/27 06:12:10 rgb
3096 + * Added structures for pid, packet count and last access time to eroute.
3097 + * Added packet count to beginning of /proc/net/ipsec_eroute.
3098 + *
3099 + * Revision 1.11 2000/09/08 19:12:56 rgb
3100 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
3101 + *
3102 + * Revision 1.10 2000/03/22 16:15:36 rgb
3103 + * Fixed renaming of dev_get (MB).
3104 + *
3105 + * Revision 1.9 2000/01/21 06:13:26 rgb
3106 + * Added a macro for AF_ENCAP
3107 + *
3108 + * Revision 1.8 1999/12/31 14:56:55 rgb
3109 + * MB fix for 2.3 dev-use-count.
3110 + *
3111 + * Revision 1.7 1999/11/18 04:09:18 rgb
3112 + * Replaced all kernel version macros to shorter, readable form.
3113 + *
3114 + * Revision 1.6 1999/09/24 00:34:13 rgb
3115 + * Add Marc Boucher's support for 2.3.xx+.
3116 + *
3117 + * Revision 1.5 1999/04/11 00:28:57 henry
3118 + * GPL boilerplate
3119 + *
3120 + * Revision 1.4 1999/04/06 04:54:25 rgb
3121 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
3122 + * patch shell fixes.
3123 + *
3124 + * Revision 1.3 1998/10/19 14:44:28 rgb
3125 + * Added inclusion of freeswan.h.
3126 + * sa_id structure implemented and used: now includes protocol.
3127 + *
3128 + * Revision 1.2 1998/07/14 18:19:33 rgb
3129 + * Added #ifdef __KERNEL__ directives to restrict scope of header.
3130 + *
3131 + * Revision 1.1 1998/06/18 21:27:44 henry
3132 + * move sources from klips/src to klips/net/ipsec, to keep stupid
3133 + * kernel-build scripts happier in the presence of symlinks
3134 + *
3135 + * Revision 1.2 1998/04/21 21:29:10 rgb
3136 + * Rearrange debug switches to change on the fly debug output from user
3137 + * space. Only kernel changes checked in at this time. radij.c was also
3138 + * changed to temporarily remove buggy debugging code in rj_delete causing
3139 + * an OOPS and hence, netlink device open errors.
3140 + *
3141 + * Revision 1.1 1998/04/09 03:05:58 henry
3142 + * sources moved up from linux/net/ipsec
3143 + *
3144 + * Revision 1.1.1.1 1998/04/08 05:35:02 henry
3145 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
3146 + *
3147 + * Revision 0.4 1997/01/15 01:28:15 ji
3148 + * Minor cosmetic changes.
3149 + *
3150 + * Revision 0.3 1996/11/20 14:35:48 ji
3151 + * Minor Cleanup.
3152 + * Rationalized debugging code.
3153 + *
3154 + * Revision 0.2 1996/11/02 00:18:33 ji
3155 + * First limited release.
3156 + *
3157 + *
3158 + */
3159 --- /dev/null Tue Mar 11 13:02:56 2003
3160 +++ linux/include/openswan/ipsec_eroute.h Mon Feb 9 13:51:03 2004
3161 @@ -0,0 +1,112 @@
3162 +/*
3163 + * @(#) declarations of eroute structures
3164 + *
3165 + * Copyright (C) 1996, 1997 John Ioannidis.
3166 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
3167 + * Copyright (C) 2001 Michael Richardson <mcr@freeswan.org>
3168 + *
3169 + * This program is free software; you can redistribute it and/or modify it
3170 + * under the terms of the GNU General Public License as published by the
3171 + * Free Software Foundation; either version 2 of the License, or (at your
3172 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3173 + *
3174 + * This program is distributed in the hope that it will be useful, but
3175 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3176 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3177 + * for more details.
3178 + *
3179 + * RCSID $Id: ipsec_eroute.h,v 1.5 2004/04/05 19:55:05 mcr Exp $
3180 + *
3181 + * derived from ipsec_encap.h 1.15 on 2001/9/18 by mcr.
3182 + *
3183 + */
3184 +
3185 +#ifndef _IPSEC_EROUTE_H_
3186 +
3187 +#include "radij.h"
3188 +#include "ipsec_encap.h"
3189 +#include "ipsec_radij.h"
3190 +
3191 +/*
3192 + * The "type" is really part of the address as far as the routing
3193 + * system is concerned. By using only one bit in the type field
3194 + * for each type, we sort-of make sure that different types of
3195 + * encapsulation addresses won't be matched against the wrong type.
3196 + */
3197 +
3198 +/*
3199 + * An entry in the radix tree
3200 + */
3201 +
3202 +struct rjtentry
3203 +{
3204 + struct radij_node rd_nodes[2]; /* tree glue, and other values */
3205 +#define rd_key(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_key))
3206 +#define rd_mask(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_mask))
3207 + short rd_flags;
3208 + short rd_count;
3209 +};
3210 +
3211 +struct ident
3212 +{
3213 + __u16 type; /* identity type */
3214 + __u64 id; /* identity id */
3215 + __u8 len; /* identity len */
3216 + caddr_t data; /* identity data */
3217 +};
3218 +
3219 +/*
3220 + * An encapsulation route consists of a pointer to a
3221 + * radix tree entry and a SAID (a destination_address/SPI/protocol triple).
3222 + */
3223 +
3224 +struct eroute
3225 +{
3226 + struct rjtentry er_rjt;
3227 + ip_said er_said;
3228 + uint32_t er_pid;
3229 + uint32_t er_count;
3230 + uint64_t er_lasttime;
3231 + struct sockaddr_encap er_eaddr; /* MCR get rid of _encap, it is silly*/
3232 + struct sockaddr_encap er_emask;
3233 + struct ident er_ident_s;
3234 + struct ident er_ident_d;
3235 + struct sk_buff* er_first;
3236 + struct sk_buff* er_last;
3237 +};
3238 +
3239 +#define er_dst er_said.dst
3240 +#define er_spi er_said.spi
3241 +
3242 +#define _IPSEC_EROUTE_H_
3243 +#endif /* _IPSEC_EROUTE_H_ */
3244 +
3245 +/*
3246 + * $Log: ipsec_eroute.h,v $
3247 + * Revision 1.5 2004/04/05 19:55:05 mcr
3248 + * Moved from linux/include/freeswan/ipsec_eroute.h,v
3249 + *
3250 + * Revision 1.4 2003/10/31 02:27:05 mcr
3251 + * pulled up port-selector patches and sa_id elimination.
3252 + *
3253 + * Revision 1.3.30.2 2003/10/29 01:10:19 mcr
3254 + * elimited "struct sa_id"
3255 + *
3256 + * Revision 1.3.30.1 2003/09/21 13:59:38 mcr
3257 + * pre-liminary X.509 patch - does not yet pass tests.
3258 + *
3259 + * Revision 1.3 2002/04/24 07:36:46 mcr
3260 + * Moved from ./klips/net/ipsec/ipsec_eroute.h,v
3261 + *
3262 + * Revision 1.2 2001/11/26 09:16:13 rgb
3263 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3264 + *
3265 + * Revision 1.1.2.1 2001/09/25 02:18:54 mcr
3266 + * struct eroute moved to ipsec_eroute.h
3267 + *
3268 + *
3269 + * Local variables:
3270 + * c-file-style: "linux"
3271 + * End:
3272 + *
3273 + */
3274 --- /dev/null Tue Mar 11 13:02:56 2003
3275 +++ linux/include/openswan/ipsec_errs.h Mon Feb 9 13:51:03 2004
3276 @@ -0,0 +1,53 @@
3277 +/*
3278 + * @(#) definition of ipsec_errs structure
3279 + *
3280 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
3281 + * and Michael Richardson <mcr@freeswan.org>
3282 + *
3283 + * This program is free software; you can redistribute it and/or modify it
3284 + * under the terms of the GNU General Public License as published by the
3285 + * Free Software Foundation; either version 2 of the License, or (at your
3286 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3287 + *
3288 + * This program is distributed in the hope that it will be useful, but
3289 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3290 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3291 + * for more details.
3292 + *
3293 + * RCSID $Id: ipsec_errs.h,v 1.4 2004/04/05 19:55:05 mcr Exp $
3294 + *
3295 + */
3296 +
3297 +/*
3298 + * This file describes the errors/statistics that FreeSWAN collects.
3299 + *
3300 + */
3301 +
3302 +struct ipsec_errs {
3303 + __u32 ips_alg_errs; /* number of algorithm errors */
3304 + __u32 ips_auth_errs; /* # of authentication errors */
3305 + __u32 ips_encsize_errs; /* # of encryption size errors*/
3306 + __u32 ips_encpad_errs; /* # of encryption pad errors*/
3307 + __u32 ips_replaywin_errs; /* # of pkt sequence errors */
3308 +};
3309 +
3310 +/*
3311 + * $Log: ipsec_errs.h,v $
3312 + * Revision 1.4 2004/04/05 19:55:05 mcr
3313 + * Moved from linux/include/freeswan/ipsec_errs.h,v
3314 + *
3315 + * Revision 1.3 2002/04/24 07:36:46 mcr
3316 + * Moved from ./klips/net/ipsec/ipsec_errs.h,v
3317 + *
3318 + * Revision 1.2 2001/11/26 09:16:13 rgb
3319 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3320 + *
3321 + * Revision 1.1.2.1 2001/09/25 02:25:57 mcr
3322 + * lifetime structure created and common functions created.
3323 + *
3324 + *
3325 + * Local variables:
3326 + * c-file-style: "linux"
3327 + * End:
3328 + *
3329 + */
3330 --- /dev/null Tue Mar 11 13:02:56 2003
3331 +++ linux/include/openswan/ipsec_esp.h Mon Feb 9 13:51:03 2004
3332 @@ -0,0 +1,159 @@
3333 +/*
3334 + * Copyright (C) 1996, 1997 John Ioannidis.
3335 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
3336 + *
3337 + * This program is free software; you can redistribute it and/or modify it
3338 + * under the terms of the GNU General Public License as published by the
3339 + * Free Software Foundation; either version 2 of the License, or (at your
3340 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3341 + *
3342 + * This program is distributed in the hope that it will be useful, but
3343 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3344 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3345 + * for more details.
3346 + *
3347 + * RCSID $Id: ipsec_esp.h,v 1.28 2004/09/13 02:22:10 mcr Exp $
3348 + */
3349 +
3350 +#include "openswan/ipsec_md5h.h"
3351 +#include "openswan/ipsec_sha1.h"
3352 +
3353 +#include "crypto/des.h"
3354 +
3355 +#ifndef IPPROTO_ESP
3356 +#define IPPROTO_ESP 50
3357 +#endif /* IPPROTO_ESP */
3358 +
3359 +#define ESP_HEADER_LEN 8 /* 64 bits header (spi+rpl)*/
3360 +
3361 +#define EMT_ESPDESCBC_ULEN 20 /* coming from user mode */
3362 +#define EMT_ESPDES_KMAX 64 /* 512 bit secret key enough? */
3363 +#define EMT_ESPDES_KEY_SZ 8 /* 56 bit secret key with parity = 64 bits */
3364 +#define EMT_ESP3DES_KEY_SZ 24 /* 168 bit secret key with parity = 192 bits */
3365 +#define EMT_ESPDES_IV_SZ 8 /* IV size */
3366 +#define ESP_DESCBC_BLKLEN 8 /* DES-CBC block size */
3367 +
3368 +#define ESP_IV_MAXSZ 16 /* This is _critical_ */
3369 +#define ESP_IV_MAXSZ_INT (ESP_IV_MAXSZ/sizeof(int))
3370 +
3371 +#define DB_ES_PKTRX 0x0001
3372 +#define DB_ES_PKTRX2 0x0002
3373 +#define DB_ES_IPSA 0x0010
3374 +#define DB_ES_XF 0x0020
3375 +#define DB_ES_IPAD 0x0040
3376 +#define DB_ES_INAU 0x0080
3377 +#define DB_ES_OINFO 0x0100
3378 +#define DB_ES_OINFO2 0x0200
3379 +#define DB_ES_OH 0x0400
3380 +#define DB_ES_REPLAY 0x0800
3381 +
3382 +#ifdef __KERNEL__
3383 +struct des_eks {
3384 + des_key_schedule ks;
3385 +};
3386 +
3387 +#ifndef CONFIG_XFRM_ALTERNATE_STACK
3388 +extern struct inet_protocol esp_protocol;
3389 +#endif /* CONFIG_XFRM_ALTERNATE_STACK */
3390 +
3391 +struct options;
3392 +
3393 +struct esphdr
3394 +{
3395 + __u32 esp_spi; /* Security Parameters Index */
3396 + __u32 esp_rpl; /* Replay counter */
3397 + __u8 esp_iv[8]; /* iv */
3398 +};
3399 +
3400 +extern struct xform_functions esp_xform_funcs[];
3401 +
3402 +#ifdef CONFIG_KLIPS_DEBUG
3403 +extern int debug_esp;
3404 +#endif /* CONFIG_KLIPS_DEBUG */
3405 +#endif /* __KERNEL__ */
3406 +
3407 +/*
3408 + * $Log: ipsec_esp.h,v $
3409 + * Revision 1.28 2004/09/13 02:22:10 mcr
3410 + * #define inet_protocol if necessary.
3411 + *
3412 + * Revision 1.27 2004/09/06 18:35:41 mcr
3413 + * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
3414 + * so adjust for that.
3415 + *
3416 + * Revision 1.26 2004/07/10 19:08:41 mcr
3417 + * CONFIG_IPSEC -> CONFIG_KLIPS.
3418 + *
3419 + * Revision 1.25 2004/04/06 02:49:08 mcr
3420 + * pullup of algo code from alg-branch.
3421 + *
3422 + * Revision 1.24 2004/04/05 19:55:05 mcr
3423 + * Moved from linux/include/freeswan/ipsec_esp.h,v
3424 + *
3425 + * Revision 1.23 2004/04/05 19:41:05 mcr
3426 + * merged alg-branch code.
3427 + *
3428 + * Revision 1.22 2003/12/13 19:10:16 mcr
3429 + * refactored rcv and xmit code - same as FS 2.05.
3430 + *
3431 + * Revision 1.23 2003/12/11 20:14:58 mcr
3432 + * refactored the xmit code, to move all encapsulation
3433 + * code into protocol functions. Note that all functions
3434 + * are essentially done by a single function, which is probably
3435 + * wrong.
3436 + * the rcv_functions structures are renamed xform_functions.
3437 + *
3438 + * Revision 1.22 2003/12/06 21:21:19 mcr
3439 + * split up receive path into per-transform files, for
3440 + * easier later removal.
3441 + *
3442 + * Revision 1.21.8.1 2003/12/22 15:25:52 jjo
3443 + * Merged algo-0.8.1-rc11-test1 into alg-branch
3444 + *
3445 + * Revision 1.21 2003/02/06 02:21:34 rgb
3446 + *
3447 + * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
3448 + * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
3449 + * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
3450 + *
3451 + * Revision 1.20 2002/05/14 02:37:02 rgb
3452 + * Change reference from _TDB to _IPSA.
3453 + *
3454 + * Revision 1.19 2002/04/24 07:55:32 mcr
3455 + * #include patches and Makefiles for post-reorg compilation.
3456 + *
3457 + * Revision 1.18 2002/04/24 07:36:46 mcr
3458 + * Moved from ./klips/net/ipsec/ipsec_esp.h,v
3459 + *
3460 + * Revision 1.17 2002/02/20 01:27:07 rgb
3461 + * Ditched a pile of structs only used by the old Netlink interface.
3462 + *
3463 + * Revision 1.16 2001/12/11 02:35:57 rgb
3464 + * Change "struct net_device" to "struct device" for 2.2 compatibility.
3465 + *
3466 + * Revision 1.15 2001/11/26 09:23:48 rgb
3467 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3468 + *
3469 + * Revision 1.14.2.3 2001/10/23 04:16:42 mcr
3470 + * get definition of des_key_schedule from des.h
3471 + *
3472 + * Revision 1.14.2.2 2001/10/22 20:33:13 mcr
3473 + * use "des_key_schedule" structure instead of cooking our own.
3474 + *
3475 + * Revision 1.14.2.1 2001/09/25 02:18:25 mcr
3476 + * replace "struct device" with "struct netdevice"
3477 + *
3478 + * Revision 1.14 2001/06/14 19:35:08 rgb
3479 + * Update copyright date.
3480 + *
3481 + * Revision 1.13 2000/09/08 19:12:56 rgb
3482 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
3483 + *
3484 + * Revision 1.12 2000/08/01 14:51:50 rgb
3485 + * Removed _all_ remaining traces of DES.
3486 + *
3487 + * Revision 1.11 2000/01/10 16:36:20 rgb
3488 + * Ditch last of EME option flags, including initiator.
3489 + *
3490 + *
3491 + */
3492 --- /dev/null Tue Mar 11 13:02:56 2003
3493 +++ linux/include/openswan/ipsec_ipcomp.h Mon Feb 9 13:51:03 2004
3494 @@ -0,0 +1,97 @@
3495 +/*
3496 + * IP compression header declations
3497 + *
3498 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
3499 + *
3500 + * This program is free software; you can redistribute it and/or modify it
3501 + * under the terms of the GNU General Public License as published by the
3502 + * Free Software Foundation; either version 2 of the License, or (at your
3503 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3504 + *
3505 + * This program is distributed in the hope that it will be useful, but
3506 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3507 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3508 + * for more details.
3509 + *
3510 + * RCSID $Id: ipsec_ipcomp.h,v 1.4 2004/07/10 19:08:41 mcr Exp $
3511 + */
3512 +
3513 +#ifndef IPSEC_IPCOMP_H
3514 +#define IPSEC_IPCOMP_H
3515 +
3516 +#include "openswan/ipsec_auth.h"
3517 +
3518 +/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
3519 +#ifndef IPCOMP_PREFIX
3520 +#define IPCOMP_PREFIX
3521 +#endif /* IPCOMP_PREFIX */
3522 +
3523 +#ifndef IPPROTO_COMP
3524 +#define IPPROTO_COMP 108
3525 +#endif /* IPPROTO_COMP */
3526 +
3527 +#ifdef CONFIG_KLIPS_DEBUG
3528 +extern int sysctl_ipsec_debug_ipcomp;
3529 +#endif /* CONFIG_KLIPS_DEBUG */
3530 +
3531 +struct ipcomphdr { /* IPCOMP header */
3532 + __u8 ipcomp_nh; /* Next header (protocol) */
3533 + __u8 ipcomp_flags; /* Reserved, must be 0 */
3534 + __u16 ipcomp_cpi; /* Compression Parameter Index */
3535 +};
3536 +
3537 +#ifndef CONFIG_XFRM_ALTERNATE_STACK
3538 +extern struct inet_protocol comp_protocol;
3539 +#endif /* CONFIG_XFRM_ALTERNATE_STACK */
3540 +
3541 +extern int sysctl_ipsec_debug_ipcomp;
3542 +
3543 +#define IPCOMP_UNCOMPRESSABLE 0x000000001
3544 +#define IPCOMP_COMPRESSIONERROR 0x000000002
3545 +#define IPCOMP_PARMERROR 0x000000004
3546 +#define IPCOMP_DECOMPRESSIONERROR 0x000000008
3547 +
3548 +#define IPCOMP_ADAPT_INITIAL_TRIES 8
3549 +#define IPCOMP_ADAPT_INITIAL_SKIP 4
3550 +#define IPCOMP_ADAPT_SUBSEQ_TRIES 2
3551 +#define IPCOMP_ADAPT_SUBSEQ_SKIP 8
3552 +
3553 +/* Function prototypes */
3554 +struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
3555 +struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
3556 +
3557 +extern struct xform_functions ipcomp_xform_funcs[];
3558 +
3559 +#endif /* IPSEC_IPCOMP_H */
3560 +
3561 +/*
3562 + * $Log: ipsec_ipcomp.h,v $
3563 + * Revision 1.4 2004/07/10 19:08:41 mcr
3564 + * CONFIG_IPSEC -> CONFIG_KLIPS.
3565 + *
3566 + * Revision 1.3 2004/04/06 02:49:08 mcr
3567 + * pullup of algo code from alg-branch.
3568 + *
3569 + * Revision 1.2 2004/04/05 19:55:05 mcr
3570 + * Moved from linux/include/freeswan/ipsec_ipcomp.h,v
3571 + *
3572 + * Revision 1.1 2003/12/13 19:10:16 mcr
3573 + * refactored rcv and xmit code - same as FS 2.05.
3574 + *
3575 + * Revision 1.2 2003/12/11 20:14:58 mcr
3576 + * refactored the xmit code, to move all encapsulation
3577 + * code into protocol functions. Note that all functions
3578 + * are essentially done by a single function, which is probably
3579 + * wrong.
3580 + * the rcv_functions structures are renamed xform_functions.
3581 + *
3582 + * Revision 1.1 2003/12/06 21:21:19 mcr
3583 + * split up receive path into per-transform files, for
3584 + * easier later removal.
3585 + *
3586 + *
3587 + *
3588 + */
3589 +
3590 +
3591 +
3592 --- /dev/null Tue Mar 11 13:02:56 2003
3593 +++ linux/include/openswan/ipsec_ipe4.h Mon Feb 9 13:51:03 2004
3594 @@ -0,0 +1,68 @@
3595 +/*
3596 + * IP-in-IP Header declarations
3597 + * Copyright (C) 1996, 1997 John Ioannidis.
3598 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
3599 + *
3600 + * This program is free software; you can redistribute it and/or modify it
3601 + * under the terms of the GNU General Public License as published by the
3602 + * Free Software Foundation; either version 2 of the License, or (at your
3603 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3604 + *
3605 + * This program is distributed in the hope that it will be useful, but
3606 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3607 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3608 + * for more details.
3609 + *
3610 + * RCSID $Id: ipsec_ipe4.h,v 1.6 2004/04/05 19:55:05 mcr Exp $
3611 + */
3612 +
3613 +/* The packet header is an IP header! */
3614 +
3615 +struct ipe4_xdata /* transform table data */
3616 +{
3617 + struct in_addr i4_src;
3618 + struct in_addr i4_dst;
3619 +};
3620 +
3621 +#define EMT_IPE4_ULEN 8 /* coming from user mode */
3622 +
3623 +
3624 +/*
3625 + * $Log: ipsec_ipe4.h,v $
3626 + * Revision 1.6 2004/04/05 19:55:05 mcr
3627 + * Moved from linux/include/freeswan/ipsec_ipe4.h,v
3628 + *
3629 + * Revision 1.5 2002/04/24 07:36:46 mcr
3630 + * Moved from ./klips/net/ipsec/ipsec_ipe4.h,v
3631 + *
3632 + * Revision 1.4 2001/06/14 19:35:08 rgb
3633 + * Update copyright date.
3634 + *
3635 + * Revision 1.3 1999/04/11 00:28:57 henry
3636 + * GPL boilerplate
3637 + *
3638 + * Revision 1.2 1999/04/06 04:54:25 rgb
3639 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
3640 + * patch shell fixes.
3641 + *
3642 + * Revision 1.1 1998/06/18 21:27:47 henry
3643 + * move sources from klips/src to klips/net/ipsec, to keep stupid
3644 + * kernel-build scripts happier in the presence of symlinks
3645 + *
3646 + * Revision 1.1 1998/04/09 03:06:07 henry
3647 + * sources moved up from linux/net/ipsec
3648 + *
3649 + * Revision 1.1.1.1 1998/04/08 05:35:03 henry
3650 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
3651 + *
3652 + * Revision 0.4 1997/01/15 01:28:15 ji
3653 + * No changes.
3654 + *
3655 + * Revision 0.3 1996/11/20 14:48:53 ji
3656 + * Release update only.
3657 + *
3658 + * Revision 0.2 1996/11/02 00:18:33 ji
3659 + * First limited release.
3660 + *
3661 + *
3662 + */
3663 --- /dev/null Tue Mar 11 13:02:56 2003
3664 +++ linux/include/openswan/ipsec_ipip.h Mon Feb 9 13:51:03 2004
3665 @@ -0,0 +1,45 @@
3666 +/*
3667 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
3668 + *
3669 + * This program is free software; you can redistribute it and/or modify it
3670 + * under the terms of the GNU General Public License as published by the
3671 + * Free Software Foundation; either version 2 of the License, or (at your
3672 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3673 + *
3674 + * This program is distributed in the hope that it will be useful, but
3675 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3676 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3677 + * for more details.
3678 + *
3679 + * RCSID $Id: ipsec_ipip.h,v 1.2 2004/04/05 19:55:05 mcr Exp $
3680 + */
3681 +
3682 +#ifndef _IPSEC_IPIP_H_
3683 +
3684 +#ifndef IPPROTO_IPIP
3685 +#define IPPROTO_IPIP 4
3686 +#endif /* IPPROTO_ESP */
3687 +
3688 +extern struct xform_functions ipip_xform_funcs[];
3689 +
3690 +#define _IPSEC_IPIP_H_
3691 +
3692 +#endif /* _IPSEC_IPIP_H_ */
3693 +
3694 +/*
3695 + * $Log: ipsec_ipip.h,v $
3696 + * Revision 1.2 2004/04/05 19:55:05 mcr
3697 + * Moved from linux/include/freeswan/ipsec_ipip.h,v
3698 + *
3699 + * Revision 1.1 2003/12/13 19:10:16 mcr
3700 + * refactored rcv and xmit code - same as FS 2.05.
3701 + *
3702 + * Revision 1.1 2003/12/11 20:14:58 mcr
3703 + * refactored the xmit code, to move all encapsulation
3704 + * code into protocol functions. Note that all functions
3705 + * are essentially done by a single function, which is probably
3706 + * wrong.
3707 + * the rcv_functions structures are renamed xform_functions.
3708 + *
3709 + *
3710 + */
3711 --- /dev/null Tue Mar 11 13:02:56 2003
3712 +++ linux/include/openswan/ipsec_kern24.h Mon Feb 9 13:51:03 2004
3713 @@ -0,0 +1,152 @@
3714 +/*
3715 + * @(#) routines to makes kernel 2.4 compatible with 2.6 usage.
3716 + *
3717 + * Copyright (C) 2004 Michael Richardson <mcr@sandelman.ottawa.on.ca>
3718 + *
3719 + * This program is free software; you can redistribute it and/or modify it
3720 + * under the terms of the GNU General Public License as published by the
3721 + * Free Software Foundation; either version 2 of the License, or (at your
3722 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3723 + *
3724 + * This program is distributed in the hope that it will be useful, but
3725 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3726 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3727 + * for more details.
3728 + *
3729 + * RCSID $Id: ipsec_kern24.h,v 1.5 2005/08/05 08:48:38 mcr Exp $
3730 + */
3731 +
3732 +#ifndef _IPSEC_KERN24_H
3733 +
3734 +#ifdef NET_21
3735 +# include <linux/in6.h>
3736 +#else
3737 + /* old kernel in.h has some IPv6 stuff, but not quite enough */
3738 +# define s6_addr16 s6_addr
3739 +# define AF_INET6 10
3740 +# define uint8_t __u8
3741 +# define uint16_t __u16
3742 +# define uint32_t __u32
3743 +# define uint64_t __u64
3744 +#endif
3745 +
3746 +#ifdef NET_21
3747 +# define ipsec_kfree_skb(a) kfree_skb(a)
3748 +#else /* NET_21 */
3749 +# define ipsec_kfree_skb(a) kfree_skb(a, FREE_WRITE)
3750 +#endif /* NET_21 */
3751 +
3752 +#ifdef NETDEV_23
3753 +#if 0
3754 +#ifndef NETDEV_25
3755 +#define device net_device
3756 +#endif
3757 +#endif
3758 +# define ipsec_dev_get dev_get_by_name
3759 +# define __ipsec_dev_get __dev_get_by_name
3760 +# define ipsec_dev_put(x) dev_put(x)
3761 +# define __ipsec_dev_put(x) __dev_put(x)
3762 +# define ipsec_dev_hold(x) dev_hold(x)
3763 +#else /* NETDEV_23 */
3764 +# define ipsec_dev_get dev_get
3765 +# define __ipsec_dev_put(x)
3766 +# define ipsec_dev_put(x)
3767 +# define ipsec_dev_hold(x)
3768 +#endif /* NETDEV_23 */
3769 +
3770 +#ifndef SPINLOCK
3771 +# include <linux/bios32.h>
3772 + /* simulate spin locks and read/write locks */
3773 + typedef struct {
3774 + volatile char lock;
3775 + } spinlock_t;
3776 +
3777 + typedef struct {
3778 + volatile unsigned int lock;
3779 + } rwlock_t;
3780 +
3781 +# define spin_lock_init(x) { (x)->lock = 0;}
3782 +# define rw_lock_init(x) { (x)->lock = 0; }
3783 +
3784 +# define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;}
3785 +# define spin_lock_irq(x) { cli(); spin_lock(x);}
3786 +# define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);}
3787 +
3788 +# define spin_unlock(x) { (x)->lock=0;}
3789 +# define spin_unlock_irq(x) { spin_unlock(x); sti();}
3790 +# define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);}
3791 +
3792 +# define read_lock(x) spin_lock(x)
3793 +# define read_lock_irq(x) spin_lock_irq(x)
3794 +# define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
3795 +
3796 +# define read_unlock(x) spin_unlock(x)
3797 +# define read_unlock_irq(x) spin_unlock_irq(x)
3798 +# define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
3799 +
3800 +# define write_lock(x) spin_lock(x)
3801 +# define write_lock_irq(x) spin_lock_irq(x)
3802 +# define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
3803 +
3804 +# define write_unlock(x) spin_unlock(x)
3805 +# define write_unlock_irq(x) spin_unlock_irq(x)
3806 +# define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
3807 +#endif /* !SPINLOCK */
3808 +
3809 +#ifndef SPINLOCK_23
3810 +# define spin_lock_bh(x) spin_lock_irq(x)
3811 +# define spin_unlock_bh(x) spin_unlock_irq(x)
3812 +
3813 +# define read_lock_bh(x) read_lock_irq(x)
3814 +# define read_unlock_bh(x) read_unlock_irq(x)
3815 +
3816 +# define write_lock_bh(x) write_lock_irq(x)
3817 +# define write_unlock_bh(x) write_unlock_irq(x)
3818 +#endif /* !SPINLOCK_23 */
3819 +
3820 +#ifndef HAVE_NETDEV_PRINTK
3821 +#define netdev_printk(sevlevel, netdev, msglevel, format, arg...) \
3822 + printk(sevlevel "%s: " format , netdev->name , ## arg)
3823 +#endif
3824 +
3825 +#ifndef NET_26
3826 +#define sk_receive_queue receive_queue
3827 +#define sk_destruct destruct
3828 +#define sk_reuse reuse
3829 +#define sk_zapped zapped
3830 +#define sk_family family
3831 +#define sk_protocol protocol
3832 +#define sk_protinfo protinfo
3833 +#define sk_sleep sleep
3834 +#define sk_state_change state_change
3835 +#define sk_shutdown shutdown
3836 +#define sk_err err
3837 +#define sk_stamp stamp
3838 +#define sk_socket socket
3839 +#define sk_sndbuf sndbuf
3840 +#define sock_flag(sk, flag) sk->dead
3841 +#define sk_for_each(sk, node, plist) for(sk=*plist; sk!=NULL; sk = sk->next)
3842 +#endif
3843 +
3844 +/* deal with 2.4 vs 2.6 issues with module counts */
3845 +
3846 +/* in 2.6, all refcounts are maintained *outside* of the
3847 + * module to deal with race conditions.
3848 + */
3849 +
3850 +#ifdef NET_26
3851 +#define KLIPS_INC_USE /* nothing */
3852 +#define KLIPS_DEC_USE /* nothing */
3853 +
3854 +#else
3855 +#define KLIPS_INC_USE MOD_INC_USE_COUNT
3856 +#define KLIPS_DEC_USE MOD_DEC_USE_COUNT
3857 +#endif
3858 +
3859 +extern int printk_ratelimit(void);
3860 +
3861 +
3862 +#define _IPSEC_KERN24_H 1
3863 +
3864 +#endif /* _IPSEC_KERN24_H */
3865 +
3866 --- /dev/null Tue Mar 11 13:02:56 2003
3867 +++ linux/include/openswan/ipsec_kversion.h Mon Feb 9 13:51:03 2004
3868 @@ -0,0 +1,260 @@
3869 +#ifndef _OPENSWAN_KVERSIONS_H
3870 +/*
3871 + * header file for FreeS/WAN library functions
3872 + * Copyright (C) 1998, 1999, 2000 Henry Spencer.
3873 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
3874 + *
3875 + * This library is free software; you can redistribute it and/or modify it
3876 + * under the terms of the GNU Library General Public License as published by
3877 + * the Free Software Foundation; either version 2 of the License, or (at your
3878 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
3879 + *
3880 + * This library is distributed in the hope that it will be useful, but
3881 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3882 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
3883 + * License for more details.
3884 + *
3885 + * RCSID $Id: ipsec_kversion.h,v 1.23 2005/11/13 15:24:07 ken Exp $
3886 + */
3887 +#define _OPENSWAN_KVERSIONS_H /* seen it, no need to see it again */
3888 +
3889 +/*
3890 + * this file contains a series of atomic defines that depend upon
3891 + * kernel version numbers. The kernel versions are arranged
3892 + * in version-order number (which is often not chronological)
3893 + * and each clause enables or disables a feature.
3894 + */
3895 +
3896 +/*
3897 + * First, assorted kernel-version-dependent trickery.
3898 + */
3899 +#include <linux/version.h>
3900 +#ifndef KERNEL_VERSION
3901 +#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
3902 +#endif
3903 +
3904 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
3905 +#define HEADER_CACHE_BIND_21
3906 +#error "KLIPS is no longer supported on Linux 2.0. Sorry"
3907 +#endif
3908 +
3909 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
3910 +#define SPINLOCK
3911 +#define PROC_FS_21
3912 +#define NETLINK_SOCK
3913 +#define NET_21
3914 +#endif
3915 +
3916 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,19)
3917 +#define net_device_stats enet_statistics
3918 +#endif
3919 +
3920 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3921 +#define SPINLOCK_23
3922 +#define NETDEV_23
3923 +# ifndef CONFIG_IP_ALIAS
3924 +# define CONFIG_IP_ALIAS
3925 +# endif
3926 +#endif
3927 +
3928 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,25)
3929 +#define PROC_FS_2325
3930 +#undef PROC_FS_21
3931 +#endif
3932 +
3933 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
3934 +#define PROC_NO_DUMMY
3935 +#endif
3936 +
3937 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,35)
3938 +#define SKB_COPY_EXPAND
3939 +#endif
3940 +
3941 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,37)
3942 +#define IP_SELECT_IDENT
3943 +#endif
3944 +
3945 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,50)) && defined(CONFIG_NETFILTER)
3946 +#define SKB_RESET_NFCT
3947 +#endif
3948 +
3949 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2)
3950 +#define IP_SELECT_IDENT_NEW
3951 +#endif
3952 +
3953 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
3954 +#define IPH_is_SKB_PULLED
3955 +#define SKB_COW_NEW
3956 +#define PROTO_HANDLER_SINGLE_PARM
3957 +#define IP_FRAGMENT_LINEARIZE 1
3958 +#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
3959 +# ifdef REDHAT_BOGOSITY
3960 +# define IP_SELECT_IDENT_NEW
3961 +# define IPH_is_SKB_PULLED
3962 +# define SKB_COW_NEW
3963 +# define PROTO_HANDLER_SINGLE_PARM
3964 +# endif /* REDHAT_BOGOSITY */
3965 +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
3966 +
3967 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
3968 +#define MALLOC_SLAB
3969 +#define LINUX_KERNEL_HAS_SNPRINTF
3970 +#endif
3971 +
3972 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
3973 +#define HAVE_NETDEV_PRINTK 1
3974 +#define NET_26
3975 +#define NETDEV_25
3976 +#endif
3977 +
3978 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)
3979 +#define NEED_INET_PROTOCOL
3980 +#endif
3981 +
3982 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
3983 +#define HAVE_SOCK_ZAPPED
3984 +#define NET_26_12_SKALLOC
3985 +#endif
3986 +
3987 +/* see <linux/security.h> */
3988 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
3989 +#define HAVE_SOCK_SECURITY
3990 +/* skb->nf_debug disappared completely in 2.6.13 */
3991 +#define HAVE_SKB_NF_DEBUG
3992 +#endif
3993 +
3994 +/* skb->stamp changed to skb->tstamp in 2.6.14 */
3995 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
3996 +#define HAVE_TSTAMP
3997 +#define HAVE_INET_SK_SPORT
3998 +#else
3999 +#define HAVE_SKB_LIST
4000 +#endif
4001 +
4002 +#define SYSCTL_IPSEC_DEFAULT_TTL sysctl_ip_default_ttl
4003 +/* it seems 2.6.14 accidentally removed sysctl_ip_default_ttl */
4004 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
4005 +#undef SYSCTL_IPSEC_DEFAULT_TTL
4006 +#define SYSCTL_IPSEC_DEFAULT_TTL IPSEC_DEFAULT_TTL
4007 +#endif
4008 +
4009 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
4010 +#define HAVE_NEW_SKB_LINEARIZE
4011 +#endif
4012 +
4013 +/* this is the best we can do to detect XEN, which makes
4014 + * patches to linux/skbuff.h, making it look like 2.6.18 version
4015 + */
4016 +#ifdef CONFIG_XEN
4017 +#define HAVE_NEW_SKB_LINEARIZE
4018 +#endif
4019 +
4020 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
4021 +/* skb->nfmark changed to skb->mark in 2.6.20 */
4022 +#define nfmark mark
4023 +#endif
4024 +
4025 +#if __KERNEL__
4026 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0)
4027 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4028 +#include "openswan/ipsec_kern24.h"
4029 +#else
4030 +#error "kernels before 2.4 are not supported at this time"
4031 +#endif
4032 +#endif
4033 +#endif
4034 +
4035 +#endif /* _OPENSWAN_KVERSIONS_H */
4036 +
4037 +/*
4038 + * $Log: ipsec_kversion.h,v $
4039 + * Revision 1.23 2005/11/13 15:24:07 ken
4040 + * sysctl_ip_default_ttl is missing in 2.6.14.2, and might be for awhile
4041 + *
4042 + * Revision 1.22 2005/11/11 05:01:28 paul
4043 + * Added HAVE_SKB_LIST for 2.6.14 that no longer has skb->list
4044 + *
4045 + * Revision 1.21 2005/11/11 04:42:02 paul
4046 + * Added define for HAVE_INET_SK_SPORT for 2.6.14 and up
4047 + *
4048 + * Revision 1.20 2005/11/11 03:58:34 paul
4049 + * Added a define for 2.6.14 that is not exporting sysctl_ip_default_ttl
4050 + * by accident.
4051 + *
4052 + * Revision 1.19 2005/11/11 03:16:22 paul
4053 + * Added HAVE_TSTAMP define for 2.6.14 kernels
4054 + * (skb->stamp changed to skb->tstamp)
4055 + *
4056 + * Revision 1.18 2005/08/31 23:26:11 mcr
4057 + * fixes for 2.6.13
4058 + *
4059 + * Revision 1.15.2.3 2005/11/22 04:11:52 ken
4060 + * Backport fixes for 2.6.14 kernels from HEAD
4061 + *
4062 + * Revision 1.15.2.2 2005/09/01 01:57:19 paul
4063 + * michael's fixes for 2.6.13 from head
4064 + *
4065 + * Revision 1.17 2005/08/27 23:07:21 paul
4066 + * Somewhere between 2.6.12 and 2.6.13rc7 the unused security memnber in sk_buff
4067 + * has been removed. This patch should fix compilation for both cases.
4068 + *
4069 + * Revision 1.16 2005/08/05 08:48:38 mcr
4070 + * many compat definitions moved to kern24.h because
4071 + * ipsec_kversion.h may be needed by openswan.h.
4072 + *
4073 + * Revision 1.15 2005/07/19 20:02:15 mcr
4074 + * sk_alloc() interface change.
4075 + *
4076 + * Revision 1.14 2005/07/08 16:20:05 mcr
4077 + * fix for 2.6.12 disapperance of sk_zapped field -> sock_flags.
4078 + *
4079 + * Revision 1.13 2005/05/20 03:19:18 mcr
4080 + * modifications for use on 2.4.30 kernel, with backported
4081 + * printk_ratelimit(). all warnings removed.
4082 + *
4083 + * Revision 1.12 2005/04/13 22:46:21 mcr
4084 + * note that KLIPS does not work on Linux 2.0.
4085 + *
4086 + * Revision 1.11 2004/09/13 02:22:26 mcr
4087 + * #define inet_protocol if necessary.
4088 + *
4089 + * Revision 1.10 2004/08/03 18:17:15 mcr
4090 + * in 2.6, use "net_device" instead of #define device->net_device.
4091 + * this probably breaks 2.0 compiles.
4092 + *
4093 + * Revision 1.9 2004/04/05 19:55:05 mcr
4094 + * Moved from linux/include/freeswan/ipsec_kversion.h,v
4095 + *
4096 + * Revision 1.8 2003/12/13 19:10:16 mcr
4097 + * refactored rcv and xmit code - same as FS 2.05.
4098 + *
4099 + * Revision 1.7 2003/07/31 22:48:08 mcr
4100 + * derive NET25-ness from presence of NETLINK_XFRM macro.
4101 + *
4102 + * Revision 1.6 2003/06/24 20:22:32 mcr
4103 + * added new global: ipsecdevices[] so that we can keep track of
4104 + * the ipsecX devices. They will be referenced with dev_hold(),
4105 + * so 2.2 may need this as well.
4106 + *
4107 + * Revision 1.5 2003/04/03 17:38:09 rgb
4108 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
4109 + *
4110 + * Revision 1.4 2002/04/24 07:36:46 mcr
4111 + * Moved from ./klips/net/ipsec/ipsec_kversion.h,v
4112 + *
4113 + * Revision 1.3 2002/04/12 03:21:17 mcr
4114 + * three parameter version of ip_select_ident appears first
4115 + * in 2.4.2 (RH7.1) not 2.4.4.
4116 + *
4117 + * Revision 1.2 2002/03/08 21:35:22 rgb
4118 + * Defined LINUX_KERNEL_HAS_SNPRINTF to shut up compiler warnings after
4119 + * 2.4.9. (Andreas Piesk).
4120 + *
4121 + * Revision 1.1 2002/01/29 02:11:42 mcr
4122 + * removal of kversions.h - sources that needed it now use ipsec_param.h.
4123 + * updating of IPv6 structures to match latest in6.h version.
4124 + * removed dead code from freeswan.h that also duplicated kversions.h
4125 + * code.
4126 + *
4127 + *
4128 + */
4129 --- /dev/null Tue Mar 11 13:02:56 2003
4130 +++ linux/include/openswan/ipsec_life.h Mon Feb 9 13:51:03 2004
4131 @@ -0,0 +1,112 @@
4132 +/*
4133 + * Definitions relevant to IPSEC lifetimes
4134 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
4135 + * and Michael Richardson <mcr@freeswan.org>
4136 + *
4137 + * This program is free software; you can redistribute it and/or modify it
4138 + * under the terms of the GNU General Public License as published by the
4139 + * Free Software Foundation; either version 2 of the License, or (at your
4140 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4141 + *
4142 + * This program is distributed in the hope that it will be useful, but
4143 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4144 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4145 + * for more details.
4146 + *
4147 + * RCSID $Id: ipsec_life.h,v 1.4 2004/04/05 19:55:05 mcr Exp $
4148 + *
4149 + * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
4150 + *
4151 + */
4152 +
4153 +/*
4154 + * This file describes the book keeping fields for the
4155 + * IPsec Security Association Structure. ("ipsec_sa")
4156 + *
4157 + * This structure is never allocated directly by kernel code,
4158 + * (it is always a static/auto or is part of a structure)
4159 + * so it does not have a reference count.
4160 + *
4161 + */
4162 +
4163 +#ifndef _IPSEC_LIFE_H_
4164 +
4165 +/*
4166 + * _count is total count.
4167 + * _hard is hard limit (kill SA after this number)
4168 + * _soft is soft limit (try to renew SA after this number)
4169 + * _last is used in some special cases.
4170 + *
4171 + */
4172 +
4173 +struct ipsec_lifetime64
4174 +{
4175 + __u64 ipl_count;
4176 + __u64 ipl_soft;
4177 + __u64 ipl_hard;
4178 + __u64 ipl_last;
4179 +};
4180 +
4181 +struct ipsec_lifetimes
4182 +{
4183 + /* number of bytes processed */
4184 + struct ipsec_lifetime64 ipl_bytes;
4185 +
4186 + /* number of packets processed */
4187 + struct ipsec_lifetime64 ipl_packets;
4188 +
4189 + /* time since SA was added */
4190 + struct ipsec_lifetime64 ipl_addtime;
4191 +
4192 + /* time since SA was first used */
4193 + struct ipsec_lifetime64 ipl_usetime;
4194 +
4195 + /* from rfc2367:
4196 + * For CURRENT, the number of different connections,
4197 + * endpoints, or flows that the association has been
4198 + * allocated towards. For HARD and SOFT, the number of
4199 + * these the association may be allocated towards
4200 + * before it expires. The concept of a connection,
4201 + * flow, or endpoint is system specific.
4202 + *
4203 + * mcr(2001-9-18) it is unclear what purpose these serve for FreeSWAN.
4204 + * They are maintained for PF_KEY compatibility.
4205 + */
4206 + struct ipsec_lifetime64 ipl_allocations;
4207 +};
4208 +
4209 +enum ipsec_life_alive {
4210 + ipsec_life_harddied = -1,
4211 + ipsec_life_softdied = 0,
4212 + ipsec_life_okay = 1
4213 +};
4214 +
4215 +enum ipsec_life_type {
4216 + ipsec_life_timebased = 1,
4217 + ipsec_life_countbased= 0
4218 +};
4219 +
4220 +#define _IPSEC_LIFE_H_
4221 +#endif /* _IPSEC_LIFE_H_ */
4222 +
4223 +
4224 +/*
4225 + * $Log: ipsec_life.h,v $
4226 + * Revision 1.4 2004/04/05 19:55:05 mcr
4227 + * Moved from linux/include/freeswan/ipsec_life.h,v
4228 + *
4229 + * Revision 1.3 2002/04/24 07:36:46 mcr
4230 + * Moved from ./klips/net/ipsec/ipsec_life.h,v
4231 + *
4232 + * Revision 1.2 2001/11/26 09:16:14 rgb
4233 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
4234 + *
4235 + * Revision 1.1.2.1 2001/09/25 02:25:58 mcr
4236 + * lifetime structure created and common functions created.
4237 + *
4238 + *
4239 + * Local variables:
4240 + * c-file-style: "linux"
4241 + * End:
4242 + *
4243 + */
4244 --- /dev/null Tue Mar 11 13:02:56 2003
4245 +++ linux/include/openswan/ipsec_md5h.h Mon Feb 9 13:51:03 2004
4246 @@ -0,0 +1,143 @@
4247 +/*
4248 + * RCSID $Id: ipsec_md5h.h,v 1.10 2004/09/08 17:21:35 ken Exp $
4249 + */
4250 +
4251 +/*
4252 + * The rest of this file is Copyright RSA DSI. See the following comments
4253 + * for the full Copyright notice.
4254 + */
4255 +
4256 +#ifndef _IPSEC_MD5H_H_
4257 +#define _IPSEC_MD5H_H_
4258 +
4259 +/* GLOBAL.H - RSAREF types and constants
4260 + */
4261 +
4262 +/* PROTOTYPES should be set to one if and only if the compiler supports
4263 + function argument prototyping.
4264 + The following makes PROTOTYPES default to 0 if it has not already
4265 + been defined with C compiler flags.
4266 + */
4267 +#ifndef PROTOTYPES
4268 +#define PROTOTYPES 1
4269 +#endif /* !PROTOTYPES */
4270 +
4271 +/* POINTER defines a generic pointer type */
4272 +typedef __u8 *POINTER;
4273 +
4274 +/* UINT2 defines a two byte word */
4275 +typedef __u16 UINT2;
4276 +
4277 +/* UINT4 defines a four byte word */
4278 +typedef __u32 UINT4;
4279 +
4280 +/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
4281 + If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
4282 + returns an empty list.
4283 + */
4284 +
4285 +#if PROTOTYPES
4286 +#define PROTO_LIST(list) list
4287 +#else /* PROTOTYPES */
4288 +#define PROTO_LIST(list) ()
4289 +#endif /* PROTOTYPES */
4290 +
4291 +
4292 +/* MD5.H - header file for MD5C.C
4293 + */
4294 +
4295 +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
4296 +rights reserved.
4297 +
4298 +License to copy and use this software is granted provided that it
4299 +is identified as the "RSA Data Security, Inc. MD5 Message-Digest
4300 +Algorithm" in all material mentioning or referencing this software
4301 +or this function.
4302 +
4303 +License is also granted to make and use derivative works provided
4304 +that such works are identified as "derived from the RSA Data
4305 +Security, Inc. MD5 Message-Digest Algorithm" in all material
4306 +mentioning or referencing the derived work.
4307 +
4308 +RSA Data Security, Inc. makes no representations concerning either
4309 +the merchantability of this software or the suitability of this
4310 +software for any particular purpose. It is provided "as is"
4311 +without express or implied warranty of any kind.
4312 +
4313 +These notices must be retained in any copies of any part of this
4314 +documentation and/or software.
4315 + */
4316 +
4317 +/* MD5 context. */
4318 +typedef struct {
4319 + UINT4 state[4]; /* state (ABCD) */
4320 + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
4321 + unsigned char buffer[64]; /* input buffer */
4322 +} MD5_CTX;
4323 +
4324 +void osMD5Init PROTO_LIST ((void *));
4325 +void osMD5Update PROTO_LIST
4326 + ((void *, unsigned char *, __u32));
4327 +void osMD5Final PROTO_LIST ((unsigned char [16], void *));
4328 +
4329 +#endif /* _IPSEC_MD5H_H_ */
4330 +
4331 +/*
4332 + * $Log: ipsec_md5h.h,v $
4333 + * Revision 1.10 2004/09/08 17:21:35 ken
4334 + * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
4335 + *
4336 + * Revision 1.9 2004/04/05 19:55:05 mcr
4337 + * Moved from linux/include/freeswan/ipsec_md5h.h,v
4338 + *
4339 + * Revision 1.8 2002/09/10 01:45:09 mcr
4340 + * changed type of MD5_CTX and SHA1_CTX to void * so that
4341 + * the function prototypes would match, and could be placed
4342 + * into a pointer to a function.
4343 + *
4344 + * Revision 1.7 2002/04/24 07:36:46 mcr
4345 + * Moved from ./klips/net/ipsec/ipsec_md5h.h,v
4346 + *
4347 + * Revision 1.6 1999/12/13 13:59:13 rgb
4348 + * Quick fix to argument size to Update bugs.
4349 + *
4350 + * Revision 1.5 1999/12/07 18:16:23 rgb
4351 + * Fixed comments at end of #endif lines.
4352 + *
4353 + * Revision 1.4 1999/04/06 04:54:26 rgb
4354 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
4355 + * patch shell fixes.
4356 + *
4357 + * Revision 1.3 1999/01/22 06:19:58 rgb
4358 + * 64-bit clean-up.
4359 + *
4360 + * Revision 1.2 1998/11/30 13:22:54 rgb
4361 + * Rationalised all the klips kernel file headers. They are much shorter
4362 + * now and won't conflict under RH5.2.
4363 + *
4364 + * Revision 1.1 1998/06/18 21:27:48 henry
4365 + * move sources from klips/src to klips/net/ipsec, to keep stupid
4366 + * kernel-build scripts happier in the presence of symlinks
4367 + *
4368 + * Revision 1.2 1998/04/23 20:54:03 rgb
4369 + * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
4370 + * verified.
4371 + *
4372 + * Revision 1.1 1998/04/09 03:04:21 henry
4373 + * sources moved up from linux/net/ipsec
4374 + * these two include files modified not to include others except in kernel
4375 + *
4376 + * Revision 1.1.1.1 1998/04/08 05:35:03 henry
4377 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
4378 + *
4379 + * Revision 0.4 1997/01/15 01:28:15 ji
4380 + * No changes.
4381 + *
4382 + * Revision 0.3 1996/11/20 14:48:53 ji
4383 + * Release update only.
4384 + *
4385 + * Revision 0.2 1996/11/02 00:18:33 ji
4386 + * First limited release.
4387 + *
4388 + *
4389 + */
4390 --- /dev/null Tue Mar 11 13:02:56 2003
4391 +++ linux/include/openswan/ipsec_param.h Mon Feb 9 13:51:03 2004
4392 @@ -0,0 +1,389 @@
4393 +/*
4394 + * @(#) Openswan tunable paramaters
4395 + *
4396 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
4397 + * and Michael Richardson <mcr@freeswan.org>
4398 + * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
4399 + *
4400 + * This program is free software; you can redistribute it and/or modify it
4401 + * under the terms of the GNU General Public License as published by the
4402 + * Free Software Foundation; either version 2 of the License, or (at your
4403 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4404 + *
4405 + * This program is distributed in the hope that it will be useful, but
4406 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4407 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4408 + * for more details.
4409 + *
4410 + * RCSID $Id: ipsec_param.h,v 1.31 2005/08/12 15:01:38 mcr Exp $
4411 + *
4412 + */
4413 +
4414 +/*
4415 + * This file provides a set of #define's which may be tuned by various
4416 + * people/configurations. It keeps all compile-time tunables in one place.
4417 + *
4418 + * This file should be included before all other IPsec kernel-only files.
4419 + *
4420 + */
4421 +
4422 +#ifndef _IPSEC_PARAM_H_
4423 +
4424 +#ifdef __KERNEL__
4425 +
4426 +#include "openswan/ipsec_kversion.h"
4427 +
4428 +/* Set number of ipsecX virtual devices here. */
4429 +/* This must be < exp(field width of IPSEC_DEV_FORMAT) */
4430 +/* It must also be reasonable so as not to overload the memory and CPU */
4431 +/* constraints of the host. */
4432 +#ifdef CONFIG_KLIPS_IF_MAX
4433 +#define IPSEC_NUM_IFMAX CONFIG_KLIPS_IF_MAX
4434 +#endif
4435 +#ifndef IPSEC_NUM_IFMAX
4436 +#define IPSEC_NUM_IFMAX 64
4437 +#endif
4438 +
4439 +/* default number of ipsecX devices to create */
4440 +#define IPSEC_NUM_IF 2
4441 +
4442 +/* The field width must be < IF_NAM_SIZ - strlen("ipsec") - 1. */
4443 +/* With "ipsec" being 5 characters, that means 10 is the max field width */
4444 +/* but machine memory and CPU constraints are not likely to tollerate */
4445 +/* more than 3 digits. The default is one digit. */
4446 +/* Update: userland scripts get upset if they can't find "ipsec0", so */
4447 +/* for now, no "0"-padding should be used (which would have been helpful */
4448 +/* to make text-searches work */
4449 +#define IPSEC_DEV_FORMAT "ipsec%d"
4450 +#define MAST_DEV_FORMAT "mast%d"
4451 +
4452 +/* For, say, 500 virtual ipsec devices, I would recommend: */
4453 +/* #define IPSEC_NUM_IF 500 */
4454 +/* #define IPSEC_DEV_FORMAT "ipsec%03d" */
4455 +/* Note that the "interfaces=" line in /etc/ipsec.conf would be, um, challenging. */
4456 +
4457 +/* use dynamic ipsecX device allocation */
4458 +#ifndef CONFIG_KLIPS_DYNDEV
4459 +#define CONFIG_KLIPS_DYNDEV 1
4460 +#endif /* CONFIG_KLIPS_DYNDEV */
4461 +
4462 +
4463 +#ifdef CONFIG_KLIPS_BIGGATE
4464 +# define SADB_HASHMOD 8069
4465 +#else /* CONFIG_KLIPS_BIGGATE */
4466 +# define SADB_HASHMOD 257
4467 +#endif /* CONFIG_KLIPS_BIGGATE */
4468 +
4469 +#endif /* __KERNEL__ */
4470 +
4471 +/*
4472 + * This is for the SA reference table. This number is related to the
4473 + * maximum number of SAs that KLIPS can concurrently deal with, plus enough
4474 + * space for keeping expired SAs around.
4475 + *
4476 + * TABLE_IDX_WIDTH is the number of bits that we will use.
4477 + * MAIN_TABLE_WIDTH is the number of bits used for the primary index table.
4478 + *
4479 + */
4480 +#ifndef IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
4481 +# define IPSEC_SA_REF_MAINTABLE_IDX_WIDTH 4
4482 +#endif
4483 +
4484 +#ifndef IPSEC_SA_REF_FREELIST_NUM_ENTRIES
4485 +# define IPSEC_SA_REF_FREELIST_NUM_ENTRIES 256
4486 +#endif
4487 +
4488 +#ifndef IPSEC_SA_REF_CODE
4489 +# define IPSEC_SA_REF_CODE 1
4490 +#endif
4491 +
4492 +#ifdef __KERNEL__
4493 +/* This is defined for 2.4, but not 2.2.... */
4494 +#ifndef ARPHRD_VOID
4495 +# define ARPHRD_VOID 0xFFFF
4496 +#endif
4497 +
4498 +/* always turn on IPIP mode */
4499 +#ifndef CONFIG_KLIPS_IPIP
4500 +#define CONFIG_KLIPS_IPIP 1
4501 +#endif
4502 +
4503 +/*
4504 + * Worry about PROC_FS stuff
4505 + */
4506 +#if defined(PROC_FS_2325)
4507 +/* kernel 2.4 */
4508 +# define IPSEC_PROC_LAST_ARG ,int *eof,void *data
4509 +# define IPSEC_PROCFS_DEBUG_NO_STATIC
4510 +# define IPSEC_PROC_SUBDIRS
4511 +#else
4512 +/* kernel <2.4 */
4513 +# define IPSEC_PROCFS_DEBUG_NO_STATIC DEBUG_NO_STATIC
4514 +
4515 +# ifndef PROC_NO_DUMMY
4516 +# define IPSEC_PROC_LAST_ARG , int dummy
4517 +# else
4518 +# define IPSEC_PROC_LAST_ARG
4519 +# endif /* !PROC_NO_DUMMY */
4520 +#endif /* PROC_FS_2325 */
4521 +
4522 +#if !defined(LINUX_KERNEL_HAS_SNPRINTF)
4523 +/* GNU CPP specific! */
4524 +# define snprintf(buf, len, fmt...) sprintf(buf, ##fmt)
4525 +#endif /* !LINUX_KERNEL_HAS_SNPRINTF */
4526 +
4527 +#ifdef SPINLOCK
4528 +# ifdef SPINLOCK_23
4529 +# include <linux/spinlock.h> /* *lock* */
4530 +# else /* SPINLOCK_23 */
4531 +# include <asm/spinlock.h> /* *lock* */
4532 +# endif /* SPINLOCK_23 */
4533 +#endif /* SPINLOCK */
4534 +
4535 +#ifndef KLIPS_FIXES_DES_PARITY
4536 +# define KLIPS_FIXES_DES_PARITY 1
4537 +#endif /* !KLIPS_FIXES_DES_PARITY */
4538 +
4539 +/* we don't really want to print these unless there are really big problems */
4540 +#ifndef KLIPS_DIVULGE_CYPHER_KEY
4541 +# define KLIPS_DIVULGE_CYPHER_KEY 0
4542 +#endif /* !KLIPS_DIVULGE_CYPHER_KEY */
4543 +
4544 +#ifndef KLIPS_DIVULGE_HMAC_KEY
4545 +# define KLIPS_DIVULGE_HMAC_KEY 0
4546 +#endif /* !KLIPS_DIVULGE_HMAC_KEY */
4547 +
4548 +#ifndef IPSEC_DISALLOW_IPOPTIONS
4549 +# define IPSEC_DISALLOW_IPOPTIONS 1
4550 +#endif /* !KLIPS_DIVULGE_HMAC_KEY */
4551 +
4552 +/* extra toggles for regression testing */
4553 +#ifdef CONFIG_KLIPS_REGRESS
4554 +
4555 +/*
4556 + * should pfkey_acquire() become 100% lossy?
4557 + *
4558 + */
4559 +extern int sysctl_ipsec_regress_pfkey_lossage;
4560 +#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE
4561 +# ifdef CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE
4562 +# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100
4563 +# else /* CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE */
4564 +/* not by default! */
4565 +# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
4566 +# endif /* CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE */
4567 +#endif /* KLIPS_PFKEY_ACQUIRE_LOSSAGE */
4568 +
4569 +#endif /* CONFIG_KLIPS_REGRESS */
4570 +
4571 +
4572 +/*
4573 + * debugging routines.
4574 + */
4575 +#define KLIPS_ERROR(flag, format, args...) if(printk_ratelimit() || flag) printk(KERN_ERR "KLIPS " format, ## args)
4576 +#ifdef CONFIG_KLIPS_DEBUG
4577 + #define KLIPS_PRINT(flag, format, args...) \
4578 + ((flag) ? printk(KERN_INFO format , ## args) : 0)
4579 + #define KLIPS_PRINTMORE(flag, format, args...) \
4580 + ((flag) ? printk(format , ## args) : 0)
4581 + #define KLIPS_IP_PRINT(flag, ip) \
4582 + ((flag) ? ipsec_print_ip(ip) : 0)
4583 +#else /* CONFIG_KLIPS_DEBUG */
4584 + #define KLIPS_PRINT(flag, format, args...) do ; while(0)
4585 + #define KLIPS_PRINTMORE(flag, format, args...) do ; while(0)
4586 + #define KLIPS_IP_PRINT(flag, ip) do ; while(0)
4587 +#endif /* CONFIG_KLIPS_DEBUG */
4588 +
4589 +
4590 +/*
4591 + * Stupid kernel API differences in APIs. Not only do some
4592 + * kernels not have ip_select_ident, but some have differing APIs,
4593 + * and SuSE has one with one parameter, but no way of checking to
4594 + * see what is really what.
4595 + */
4596 +
4597 +#ifdef SUSE_LINUX_2_4_19_IS_STUPID
4598 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
4599 +#else
4600 +
4601 +/* simplest case, nothing */
4602 +#if !defined(IP_SELECT_IDENT)
4603 +#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
4604 +#endif
4605 +
4606 +/* kernels > 2.3.37-ish */
4607 +#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
4608 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
4609 +#endif
4610 +
4611 +/* kernels > 2.4.2 */
4612 +#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
4613 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
4614 +#endif
4615 +
4616 +#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
4617 +
4618 +/*
4619 + * make klips fail test:east-espiv-01.
4620 + * exploit is at testing/attacks/espiv
4621 + *
4622 + */
4623 +#define KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK 0
4624 +
4625 +
4626 +/* IP_FRAGMENT_LINEARIZE is set in freeswan.h if Kernel > 2.4.4 */
4627 +#ifndef IP_FRAGMENT_LINEARIZE
4628 +# define IP_FRAGMENT_LINEARIZE 0
4629 +#endif /* IP_FRAGMENT_LINEARIZE */
4630 +#endif /* __KERNEL__ */
4631 +
4632 +#ifdef NEED_INET_PROTOCOL
4633 +#define inet_protocol net_protocol
4634 +#endif
4635 +
4636 +#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && CONFIG_IPSEC_NAT_TRAVERSAL
4637 +#define NAT_TRAVERSAL 1
4638 +#else
4639 +/* let people either #undef, or #define = 0 it */
4640 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
4641 +#undef CONFIG_IPSEC_NAT_TRAVERSAL
4642 +#endif
4643 +#endif
4644 +
4645 +#ifndef IPSEC_DEFAULT_TTL
4646 +#define IPSEC_DEFAULT_TTL 64
4647 +#endif
4648 +
4649 +#define _IPSEC_PARAM_H_
4650 +#endif /* _IPSEC_PARAM_H_ */
4651 +
4652 +/*
4653 + * $Log: ipsec_param.h,v $
4654 + * Revision 1.31 2005/08/12 15:01:38 mcr
4655 + * attempt to #undef CONFIG_IPSEC_NAT_TRAVERSAL if it is =0.
4656 + *
4657 + * Revision 1.30 2005/08/05 08:50:45 mcr
4658 + * move #include of skbuff.h to a place where
4659 + * we know it will be kernel only code.
4660 + *
4661 + * Revision 1.29 2005/01/26 00:50:35 mcr
4662 + * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
4663 + * and make sure that NAT_TRAVERSAL is set as well to match
4664 + * userspace compiles of code.
4665 + *
4666 + * Revision 1.28 2004/09/13 15:50:15 mcr
4667 + * spell NEED_INET properly, not NET_INET.
4668 + *
4669 + * Revision 1.27 2004/09/13 02:21:45 mcr
4670 + * always turn on IPIP mode.
4671 + * #define inet_protocol if necessary.
4672 + *
4673 + * Revision 1.26 2004/08/17 03:25:43 mcr
4674 + * freeswan->openswan.
4675 + *
4676 + * Revision 1.25 2004/07/10 19:08:41 mcr
4677 + * CONFIG_IPSEC -> CONFIG_KLIPS.
4678 + *
4679 + * Revision 1.24 2004/04/05 19:55:06 mcr
4680 + * Moved from linux/include/freeswan/ipsec_param.h,v
4681 + *
4682 + * Revision 1.23 2003/12/13 19:10:16 mcr
4683 + * refactored rcv and xmit code - same as FS 2.05.
4684 + *
4685 + * Revision 1.22 2003/10/31 02:27:05 mcr
4686 + * pulled up port-selector patches and sa_id elimination.
4687 + *
4688 + * Revision 1.21.4.1 2003/10/29 01:10:19 mcr
4689 + * elimited "struct sa_id"
4690 + *
4691 + * Revision 1.21 2003/04/03 17:38:18 rgb
4692 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
4693 + * Change indentation for readability.
4694 + *
4695 + * Revision 1.20 2003/03/14 08:09:26 rgb
4696 + * Fixed up CONFIG_IPSEC_DYNDEV definitions.
4697 + *
4698 + * Revision 1.19 2003/01/30 02:31:43 rgb
4699 + *
4700 + * Rename SAref table macro names for clarity.
4701 + *
4702 + * Revision 1.18 2002/09/30 19:06:26 rgb
4703 + * Reduce default table to 16 bits width.
4704 + *
4705 + * Revision 1.17 2002/09/20 15:40:29 rgb
4706 + * Define switch to activate new SAref code.
4707 + * Prefix macros with "IPSEC_".
4708 + * Rework saref freelist.
4709 + * Restrict some bits to kernel context for use to klips utils.
4710 + *
4711 + * Revision 1.16 2002/09/20 05:00:31 rgb
4712 + * Define switch to divulge hmac keys for debugging.
4713 + * Added IPOPTIONS switch.
4714 + *
4715 + * Revision 1.15 2002/09/19 02:34:24 mcr
4716 + * define IPSEC_PROC_SUBDIRS if we are 2.4, and use that in ipsec_proc.c
4717 + * to decide if we are to create /proc/net/ipsec/.
4718 + *
4719 + * Revision 1.14 2002/08/30 01:20:54 mcr
4720 + * reorganized 2.0/2.2/2.4 procfs support macro so match
4721 + * 2.4 values/typedefs.
4722 + *
4723 + * Revision 1.13 2002/07/28 22:03:28 mcr
4724 + * added some documentation to SA_REF_*
4725 + * turned on fix for ESPIV attack, now that we have the attack code.
4726 + *
4727 + * Revision 1.12 2002/07/26 08:48:31 rgb
4728 + * Added SA ref table code.
4729 + *
4730 + * Revision 1.11 2002/07/23 02:57:45 rgb
4731 + * Define ARPHRD_VOID for < 2.4 kernels.
4732 + *
4733 + * Revision 1.10 2002/05/27 21:37:28 rgb
4734 + * Set the defaults sanely for those adventurous enough to try more than 1
4735 + * digit of ipsec devices.
4736 + *
4737 + * Revision 1.9 2002/05/27 18:56:07 rgb
4738 + * Convert to dynamic ipsec device allocation.
4739 + *
4740 + * Revision 1.8 2002/04/24 07:36:47 mcr
4741 + * Moved from ./klips/net/ipsec/ipsec_param.h,v
4742 + *
4743 + * Revision 1.7 2002/04/20 00:12:25 rgb
4744 + * Added esp IV CBC attack fix, disabled.
4745 + *
4746 + * Revision 1.6 2002/01/29 02:11:42 mcr
4747 + * removal of kversions.h - sources that needed it now use ipsec_param.h.
4748 + * updating of IPv6 structures to match latest in6.h version.
4749 + * removed dead code from freeswan.h that also duplicated kversions.h
4750 + * code.
4751 + *
4752 + * Revision 1.5 2002/01/28 19:22:01 mcr
4753 + * by default, turn off LINEARIZE option
4754 + * (let kversions.h turn it on)
4755 + *
4756 + * Revision 1.4 2002/01/20 20:19:36 mcr
4757 + * renamed option to IP_FRAGMENT_LINEARIZE.
4758 + *
4759 + * Revision 1.3 2002/01/12 02:57:25 mcr
4760 + * first regression test causes acquire messages to be lost
4761 + * 100% of the time. This is to help testing of pluto.
4762 + *
4763 + * Revision 1.2 2001/11/26 09:16:14 rgb
4764 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
4765 + *
4766 + * Revision 1.1.2.3 2001/10/23 04:40:16 mcr
4767 + * added #define for DIVULGING session keys in debug output.
4768 + *
4769 + * Revision 1.1.2.2 2001/10/22 20:53:25 mcr
4770 + * added a define to control forcing of DES parity.
4771 + *
4772 + * Revision 1.1.2.1 2001/09/25 02:20:19 mcr
4773 + * many common kernel configuration questions centralized.
4774 + * more things remain that should be moved from freeswan.h.
4775 + *
4776 + *
4777 + * Local variables:
4778 + * c-file-style: "linux"
4779 + * End:
4780 + *
4781 + */
4782 --- /dev/null Tue Mar 11 13:02:56 2003
4783 +++ linux/include/openswan/ipsec_policy.h Mon Feb 9 13:51:03 2004
4784 @@ -0,0 +1,217 @@
4785 +#ifndef _IPSEC_POLICY_H
4786 +/*
4787 + * policy interface file between pluto and applications
4788 + * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
4789 + *
4790 + * This library is free software; you can redistribute it and/or modify it
4791 + * under the terms of the GNU Library General Public License as published by
4792 + * the Free Software Foundation; either version 2 of the License, or (at your
4793 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
4794 + *
4795 + * This library is distributed in the hope that it will be useful, but
4796 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4797 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
4798 + * License for more details.
4799 + *
4800 + * RCSID $Id: ipsec_policy.h,v 1.8 2005/07/26 01:12:38 mcr Exp $
4801 + */
4802 +#define _IPSEC_POLICY_H /* seen it, no need to see it again */
4803 +
4804 +
4805 +/*
4806 + * this file defines an interface between an application (or rather an
4807 + * application library) and a key/policy daemon. It provides for inquiries
4808 + * as to the current state of a connected socket, as well as for general
4809 + * questions.
4810 + *
4811 + * In general, the interface is defined as a series of functional interfaces,
4812 + * and the policy messages should be internal. However, because this is in
4813 + * fact an ABI between pieces of the system that may get compiled and revised
4814 + * seperately, this ABI must be public and revision controlled.
4815 + *
4816 + * It is expected that the daemon will always support previous versions.
4817 + */
4818 +
4819 +#define IPSEC_POLICY_MSG_REVISION (unsigned)200305061
4820 +
4821 +enum ipsec_policy_command {
4822 + IPSEC_CMD_QUERY_FD = 1,
4823 + IPSEC_CMD_QUERY_HOSTPAIR = 2,
4824 + IPSEC_CMD_QUERY_DSTONLY = 3,
4825 +};
4826 +
4827 +struct ipsec_policy_msg_head {
4828 + u_int32_t ipm_version;
4829 + u_int32_t ipm_msg_len;
4830 + u_int32_t ipm_msg_type;
4831 + u_int32_t ipm_msg_seq;
4832 +};
4833 +
4834 +enum ipsec_privacy_quality {
4835 + IPSEC_PRIVACY_NONE = 0,
4836 + IPSEC_PRIVACY_INTEGRAL = 4, /* not private at all. AH-like */
4837 + IPSEC_PRIVACY_UNKNOWN = 8, /* something is claimed, but details unavail */
4838 + IPSEC_PRIVACY_ROT13 = 12, /* trivially breakable, i.e. 1DES */
4839 + IPSEC_PRIVACY_GAK = 16, /* known eavesdroppers */
4840 + IPSEC_PRIVACY_PRIVATE = 32, /* secure for at least a decade */
4841 + IPSEC_PRIVACY_STRONG = 64, /* ridiculously secure */
4842 + IPSEC_PRIVACY_TORTOISE = 192, /* even stronger, but very slow */
4843 + IPSEC_PRIVACY_OTP = 224, /* some kind of *true* one time pad */
4844 +};
4845 +
4846 +enum ipsec_bandwidth_quality {
4847 + IPSEC_QOS_UNKNOWN = 0, /* unknown bandwidth */
4848 + IPSEC_QOS_INTERACTIVE = 16, /* reasonably moderate jitter, moderate fast.
4849 + Good enough for telnet/ssh. */
4850 + IPSEC_QOS_VOIP = 32, /* faster crypto, predicable jitter */
4851 + IPSEC_QOS_FTP = 64, /* higher throughput crypto, perhaps hardware
4852 + offloaded, but latency/jitter may be bad */
4853 + IPSEC_QOS_WIRESPEED = 128, /* expect to be able to fill your pipe */
4854 +};
4855 +
4856 +/* moved from programs/pluto/constants.h */
4857 +/* IPsec AH transform values
4858 + * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.3
4859 + * and in http://www.iana.org/assignments/isakmp-registry
4860 + */
4861 +enum ipsec_authentication_algo {
4862 + AH_MD5=2,
4863 + AH_SHA=3,
4864 + AH_DES=4,
4865 + AH_SHA2_256=5,
4866 + AH_SHA2_384=6,
4867 + AH_SHA2_512=7
4868 +};
4869 +
4870 +/* IPsec ESP transform values
4871 + * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.4
4872 + * and from http://www.iana.org/assignments/isakmp-registry
4873 + */
4874 +
4875 +enum ipsec_cipher_algo {
4876 + ESP_reserved=0,
4877 + ESP_DES_IV64=1,
4878 + ESP_DES=2,
4879 + ESP_3DES=3,
4880 + ESP_RC5=4,
4881 + ESP_IDEA=5,
4882 + ESP_CAST=6,
4883 + ESP_BLOWFISH=7,
4884 + ESP_3IDEA=8,
4885 + ESP_DES_IV32=9,
4886 + ESP_RC4=10,
4887 + ESP_NULL=11,
4888 + ESP_AES=12, /* 128 bit AES */
4889 +};
4890 +
4891 +/* IPCOMP transform values
4892 + * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.5
4893 + */
4894 +
4895 +enum ipsec_comp_algo {
4896 + IPCOMP_OUI= 1,
4897 + IPCOMP_DEFLATE= 2,
4898 + IPCOMP_LZS= 3,
4899 + IPCOMP_V42BIS= 4
4900 +};
4901 +
4902 +/* Identification type values
4903 + * RFC 2407 The Internet IP security Domain of Interpretation for ISAKMP 4.6.2.1
4904 + */
4905 +
4906 +enum ipsec_id_type {
4907 + ID_IMPOSSIBLE= (-2), /* private to Pluto */
4908 + ID_MYID= (-1), /* private to Pluto */
4909 + ID_NONE= 0, /* private to Pluto */
4910 + ID_IPV4_ADDR= 1,
4911 + ID_FQDN= 2,
4912 + ID_USER_FQDN= 3,
4913 + ID_IPV4_ADDR_SUBNET= 4,
4914 + ID_IPV6_ADDR= 5,
4915 + ID_IPV6_ADDR_SUBNET= 6,
4916 + ID_IPV4_ADDR_RANGE= 7,
4917 + ID_IPV6_ADDR_RANGE= 8,
4918 + ID_DER_ASN1_DN= 9,
4919 + ID_DER_ASN1_GN= 10,
4920 + ID_KEY_ID= 11
4921 +};
4922 +
4923 +/* Certificate type values
4924 + * RFC 2408 ISAKMP, chapter 3.9
4925 + */
4926 +enum ipsec_cert_type {
4927 + CERT_NONE= 0, /* none, or guess from file contents */
4928 + CERT_PKCS7_WRAPPED_X509= 1, /* self-signed certificate from disk */
4929 + CERT_PGP= 2,
4930 + CERT_DNS_SIGNED_KEY= 3, /* KEY RR from DNS */
4931 + CERT_X509_SIGNATURE= 4,
4932 + CERT_X509_KEY_EXCHANGE= 5,
4933 + CERT_KERBEROS_TOKENS= 6,
4934 + CERT_CRL= 7,
4935 + CERT_ARL= 8,
4936 + CERT_SPKI= 9,
4937 + CERT_X509_ATTRIBUTE= 10,
4938 + CERT_RAW_RSA= 11, /* raw RSA from config file */
4939 +};
4940 +
4941 +/* a SIG record in ASCII */
4942 +struct ipsec_dns_sig {
4943 + char fqdn[256];
4944 + char dns_sig[768]; /* empty string if not signed */
4945 +};
4946 +
4947 +struct ipsec_raw_key {
4948 + char id_name[256];
4949 + char fs_keyid[8];
4950 +};
4951 +
4952 +struct ipsec_identity {
4953 + enum ipsec_id_type ii_type;
4954 + enum ipsec_cert_type ii_format;
4955 + union {
4956 + struct ipsec_dns_sig ipsec_dns_signed;
4957 + /* some thing for PGP */
4958 + /* some thing for PKIX */
4959 + struct ipsec_raw_key ipsec_raw_key;
4960 + } ii_credential;
4961 +};
4962 +
4963 +#define IPSEC_MAX_CREDENTIALS 32
4964 +
4965 +struct ipsec_policy_cmd_query {
4966 + struct ipsec_policy_msg_head head;
4967 +
4968 + /* Query section */
4969 + ip_address query_local; /* us */
4970 + ip_address query_remote; /* them */
4971 + u_int8_t proto; /* TCP, ICMP, etc. */
4972 + u_short src_port, dst_port;
4973 +
4974 + /* Answer section */
4975 + enum ipsec_privacy_quality strength;
4976 + enum ipsec_bandwidth_quality bandwidth;
4977 + enum ipsec_authentication_algo auth_detail;
4978 + enum ipsec_cipher_algo esp_detail;
4979 + enum ipsec_comp_algo comp_detail;
4980 +
4981 + int credential_count;
4982 +
4983 + struct ipsec_identity credentials[IPSEC_MAX_CREDENTIALS];
4984 +};
4985 +
4986 +#define IPSEC_POLICY_SOCKET "/var/run/pluto/pluto.info"
4987 +
4988 +/* prototypes */
4989 +extern err_t ipsec_policy_lookup(int fd, struct ipsec_policy_cmd_query *result);
4990 +extern err_t ipsec_policy_init(void);
4991 +extern err_t ipsec_policy_final(void);
4992 +extern err_t ipsec_policy_readmsg(int policysock,
4993 + unsigned char *buf, size_t buflen);
4994 +extern err_t ipsec_policy_sendrecv(unsigned char *buf, size_t buflen);
4995 +extern err_t ipsec_policy_cgilookup(struct ipsec_policy_cmd_query *result);
4996 +
4997 +
4998 +extern const char *ipsec_policy_version_code(void);
4999 +extern const char *ipsec_policy_version_string(void);
5000 +
5001 +#endif /* _IPSEC_POLICY_H */
5002 --- /dev/null Tue Mar 11 13:02:56 2003
5003 +++ linux/include/openswan/ipsec_proto.h Mon Feb 9 13:51:03 2004
5004 @@ -0,0 +1,195 @@
5005 +/*
5006 + * @(#) prototypes for FreeSWAN functions
5007 + *
5008 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
5009 + * and Michael Richardson <mcr@freeswan.org>
5010 + *
5011 + * This program is free software; you can redistribute it and/or modify it
5012 + * under the terms of the GNU General Public License as published by the
5013 + * Free Software Foundation; either version 2 of the License, or (at your
5014 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5015 + *
5016 + * This program is distributed in the hope that it will be useful, but
5017 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5018 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5019 + * for more details.
5020 + *
5021 + * RCSID $Id: ipsec_proto.h,v 1.14 2005/04/29 04:50:03 mcr Exp $
5022 + *
5023 + */
5024 +
5025 +#ifndef _IPSEC_PROTO_H_
5026 +
5027 +#include "ipsec_param.h"
5028 +
5029 +/*
5030 + * This file is a kernel only file that declares prototypes for
5031 + * all intra-module function calls and global data structures.
5032 + *
5033 + * Include this file last.
5034 + *
5035 + */
5036 +
5037 +/* forward references */
5038 +enum ipsec_direction;
5039 +enum ipsec_life_type;
5040 +struct ipsec_lifetime64;
5041 +struct ident;
5042 +struct sockaddr_encap;
5043 +struct ipsec_sa;
5044 +
5045 +/* ipsec_init.c */
5046 +extern struct prng ipsec_prng;
5047 +
5048 +/* ipsec_sa.c */
5049 +extern struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
5050 +extern spinlock_t tdb_lock;
5051 +extern int ipsec_sadb_init(void);
5052 +extern int ipsec_sadb_cleanup(__u8);
5053 +
5054 +extern struct ipsec_sa *ipsec_sa_alloc(int*error);
5055 +
5056 +
5057 +extern struct ipsec_sa *ipsec_sa_getbyid(ip_said *);
5058 +extern /* void */ int ipsec_sa_add(struct ipsec_sa *);
5059 +
5060 +extern int ipsec_sa_init(struct ipsec_sa *ipsp);
5061 +
5062 +/* debug declarations */
5063 +
5064 +/* ipsec_proc.c */
5065 +extern int ipsec_proc_init(void);
5066 +extern void ipsec_proc_cleanup(void);
5067 +
5068 +/* ipsec_rcv.c */
5069 +extern int ipsec_rcv(struct sk_buff *skb);
5070 +extern int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type);
5071 +
5072 +/* ipsec_xmit.c */
5073 +struct ipsec_xmit_state;
5074 +extern enum ipsec_xmit_value ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
5075 +extern enum ipsec_xmit_value ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
5076 +extern void ipsec_print_ip(struct iphdr *ip);
5077 +
5078 +
5079 +
5080 +/* ipsec_radij.c */
5081 +extern int ipsec_makeroute(struct sockaddr_encap *ea,
5082 + struct sockaddr_encap *em,
5083 + ip_said said,
5084 + uint32_t pid,
5085 + struct sk_buff *skb,
5086 + struct ident *ident_s,
5087 + struct ident *ident_d);
5088 +
5089 +extern int ipsec_breakroute(struct sockaddr_encap *ea,
5090 + struct sockaddr_encap *em,
5091 + struct sk_buff **first,
5092 + struct sk_buff **last);
5093 +
5094 +int ipsec_radijinit(void);
5095 +int ipsec_cleareroutes(void);
5096 +int ipsec_radijcleanup(void);
5097 +
5098 +/* ipsec_life.c */
5099 +extern enum ipsec_life_alive ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
5100 + const char *lifename,
5101 + const char *saname,
5102 + enum ipsec_life_type ilt,
5103 + enum ipsec_direction idir,
5104 + struct ipsec_sa *ips);
5105 +
5106 +
5107 +extern int ipsec_lifetime_format(char *buffer,
5108 + int buflen,
5109 + char *lifename,
5110 + enum ipsec_life_type timebaselife,
5111 + struct ipsec_lifetime64 *lifetime);
5112 +
5113 +extern void ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
5114 + __u64 newvalue);
5115 +
5116 +extern void ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
5117 + __u64 newvalue);
5118 +
5119 +/* ipsec_snprintf.c */
5120 +extern int ipsec_snprintf(char * buf, ssize_t size, const char *fmt, ...);
5121 +extern void ipsec_dmp_block(char *s, caddr_t bb, int len);
5122 +
5123 +
5124 +/* ipsec_alg.c */
5125 +extern int ipsec_alg_init(void);
5126 +
5127 +
5128 +#ifdef CONFIG_KLIPS_DEBUG
5129 +
5130 +extern int debug_xform;
5131 +extern int debug_eroute;
5132 +extern int debug_spi;
5133 +extern int debug_netlink;
5134 +
5135 +#endif /* CONFIG_KLIPS_DEBUG */
5136 +
5137 +
5138 +
5139 +
5140 +#define _IPSEC_PROTO_H
5141 +#endif /* _IPSEC_PROTO_H_ */
5142 +
5143 +/*
5144 + * $Log: ipsec_proto.h,v $
5145 + * Revision 1.14 2005/04/29 04:50:03 mcr
5146 + * prototypes for xmit and alg code.
5147 + *
5148 + * Revision 1.13 2005/04/17 03:46:07 mcr
5149 + * added prototypes for ipsec_rcv() routines.
5150 + *
5151 + * Revision 1.12 2005/04/14 20:28:37 mcr
5152 + * added additional prototypes.
5153 + *
5154 + * Revision 1.11 2005/04/14 01:16:28 mcr
5155 + * add prototypes for snprintf.
5156 + *
5157 + * Revision 1.10 2005/04/13 22:47:28 mcr
5158 + * make sure that forward references are available.
5159 + *
5160 + * Revision 1.9 2004/07/10 19:08:41 mcr
5161 + * CONFIG_IPSEC -> CONFIG_KLIPS.
5162 + *
5163 + * Revision 1.8 2004/04/05 19:55:06 mcr
5164 + * Moved from linux/include/freeswan/ipsec_proto.h,v
5165 + *
5166 + * Revision 1.7 2003/10/31 02:27:05 mcr
5167 + * pulled up port-selector patches and sa_id elimination.
5168 + *
5169 + * Revision 1.6.30.1 2003/10/29 01:10:19 mcr
5170 + * elimited "struct sa_id"
5171 + *
5172 + * Revision 1.6 2002/05/23 07:13:48 rgb
5173 + * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
5174 + *
5175 + * Revision 1.5 2002/05/14 02:36:40 rgb
5176 + * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
5177 + * with "put" usage in the kernel.
5178 + *
5179 + * Revision 1.4 2002/04/24 07:36:47 mcr
5180 + * Moved from ./klips/net/ipsec/ipsec_proto.h,v
5181 + *
5182 + * Revision 1.3 2002/04/20 00:12:25 rgb
5183 + * Added esp IV CBC attack fix, disabled.
5184 + *
5185 + * Revision 1.2 2001/11/26 09:16:15 rgb
5186 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
5187 + *
5188 + * Revision 1.1.2.1 2001/09/25 02:21:01 mcr
5189 + * ipsec_proto.h created to keep prototypes rather than deal with
5190 + * cyclic dependancies of structures and prototypes in .h files.
5191 + *
5192 + *
5193 + *
5194 + * Local variables:
5195 + * c-file-style: "linux"
5196 + * End:
5197 + *
5198 + */
5199 +
5200 --- /dev/null Tue Mar 11 13:02:56 2003
5201 +++ linux/include/openswan/ipsec_radij.h Mon Feb 9 13:51:03 2004
5202 @@ -0,0 +1,179 @@
5203 +/*
5204 + * @(#) Definitions relevant to the IPSEC <> radij tree interfacing
5205 + * Copyright (C) 1996, 1997 John Ioannidis.
5206 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
5207 + *
5208 + * This program is free software; you can redistribute it and/or modify it
5209 + * under the terms of the GNU General Public License as published by the
5210 + * Free Software Foundation; either version 2 of the License, or (at your
5211 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5212 + *
5213 + * This program is distributed in the hope that it will be useful, but
5214 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5215 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5216 + * for more details.
5217 + *
5218 + * RCSID $Id: ipsec_radij.h,v 1.22 2004/07/10 19:08:41 mcr Exp $
5219 + */
5220 +
5221 +#ifndef _IPSEC_RADIJ_H
5222 +
5223 +#include <openswan.h>
5224 +
5225 +int ipsec_walk(char *);
5226 +
5227 +int ipsec_rj_walker_procprint(struct radij_node *, void *);
5228 +int ipsec_rj_walker_delete(struct radij_node *, void *);
5229 +
5230 +/* This structure is used to pass information between
5231 + * ipsec_eroute_get_info and ipsec_rj_walker_procprint
5232 + * (through rj_walktree) and between calls of ipsec_rj_walker_procprint.
5233 + */
5234 +struct wsbuf
5235 +{
5236 + /* from caller of ipsec_eroute_get_info: */
5237 + char *const buffer; /* start of buffer provided */
5238 + const int length; /* length of buffer provided */
5239 + const off_t offset; /* file position of first character of interest */
5240 + /* accumulated by ipsec_rj_walker_procprint: */
5241 + int len; /* number of character filled into buffer */
5242 + off_t begin; /* file position contained in buffer[0] (<=offset) */
5243 +};
5244 +
5245 +extern struct radij_node_head *rnh;
5246 +extern spinlock_t eroute_lock;
5247 +
5248 +struct eroute * ipsec_findroute(struct sockaddr_encap *);
5249 +
5250 +#define O1(x) (int)(((x)>>24)&0xff)
5251 +#define O2(x) (int)(((x)>>16)&0xff)
5252 +#define O3(x) (int)(((x)>>8)&0xff)
5253 +#define O4(x) (int)(((x))&0xff)
5254 +
5255 +#ifdef CONFIG_KLIPS_DEBUG
5256 +extern int debug_radij;
5257 +void rj_dumptrees(void);
5258 +
5259 +#define DB_RJ_DUMPTREES 0x0001
5260 +#define DB_RJ_FINDROUTE 0x0002
5261 +#endif /* CONFIG_KLIPS_DEBUG */
5262 +
5263 +#define _IPSEC_RADIJ_H
5264 +#endif
5265 +
5266 +/*
5267 + * $Log: ipsec_radij.h,v $
5268 + * Revision 1.22 2004/07/10 19:08:41 mcr
5269 + * CONFIG_IPSEC -> CONFIG_KLIPS.
5270 + *
5271 + * Revision 1.21 2004/04/29 11:06:42 ken
5272 + * Last bits from 2.06 procfs updates
5273 + *
5274 + * Revision 1.20 2004/04/06 02:49:08 mcr
5275 + * pullup of algo code from alg-branch.
5276 + *
5277 + * Revision 1.19 2004/04/05 19:55:06 mcr
5278 + * Moved from linux/include/freeswan/ipsec_radij.h,v
5279 + *
5280 + * Revision 1.18 2002/04/24 07:36:47 mcr
5281 + * Moved from ./klips/net/ipsec/ipsec_radij.h,v
5282 + *
5283 + * Revision 1.17 2001/11/26 09:23:49 rgb
5284 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
5285 + *
5286 + * Revision 1.16.2.1 2001/09/25 02:21:17 mcr
5287 + * ipsec_proto.h created to keep prototypes rather than deal with
5288 + * cyclic dependancies of structures and prototypes in .h files.
5289 + *
5290 + * Revision 1.16 2001/09/15 16:24:04 rgb
5291 + * Re-inject first and last HOLD packet when an eroute REPLACE is done.
5292 + *
5293 + * Revision 1.15 2001/09/14 16:58:37 rgb
5294 + * Added support for storing the first and last packets through a HOLD.
5295 + *
5296 + * Revision 1.14 2001/09/08 21:13:32 rgb
5297 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
5298 + *
5299 + * Revision 1.13 2001/06/14 19:35:09 rgb
5300 + * Update copyright date.
5301 + *
5302 + * Revision 1.12 2001/05/27 06:12:11 rgb
5303 + * Added structures for pid, packet count and last access time to eroute.
5304 + * Added packet count to beginning of /proc/net/ipsec_eroute.
5305 + *
5306 + * Revision 1.11 2000/09/08 19:12:56 rgb
5307 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
5308 + *
5309 + * Revision 1.10 1999/11/17 15:53:39 rgb
5310 + * Changed all occurrences of #include "../../../lib/freeswan.h"
5311 + * to #include <freeswan.h> which works due to -Ilibfreeswan in the
5312 + * klips/net/ipsec/Makefile.
5313 + *
5314 + * Revision 1.9 1999/10/01 00:01:23 rgb
5315 + * Added eroute structure locking.
5316 + *
5317 + * Revision 1.8 1999/04/11 00:28:59 henry
5318 + * GPL boilerplate
5319 + *
5320 + * Revision 1.7 1999/04/06 04:54:26 rgb
5321 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
5322 + * patch shell fixes.
5323 + *
5324 + * Revision 1.6 1999/01/22 06:23:26 rgb
5325 + * Cruft clean-out.
5326 + *
5327 + * Revision 1.5 1998/10/25 02:42:08 rgb
5328 + * Change return type on ipsec_breakroute and ipsec_makeroute and add an
5329 + * argument to be able to transmit more infomation about errors.
5330 + *
5331 + * Revision 1.4 1998/10/19 14:44:29 rgb
5332 + * Added inclusion of freeswan.h.
5333 + * sa_id structure implemented and used: now includes protocol.
5334 + *
5335 + * Revision 1.3 1998/07/28 00:03:31 rgb
5336 + * Comment out temporary inet_nto4u() kluge.
5337 + *
5338 + * Revision 1.2 1998/07/14 18:22:00 rgb
5339 + * Add function to clear the eroute table.
5340 + *
5341 + * Revision 1.1 1998/06/18 21:27:49 henry
5342 + * move sources from klips/src to klips/net/ipsec, to keep stupid
5343 + * kernel-build scripts happier in the presence of symlinks
5344 + *
5345 + * Revision 1.5 1998/05/25 20:30:38 rgb
5346 + * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
5347 + *
5348 + * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
5349 + * add ipsec_rj_walker_delete.
5350 + *
5351 + * Revision 1.4 1998/05/21 13:02:56 rgb
5352 + * Imported definitions from ipsec_radij.c and radij.c to support /proc 3k
5353 + * limit fix.
5354 + *
5355 + * Revision 1.3 1998/04/21 21:29:09 rgb
5356 + * Rearrange debug switches to change on the fly debug output from user
5357 + * space. Only kernel changes checked in at this time. radij.c was also
5358 + * changed to temporarily remove buggy debugging code in rj_delete causing
5359 + * an OOPS and hence, netlink device open errors.
5360 + *
5361 + * Revision 1.2 1998/04/14 17:30:39 rgb
5362 + * Fix up compiling errors for radij tree memory reclamation.
5363 + *
5364 + * Revision 1.1 1998/04/09 03:06:10 henry
5365 + * sources moved up from linux/net/ipsec
5366 + *
5367 + * Revision 1.1.1.1 1998/04/08 05:35:04 henry
5368 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
5369 + *
5370 + * Revision 0.4 1997/01/15 01:28:15 ji
5371 + * No changes.
5372 + *
5373 + * Revision 0.3 1996/11/20 14:39:04 ji
5374 + * Minor cleanups.
5375 + * Rationalized debugging code.
5376 + *
5377 + * Revision 0.2 1996/11/02 00:18:33 ji
5378 + * First limited release.
5379 + *
5380 + *
5381 + */
5382 --- /dev/null Tue Mar 11 13:02:56 2003
5383 +++ linux/include/openswan/ipsec_rcv.h Mon Feb 9 13:51:03 2004
5384 @@ -0,0 +1,197 @@
5385 +/*
5386 + *
5387 + * Copyright (C) 1996, 1997 John Ioannidis.
5388 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
5389 + *
5390 + * This program is free software; you can redistribute it and/or modify it
5391 + * under the terms of the GNU General Public License as published by the
5392 + * Free Software Foundation; either version 2 of the License, or (at your
5393 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5394 + *
5395 + * This program is distributed in the hope that it will be useful, but
5396 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5397 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5398 + * for more details.
5399 + *
5400 + * RCSID $Id: ipsec_rcv.h,v 1.28.2.1 2006/07/10 15:52:20 paul Exp $
5401 + */
5402 +
5403 +#ifndef IPSEC_RCV_H
5404 +#define IPSEC_RCV_H
5405 +
5406 +#include "openswan/ipsec_auth.h"
5407 +
5408 +#define DB_RX_PKTRX 0x0001
5409 +#define DB_RX_PKTRX2 0x0002
5410 +#define DB_RX_DMP 0x0004
5411 +#define DB_RX_IPSA 0x0010
5412 +#define DB_RX_XF 0x0020
5413 +#define DB_RX_IPAD 0x0040
5414 +#define DB_RX_INAU 0x0080
5415 +#define DB_RX_OINFO 0x0100
5416 +#define DB_RX_OINFO2 0x0200
5417 +#define DB_RX_OH 0x0400
5418 +#define DB_RX_REPLAY 0x0800
5419 +
5420 +#ifdef __KERNEL__
5421 +/* struct options; */
5422 +
5423 +#define __NO_VERSION__
5424 +#ifndef AUTOCONF_INCLUDED
5425 +#include <linux/config.h>
5426 +#endif /* for CONFIG_IP_FORWARD */
5427 +#ifdef CONFIG_MODULES
5428 +#include <linux/module.h>
5429 +#endif
5430 +#include <linux/version.h>
5431 +#include <openswan.h>
5432 +
5433 +#define IPSEC_BIRTH_TEMPLATE_MAXLEN 256
5434 +
5435 +struct ipsec_birth_reply {
5436 + int packet_template_len;
5437 + unsigned char packet_template[IPSEC_BIRTH_TEMPLATE_MAXLEN];
5438 +};
5439 +
5440 +extern struct ipsec_birth_reply ipsec_ipv4_birth_packet;
5441 +extern struct ipsec_birth_reply ipsec_ipv6_birth_packet;
5442 +
5443 +enum ipsec_rcv_value {
5444 + IPSEC_RCV_LASTPROTO=1,
5445 + IPSEC_RCV_OK=0,
5446 + IPSEC_RCV_BADPROTO=-1,
5447 + IPSEC_RCV_BADLEN=-2,
5448 + IPSEC_RCV_ESP_BADALG=-3,
5449 + IPSEC_RCV_3DES_BADBLOCKING=-4,
5450 + IPSEC_RCV_ESP_DECAPFAIL=-5,
5451 + IPSEC_RCV_DECAPFAIL=-6,
5452 + IPSEC_RCV_SAIDNOTFOUND=-7,
5453 + IPSEC_RCV_IPCOMPALONE=-8,
5454 + IPSEC_RCV_IPCOMPFAILED=-10,
5455 + IPSEC_RCV_SAIDNOTLIVE=-11,
5456 + IPSEC_RCV_FAILEDINBOUND=-12,
5457 + IPSEC_RCV_LIFETIMEFAILED=-13,
5458 + IPSEC_RCV_BADAUTH=-14,
5459 + IPSEC_RCV_REPLAYFAILED=-15,
5460 + IPSEC_RCV_AUTHFAILED=-16,
5461 + IPSEC_RCV_REPLAYROLLED=-17,
5462 + IPSEC_RCV_BAD_DECRYPT=-18
5463 +};
5464 +
5465 +struct ipsec_rcv_state {
5466 + struct sk_buff *skb;
5467 + struct net_device_stats *stats;
5468 + struct iphdr *ipp; /* the IP header */
5469 + struct ipsec_sa *ipsp; /* current SA being processed */
5470 + int len; /* length of packet */
5471 + int ilen; /* length of inner payload (-authlen) */
5472 + int authlen; /* how big is the auth data at end */
5473 + int hard_header_len; /* layer 2 size */
5474 + int iphlen; /* how big is IP header */
5475 + struct auth_alg *authfuncs;
5476 + ip_said said;
5477 + char sa[SATOT_BUF];
5478 + size_t sa_len;
5479 + __u8 next_header;
5480 + __u8 hash[AH_AMAX];
5481 + char ipsaddr_txt[ADDRTOA_BUF];
5482 + char ipdaddr_txt[ADDRTOA_BUF];
5483 + __u8 *octx;
5484 + __u8 *ictx;
5485 + int ictx_len;
5486 + int octx_len;
5487 + union {
5488 + struct {
5489 + struct esphdr *espp;
5490 + } espstuff;
5491 + struct {
5492 + struct ahhdr *ahp;
5493 + } ahstuff;
5494 + struct {
5495 + struct ipcomphdr *compp;
5496 + } ipcompstuff;
5497 + } protostuff;
5498 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
5499 + __u8 natt_type;
5500 + __u16 natt_sport;
5501 + __u16 natt_dport;
5502 + int natt_len;
5503 +#endif
5504 +};
5505 +
5506 +extern int
5507 +#ifdef PROTO_HANDLER_SINGLE_PARM
5508 +ipsec_rcv(struct sk_buff *skb);
5509 +#else /* PROTO_HANDLER_SINGLE_PARM */
5510 +ipsec_rcv(struct sk_buff *skb,
5511 + unsigned short xlen);
5512 +#endif /* PROTO_HANDLER_SINGLE_PARM */
5513 +
5514 +#ifdef CONFIG_KLIPS_DEBUG
5515 +extern int debug_rcv;
5516 +#define ipsec_rcv_dmp(_x,_y, _z) if (debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
5517 +#else
5518 +#define ipsec_rcv_dmp(_x,_y, _z) do {} while(0)
5519 +#endif /* CONFIG_KLIPS_DEBUG */
5520 +
5521 +extern int sysctl_ipsec_inbound_policy_check;
5522 +#endif /* __KERNEL__ */
5523 +
5524 +extern int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type);
5525 +
5526 +// manage ipsec rcv state objects
5527 +extern int ipsec_rcv_state_cache_init (void);
5528 +extern void ipsec_rcv_state_cache_cleanup (void);
5529 +
5530 +#endif /* IPSEC_RCV_H */
5531 +
5532 +/*
5533 + * $Log: ipsec_rcv.h,v $
5534 + * Revision 1.28.2.1 2006/07/10 15:52:20 paul
5535 + * Fix for bug #642 by Bart Trojanowski
5536 + *
5537 + * Revision 1.28 2005/05/11 00:59:45 mcr
5538 + * do not call debug routines if !defined KLIPS_DEBUG.
5539 + *
5540 + * Revision 1.27 2005/04/29 04:59:46 mcr
5541 + * use ipsec_dmp_block.
5542 + *
5543 + * Revision 1.26 2005/04/13 22:48:35 mcr
5544 + * added comments, and removed some log.
5545 + * removed Linux 2.0 support.
5546 + *
5547 + * Revision 1.25 2005/04/08 18:25:37 mcr
5548 + * prototype klips26 encap receive function
5549 + *
5550 + * Revision 1.24 2004/08/20 21:45:37 mcr
5551 + * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
5552 + * be 26sec compatible. But, some defines where changed.
5553 + *
5554 + * Revision 1.23 2004/08/03 18:17:40 mcr
5555 + * in 2.6, use "net_device" instead of #define device->net_device.
5556 + * this probably breaks 2.0 compiles.
5557 + *
5558 + * Revision 1.22 2004/07/10 19:08:41 mcr
5559 + * CONFIG_IPSEC -> CONFIG_KLIPS.
5560 + *
5561 + * Revision 1.21 2004/04/06 02:49:08 mcr
5562 + * pullup of algo code from alg-branch.
5563 + *
5564 + * Revision 1.20 2004/04/05 19:55:06 mcr
5565 + * Moved from linux/include/freeswan/ipsec_rcv.h,v
5566 + *
5567 + * Revision 1.19 2003/12/15 18:13:09 mcr
5568 + * when compiling with NAT traversal, don't assume that the
5569 + * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
5570 + * is set.
5571 + *
5572 + * history elided 2005-04-12.
5573 + *
5574 + * Local Variables:
5575 + * c-basic-offset:8
5576 + * c-style:linux
5577 + * End:
5578 + *
5579 + */
5580 +
5581 +
5582 --- /dev/null Tue Mar 11 13:02:56 2003
5583 +++ linux/include/openswan/ipsec_sa.h Mon Feb 9 13:51:03 2004
5584 @@ -0,0 +1,279 @@
5585 +/*
5586 + * @(#) Definitions of IPsec Security Association (ipsec_sa)
5587 + *
5588 + * Copyright (C) 2001, 2002, 2003
5589 + * Richard Guy Briggs <rgb@freeswan.org>
5590 + * and Michael Richardson <mcr@freeswan.org>
5591 + *
5592 + * This program is free software; you can redistribute it and/or modify it
5593 + * under the terms of the GNU General Public License as published by the
5594 + * Free Software Foundation; either version 2 of the License, or (at your
5595 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5596 + *
5597 + * This program is distributed in the hope that it will be useful, but
5598 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5599 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5600 + * for more details.
5601 + *
5602 + * RCSID $Id: ipsec_sa.h,v 1.23 2005/05/11 01:18:59 mcr Exp $
5603 + *
5604 + * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
5605 + *
5606 + */
5607 +
5608 +/*
5609 + * This file describes the IPsec Security Association Structure.
5610 + *
5611 + * This structure keeps track of a single transform that may be done
5612 + * to a set of packets. It can describe applying the transform or
5613 + * apply the reverse. (e.g. compression vs expansion). However, it
5614 + * only describes one at a time. To describe both, two structures would
5615 + * be used, but since the sides of the transform are performed
5616 + * on different machines typically it is usual to have only one side
5617 + * of each association.
5618 + *
5619 + */
5620 +
5621 +#ifndef _IPSEC_SA_H_
5622 +
5623 +#ifdef __KERNEL__
5624 +#include "openswan/ipsec_stats.h"
5625 +#include "openswan/ipsec_life.h"
5626 +#include "openswan/ipsec_eroute.h"
5627 +#endif /* __KERNEL__ */
5628 +#include "openswan/ipsec_param.h"
5629 +
5630 +#include "openswan/pfkeyv2.h"
5631 +
5632 +
5633 +/* SAs are held in a table.
5634 + * Entries in this table are referenced by IPsecSAref_t values.
5635 + * IPsecSAref_t values are conceptually subscripts. Because
5636 + * we want to allocate the table piece-meal, the subscripting
5637 + * is implemented with two levels, a bit like paged virtual memory.
5638 + * This representation mechanism is known as an Iliffe Vector.
5639 + *
5640 + * The Main table (AKA the refTable) consists of 2^IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
5641 + * pointers to subtables.
5642 + * Each subtable has 2^IPSEC_SA_REF_SUBTABLE_IDX_WIDTH entries, each of which
5643 + * is a pointer to an SA.
5644 + *
5645 + * An IPsecSAref_t contains either an exceptional value (signified by the
5646 + * high-order bit being on) or a reference to a table entry. A table entry
5647 + * reference has the subtable subscript in the low-order
5648 + * IPSEC_SA_REF_SUBTABLE_IDX_WIDTH bits and the Main table subscript
5649 + * in the next lowest IPSEC_SA_REF_MAINTABLE_IDX_WIDTH bits.
5650 + *
5651 + * The Maintable entry for an IPsecSAref_t x, a pointer to its subtable, is
5652 + * IPsecSAref2table(x). It is of type struct IPsecSArefSubTable *.
5653 + *
5654 + * The pointer to the SA for x is IPsecSAref2SA(x). It is of type
5655 + * struct ipsec_sa*. The macro definition clearly shows the two-level
5656 + * access needed to find the SA pointer.
5657 + *
5658 + * The Maintable is allocated when IPsec is initialized.
5659 + * Each subtable is allocated when needed, but the first is allocated
5660 + * when IPsec is initialized.
5661 + *
5662 + * IPsecSAref_t is designed to be smaller than an NFmark so that
5663 + * they can be stored in NFmarks and still leave a few bits for other
5664 + * purposes. The spare bits are in the low order of the NFmark
5665 + * but in the high order of the IPsecSAref_t, so conversion is required.
5666 + * We pick the upper bits of NFmark on the theory that they are less likely to
5667 + * interfere with more pedestrian uses of nfmark.
5668 + */
5669 +
5670 +
5671 +typedef unsigned short int IPsecRefTableUnusedCount;
5672 +
5673 +#define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH)
5674 +
5675 +#ifdef __KERNEL__
5676 +#if ((IPSEC_SA_REF_TABLE_IDX_WIDTH - (1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) < 0)
5677 +#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")"
5678 +#endif
5679 +
5680 +#define IPSEC_SA_REF_SUBTABLE_IDX_WIDTH (IPSEC_SA_REF_TABLE_IDX_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
5681 +
5682 +#define IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
5683 +#define IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
5684 +
5685 +#ifdef CONFIG_NETFILTER
5686 +#define IPSEC_SA_REF_HOST_FIELD(x) ((struct sk_buff*)(x))->nfmark
5687 +#define IPSEC_SA_REF_HOST_FIELD_TYPE typeof(IPSEC_SA_REF_HOST_FIELD(NULL))
5688 +#else /* CONFIG_NETFILTER */
5689 +/* just make it work for now, it doesn't matter, since there is no nfmark */
5690 +#define IPSEC_SA_REF_HOST_FIELD_TYPE unsigned long
5691 +#endif /* CONFIG_NETFILTER */
5692 +#define IPSEC_SA_REF_HOST_FIELD_WIDTH (8 * sizeof(IPSEC_SA_REF_HOST_FIELD_TYPE))
5693 +#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
5694 +
5695 +#define IPSEC_SA_REF_MAX (~IPSEC_SAREF_NULL)
5696 +#define IPSEC_SAREF_FIRST 1
5697 +#define IPSEC_SA_REF_MASK (IPSEC_SA_REF_MAX >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
5698 +#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)
5699 +#define IPSEC_SA_REF_ENTRY_MASK (IPSEC_SA_REF_MAX >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_SUBTABLE_IDX_WIDTH))
5700 +
5701 +#define IPsecSAref2table(x) (((x) & IPSEC_SA_REF_TABLE_MASK) >> IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
5702 +#define IPsecSAref2entry(x) ((x) & IPSEC_SA_REF_ENTRY_MASK)
5703 +#define IPsecSArefBuild(x,y) (((x) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) + (y))
5704 +
5705 +#define IPsecSAref2SA(x) (ipsec_sadb.refTable[IPsecSAref2table(x)]->entry[IPsecSAref2entry(x)])
5706 +#define IPsecSA2SAref(x) ((x)->ips_ref)
5707 +
5708 +#define EMT_INBOUND 0x01 /* SA direction, 1=inbound */
5709 +
5710 +/* 'struct ipsec_sa' should be 64bit aligned when allocated. */
5711 +struct ipsec_sa
5712 +{
5713 + atomic_t ips_refcount; /* reference count for this struct */
5714 + int ips_marked_deleted; /* used with reference counting */
5715 + IPsecSAref_t ips_ref; /* reference table entry number */
5716 + IPsecSAref_t ips_refhim; /* ref of paired SA, if any */
5717 + struct ipsec_sa *ips_next; /* pointer to next xform */
5718 +
5719 + struct ipsec_sa *ips_hnext; /* next in hash chain */
5720 + struct ipsec_sa *ips_inext; /* pointer to next xform */
5721 + struct ipsec_sa *ips_onext; /* pointer to prev xform */
5722 +
5723 + struct ifnet *ips_rcvif; /* related rcv encap interface */
5724 +
5725 + struct xform_functions *ips_xformfuncs; /* pointer to routines to process this SA */
5726 +
5727 + struct net_device *ips_out; /* what interface to emerge on */
5728 + __u8 ips_transport_direct; /* if true, punt directly to
5729 + * the protocol layer */
5730 + struct socket *ips_sock; /* cache of transport socket */
5731 +
5732 + ip_said ips_said; /* SA ID */
5733 +
5734 + __u32 ips_seq; /* seq num of msg that initiated this SA */
5735 + __u32 ips_pid; /* PID of process that initiated this SA */
5736 + __u8 ips_authalg; /* auth algorithm for this SA */
5737 + __u8 ips_encalg; /* enc algorithm for this SA */
5738 +
5739 + struct ipsec_stats ips_errs;
5740 +
5741 + __u8 ips_replaywin; /* replay window size */
5742 + enum sadb_sastate ips_state; /* state of SA */
5743 + __u32 ips_replaywin_lastseq; /* last pkt sequence num */
5744 + __u64 ips_replaywin_bitmap; /* bitmap of received pkts */
5745 + __u32 ips_replaywin_maxdiff; /* max pkt sequence difference */
5746 +
5747 + __u32 ips_flags; /* generic xform flags */
5748 +
5749 +
5750 + struct ipsec_lifetimes ips_life; /* lifetime records */
5751 +
5752 + /* selector information */
5753 + __u8 ips_transport_protocol; /* protocol for this SA, if ports are involved */
5754 + struct sockaddr*ips_addr_s; /* src sockaddr */
5755 + struct sockaddr*ips_addr_d; /* dst sockaddr */
5756 + struct sockaddr*ips_addr_p; /* proxy sockaddr */
5757 + __u16 ips_addr_s_size;
5758 + __u16 ips_addr_d_size;
5759 + __u16 ips_addr_p_size;
5760 + ip_address ips_flow_s;
5761 + ip_address ips_flow_d;
5762 + ip_address ips_mask_s;
5763 + ip_address ips_mask_d;
5764 +
5765 + __u16 ips_key_bits_a; /* size of authkey in bits */
5766 + __u16 ips_auth_bits; /* size of authenticator in bits */
5767 + __u16 ips_key_bits_e; /* size of enckey in bits */
5768 + __u16 ips_iv_bits; /* size of IV in bits */
5769 + __u8 ips_iv_size;
5770 + __u16 ips_key_a_size;
5771 + __u16 ips_key_e_size;
5772 +
5773 + caddr_t ips_key_a; /* authentication key */
5774 + caddr_t ips_key_e; /* encryption key */
5775 + caddr_t ips_iv; /* Initialisation Vector */
5776 +
5777 + struct ident ips_ident_s; /* identity src */
5778 + struct ident ips_ident_d; /* identity dst */
5779 +
5780 + /* these are included even if CONFIG_KLIPS_IPCOMP is off */
5781 + __u16 ips_comp_adapt_tries; /* ipcomp self-adaption tries */
5782 + __u16 ips_comp_adapt_skip; /* ipcomp self-adaption to-skip */
5783 + __u64 ips_comp_ratio_cbytes; /* compressed bytes */
5784 + __u64 ips_comp_ratio_dbytes; /* decompressed (or uncompressed) bytes */
5785 +
5786 + /* these are included even if CONFIG_IPSEC_NAT_TRAVERSAL is off */
5787 + __u8 ips_natt_type;
5788 + __u8 ips_natt_reserved[3];
5789 + __u16 ips_natt_sport;
5790 + __u16 ips_natt_dport;
5791 +
5792 + struct sockaddr *ips_natt_oa;
5793 + __u16 ips_natt_oa_size;
5794 + __u16 ips_natt_reserved2;
5795 +
5796 +#if 0
5797 + __u32 ips_sens_dpd;
5798 + __u8 ips_sens_sens_level;
5799 + __u8 ips_sens_sens_len;
5800 + __u64* ips_sens_sens_bitmap;
5801 + __u8 ips_sens_integ_level;
5802 + __u8 ips_sens_integ_len;
5803 + __u64* ips_sens_integ_bitmap;
5804 +#endif
5805 + struct ipsec_alg_enc *ips_alg_enc;
5806 + struct ipsec_alg_auth *ips_alg_auth;
5807 +//IPsecSAref_t ips_ref_rel;
5808 +};
5809 +
5810 +struct IPsecSArefSubTable
5811 +{
5812 + struct ipsec_sa* entry[IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES];
5813 +};
5814 +
5815 +struct ipsec_sadb {
5816 + struct IPsecSArefSubTable* refTable[IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES];
5817 + IPsecSAref_t refFreeList[IPSEC_SA_REF_FREELIST_NUM_ENTRIES];
5818 + int refFreeListHead;
5819 + int refFreeListTail;
5820 + IPsecSAref_t refFreeListCont;
5821 + IPsecSAref_t said_hash[SADB_HASHMOD];
5822 + spinlock_t sadb_lock;
5823 +};
5824 +
5825 +extern struct ipsec_sadb ipsec_sadb;
5826 +
5827 +extern int ipsec_SAref_recycle(void);
5828 +extern int ipsec_SArefSubTable_alloc(unsigned table);
5829 +extern int ipsec_saref_freelist_init(void);
5830 +extern int ipsec_sadb_init(void);
5831 +extern struct ipsec_sa *ipsec_sa_alloc(int*error); /* pass in error var by pointer */
5832 +extern IPsecSAref_t ipsec_SAref_alloc(int*erorr); /* pass in error var by pointer */
5833 +extern int ipsec_sa_free(struct ipsec_sa* ips);
5834 +
5835 +#define ipsec_sa_get(ips) __ipsec_sa_get(ips, __FUNCTION__, __LINE__)
5836 +extern struct ipsec_sa * __ipsec_sa_get(struct ipsec_sa *ips, const char *func, int line);
5837 +
5838 +#define ipsec_sa_put(ips) __ipsec_sa_put(ips, __FUNCTION__, __LINE__)
5839 +extern void __ipsec_sa_put(struct ipsec_sa *ips, const char *func, int line);
5840 +extern int ipsec_sa_add(struct ipsec_sa *ips);
5841 +extern void ipsec_sa_rm(struct ipsec_sa *ips);
5842 +extern int ipsec_sadb_cleanup(__u8 proto);
5843 +extern int ipsec_sadb_free(void);
5844 +extern int ipsec_sa_intern(struct ipsec_sa *ips);
5845 +extern void ipsec_sa_untern(struct ipsec_sa *ips);
5846 +extern struct ipsec_sa *ipsec_sa_getbyref(IPsecSAref_t ref);
5847 +
5848 +#endif /* __KERNEL__ */
5849 +
5850 +enum ipsec_direction {
5851 + ipsec_incoming = 1,
5852 + ipsec_outgoing = 2
5853 +};
5854 +
5855 +#define _IPSEC_SA_H_
5856 +#endif /* _IPSEC_SA_H_ */
5857 +
5858 +/*
5859 + * Local variables:
5860 + * c-file-style: "linux"
5861 + * End:
5862 + *
5863 + */
5864 --- /dev/null Tue Mar 11 13:02:56 2003
5865 +++ linux/include/openswan/ipsec_sha1.h Mon Feb 9 13:51:03 2004
5866 @@ -0,0 +1,79 @@
5867 +/*
5868 + * RCSID $Id: ipsec_sha1.h,v 1.8 2004/04/05 19:55:07 mcr Exp $
5869 + */
5870 +
5871 +/*
5872 + * Here is the original comment from the distribution:
5873 +
5874 +SHA-1 in C
5875 +By Steve Reid <steve@edmweb.com>
5876 +100% Public Domain
5877 +
5878 + * Adapted for use by the IPSEC code by John Ioannidis
5879 + */
5880 +
5881 +
5882 +#ifndef _IPSEC_SHA1_H_
5883 +#define _IPSEC_SHA1_H_
5884 +
5885 +typedef struct
5886 +{
5887 + __u32 state[5];
5888 + __u32 count[2];
5889 + __u8 buffer[64];
5890 +} SHA1_CTX;
5891 +
5892 +void SHA1Transform(__u32 state[5], __u8 buffer[64]);
5893 +void SHA1Init(void *context);
5894 +void SHA1Update(void *context, unsigned char *data, __u32 len);
5895 +void SHA1Final(unsigned char digest[20], void *context);
5896 +
5897 +
5898 +#endif /* _IPSEC_SHA1_H_ */
5899 +
5900 +/*
5901 + * $Log: ipsec_sha1.h,v $
5902 + * Revision 1.8 2004/04/05 19:55:07 mcr
5903 + * Moved from linux/include/freeswan/ipsec_sha1.h,v
5904 + *
5905 + * Revision 1.7 2002/09/10 01:45:09 mcr
5906 + * changed type of MD5_CTX and SHA1_CTX to void * so that
5907 + * the function prototypes would match, and could be placed
5908 + * into a pointer to a function.
5909 + *
5910 + * Revision 1.6 2002/04/24 07:36:47 mcr
5911 + * Moved from ./klips/net/ipsec/ipsec_sha1.h,v
5912 + *
5913 + * Revision 1.5 1999/12/13 13:59:13 rgb
5914 + * Quick fix to argument size to Update bugs.
5915 + *
5916 + * Revision 1.4 1999/12/07 18:16:23 rgb
5917 + * Fixed comments at end of #endif lines.
5918 + *
5919 + * Revision 1.3 1999/04/06 04:54:27 rgb
5920 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
5921 + * patch shell fixes.
5922 + *
5923 + * Revision 1.2 1998/11/30 13:22:54 rgb
5924 + * Rationalised all the klips kernel file headers. They are much shorter
5925 + * now and won't conflict under RH5.2.
5926 + *
5927 + * Revision 1.1 1998/06/18 21:27:50 henry
5928 + * move sources from klips/src to klips/net/ipsec, to keep stupid
5929 + * kernel-build scripts happier in the presence of symlinks
5930 + *
5931 + * Revision 1.2 1998/04/23 20:54:05 rgb
5932 + * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
5933 + * verified.
5934 + *
5935 + * Revision 1.1 1998/04/09 03:04:21 henry
5936 + * sources moved up from linux/net/ipsec
5937 + * these two include files modified not to include others except in kernel
5938 + *
5939 + * Revision 1.1.1.1 1998/04/08 05:35:04 henry
5940 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
5941 + *
5942 + * Revision 0.4 1997/01/15 01:28:15 ji
5943 + * New transform
5944 + *
5945 + */
5946 --- /dev/null Tue Mar 11 13:02:56 2003
5947 +++ linux/include/openswan/ipsec_stats.h Mon Feb 9 13:51:03 2004
5948 @@ -0,0 +1,76 @@
5949 +/*
5950 + * @(#) definition of ipsec_stats structure
5951 + *
5952 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
5953 + * and Michael Richardson <mcr@freeswan.org>
5954 + *
5955 + * This program is free software; you can redistribute it and/or modify it
5956 + * under the terms of the GNU General Public License as published by the
5957 + * Free Software Foundation; either version 2 of the License, or (at your
5958 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5959 + *
5960 + * This program is distributed in the hope that it will be useful, but
5961 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5962 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5963 + * for more details.
5964 + *
5965 + * RCSID $Id: ipsec_stats.h,v 1.7 2005/04/14 01:17:45 mcr Exp $
5966 + *
5967 + */
5968 +
5969 +/*
5970 + * This file describes the errors/statistics that FreeSWAN collects.
5971 + */
5972 +
5973 +#ifndef _IPSEC_STATS_H_
5974 +
5975 +struct ipsec_stats {
5976 + __u32 ips_alg_errs; /* number of algorithm errors */
5977 + __u32 ips_auth_errs; /* # of authentication errors */
5978 + __u32 ips_encsize_errs; /* # of encryption size errors*/
5979 + __u32 ips_encpad_errs; /* # of encryption pad errors*/
5980 + __u32 ips_replaywin_errs; /* # of pkt sequence errors */
5981 +};
5982 +
5983 +#define _IPSEC_STATS_H_
5984 +#endif /* _IPSEC_STATS_H_ */
5985 +
5986 +/*
5987 + * $Log: ipsec_stats.h,v $
5988 + * Revision 1.7 2005/04/14 01:17:45 mcr
5989 + * add prototypes for snprintf.
5990 + *
5991 + * Revision 1.6 2004/04/05 19:55:07 mcr
5992 + * Moved from linux/include/freeswan/ipsec_stats.h,v
5993 + *
5994 + * Revision 1.5 2004/04/05 19:41:05 mcr
5995 + * merged alg-branch code.
5996 + *
5997 + * Revision 1.4 2004/03/28 20:27:19 paul
5998 + * Included tested and confirmed fixes mcr made and dhr verified for
5999 + * snprint statements. Changed one other snprintf to use ipsec_snprintf
6000 + * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
6001 + * dhr. (thanks dhr!)
6002 + *
6003 + * Revision 1.4 2004/03/24 01:58:31 mcr
6004 + * sprintf->snprintf for formatting into proc buffer.
6005 + *
6006 + * Revision 1.3.34.1 2004/04/05 04:30:46 mcr
6007 + * patches for alg-branch to compile/work with 2.x openswan
6008 + *
6009 + * Revision 1.3 2002/04/24 07:36:47 mcr
6010 + * Moved from ./klips/net/ipsec/ipsec_stats.h,v
6011 + *
6012 + * Revision 1.2 2001/11/26 09:16:16 rgb
6013 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
6014 + *
6015 + * Revision 1.1.2.1 2001/09/25 02:27:00 mcr
6016 + * statistics moved to seperate structure.
6017 + *
6018 + *
6019 + *
6020 + * Local variables:
6021 + * c-file-style: "linux"
6022 + * End:
6023 + *
6024 + */
6025 --- /dev/null Tue Mar 11 13:02:56 2003
6026 +++ linux/include/openswan/ipsec_tunnel.h Mon Feb 9 13:51:03 2004
6027 @@ -0,0 +1,270 @@
6028 +/*
6029 + * IPSEC tunneling code
6030 + * Copyright (C) 1996, 1997 John Ioannidis.
6031 + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
6032 + *
6033 + * This program is free software; you can redistribute it and/or modify it
6034 + * under the terms of the GNU General Public License as published by the
6035 + * Free Software Foundation; either version 2 of the License, or (at your
6036 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6037 + *
6038 + * This program is distributed in the hope that it will be useful, but
6039 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6040 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6041 + * for more details.
6042 + *
6043 + * RCSID $Id: ipsec_tunnel.h,v 1.33 2005/06/04 16:06:05 mcr Exp $
6044 + */
6045 +
6046 +
6047 +# define DEV_QUEUE_XMIT(skb, device, pri) {\
6048 + skb->dev = device; \
6049 + neigh_compat_output(skb); \
6050 + /* skb->dst->output(skb); */ \
6051 + }
6052 +# define ICMP_SEND(skb_in, type, code, info, dev) \
6053 + icmp_send(skb_in, type, code, htonl(info))
6054 +# define IP_SEND(skb, dev) \
6055 + ip_send(skb);
6056 +
6057 +
6058 +#if defined(KLIPS)
6059 +/*
6060 + * Heavily based on drivers/net/new_tunnel.c. Lots
6061 + * of ideas also taken from the 2.1.x version of drivers/net/shaper.c
6062 + */
6063 +
6064 +struct ipsectunnelconf
6065 +{
6066 + __u32 cf_cmd;
6067 + union
6068 + {
6069 + char cfu_name[12];
6070 + } cf_u;
6071 +#define cf_name cf_u.cfu_name
6072 +};
6073 +
6074 +#define IPSEC_SET_DEV (SIOCDEVPRIVATE)
6075 +#define IPSEC_DEL_DEV (SIOCDEVPRIVATE + 1)
6076 +#define IPSEC_CLR_DEV (SIOCDEVPRIVATE + 2)
6077 +#endif
6078 +
6079 +#ifdef __KERNEL__
6080 +#include <linux/version.h>
6081 +#ifndef KERNEL_VERSION
6082 +# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
6083 +#endif
6084 +struct ipsecpriv
6085 +{
6086 + struct sk_buff_head sendq;
6087 + struct net_device *dev;
6088 + struct wait_queue *wait_queue;
6089 + char locked;
6090 + int (*hard_start_xmit) (struct sk_buff *skb,
6091 + struct net_device *dev);
6092 + int (*hard_header) (struct sk_buff *skb,
6093 + struct net_device *dev,
6094 + unsigned short type,
6095 + void *daddr,
6096 + void *saddr,
6097 + unsigned len);
6098 +#ifdef NET_21
6099 + int (*rebuild_header)(struct sk_buff *skb);
6100 +#else /* NET_21 */
6101 + int (*rebuild_header)(void *buff, struct net_device *dev,
6102 + unsigned long raddr, struct sk_buff *skb);
6103 +#endif /* NET_21 */
6104 + int (*set_mac_address)(struct net_device *dev, void *addr);
6105 +#ifndef NET_21
6106 + void (*header_cache_bind)(struct hh_cache **hhp, struct net_device *dev,
6107 + unsigned short htype, __u32 daddr);
6108 +#endif /* !NET_21 */
6109 + void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr);
6110 + struct net_device_stats *(*get_stats)(struct net_device *dev);
6111 + struct net_device_stats mystats;
6112 + int mtu; /* What is the desired MTU? */
6113 +};
6114 +
6115 +extern char ipsec_tunnel_c_version[];
6116 +
6117 +extern struct net_device *ipsecdevices[IPSEC_NUM_IF];
6118 +
6119 +int ipsec_tunnel_init_devices(void);
6120 +
6121 +/* void */ int ipsec_tunnel_cleanup_devices(void);
6122 +
6123 +extern /* void */ int ipsec_init(void);
6124 +
6125 +extern int ipsec_tunnel_start_xmit(struct sk_buff *skb, struct net_device *dev);
6126 +extern struct net_device *ipsec_get_device(int inst);
6127 +
6128 +#ifdef CONFIG_KLIPS_DEBUG
6129 +extern int debug_tunnel;
6130 +extern int sysctl_ipsec_debug_verbose;
6131 +#endif /* CONFIG_KLIPS_DEBUG */
6132 +#endif /* __KERNEL__ */
6133 +
6134 +#ifdef CONFIG_KLIPS_DEBUG
6135 +#define DB_TN_INIT 0x0001
6136 +#define DB_TN_PROCFS 0x0002
6137 +#define DB_TN_XMIT 0x0010
6138 +#define DB_TN_OHDR 0x0020
6139 +#define DB_TN_CROUT 0x0040
6140 +#define DB_TN_OXFS 0x0080
6141 +#define DB_TN_REVEC 0x0100
6142 +#define DB_TN_ENCAP 0x0200
6143 +#endif /* CONFIG_KLIPS_DEBUG */
6144 +
6145 +// manage ipsec xmit state objects
6146 +extern int ipsec_xmit_state_cache_init (void);
6147 +extern void ipsec_xmit_state_cache_cleanup (void);
6148 +/*
6149 + * $Log: ipsec_tunnel.h,v $
6150 + * Revision 1.33 2005/06/04 16:06:05 mcr
6151 + * better patch for nat-t rcv-device code.
6152 + *
6153 + * Revision 1.32 2005/05/21 03:18:35 mcr
6154 + * added additional debug flag tunnelling.
6155 + *
6156 + * Revision 1.31 2004/08/03 18:18:02 mcr
6157 + * in 2.6, use "net_device" instead of #define device->net_device.
6158 + * this probably breaks 2.0 compiles.
6159 + *
6160 + * Revision 1.30 2004/07/10 19:08:41 mcr
6161 + * CONFIG_IPSEC -> CONFIG_KLIPS.
6162 + *
6163 + * Revision 1.29 2004/04/05 19:55:07 mcr
6164 + * Moved from linux/include/freeswan/ipsec_tunnel.h,v
6165 + *
6166 + * Revision 1.28 2003/06/24 20:22:32 mcr
6167 + * added new global: ipsecdevices[] so that we can keep track of
6168 + * the ipsecX devices. They will be referenced with dev_hold(),
6169 + * so 2.2 may need this as well.
6170 + *
6171 + * Revision 1.27 2003/04/03 17:38:09 rgb
6172 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
6173 + *
6174 + * Revision 1.26 2003/02/12 19:32:20 rgb
6175 + * Updated copyright year.
6176 + *
6177 + * Revision 1.25 2002/05/27 18:56:07 rgb
6178 + * Convert to dynamic ipsec device allocation.
6179 + *
6180 + * Revision 1.24 2002/04/24 07:36:48 mcr
6181 + * Moved from ./klips/net/ipsec/ipsec_tunnel.h,v
6182 + *
6183 + * Revision 1.23 2001/11/06 19:50:44 rgb
6184 + * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
6185 + * use also by pfkey_v2_parser.c
6186 + *
6187 + * Revision 1.22 2001/09/15 16:24:05 rgb
6188 + * Re-inject first and last HOLD packet when an eroute REPLACE is done.
6189 + *
6190 + * Revision 1.21 2001/06/14 19:35:10 rgb
6191 + * Update copyright date.
6192 + *
6193 + * Revision 1.20 2000/09/15 11:37:02 rgb
6194 + * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
6195 + * IPCOMP zlib deflate code.
6196 + *
6197 + * Revision 1.19 2000/09/08 19:12:56 rgb
6198 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
6199 + *
6200 + * Revision 1.18 2000/07/28 13:50:54 rgb
6201 + * Changed enet_statistics to net_device_stats and added back compatibility
6202 + * for pre-2.1.19.
6203 + *
6204 + * Revision 1.17 1999/11/19 01:12:15 rgb
6205 + * Purge unneeded proc_info prototypes, now that static linking uses
6206 + * dynamic proc_info registration.
6207 + *
6208 + * Revision 1.16 1999/11/18 18:51:00 rgb
6209 + * Changed all device registrations for static linking to
6210 + * dynamic to reduce the number and size of patches.
6211 + *
6212 + * Revision 1.15 1999/11/18 04:14:21 rgb
6213 + * Replaced all kernel version macros to shorter, readable form.
6214 + * Added CONFIG_PROC_FS compiler directives in case it is shut off.
6215 + * Added Marc Boucher's 2.3.25 proc patches.
6216 + *
6217 + * Revision 1.14 1999/05/25 02:50:10 rgb
6218 + * Fix kernel version macros for 2.0.x static linking.
6219 + *
6220 + * Revision 1.13 1999/05/25 02:41:06 rgb
6221 + * Add ipsec_klipsdebug support for static linking.
6222 + *
6223 + * Revision 1.12 1999/05/05 22:02:32 rgb
6224 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
6225 + *
6226 + * Revision 1.11 1999/04/29 15:19:50 rgb
6227 + * Add return values to init and cleanup functions.
6228 + *
6229 + * Revision 1.10 1999/04/16 16:02:39 rgb
6230 + * Bump up macro to 4 ipsec I/Fs.
6231 + *
6232 + * Revision 1.9 1999/04/15 15:37:25 rgb
6233 + * Forward check changes from POST1_00 branch.
6234 + *
6235 + * Revision 1.5.2.1 1999/04/02 04:26:14 rgb
6236 + * Backcheck from HEAD, pre1.0.
6237 + *
6238 + * Revision 1.8 1999/04/11 00:29:01 henry
6239 + * GPL boilerplate
6240 + *
6241 + * Revision 1.7 1999/04/06 04:54:28 rgb
6242 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
6243 + * patch shell fixes.
6244 + *
6245 + * Revision 1.6 1999/03/31 05:44:48 rgb
6246 + * Keep PMTU reduction private.
6247 + *
6248 + * Revision 1.5 1999/02/10 22:31:20 rgb
6249 + * Change rebuild_header member to reflect generality of link layer.
6250 + *
6251 + * Revision 1.4 1998/12/01 13:22:04 rgb
6252 + * Added support for debug printing of version info.
6253 + *
6254 + * Revision 1.3 1998/07/29 20:42:46 rgb
6255 + * Add a macro for clearing all tunnel devices.
6256 + * Rearrange structures and declarations for sharing with userspace.
6257 + *
6258 + * Revision 1.2 1998/06/25 20:01:45 rgb
6259 + * Make prototypes available for ipsec_init and ipsec proc_dir_entries
6260 + * for static linking.
6261 + *
6262 + * Revision 1.1 1998/06/18 21:27:50 henry
6263 + * move sources from klips/src to klips/net/ipsec, to keep stupid
6264 + * kernel-build scripts happier in the presence of symlinks
6265 + *
6266 + * Revision 1.3 1998/05/18 21:51:50 rgb
6267 + * Added macros for num of I/F's and a procfs debug switch.
6268 + *
6269 + * Revision 1.2 1998/04/21 21:29:09 rgb
6270 + * Rearrange debug switches to change on the fly debug output from user
6271 + * space. Only kernel changes checked in at this time. radij.c was also
6272 + * changed to temporarily remove buggy debugging code in rj_delete causing
6273 + * an OOPS and hence, netlink device open errors.
6274 + *
6275 + * Revision 1.1 1998/04/09 03:06:13 henry
6276 + * sources moved up from linux/net/ipsec
6277 + *
6278 + * Revision 1.1.1.1 1998/04/08 05:35:05 henry
6279 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
6280 + *
6281 + * Revision 0.5 1997/06/03 04:24:48 ji
6282 + * Added transport mode.
6283 + * Changed the way routing is done.
6284 + * Lots of bug fixes.
6285 + *
6286 + * Revision 0.4 1997/01/15 01:28:15 ji
6287 + * No changes.
6288 + *
6289 + * Revision 0.3 1996/11/20 14:39:04 ji
6290 + * Minor cleanups.
6291 + * Rationalized debugging code.
6292 + *
6293 + * Revision 0.2 1996/11/02 00:18:33 ji
6294 + * First limited release.
6295 + *
6296 + *
6297 + */
6298 --- /dev/null Tue Mar 11 13:02:56 2003
6299 +++ linux/include/openswan/ipsec_xform.h Mon Feb 9 13:51:03 2004
6300 @@ -0,0 +1,263 @@
6301 +/*
6302 + * Definitions relevant to IPSEC transformations
6303 + * Copyright (C) 1996, 1997 John Ioannidis.
6304 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
6305 + * COpyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
6306 + *
6307 + * This program is free software; you can redistribute it and/or modify it
6308 + * under the terms of the GNU General Public License as published by the
6309 + * Free Software Foundation; either version 2 of the License, or (at your
6310 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6311 + *
6312 + * This program is distributed in the hope that it will be useful, but
6313 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6314 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6315 + * for more details.
6316 + *
6317 + * RCSID $Id: ipsec_xform.h,v 1.42 2005/08/05 08:50:45 mcr Exp $
6318 + */
6319 +
6320 +#ifndef _IPSEC_XFORM_H_
6321 +
6322 +#include <openswan.h>
6323 +
6324 +#define XF_NONE 0 /* No transform set */
6325 +#define XF_IP4 1 /* IPv4 inside IPv4 */
6326 +#define XF_AHMD5 2 /* AH MD5 */
6327 +#define XF_AHSHA 3 /* AH SHA */
6328 +#define XF_ESP3DES 5 /* ESP DES3-CBC */
6329 +#define XF_AHHMACMD5 6 /* AH-HMAC-MD5 with opt replay prot */
6330 +#define XF_AHHMACSHA1 7 /* AH-HMAC-SHA1 with opt replay prot */
6331 +#define XF_ESP3DESMD5 9 /* triple DES, HMAC-MD-5, 128-bits of authentication */
6332 +#define XF_ESP3DESMD596 10 /* triple DES, HMAC-MD-5, 96-bits of authentication */
6333 +#define XF_ESPNULLMD596 12 /* NULL, HMAC-MD-5 with 96-bits of authentication */
6334 +#define XF_ESPNULLSHA196 13 /* NULL, HMAC-SHA-1 with 96-bits of authentication */
6335 +#define XF_ESP3DESSHA196 14 /* triple DES, HMAC-SHA-1, 96-bits of authentication */
6336 +#define XF_IP6 15 /* IPv6 inside IPv6 */
6337 +#define XF_COMPDEFLATE 16 /* IPCOMP deflate */
6338 +
6339 +#define XF_CLR 126 /* Clear SA table */
6340 +#define XF_DEL 127 /* Delete SA */
6341 +
6342 +/* IPsec AH transform values
6343 + * RFC 2407
6344 + * draft-ietf-ipsec-doi-tc-mib-02.txt
6345 + */
6346 +
6347 +#define AH_NONE 0
6348 +#define AH_MD5 2
6349 +#define AH_SHA 3
6350 +/* draft-ietf-ipsec-ciph-aes-cbc-03.txt */
6351 +#define AH_SHA2_256 5
6352 +#define AH_SHA2_384 6
6353 +#define AH_SHA2_512 7
6354 +#define AH_RIPEMD 8
6355 +#define AH_MAX 15
6356 +
6357 +/* IPsec ESP transform values */
6358 +
6359 +#define ESP_NONE 0
6360 +#define ESP_DES 2
6361 +#define ESP_3DES 3
6362 +#define ESP_RC5 4
6363 +#define ESP_IDEA 5
6364 +#define ESP_CAST 6
6365 +#define ESP_BLOWFISH 7
6366 +#define ESP_3IDEA 8
6367 +#define ESP_RC4 10
6368 +#define ESP_NULL 11
6369 +#define ESP_AES 12
6370 +
6371 +/* as draft-ietf-ipsec-ciph-aes-cbc-02.txt */
6372 +#define ESP_MARS 249
6373 +#define ESP_RC6 250
6374 +#define ESP_SERPENT 252
6375 +#define ESP_TWOFISH 253
6376 +
6377 +/* IPCOMP transform values */
6378 +
6379 +#define IPCOMP_NONE 0
6380 +#define IPCOMP_OUI 1
6381 +#define IPCOMP_DEFLAT 2
6382 +#define IPCOMP_LZS 3
6383 +#define IPCOMP_V42BIS 4
6384 +
6385 +#define XFT_AUTH 0x0001
6386 +#define XFT_CONF 0x0100
6387 +
6388 +/* available if CONFIG_KLIPS_DEBUG is defined */
6389 +#define DB_XF_INIT 0x0001
6390 +
6391 +#define PROTO2TXT(x) \
6392 + (x) == IPPROTO_AH ? "AH" : \
6393 + (x) == IPPROTO_ESP ? "ESP" : \
6394 + (x) == IPPROTO_IPIP ? "IPIP" : \
6395 + (x) == IPPROTO_COMP ? "COMP" : \
6396 + "UNKNOWN_proto"
6397 +static inline const char *enc_name_id (unsigned id) {
6398 + static char buf[16];
6399 + snprintf(buf, sizeof(buf), "_ID%d", id);
6400 + return buf;
6401 +}
6402 +static inline const char *auth_name_id (unsigned id) {
6403 + static char buf[16];
6404 + snprintf(buf, sizeof(buf), "_ID%d", id);
6405 + return buf;
6406 +}
6407 +#define IPS_XFORM_NAME(x) \
6408 + PROTO2TXT((x)->ips_said.proto), \
6409 + (x)->ips_said.proto == IPPROTO_COMP ? \
6410 + ((x)->ips_encalg == SADB_X_CALG_DEFLATE ? \
6411 + "_DEFLATE" : "_UNKNOWN_comp") : \
6412 + (x)->ips_encalg == ESP_NONE ? "" : \
6413 + (x)->ips_encalg == ESP_3DES ? "_3DES" : \
6414 + (x)->ips_encalg == ESP_AES ? "_AES" : \
6415 + (x)->ips_encalg == ESP_SERPENT ? "_SERPENT" : \
6416 + (x)->ips_encalg == ESP_TWOFISH ? "_TWOFISH" : \
6417 + enc_name_id(x->ips_encalg)/* "_UNKNOWN_encr" */, \
6418 + (x)->ips_authalg == AH_NONE ? "" : \
6419 + (x)->ips_authalg == AH_MD5 ? "_HMAC_MD5" : \
6420 + (x)->ips_authalg == AH_SHA ? "_HMAC_SHA1" : \
6421 + (x)->ips_authalg == AH_SHA2_256 ? "_HMAC_SHA2_256" : \
6422 + (x)->ips_authalg == AH_SHA2_384 ? "_HMAC_SHA2_384" : \
6423 + (x)->ips_authalg == AH_SHA2_512 ? "_HMAC_SHA2_512" : \
6424 + auth_name_id(x->ips_authalg) /* "_UNKNOWN_auth" */ \
6425 +
6426 +#ifdef __KERNEL__
6427 +#include <linux/skbuff.h>
6428 +
6429 +struct ipsec_rcv_state;
6430 +struct ipsec_xmit_state;
6431 +
6432 +struct xform_functions {
6433 + enum ipsec_rcv_value (*rcv_checks)(struct ipsec_rcv_state *irs,
6434 + struct sk_buff *skb);
6435 + enum ipsec_rcv_value (*rcv_decrypt)(struct ipsec_rcv_state *irs);
6436 +
6437 + enum ipsec_rcv_value (*rcv_setup_auth)(struct ipsec_rcv_state *irs,
6438 + struct sk_buff *skb,
6439 + __u32 *replay,
6440 + unsigned char **authenticator);
6441 + enum ipsec_rcv_value (*rcv_calc_auth)(struct ipsec_rcv_state *irs,
6442 + struct sk_buff *skb);
6443 +
6444 + enum ipsec_xmit_value (*xmit_setup)(struct ipsec_xmit_state *ixs);
6445 + enum ipsec_xmit_value (*xmit_encrypt)(struct ipsec_xmit_state *ixs);
6446 +
6447 + enum ipsec_xmit_value (*xmit_setup_auth)(struct ipsec_xmit_state *ixs,
6448 + struct sk_buff *skb,
6449 + __u32 *replay,
6450 + unsigned char **authenticator);
6451 + enum ipsec_xmit_value (*xmit_calc_auth)(struct ipsec_xmit_state *ixs,
6452 + struct sk_buff *skb);
6453 + int xmit_headroom;
6454 + int xmit_needtailroom;
6455 +};
6456 +
6457 +#endif /* __KERNEL__ */
6458 +
6459 +#ifdef CONFIG_KLIPS_DEBUG
6460 +extern void ipsec_dmp(char *s, caddr_t bb, int len);
6461 +#else /* CONFIG_KLIPS_DEBUG */
6462 +#define ipsec_dmp(_x, _y, _z)
6463 +#endif /* CONFIG_KLIPS_DEBUG */
6464 +
6465 +
6466 +#define _IPSEC_XFORM_H_
6467 +#endif /* _IPSEC_XFORM_H_ */
6468 +
6469 +/*
6470 + * $Log: ipsec_xform.h,v $
6471 + * Revision 1.42 2005/08/05 08:50:45 mcr
6472 + * move #include of skbuff.h to a place where
6473 + * we know it will be kernel only code.
6474 + *
6475 + * Revision 1.41 2004/07/10 19:08:41 mcr
6476 + * CONFIG_IPSEC -> CONFIG_KLIPS.
6477 + *
6478 + * Revision 1.40 2004/04/06 02:49:08 mcr
6479 + * pullup of algo code from alg-branch.
6480 + *
6481 + * Revision 1.39 2004/04/05 19:55:07 mcr
6482 + * Moved from linux/include/freeswan/ipsec_xform.h,v
6483 + *
6484 + * Revision 1.38 2004/04/05 19:41:05 mcr
6485 + * merged alg-branch code.
6486 + *
6487 + * Revision 1.37 2003/12/13 19:10:16 mcr
6488 + * refactored rcv and xmit code - same as FS 2.05.
6489 + *
6490 + * Revision 1.36.34.1 2003/12/22 15:25:52 jjo
6491 + * Merged algo-0.8.1-rc11-test1 into alg-branch
6492 + *
6493 + * Revision 1.36 2002/04/24 07:36:48 mcr
6494 + * Moved from ./klips/net/ipsec/ipsec_xform.h,v
6495 + *
6496 + * Revision 1.35 2001/11/26 09:23:51 rgb
6497 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
6498 + *
6499 + * Revision 1.33.2.1 2001/09/25 02:24:58 mcr
6500 + * struct tdb -> struct ipsec_sa.
6501 + * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
6502 + * ipsec_xform.c removed. header file still contains useful things.
6503 + *
6504 + * Revision 1.34 2001/11/06 19:47:17 rgb
6505 + * Changed lifetime_packets to uint32 from uint64.
6506 + *
6507 + * Revision 1.33 2001/09/08 21:13:34 rgb
6508 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
6509 + *
6510 + * Revision 1.32 2001/07/06 07:40:01 rgb
6511 + * Reformatted for readability.
6512 + * Added inbound policy checking fields for use with IPIP SAs.
6513 + *
6514 + * Revision 1.31 2001/06/14 19:35:11 rgb
6515 + * Update copyright date.
6516 + *
6517 + * Revision 1.30 2001/05/30 08:14:03 rgb
6518 + * Removed vestiges of esp-null transforms.
6519 + *
6520 + * Revision 1.29 2001/01/30 23:42:47 rgb
6521 + * Allow pfkey msgs from pid other than user context required for ACQUIRE
6522 + * and subsequent ADD or UDATE.
6523 + *
6524 + * Revision 1.28 2000/11/06 04:30:40 rgb
6525 + * Add Svenning's adaptive content compression.
6526 + *
6527 + * Revision 1.27 2000/09/19 00:38:25 rgb
6528 + * Fixed algorithm name bugs introduced for ipcomp.
6529 + *
6530 + * Revision 1.26 2000/09/17 21:36:48 rgb
6531 + * Added proto2txt macro.
6532 + *
6533 + * Revision 1.25 2000/09/17 18:56:47 rgb
6534 + * Added IPCOMP support.
6535 + *
6536 + * Revision 1.24 2000/09/12 19:34:12 rgb
6537 + * Defined XF_IP6 from Gerhard for ipv6 tunnel support.
6538 + *
6539 + * Revision 1.23 2000/09/12 03:23:14 rgb
6540 + * Cleaned out now unused tdb_xform and tdb_xdata members of struct tdb.
6541 + *
6542 + * Revision 1.22 2000/09/08 19:12:56 rgb
6543 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
6544 + *
6545 + * Revision 1.21 2000/09/01 18:32:43 rgb
6546 + * Added (disabled) sensitivity members to tdb struct.
6547 + *
6548 + * Revision 1.20 2000/08/30 05:31:01 rgb
6549 + * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
6550 + * Kill remainder of tdb_xform, tdb_xdata, xformsw.
6551 + *
6552 + * Revision 1.19 2000/08/01 14:51:52 rgb
6553 + * Removed _all_ remaining traces of DES.
6554 + *
6555 + * Revision 1.18 2000/01/21 06:17:45 rgb
6556 + * Tidied up spacing.
6557 + *
6558 + *
6559 + * Local variables:
6560 + * c-file-style: "linux"
6561 + * End:
6562 + *
6563 + */
6564 --- /dev/null Tue Mar 11 13:02:56 2003
6565 +++ linux/include/openswan/ipsec_xmit.h Mon Feb 9 13:51:03 2004
6566 @@ -0,0 +1,198 @@
6567 +/*
6568 + * IPSEC tunneling code
6569 + * Copyright (C) 1996, 1997 John Ioannidis.
6570 + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
6571 + *
6572 + * This program is free software; you can redistribute it and/or modify it
6573 + * under the terms of the GNU General Public License as published by the
6574 + * Free Software Foundation; either version 2 of the License, or (at your
6575 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6576 + *
6577 + * This program is distributed in the hope that it will be useful, but
6578 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6579 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6580 + * for more details.
6581 + *
6582 + * RCSID $Id: ipsec_xmit.h,v 1.14 2005/05/11 01:00:26 mcr Exp $
6583 + */
6584 +
6585 +#include "openswan/ipsec_sa.h"
6586 +
6587 +enum ipsec_xmit_value
6588 +{
6589 + IPSEC_XMIT_STOLEN=2,
6590 + IPSEC_XMIT_PASS=1,
6591 + IPSEC_XMIT_OK=0,
6592 + IPSEC_XMIT_ERRMEMALLOC=-1,
6593 + IPSEC_XMIT_ESP_BADALG=-2,
6594 + IPSEC_XMIT_BADPROTO=-3,
6595 + IPSEC_XMIT_ESP_PUSHPULLERR=-4,
6596 + IPSEC_XMIT_BADLEN=-5,
6597 + IPSEC_XMIT_AH_BADALG=-6,
6598 + IPSEC_XMIT_SAIDNOTFOUND=-7,
6599 + IPSEC_XMIT_SAIDNOTLIVE=-8,
6600 + IPSEC_XMIT_REPLAYROLLED=-9,
6601 + IPSEC_XMIT_LIFETIMEFAILED=-10,
6602 + IPSEC_XMIT_CANNOTFRAG=-11,
6603 + IPSEC_XMIT_MSSERR=-12,
6604 + IPSEC_XMIT_ERRSKBALLOC=-13,
6605 + IPSEC_XMIT_ENCAPFAIL=-14,
6606 + IPSEC_XMIT_NODEV=-15,
6607 + IPSEC_XMIT_NOPRIVDEV=-16,
6608 + IPSEC_XMIT_NOPHYSDEV=-17,
6609 + IPSEC_XMIT_NOSKB=-18,
6610 + IPSEC_XMIT_NOIPV6=-19,
6611 + IPSEC_XMIT_NOIPOPTIONS=-20,
6612 + IPSEC_XMIT_TTLEXPIRED=-21,
6613 + IPSEC_XMIT_BADHHLEN=-22,
6614 + IPSEC_XMIT_PUSHPULLERR=-23,
6615 + IPSEC_XMIT_ROUTEERR=-24,
6616 + IPSEC_XMIT_RECURSDETECT=-25,
6617 + IPSEC_XMIT_IPSENDFAILURE=-26,
6618 + IPSEC_XMIT_ESPUDP=-27,
6619 + IPSEC_XMIT_ESPUDP_BADTYPE=-28,
6620 +};
6621 +
6622 +struct ipsec_xmit_state
6623 +{
6624 + struct sk_buff *skb; /* working skb pointer */
6625 + struct net_device *dev; /* working dev pointer */
6626 + struct ipsecpriv *prv; /* Our device' private space */
6627 + struct sk_buff *oskb; /* Original skb pointer */
6628 + struct net_device_stats *stats; /* This device's statistics */
6629 + struct iphdr *iph; /* Our new IP header */
6630 + __u32 newdst; /* The other SG's IP address */
6631 + __u32 orgdst; /* Original IP destination address */
6632 + __u32 orgedst; /* 1st SG's IP address */
6633 + __u32 newsrc; /* The new source SG's IP address */
6634 + __u32 orgsrc; /* Original IP source address */
6635 + __u32 innersrc; /* Innermost IP source address */
6636 + int iphlen; /* IP header length */
6637 + int pyldsz; /* upper protocol payload size */
6638 + int headroom;
6639 + int tailroom;
6640 + int authlen;
6641 + int max_headroom; /* The extra header space needed */
6642 + int max_tailroom; /* The extra stuffing needed */
6643 + int ll_headroom; /* The extra link layer hard_header space needed */
6644 + int tot_headroom; /* The total header space needed */
6645 + int tot_tailroom; /* The totalstuffing needed */
6646 + __u8 *saved_header; /* saved copy of the hard header */
6647 + unsigned short sport, dport;
6648 +
6649 + struct sockaddr_encap matcher; /* eroute search key */
6650 + struct eroute *eroute;
6651 + struct ipsec_sa *ipsp, *ipsq; /* ipsec_sa pointers */
6652 + char sa_txt[SATOT_BUF];
6653 + size_t sa_len;
6654 + int hard_header_stripped; /* has the hard header been removed yet? */
6655 + int hard_header_len;
6656 + struct net_device *physdev;
6657 +/* struct device *virtdev; */
6658 + short physmtu;
6659 + short cur_mtu; /* copy of prv->mtu, cause prv may == NULL */
6660 + short mtudiff;
6661 +#ifdef NET_21
6662 + struct rtable *route;
6663 +#endif /* NET_21 */
6664 + ip_said outgoing_said;
6665 +#ifdef NET_21
6666 + int pass;
6667 +#endif /* NET_21 */
6668 + int error;
6669 + uint32_t eroute_pid;
6670 + struct ipsec_sa ips;
6671 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
6672 + uint8_t natt_type;
6673 + uint8_t natt_head;
6674 + uint16_t natt_sport;
6675 + uint16_t natt_dport;
6676 +#endif
6677 +};
6678 +
6679 +enum ipsec_xmit_value
6680 +ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
6681 +
6682 +enum ipsec_xmit_value
6683 +ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
6684 +
6685 +enum ipsec_xmit_value
6686 +ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs);
6687 +
6688 +extern void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er);
6689 +
6690 +
6691 +extern int ipsec_xmit_trap_count;
6692 +extern int ipsec_xmit_trap_sendcount;
6693 +
6694 +#ifdef CONFIG_KLIPS_DEBUG
6695 +extern int debug_tunnel;
6696 +
6697 +#define debug_xmit debug_tunnel
6698 +
6699 +#define ipsec_xmit_dmp(_x,_y, _z) if (debug_xmit && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
6700 +#else
6701 +#define ipsec_xmit_dmp(_x,_y, _z) do {} while(0)
6702 +
6703 +#endif /* CONFIG_KLIPS_DEBUG */
6704 +
6705 +extern int sysctl_ipsec_debug_verbose;
6706 +extern int sysctl_ipsec_icmp;
6707 +extern int sysctl_ipsec_tos;
6708 +
6709 +
6710 +/*
6711 + * $Log: ipsec_xmit.h,v $
6712 + * Revision 1.14 2005/05/11 01:00:26 mcr
6713 + * do not call debug routines if !defined KLIPS_DEBUG.
6714 + *
6715 + * Revision 1.13 2005/04/29 05:01:38 mcr
6716 + * use ipsec_dmp_block.
6717 + * added cur_mtu to ixs instead of using ixs->dev.
6718 + *
6719 + * Revision 1.12 2004/08/20 21:45:37 mcr
6720 + * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
6721 + * be 26sec compatible. But, some defines where changed.
6722 + *
6723 + * Revision 1.11 2004/08/03 18:18:21 mcr
6724 + * in 2.6, use "net_device" instead of #define device->net_device.
6725 + * this probably breaks 2.0 compiles.
6726 + *
6727 + * Revision 1.10 2004/07/10 19:08:41 mcr
6728 + * CONFIG_IPSEC -> CONFIG_KLIPS.
6729 + *
6730 + * Revision 1.9 2004/04/06 02:49:08 mcr
6731 + * pullup of algo code from alg-branch.
6732 + *
6733 + * Revision 1.8 2004/04/05 19:55:07 mcr
6734 + * Moved from linux/include/freeswan/ipsec_xmit.h,v
6735 + *
6736 + * Revision 1.7 2004/02/03 03:11:40 mcr
6737 + * new xmit type if the UDP encapsulation is wrong.
6738 + *
6739 + * Revision 1.6 2003/12/13 19:10:16 mcr
6740 + * refactored rcv and xmit code - same as FS 2.05.
6741 + *
6742 + * Revision 1.5 2003/12/10 01:20:06 mcr
6743 + * NAT-traversal patches to KLIPS.
6744 + *
6745 + * Revision 1.4 2003/12/06 16:37:04 mcr
6746 + * 1.4.7a X.509 patch applied.
6747 + *
6748 + * Revision 1.3 2003/10/31 02:27:05 mcr
6749 + * pulled up port-selector patches and sa_id elimination.
6750 + *
6751 + * Revision 1.2.4.2 2003/10/29 01:10:19 mcr
6752 + * elimited "struct sa_id"
6753 + *
6754 + * Revision 1.2.4.1 2003/09/21 13:59:38 mcr
6755 + * pre-liminary X.509 patch - does not yet pass tests.
6756 + *
6757 + * Revision 1.2 2003/06/20 01:42:13 mcr
6758 + * added counters to measure how many ACQUIREs we send to pluto,
6759 + * and how many are successfully sent.
6760 + *
6761 + * Revision 1.1 2003/02/12 19:31:03 rgb
6762 + * Refactored from ipsec_tunnel.c
6763 + *
6764 + */
6765 --- /dev/null Tue Mar 11 13:02:56 2003
6766 +++ linux/include/openswan/passert.h Mon Feb 9 13:51:03 2004
6767 @@ -0,0 +1,75 @@
6768 +/*
6769 + * sanitize a string into a printable format.
6770 + *
6771 + * Copyright (C) 1998-2002 D. Hugh Redelmeier.
6772 + * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
6773 + *
6774 + * This library is free software; you can redistribute it and/or modify it
6775 + * under the terms of the GNU Library General Public License as published by
6776 + * the Free Software Foundation; either version 2 of the License, or (at your
6777 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
6778 + *
6779 + * This library is distributed in the hope that it will be useful, but
6780 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6781 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
6782 + * License for more details.
6783 + *
6784 + * RCSID $Id: passert.h,v 1.7 2004/10/21 18:44:42 mcr Exp $
6785 + */
6786 +
6787 +#include "openswan.h"
6788 +
6789 +#ifndef _OPENSWAN_PASSERT_H
6790 +#define _OPENSWAN_PASSERT_H
6791 +/* our versions of assert: log result */
6792 +
6793 +#ifdef DEBUG
6794 +
6795 +typedef void (*openswan_passert_fail_t)(const char *pred_str,
6796 + const char *file_str,
6797 + unsigned long line_no) NEVER_RETURNS;
6798 +
6799 +openswan_passert_fail_t openswan_passert_fail;
6800 +
6801 +extern void pexpect_log(const char *pred_str
6802 + , const char *file_str, unsigned long line_no);
6803 +
6804 +# define impossible() do { \
6805 + if(openswan_passert_fail) { \
6806 + (*openswan_passert_fail)("impossible", __FILE__, __LINE__); \
6807 + }} while(0)
6808 +
6809 +extern void openswan_switch_fail(int n
6810 + , const char *file_str, unsigned long line_no) NEVER_RETURNS;
6811 +
6812 +# define bad_case(n) openswan_switch_fail((int) n, __FILE__, __LINE__)
6813 +
6814 +# define passert(pred) do { \
6815 + if (!(pred)) \
6816 + if(openswan_passert_fail) { \
6817 + (*openswan_passert_fail)(#pred, __FILE__, __LINE__); \
6818 + } \
6819 + } while(0)
6820 +
6821 +# define pexpect(pred) do { \
6822 + if (!(pred)) \
6823 + pexpect_log(#pred, __FILE__, __LINE__); \
6824 + } while(0)
6825 +
6826 +/* assert that an err_t is NULL; evaluate exactly once */
6827 +# define happy(x) { \
6828 + err_t ugh = x; \
6829 + if (ugh != NULL) \
6830 + if(openswan_passert_fail) { (*openswan_passert_fail)(ugh, __FILE__, __LINE__); } \
6831 + }
6832 +
6833 +#else /*!DEBUG*/
6834 +
6835 +# define impossible() abort()
6836 +# define bad_case(n) abort()
6837 +# define passert(pred) { } /* do nothing */
6838 +# define happy(x) { (void) x; } /* evaluate non-judgementally */
6839 +
6840 +#endif /*!DEBUG*/
6841 +
6842 +#endif /* _OPENSWAN_PASSERT_H */
6843 --- /dev/null Tue Mar 11 13:02:56 2003
6844 +++ linux/include/openswan/pfkey.h Mon Feb 9 13:51:03 2004
6845 @@ -0,0 +1,344 @@
6846 +/*
6847 + * FreeS/WAN specific PF_KEY headers
6848 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
6849 + *
6850 + * This program is free software; you can redistribute it and/or modify it
6851 + * under the terms of the GNU General Public License as published by the
6852 + * Free Software Foundation; either version 2 of the License, or (at your
6853 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6854 + *
6855 + * This program is distributed in the hope that it will be useful, but
6856 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6857 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6858 + * for more details.
6859 + *
6860 + * RCSID $Id: pfkey.h,v 1.52 2005/11/09 00:30:37 mcr Exp $
6861 + */
6862 +
6863 +#ifndef __NET_IPSEC_PF_KEY_H
6864 +#define __NET_IPSEC_PF_KEY_H
6865 +#ifdef __KERNEL__
6866 +extern struct proto_ops pfkey_proto_ops;
6867 +typedef struct sock pfkey_sock;
6868 +extern int debug_pfkey;
6869 +
6870 +extern /* void */ int pfkey_init(void);
6871 +extern /* void */ int pfkey_cleanup(void);
6872 +
6873 +struct socket_list
6874 +{
6875 + struct socket *socketp;
6876 + struct socket_list *next;
6877 +};
6878 +extern int pfkey_list_insert_socket(struct socket*, struct socket_list**);
6879 +extern int pfkey_list_remove_socket(struct socket*, struct socket_list**);
6880 +extern struct socket_list *pfkey_open_sockets;
6881 +extern struct socket_list *pfkey_registered_sockets[];
6882 +
6883 +struct ipsec_alg_supported
6884 +{
6885 + uint16_t ias_exttype;
6886 + uint8_t ias_id;
6887 + uint8_t ias_ivlen;
6888 + uint16_t ias_keyminbits;
6889 + uint16_t ias_keymaxbits;
6890 + char *ias_name;
6891 +};
6892 +
6893 +extern struct supported_list *pfkey_supported_list[];
6894 +struct supported_list
6895 +{
6896 + struct ipsec_alg_supported *supportedp;
6897 + struct supported_list *next;
6898 +};
6899 +extern int pfkey_list_insert_supported(struct ipsec_alg_supported*, struct supported_list**);
6900 +extern int pfkey_list_remove_supported(struct ipsec_alg_supported*, struct supported_list**);
6901 +
6902 +struct sockaddr_key
6903 +{
6904 + uint16_t key_family; /* PF_KEY */
6905 + uint16_t key_pad; /* not used */
6906 + uint32_t key_pid; /* process ID */
6907 +};
6908 +
6909 +struct pfkey_extracted_data
6910 +{
6911 + struct ipsec_sa* ips;
6912 + struct ipsec_sa* ips2;
6913 + struct eroute *eroute;
6914 +};
6915 +
6916 +/* forward reference */
6917 +struct sadb_ext;
6918 +struct sadb_msg;
6919 +struct sockaddr;
6920 +struct sadb_comb;
6921 +struct sadb_sadb;
6922 +struct sadb_alg;
6923 +
6924 +extern int
6925 +pfkey_alloc_eroute(struct eroute** eroute);
6926 +
6927 +extern int
6928 +pfkey_sa_process(struct sadb_ext *pfkey_ext,
6929 + struct pfkey_extracted_data* extr);
6930 +
6931 +extern int
6932 +pfkey_lifetime_process(struct sadb_ext *pfkey_ext,
6933 + struct pfkey_extracted_data* extr);
6934 +
6935 +extern int
6936 +pfkey_address_process(struct sadb_ext *pfkey_ext,
6937 + struct pfkey_extracted_data* extr);
6938 +
6939 +extern int
6940 +pfkey_key_process(struct sadb_ext *pfkey_ext,
6941 + struct pfkey_extracted_data* extr);
6942 +
6943 +extern int
6944 +pfkey_ident_process(struct sadb_ext *pfkey_ext,
6945 + struct pfkey_extracted_data* extr);
6946 +
6947 +extern int
6948 +pfkey_sens_process(struct sadb_ext *pfkey_ext,
6949 + struct pfkey_extracted_data* extr);
6950 +
6951 +extern int
6952 +pfkey_prop_process(struct sadb_ext *pfkey_ext,
6953 + struct pfkey_extracted_data* extr);
6954 +
6955 +extern int
6956 +pfkey_supported_process(struct sadb_ext *pfkey_ext,
6957 + struct pfkey_extracted_data* extr);
6958 +
6959 +extern int
6960 +pfkey_spirange_process(struct sadb_ext *pfkey_ext,
6961 + struct pfkey_extracted_data* extr);
6962 +
6963 +extern int
6964 +pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext,
6965 + struct pfkey_extracted_data* extr);
6966 +
6967 +extern int
6968 +pfkey_x_satype_process(struct sadb_ext *pfkey_ext,
6969 + struct pfkey_extracted_data* extr);
6970 +
6971 +extern int
6972 +pfkey_x_debug_process(struct sadb_ext *pfkey_ext,
6973 + struct pfkey_extracted_data* extr);
6974 +
6975 +extern int pfkey_upmsg(struct socket *, struct sadb_msg *);
6976 +extern int pfkey_expire(struct ipsec_sa *, int);
6977 +extern int pfkey_acquire(struct ipsec_sa *);
6978 +#else /* ! __KERNEL__ */
6979 +
6980 +extern openswan_keying_debug_func_t pfkey_debug_func;
6981 +extern openswan_keying_debug_func_t pfkey_error_func;
6982 +extern void pfkey_print(struct sadb_msg *msg, FILE *out);
6983 +
6984 +
6985 +#endif /* __KERNEL__ */
6986 +
6987 +extern uint8_t satype2proto(uint8_t satype);
6988 +extern uint8_t proto2satype(uint8_t proto);
6989 +extern char* satype2name(uint8_t satype);
6990 +extern char* proto2name(uint8_t proto);
6991 +
6992 +struct key_opt
6993 +{
6994 + uint32_t key_pid; /* process ID */
6995 + struct sock *sk;
6996 +};
6997 +
6998 +#define key_pid(sk) ((struct key_opt*)&((sk)->sk_protinfo))->key_pid
6999 +
7000 +/* XXX-mcr this is not an alignment, this is because the count is in 64-bit
7001 + * words.
7002 + */
7003 +#define IPSEC_PFKEYv2_ALIGN (sizeof(uint64_t)/sizeof(uint8_t))
7004 +#define BITS_PER_OCTET 8
7005 +#define OCTETBITS 8
7006 +#define PFKEYBITS 64
7007 +#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */
7008 +#define ALIGN_N(x,y) (DIVUP(x,y) * y) /* align on y boundary */
7009 +
7010 +#define IPSEC_PFKEYv2_LEN(x) ((x) * IPSEC_PFKEYv2_ALIGN)
7011 +#define IPSEC_PFKEYv2_WORDS(x) ((x) / IPSEC_PFKEYv2_ALIGN)
7012 +
7013 +
7014 +#define PFKEYv2_MAX_MSGSIZE 4096
7015 +
7016 +/*
7017 + * PF_KEYv2 permitted and required extensions in and out bitmaps
7018 + */
7019 +struct pf_key_ext_parsers_def {
7020 + int (*parser)(struct sadb_ext*);
7021 + char *parser_name;
7022 +};
7023 +
7024 +
7025 +#define SADB_EXTENSIONS_MAX 31
7026 +extern unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_EXTENSIONS_MAX];
7027 +#define EXT_BITS_IN 0
7028 +#define EXT_BITS_OUT 1
7029 +#define EXT_BITS_PERM 0
7030 +#define EXT_BITS_REQ 1
7031 +
7032 +extern void pfkey_extensions_init(struct sadb_ext *extensions[]);
7033 +extern void pfkey_extensions_free(struct sadb_ext *extensions[]);
7034 +extern void pfkey_msg_free(struct sadb_msg **pfkey_msg);
7035 +
7036 +extern int pfkey_msg_parse(struct sadb_msg *pfkey_msg,
7037 + struct pf_key_ext_parsers_def *ext_parsers[],
7038 + struct sadb_ext **extensions,
7039 + int dir);
7040 +
7041 +extern int pfkey_register_reply(int satype, struct sadb_msg *sadb_msg);
7042 +
7043 +/*
7044 + * PF_KEYv2 build function prototypes
7045 + */
7046 +
7047 +int
7048 +pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
7049 + uint8_t msg_type,
7050 + uint8_t satype,
7051 + uint8_t msg_errno,
7052 + uint32_t seq,
7053 + uint32_t pid);
7054 +
7055 +int
7056 +pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
7057 + uint16_t exttype,
7058 + uint32_t spi, /* in network order */
7059 + uint8_t replay_window,
7060 + uint8_t sa_state,
7061 + uint8_t auth,
7062 + uint8_t encrypt,
7063 + uint32_t flags,
7064 + uint32_t/*IPsecSAref_t*/ ref);
7065 +
7066 +int
7067 +pfkey_sa_build(struct sadb_ext ** pfkey_ext,
7068 + uint16_t exttype,
7069 + uint32_t spi, /* in network order */
7070 + uint8_t replay_window,
7071 + uint8_t sa_state,
7072 + uint8_t auth,
7073 + uint8_t encrypt,
7074 + uint32_t flags);
7075 +
7076 +int
7077 +pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
7078 + uint16_t exttype,
7079 + uint32_t allocations,
7080 + uint64_t bytes,
7081 + uint64_t addtime,
7082 + uint64_t usetime,
7083 + uint32_t packets);
7084 +
7085 +int
7086 +pfkey_address_build(struct sadb_ext** pfkey_ext,
7087 + uint16_t exttype,
7088 + uint8_t proto,
7089 + uint8_t prefixlen,
7090 + struct sockaddr* address);
7091 +
7092 +int
7093 +pfkey_key_build(struct sadb_ext** pfkey_ext,
7094 + uint16_t exttype,
7095 + uint16_t key_bits,
7096 + unsigned char *key);
7097 +
7098 +int
7099 +pfkey_ident_build(struct sadb_ext** pfkey_ext,
7100 + uint16_t exttype,
7101 + uint16_t ident_type,
7102 + uint64_t ident_id,
7103 + uint8_t ident_len,
7104 + char* ident_string);
7105 +
7106 +#ifdef __KERNEL__
7107 +extern int pfkey_nat_t_new_mapping(struct ipsec_sa *, struct sockaddr *, __u16);
7108 +extern int pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
7109 +extern int pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
7110 +#endif /* __KERNEL__ */
7111 +int
7112 +pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
7113 + uint8_t type);
7114 +int
7115 +pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
7116 + uint16_t exttype,
7117 + uint16_t port);
7118 +
7119 +int
7120 +pfkey_sens_build(struct sadb_ext** pfkey_ext,
7121 + uint32_t dpd,
7122 + uint8_t sens_level,
7123 + uint8_t sens_len,
7124 + uint64_t* sens_bitmap,
7125 + uint8_t integ_level,
7126 + uint8_t integ_len,
7127 + uint64_t* integ_bitmap);
7128 +
7129 +int pfkey_x_protocol_build(struct sadb_ext **, uint8_t);
7130 +
7131 +
7132 +int
7133 +pfkey_prop_build(struct sadb_ext** pfkey_ext,
7134 + uint8_t replay,
7135 + unsigned int comb_num,
7136 + struct sadb_comb* comb);
7137 +
7138 +int
7139 +pfkey_supported_build(struct sadb_ext** pfkey_ext,
7140 + uint16_t exttype,
7141 + unsigned int alg_num,
7142 + struct sadb_alg* alg);
7143 +
7144 +int
7145 +pfkey_spirange_build(struct sadb_ext** pfkey_ext,
7146 + uint16_t exttype,
7147 + uint32_t min,
7148 + uint32_t max);
7149 +
7150 +int
7151 +pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext);
7152 +
7153 +int
7154 +pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
7155 + uint8_t satype);
7156 +
7157 +int
7158 +pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
7159 + uint32_t tunnel,
7160 + uint32_t netlink,
7161 + uint32_t xform,
7162 + uint32_t eroute,
7163 + uint32_t spi,
7164 + uint32_t radij,
7165 + uint32_t esp,
7166 + uint32_t ah,
7167 + uint32_t rcv,
7168 + uint32_t pfkey,
7169 + uint32_t ipcomp,
7170 + uint32_t verbose);
7171 +
7172 +int
7173 +pfkey_msg_build(struct sadb_msg** pfkey_msg,
7174 + struct sadb_ext* extensions[],
7175 + int dir);
7176 +
7177 +/* in pfkey_v2_debug.c - routines to decode numbers -> strings */
7178 +const char *
7179 +pfkey_v2_sadb_ext_string(int extnum);
7180 +
7181 +const char *
7182 +pfkey_v2_sadb_type_string(int sadb_type);
7183 +
7184 +extern int
7185 +pfkey_outif_build(struct sadb_ext **pfkey_ext,
7186 + uint16_t outif);
7187 +
7188 +#endif /* __NET_IPSEC_PF_KEY_H */
7189 +
7190 --- /dev/null Tue Mar 11 13:02:56 2003
7191 +++ linux/include/openswan/pfkey_debug.h Mon Feb 9 13:51:03 2004
7192 @@ -0,0 +1,54 @@
7193 +/*
7194 + * sanitize a string into a printable format.
7195 + *
7196 + * Copyright (C) 1998-2002 D. Hugh Redelmeier.
7197 + * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
7198 + *
7199 + * This library is free software; you can redistribute it and/or modify it
7200 + * under the terms of the GNU Library General Public License as published by
7201 + * the Free Software Foundation; either version 2 of the License, or (at your
7202 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
7203 + *
7204 + * This library is distributed in the hope that it will be useful, but
7205 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
7206 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
7207 + * License for more details.
7208 + *
7209 + * RCSID $Id: pfkey_debug.h,v 1.3 2004/04/05 19:55:07 mcr Exp $
7210 + */
7211 +
7212 +#ifndef _FREESWAN_PFKEY_DEBUG_H
7213 +#define _FREESWAN_PFKEY_DEBUG_H
7214 +
7215 +#ifdef __KERNEL__
7216 +
7217 +/* note, kernel version ignores pfkey levels */
7218 +# define DEBUGGING(level,args...) \
7219 + KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
7220 +
7221 +# define ERROR(args...) printk(KERN_ERR "klips:" args)
7222 +
7223 +#else
7224 +
7225 +extern unsigned int pfkey_lib_debug;
7226 +
7227 +extern int (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
7228 +extern int (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
7229 +
7230 +#define DEBUGGING(level,args...) if(pfkey_lib_debug & level) { \
7231 + if(pfkey_debug_func != NULL) { \
7232 + (*pfkey_debug_func)("pfkey_lib_debug:" args); \
7233 + } else { \
7234 + printf("pfkey_lib_debug:" args); \
7235 + } }
7236 +
7237 +#define ERROR(args...) if(pfkey_error_func != NULL) { \
7238 + (*pfkey_error_func)("pfkey_lib_debug:" args); \
7239 + }
7240 +
7241 +# define MALLOC(size) malloc(size)
7242 +# define FREE(obj) free(obj)
7243 +
7244 +#endif
7245 +
7246 +#endif
7247 --- /dev/null Tue Mar 11 13:02:56 2003
7248 +++ linux/include/openswan/pfkeyv2.h Mon Feb 9 13:51:03 2004
7249 @@ -0,0 +1,505 @@
7250 +/*
7251 + * RCSID $Id: pfkeyv2.h,v 1.31 2005/04/14 01:14:54 mcr Exp $
7252 + */
7253 +
7254 +/*
7255 +RFC 2367 PF_KEY Key Management API July 1998
7256 +
7257 +
7258 +Appendix D: Sample Header File
7259 +
7260 +This file defines structures and symbols for the PF_KEY Version 2
7261 +key management interface. It was written at the U.S. Naval Research
7262 +Laboratory. This file is in the public domain. The authors ask that
7263 +you leave this credit intact on any copies of this file.
7264 +*/
7265 +#ifndef __PFKEY_V2_H
7266 +#define __PFKEY_V2_H 1
7267 +
7268 +#define PF_KEY_V2 2
7269 +#define PFKEYV2_REVISION 199806L
7270 +
7271 +#define SADB_RESERVED 0
7272 +#define SADB_GETSPI 1
7273 +#define SADB_UPDATE 2
7274 +#define SADB_ADD 3
7275 +#define SADB_DELETE 4
7276 +#define SADB_GET 5
7277 +#define SADB_ACQUIRE 6
7278 +#define SADB_REGISTER 7
7279 +#define SADB_EXPIRE 8
7280 +#define SADB_FLUSH 9
7281 +#define SADB_DUMP 10
7282 +#define SADB_X_PROMISC 11
7283 +#define SADB_X_PCHANGE 12
7284 +#define SADB_X_NAT_T_NEW_MAPPING 17
7285 +#define SADB_MAX 17
7286 +
7287 +enum sadb_msg_t {
7288 + K_SADB_RESERVED=SADB_RESERVED,
7289 + K_SADB_GETSPI=SADB_GETSPI,
7290 + K_SADB_UPDATE=SADB_UPDATE,
7291 + K_SADB_ADD=SADB_ADD,
7292 + K_SADB_DELETE=SADB_DELETE,
7293 + K_SADB_GET=SADB_GET,
7294 + K_SADB_ACQUIRE=SADB_ACQUIRE,
7295 + K_SADB_REGISTER=SADB_REGISTER,
7296 + K_SADB_EXPIRE=SADB_EXPIRE,
7297 + K_SADB_FLUSH=SADB_FLUSH,
7298 + K_SADB_DUMP=SADB_DUMP,
7299 + K_SADB_X_PROMISC=SADB_X_PROMISC,
7300 + K_SADB_X_PCHANGE=SADB_X_PCHANGE,
7301 + K_SADB_X_GRPSA=13,
7302 + K_SADB_X_ADDFLOW=14,
7303 + K_SADB_X_DELFLOW=15,
7304 + K_SADB_X_DEBUG=16,
7305 + K_SADB_X_NAT_T_NEW_MAPPING=17,
7306 + K_SADB_X_PLUMBIF=18,
7307 + K_SADB_X_UNPLUMBIF=19,
7308 + K_SADB_MAX=19
7309 +};
7310 +
7311 +#define SADB_X_GRPSA K_SADB_X_GRPSA
7312 +#define SADB_X_ADDFLOW K_SADB_X_ADDFLOW
7313 +#define SADB_X_DELFLOW K_SADB_X_DELFLOW
7314 +#define SADB_X_DEBUG K_SADB_X_DEBUG
7315 +#define SADB_X_PLUMBIF K_SADB_X_PLUMBIF
7316 +#define SADB_X_UNPLUMBIF K_SADB_X_UNPLUMBIF
7317 +
7318 +
7319 +struct sadb_msg {
7320 + uint8_t sadb_msg_version;
7321 + uint8_t sadb_msg_type;
7322 + uint8_t sadb_msg_errno;
7323 + uint8_t sadb_msg_satype;
7324 + uint16_t sadb_msg_len;
7325 + uint16_t sadb_msg_reserved;
7326 + uint32_t sadb_msg_seq;
7327 + uint32_t sadb_msg_pid;
7328 +};
7329 +
7330 +struct sadb_ext {
7331 + uint16_t sadb_ext_len;
7332 + uint16_t sadb_ext_type;
7333 +};
7334 +
7335 +struct sadb_sa {
7336 + uint16_t sadb_sa_len;
7337 + uint16_t sadb_sa_exttype;
7338 + uint32_t sadb_sa_spi;
7339 + uint8_t sadb_sa_replay;
7340 + uint8_t sadb_sa_state;
7341 + uint8_t sadb_sa_auth;
7342 + uint8_t sadb_sa_encrypt;
7343 + uint32_t sadb_sa_flags;
7344 + uint32_t /*IPsecSAref_t*/ sadb_x_sa_ref; /* 32 bits */
7345 + uint8_t sadb_x_reserved[4];
7346 +};
7347 +
7348 +struct sadb_sa_v1 {
7349 + uint16_t sadb_sa_len;
7350 + uint16_t sadb_sa_exttype;
7351 + uint32_t sadb_sa_spi;
7352 + uint8_t sadb_sa_replay;
7353 + uint8_t sadb_sa_state;
7354 + uint8_t sadb_sa_auth;
7355 + uint8_t sadb_sa_encrypt;
7356 + uint32_t sadb_sa_flags;
7357 +};
7358 +
7359 +struct sadb_lifetime {
7360 + uint16_t sadb_lifetime_len;
7361 + uint16_t sadb_lifetime_exttype;
7362 + uint32_t sadb_lifetime_allocations;
7363 + uint64_t sadb_lifetime_bytes;
7364 + uint64_t sadb_lifetime_addtime;
7365 + uint64_t sadb_lifetime_usetime;
7366 + uint32_t sadb_x_lifetime_packets;
7367 + uint32_t sadb_x_lifetime_reserved;
7368 +};
7369 +
7370 +struct sadb_address {
7371 + uint16_t sadb_address_len;
7372 + uint16_t sadb_address_exttype;
7373 + uint8_t sadb_address_proto;
7374 + uint8_t sadb_address_prefixlen;
7375 + uint16_t sadb_address_reserved;
7376 +};
7377 +
7378 +struct sadb_key {
7379 + uint16_t sadb_key_len;
7380 + uint16_t sadb_key_exttype;
7381 + uint16_t sadb_key_bits;
7382 + uint16_t sadb_key_reserved;
7383 +};
7384 +
7385 +struct sadb_ident {
7386 + uint16_t sadb_ident_len;
7387 + uint16_t sadb_ident_exttype;
7388 + uint16_t sadb_ident_type;
7389 + uint16_t sadb_ident_reserved;
7390 + uint64_t sadb_ident_id;
7391 +};
7392 +
7393 +struct sadb_sens {
7394 + uint16_t sadb_sens_len;
7395 + uint16_t sadb_sens_exttype;
7396 + uint32_t sadb_sens_dpd;
7397 + uint8_t sadb_sens_sens_level;
7398 + uint8_t sadb_sens_sens_len;
7399 + uint8_t sadb_sens_integ_level;
7400 + uint8_t sadb_sens_integ_len;
7401 + uint32_t sadb_sens_reserved;
7402 +};
7403 +
7404 +struct sadb_prop {
7405 + uint16_t sadb_prop_len;
7406 + uint16_t sadb_prop_exttype;
7407 + uint8_t sadb_prop_replay;
7408 + uint8_t sadb_prop_reserved[3];
7409 +};
7410 +
7411 +struct sadb_comb {
7412 + uint8_t sadb_comb_auth;
7413 + uint8_t sadb_comb_encrypt;
7414 + uint16_t sadb_comb_flags;
7415 + uint16_t sadb_comb_auth_minbits;
7416 + uint16_t sadb_comb_auth_maxbits;
7417 + uint16_t sadb_comb_encrypt_minbits;
7418 + uint16_t sadb_comb_encrypt_maxbits;
7419 + uint32_t sadb_comb_reserved;
7420 + uint32_t sadb_comb_soft_allocations;
7421 + uint32_t sadb_comb_hard_allocations;
7422 + uint64_t sadb_comb_soft_bytes;
7423 + uint64_t sadb_comb_hard_bytes;
7424 + uint64_t sadb_comb_soft_addtime;
7425 + uint64_t sadb_comb_hard_addtime;
7426 + uint64_t sadb_comb_soft_usetime;
7427 + uint64_t sadb_comb_hard_usetime;
7428 + uint32_t sadb_x_comb_soft_packets;
7429 + uint32_t sadb_x_comb_hard_packets;
7430 +};
7431 +
7432 +struct sadb_supported {
7433 + uint16_t sadb_supported_len;
7434 + uint16_t sadb_supported_exttype;
7435 + uint32_t sadb_supported_reserved;
7436 +};
7437 +
7438 +struct sadb_alg {
7439 + uint8_t sadb_alg_id;
7440 + uint8_t sadb_alg_ivlen;
7441 + uint16_t sadb_alg_minbits;
7442 + uint16_t sadb_alg_maxbits;
7443 + uint16_t sadb_alg_reserved;
7444 +};
7445 +
7446 +struct sadb_spirange {
7447 + uint16_t sadb_spirange_len;
7448 + uint16_t sadb_spirange_exttype;
7449 + uint32_t sadb_spirange_min;
7450 + uint32_t sadb_spirange_max;
7451 + uint32_t sadb_spirange_reserved;
7452 +};
7453 +
7454 +struct sadb_x_kmprivate {
7455 + uint16_t sadb_x_kmprivate_len;
7456 + uint16_t sadb_x_kmprivate_exttype;
7457 + uint32_t sadb_x_kmprivate_reserved;
7458 +};
7459 +
7460 +struct sadb_x_satype {
7461 + uint16_t sadb_x_satype_len;
7462 + uint16_t sadb_x_satype_exttype;
7463 + uint8_t sadb_x_satype_satype;
7464 + uint8_t sadb_x_satype_reserved[3];
7465 +};
7466 +
7467 +struct sadb_x_policy {
7468 + uint16_t sadb_x_policy_len;
7469 + uint16_t sadb_x_policy_exttype;
7470 + uint16_t sadb_x_policy_type;
7471 + uint8_t sadb_x_policy_dir;
7472 + uint8_t sadb_x_policy_reserved;
7473 + uint32_t sadb_x_policy_id;
7474 + uint32_t sadb_x_policy_reserved2;
7475 +};
7476 +
7477 +struct sadb_x_debug {
7478 + uint16_t sadb_x_debug_len;
7479 + uint16_t sadb_x_debug_exttype;
7480 + uint32_t sadb_x_debug_tunnel;
7481 + uint32_t sadb_x_debug_netlink;
7482 + uint32_t sadb_x_debug_xform;
7483 + uint32_t sadb_x_debug_eroute;
7484 + uint32_t sadb_x_debug_spi;
7485 + uint32_t sadb_x_debug_radij;
7486 + uint32_t sadb_x_debug_esp;
7487 + uint32_t sadb_x_debug_ah;
7488 + uint32_t sadb_x_debug_rcv;
7489 + uint32_t sadb_x_debug_pfkey;
7490 + uint32_t sadb_x_debug_ipcomp;
7491 + uint32_t sadb_x_debug_verbose;
7492 + uint8_t sadb_x_debug_reserved[4];
7493 +};
7494 +
7495 +struct sadb_x_nat_t_type {
7496 + uint16_t sadb_x_nat_t_type_len;
7497 + uint16_t sadb_x_nat_t_type_exttype;
7498 + uint8_t sadb_x_nat_t_type_type;
7499 + uint8_t sadb_x_nat_t_type_reserved[3];
7500 +};
7501 +struct sadb_x_nat_t_port {
7502 + uint16_t sadb_x_nat_t_port_len;
7503 + uint16_t sadb_x_nat_t_port_exttype;
7504 + uint16_t sadb_x_nat_t_port_port;
7505 + uint16_t sadb_x_nat_t_port_reserved;
7506 +};
7507 +
7508 +/*
7509 + * a plumbif extension can appear in
7510 + * - a plumbif message to create the interface.
7511 + * - a unplumbif message to delete the interface.
7512 + * - a sadb add/replace to indicate which interface
7513 + * a decrypted packet should emerge on.
7514 + *
7515 + * the create/delete part could/should be replaced with netlink equivalents,
7516 + * or better yet, FORCES versions of same.
7517 + *
7518 + */
7519 +struct sadb_x_plumbif {
7520 + uint16_t sadb_x_outif_len;
7521 + uint16_t sadb_x_outif_exttype;
7522 + uint16_t sadb_x_outif_ifnum;
7523 +} __attribute__((packed));
7524 +
7525 +/*
7526 + * the ifnum describes a device that you wish to create refer to.
7527 + *
7528 + * devices 0-40959 are mastXXX devices.
7529 + * devices 40960-49141 are mastXXX devices with transport set.
7530 + * devices 49152-65536 are deprecated ipsecXXX devices.
7531 + */
7532 +#define IPSECDEV_OFFSET (48*1024)
7533 +#define MASTTRANSPORT_OFFSET (40*1024)
7534 +
7535 +/*
7536 + * A protocol structure for passing through the transport level
7537 + * protocol. It contains more fields than are actually used/needed
7538 + * but it is this way to be compatible with the structure used in
7539 + * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h)
7540 + */
7541 +struct sadb_protocol {
7542 + uint16_t sadb_protocol_len;
7543 + uint16_t sadb_protocol_exttype;
7544 + uint8_t sadb_protocol_proto;
7545 + uint8_t sadb_protocol_direction;
7546 + uint8_t sadb_protocol_flags;
7547 + uint8_t sadb_protocol_reserved2;
7548 +};
7549 +
7550 +#define SADB_EXT_RESERVED 0
7551 +#define SADB_EXT_SA 1
7552 +#define SADB_EXT_LIFETIME_CURRENT 2
7553 +#define SADB_EXT_LIFETIME_HARD 3
7554 +#define SADB_EXT_LIFETIME_SOFT 4
7555 +#define SADB_EXT_ADDRESS_SRC 5
7556 +#define SADB_EXT_ADDRESS_DST 6
7557 +#define SADB_EXT_ADDRESS_PROXY 7
7558 +#define SADB_EXT_KEY_AUTH 8
7559 +#define SADB_EXT_KEY_ENCRYPT 9
7560 +#define SADB_EXT_IDENTITY_SRC 10
7561 +#define SADB_EXT_IDENTITY_DST 11
7562 +#define SADB_EXT_SENSITIVITY 12
7563 +#define SADB_EXT_PROPOSAL 13
7564 +#define SADB_EXT_SUPPORTED_AUTH 14
7565 +#define SADB_EXT_SUPPORTED_ENCRYPT 15
7566 +#define SADB_EXT_SPIRANGE 16
7567 +#define SADB_X_EXT_KMPRIVATE 17
7568 +#define SADB_X_EXT_POLICY 18
7569 +#define SADB_X_EXT_SA2 19
7570 +#define SADB_X_EXT_NAT_T_TYPE 27
7571 +#define SADB_X_EXT_NAT_T_SPORT 28
7572 +#define SADB_X_EXT_NAT_T_DPORT 29
7573 +#define SADB_X_EXT_NAT_T_OA 30
7574 +#define SADB_EXT_MAX 30
7575 +
7576 +/*
7577 + * NOTE that there is a limit of 31 extensions due to current implementation
7578 + * in pfkeyv2_ext_bits.c
7579 + */
7580 +enum sadb_extension_t {
7581 + K_SADB_EXT_RESERVED=SADB_RESERVED,
7582 + K_SADB_EXT_SA= SADB_EXT_SA,
7583 + K_SADB_EXT_LIFETIME_CURRENT=SADB_EXT_LIFETIME_CURRENT,
7584 + K_SADB_EXT_LIFETIME_HARD= SADB_EXT_LIFETIME_HARD,
7585 + K_SADB_EXT_LIFETIME_SOFT= SADB_EXT_LIFETIME_SOFT,
7586 + K_SADB_EXT_ADDRESS_SRC= SADB_EXT_ADDRESS_SRC,
7587 + K_SADB_EXT_ADDRESS_DST= SADB_EXT_ADDRESS_DST,
7588 + K_SADB_EXT_ADDRESS_PROXY= SADB_EXT_ADDRESS_PROXY,
7589 + K_SADB_EXT_KEY_AUTH= SADB_EXT_KEY_AUTH,
7590 + K_SADB_EXT_KEY_ENCRYPT= SADB_EXT_KEY_ENCRYPT,
7591 + K_SADB_EXT_IDENTITY_SRC= SADB_EXT_IDENTITY_SRC,
7592 + K_SADB_EXT_IDENTITY_DST= SADB_EXT_IDENTITY_DST,
7593 + K_SADB_EXT_SENSITIVITY= SADB_EXT_SENSITIVITY,
7594 + K_SADB_EXT_PROPOSAL= SADB_EXT_PROPOSAL,
7595 + K_SADB_EXT_SUPPORTED_AUTH= SADB_EXT_SUPPORTED_AUTH,
7596 + K_SADB_EXT_SUPPORTED_ENCRYPT=SADB_EXT_SUPPORTED_ENCRYPT,
7597 + K_SADB_EXT_SPIRANGE= SADB_EXT_SPIRANGE,
7598 + K_SADB_X_EXT_KMPRIVATE= SADB_X_EXT_KMPRIVATE,
7599 + K_SADB_X_EXT_SATYPE2= 18,
7600 + K_SADB_X_EXT_POLICY= SADB_X_EXT_POLICY,
7601 + K_SADB_X_EXT_SA2= SADB_X_EXT_SA2,
7602 + K_SADB_X_EXT_ADDRESS_DST2= 20,
7603 + K_SADB_X_EXT_ADDRESS_SRC_FLOW=21,
7604 + K_SADB_X_EXT_ADDRESS_DST_FLOW=22,
7605 + K_SADB_X_EXT_ADDRESS_SRC_MASK=23,
7606 + K_SADB_X_EXT_ADDRESS_DST_MASK=24,
7607 + K_SADB_X_EXT_DEBUG= 25,
7608 + K_SADB_X_EXT_PROTOCOL= 26,
7609 + K_SADB_X_EXT_NAT_T_TYPE= 27,
7610 + K_SADB_X_EXT_NAT_T_SPORT= 28,
7611 + K_SADB_X_EXT_NAT_T_DPORT= 29,
7612 + K_SADB_X_EXT_NAT_T_OA= 30,
7613 + K_SADB_X_EXT_PLUMBIF= 31,
7614 + K_SADB_EXT_MAX= 31,
7615 +};
7616 +
7617 +
7618 +#define SADB_X_EXT_SATYPE2 K_SADB_X_EXT_SATYPE2
7619 +#define SADB_X_EXT_ADDRESS_DST2 K_SADB_X_EXT_ADDRESS_DST2
7620 +#define SADB_X_EXT_ADDRESS_SRC_FLOW K_SADB_X_EXT_ADDRESS_SRC_FLOW
7621 +#define SADB_X_EXT_ADDRESS_DST_FLOW K_SADB_X_EXT_ADDRESS_DST_FLOW
7622 +#define SADB_X_EXT_ADDRESS_SRC_MASK K_SADB_X_EXT_ADDRESS_SRC_MASK
7623 +#define SADB_X_EXT_ADDRESS_DST_MASK K_SADB_X_EXT_ADDRESS_DST_MASK
7624 +#define SADB_X_EXT_DEBUG K_SADB_X_EXT_DEBUG
7625 +#define SADB_X_EXT_PROTOCOL K_SADB_X_EXT_PROTOCOL
7626 +#define SADB_X_EXT_PLUMBIF K_SADB_X_EXT_PLUMBIF
7627 +
7628 +
7629 +
7630 +/* K_SADB_X_DELFLOW required over and above K_SADB_X_SAFLAGS_CLEARFLOW */
7631 +#define K_SADB_X_EXT_ADDRESS_DELFLOW \
7632 + ( (1<<K_SADB_X_EXT_ADDRESS_SRC_FLOW) \
7633 + | (1<<K_SADB_X_EXT_ADDRESS_DST_FLOW) \
7634 + | (1<<K_SADB_X_EXT_ADDRESS_SRC_MASK) \
7635 + | (1<<K_SADB_X_EXT_ADDRESS_DST_MASK))
7636 +
7637 +#define SADB_SATYPE_UNSPEC 0
7638 +#define SADB_SATYPE_AH 2
7639 +#define SADB_SATYPE_ESP 3
7640 +#define SADB_SATYPE_RSVP 5
7641 +#define SADB_SATYPE_OSPFV2 6
7642 +#define SADB_SATYPE_RIPV2 7
7643 +#define SADB_SATYPE_MIP 8
7644 +#define SADB_X_SATYPE_IPIP 9
7645 +#ifdef KERNEL26_HAS_KAME_DUPLICATES
7646 +#define SADB_X_SATYPE_IPCOMP 9 /* ICK! */
7647 +#endif
7648 +#define SADB_X_SATYPE_COMP 10
7649 +#define SADB_X_SATYPE_INT 11
7650 +#define SADB_SATYPE_MAX 11
7651 +
7652 +enum sadb_satype {
7653 + K_SADB_SATYPE_UNSPEC=SADB_SATYPE_UNSPEC,
7654 + K_SADB_SATYPE_AH=SADB_SATYPE_AH,
7655 + K_SADB_SATYPE_ESP=SADB_SATYPE_ESP,
7656 + K_SADB_SATYPE_RSVP=SADB_SATYPE_RSVP,
7657 + K_SADB_SATYPE_OSPFV2=SADB_SATYPE_OSPFV2,
7658 + K_SADB_SATYPE_RIPV2=SADB_SATYPE_RIPV2,
7659 + K_SADB_SATYPE_MIP=SADB_SATYPE_MIP,
7660 + K_SADB_X_SATYPE_IPIP=9,
7661 + K_SADB_X_SATYPE_COMP=10,
7662 + K_SADB_X_SATYPE_INT=11
7663 +};
7664 +#define K_SADB_SATYPE_MAX 11
7665 +
7666 +enum sadb_sastate {
7667 + K_SADB_SASTATE_LARVAL=0,
7668 + K_SADB_SASTATE_MATURE=1,
7669 + K_SADB_SASTATE_DYING=2,
7670 + K_SADB_SASTATE_DEAD=3
7671 +};
7672 +#define K_SADB_SASTATE_MAX 3
7673 +
7674 +#define SADB_SAFLAGS_PFS 1
7675 +#define SADB_X_SAFLAGS_REPLACEFLOW 2
7676 +#define SADB_X_SAFLAGS_CLEARFLOW 4
7677 +#define SADB_X_SAFLAGS_INFLOW 8
7678 +
7679 +/* not obvious, but these are the same values as used in isakmp,
7680 + * and in freeswan/ipsec_policy.h. If you need to add any, they
7681 + * should be added as according to
7682 + * http://www.iana.org/assignments/isakmp-registry
7683 + *
7684 + * and if not, then please try to use a private-use value, and
7685 + * consider asking IANA to assign a value.
7686 + */
7687 +#define SADB_AALG_NONE 0
7688 +#define SADB_AALG_MD5HMAC 2
7689 +#define SADB_AALG_SHA1HMAC 3
7690 +#define SADB_X_AALG_SHA2_256HMAC 5
7691 +#define SADB_X_AALG_SHA2_384HMAC 6
7692 +#define SADB_X_AALG_SHA2_512HMAC 7
7693 +#define SADB_X_AALG_RIPEMD160HMAC 8
7694 +#define SADB_X_AALG_NULL 251 /* kame */
7695 +#define SADB_AALG_MAX 251
7696 +enum sadb_aalg {
7697 + K_SADB_AALG_NONE= SADB_AALG_NONE,
7698 + K_SADB_AALG_MD5HMAC= SADB_AALG_MD5HMAC,
7699 + K_SADB_AALG_SHA1HMAC= SADB_AALG_SHA1HMAC,
7700 + K_SADB_X_AALG_SHA2_256HMAC=SADB_X_AALG_SHA2_256HMAC,
7701 + K_SADB_X_AALG_SHA2_384HMAC=SADB_X_AALG_SHA2_384HMAC,
7702 + K_SADB_X_AALG_SHA2_512HMAC=SADB_X_AALG_SHA2_512HMAC,
7703 + K_SADB_X_AALG_RIPEMD160HMAC=SADB_X_AALG_RIPEMD160HMAC,
7704 +};
7705 +#define K_SADB_AALG_MAX 251
7706 +
7707 +#define SADB_EALG_NONE 0
7708 +#define SADB_EALG_DESCBC 2
7709 +#define SADB_EALG_3DESCBC 3
7710 +#define SADB_X_EALG_CASTCBC 6
7711 +#define SADB_X_EALG_BLOWFISHCBC 7
7712 +#define SADB_EALG_NULL 11
7713 +#define SADB_X_EALG_AESCBC 12
7714 +#define SADB_EALG_MAX 255
7715 +
7716 +enum sadb_ealg {
7717 + K_SADB_EALG_NONE=SADB_EALG_NONE,
7718 + K_SADB_EALG_DESCBC=SADB_EALG_DESCBC,
7719 + K_SADB_EALG_3DESCBC=SADB_EALG_3DESCBC,
7720 + K_SADB_X_EALG_CASTCBC=SADB_X_EALG_CASTCBC,
7721 + K_SADB_X_EALG_BLOWFISHCBC=SADB_X_EALG_BLOWFISHCBC,
7722 + K_SADB_EALG_NULL=SADB_EALG_NULL,
7723 + K_SADB_X_EALG_AESCBC=SADB_X_EALG_AESCBC
7724 +};
7725 +
7726 +#define K_SADB_EALG_MAX 255
7727 +
7728 +#define SADB_X_CALG_NONE 0
7729 +#define SADB_X_CALG_OUI 1
7730 +#define SADB_X_CALG_DEFLATE 2
7731 +#define SADB_X_CALG_LZS 3
7732 +#define SADB_X_CALG_LZJH 4
7733 +#define SADB_X_CALG_MAX 4
7734 +
7735 +enum sadb_talg {
7736 + K_SADB_X_TALG_NONE=0,
7737 + K_SADB_X_TALG_IPv4_in_IPv4=1,
7738 + K_SADB_X_TALG_IPv6_in_IPv4=2,
7739 + K_SADB_X_TALG_IPv4_in_IPv6=3,
7740 + K_SADB_X_TALG_IPv6_in_IPv6=4,
7741 +};
7742 +#define SADB_X_TALG_MAX 4
7743 +
7744 +
7745 +#define SADB_IDENTTYPE_RESERVED 0
7746 +#define SADB_IDENTTYPE_PREFIX 1
7747 +#define SADB_IDENTTYPE_FQDN 2
7748 +#define SADB_IDENTTYPE_USERFQDN 3
7749 +#define SADB_X_IDENTTYPE_CONNECTION 4
7750 +#define SADB_IDENTTYPE_MAX 4
7751 +
7752 +#define SADB_KEY_FLAGS_MAX 0
7753 +#endif /* __PFKEY_V2_H */
7754 +
7755 --- /dev/null Tue Mar 11 13:02:56 2003
7756 +++ linux/include/openswan/radij.h Mon Feb 9 13:51:03 2004
7757 @@ -0,0 +1,280 @@
7758 +/*
7759 + * RCSID $Id: radij.h,v 1.13 2004/04/05 19:55:08 mcr Exp $
7760 + */
7761 +
7762 +/*
7763 + * This file is defived from ${SRC}/sys/net/radix.h of BSD 4.4lite
7764 + *
7765 + * Variable and procedure names have been modified so that they don't
7766 + * conflict with the original BSD code, as a small number of modifications
7767 + * have been introduced and we may want to reuse this code in BSD.
7768 + *
7769 + * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
7770 + * chi or a German ch sound (as `doch', not as in `milch'), or even a
7771 + * spanish j as in Juan. It is not as far back in the throat like
7772 + * the corresponding Hebrew sound, nor is it a soft breath like the English h.
7773 + * It has nothing to do with the Dutch ij sound.
7774 + *
7775 + * Here is the appropriate copyright notice:
7776 + */
7777 +
7778 +/*
7779 + * Copyright (c) 1988, 1989, 1993
7780 + * The Regents of the University of California. All rights reserved.
7781 + *
7782 + * Redistribution and use in source and binary forms, with or without
7783 + * modification, are permitted provided that the following conditions
7784 + * are met:
7785 + * 1. Redistributions of source code must retain the above copyright
7786 + * notice, this list of conditions and the following disclaimer.
7787 + * 2. Redistributions in binary form must reproduce the above copyright
7788 + * notice, this list of conditions and the following disclaimer in the
7789 + * documentation and/or other materials provided with the distribution.
7790 + * 3. All advertising materials mentioning features or use of this software
7791 + * must display the following acknowledgement:
7792 + * This product includes software developed by the University of
7793 + * California, Berkeley and its contributors.
7794 + * 4. Neither the name of the University nor the names of its contributors
7795 + * may be used to endorse or promote products derived from this software
7796 + * without specific prior written permission.
7797 + *
7798 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
7799 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7800 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7801 + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
7802 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
7803 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
7804 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
7805 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
7806 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
7807 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
7808 + * SUCH DAMAGE.
7809 + *
7810 + * @(#)radix.h 8.1 (Berkeley) 6/10/93
7811 + */
7812 +
7813 +#ifndef _RADIJ_H_
7814 +#define _RADIJ_H_
7815 +
7816 +/*
7817 +#define RJ_DEBUG
7818 +*/
7819 +
7820 +#ifdef __KERNEL__
7821 +
7822 +#ifndef __P
7823 +#ifdef __STDC__
7824 +#define __P(x) x
7825 +#else
7826 +#define __P(x) ()
7827 +#endif
7828 +#endif
7829 +
7830 +/*
7831 + * Radix search tree node layout.
7832 + */
7833 +
7834 +struct radij_node
7835 +{
7836 + struct radij_mask *rj_mklist; /* list of masks contained in subtree */
7837 + struct radij_node *rj_p; /* parent */
7838 + short rj_b; /* bit offset; -1-index(netmask) */
7839 + char rj_bmask; /* node: mask for bit test*/
7840 + u_char rj_flags; /* enumerated next */
7841 +#define RJF_NORMAL 1 /* leaf contains normal route */
7842 +#define RJF_ROOT 2 /* leaf is root leaf for tree */
7843 +#define RJF_ACTIVE 4 /* This node is alive (for rtfree) */
7844 + union {
7845 + struct { /* leaf only data: */
7846 + caddr_t rj_Key; /* object of search */
7847 + caddr_t rj_Mask; /* netmask, if present */
7848 + struct radij_node *rj_Dupedkey;
7849 + } rj_leaf;
7850 + struct { /* node only data: */
7851 + int rj_Off; /* where to start compare */
7852 + struct radij_node *rj_L;/* progeny */
7853 + struct radij_node *rj_R;/* progeny */
7854 + }rj_node;
7855 + } rj_u;
7856 +#ifdef RJ_DEBUG
7857 + int rj_info;
7858 + struct radij_node *rj_twin;
7859 + struct radij_node *rj_ybro;
7860 +#endif
7861 +};
7862 +
7863 +#define rj_dupedkey rj_u.rj_leaf.rj_Dupedkey
7864 +#define rj_key rj_u.rj_leaf.rj_Key
7865 +#define rj_mask rj_u.rj_leaf.rj_Mask
7866 +#define rj_off rj_u.rj_node.rj_Off
7867 +#define rj_l rj_u.rj_node.rj_L
7868 +#define rj_r rj_u.rj_node.rj_R
7869 +
7870 +/*
7871 + * Annotations to tree concerning potential routes applying to subtrees.
7872 + */
7873 +
7874 +extern struct radij_mask {
7875 + short rm_b; /* bit offset; -1-index(netmask) */
7876 + char rm_unused; /* cf. rj_bmask */
7877 + u_char rm_flags; /* cf. rj_flags */
7878 + struct radij_mask *rm_mklist; /* more masks to try */
7879 + caddr_t rm_mask; /* the mask */
7880 + int rm_refs; /* # of references to this struct */
7881 +} *rj_mkfreelist;
7882 +
7883 +#define MKGet(m) {\
7884 + if (rj_mkfreelist) {\
7885 + m = rj_mkfreelist; \
7886 + rj_mkfreelist = (m)->rm_mklist; \
7887 + } else \
7888 + R_Malloc(m, struct radij_mask *, sizeof (*(m))); }\
7889 +
7890 +#define MKFree(m) { (m)->rm_mklist = rj_mkfreelist; rj_mkfreelist = (m);}
7891 +
7892 +struct radij_node_head {
7893 + struct radij_node *rnh_treetop;
7894 + int rnh_addrsize; /* permit, but not require fixed keys */
7895 + int rnh_pktsize; /* permit, but not require fixed keys */
7896 +#if 0
7897 + struct radij_node *(*rnh_addaddr) /* add based on sockaddr */
7898 + __P((void *v, void *mask,
7899 + struct radij_node_head *head, struct radij_node nodes[]));
7900 +#endif
7901 + int (*rnh_addaddr) /* add based on sockaddr */
7902 + __P((void *v, void *mask,
7903 + struct radij_node_head *head, struct radij_node nodes[]));
7904 + struct radij_node *(*rnh_addpkt) /* add based on packet hdr */
7905 + __P((void *v, void *mask,
7906 + struct radij_node_head *head, struct radij_node nodes[]));
7907 +#if 0
7908 + struct radij_node *(*rnh_deladdr) /* remove based on sockaddr */
7909 + __P((void *v, void *mask, struct radij_node_head *head));
7910 +#endif
7911 + int (*rnh_deladdr) /* remove based on sockaddr */
7912 + __P((void *v, void *mask, struct radij_node_head *head, struct radij_node **node));
7913 + struct radij_node *(*rnh_delpkt) /* remove based on packet hdr */
7914 + __P((void *v, void *mask, struct radij_node_head *head));
7915 + struct radij_node *(*rnh_matchaddr) /* locate based on sockaddr */
7916 + __P((void *v, struct radij_node_head *head));
7917 + struct radij_node *(*rnh_matchpkt) /* locate based on packet hdr */
7918 + __P((void *v, struct radij_node_head *head));
7919 + int (*rnh_walktree) /* traverse tree */
7920 + __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
7921 + struct radij_node rnh_nodes[3]; /* empty tree for common case */
7922 +};
7923 +
7924 +
7925 +#define Bcmp(a, b, n) memcmp(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
7926 +#define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
7927 +#define Bzero(p, n) memset((caddr_t)(p), 0, (unsigned)(n))
7928 +#define R_Malloc(p, t, n) ((p = (t) kmalloc((size_t)(n), GFP_ATOMIC)), Bzero((p),(n)))
7929 +#define Free(p) kfree((caddr_t)p);
7930 +
7931 +void rj_init __P((void));
7932 +int rj_inithead __P((void **, int));
7933 +int rj_refines __P((void *, void *));
7934 +int rj_walktree __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
7935 +struct radij_node
7936 + *rj_addmask __P((void *, int, int)) /* , rgb */ ;
7937 +int /* * */ rj_addroute __P((void *, void *, struct radij_node_head *,
7938 + struct radij_node [2])) /* , rgb */ ;
7939 +int /* * */ rj_delete __P((void *, void *, struct radij_node_head *, struct radij_node **)) /* , rgb */ ;
7940 +struct radij_node /* rgb */
7941 + *rj_insert __P((void *, struct radij_node_head *, int *,
7942 + struct radij_node [2])),
7943 + *rj_match __P((void *, struct radij_node_head *)),
7944 + *rj_newpair __P((void *, int, struct radij_node[2])),
7945 + *rj_search __P((void *, struct radij_node *)),
7946 + *rj_search_m __P((void *, struct radij_node *, void *));
7947 +
7948 +void rj_deltree(struct radij_node_head *);
7949 +void rj_delnodes(struct radij_node *);
7950 +void rj_free_mkfreelist(void);
7951 +int radijcleartree(void);
7952 +int radijcleanup(void);
7953 +
7954 +extern struct radij_node_head *mask_rjhead;
7955 +extern int maj_keylen;
7956 +#endif /* __KERNEL__ */
7957 +
7958 +#endif /* _RADIJ_H_ */
7959 +
7960 +
7961 +/*
7962 + * $Log: radij.h,v $
7963 + * Revision 1.13 2004/04/05 19:55:08 mcr
7964 + * Moved from linux/include/freeswan/radij.h,v
7965 + *
7966 + * Revision 1.12 2002/04/24 07:36:48 mcr
7967 + * Moved from ./klips/net/ipsec/radij.h,v
7968 + *
7969 + * Revision 1.11 2001/09/20 15:33:00 rgb
7970 + * Min/max cleanup.
7971 + *
7972 + * Revision 1.10 1999/11/18 04:09:20 rgb
7973 + * Replaced all kernel version macros to shorter, readable form.
7974 + *
7975 + * Revision 1.9 1999/05/05 22:02:33 rgb
7976 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
7977 + *
7978 + * Revision 1.8 1999/04/29 15:24:58 rgb
7979 + * Add check for existence of macros min/max.
7980 + *
7981 + * Revision 1.7 1999/04/11 00:29:02 henry
7982 + * GPL boilerplate
7983 + *
7984 + * Revision 1.6 1999/04/06 04:54:29 rgb
7985 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
7986 + * patch shell fixes.
7987 + *
7988 + * Revision 1.5 1999/01/22 06:30:32 rgb
7989 + * 64-bit clean-up.
7990 + *
7991 + * Revision 1.4 1998/11/30 13:22:55 rgb
7992 + * Rationalised all the klips kernel file headers. They are much shorter
7993 + * now and won't conflict under RH5.2.
7994 + *
7995 + * Revision 1.3 1998/10/25 02:43:27 rgb
7996 + * Change return type on rj_addroute and rj_delete and add and argument
7997 + * to the latter to be able to transmit more infomation about errors.
7998 + *
7999 + * Revision 1.2 1998/07/14 18:09:51 rgb
8000 + * Add a routine to clear eroute table.
8001 + * Added #ifdef __KERNEL__ directives to restrict scope of header.
8002 + *
8003 + * Revision 1.1 1998/06/18 21:30:22 henry
8004 + * move sources from klips/src to klips/net/ipsec to keep stupid kernel
8005 + * build scripts happier about symlinks
8006 + *
8007 + * Revision 1.4 1998/05/25 20:34:16 rgb
8008 + * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
8009 + *
8010 + * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
8011 + * add ipsec_rj_walker_delete.
8012 + *
8013 + * Recover memory for eroute table on unload of module.
8014 + *
8015 + * Revision 1.3 1998/04/22 16:51:37 rgb
8016 + * Tidy up radij debug code from recent rash of modifications to debug code.
8017 + *
8018 + * Revision 1.2 1998/04/14 17:30:38 rgb
8019 + * Fix up compiling errors for radij tree memory reclamation.
8020 + *
8021 + * Revision 1.1 1998/04/09 03:06:16 henry
8022 + * sources moved up from linux/net/ipsec
8023 + *
8024 + * Revision 1.1.1.1 1998/04/08 05:35:04 henry
8025 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
8026 + *
8027 + * Revision 0.4 1997/01/15 01:28:15 ji
8028 + * No changes.
8029 + *
8030 + * Revision 0.3 1996/11/20 14:44:45 ji
8031 + * Release update only.
8032 + *
8033 + * Revision 0.2 1996/11/02 00:18:33 ji
8034 + * First limited release.
8035 + *
8036 + *
8037 + */
8038 --- /dev/null Tue Mar 11 13:02:56 2003
8039 +++ linux/include/zlib/zconf.h Mon Feb 9 13:51:03 2004
8040 @@ -0,0 +1,309 @@
8041 +/* zconf.h -- configuration of the zlib compression library
8042 + * Copyright (C) 1995-2002 Jean-loup Gailly.
8043 + * For conditions of distribution and use, see copyright notice in zlib.h
8044 + */
8045 +
8046 +/* @(#) $Id: zconf.h,v 1.4 2004/07/10 07:48:40 mcr Exp $ */
8047 +
8048 +#ifndef _ZCONF_H
8049 +#define _ZCONF_H
8050 +
8051 +/*
8052 + * If you *really* need a unique prefix for all types and library functions,
8053 + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
8054 + */
8055 +#ifdef IPCOMP_PREFIX
8056 +# define deflateInit_ ipcomp_deflateInit_
8057 +# define deflate ipcomp_deflate
8058 +# define deflateEnd ipcomp_deflateEnd
8059 +# define inflateInit_ ipcomp_inflateInit_
8060 +# define inflate ipcomp_inflate
8061 +# define inflateEnd ipcomp_inflateEnd
8062 +# define deflateInit2_ ipcomp_deflateInit2_
8063 +# define deflateSetDictionary ipcomp_deflateSetDictionary
8064 +# define deflateCopy ipcomp_deflateCopy
8065 +# define deflateReset ipcomp_deflateReset
8066 +# define deflateParams ipcomp_deflateParams
8067 +# define inflateInit2_ ipcomp_inflateInit2_
8068 +# define inflateSetDictionary ipcomp_inflateSetDictionary
8069 +# define inflateSync ipcomp_inflateSync
8070 +# define inflateSyncPoint ipcomp_inflateSyncPoint
8071 +# define inflateReset ipcomp_inflateReset
8072 +# define compress ipcomp_compress
8073 +# define compress2 ipcomp_compress2
8074 +# define uncompress ipcomp_uncompress
8075 +# define adler32 ipcomp_adler32
8076 +# define crc32 ipcomp_crc32
8077 +# define get_crc_table ipcomp_get_crc_table
8078 +/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */
8079 +# define inflate_blocks ipcomp_deflate_blocks
8080 +# define inflate_blocks_free ipcomp_deflate_blocks_free
8081 +# define inflate_blocks_new ipcomp_inflate_blocks_new
8082 +# define inflate_blocks_reset ipcomp_inflate_blocks_reset
8083 +# define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point
8084 +# define inflate_set_dictionary ipcomp_inflate_set_dictionary
8085 +# define inflate_codes ipcomp_inflate_codes
8086 +# define inflate_codes_free ipcomp_inflate_codes_free
8087 +# define inflate_codes_new ipcomp_inflate_codes_new
8088 +# define inflate_fast ipcomp_inflate_fast
8089 +# define inflate_trees_bits ipcomp_inflate_trees_bits
8090 +# define inflate_trees_dynamic ipcomp_inflate_trees_dynamic
8091 +# define inflate_trees_fixed ipcomp_inflate_trees_fixed
8092 +# define inflate_flush ipcomp_inflate_flush
8093 +# define inflate_mask ipcomp_inflate_mask
8094 +# define _dist_code _ipcomp_dist_code
8095 +# define _length_code _ipcomp_length_code
8096 +# define _tr_align _ipcomp_tr_align
8097 +# define _tr_flush_block _ipcomp_tr_flush_block
8098 +# define _tr_init _ipcomp_tr_init
8099 +# define _tr_stored_block _ipcomp_tr_stored_block
8100 +# define _tr_tally _ipcomp_tr_tally
8101 +# define zError ipcomp_zError
8102 +# define z_errmsg ipcomp_z_errmsg
8103 +# define zlibVersion ipcomp_zlibVersion
8104 +# define match_init ipcomp_match_init
8105 +# define longest_match ipcomp_longest_match
8106 +#endif
8107 +
8108 +#ifdef Z_PREFIX
8109 +# define Byte z_Byte
8110 +# define uInt z_uInt
8111 +# define uLong z_uLong
8112 +# define Bytef z_Bytef
8113 +# define charf z_charf
8114 +# define intf z_intf
8115 +# define uIntf z_uIntf
8116 +# define uLongf z_uLongf
8117 +# define voidpf z_voidpf
8118 +# define voidp z_voidp
8119 +#endif
8120 +
8121 +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
8122 +# define WIN32
8123 +#endif
8124 +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
8125 +# ifndef __32BIT__
8126 +# define __32BIT__
8127 +# endif
8128 +#endif
8129 +#if defined(__MSDOS__) && !defined(MSDOS)
8130 +# define MSDOS
8131 +#endif
8132 +
8133 +/*
8134 + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
8135 + * than 64k bytes at a time (needed on systems with 16-bit int).
8136 + */
8137 +#if defined(MSDOS) && !defined(__32BIT__)
8138 +# define MAXSEG_64K
8139 +#endif
8140 +#ifdef MSDOS
8141 +# define UNALIGNED_OK
8142 +#endif
8143 +
8144 +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
8145 +# define STDC
8146 +#endif
8147 +#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
8148 +# ifndef STDC
8149 +# define STDC
8150 +# endif
8151 +#endif
8152 +
8153 +#ifndef STDC
8154 +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
8155 +# define const
8156 +# endif
8157 +#endif
8158 +
8159 +/* Some Mac compilers merge all .h files incorrectly: */
8160 +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
8161 +# define NO_DUMMY_DECL
8162 +#endif
8163 +
8164 +/* Old Borland C incorrectly complains about missing returns: */
8165 +#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
8166 +# define NEED_DUMMY_RETURN
8167 +#endif
8168 +
8169 +
8170 +/* Maximum value for memLevel in deflateInit2 */
8171 +#ifndef MAX_MEM_LEVEL
8172 +# ifdef MAXSEG_64K
8173 +# define MAX_MEM_LEVEL 8
8174 +# else
8175 +# define MAX_MEM_LEVEL 9
8176 +# endif
8177 +#endif
8178 +
8179 +/* Maximum value for windowBits in deflateInit2 and inflateInit2.
8180 + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
8181 + * created by gzip. (Files created by minigzip can still be extracted by
8182 + * gzip.)
8183 + */
8184 +#ifndef MAX_WBITS
8185 +# define MAX_WBITS 15 /* 32K LZ77 window */
8186 +#endif
8187 +
8188 +/* The memory requirements for deflate are (in bytes):
8189 + (1 << (windowBits+2)) + (1 << (memLevel+9))
8190 + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
8191 + plus a few kilobytes for small objects. For example, if you want to reduce
8192 + the default memory requirements from 256K to 128K, compile with
8193 + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
8194 + Of course this will generally degrade compression (there's no free lunch).
8195 +
8196 + The memory requirements for inflate are (in bytes) 1 << windowBits
8197 + that is, 32K for windowBits=15 (default value) plus a few kilobytes
8198 + for small objects.
8199 +*/
8200 +
8201 + /* Type declarations */
8202 +
8203 +#ifndef OF /* function prototypes */
8204 +# ifdef STDC
8205 +# define OF(args) args
8206 +# else
8207 +# define OF(args) ()
8208 +# endif
8209 +#endif
8210 +
8211 +/* The following definitions for FAR are needed only for MSDOS mixed
8212 + * model programming (small or medium model with some far allocations).
8213 + * This was tested only with MSC; for other MSDOS compilers you may have
8214 + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
8215 + * just define FAR to be empty.
8216 + */
8217 +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
8218 + /* MSC small or medium model */
8219 +# define SMALL_MEDIUM
8220 +# ifdef _MSC_VER
8221 +# define FAR _far
8222 +# else
8223 +# define FAR far
8224 +# endif
8225 +#endif
8226 +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
8227 +# ifndef __32BIT__
8228 +# define SMALL_MEDIUM
8229 +# define FAR _far
8230 +# endif
8231 +#endif
8232 +
8233 +/* Compile with -DZLIB_DLL for Windows DLL support */
8234 +#if defined(ZLIB_DLL)
8235 +# if defined(_WINDOWS) || defined(WINDOWS)
8236 +# ifdef FAR
8237 +# undef FAR
8238 +# endif
8239 +# include <windows.h>
8240 +# define ZEXPORT WINAPI
8241 +# ifdef WIN32
8242 +# define ZEXPORTVA WINAPIV
8243 +# else
8244 +# define ZEXPORTVA FAR _cdecl _export
8245 +# endif
8246 +# endif
8247 +# if defined (__BORLANDC__)
8248 +# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
8249 +# include <windows.h>
8250 +# define ZEXPORT __declspec(dllexport) WINAPI
8251 +# define ZEXPORTRVA __declspec(dllexport) WINAPIV
8252 +# else
8253 +# if defined (_Windows) && defined (__DLL__)
8254 +# define ZEXPORT _export
8255 +# define ZEXPORTVA _export
8256 +# endif
8257 +# endif
8258 +# endif
8259 +#endif
8260 +
8261 +#if defined (__BEOS__)
8262 +# if defined (ZLIB_DLL)
8263 +# define ZEXTERN extern __declspec(dllexport)
8264 +# else
8265 +# define ZEXTERN extern __declspec(dllimport)
8266 +# endif
8267 +#endif
8268 +
8269 +#ifndef ZEXPORT
8270 +# define ZEXPORT
8271 +#endif
8272 +#ifndef ZEXPORTVA
8273 +# define ZEXPORTVA
8274 +#endif
8275 +#ifndef ZEXTERN
8276 +# define ZEXTERN extern
8277 +#endif
8278 +
8279 +#ifndef FAR
8280 +# define FAR
8281 +#endif
8282 +
8283 +#if !defined(MACOS) && !defined(TARGET_OS_MAC)
8284 +typedef unsigned char Byte; /* 8 bits */
8285 +#endif
8286 +typedef unsigned int uInt; /* 16 bits or more */
8287 +typedef unsigned long uLong; /* 32 bits or more */
8288 +
8289 +#ifdef SMALL_MEDIUM
8290 + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
8291 +# define Bytef Byte FAR
8292 +#else
8293 + typedef Byte FAR Bytef;
8294 +#endif
8295 +typedef char FAR charf;
8296 +typedef int FAR intf;
8297 +typedef uInt FAR uIntf;
8298 +typedef uLong FAR uLongf;
8299 +
8300 +#ifdef STDC
8301 + typedef void FAR *voidpf;
8302 + typedef void *voidp;
8303 +#else
8304 + typedef Byte FAR *voidpf;
8305 + typedef Byte *voidp;
8306 +#endif
8307 +
8308 +#ifdef HAVE_UNISTD_H
8309 +# include <sys/types.h> /* for off_t */
8310 +# include <unistd.h> /* for SEEK_* and off_t */
8311 +# define z_off_t off_t
8312 +#endif
8313 +#ifndef SEEK_SET
8314 +# define SEEK_SET 0 /* Seek from beginning of file. */
8315 +# define SEEK_CUR 1 /* Seek from current position. */
8316 +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
8317 +#endif
8318 +#ifndef z_off_t
8319 +# define z_off_t long
8320 +#endif
8321 +
8322 +/* MVS linker does not support external names larger than 8 bytes */
8323 +#if defined(__MVS__)
8324 +# pragma map(deflateInit_,"DEIN")
8325 +# pragma map(deflateInit2_,"DEIN2")
8326 +# pragma map(deflateEnd,"DEEND")
8327 +# pragma map(inflateInit_,"ININ")
8328 +# pragma map(inflateInit2_,"ININ2")
8329 +# pragma map(inflateEnd,"INEND")
8330 +# pragma map(inflateSync,"INSY")
8331 +# pragma map(inflateSetDictionary,"INSEDI")
8332 +# pragma map(inflate_blocks,"INBL")
8333 +# pragma map(inflate_blocks_new,"INBLNE")
8334 +# pragma map(inflate_blocks_free,"INBLFR")
8335 +# pragma map(inflate_blocks_reset,"INBLRE")
8336 +# pragma map(inflate_codes_free,"INCOFR")
8337 +# pragma map(inflate_codes,"INCO")
8338 +# pragma map(inflate_fast,"INFA")
8339 +# pragma map(inflate_flush,"INFLU")
8340 +# pragma map(inflate_mask,"INMA")
8341 +# pragma map(inflate_set_dictionary,"INSEDI2")
8342 +# pragma map(ipcomp_inflate_copyright,"INCOPY")
8343 +# pragma map(inflate_trees_bits,"INTRBI")
8344 +# pragma map(inflate_trees_dynamic,"INTRDY")
8345 +# pragma map(inflate_trees_fixed,"INTRFI")
8346 +# pragma map(inflate_trees_free,"INTRFR")
8347 +#endif
8348 +
8349 +#endif /* _ZCONF_H */
8350 --- /dev/null Tue Mar 11 13:02:56 2003
8351 +++ linux/include/zlib/zlib.h Mon Feb 9 13:51:03 2004
8352 @@ -0,0 +1,893 @@
8353 +/* zlib.h -- interface of the 'zlib' general purpose compression library
8354 + version 1.1.4, March 11th, 2002
8355 +
8356 + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
8357 +
8358 + This software is provided 'as-is', without any express or implied
8359 + warranty. In no event will the authors be held liable for any damages
8360 + arising from the use of this software.
8361 +
8362 + Permission is granted to anyone to use this software for any purpose,
8363 + including commercial applications, and to alter it and redistribute it
8364 + freely, subject to the following restrictions:
8365 +
8366 + 1. The origin of this software must not be misrepresented; you must not
8367 + claim that you wrote the original software. If you use this software
8368 + in a product, an acknowledgment in the product documentation would be
8369 + appreciated but is not required.
8370 + 2. Altered source versions must be plainly marked as such, and must not be
8371 + misrepresented as being the original software.
8372 + 3. This notice may not be removed or altered from any source distribution.
8373 +
8374 + Jean-loup Gailly Mark Adler
8375 + jloup@gzip.org madler@alumni.caltech.edu
8376 +
8377 +
8378 + The data format used by the zlib library is described by RFCs (Request for
8379 + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
8380 + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
8381 +*/
8382 +
8383 +#ifndef _ZLIB_H
8384 +#define _ZLIB_H
8385 +
8386 +#include "zconf.h"
8387 +
8388 +#ifdef __cplusplus
8389 +extern "C" {
8390 +#endif
8391 +
8392 +#define ZLIB_VERSION "1.1.4"
8393 +
8394 +/*
8395 + The 'zlib' compression library provides in-memory compression and
8396 + decompression functions, including integrity checks of the uncompressed
8397 + data. This version of the library supports only one compression method
8398 + (deflation) but other algorithms will be added later and will have the same
8399 + stream interface.
8400 +
8401 + Compression can be done in a single step if the buffers are large
8402 + enough (for example if an input file is mmap'ed), or can be done by
8403 + repeated calls of the compression function. In the latter case, the
8404 + application must provide more input and/or consume the output
8405 + (providing more output space) before each call.
8406 +
8407 + The library also supports reading and writing files in gzip (.gz) format
8408 + with an interface similar to that of stdio.
8409 +
8410 + The library does not install any signal handler. The decoder checks
8411 + the consistency of the compressed data, so the library should never
8412 + crash even in case of corrupted input.
8413 +*/
8414 +
8415 +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
8416 +typedef void (*free_func) OF((voidpf opaque, voidpf address));
8417 +
8418 +struct internal_state;
8419 +
8420 +typedef struct z_stream_s {
8421 + Bytef *next_in; /* next input byte */
8422 + uInt avail_in; /* number of bytes available at next_in */
8423 + uLong total_in; /* total nb of input bytes read so far */
8424 +
8425 + Bytef *next_out; /* next output byte should be put there */
8426 + uInt avail_out; /* remaining free space at next_out */
8427 + uLong total_out; /* total nb of bytes output so far */
8428 +
8429 + const char *msg; /* last error message, NULL if no error */
8430 + struct internal_state FAR *state; /* not visible by applications */
8431 +
8432 + alloc_func zalloc; /* used to allocate the internal state */
8433 + free_func zfree; /* used to free the internal state */
8434 + voidpf opaque; /* private data object passed to zalloc and zfree */
8435 +
8436 + int data_type; /* best guess about the data type: ascii or binary */
8437 + uLong adler; /* adler32 value of the uncompressed data */
8438 + uLong reserved; /* reserved for future use */
8439 +} z_stream;
8440 +
8441 +typedef z_stream FAR *z_streamp;
8442 +
8443 +/*
8444 + The application must update next_in and avail_in when avail_in has
8445 + dropped to zero. It must update next_out and avail_out when avail_out
8446 + has dropped to zero. The application must initialize zalloc, zfree and
8447 + opaque before calling the init function. All other fields are set by the
8448 + compression library and must not be updated by the application.
8449 +
8450 + The opaque value provided by the application will be passed as the first
8451 + parameter for calls of zalloc and zfree. This can be useful for custom
8452 + memory management. The compression library attaches no meaning to the
8453 + opaque value.
8454 +
8455 + zalloc must return Z_NULL if there is not enough memory for the object.
8456 + If zlib is used in a multi-threaded application, zalloc and zfree must be
8457 + thread safe.
8458 +
8459 + On 16-bit systems, the functions zalloc and zfree must be able to allocate
8460 + exactly 65536 bytes, but will not be required to allocate more than this
8461 + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
8462 + pointers returned by zalloc for objects of exactly 65536 bytes *must*
8463 + have their offset normalized to zero. The default allocation function
8464 + provided by this library ensures this (see zutil.c). To reduce memory
8465 + requirements and avoid any allocation of 64K objects, at the expense of
8466 + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
8467 +
8468 + The fields total_in and total_out can be used for statistics or
8469 + progress reports. After compression, total_in holds the total size of
8470 + the uncompressed data and may be saved for use in the decompressor
8471 + (particularly if the decompressor wants to decompress everything in
8472 + a single step).
8473 +*/
8474 +
8475 + /* constants */
8476 +
8477 +#define Z_NO_FLUSH 0
8478 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
8479 +#define Z_SYNC_FLUSH 2
8480 +#define Z_FULL_FLUSH 3
8481 +#define Z_FINISH 4
8482 +/* Allowed flush values; see deflate() below for details */
8483 +
8484 +#define Z_OK 0
8485 +#define Z_STREAM_END 1
8486 +#define Z_NEED_DICT 2
8487 +#define Z_ERRNO (-1)
8488 +#define Z_STREAM_ERROR (-2)
8489 +#define Z_DATA_ERROR (-3)
8490 +#define Z_MEM_ERROR (-4)
8491 +#define Z_BUF_ERROR (-5)
8492 +#define Z_VERSION_ERROR (-6)
8493 +/* Return codes for the compression/decompression functions. Negative
8494 + * values are errors, positive values are used for special but normal events.
8495 + */
8496 +
8497 +#define Z_NO_COMPRESSION 0
8498 +#define Z_BEST_SPEED 1
8499 +#define Z_BEST_COMPRESSION 9
8500 +#define Z_DEFAULT_COMPRESSION (-1)
8501 +/* compression levels */
8502 +
8503 +#define Z_FILTERED 1
8504 +#define Z_HUFFMAN_ONLY 2
8505 +#define Z_DEFAULT_STRATEGY 0
8506 +/* compression strategy; see deflateInit2() below for details */
8507 +
8508 +#define Z_BINARY 0
8509 +#define Z_ASCII 1
8510 +#define Z_UNKNOWN 2
8511 +/* Possible values of the data_type field */
8512 +
8513 +#define Z_DEFLATED 8
8514 +/* The deflate compression method (the only one supported in this version) */
8515 +
8516 +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
8517 +
8518 +#define zlib_version zlibVersion()
8519 +/* for compatibility with versions < 1.0.2 */
8520 +
8521 + /* basic functions */
8522 +
8523 +ZEXTERN const char * ZEXPORT zlibVersion OF((void));
8524 +/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
8525 + If the first character differs, the library code actually used is
8526 + not compatible with the zlib.h header file used by the application.
8527 + This check is automatically made by deflateInit and inflateInit.
8528 + */
8529 +
8530 +/*
8531 +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
8532 +
8533 + Initializes the internal stream state for compression. The fields
8534 + zalloc, zfree and opaque must be initialized before by the caller.
8535 + If zalloc and zfree are set to Z_NULL, deflateInit updates them to
8536 + use default allocation functions.
8537 +
8538 + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
8539 + 1 gives best speed, 9 gives best compression, 0 gives no compression at
8540 + all (the input data is simply copied a block at a time).
8541 + Z_DEFAULT_COMPRESSION requests a default compromise between speed and
8542 + compression (currently equivalent to level 6).
8543 +
8544 + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
8545 + enough memory, Z_STREAM_ERROR if level is not a valid compression level,
8546 + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
8547 + with the version assumed by the caller (ZLIB_VERSION).
8548 + msg is set to null if there is no error message. deflateInit does not
8549 + perform any compression: this will be done by deflate().
8550 +*/
8551 +
8552 +
8553 +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
8554 +/*
8555 + deflate compresses as much data as possible, and stops when the input
8556 + buffer becomes empty or the output buffer becomes full. It may introduce some
8557 + output latency (reading input without producing any output) except when
8558 + forced to flush.
8559 +
8560 + The detailed semantics are as follows. deflate performs one or both of the
8561 + following actions:
8562 +
8563 + - Compress more input starting at next_in and update next_in and avail_in
8564 + accordingly. If not all input can be processed (because there is not
8565 + enough room in the output buffer), next_in and avail_in are updated and
8566 + processing will resume at this point for the next call of deflate().
8567 +
8568 + - Provide more output starting at next_out and update next_out and avail_out
8569 + accordingly. This action is forced if the parameter flush is non zero.
8570 + Forcing flush frequently degrades the compression ratio, so this parameter
8571 + should be set only when necessary (in interactive applications).
8572 + Some output may be provided even if flush is not set.
8573 +
8574 + Before the call of deflate(), the application should ensure that at least
8575 + one of the actions is possible, by providing more input and/or consuming
8576 + more output, and updating avail_in or avail_out accordingly; avail_out
8577 + should never be zero before the call. The application can consume the
8578 + compressed output when it wants, for example when the output buffer is full
8579 + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
8580 + and with zero avail_out, it must be called again after making room in the
8581 + output buffer because there might be more output pending.
8582 +
8583 + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
8584 + flushed to the output buffer and the output is aligned on a byte boundary, so
8585 + that the decompressor can get all input data available so far. (In particular
8586 + avail_in is zero after the call if enough output space has been provided
8587 + before the call.) Flushing may degrade compression for some compression
8588 + algorithms and so it should be used only when necessary.
8589 +
8590 + If flush is set to Z_FULL_FLUSH, all output is flushed as with
8591 + Z_SYNC_FLUSH, and the compression state is reset so that decompression can
8592 + restart from this point if previous compressed data has been damaged or if
8593 + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
8594 + the compression.
8595 +
8596 + If deflate returns with avail_out == 0, this function must be called again
8597 + with the same value of the flush parameter and more output space (updated
8598 + avail_out), until the flush is complete (deflate returns with non-zero
8599 + avail_out).
8600 +
8601 + If the parameter flush is set to Z_FINISH, pending input is processed,
8602 + pending output is flushed and deflate returns with Z_STREAM_END if there
8603 + was enough output space; if deflate returns with Z_OK, this function must be
8604 + called again with Z_FINISH and more output space (updated avail_out) but no
8605 + more input data, until it returns with Z_STREAM_END or an error. After
8606 + deflate has returned Z_STREAM_END, the only possible operations on the
8607 + stream are deflateReset or deflateEnd.
8608 +
8609 + Z_FINISH can be used immediately after deflateInit if all the compression
8610 + is to be done in a single step. In this case, avail_out must be at least
8611 + 0.1% larger than avail_in plus 12 bytes. If deflate does not return
8612 + Z_STREAM_END, then it must be called again as described above.
8613 +
8614 + deflate() sets strm->adler to the adler32 checksum of all input read
8615 + so far (that is, total_in bytes).
8616 +
8617 + deflate() may update data_type if it can make a good guess about
8618 + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
8619 + binary. This field is only for information purposes and does not affect
8620 + the compression algorithm in any manner.
8621 +
8622 + deflate() returns Z_OK if some progress has been made (more input
8623 + processed or more output produced), Z_STREAM_END if all input has been
8624 + consumed and all output has been produced (only when flush is set to
8625 + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
8626 + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
8627 + (for example avail_in or avail_out was zero).
8628 +*/
8629 +
8630 +
8631 +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
8632 +/*
8633 + All dynamically allocated data structures for this stream are freed.
8634 + This function discards any unprocessed input and does not flush any
8635 + pending output.
8636 +
8637 + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
8638 + stream state was inconsistent, Z_DATA_ERROR if the stream was freed
8639 + prematurely (some input or output was discarded). In the error case,
8640 + msg may be set but then points to a static string (which must not be
8641 + deallocated).
8642 +*/
8643 +
8644 +
8645 +/*
8646 +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
8647 +
8648 + Initializes the internal stream state for decompression. The fields
8649 + next_in, avail_in, zalloc, zfree and opaque must be initialized before by
8650 + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
8651 + value depends on the compression method), inflateInit determines the
8652 + compression method from the zlib header and allocates all data structures
8653 + accordingly; otherwise the allocation will be deferred to the first call of
8654 + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
8655 + use default allocation functions.
8656 +
8657 + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
8658 + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
8659 + version assumed by the caller. msg is set to null if there is no error
8660 + message. inflateInit does not perform any decompression apart from reading
8661 + the zlib header if present: this will be done by inflate(). (So next_in and
8662 + avail_in may be modified, but next_out and avail_out are unchanged.)
8663 +*/
8664 +
8665 +
8666 +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
8667 +/*
8668 + inflate decompresses as much data as possible, and stops when the input
8669 + buffer becomes empty or the output buffer becomes full. It may some
8670 + introduce some output latency (reading input without producing any output)
8671 + except when forced to flush.
8672 +
8673 + The detailed semantics are as follows. inflate performs one or both of the
8674 + following actions:
8675 +
8676 + - Decompress more input starting at next_in and update next_in and avail_in
8677 + accordingly. If not all input can be processed (because there is not
8678 + enough room in the output buffer), next_in is updated and processing
8679 + will resume at this point for the next call of inflate().
8680 +
8681 + - Provide more output starting at next_out and update next_out and avail_out
8682 + accordingly. inflate() provides as much output as possible, until there
8683 + is no more input data or no more space in the output buffer (see below
8684 + about the flush parameter).
8685 +
8686 + Before the call of inflate(), the application should ensure that at least
8687 + one of the actions is possible, by providing more input and/or consuming
8688 + more output, and updating the next_* and avail_* values accordingly.
8689 + The application can consume the uncompressed output when it wants, for
8690 + example when the output buffer is full (avail_out == 0), or after each
8691 + call of inflate(). If inflate returns Z_OK and with zero avail_out, it
8692 + must be called again after making room in the output buffer because there
8693 + might be more output pending.
8694 +
8695 + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
8696 + output as possible to the output buffer. The flushing behavior of inflate is
8697 + not specified for values of the flush parameter other than Z_SYNC_FLUSH
8698 + and Z_FINISH, but the current implementation actually flushes as much output
8699 + as possible anyway.
8700 +
8701 + inflate() should normally be called until it returns Z_STREAM_END or an
8702 + error. However if all decompression is to be performed in a single step
8703 + (a single call of inflate), the parameter flush should be set to
8704 + Z_FINISH. In this case all pending input is processed and all pending
8705 + output is flushed; avail_out must be large enough to hold all the
8706 + uncompressed data. (The size of the uncompressed data may have been saved
8707 + by the compressor for this purpose.) The next operation on this stream must
8708 + be inflateEnd to deallocate the decompression state. The use of Z_FINISH
8709 + is never required, but can be used to inform inflate that a faster routine
8710 + may be used for the single inflate() call.
8711 +
8712 + If a preset dictionary is needed at this point (see inflateSetDictionary
8713 + below), inflate sets strm-adler to the adler32 checksum of the
8714 + dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
8715 + it sets strm->adler to the adler32 checksum of all output produced
8716 + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
8717 + an error code as described below. At the end of the stream, inflate()
8718 + checks that its computed adler32 checksum is equal to that saved by the
8719 + compressor and returns Z_STREAM_END only if the checksum is correct.
8720 +
8721 + inflate() returns Z_OK if some progress has been made (more input processed
8722 + or more output produced), Z_STREAM_END if the end of the compressed data has
8723 + been reached and all uncompressed output has been produced, Z_NEED_DICT if a
8724 + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
8725 + corrupted (input stream not conforming to the zlib format or incorrect
8726 + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
8727 + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
8728 + enough memory, Z_BUF_ERROR if no progress is possible or if there was not
8729 + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
8730 + case, the application may then call inflateSync to look for a good
8731 + compression block.
8732 +*/
8733 +
8734 +
8735 +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
8736 +/*
8737 + All dynamically allocated data structures for this stream are freed.
8738 + This function discards any unprocessed input and does not flush any
8739 + pending output.
8740 +
8741 + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
8742 + was inconsistent. In the error case, msg may be set but then points to a
8743 + static string (which must not be deallocated).
8744 +*/
8745 +
8746 + /* Advanced functions */
8747 +
8748 +/*
8749 + The following functions are needed only in some special applications.
8750 +*/
8751 +
8752 +/*
8753 +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
8754 + int level,
8755 + int method,
8756 + int windowBits,
8757 + int memLevel,
8758 + int strategy));
8759 +
8760 + This is another version of deflateInit with more compression options. The
8761 + fields next_in, zalloc, zfree and opaque must be initialized before by
8762 + the caller.
8763 +
8764 + The method parameter is the compression method. It must be Z_DEFLATED in
8765 + this version of the library.
8766 +
8767 + The windowBits parameter is the base two logarithm of the window size
8768 + (the size of the history buffer). It should be in the range 8..15 for this
8769 + version of the library. Larger values of this parameter result in better
8770 + compression at the expense of memory usage. The default value is 15 if
8771 + deflateInit is used instead.
8772 +
8773 + The memLevel parameter specifies how much memory should be allocated
8774 + for the internal compression state. memLevel=1 uses minimum memory but
8775 + is slow and reduces compression ratio; memLevel=9 uses maximum memory
8776 + for optimal speed. The default value is 8. See zconf.h for total memory
8777 + usage as a function of windowBits and memLevel.
8778 +
8779 + The strategy parameter is used to tune the compression algorithm. Use the
8780 + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
8781 + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
8782 + string match). Filtered data consists mostly of small values with a
8783 + somewhat random distribution. In this case, the compression algorithm is
8784 + tuned to compress them better. The effect of Z_FILTERED is to force more
8785 + Huffman coding and less string matching; it is somewhat intermediate
8786 + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
8787 + the compression ratio but not the correctness of the compressed output even
8788 + if it is not set appropriately.
8789 +
8790 + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
8791 + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
8792 + method). msg is set to null if there is no error message. deflateInit2 does
8793 + not perform any compression: this will be done by deflate().
8794 +*/
8795 +
8796 +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
8797 + const Bytef *dictionary,
8798 + uInt dictLength));
8799 +/*
8800 + Initializes the compression dictionary from the given byte sequence
8801 + without producing any compressed output. This function must be called
8802 + immediately after deflateInit, deflateInit2 or deflateReset, before any
8803 + call of deflate. The compressor and decompressor must use exactly the same
8804 + dictionary (see inflateSetDictionary).
8805 +
8806 + The dictionary should consist of strings (byte sequences) that are likely
8807 + to be encountered later in the data to be compressed, with the most commonly
8808 + used strings preferably put towards the end of the dictionary. Using a
8809 + dictionary is most useful when the data to be compressed is short and can be
8810 + predicted with good accuracy; the data can then be compressed better than
8811 + with the default empty dictionary.
8812 +
8813 + Depending on the size of the compression data structures selected by
8814 + deflateInit or deflateInit2, a part of the dictionary may in effect be
8815 + discarded, for example if the dictionary is larger than the window size in
8816 + deflate or deflate2. Thus the strings most likely to be useful should be
8817 + put at the end of the dictionary, not at the front.
8818 +
8819 + Upon return of this function, strm->adler is set to the Adler32 value
8820 + of the dictionary; the decompressor may later use this value to determine
8821 + which dictionary has been used by the compressor. (The Adler32 value
8822 + applies to the whole dictionary even if only a subset of the dictionary is
8823 + actually used by the compressor.)
8824 +
8825 + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
8826 + parameter is invalid (such as NULL dictionary) or the stream state is
8827 + inconsistent (for example if deflate has already been called for this stream
8828 + or if the compression method is bsort). deflateSetDictionary does not
8829 + perform any compression: this will be done by deflate().
8830 +*/
8831 +
8832 +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
8833 + z_streamp source));
8834 +/*
8835 + Sets the destination stream as a complete copy of the source stream.
8836 +
8837 + This function can be useful when several compression strategies will be
8838 + tried, for example when there are several ways of pre-processing the input
8839 + data with a filter. The streams that will be discarded should then be freed
8840 + by calling deflateEnd. Note that deflateCopy duplicates the internal
8841 + compression state which can be quite large, so this strategy is slow and
8842 + can consume lots of memory.
8843 +
8844 + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
8845 + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
8846 + (such as zalloc being NULL). msg is left unchanged in both source and
8847 + destination.
8848 +*/
8849 +
8850 +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
8851 +/*
8852 + This function is equivalent to deflateEnd followed by deflateInit,
8853 + but does not free and reallocate all the internal compression state.
8854 + The stream will keep the same compression level and any other attributes
8855 + that may have been set by deflateInit2.
8856 +
8857 + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
8858 + stream state was inconsistent (such as zalloc or state being NULL).
8859 +*/
8860 +
8861 +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
8862 + int level,
8863 + int strategy));
8864 +/*
8865 + Dynamically update the compression level and compression strategy. The
8866 + interpretation of level and strategy is as in deflateInit2. This can be
8867 + used to switch between compression and straight copy of the input data, or
8868 + to switch to a different kind of input data requiring a different
8869 + strategy. If the compression level is changed, the input available so far
8870 + is compressed with the old level (and may be flushed); the new level will
8871 + take effect only at the next call of deflate().
8872 +
8873 + Before the call of deflateParams, the stream state must be set as for
8874 + a call of deflate(), since the currently available input may have to
8875 + be compressed and flushed. In particular, strm->avail_out must be non-zero.
8876 +
8877 + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
8878 + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
8879 + if strm->avail_out was zero.
8880 +*/
8881 +
8882 +/*
8883 +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
8884 + int windowBits));
8885 +
8886 + This is another version of inflateInit with an extra parameter. The
8887 + fields next_in, avail_in, zalloc, zfree and opaque must be initialized
8888 + before by the caller.
8889 +
8890 + The windowBits parameter is the base two logarithm of the maximum window
8891 + size (the size of the history buffer). It should be in the range 8..15 for
8892 + this version of the library. The default value is 15 if inflateInit is used
8893 + instead. If a compressed stream with a larger window size is given as
8894 + input, inflate() will return with the error code Z_DATA_ERROR instead of
8895 + trying to allocate a larger window.
8896 +
8897 + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
8898 + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
8899 + memLevel). msg is set to null if there is no error message. inflateInit2
8900 + does not perform any decompression apart from reading the zlib header if
8901 + present: this will be done by inflate(). (So next_in and avail_in may be
8902 + modified, but next_out and avail_out are unchanged.)
8903 +*/
8904 +
8905 +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
8906 + const Bytef *dictionary,
8907 + uInt dictLength));
8908 +/*
8909 + Initializes the decompression dictionary from the given uncompressed byte
8910 + sequence. This function must be called immediately after a call of inflate
8911 + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
8912 + can be determined from the Adler32 value returned by this call of
8913 + inflate. The compressor and decompressor must use exactly the same
8914 + dictionary (see deflateSetDictionary).
8915 +
8916 + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
8917 + parameter is invalid (such as NULL dictionary) or the stream state is
8918 + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
8919 + expected one (incorrect Adler32 value). inflateSetDictionary does not
8920 + perform any decompression: this will be done by subsequent calls of
8921 + inflate().
8922 +*/
8923 +
8924 +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
8925 +/*
8926 + Skips invalid compressed data until a full flush point (see above the
8927 + description of deflate with Z_FULL_FLUSH) can be found, or until all
8928 + available input is skipped. No output is provided.
8929 +
8930 + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
8931 + if no more input was provided, Z_DATA_ERROR if no flush point has been found,
8932 + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
8933 + case, the application may save the current current value of total_in which
8934 + indicates where valid compressed data was found. In the error case, the
8935 + application may repeatedly call inflateSync, providing more input each time,
8936 + until success or end of the input data.
8937 +*/
8938 +
8939 +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
8940 +/*
8941 + This function is equivalent to inflateEnd followed by inflateInit,
8942 + but does not free and reallocate all the internal decompression state.
8943 + The stream will keep attributes that may have been set by inflateInit2.
8944 +
8945 + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
8946 + stream state was inconsistent (such as zalloc or state being NULL).
8947 +*/
8948 +
8949 +
8950 + /* utility functions */
8951 +
8952 +/*
8953 + The following utility functions are implemented on top of the
8954 + basic stream-oriented functions. To simplify the interface, some
8955 + default options are assumed (compression level and memory usage,
8956 + standard memory allocation functions). The source code of these
8957 + utility functions can easily be modified if you need special options.
8958 +*/
8959 +
8960 +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
8961 + const Bytef *source, uLong sourceLen));
8962 +/*
8963 + Compresses the source buffer into the destination buffer. sourceLen is
8964 + the byte length of the source buffer. Upon entry, destLen is the total
8965 + size of the destination buffer, which must be at least 0.1% larger than
8966 + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
8967 + compressed buffer.
8968 + This function can be used to compress a whole file at once if the
8969 + input file is mmap'ed.
8970 + compress returns Z_OK if success, Z_MEM_ERROR if there was not
8971 + enough memory, Z_BUF_ERROR if there was not enough room in the output
8972 + buffer.
8973 +*/
8974 +
8975 +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
8976 + const Bytef *source, uLong sourceLen,
8977 + int level));
8978 +/*
8979 + Compresses the source buffer into the destination buffer. The level
8980 + parameter has the same meaning as in deflateInit. sourceLen is the byte
8981 + length of the source buffer. Upon entry, destLen is the total size of the
8982 + destination buffer, which must be at least 0.1% larger than sourceLen plus
8983 + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
8984 +
8985 + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
8986 + memory, Z_BUF_ERROR if there was not enough room in the output buffer,
8987 + Z_STREAM_ERROR if the level parameter is invalid.
8988 +*/
8989 +
8990 +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
8991 + const Bytef *source, uLong sourceLen));
8992 +/*
8993 + Decompresses the source buffer into the destination buffer. sourceLen is
8994 + the byte length of the source buffer. Upon entry, destLen is the total
8995 + size of the destination buffer, which must be large enough to hold the
8996 + entire uncompressed data. (The size of the uncompressed data must have
8997 + been saved previously by the compressor and transmitted to the decompressor
8998 + by some mechanism outside the scope of this compression library.)
8999 + Upon exit, destLen is the actual size of the compressed buffer.
9000 + This function can be used to decompress a whole file at once if the
9001 + input file is mmap'ed.
9002 +
9003 + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
9004 + enough memory, Z_BUF_ERROR if there was not enough room in the output
9005 + buffer, or Z_DATA_ERROR if the input data was corrupted.
9006 +*/
9007 +
9008 +
9009 +typedef voidp gzFile;
9010 +
9011 +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
9012 +/*
9013 + Opens a gzip (.gz) file for reading or writing. The mode parameter
9014 + is as in fopen ("rb" or "wb") but can also include a compression level
9015 + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
9016 + Huffman only compression as in "wb1h". (See the description
9017 + of deflateInit2 for more information about the strategy parameter.)
9018 +
9019 + gzopen can be used to read a file which is not in gzip format; in this
9020 + case gzread will directly read from the file without decompression.
9021 +
9022 + gzopen returns NULL if the file could not be opened or if there was
9023 + insufficient memory to allocate the (de)compression state; errno
9024 + can be checked to distinguish the two cases (if errno is zero, the
9025 + zlib error is Z_MEM_ERROR). */
9026 +
9027 +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
9028 +/*
9029 + gzdopen() associates a gzFile with the file descriptor fd. File
9030 + descriptors are obtained from calls like open, dup, creat, pipe or
9031 + fileno (in the file has been previously opened with fopen).
9032 + The mode parameter is as in gzopen.
9033 + The next call of gzclose on the returned gzFile will also close the
9034 + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
9035 + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
9036 + gzdopen returns NULL if there was insufficient memory to allocate
9037 + the (de)compression state.
9038 +*/
9039 +
9040 +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
9041 +/*
9042 + Dynamically update the compression level or strategy. See the description
9043 + of deflateInit2 for the meaning of these parameters.
9044 + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
9045 + opened for writing.
9046 +*/
9047 +
9048 +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
9049 +/*
9050 + Reads the given number of uncompressed bytes from the compressed file.
9051 + If the input file was not in gzip format, gzread copies the given number
9052 + of bytes into the buffer.
9053 + gzread returns the number of uncompressed bytes actually read (0 for
9054 + end of file, -1 for error). */
9055 +
9056 +ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
9057 + const voidp buf, unsigned len));
9058 +/*
9059 + Writes the given number of uncompressed bytes into the compressed file.
9060 + gzwrite returns the number of uncompressed bytes actually written
9061 + (0 in case of error).
9062 +*/
9063 +
9064 +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
9065 +/*
9066 + Converts, formats, and writes the args to the compressed file under
9067 + control of the format string, as in fprintf. gzprintf returns the number of
9068 + uncompressed bytes actually written (0 in case of error).
9069 +*/
9070 +
9071 +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
9072 +/*
9073 + Writes the given null-terminated string to the compressed file, excluding
9074 + the terminating null character.
9075 + gzputs returns the number of characters written, or -1 in case of error.
9076 +*/
9077 +
9078 +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
9079 +/*
9080 + Reads bytes from the compressed file until len-1 characters are read, or
9081 + a newline character is read and transferred to buf, or an end-of-file
9082 + condition is encountered. The string is then terminated with a null
9083 + character.
9084 + gzgets returns buf, or Z_NULL in case of error.
9085 +*/
9086 +
9087 +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
9088 +/*
9089 + Writes c, converted to an unsigned char, into the compressed file.
9090 + gzputc returns the value that was written, or -1 in case of error.
9091 +*/
9092 +
9093 +ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
9094 +/*
9095 + Reads one byte from the compressed file. gzgetc returns this byte
9096 + or -1 in case of end of file or error.
9097 +*/
9098 +
9099 +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
9100 +/*
9101 + Flushes all pending output into the compressed file. The parameter
9102 + flush is as in the deflate() function. The return value is the zlib
9103 + error number (see function gzerror below). gzflush returns Z_OK if
9104 + the flush parameter is Z_FINISH and all output could be flushed.
9105 + gzflush should be called only when strictly necessary because it can
9106 + degrade compression.
9107 +*/
9108 +
9109 +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
9110 + z_off_t offset, int whence));
9111 +/*
9112 + Sets the starting position for the next gzread or gzwrite on the
9113 + given compressed file. The offset represents a number of bytes in the
9114 + uncompressed data stream. The whence parameter is defined as in lseek(2);
9115 + the value SEEK_END is not supported.
9116 + If the file is opened for reading, this function is emulated but can be
9117 + extremely slow. If the file is opened for writing, only forward seeks are
9118 + supported; gzseek then compresses a sequence of zeroes up to the new
9119 + starting position.
9120 +
9121 + gzseek returns the resulting offset location as measured in bytes from
9122 + the beginning of the uncompressed stream, or -1 in case of error, in
9123 + particular if the file is opened for writing and the new starting position
9124 + would be before the current position.
9125 +*/
9126 +
9127 +ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
9128 +/*
9129 + Rewinds the given file. This function is supported only for reading.
9130 +
9131 + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
9132 +*/
9133 +
9134 +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
9135 +/*
9136 + Returns the starting position for the next gzread or gzwrite on the
9137 + given compressed file. This position represents a number of bytes in the
9138 + uncompressed data stream.
9139 +
9140 + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
9141 +*/
9142 +
9143 +ZEXTERN int ZEXPORT gzeof OF((gzFile file));
9144 +/*
9145 + Returns 1 when EOF has previously been detected reading the given
9146 + input stream, otherwise zero.
9147 +*/
9148 +
9149 +ZEXTERN int ZEXPORT gzclose OF((gzFile file));
9150 +/*
9151 + Flushes all pending output if necessary, closes the compressed file
9152 + and deallocates all the (de)compression state. The return value is the zlib
9153 + error number (see function gzerror below).
9154 +*/
9155 +
9156 +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
9157 +/*
9158 + Returns the error message for the last error which occurred on the
9159 + given compressed file. errnum is set to zlib error number. If an
9160 + error occurred in the file system and not in the compression library,
9161 + errnum is set to Z_ERRNO and the application may consult errno
9162 + to get the exact error code.
9163 +*/
9164 +
9165 + /* checksum functions */
9166 +
9167 +/*
9168 + These functions are not related to compression but are exported
9169 + anyway because they might be useful in applications using the
9170 + compression library.
9171 +*/
9172 +
9173 +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
9174 +
9175 +/*
9176 + Update a running Adler-32 checksum with the bytes buf[0..len-1] and
9177 + return the updated checksum. If buf is NULL, this function returns
9178 + the required initial value for the checksum.
9179 + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
9180 + much faster. Usage example:
9181 +
9182 + uLong adler = adler32(0L, Z_NULL, 0);
9183 +
9184 + while (read_buffer(buffer, length) != EOF) {
9185 + adler = adler32(adler, buffer, length);
9186 + }
9187 + if (adler != original_adler) error();
9188 +*/
9189 +
9190 +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
9191 +/*
9192 + Update a running crc with the bytes buf[0..len-1] and return the updated
9193 + crc. If buf is NULL, this function returns the required initial value
9194 + for the crc. Pre- and post-conditioning (one's complement) is performed
9195 + within this function so it shouldn't be done by the application.
9196 + Usage example:
9197 +
9198 + uLong crc = crc32(0L, Z_NULL, 0);
9199 +
9200 + while (read_buffer(buffer, length) != EOF) {
9201 + crc = crc32(crc, buffer, length);
9202 + }
9203 + if (crc != original_crc) error();
9204 +*/
9205 +
9206 +
9207 + /* various hacks, don't look :) */
9208 +
9209 +/* deflateInit and inflateInit are macros to allow checking the zlib version
9210 + * and the compiler's view of z_stream:
9211 + */
9212 +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
9213 + const char *version, int stream_size));
9214 +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
9215 + const char *version, int stream_size));
9216 +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
9217 + int windowBits, int memLevel,
9218 + int strategy, const char *version,
9219 + int stream_size));
9220 +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
9221 + const char *version, int stream_size));
9222 +#define deflateInit(strm, level) \
9223 + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
9224 +#define inflateInit(strm) \
9225 + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
9226 +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
9227 + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
9228 + (strategy), ZLIB_VERSION, sizeof(z_stream))
9229 +#define inflateInit2(strm, windowBits) \
9230 + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
9231 +
9232 +
9233 +#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
9234 + struct internal_state {int dummy;}; /* hack for buggy compilers */
9235 +#endif
9236 +
9237 +ZEXTERN const char * ZEXPORT zError OF((int err));
9238 +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
9239 +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
9240 +
9241 +#ifdef __cplusplus
9242 +}
9243 +#endif
9244 +
9245 +#endif /* _ZLIB_H */
9246 --- /dev/null Tue Mar 11 13:02:56 2003
9247 +++ linux/include/zlib/zutil.h Mon Feb 9 13:51:03 2004
9248 @@ -0,0 +1,225 @@
9249 +/* zutil.h -- internal interface and configuration of the compression library
9250 + * Copyright (C) 1995-2002 Jean-loup Gailly.
9251 + * For conditions of distribution and use, see copyright notice in zlib.h
9252 + */
9253 +
9254 +/* WARNING: this file should *not* be used by applications. It is
9255 + part of the implementation of the compression library and is
9256 + subject to change. Applications should only use zlib.h.
9257 + */
9258 +
9259 +/* @(#) $Id: zutil.h,v 1.4 2002/04/24 07:36:48 mcr Exp $ */
9260 +
9261 +#ifndef _Z_UTIL_H
9262 +#define _Z_UTIL_H
9263 +
9264 +#include "zlib.h"
9265 +
9266 +#include <linux/string.h>
9267 +#define HAVE_MEMCPY
9268 +
9269 +#if 0 // #ifdef STDC
9270 +# include <stddef.h>
9271 +# include <string.h>
9272 +# include <stdlib.h>
9273 +#endif
9274 +#ifndef __KERNEL__
9275 +#ifdef NO_ERRNO_H
9276 + extern int errno;
9277 +#else
9278 +# include <errno.h>
9279 +#endif
9280 +#endif
9281 +
9282 +#ifndef local
9283 +# define local static
9284 +#endif
9285 +/* compile with -Dlocal if your debugger can't find static symbols */
9286 +
9287 +typedef unsigned char uch;
9288 +typedef uch FAR uchf;
9289 +typedef unsigned short ush;
9290 +typedef ush FAR ushf;
9291 +typedef unsigned long ulg;
9292 +
9293 +extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
9294 +/* (size given to avoid silly warnings with Visual C++) */
9295 +
9296 +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
9297 +
9298 +#define ERR_RETURN(strm,err) \
9299 + return (strm->msg = ERR_MSG(err), (err))
9300 +/* To be used only when the state is known to be valid */
9301 +
9302 + /* common constants */
9303 +
9304 +#ifndef DEF_WBITS
9305 +# define DEF_WBITS MAX_WBITS
9306 +#endif
9307 +/* default windowBits for decompression. MAX_WBITS is for compression only */
9308 +
9309 +#if MAX_MEM_LEVEL >= 8
9310 +# define DEF_MEM_LEVEL 8
9311 +#else
9312 +# define DEF_MEM_LEVEL MAX_MEM_LEVEL
9313 +#endif
9314 +/* default memLevel */
9315 +
9316 +#define STORED_BLOCK 0
9317 +#define STATIC_TREES 1
9318 +#define DYN_TREES 2
9319 +/* The three kinds of block type */
9320 +
9321 +#define MIN_MATCH 3
9322 +#define MAX_MATCH 258
9323 +/* The minimum and maximum match lengths */
9324 +
9325 +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
9326 +
9327 + /* target dependencies */
9328 +
9329 +#ifdef MSDOS
9330 +# define OS_CODE 0x00
9331 +# if defined(__TURBOC__) || defined(__BORLANDC__)
9332 +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
9333 + /* Allow compilation with ANSI keywords only enabled */
9334 + void _Cdecl farfree( void *block );
9335 + void *_Cdecl farmalloc( unsigned long nbytes );
9336 +# else
9337 +# include <alloc.h>
9338 +# endif
9339 +# else /* MSC or DJGPP */
9340 +# include <malloc.h>
9341 +# endif
9342 +#endif
9343 +
9344 +#ifdef OS2
9345 +# define OS_CODE 0x06
9346 +#endif
9347 +
9348 +#ifdef WIN32 /* Window 95 & Windows NT */
9349 +# define OS_CODE 0x0b
9350 +#endif
9351 +
9352 +#if defined(VAXC) || defined(VMS)
9353 +# define OS_CODE 0x02
9354 +# define F_OPEN(name, mode) \
9355 + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
9356 +#endif
9357 +
9358 +#ifdef AMIGA
9359 +# define OS_CODE 0x01
9360 +#endif
9361 +
9362 +#if defined(ATARI) || defined(atarist)
9363 +# define OS_CODE 0x05
9364 +#endif
9365 +
9366 +#if defined(MACOS) || defined(TARGET_OS_MAC)
9367 +# define OS_CODE 0x07
9368 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
9369 +# include <unix.h> /* for fdopen */
9370 +# else
9371 +# ifndef fdopen
9372 +# define fdopen(fd,mode) NULL /* No fdopen() */
9373 +# endif
9374 +# endif
9375 +#endif
9376 +
9377 +#ifdef __50SERIES /* Prime/PRIMOS */
9378 +# define OS_CODE 0x0F
9379 +#endif
9380 +
9381 +#ifdef TOPS20
9382 +# define OS_CODE 0x0a
9383 +#endif
9384 +
9385 +#if defined(_BEOS_) || defined(RISCOS)
9386 +# define fdopen(fd,mode) NULL /* No fdopen() */
9387 +#endif
9388 +
9389 +#if (defined(_MSC_VER) && (_MSC_VER > 600))
9390 +# define fdopen(fd,type) _fdopen(fd,type)
9391 +#endif
9392 +
9393 +
9394 + /* Common defaults */
9395 +
9396 +#ifndef OS_CODE
9397 +# define OS_CODE 0x03 /* assume Unix */
9398 +#endif
9399 +
9400 +#ifndef F_OPEN
9401 +# define F_OPEN(name, mode) fopen((name), (mode))
9402 +#endif
9403 +
9404 + /* functions */
9405 +
9406 +#ifdef HAVE_STRERROR
9407 + extern char *strerror OF((int));
9408 +# define zstrerror(errnum) strerror(errnum)
9409 +#else
9410 +# define zstrerror(errnum) ""
9411 +#endif
9412 +
9413 +#if defined(pyr)
9414 +# define NO_MEMCPY
9415 +#endif
9416 +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
9417 + /* Use our own functions for small and medium model with MSC <= 5.0.
9418 + * You may have to use the same strategy for Borland C (untested).
9419 + * The __SC__ check is for Symantec.
9420 + */
9421 +# define NO_MEMCPY
9422 +#endif
9423 +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
9424 +# define HAVE_MEMCPY
9425 +#endif
9426 +#ifdef HAVE_MEMCPY
9427 +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
9428 +# define zmemcpy _fmemcpy
9429 +# define zmemcmp _fmemcmp
9430 +# define zmemzero(dest, len) _fmemset(dest, 0, len)
9431 +# else
9432 +# define zmemcpy memcpy
9433 +# define zmemcmp memcmp
9434 +# define zmemzero(dest, len) memset(dest, 0, len)
9435 +# endif
9436 +#else
9437 + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
9438 + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
9439 + extern void zmemzero OF((Bytef* dest, uInt len));
9440 +#endif
9441 +
9442 +/* Diagnostic functions */
9443 +#ifdef DEBUG
9444 +# include <stdio.h>
9445 + extern int z_verbose;
9446 + extern void z_error OF((char *m));
9447 +# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
9448 +# define Trace(x) {if (z_verbose>=0) fprintf x ;}
9449 +# define Tracev(x) {if (z_verbose>0) fprintf x ;}
9450 +# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
9451 +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
9452 +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
9453 +#else
9454 +# define Assert(cond,msg)
9455 +# define Trace(x)
9456 +# define Tracev(x)
9457 +# define Tracevv(x)
9458 +# define Tracec(c,x)
9459 +# define Tracecv(c,x)
9460 +#endif
9461 +
9462 +
9463 +typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
9464 + uInt len));
9465 +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
9466 +void zcfree OF((voidpf opaque, voidpf ptr));
9467 +
9468 +#define ZALLOC(strm, items, size) \
9469 + (*((strm)->zalloc))((strm)->opaque, (items), (size))
9470 +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
9471 +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
9472 +
9473 +#endif /* _Z_UTIL_H */
9474 --- swan26/net/Kconfig.preipsec 2005-09-01 18:15:19.000000000 -0400
9475 +++ swan26/net/Kconfig 2005-09-03 16:51:17.000000000 -0400
9476 @@ -215,2 +215,6 @@
9477
9478 +if INET
9479 +source "net/ipsec/Kconfig"
9480 +endif # if INET
9481 +
9482 endif # if NET
9483 --- /distros/kernel/linux-2.6.3-rc4/net/Makefile Mon Feb 16 21:22:12 2004
9484 +++ ref26/net/Makefile Thu Feb 19 21:02:25 2004
9485 @@ -42,3 +42,6 @@
9486 ifeq ($(CONFIG_NET),y)
9487 obj-$(CONFIG_SYSCTL) += sysctl_net.o
9488 endif
9489 +
9490 +obj-$(CONFIG_KLIPS) += ipsec/
9491 +
9492 --- /dev/null Tue Mar 11 13:02:56 2003
9493 +++ linux/net/ipsec/Kconfig Mon Feb 9 13:51:03 2004
9494 @@ -0,0 +1,150 @@
9495 +#
9496 +# IPSEC configuration
9497 +# Copyright (C) 2004 Michael Richardson <mcr@freeswan.org>
9498 +#
9499 +# This program is free software; you can redistribute it and/or modify it
9500 +# under the terms of the GNU General Public License as published by the
9501 +# Free Software Foundation; either version 2 of the License, or (at your
9502 +# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9503 +#
9504 +# This program is distributed in the hope that it will be useful, but
9505 +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9506 +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9507 +# for more details.
9508 +#
9509 +# RCSID $Id: Kconfig,v 1.6.2.1 2006/04/20 16:33:06 mcr Exp $
9510 +
9511 +config KLIPS
9512 + tristate "Openswan IPsec (KLIPS26)"
9513 + default n
9514 + help
9515 + KLIPS is the Openswan (www.openswan.org) Kernel Level IP Security
9516 + system. It is extensively tested, and has interoperated with
9517 + many other systems.
9518 + It provides "ipsecX" devices on which one can do firewalling.
9519 + The userland, is compatible with both KLIPS and 26sec.
9520 +
9521 +menu "KLIPS options"
9522 + depends on KLIPS
9523 +
9524 +config KLIPS_ESP
9525 + bool 'Encapsulating Security Payload - ESP ("VPN")'
9526 + default y
9527 + help
9528 + This option provides support for the IPSEC Encapsulation Security
9529 + Payload (IP protocol 50) which provides packet layer content
9530 + hiding, and content authentication.
9531 + It is recommended to enable this. RFC2406
9532 +
9533 +config KLIPS_AH
9534 + bool 'Authentication Header - AH'
9535 + default n
9536 + help
9537 + This option provides support for the IPSEC Authentication Header
9538 + (IP protocol 51) which provides packet layer sender and content
9539 + authentication. It does not provide for confidentiality.
9540 + It is not recommended to enable this. RFC2402
9541 +
9542 +config KLIPS_AUTH_HMAC_MD5
9543 + bool 'HMAC-MD5 authentication algorithm'
9544 + default y
9545 + help
9546 + The HMAC-MD5 algorithm is used by ESP (and AH) to guarantee packet
9547 + integrity. There is little reason not to include it.
9548 +
9549 +config KLIPS_AUTH_HMAC_SHA1
9550 + bool 'HMAC-SHA1 authentication algorithm'
9551 + default y
9552 + help
9553 + The HMAC-SHA1 algorithm is used by ESP (and AH) to guarantee packet
9554 + integrity. SHA1 is a little slower than MD5, but is said to be
9555 + a bit more secure. There is little reason not to include it.
9556 +
9557 +config KLIPS_ENC_CRYPTOAPI
9558 + bool 'CryptoAPI algorithm interface'
9559 + default n
9560 + help
9561 + Enable the algorithm interface to make all CryptoAPI 1.0 algorithms
9562 + available to KLIPS.
9563 +
9564 +config KLIPS_ENC_1DES
9565 + bool 'Include 1DES with CryptoAPI'
9566 + default n
9567 + depends on KLIPS_ENC_CRYPTOAPI
9568 + help
9569 + The CryptoAPI interface does not include support for every algorithm
9570 + yet, and one that it doesn't support by default is the VERY WEAK
9571 + 1DES. Select this if you are terminally stupid.
9572 +
9573 +config KLIPS_ENC_3DES
9574 + bool '3DES encryption algorithm'
9575 + default y
9576 + help
9577 + The 3DES algorithm is used by ESP to provide for packet privacy.
9578 + 3DES is 3-repeats of the DES algorithm. 3DES is widely supported,
9579 + and analyzed and is considered very secure. 1DES is not supported.
9580 +
9581 +config KLIPS_ENC_AES
9582 + bool 'AES encryption algorithm'
9583 + default y
9584 + help
9585 + The AES algorithm is used by ESP to provide for packet privacy.
9586 + AES the NIST replacement for DES. AES is being widely analyzed,
9587 + and is very fast.
9588 +
9589 +config KLIPS_IPCOMP
9590 + bool 'IP compression'
9591 + default y
9592 + help
9593 + The IPcomp protocol is used prior to ESP to make the packet
9594 + smaller. Once encrypted, compression will fail, so any link
9595 + layer efforts (e.g. PPP) will not work.
9596 +
9597 +config KLIPS_DEBUG
9598 + bool 'IPsec debugging'
9599 + default y
9600 + help
9601 + KLIPS includes a lot of debugging code. Unless there is a real
9602 + tangible benefit to removing this code, it should be left in place.
9603 + Debugging connections without access to kernel level debugging is
9604 + essentially impossible. Leave this on.
9605 +
9606 +endmenu
9607 +
9608 +#
9609 +#
9610 +# $Log: Kconfig,v $
9611 +# Revision 1.6.2.1 2006/04/20 16:33:06 mcr
9612 +# remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
9613 +# Fix in-kernel module compilation. Sub-makefiles do not work.
9614 +#
9615 +# Revision 1.6 2005/05/18 20:55:27 mcr
9616 +# default cryptoapi to n.
9617 +#
9618 +# Revision 1.5 2005/05/11 01:23:25 mcr
9619 +# added 1DES option to cryptoapi.
9620 +#
9621 +# Revision 1.4 2005/04/29 05:29:54 mcr
9622 +# add option to include cryptoapi algorithms.
9623 +#
9624 +# Revision 1.3 2004/08/17 03:27:23 mcr
9625 +# klips 2.6 edits.
9626 +#
9627 +# Revision 1.2 2004/08/14 03:27:39 mcr
9628 +# 2.6 kernel build/configuration files.
9629 +#
9630 +# Revision 1.1 2004/08/14 02:47:55 mcr
9631 +# kernel build/config patches
9632 +#
9633 +# Revision 1.3 2004/02/24 17:17:04 mcr
9634 +# s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
9635 +# turn it on/off as well.
9636 +#
9637 +# Revision 1.2 2004/02/22 06:50:42 mcr
9638 +# kernel 2.6 port - merged with 2.4 code.
9639 +#
9640 +# Revision 1.1.2.1 2004/02/20 02:07:53 mcr
9641 +# module configuration for KLIPS 2.6
9642 +#
9643 +#
9644 +
9645 --- /dev/null Tue Mar 11 13:02:56 2003
9646 +++ linux/net/ipsec/Makefile Mon Feb 9 13:51:03 2004
9647 @@ -0,0 +1,189 @@
9648 +# Makefile for KLIPS kernel code as a module for 2.6 kernels
9649 +#
9650 +# Makefile for KLIPS kernel code as a module
9651 +# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
9652 +# Copyright (C) 2002-2004 Michael Richardson <mcr@freeswan.org>
9653 +#
9654 +# This program is free software; you can redistribute it and/or modify it
9655 +# under the terms of the GNU General Public License as published by the
9656 +# Free Software Foundation; either version 2 of the License, or (at your
9657 +# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9658 +#
9659 +# This program is distributed in the hope that it will be useful, but
9660 +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9661 +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9662 +# for more details.
9663 +#
9664 +# RCSID $Id: Makefile.fs2_6,v 1.8.2.1 2006/04/20 16:33:06 mcr Exp $
9665 +#
9666 +# Note! Dependencies are done automagically by 'make dep', which also
9667 +# removes any old dependencies. DON'T put your own dependencies here
9668 +# unless it's something special (ie not a .c file).
9669 +#
9670 +
9671 +OPENSWANSRCDIR?=.
9672 +KLIPS_TOP?=.
9673 +
9674 +-include ${OPENSWANSRCDIR}/Makefile.ver
9675 +
9676 +base-klips-objs :=
9677 +
9678 +base-klips-objs+= ipsec_init.o ipsec_sa.o ipsec_radij.o radij.o
9679 +base-klips-objs+= ipsec_life.o ipsec_proc.o
9680 +base-klips-objs+= ipsec_tunnel.o ipsec_xmit.o ipsec_rcv.o ipsec_ipip.o
9681 +base-klips-objs+= ipsec_snprintf.o
9682 +base-klips-objs+= sysctl_net_ipsec.o
9683 +base-klips-objs+= pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o
9684 +base-klips-objs+= version.o
9685 +
9686 +base-klips-objs+= satot.o
9687 +base-klips-objs+= addrtot.o
9688 +base-klips-objs+= ultot.o
9689 +base-klips-objs+= addrtypeof.o
9690 +base-klips-objs+= anyaddr.o
9691 +base-klips-objs+= initaddr.o
9692 +base-klips-objs+= ultoa.o
9693 +base-klips-objs+= addrtoa.o
9694 +base-klips-objs+= subnettoa.o
9695 +base-klips-objs+= subnetof.o
9696 +base-klips-objs+= goodmask.o
9697 +base-klips-objs+= datatot.o
9698 +base-klips-objs+= rangetoa.o
9699 +base-klips-objs+= prng.o
9700 +base-klips-objs+= pfkey_v2_parse.o
9701 +base-klips-objs+= pfkey_v2_build.o
9702 +base-klips-objs+= pfkey_v2_debug.o
9703 +base-klips-objs+= pfkey_v2_ext_bits.o
9704 +base-klips-objs+= version.o
9705 +
9706 +obj-${CONFIG_KLIPS} += ipsec.o
9707 +
9708 +ipsec-objs += ${base-klips-objs}
9709 +
9710 +ipsec-$(CONFIG_KLIPS_ESP) += ipsec_esp.o
9711 +ipsec-$(CONFIG_KLIPS_IPCOMP) += ipsec_ipcomp.o
9712 +ipsec-$(CONFIG_KLIPS_AUTH_HMAC_MD5) += ipsec_md5c.o
9713 +ipsec-$(CONFIG_KLIPS_AUTH_HMAC_SHA1) += ipsec_sha1.o
9714 +
9715 +# AH, if you really think you need it.
9716 +ipsec-$(CONFIG_KLIPS_AH) += ipsec_ah.o
9717 +
9718 +ipsec-y += ipsec_alg.o
9719 +
9720 +# include code from DES subdir
9721 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/ipsec_alg_3des.o
9722 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/cbc_enc.o
9723 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/ecb_enc.o
9724 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/set_key.o
9725 +
9726 +ifeq ($(strip ${SUBARCH}),)
9727 +SUBARCH:=${ARCH}
9728 +endif
9729 +
9730 +# the assembly version expects frame pointers, which are
9731 +# optional in many kernel builds. If you want speed, you should
9732 +# probably use cryptoapi code instead.
9733 +USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
9734 +ifeq (${USEASSEMBLY},i386y)
9735 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/dx86unix.o
9736 +else
9737 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/des_enc.o
9738 +endif
9739 +
9740 +# include code from AES subdir
9741 +crypto-$(CONFIG_KLIPS_ENC_AES) += aes/ipsec_alg_aes.o
9742 +crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes_xcbc_mac.o
9743 +crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes_cbc.o
9744 +
9745 +ifeq ($(strip ${SUBARCH}),)
9746 +SUBARCH:=${ARCH}
9747 +endif
9748 +
9749 +USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
9750 +ifeq (${USEASSEMBLY},i386y)
9751 +crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes-i586.o
9752 +else
9753 +crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes.o
9754 +endif
9755 +
9756 +ipsec-y += ${crypto-y}
9757 +
9758 +ipsec-$(CONFIG_KLIPS_ENC_CRYPTOAPI) += ipsec_alg_cryptoapi.o
9759 +
9760 +# IPcomp stuff
9761 +base-ipcomp-objs := ipcomp.o
9762 +base-ipcomp-objs += adler32.o
9763 +base-ipcomp-objs += deflate.o
9764 +base-ipcomp-objs += infblock.o
9765 +base-ipcomp-objs += infcodes.o
9766 +base-ipcomp-objs += inffast.o
9767 +base-ipcomp-objs += inflate.o
9768 +base-ipcomp-objs += inftrees.o
9769 +base-ipcomp-objs += infutil.o
9770 +base-ipcomp-objs += trees.o
9771 +base-ipcomp-objs += zutil.o
9772 +asm-ipcomp-obj-$(CONFIG_M586) += match586.o
9773 +asm-ipcomp-obj-$(CONFIG_M586TSC) += match586.o
9774 +asm-ipcomp-obj-$(CONFIG_M586MMX) += match586.o
9775 +asm-ipcomp-obj-$(CONFIG_M686) += match686.o
9776 +asm-ipcomp-obj-$(CONFIG_MPENTIUMIII) += match686.o
9777 +asm-ipcomp-obj-$(CONFIG_MPENTIUM4) += match686.o
9778 +asm-ipcomp-obj-$(CONFIG_MK6) += match586.o
9779 +asm-ipcomp-obj-$(CONFIG_MK7) += match686.o
9780 +asm-ipcomp-obj-$(CONFIG_MCRUSOE) += match586.o
9781 +asm-ipcomp-obj-$(CONFIG_MWINCHIPC6) += match586.o
9782 +asm-ipcomp-obj-$(CONFIG_MWINCHIP2) += match686.o
9783 +asm-ipcomp-obj-$(CONFIG_MWINCHIP3D) += match686.o
9784 +base-ipcomp-objs += ${asm-ipcomp-obj-y}
9785 +
9786 +ipsec-$(CONFIG_KLIPS_IPCOMP) += ${base-ipcomp-objs}
9787 +
9788 +EXTRA_CFLAGS += -DIPCOMP_PREFIX -DKLIPS
9789 +
9790 +#
9791 +# $Log: Makefile.fs2_6,v $
9792 +# Revision 1.8.2.1 2006/04/20 16:33:06 mcr
9793 +# remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
9794 +# Fix in-kernel module compilation. Sub-makefiles do not work.
9795 +#
9796 +# Revision 1.8 2005/05/11 03:15:42 mcr
9797 +# adjusted makefiles to sanely build modules properly.
9798 +#
9799 +# Revision 1.7 2005/04/13 22:52:12 mcr
9800 +# moved KLIPS specific snprintf() wrapper to seperate file.
9801 +#
9802 +# Revision 1.6 2004/08/22 05:02:03 mcr
9803 +# organized symbols such that it is easier to build modules.
9804 +#
9805 +# Revision 1.5 2004/08/18 01:43:56 mcr
9806 +# adjusted makefile enumation so that it can be used by module
9807 +# wrapper.
9808 +#
9809 +# Revision 1.4 2004/08/17 03:27:23 mcr
9810 +# klips 2.6 edits.
9811 +#
9812 +# Revision 1.3 2004/08/04 16:50:13 mcr
9813 +# removed duplicate definition of dx86unix.o
9814 +#
9815 +# Revision 1.2 2004/08/03 18:21:09 mcr
9816 +# only set KLIPS_TOP and OPENSWANSRCDIR if not already set.
9817 +#
9818 +# Revision 1.1 2004/07/26 15:02:22 mcr
9819 +# makefile for KLIPS module for 2.6.
9820 +#
9821 +# Revision 1.3 2004/02/24 17:17:04 mcr
9822 +# s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
9823 +# turn it on/off as well.
9824 +#
9825 +# Revision 1.2 2004/02/22 06:50:42 mcr
9826 +# kernel 2.6 port - merged with 2.4 code.
9827 +#
9828 +# Revision 1.1.2.1 2004/02/20 02:07:53 mcr
9829 +# module configuration for KLIPS 2.6
9830 +#
9831 +#
9832 +# Local Variables:
9833 +# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
9834 +# End Variables:
9835 +#
9836 +
9837 --- /dev/null Tue Mar 11 13:02:56 2003
9838 +++ linux/net/ipsec/README-zlib Mon Feb 9 13:51:03 2004
9839 @@ -0,0 +1,147 @@
9840 +zlib 1.1.4 is a general purpose data compression library. All the code
9841 +is thread safe. The data format used by the zlib library
9842 +is described by RFCs (Request for Comments) 1950 to 1952 in the files
9843 +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
9844 +format) and rfc1952.txt (gzip format). These documents are also available in
9845 +other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
9846 +
9847 +All functions of the compression library are documented in the file zlib.h
9848 +(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
9849 +example of the library is given in the file example.c which also tests that
9850 +the library is working correctly. Another example is given in the file
9851 +minigzip.c. The compression library itself is composed of all source files
9852 +except example.c and minigzip.c.
9853 +
9854 +To compile all files and run the test program, follow the instructions
9855 +given at the top of Makefile. In short "make test; make install"
9856 +should work for most machines. For Unix: "./configure; make test; make install"
9857 +For MSDOS, use one of the special makefiles such as Makefile.msc.
9858 +For VMS, use Make_vms.com or descrip.mms.
9859 +
9860 +Questions about zlib should be sent to <zlib@gzip.org>, or to
9861 +Gilles Vollant <info@winimage.com> for the Windows DLL version.
9862 +The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
9863 +Before reporting a problem, please check this site to verify that
9864 +you have the latest version of zlib; otherwise get the latest version and
9865 +check whether the problem still exists or not.
9866 +
9867 +PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
9868 +before asking for help.
9869 +
9870 +Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
9871 +issue of Dr. Dobb's Journal; a copy of the article is available in
9872 +http://dogma.net/markn/articles/zlibtool/zlibtool.htm
9873 +
9874 +The changes made in version 1.1.4 are documented in the file ChangeLog.
9875 +The only changes made since 1.1.3 are bug corrections:
9876 +
9877 +- ZFREE was repeated on same allocation on some error conditions.
9878 + This creates a security problem described in
9879 + http://www.zlib.org/advisory-2002-03-11.txt
9880 +- Returned incorrect error (Z_MEM_ERROR) on some invalid data
9881 +- Avoid accesses before window for invalid distances with inflate window
9882 + less than 32K.
9883 +- force windowBits > 8 to avoid a bug in the encoder for a window size
9884 + of 256 bytes. (A complete fix will be available in 1.1.5).
9885 +
9886 +The beta version 1.1.5beta includes many more changes. A new official
9887 +version 1.1.5 will be released as soon as extensive testing has been
9888 +completed on it.
9889 +
9890 +
9891 +Unsupported third party contributions are provided in directory "contrib".
9892 +
9893 +A Java implementation of zlib is available in the Java Development Kit
9894 +http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
9895 +See the zlib home page http://www.zlib.org for details.
9896 +
9897 +A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
9898 +is in the CPAN (Comprehensive Perl Archive Network) sites
9899 +http://www.cpan.org/modules/by-module/Compress/
9900 +
9901 +A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
9902 +is available in Python 1.5 and later versions, see
9903 +http://www.python.org/doc/lib/module-zlib.html
9904 +
9905 +A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
9906 +is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
9907 +
9908 +An experimental package to read and write files in .zip format,
9909 +written on top of zlib by Gilles Vollant <info@winimage.com>, is
9910 +available at http://www.winimage.com/zLibDll/unzip.html
9911 +and also in the contrib/minizip directory of zlib.
9912 +
9913 +
9914 +Notes for some targets:
9915 +
9916 +- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
9917 + and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
9918 + The zlib DLL support was initially done by Alessandro Iacopetti and is
9919 + now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
9920 + home page at http://www.winimage.com/zLibDll
9921 +
9922 + From Visual Basic, you can call the DLL functions which do not take
9923 + a structure as argument: compress, uncompress and all gz* functions.
9924 + See contrib/visual-basic.txt for more information, or get
9925 + http://www.tcfb.com/dowseware/cmp-z-it.zip
9926 +
9927 +- For 64-bit Irix, deflate.c must be compiled without any optimization.
9928 + With -O, one libpng test fails. The test works in 32 bit mode (with
9929 + the -n32 compiler flag). The compiler bug has been reported to SGI.
9930 +
9931 +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1
9932 + it works when compiled with cc.
9933 +
9934 +- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
9935 + is necessary to get gzprintf working correctly. This is done by configure.
9936 +
9937 +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
9938 + with other compilers. Use "make test" to check your compiler.
9939 +
9940 +- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
9941 +
9942 +- For Turbo C the small model is supported only with reduced performance to
9943 + avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
9944 +
9945 +- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
9946 + Per Harald Myrvang <perm@stud.cs.uit.no>
9947 +
9948 +
9949 +Acknowledgments:
9950 +
9951 + The deflate format used by zlib was defined by Phil Katz. The deflate
9952 + and zlib specifications were written by L. Peter Deutsch. Thanks to all the
9953 + people who reported problems and suggested various improvements in zlib;
9954 + they are too numerous to cite here.
9955 +
9956 +Copyright notice:
9957 +
9958 + (C) 1995-2002 Jean-loup Gailly and Mark Adler
9959 +
9960 + This software is provided 'as-is', without any express or implied
9961 + warranty. In no event will the authors be held liable for any damages
9962 + arising from the use of this software.
9963 +
9964 + Permission is granted to anyone to use this software for any purpose,
9965 + including commercial applications, and to alter it and redistribute it
9966 + freely, subject to the following restrictions:
9967 +
9968 + 1. The origin of this software must not be misrepresented; you must not
9969 + claim that you wrote the original software. If you use this software
9970 + in a product, an acknowledgment in the product documentation would be
9971 + appreciated but is not required.
9972 + 2. Altered source versions must be plainly marked as such, and must not be
9973 + misrepresented as being the original software.
9974 + 3. This notice may not be removed or altered from any source distribution.
9975 +
9976 + Jean-loup Gailly Mark Adler
9977 + jloup@gzip.org madler@alumni.caltech.edu
9978 +
9979 +If you use the zlib library in a product, we would appreciate *not*
9980 +receiving lengthy legal documents to sign. The sources are provided
9981 +for free but without warranty of any kind. The library has been
9982 +entirely written by Jean-loup Gailly and Mark Adler; it does not
9983 +include third-party code.
9984 +
9985 +If you redistribute modified sources, we would appreciate that you include
9986 +in the file ChangeLog history information documenting your changes.
9987 --- /dev/null Tue Mar 11 13:02:56 2003
9988 +++ linux/net/ipsec/README-zlib.freeswan Mon Feb 9 13:51:03 2004
9989 @@ -0,0 +1,13 @@
9990 +The only changes made to these files for use in FreeS/WAN are:
9991 +
9992 + - In zconf.h, macros are defined to prefix global symbols with "ipcomp_"
9993 + (or "_ipcomp"), when compiled with -DIPCOMP_PREFIX.
9994 + - The copyright strings are defined local (static)
9995 +
9996 + The above changes are made to avoid name collisions with ppp_deflate
9997 + and ext2compr.
9998 +
9999 + - Files not needed for FreeS/WAN have been removed
10000 +
10001 + See the "README" file for information about where to obtain the complete
10002 + zlib package.
10003 --- /dev/null Tue Mar 11 13:02:56 2003
10004 +++ linux/net/ipsec/addrtoa.c Mon Feb 9 13:51:03 2004
10005 @@ -0,0 +1,67 @@
10006 +/*
10007 + * addresses to ASCII
10008 + * Copyright (C) 1998, 1999 Henry Spencer.
10009 + *
10010 + * This library is free software; you can redistribute it and/or modify it
10011 + * under the terms of the GNU Library General Public License as published by
10012 + * the Free Software Foundation; either version 2 of the License, or (at your
10013 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10014 + *
10015 + * This library is distributed in the hope that it will be useful, but
10016 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10017 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10018 + * License for more details.
10019 + *
10020 + * RCSID $Id: addrtoa.c,v 1.10 2004/07/10 07:43:47 mcr Exp $
10021 + */
10022 +#include "openswan.h"
10023 +
10024 +#define NBYTES 4 /* bytes in an address */
10025 +#define PERBYTE 4 /* three digits plus a dot or NUL */
10026 +#define BUFLEN (NBYTES*PERBYTE)
10027 +
10028 +#if BUFLEN != ADDRTOA_BUF
10029 +#error "ADDRTOA_BUF in openswan.h inconsistent with addrtoa() code"
10030 +#endif
10031 +
10032 +/*
10033 + - addrtoa - convert binary address to ASCII dotted decimal
10034 + */
10035 +size_t /* space needed for full conversion */
10036 +addrtoa(addr, format, dst, dstlen)
10037 +struct in_addr addr;
10038 +int format; /* character */
10039 +char *dst; /* need not be valid if dstlen is 0 */
10040 +size_t dstlen;
10041 +{
10042 + unsigned long a = ntohl(addr.s_addr);
10043 + int i;
10044 + size_t n;
10045 + unsigned long byte;
10046 + char buf[BUFLEN];
10047 + char *p;
10048 +
10049 + switch (format) {
10050 + case 0:
10051 + break;
10052 + default:
10053 + return 0;
10054 + break;
10055 + }
10056 +
10057 + p = buf;
10058 + for (i = NBYTES-1; i >= 0; i--) {
10059 + byte = (a >> (i*8)) & 0xff;
10060 + p += ultoa(byte, 10, p, PERBYTE);
10061 + if (i != 0)
10062 + *(p-1) = '.';
10063 + }
10064 + n = p - buf;
10065 +
10066 + if (dstlen > 0) {
10067 + if (n > dstlen)
10068 + buf[dstlen - 1] = '\0';
10069 + strcpy(dst, buf);
10070 + }
10071 + return n;
10072 +}
10073 --- /dev/null Tue Mar 11 13:02:56 2003
10074 +++ linux/net/ipsec/addrtot.c Mon Feb 9 13:51:03 2004
10075 @@ -0,0 +1,387 @@
10076 +/*
10077 + * addresses to text
10078 + * Copyright (C) 2000 Henry Spencer.
10079 + *
10080 + * This library is free software; you can redistribute it and/or modify it
10081 + * under the terms of the GNU Library General Public License as published by
10082 + * the Free Software Foundation; either version 2 of the License, or (at your
10083 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10084 + *
10085 + * This library is distributed in the hope that it will be useful, but
10086 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10087 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10088 + * License for more details.
10089 + *
10090 + * RCSID $Id: addrtot.c,v 1.24 2005/11/11 06:59:40 mcr Exp $
10091 + */
10092 +
10093 +#if defined(__KERNEL__) && defined(__HAVE_ARCH_STRSTR)
10094 +#include <linux/string.h>
10095 +#endif
10096 +
10097 +#include "openswan.h"
10098 +
10099 +#define IP4BYTES 4 /* bytes in an IPv4 address */
10100 +#define PERBYTE 4 /* three digits plus a dot or NUL */
10101 +#define IP6BYTES 16 /* bytes in an IPv6 address */
10102 +
10103 +/* forwards */
10104 +static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp);
10105 +static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp, int squish);
10106 +static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp);
10107 +static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp);
10108 +
10109 +#if defined(__KERNEL__) && !defined(__HAVE_ARCH_STRSTR)
10110 +#define strstr ipsec_strstr
10111 +/*
10112 + * Find the first occurrence of find in s.
10113 + * (from NetBSD 1.6's /src/lib/libc/string/strstr.c)
10114 + */
10115 +static char *ipsec_strstr(const char *s, const char *find)
10116 +{
10117 + char c, sc;
10118 + size_t len;
10119 +
10120 + if ((c = *find++) != 0) {
10121 + len = strlen(find);
10122 + do {
10123 + do {
10124 + if ((sc = *s++) == 0)
10125 + return (NULL);
10126 + } while (sc != c);
10127 + } while (strncmp(s, find, len) != 0);
10128 + s--;
10129 + }
10130 + /* LINTED interface specification */
10131 + return ((char *)s);
10132 +}
10133 +#endif
10134 +
10135 +/*
10136 + - addrtot - convert binary address to text (dotted decimal or IPv6 string)
10137 + */
10138 +size_t /* space needed for full conversion */
10139 +addrtot(src, format, dst, dstlen)
10140 +const ip_address *src;
10141 +int format; /* character */
10142 +char *dst; /* need not be valid if dstlen is 0 */
10143 +size_t dstlen;
10144 +{
10145 + const unsigned char *b;
10146 + size_t n;
10147 + char buf[1+ADDRTOT_BUF+1]; /* :address: */
10148 + char *p;
10149 + int t = addrtypeof(src);
10150 +# define TF(t, f) (((t)<<8) | (f))
10151 +
10152 + n = addrbytesptr(src, &b);
10153 + if (n == 0) {
10154 + bad:
10155 + dst[0]='\0';
10156 + strncat(dst, "<invalid>", dstlen);
10157 + return sizeof("<invalid>");
10158 + }
10159 +
10160 + switch (TF(t, format)) {
10161 + case TF(AF_INET, 0):
10162 + n = normal4(b, n, buf, &p);
10163 + break;
10164 + case TF(AF_INET6, 0):
10165 + n = normal6(b, n, buf, &p, 1);
10166 + break;
10167 + case TF(AF_INET, 'Q'):
10168 + n = normal4(b, n, buf, &p);
10169 + break;
10170 + case TF(AF_INET6, 'Q'):
10171 + n = normal6(b, n, buf, &p, 0);
10172 + break;
10173 + case TF(AF_INET, 'r'):
10174 + n = reverse4(b, n, buf, &p);
10175 + break;
10176 + case TF(AF_INET6, 'r'):
10177 + n = reverse6(b, n, buf, &p);
10178 + break;
10179 + default: /* including (AF_INET, 'R') */
10180 + goto bad;
10181 + break;
10182 + }
10183 +
10184 + if (dstlen > 0) {
10185 + if (dstlen < n)
10186 + p[dstlen - 1] = '\0';
10187 + strcpy(dst, p);
10188 + }
10189 + return n;
10190 +}
10191 +
10192 +/*
10193 + - normal4 - normal IPv4 address-text conversion
10194 + */
10195 +static size_t /* size of text, including NUL */
10196 +normal4(srcp, srclen, buf, dstp)
10197 +const unsigned char *srcp;
10198 +size_t srclen;
10199 +char *buf; /* guaranteed large enough */
10200 +char **dstp; /* where to put result pointer */
10201 +{
10202 + int i;
10203 + char *p;
10204 +
10205 + if (srclen != IP4BYTES) /* "can't happen" */
10206 + return 0;
10207 + p = buf;
10208 + for (i = 0; i < IP4BYTES; i++) {
10209 + p += ultot(srcp[i], 10, p, PERBYTE);
10210 + if (i != IP4BYTES - 1)
10211 + *(p-1) = '.'; /* overwrites the NUL */
10212 + }
10213 + *dstp = buf;
10214 + return p - buf;
10215 +}
10216 +
10217 +/*
10218 + - normal6 - normal IPv6 address-text conversion
10219 + */
10220 +static size_t /* size of text, including NUL */
10221 +normal6(srcp, srclen, buf, dstp, squish)
10222 +const unsigned char *srcp;
10223 +size_t srclen;
10224 +char *buf; /* guaranteed large enough, plus 2 */
10225 +char **dstp; /* where to put result pointer */
10226 +int squish; /* whether to squish out 0:0 */
10227 +{
10228 + int i;
10229 + unsigned long piece;
10230 + char *p;
10231 + char *q;
10232 +
10233 + if (srclen != IP6BYTES) /* "can't happen" */
10234 + return 0;
10235 + p = buf;
10236 + *p++ = ':';
10237 + for (i = 0; i < IP6BYTES/2; i++) {
10238 + piece = (srcp[2*i] << 8) + srcp[2*i + 1];
10239 + p += ultot(piece, 16, p, 5); /* 5 = abcd + NUL */
10240 + *(p-1) = ':'; /* overwrites the NUL */
10241 + }
10242 + *p = '\0';
10243 + q = strstr(buf, ":0:0:");
10244 + if (squish && q != NULL) { /* zero squishing is possible */
10245 + p = q + 1;
10246 + while (*p == '0' && *(p+1) == ':')
10247 + p += 2;
10248 + q++;
10249 + *q++ = ':'; /* overwrite first 0 */
10250 + while (*p != '\0')
10251 + *q++ = *p++;
10252 + *q = '\0';
10253 + if (!(*(q-1) == ':' && *(q-2) == ':'))
10254 + *--q = '\0'; /* strip final : unless :: */
10255 + p = buf;
10256 + if (!(*p == ':' && *(p+1) == ':'))
10257 + p++; /* skip initial : unless :: */
10258 + } else {
10259 + q = p;
10260 + *--q = '\0'; /* strip final : */
10261 + p = buf + 1; /* skip initial : */
10262 + }
10263 + *dstp = p;
10264 + return q - p + 1;
10265 +}
10266 +
10267 +/*
10268 + - reverse4 - IPv4 reverse-lookup conversion
10269 + */
10270 +static size_t /* size of text, including NUL */
10271 +reverse4(srcp, srclen, buf, dstp)
10272 +const unsigned char *srcp;
10273 +size_t srclen;
10274 +char *buf; /* guaranteed large enough */
10275 +char **dstp; /* where to put result pointer */
10276 +{
10277 + int i;
10278 + char *p;
10279 +
10280 + if (srclen != IP4BYTES) /* "can't happen" */
10281 + return 0;
10282 + p = buf;
10283 + for (i = IP4BYTES-1; i >= 0; i--) {
10284 + p += ultot(srcp[i], 10, p, PERBYTE);
10285 + *(p-1) = '.'; /* overwrites the NUL */
10286 + }
10287 + strcpy(p, "IN-ADDR.ARPA.");
10288 + *dstp = buf;
10289 + return strlen(buf) + 1;
10290 +}
10291 +
10292 +/*
10293 + - reverse6 - IPv6 reverse-lookup conversion (RFC 1886)
10294 + * A trifle inefficient, really shouldn't use ultot...
10295 + */
10296 +static size_t /* size of text, including NUL */
10297 +reverse6(srcp, srclen, buf, dstp)
10298 +const unsigned char *srcp;
10299 +size_t srclen;
10300 +char *buf; /* guaranteed large enough */
10301 +char **dstp; /* where to put result pointer */
10302 +{
10303 + int i;
10304 + unsigned long piece;
10305 + char *p;
10306 +
10307 + if (srclen != IP6BYTES) /* "can't happen" */
10308 + return 0;
10309 + p = buf;
10310 + for (i = IP6BYTES-1; i >= 0; i--) {
10311 + piece = srcp[i];
10312 + p += ultot(piece&0xf, 16, p, 2);
10313 + *(p-1) = '.';
10314 + p += ultot(piece>>4, 16, p, 2);
10315 + *(p-1) = '.';
10316 + }
10317 + strcpy(p, "IP6.ARPA.");
10318 + *dstp = buf;
10319 + return strlen(buf) + 1;
10320 +}
10321 +
10322 +/*
10323 + - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874)
10324 + * this version removed as it was obsoleted in the end.
10325 + */
10326 +
10327 +#ifdef ADDRTOT_MAIN
10328 +
10329 +#include <stdio.h>
10330 +#include <stdlib.h>
10331 +#include <sys/socket.h>
10332 +#include <netinet/in.h>
10333 +#include <arpa/inet.h>
10334 +
10335 +void regress(void);
10336 +
10337 +int
10338 +main(int argc, char *argv[])
10339 +{
10340 + if (argc < 2) {
10341 + fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
10342 + argv[0]);
10343 + exit(2);
10344 + }
10345 +
10346 + if (strcmp(argv[1], "-r") == 0) {
10347 + regress();
10348 + fprintf(stderr, "regress() returned?!?\n");
10349 + exit(1);
10350 + }
10351 + exit(0);
10352 +}
10353 +
10354 +struct rtab {
10355 + char *input;
10356 + char format;
10357 + char *output; /* NULL means error expected */
10358 +} rtab[] = {
10359 + {"1.2.3.0", 0, "1.2.3.0"},
10360 + {"1:2::3:4", 0, "1:2::3:4"},
10361 + {"1:2::3:4", 'Q', "1:2:0:0:0:0:3:4"},
10362 + {"1:2:0:0:3:4:0:0", 0, "1:2::3:4:0:0"},
10363 + {"1.2.3.4", 'r' , "4.3.2.1.IN-ADDR.ARPA."},
10364 + /* 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 */
10365 + {"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."},
10366 + {NULL, 0, NULL}
10367 +};
10368 +
10369 +void
10370 +regress()
10371 +{
10372 + struct rtab *r;
10373 + int status = 0;
10374 + ip_address a;
10375 + char in[100];
10376 + char buf[100];
10377 + const char *oops;
10378 + size_t n;
10379 +
10380 + for (r = rtab; r->input != NULL; r++) {
10381 + strcpy(in, r->input);
10382 +
10383 + /* convert it *to* internal format */
10384 + oops = ttoaddr(in, strlen(in), 0, &a);
10385 +
10386 + /* now convert it back */
10387 +
10388 + n = addrtot(&a, r->format, buf, sizeof(buf));
10389 +
10390 + if (n == 0 && r->output == NULL)
10391 + {} /* okay, error expected */
10392 +
10393 + else if (n == 0) {
10394 + printf("`%s' atoasr failed\n", r->input);
10395 + status = 1;
10396 +
10397 + } else if (r->output == NULL) {
10398 + printf("`%s' atoasr succeeded unexpectedly '%c'\n",
10399 + r->input, r->format);
10400 + status = 1;
10401 + } else {
10402 + if (strcasecmp(r->output, buf) != 0) {
10403 + printf("`%s' '%c' gave `%s', expected `%s'\n",
10404 + r->input, r->format, buf, r->output);
10405 + status = 1;
10406 + }
10407 + }
10408 + }
10409 + exit(status);
10410 +}
10411 +
10412 +#endif /* ADDRTOT_MAIN */
10413 +
10414 +/*
10415 + * $Log: addrtot.c,v $
10416 + * Revision 1.24 2005/11/11 06:59:40 mcr
10417 + * try this code to avoid static/extern conflict with newer
10418 + * kernels.
10419 + *
10420 + * Revision 1.23 2005/11/11 03:09:53 paul
10421 + * Fix by Toby for newer kernels that have strstr()
10422 + *
10423 + * Revision 1.22.2.1 2005/11/17 22:30:49 paul
10424 + * pull up strstr fix from head.
10425 + *
10426 + * Revision 1.22 2005/05/20 16:47:40 mcr
10427 + * make strstr static if we need it.
10428 + *
10429 + * Revision 1.21 2005/03/21 00:35:12 mcr
10430 + * test for strstr properly
10431 + *
10432 + * Revision 1.20 2004/11/09 22:52:20 mcr
10433 + * until we figure out which kernels have strsep and which
10434 + * do not (UML does not under certain circumstances), then
10435 + * let's just provide our own.
10436 + *
10437 + * Revision 1.19 2004/10/08 16:30:33 mcr
10438 + * pull-up of initial crypto-offload work.
10439 + *
10440 + * Revision 1.18 2004/09/18 19:33:08 mcr
10441 + * use an appropriate kernel happy ifdef for strstr.
10442 + *
10443 + * Revision 1.17 2004/09/15 21:49:02 mcr
10444 + * use local copy of strstr() if this is going in the kernel.
10445 + * Not clear why this worked before, or why this shows up
10446 + * for modules only.
10447 + *
10448 + * Revision 1.16 2004/07/10 07:43:47 mcr
10449 + * Moved from linux/lib/libfreeswan/addrtot.c,v
10450 + *
10451 + * Revision 1.15 2004/04/11 17:39:25 mcr
10452 + * removed internal.h requirements.
10453 + *
10454 + * Revision 1.14 2004/03/08 01:59:08 ken
10455 + * freeswan.h -> openswan.h
10456 + *
10457 + * Revision 1.13 2004/01/05 23:21:05 mcr
10458 + * if the address type is invalid, then return length of <invalid>
10459 + * string!
10460 + *
10461 + */
10462 +
10463 --- /dev/null Tue Mar 11 13:02:56 2003
10464 +++ linux/net/ipsec/addrtypeof.c Mon Feb 9 13:51:03 2004
10465 @@ -0,0 +1,93 @@
10466 +/*
10467 + * extract parts of an ip_address
10468 + * Copyright (C) 2000 Henry Spencer.
10469 + *
10470 + * This library is free software; you can redistribute it and/or modify it
10471 + * under the terms of the GNU Library General Public License as published by
10472 + * the Free Software Foundation; either version 2 of the License, or (at your
10473 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10474 + *
10475 + * This library is distributed in the hope that it will be useful, but
10476 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10477 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10478 + * License for more details.
10479 + *
10480 + * RCSID $Id: addrtypeof.c,v 1.10 2004/07/10 07:43:47 mcr Exp $
10481 + */
10482 +#include "openswan.h"
10483 +
10484 +/*
10485 + - addrtypeof - get the type of an ip_address
10486 + */
10487 +int
10488 +addrtypeof(src)
10489 +const ip_address *src;
10490 +{
10491 + return src->u.v4.sin_family;
10492 +}
10493 +
10494 +/*
10495 + - addrbytesptr - get pointer to the address bytes of an ip_address
10496 + */
10497 +size_t /* 0 for error */
10498 +addrbytesptr(src, dstp)
10499 +const ip_address *src;
10500 +const unsigned char **dstp; /* NULL means just a size query */
10501 +{
10502 + const unsigned char *p;
10503 + size_t n;
10504 +
10505 + switch (src->u.v4.sin_family) {
10506 + case AF_INET:
10507 + p = (const unsigned char *)&src->u.v4.sin_addr.s_addr;
10508 + n = 4;
10509 + break;
10510 + case AF_INET6:
10511 + p = (const unsigned char *)&src->u.v6.sin6_addr;
10512 + n = 16;
10513 + break;
10514 + default:
10515 + return 0;
10516 + break;
10517 + }
10518 +
10519 + if (dstp != NULL)
10520 + *dstp = p;
10521 + return n;
10522 +}
10523 +
10524 +/*
10525 + - addrlenof - get length of the address bytes of an ip_address
10526 + */
10527 +size_t /* 0 for error */
10528 +addrlenof(src)
10529 +const ip_address *src;
10530 +{
10531 + return addrbytesptr(src, NULL);
10532 +}
10533 +
10534 +/*
10535 + - addrbytesof - get the address bytes of an ip_address
10536 + */
10537 +size_t /* 0 for error */
10538 +addrbytesof(src, dst, dstlen)
10539 +const ip_address *src;
10540 +unsigned char *dst;
10541 +size_t dstlen;
10542 +{
10543 + const unsigned char *p;
10544 + size_t n;
10545 + size_t ncopy;
10546 +
10547 + n = addrbytesptr(src, &p);
10548 + if (n == 0)
10549 + return 0;
10550 +
10551 + if (dstlen > 0) {
10552 + ncopy = n;
10553 + if (ncopy > dstlen)
10554 + ncopy = dstlen;
10555 + memcpy(dst, p, ncopy);
10556 + }
10557 + return n;
10558 +}
10559 --- /dev/null Tue Mar 11 13:02:56 2003
10560 +++ linux/net/ipsec/adler32.c Mon Feb 9 13:51:03 2004
10561 @@ -0,0 +1,49 @@
10562 +/* adler32.c -- compute the Adler-32 checksum of a data stream
10563 + * Copyright (C) 1995-2002 Mark Adler
10564 + * For conditions of distribution and use, see copyright notice in zlib.h
10565 + */
10566 +
10567 +/* @(#) $Id: adler32.c,v 1.6 2004/07/10 19:11:18 mcr Exp $ */
10568 +
10569 +#include <zlib/zlib.h>
10570 +#include <zlib/zconf.h>
10571 +
10572 +#define BASE 65521L /* largest prime smaller than 65536 */
10573 +#define NMAX 5552
10574 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
10575 +
10576 +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
10577 +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
10578 +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
10579 +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
10580 +#define DO16(buf) DO8(buf,0); DO8(buf,8);
10581 +
10582 +/* ========================================================================= */
10583 +uLong ZEXPORT adler32(adler, buf, len)
10584 + uLong adler;
10585 + const Bytef *buf;
10586 + uInt len;
10587 +{
10588 + unsigned long s1 = adler & 0xffff;
10589 + unsigned long s2 = (adler >> 16) & 0xffff;
10590 + int k;
10591 +
10592 + if (buf == Z_NULL) return 1L;
10593 +
10594 + while (len > 0) {
10595 + k = len < NMAX ? len : NMAX;
10596 + len -= k;
10597 + while (k >= 16) {
10598 + DO16(buf);
10599 + buf += 16;
10600 + k -= 16;
10601 + }
10602 + if (k != 0) do {
10603 + s1 += *buf++;
10604 + s2 += s1;
10605 + } while (--k);
10606 + s1 %= BASE;
10607 + s2 %= BASE;
10608 + }
10609 + return (s2 << 16) | s1;
10610 +}
10611 --- /dev/null Tue Mar 11 13:02:56 2003
10612 +++ linux/net/ipsec/aes/Makefile Mon Feb 9 13:51:03 2004
10613 @@ -0,0 +1,56 @@
10614 +# Makefile for KLIPS 3DES kernel code as a module for 2.6 kernels
10615 +#
10616 +# Makefile for KLIPS kernel code as a module
10617 +# Copyright (C) 2002-2004 Michael Richardson <mcr@xelerance.com>
10618 +#
10619 +# This program is free software; you can redistribute it and/or modify it
10620 +# under the terms of the GNU General Public License as published by the
10621 +# Free Software Foundation; either version 2 of the License, or (at your
10622 +# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10623 +#
10624 +# This program is distributed in the hope that it will be useful, but
10625 +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10626 +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10627 +# for more details.
10628 +#
10629 +# RCSID $Id: Makefile.fs2_6,v 1.2 2005/08/12 14:13:58 mcr Exp $
10630 +#
10631 +# Note! Dependencies are done automagically by 'make dep', which also
10632 +# removes any old dependencies. DON'T put your own dependencies here
10633 +# unless it's something special (ie not a .c file).
10634 +#
10635 +
10636 +obj-$(CONFIG_KLIPS_ENC_AES) += ipsec_alg_aes.o
10637 +obj-$(CONFIG_KLIPS_ENC_AES) += aes_xcbc_mac.o
10638 +obj-$(CONFIG_KLIPS_ENC_AES) += aes_cbc.o
10639 +
10640 +ifeq ($(strip ${SUBARCH}),)
10641 +SUBARCH:=${ARCH}
10642 +endif
10643 +
10644 +# the assembly version expects frame pointers, which are
10645 +# optional in many kernel builds. If you want speed, you should
10646 +# probably use cryptoapi code instead.
10647 +USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
10648 +ifeq (${USEASSEMBLY},i386y)
10649 +obj-$(CONFIG_KLIPS_ENC_AES) += aes-i586.o
10650 +else
10651 +obj-$(CONFIG_KLIPS_ENC_AES) += aes.o
10652 +endif
10653 +
10654 +
10655 +#
10656 +# $Log: Makefile.fs2_6,v $
10657 +# Revision 1.2 2005/08/12 14:13:58 mcr
10658 +# do not use assembly code with there are no frame pointers,
10659 +# as it does not have the right linkages.
10660 +#
10661 +# Revision 1.1 2004/08/17 03:31:34 mcr
10662 +# klips 2.6 edits.
10663 +#
10664 +#
10665 +# Local Variables:
10666 +# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
10667 +# End Variables:
10668 +#
10669 +
10670 --- /dev/null Tue Mar 11 13:02:56 2003
10671 +++ linux/net/ipsec/aes/aes-i586.S Mon Feb 9 13:51:03 2004
10672 @@ -0,0 +1,892 @@
10673 +//
10674 +// Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
10675 +// All rights reserved.
10676 +//
10677 +// TERMS
10678 +//
10679 +// Redistribution and use in source and binary forms, with or without
10680 +// modification, are permitted subject to the following conditions:
10681 +//
10682 +// 1. Redistributions of source code must retain the above copyright
10683 +// notice, this list of conditions and the following disclaimer.
10684 +//
10685 +// 2. Redistributions in binary form must reproduce the above copyright
10686 +// notice, this list of conditions and the following disclaimer in the
10687 +// documentation and/or other materials provided with the distribution.
10688 +//
10689 +// 3. The copyright holder's name must not be used to endorse or promote
10690 +// any products derived from this software without his specific prior
10691 +// written permission.
10692 +//
10693 +// This software is provided 'as is' with no express or implied warranties
10694 +// of correctness or fitness for purpose.
10695 +
10696 +// Modified by Jari Ruusu, December 24 2001
10697 +// - Converted syntax to GNU CPP/assembler syntax
10698 +// - C programming interface converted back to "old" API
10699 +// - Minor portability cleanups and speed optimizations
10700 +
10701 +// An AES (Rijndael) implementation for the Pentium. This version only
10702 +// implements the standard AES block length (128 bits, 16 bytes). This code
10703 +// does not preserve the eax, ecx or edx registers or the artihmetic status
10704 +// flags. However, the ebx, esi, edi, and ebp registers are preserved across
10705 +// calls.
10706 +
10707 +// void aes_set_key(aes_context *cx, const unsigned char key[], const int key_len, const int f)
10708 +// void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
10709 +// void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
10710 +
10711 +#if defined(USE_UNDERLINE)
10712 +# define aes_set_key _aes_set_key
10713 +# define aes_encrypt _aes_encrypt
10714 +# define aes_decrypt _aes_decrypt
10715 +#endif
10716 +#if !defined(ALIGN32BYTES)
10717 +# define ALIGN32BYTES 32
10718 +#endif
10719 +
10720 + .file "aes-i586.S"
10721 + .globl aes_set_key
10722 + .globl aes_encrypt
10723 + .globl aes_decrypt
10724 +
10725 +#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words)
10726 +
10727 +// offsets to parameters with one register pushed onto stack
10728 +
10729 +#define ctx 8 // AES context structure
10730 +#define in_blk 12 // input byte array address parameter
10731 +#define out_blk 16 // output byte array address parameter
10732 +
10733 +// offsets in context structure
10734 +
10735 +#define nkey 0 // key length, size 4
10736 +#define nrnd 4 // number of rounds, size 4
10737 +#define ekey 8 // encryption key schedule base address, size 256
10738 +#define dkey 264 // decryption key schedule base address, size 256
10739 +
10740 +// This macro performs a forward encryption cycle. It is entered with
10741 +// the first previous round column values in %eax, %ebx, %esi and %edi and
10742 +// exits with the final values in the same registers.
10743 +
10744 +#define fwd_rnd(p1,p2) \
10745 + mov %ebx,(%esp) ;\
10746 + movzbl %al,%edx ;\
10747 + mov %eax,%ecx ;\
10748 + mov p2(%ebp),%eax ;\
10749 + mov %edi,4(%esp) ;\
10750 + mov p2+12(%ebp),%edi ;\
10751 + xor p1(,%edx,4),%eax ;\
10752 + movzbl %ch,%edx ;\
10753 + shr $16,%ecx ;\
10754 + mov p2+4(%ebp),%ebx ;\
10755 + xor p1+tlen(,%edx,4),%edi ;\
10756 + movzbl %cl,%edx ;\
10757 + movzbl %ch,%ecx ;\
10758 + xor p1+3*tlen(,%ecx,4),%ebx ;\
10759 + mov %esi,%ecx ;\
10760 + mov p1+2*tlen(,%edx,4),%esi ;\
10761 + movzbl %cl,%edx ;\
10762 + xor p1(,%edx,4),%esi ;\
10763 + movzbl %ch,%edx ;\
10764 + shr $16,%ecx ;\
10765 + xor p1+tlen(,%edx,4),%ebx ;\
10766 + movzbl %cl,%edx ;\
10767 + movzbl %ch,%ecx ;\
10768 + xor p1+2*tlen(,%edx,4),%eax ;\
10769 + mov (%esp),%edx ;\
10770 + xor p1+3*tlen(,%ecx,4),%edi ;\
10771 + movzbl %dl,%ecx ;\
10772 + xor p2+8(%ebp),%esi ;\
10773 + xor p1(,%ecx,4),%ebx ;\
10774 + movzbl %dh,%ecx ;\
10775 + shr $16,%edx ;\
10776 + xor p1+tlen(,%ecx,4),%eax ;\
10777 + movzbl %dl,%ecx ;\
10778 + movzbl %dh,%edx ;\
10779 + xor p1+2*tlen(,%ecx,4),%edi ;\
10780 + mov 4(%esp),%ecx ;\
10781 + xor p1+3*tlen(,%edx,4),%esi ;\
10782 + movzbl %cl,%edx ;\
10783 + xor p1(,%edx,4),%edi ;\
10784 + movzbl %ch,%edx ;\
10785 + shr $16,%ecx ;\
10786 + xor p1+tlen(,%edx,4),%esi ;\
10787 + movzbl %cl,%edx ;\
10788 + movzbl %ch,%ecx ;\
10789 + xor p1+2*tlen(,%edx,4),%ebx ;\
10790 + xor p1+3*tlen(,%ecx,4),%eax
10791 +
10792 +// This macro performs an inverse encryption cycle. It is entered with
10793 +// the first previous round column values in %eax, %ebx, %esi and %edi and
10794 +// exits with the final values in the same registers.
10795 +
10796 +#define inv_rnd(p1,p2) \
10797 + movzbl %al,%edx ;\
10798 + mov %ebx,(%esp) ;\
10799 + mov %eax,%ecx ;\
10800 + mov p2(%ebp),%eax ;\
10801 + mov %edi,4(%esp) ;\
10802 + mov p2+4(%ebp),%ebx ;\
10803 + xor p1(,%edx,4),%eax ;\
10804 + movzbl %ch,%edx ;\
10805 + shr $16,%ecx ;\
10806 + mov p2+12(%ebp),%edi ;\
10807 + xor p1+tlen(,%edx,4),%ebx ;\
10808 + movzbl %cl,%edx ;\
10809 + movzbl %ch,%ecx ;\
10810 + xor p1+3*tlen(,%ecx,4),%edi ;\
10811 + mov %esi,%ecx ;\
10812 + mov p1+2*tlen(,%edx,4),%esi ;\
10813 + movzbl %cl,%edx ;\
10814 + xor p1(,%edx,4),%esi ;\
10815 + movzbl %ch,%edx ;\
10816 + shr $16,%ecx ;\
10817 + xor p1+tlen(,%edx,4),%edi ;\
10818 + movzbl %cl,%edx ;\
10819 + movzbl %ch,%ecx ;\
10820 + xor p1+2*tlen(,%edx,4),%eax ;\
10821 + mov (%esp),%edx ;\
10822 + xor p1+3*tlen(,%ecx,4),%ebx ;\
10823 + movzbl %dl,%ecx ;\
10824 + xor p2+8(%ebp),%esi ;\
10825 + xor p1(,%ecx,4),%ebx ;\
10826 + movzbl %dh,%ecx ;\
10827 + shr $16,%edx ;\
10828 + xor p1+tlen(,%ecx,4),%esi ;\
10829 + movzbl %dl,%ecx ;\
10830 + movzbl %dh,%edx ;\
10831 + xor p1+2*tlen(,%ecx,4),%edi ;\
10832 + mov 4(%esp),%ecx ;\
10833 + xor p1+3*tlen(,%edx,4),%eax ;\
10834 + movzbl %cl,%edx ;\
10835 + xor p1(,%edx,4),%edi ;\
10836 + movzbl %ch,%edx ;\
10837 + shr $16,%ecx ;\
10838 + xor p1+tlen(,%edx,4),%eax ;\
10839 + movzbl %cl,%edx ;\
10840 + movzbl %ch,%ecx ;\
10841 + xor p1+2*tlen(,%edx,4),%ebx ;\
10842 + xor p1+3*tlen(,%ecx,4),%esi
10843 +
10844 +// AES (Rijndael) Encryption Subroutine
10845 +
10846 + .text
10847 + .align ALIGN32BYTES
10848 +aes_encrypt:
10849 + push %ebp
10850 + mov ctx(%esp),%ebp // pointer to context
10851 + mov in_blk(%esp),%ecx
10852 + push %ebx
10853 + push %esi
10854 + push %edi
10855 + mov nrnd(%ebp),%edx // number of rounds
10856 + lea ekey+16(%ebp),%ebp // key pointer
10857 +
10858 +// input four columns and xor in first round key
10859 +
10860 + mov (%ecx),%eax
10861 + mov 4(%ecx),%ebx
10862 + mov 8(%ecx),%esi
10863 + mov 12(%ecx),%edi
10864 + xor -16(%ebp),%eax
10865 + xor -12(%ebp),%ebx
10866 + xor -8(%ebp),%esi
10867 + xor -4(%ebp),%edi
10868 +
10869 + sub $8,%esp // space for register saves on stack
10870 +
10871 + sub $10,%edx
10872 + je aes_15
10873 + add $32,%ebp
10874 + sub $2,%edx
10875 + je aes_13
10876 + add $32,%ebp
10877 +
10878 + fwd_rnd(aes_ft_tab,-64) // 14 rounds for 256-bit key
10879 + fwd_rnd(aes_ft_tab,-48)
10880 +aes_13: fwd_rnd(aes_ft_tab,-32) // 12 rounds for 192-bit key
10881 + fwd_rnd(aes_ft_tab,-16)
10882 +aes_15: fwd_rnd(aes_ft_tab,0) // 10 rounds for 128-bit key
10883 + fwd_rnd(aes_ft_tab,16)
10884 + fwd_rnd(aes_ft_tab,32)
10885 + fwd_rnd(aes_ft_tab,48)
10886 + fwd_rnd(aes_ft_tab,64)
10887 + fwd_rnd(aes_ft_tab,80)
10888 + fwd_rnd(aes_ft_tab,96)
10889 + fwd_rnd(aes_ft_tab,112)
10890 + fwd_rnd(aes_ft_tab,128)
10891 + fwd_rnd(aes_fl_tab,144) // last round uses a different table
10892 +
10893 +// move final values to the output array.
10894 +
10895 + mov out_blk+20(%esp),%ebp
10896 + add $8,%esp
10897 + mov %eax,(%ebp)
10898 + mov %ebx,4(%ebp)
10899 + mov %esi,8(%ebp)
10900 + mov %edi,12(%ebp)
10901 + pop %edi
10902 + pop %esi
10903 + pop %ebx
10904 + pop %ebp
10905 + ret
10906 +
10907 +
10908 +// AES (Rijndael) Decryption Subroutine
10909 +
10910 + .align ALIGN32BYTES
10911 +aes_decrypt:
10912 + push %ebp
10913 + mov ctx(%esp),%ebp // pointer to context
10914 + mov in_blk(%esp),%ecx
10915 + push %ebx
10916 + push %esi
10917 + push %edi
10918 + mov nrnd(%ebp),%edx // number of rounds
10919 + lea dkey+16(%ebp),%ebp // key pointer
10920 +
10921 +// input four columns and xor in first round key
10922 +
10923 + mov (%ecx),%eax
10924 + mov 4(%ecx),%ebx
10925 + mov 8(%ecx),%esi
10926 + mov 12(%ecx),%edi
10927 + xor -16(%ebp),%eax
10928 + xor -12(%ebp),%ebx
10929 + xor -8(%ebp),%esi
10930 + xor -4(%ebp),%edi
10931 +
10932 + sub $8,%esp // space for register saves on stack
10933 +
10934 + sub $10,%edx
10935 + je aes_25
10936 + add $32,%ebp
10937 + sub $2,%edx
10938 + je aes_23
10939 + add $32,%ebp
10940 +
10941 + inv_rnd(aes_it_tab,-64) // 14 rounds for 256-bit key
10942 + inv_rnd(aes_it_tab,-48)
10943 +aes_23: inv_rnd(aes_it_tab,-32) // 12 rounds for 192-bit key
10944 + inv_rnd(aes_it_tab,-16)
10945 +aes_25: inv_rnd(aes_it_tab,0) // 10 rounds for 128-bit key
10946 + inv_rnd(aes_it_tab,16)
10947 + inv_rnd(aes_it_tab,32)
10948 + inv_rnd(aes_it_tab,48)
10949 + inv_rnd(aes_it_tab,64)
10950 + inv_rnd(aes_it_tab,80)
10951 + inv_rnd(aes_it_tab,96)
10952 + inv_rnd(aes_it_tab,112)
10953 + inv_rnd(aes_it_tab,128)
10954 + inv_rnd(aes_il_tab,144) // last round uses a different table
10955 +
10956 +// move final values to the output array.
10957 +
10958 + mov out_blk+20(%esp),%ebp
10959 + add $8,%esp
10960 + mov %eax,(%ebp)
10961 + mov %ebx,4(%ebp)
10962 + mov %esi,8(%ebp)
10963 + mov %edi,12(%ebp)
10964 + pop %edi
10965 + pop %esi
10966 + pop %ebx
10967 + pop %ebp
10968 + ret
10969 +
10970 +// AES (Rijndael) Key Schedule Subroutine
10971 +
10972 +// input/output parameters
10973 +
10974 +#define aes_cx 12 // AES context
10975 +#define in_key 16 // key input array address
10976 +#define key_ln 20 // key length, bytes (16,24,32) or bits (128,192,256)
10977 +#define ed_flg 24 // 0=create both encr/decr keys, 1=create encr key only
10978 +
10979 +// offsets for locals
10980 +
10981 +#define cnt -4
10982 +#define kpf -8
10983 +#define slen 8
10984 +
10985 +// This macro performs a column mixing operation on an input 32-bit
10986 +// word to give a 32-bit result. It uses each of the 4 bytes in the
10987 +// the input column to index 4 different tables of 256 32-bit words
10988 +// that are xored together to form the output value.
10989 +
10990 +#define mix_col(p1) \
10991 + movzbl %bl,%ecx ;\
10992 + mov p1(,%ecx,4),%eax ;\
10993 + movzbl %bh,%ecx ;\
10994 + ror $16,%ebx ;\
10995 + xor p1+tlen(,%ecx,4),%eax ;\
10996 + movzbl %bl,%ecx ;\
10997 + xor p1+2*tlen(,%ecx,4),%eax ;\
10998 + movzbl %bh,%ecx ;\
10999 + xor p1+3*tlen(,%ecx,4),%eax
11000 +
11001 +// Key Schedule Macros
11002 +
11003 +#define ksc4(p1) \
11004 + rol $24,%ebx ;\
11005 + mix_col(aes_fl_tab) ;\
11006 + ror $8,%ebx ;\
11007 + xor 4*p1+aes_rcon_tab,%eax ;\
11008 + xor %eax,%esi ;\
11009 + xor %esi,%ebp ;\
11010 + mov %esi,16*p1(%edi) ;\
11011 + mov %ebp,16*p1+4(%edi) ;\
11012 + xor %ebp,%edx ;\
11013 + xor %edx,%ebx ;\
11014 + mov %edx,16*p1+8(%edi) ;\
11015 + mov %ebx,16*p1+12(%edi)
11016 +
11017 +#define ksc6(p1) \
11018 + rol $24,%ebx ;\
11019 + mix_col(aes_fl_tab) ;\
11020 + ror $8,%ebx ;\
11021 + xor 4*p1+aes_rcon_tab,%eax ;\
11022 + xor 24*p1-24(%edi),%eax ;\
11023 + mov %eax,24*p1(%edi) ;\
11024 + xor 24*p1-20(%edi),%eax ;\
11025 + mov %eax,24*p1+4(%edi) ;\
11026 + xor %eax,%esi ;\
11027 + xor %esi,%ebp ;\
11028 + mov %esi,24*p1+8(%edi) ;\
11029 + mov %ebp,24*p1+12(%edi) ;\
11030 + xor %ebp,%edx ;\
11031 + xor %edx,%ebx ;\
11032 + mov %edx,24*p1+16(%edi) ;\
11033 + mov %ebx,24*p1+20(%edi)
11034 +
11035 +#define ksc8(p1) \
11036 + rol $24,%ebx ;\
11037 + mix_col(aes_fl_tab) ;\
11038 + ror $8,%ebx ;\
11039 + xor 4*p1+aes_rcon_tab,%eax ;\
11040 + xor 32*p1-32(%edi),%eax ;\
11041 + mov %eax,32*p1(%edi) ;\
11042 + xor 32*p1-28(%edi),%eax ;\
11043 + mov %eax,32*p1+4(%edi) ;\
11044 + xor 32*p1-24(%edi),%eax ;\
11045 + mov %eax,32*p1+8(%edi) ;\
11046 + xor 32*p1-20(%edi),%eax ;\
11047 + mov %eax,32*p1+12(%edi) ;\
11048 + push %ebx ;\
11049 + mov %eax,%ebx ;\
11050 + mix_col(aes_fl_tab) ;\
11051 + pop %ebx ;\
11052 + xor %eax,%esi ;\
11053 + xor %esi,%ebp ;\
11054 + mov %esi,32*p1+16(%edi) ;\
11055 + mov %ebp,32*p1+20(%edi) ;\
11056 + xor %ebp,%edx ;\
11057 + xor %edx,%ebx ;\
11058 + mov %edx,32*p1+24(%edi) ;\
11059 + mov %ebx,32*p1+28(%edi)
11060 +
11061 + .align ALIGN32BYTES
11062 +aes_set_key:
11063 + pushfl
11064 + push %ebp
11065 + mov %esp,%ebp
11066 + sub $slen,%esp
11067 + push %ebx
11068 + push %esi
11069 + push %edi
11070 +
11071 + mov aes_cx(%ebp),%edx // edx -> AES context
11072 +
11073 + mov key_ln(%ebp),%ecx // key length
11074 + cmpl $128,%ecx
11075 + jb aes_30
11076 + shr $3,%ecx
11077 +aes_30: cmpl $32,%ecx
11078 + je aes_32
11079 + cmpl $24,%ecx
11080 + je aes_32
11081 + mov $16,%ecx
11082 +aes_32: shr $2,%ecx
11083 + mov %ecx,nkey(%edx)
11084 +
11085 + lea 6(%ecx),%eax // 10/12/14 for 4/6/8 32-bit key length
11086 + mov %eax,nrnd(%edx)
11087 +
11088 + mov in_key(%ebp),%esi // key input array
11089 + lea ekey(%edx),%edi // key position in AES context
11090 + cld
11091 + push %ebp
11092 + mov %ecx,%eax // save key length in eax
11093 + rep ; movsl // words in the key schedule
11094 + mov -4(%esi),%ebx // put some values in registers
11095 + mov -8(%esi),%edx // to allow faster code
11096 + mov -12(%esi),%ebp
11097 + mov -16(%esi),%esi
11098 +
11099 + cmpl $4,%eax // jump on key size
11100 + je aes_36
11101 + cmpl $6,%eax
11102 + je aes_35
11103 +
11104 + ksc8(0)
11105 + ksc8(1)
11106 + ksc8(2)
11107 + ksc8(3)
11108 + ksc8(4)
11109 + ksc8(5)
11110 + ksc8(6)
11111 + jmp aes_37
11112 +aes_35: ksc6(0)
11113 + ksc6(1)
11114 + ksc6(2)
11115 + ksc6(3)
11116 + ksc6(4)
11117 + ksc6(5)
11118 + ksc6(6)
11119 + ksc6(7)
11120 + jmp aes_37
11121 +aes_36: ksc4(0)
11122 + ksc4(1)
11123 + ksc4(2)
11124 + ksc4(3)
11125 + ksc4(4)
11126 + ksc4(5)
11127 + ksc4(6)
11128 + ksc4(7)
11129 + ksc4(8)
11130 + ksc4(9)
11131 +aes_37: pop %ebp
11132 + mov aes_cx(%ebp),%edx // edx -> AES context
11133 + cmpl $0,ed_flg(%ebp)
11134 + jne aes_39
11135 +
11136 +// compile decryption key schedule from encryption schedule - reverse
11137 +// order and do mix_column operation on round keys except first and last
11138 +
11139 + mov nrnd(%edx),%eax // kt = cx->d_key + nc * cx->Nrnd
11140 + shl $2,%eax
11141 + lea dkey(%edx,%eax,4),%edi
11142 + lea ekey(%edx),%esi // kf = cx->e_key
11143 +
11144 + movsl // copy first round key (unmodified)
11145 + movsl
11146 + movsl
11147 + movsl
11148 + sub $32,%edi
11149 + movl $1,cnt(%ebp)
11150 +aes_38: // do mix column on each column of
11151 + lodsl // each round key
11152 + mov %eax,%ebx
11153 + mix_col(aes_im_tab)
11154 + stosl
11155 + lodsl
11156 + mov %eax,%ebx
11157 + mix_col(aes_im_tab)
11158 + stosl
11159 + lodsl
11160 + mov %eax,%ebx
11161 + mix_col(aes_im_tab)
11162 + stosl
11163 + lodsl
11164 + mov %eax,%ebx
11165 + mix_col(aes_im_tab)
11166 + stosl
11167 + sub $32,%edi
11168 +
11169 + incl cnt(%ebp)
11170 + mov cnt(%ebp),%eax
11171 + cmp nrnd(%edx),%eax
11172 + jb aes_38
11173 +
11174 + movsl // copy last round key (unmodified)
11175 + movsl
11176 + movsl
11177 + movsl
11178 +aes_39: pop %edi
11179 + pop %esi
11180 + pop %ebx
11181 + mov %ebp,%esp
11182 + pop %ebp
11183 + popfl
11184 + ret
11185 +
11186 +
11187 +// finite field multiplies by {02}, {04} and {08}
11188 +
11189 +#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b))
11190 +#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b))
11191 +#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b))
11192 +
11193 +// finite field multiplies required in table generation
11194 +
11195 +#define f3(x) (f2(x) ^ x)
11196 +#define f9(x) (f8(x) ^ x)
11197 +#define fb(x) (f8(x) ^ f2(x) ^ x)
11198 +#define fd(x) (f8(x) ^ f4(x) ^ x)
11199 +#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
11200 +
11201 +// These defines generate the forward table entries
11202 +
11203 +#define u0(x) ((f3(x) << 24) | (x << 16) | (x << 8) | f2(x))
11204 +#define u1(x) ((x << 24) | (x << 16) | (f2(x) << 8) | f3(x))
11205 +#define u2(x) ((x << 24) | (f2(x) << 16) | (f3(x) << 8) | x)
11206 +#define u3(x) ((f2(x) << 24) | (f3(x) << 16) | (x << 8) | x)
11207 +
11208 +// These defines generate the inverse table entries
11209 +
11210 +#define v0(x) ((fb(x) << 24) | (fd(x) << 16) | (f9(x) << 8) | fe(x))
11211 +#define v1(x) ((fd(x) << 24) | (f9(x) << 16) | (fe(x) << 8) | fb(x))
11212 +#define v2(x) ((f9(x) << 24) | (fe(x) << 16) | (fb(x) << 8) | fd(x))
11213 +#define v3(x) ((fe(x) << 24) | (fb(x) << 16) | (fd(x) << 8) | f9(x))
11214 +
11215 +// These defines generate entries for the last round tables
11216 +
11217 +#define w0(x) (x)
11218 +#define w1(x) (x << 8)
11219 +#define w2(x) (x << 16)
11220 +#define w3(x) (x << 24)
11221 +
11222 +// macro to generate inverse mix column tables (needed for the key schedule)
11223 +
11224 +#define im_data0(p1) \
11225 + .long p1(0x00),p1(0x01),p1(0x02),p1(0x03),p1(0x04),p1(0x05),p1(0x06),p1(0x07) ;\
11226 + .long p1(0x08),p1(0x09),p1(0x0a),p1(0x0b),p1(0x0c),p1(0x0d),p1(0x0e),p1(0x0f) ;\
11227 + .long p1(0x10),p1(0x11),p1(0x12),p1(0x13),p1(0x14),p1(0x15),p1(0x16),p1(0x17) ;\
11228 + .long p1(0x18),p1(0x19),p1(0x1a),p1(0x1b),p1(0x1c),p1(0x1d),p1(0x1e),p1(0x1f)
11229 +#define im_data1(p1) \
11230 + .long p1(0x20),p1(0x21),p1(0x22),p1(0x23),p1(0x24),p1(0x25),p1(0x26),p1(0x27) ;\
11231 + .long p1(0x28),p1(0x29),p1(0x2a),p1(0x2b),p1(0x2c),p1(0x2d),p1(0x2e),p1(0x2f) ;\
11232 + .long p1(0x30),p1(0x31),p1(0x32),p1(0x33),p1(0x34),p1(0x35),p1(0x36),p1(0x37) ;\
11233 + .long p1(0x38),p1(0x39),p1(0x3a),p1(0x3b),p1(0x3c),p1(0x3d),p1(0x3e),p1(0x3f)
11234 +#define im_data2(p1) \
11235 + .long p1(0x40),p1(0x41),p1(0x42),p1(0x43),p1(0x44),p1(0x45),p1(0x46),p1(0x47) ;\
11236 + .long p1(0x48),p1(0x49),p1(0x4a),p1(0x4b),p1(0x4c),p1(0x4d),p1(0x4e),p1(0x4f) ;\
11237 + .long p1(0x50),p1(0x51),p1(0x52),p1(0x53),p1(0x54),p1(0x55),p1(0x56),p1(0x57) ;\
11238 + .long p1(0x58),p1(0x59),p1(0x5a),p1(0x5b),p1(0x5c),p1(0x5d),p1(0x5e),p1(0x5f)
11239 +#define im_data3(p1) \
11240 + .long p1(0x60),p1(0x61),p1(0x62),p1(0x63),p1(0x64),p1(0x65),p1(0x66),p1(0x67) ;\
11241 + .long p1(0x68),p1(0x69),p1(0x6a),p1(0x6b),p1(0x6c),p1(0x6d),p1(0x6e),p1(0x6f) ;\
11242 + .long p1(0x70),p1(0x71),p1(0x72),p1(0x73),p1(0x74),p1(0x75),p1(0x76),p1(0x77) ;\
11243 + .long p1(0x78),p1(0x79),p1(0x7a),p1(0x7b),p1(0x7c),p1(0x7d),p1(0x7e),p1(0x7f)
11244 +#define im_data4(p1) \
11245 + .long p1(0x80),p1(0x81),p1(0x82),p1(0x83),p1(0x84),p1(0x85),p1(0x86),p1(0x87) ;\
11246 + .long p1(0x88),p1(0x89),p1(0x8a),p1(0x8b),p1(0x8c),p1(0x8d),p1(0x8e),p1(0x8f) ;\
11247 + .long p1(0x90),p1(0x91),p1(0x92),p1(0x93),p1(0x94),p1(0x95),p1(0x96),p1(0x97) ;\
11248 + .long p1(0x98),p1(0x99),p1(0x9a),p1(0x9b),p1(0x9c),p1(0x9d),p1(0x9e),p1(0x9f)
11249 +#define im_data5(p1) \
11250 + .long p1(0xa0),p1(0xa1),p1(0xa2),p1(0xa3),p1(0xa4),p1(0xa5),p1(0xa6),p1(0xa7) ;\
11251 + .long p1(0xa8),p1(0xa9),p1(0xaa),p1(0xab),p1(0xac),p1(0xad),p1(0xae),p1(0xaf) ;\
11252 + .long p1(0xb0),p1(0xb1),p1(0xb2),p1(0xb3),p1(0xb4),p1(0xb5),p1(0xb6),p1(0xb7) ;\
11253 + .long p1(0xb8),p1(0xb9),p1(0xba),p1(0xbb),p1(0xbc),p1(0xbd),p1(0xbe),p1(0xbf)
11254 +#define im_data6(p1) \
11255 + .long p1(0xc0),p1(0xc1),p1(0xc2),p1(0xc3),p1(0xc4),p1(0xc5),p1(0xc6),p1(0xc7) ;\
11256 + .long p1(0xc8),p1(0xc9),p1(0xca),p1(0xcb),p1(0xcc),p1(0xcd),p1(0xce),p1(0xcf) ;\
11257 + .long p1(0xd0),p1(0xd1),p1(0xd2),p1(0xd3),p1(0xd4),p1(0xd5),p1(0xd6),p1(0xd7) ;\
11258 + .long p1(0xd8),p1(0xd9),p1(0xda),p1(0xdb),p1(0xdc),p1(0xdd),p1(0xde),p1(0xdf)
11259 +#define im_data7(p1) \
11260 + .long p1(0xe0),p1(0xe1),p1(0xe2),p1(0xe3),p1(0xe4),p1(0xe5),p1(0xe6),p1(0xe7) ;\
11261 + .long p1(0xe8),p1(0xe9),p1(0xea),p1(0xeb),p1(0xec),p1(0xed),p1(0xee),p1(0xef) ;\
11262 + .long p1(0xf0),p1(0xf1),p1(0xf2),p1(0xf3),p1(0xf4),p1(0xf5),p1(0xf6),p1(0xf7) ;\
11263 + .long p1(0xf8),p1(0xf9),p1(0xfa),p1(0xfb),p1(0xfc),p1(0xfd),p1(0xfe),p1(0xff)
11264 +
11265 +// S-box data - 256 entries
11266 +
11267 +#define sb_data0(p1) \
11268 + .long p1(0x63),p1(0x7c),p1(0x77),p1(0x7b),p1(0xf2),p1(0x6b),p1(0x6f),p1(0xc5) ;\
11269 + .long p1(0x30),p1(0x01),p1(0x67),p1(0x2b),p1(0xfe),p1(0xd7),p1(0xab),p1(0x76) ;\
11270 + .long p1(0xca),p1(0x82),p1(0xc9),p1(0x7d),p1(0xfa),p1(0x59),p1(0x47),p1(0xf0) ;\
11271 + .long p1(0xad),p1(0xd4),p1(0xa2),p1(0xaf),p1(0x9c),p1(0xa4),p1(0x72),p1(0xc0)
11272 +#define sb_data1(p1) \
11273 + .long p1(0xb7),p1(0xfd),p1(0x93),p1(0x26),p1(0x36),p1(0x3f),p1(0xf7),p1(0xcc) ;\
11274 + .long p1(0x34),p1(0xa5),p1(0xe5),p1(0xf1),p1(0x71),p1(0xd8),p1(0x31),p1(0x15) ;\
11275 + .long p1(0x04),p1(0xc7),p1(0x23),p1(0xc3),p1(0x18),p1(0x96),p1(0x05),p1(0x9a) ;\
11276 + .long p1(0x07),p1(0x12),p1(0x80),p1(0xe2),p1(0xeb),p1(0x27),p1(0xb2),p1(0x75)
11277 +#define sb_data2(p1) \
11278 + .long p1(0x09),p1(0x83),p1(0x2c),p1(0x1a),p1(0x1b),p1(0x6e),p1(0x5a),p1(0xa0) ;\
11279 + .long p1(0x52),p1(0x3b),p1(0xd6),p1(0xb3),p1(0x29),p1(0xe3),p1(0x2f),p1(0x84) ;\
11280 + .long p1(0x53),p1(0xd1),p1(0x00),p1(0xed),p1(0x20),p1(0xfc),p1(0xb1),p1(0x5b) ;\
11281 + .long p1(0x6a),p1(0xcb),p1(0xbe),p1(0x39),p1(0x4a),p1(0x4c),p1(0x58),p1(0xcf)
11282 +#define sb_data3(p1) \
11283 + .long p1(0xd0),p1(0xef),p1(0xaa),p1(0xfb),p1(0x43),p1(0x4d),p1(0x33),p1(0x85) ;\
11284 + .long p1(0x45),p1(0xf9),p1(0x02),p1(0x7f),p1(0x50),p1(0x3c),p1(0x9f),p1(0xa8) ;\
11285 + .long p1(0x51),p1(0xa3),p1(0x40),p1(0x8f),p1(0x92),p1(0x9d),p1(0x38),p1(0xf5) ;\
11286 + .long p1(0xbc),p1(0xb6),p1(0xda),p1(0x21),p1(0x10),p1(0xff),p1(0xf3),p1(0xd2)
11287 +#define sb_data4(p1) \
11288 + .long p1(0xcd),p1(0x0c),p1(0x13),p1(0xec),p1(0x5f),p1(0x97),p1(0x44),p1(0x17) ;\
11289 + .long p1(0xc4),p1(0xa7),p1(0x7e),p1(0x3d),p1(0x64),p1(0x5d),p1(0x19),p1(0x73) ;\
11290 + .long p1(0x60),p1(0x81),p1(0x4f),p1(0xdc),p1(0x22),p1(0x2a),p1(0x90),p1(0x88) ;\
11291 + .long p1(0x46),p1(0xee),p1(0xb8),p1(0x14),p1(0xde),p1(0x5e),p1(0x0b),p1(0xdb)
11292 +#define sb_data5(p1) \
11293 + .long p1(0xe0),p1(0x32),p1(0x3a),p1(0x0a),p1(0x49),p1(0x06),p1(0x24),p1(0x5c) ;\
11294 + .long p1(0xc2),p1(0xd3),p1(0xac),p1(0x62),p1(0x91),p1(0x95),p1(0xe4),p1(0x79) ;\
11295 + .long p1(0xe7),p1(0xc8),p1(0x37),p1(0x6d),p1(0x8d),p1(0xd5),p1(0x4e),p1(0xa9) ;\
11296 + .long p1(0x6c),p1(0x56),p1(0xf4),p1(0xea),p1(0x65),p1(0x7a),p1(0xae),p1(0x08)
11297 +#define sb_data6(p1) \
11298 + .long p1(0xba),p1(0x78),p1(0x25),p1(0x2e),p1(0x1c),p1(0xa6),p1(0xb4),p1(0xc6) ;\
11299 + .long p1(0xe8),p1(0xdd),p1(0x74),p1(0x1f),p1(0x4b),p1(0xbd),p1(0x8b),p1(0x8a) ;\
11300 + .long p1(0x70),p1(0x3e),p1(0xb5),p1(0x66),p1(0x48),p1(0x03),p1(0xf6),p1(0x0e) ;\
11301 + .long p1(0x61),p1(0x35),p1(0x57),p1(0xb9),p1(0x86),p1(0xc1),p1(0x1d),p1(0x9e)
11302 +#define sb_data7(p1) \
11303 + .long p1(0xe1),p1(0xf8),p1(0x98),p1(0x11),p1(0x69),p1(0xd9),p1(0x8e),p1(0x94) ;\
11304 + .long p1(0x9b),p1(0x1e),p1(0x87),p1(0xe9),p1(0xce),p1(0x55),p1(0x28),p1(0xdf) ;\
11305 + .long p1(0x8c),p1(0xa1),p1(0x89),p1(0x0d),p1(0xbf),p1(0xe6),p1(0x42),p1(0x68) ;\
11306 + .long p1(0x41),p1(0x99),p1(0x2d),p1(0x0f),p1(0xb0),p1(0x54),p1(0xbb),p1(0x16)
11307 +
11308 +// Inverse S-box data - 256 entries
11309 +
11310 +#define ib_data0(p1) \
11311 + .long p1(0x52),p1(0x09),p1(0x6a),p1(0xd5),p1(0x30),p1(0x36),p1(0xa5),p1(0x38) ;\
11312 + .long p1(0xbf),p1(0x40),p1(0xa3),p1(0x9e),p1(0x81),p1(0xf3),p1(0xd7),p1(0xfb) ;\
11313 + .long p1(0x7c),p1(0xe3),p1(0x39),p1(0x82),p1(0x9b),p1(0x2f),p1(0xff),p1(0x87) ;\
11314 + .long p1(0x34),p1(0x8e),p1(0x43),p1(0x44),p1(0xc4),p1(0xde),p1(0xe9),p1(0xcb)
11315 +#define ib_data1(p1) \
11316 + .long p1(0x54),p1(0x7b),p1(0x94),p1(0x32),p1(0xa6),p1(0xc2),p1(0x23),p1(0x3d) ;\
11317 + .long p1(0xee),p1(0x4c),p1(0x95),p1(0x0b),p1(0x42),p1(0xfa),p1(0xc3),p1(0x4e) ;\
11318 + .long p1(0x08),p1(0x2e),p1(0xa1),p1(0x66),p1(0x28),p1(0xd9),p1(0x24),p1(0xb2) ;\
11319 + .long p1(0x76),p1(0x5b),p1(0xa2),p1(0x49),p1(0x6d),p1(0x8b),p1(0xd1),p1(0x25)
11320 +#define ib_data2(p1) \
11321 + .long p1(0x72),p1(0xf8),p1(0xf6),p1(0x64),p1(0x86),p1(0x68),p1(0x98),p1(0x16) ;\
11322 + .long p1(0xd4),p1(0xa4),p1(0x5c),p1(0xcc),p1(0x5d),p1(0x65),p1(0xb6),p1(0x92) ;\
11323 + .long p1(0x6c),p1(0x70),p1(0x48),p1(0x50),p1(0xfd),p1(0xed),p1(0xb9),p1(0xda) ;\
11324 + .long p1(0x5e),p1(0x15),p1(0x46),p1(0x57),p1(0xa7),p1(0x8d),p1(0x9d),p1(0x84)
11325 +#define ib_data3(p1) \
11326 + .long p1(0x90),p1(0xd8),p1(0xab),p1(0x00),p1(0x8c),p1(0xbc),p1(0xd3),p1(0x0a) ;\
11327 + .long p1(0xf7),p1(0xe4),p1(0x58),p1(0x05),p1(0xb8),p1(0xb3),p1(0x45),p1(0x06) ;\
11328 + .long p1(0xd0),p1(0x2c),p1(0x1e),p1(0x8f),p1(0xca),p1(0x3f),p1(0x0f),p1(0x02) ;\
11329 + .long p1(0xc1),p1(0xaf),p1(0xbd),p1(0x03),p1(0x01),p1(0x13),p1(0x8a),p1(0x6b)
11330 +#define ib_data4(p1) \
11331 + .long p1(0x3a),p1(0x91),p1(0x11),p1(0x41),p1(0x4f),p1(0x67),p1(0xdc),p1(0xea) ;\
11332 + .long p1(0x97),p1(0xf2),p1(0xcf),p1(0xce),p1(0xf0),p1(0xb4),p1(0xe6),p1(0x73) ;\
11333 + .long p1(0x96),p1(0xac),p1(0x74),p1(0x22),p1(0xe7),p1(0xad),p1(0x35),p1(0x85) ;\
11334 + .long p1(0xe2),p1(0xf9),p1(0x37),p1(0xe8),p1(0x1c),p1(0x75),p1(0xdf),p1(0x6e)
11335 +#define ib_data5(p1) \
11336 + .long p1(0x47),p1(0xf1),p1(0x1a),p1(0x71),p1(0x1d),p1(0x29),p1(0xc5),p1(0x89) ;\
11337 + .long p1(0x6f),p1(0xb7),p1(0x62),p1(0x0e),p1(0xaa),p1(0x18),p1(0xbe),p1(0x1b) ;\
11338 + .long p1(0xfc),p1(0x56),p1(0x3e),p1(0x4b),p1(0xc6),p1(0xd2),p1(0x79),p1(0x20) ;\
11339 + .long p1(0x9a),p1(0xdb),p1(0xc0),p1(0xfe),p1(0x78),p1(0xcd),p1(0x5a),p1(0xf4)
11340 +#define ib_data6(p1) \
11341 + .long p1(0x1f),p1(0xdd),p1(0xa8),p1(0x33),p1(0x88),p1(0x07),p1(0xc7),p1(0x31) ;\
11342 + .long p1(0xb1),p1(0x12),p1(0x10),p1(0x59),p1(0x27),p1(0x80),p1(0xec),p1(0x5f) ;\
11343 + .long p1(0x60),p1(0x51),p1(0x7f),p1(0xa9),p1(0x19),p1(0xb5),p1(0x4a),p1(0x0d) ;\
11344 + .long p1(0x2d),p1(0xe5),p1(0x7a),p1(0x9f),p1(0x93),p1(0xc9),p1(0x9c),p1(0xef)
11345 +#define ib_data7(p1) \
11346 + .long p1(0xa0),p1(0xe0),p1(0x3b),p1(0x4d),p1(0xae),p1(0x2a),p1(0xf5),p1(0xb0) ;\
11347 + .long p1(0xc8),p1(0xeb),p1(0xbb),p1(0x3c),p1(0x83),p1(0x53),p1(0x99),p1(0x61) ;\
11348 + .long p1(0x17),p1(0x2b),p1(0x04),p1(0x7e),p1(0xba),p1(0x77),p1(0xd6),p1(0x26) ;\
11349 + .long p1(0xe1),p1(0x69),p1(0x14),p1(0x63),p1(0x55),p1(0x21),p1(0x0c),p1(0x7d)
11350 +
11351 +// The rcon_table (needed for the key schedule)
11352 +//
11353 +// Here is original Dr Brian Gladman's source code:
11354 +// _rcon_tab:
11355 +// %assign x 1
11356 +// %rep 29
11357 +// dd x
11358 +// %assign x f2(x)
11359 +// %endrep
11360 +//
11361 +// Here is precomputed output (it's more portable this way):
11362 +
11363 + .align ALIGN32BYTES
11364 +aes_rcon_tab:
11365 + .long 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
11366 + .long 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f
11367 + .long 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4
11368 + .long 0xb3,0x7d,0xfa,0xef,0xc5
11369 +
11370 +// The forward xor tables
11371 +
11372 + .align ALIGN32BYTES
11373 +aes_ft_tab:
11374 + sb_data0(u0)
11375 + sb_data1(u0)
11376 + sb_data2(u0)
11377 + sb_data3(u0)
11378 + sb_data4(u0)
11379 + sb_data5(u0)
11380 + sb_data6(u0)
11381 + sb_data7(u0)
11382 +
11383 + sb_data0(u1)
11384 + sb_data1(u1)
11385 + sb_data2(u1)
11386 + sb_data3(u1)
11387 + sb_data4(u1)
11388 + sb_data5(u1)
11389 + sb_data6(u1)
11390 + sb_data7(u1)
11391 +
11392 + sb_data0(u2)
11393 + sb_data1(u2)
11394 + sb_data2(u2)
11395 + sb_data3(u2)
11396 + sb_data4(u2)
11397 + sb_data5(u2)
11398 + sb_data6(u2)
11399 + sb_data7(u2)
11400 +
11401 + sb_data0(u3)
11402 + sb_data1(u3)
11403 + sb_data2(u3)
11404 + sb_data3(u3)
11405 + sb_data4(u3)
11406 + sb_data5(u3)
11407 + sb_data6(u3)
11408 + sb_data7(u3)
11409 +
11410 + .align ALIGN32BYTES
11411 +aes_fl_tab:
11412 + sb_data0(w0)
11413 + sb_data1(w0)
11414 + sb_data2(w0)
11415 + sb_data3(w0)
11416 + sb_data4(w0)
11417 + sb_data5(w0)
11418 + sb_data6(w0)
11419 + sb_data7(w0)
11420 +
11421 + sb_data0(w1)
11422 + sb_data1(w1)
11423 + sb_data2(w1)
11424 + sb_data3(w1)
11425 + sb_data4(w1)
11426 + sb_data5(w1)
11427 + sb_data6(w1)
11428 + sb_data7(w1)
11429 +
11430 + sb_data0(w2)
11431 + sb_data1(w2)
11432 + sb_data2(w2)
11433 + sb_data3(w2)
11434 + sb_data4(w2)
11435 + sb_data5(w2)
11436 + sb_data6(w2)
11437 + sb_data7(w2)
11438 +
11439 + sb_data0(w3)
11440 + sb_data1(w3)
11441 + sb_data2(w3)
11442 + sb_data3(w3)
11443 + sb_data4(w3)
11444 + sb_data5(w3)
11445 + sb_data6(w3)
11446 + sb_data7(w3)
11447 +
11448 +// The inverse xor tables
11449 +
11450 + .align ALIGN32BYTES
11451 +aes_it_tab:
11452 + ib_data0(v0)
11453 + ib_data1(v0)
11454 + ib_data2(v0)
11455 + ib_data3(v0)
11456 + ib_data4(v0)
11457 + ib_data5(v0)
11458 + ib_data6(v0)
11459 + ib_data7(v0)
11460 +
11461 + ib_data0(v1)
11462 + ib_data1(v1)
11463 + ib_data2(v1)
11464 + ib_data3(v1)
11465 + ib_data4(v1)
11466 + ib_data5(v1)
11467 + ib_data6(v1)
11468 + ib_data7(v1)
11469 +
11470 + ib_data0(v2)
11471 + ib_data1(v2)
11472 + ib_data2(v2)
11473 + ib_data3(v2)
11474 + ib_data4(v2)
11475 + ib_data5(v2)
11476 + ib_data6(v2)
11477 + ib_data7(v2)
11478 +
11479 + ib_data0(v3)
11480 + ib_data1(v3)
11481 + ib_data2(v3)
11482 + ib_data3(v3)
11483 + ib_data4(v3)
11484 + ib_data5(v3)
11485 + ib_data6(v3)
11486 + ib_data7(v3)
11487 +
11488 + .align ALIGN32BYTES
11489 +aes_il_tab:
11490 + ib_data0(w0)
11491 + ib_data1(w0)
11492 + ib_data2(w0)
11493 + ib_data3(w0)
11494 + ib_data4(w0)
11495 + ib_data5(w0)
11496 + ib_data6(w0)
11497 + ib_data7(w0)
11498 +
11499 + ib_data0(w1)
11500 + ib_data1(w1)
11501 + ib_data2(w1)
11502 + ib_data3(w1)
11503 + ib_data4(w1)
11504 + ib_data5(w1)
11505 + ib_data6(w1)
11506 + ib_data7(w1)
11507 +
11508 + ib_data0(w2)
11509 + ib_data1(w2)
11510 + ib_data2(w2)
11511 + ib_data3(w2)
11512 + ib_data4(w2)
11513 + ib_data5(w2)
11514 + ib_data6(w2)
11515 + ib_data7(w2)
11516 +
11517 + ib_data0(w3)
11518 + ib_data1(w3)
11519 + ib_data2(w3)
11520 + ib_data3(w3)
11521 + ib_data4(w3)
11522 + ib_data5(w3)
11523 + ib_data6(w3)
11524 + ib_data7(w3)
11525 +
11526 +// The inverse mix column tables
11527 +
11528 + .align ALIGN32BYTES
11529 +aes_im_tab:
11530 + im_data0(v0)
11531 + im_data1(v0)
11532 + im_data2(v0)
11533 + im_data3(v0)
11534 + im_data4(v0)
11535 + im_data5(v0)
11536 + im_data6(v0)
11537 + im_data7(v0)
11538 +
11539 + im_data0(v1)
11540 + im_data1(v1)
11541 + im_data2(v1)
11542 + im_data3(v1)
11543 + im_data4(v1)
11544 + im_data5(v1)
11545 + im_data6(v1)
11546 + im_data7(v1)
11547 +
11548 + im_data0(v2)
11549 + im_data1(v2)
11550 + im_data2(v2)
11551 + im_data3(v2)
11552 + im_data4(v2)
11553 + im_data5(v2)
11554 + im_data6(v2)
11555 + im_data7(v2)
11556 +
11557 + im_data0(v3)
11558 + im_data1(v3)
11559 + im_data2(v3)
11560 + im_data3(v3)
11561 + im_data4(v3)
11562 + im_data5(v3)
11563 + im_data6(v3)
11564 + im_data7(v3)
11565 --- /dev/null Tue Mar 11 13:02:56 2003
11566 +++ linux/net/ipsec/aes/aes.c Mon Feb 9 13:51:03 2004
11567 @@ -0,0 +1,1415 @@
11568 +// I retain copyright in this code but I encourage its free use provided
11569 +// that I don't carry any responsibility for the results. I am especially
11570 +// happy to see it used in free and open source software. If you do use
11571 +// it I would appreciate an acknowledgement of its origin in the code or
11572 +// the product that results and I would also appreciate knowing a little
11573 +// about the use to which it is being put. I am grateful to Frank Yellin
11574 +// for some ideas that are used in this implementation.
11575 +//
11576 +// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
11577 +//
11578 +// This is an implementation of the AES encryption algorithm (Rijndael)
11579 +// designed by Joan Daemen and Vincent Rijmen. This version is designed
11580 +// to provide both fixed and dynamic block and key lengths and can also
11581 +// run with either big or little endian internal byte order (see aes.h).
11582 +// It inputs block and key lengths in bytes with the legal values being
11583 +// 16, 24 and 32.
11584 +
11585 +/*
11586 + * Modified by Jari Ruusu, May 1 2001
11587 + * - Fixed some compile warnings, code was ok but gcc warned anyway.
11588 + * - Changed basic types: byte -> unsigned char, word -> u_int32_t
11589 + * - Major name space cleanup: Names visible to outside now begin
11590 + * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
11591 + * - Removed C++ and DLL support as part of name space cleanup.
11592 + * - Eliminated unnecessary recomputation of tables. (actual bug fix)
11593 + * - Merged precomputed constant tables to aes.c file.
11594 + * - Removed data alignment restrictions for portability reasons.
11595 + * - Made block and key lengths accept bit count (128/192/256)
11596 + * as well byte count (16/24/32).
11597 + * - Removed all error checks. This change also eliminated the need
11598 + * to preinitialize the context struct to zero.
11599 + * - Removed some totally unused constants.
11600 + */
11601 +
11602 +#include "crypto/aes.h"
11603 +
11604 +// CONFIGURATION OPTIONS (see also aes.h)
11605 +//
11606 +// 1. Define UNROLL for full loop unrolling in encryption and decryption.
11607 +// 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption.
11608 +// 3. Define FIXED_TABLES for compiled rather than dynamic tables.
11609 +// 4. Define FF_TABLES to use tables for field multiplies and inverses.
11610 +// Do not enable this without understanding stack space requirements.
11611 +// 5. Define ARRAYS to use arrays to hold the local state block. If this
11612 +// is not defined, individually declared 32-bit words are used.
11613 +// 6. Define FAST_VARIABLE if a high speed variable block implementation
11614 +// is needed (essentially three separate fixed block size code sequences)
11615 +// 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven
11616 +// version using 1 table (2 kbytes of table space) or 4 tables (8
11617 +// kbytes of table space) for higher speed.
11618 +// 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed
11619 +// increase by using tables for the last rounds but with more table
11620 +// space (2 or 8 kbytes extra).
11621 +// 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but
11622 +// slower version is provided.
11623 +// 10. If fast decryption key scheduling is needed define ONE_IM_TABLE
11624 +// or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra).
11625 +
11626 +#define UNROLL
11627 +//#define PARTIAL_UNROLL
11628 +
11629 +#define FIXED_TABLES
11630 +//#define FF_TABLES
11631 +//#define ARRAYS
11632 +#define FAST_VARIABLE
11633 +
11634 +//#define ONE_TABLE
11635 +#define FOUR_TABLES
11636 +
11637 +//#define ONE_LR_TABLE
11638 +#define FOUR_LR_TABLES
11639 +
11640 +//#define ONE_IM_TABLE
11641 +#define FOUR_IM_TABLES
11642 +
11643 +#if defined(UNROLL) && defined (PARTIAL_UNROLL)
11644 +#error both UNROLL and PARTIAL_UNROLL are defined
11645 +#endif
11646 +
11647 +#if defined(ONE_TABLE) && defined (FOUR_TABLES)
11648 +#error both ONE_TABLE and FOUR_TABLES are defined
11649 +#endif
11650 +
11651 +#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES)
11652 +#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined
11653 +#endif
11654 +
11655 +#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES)
11656 +#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined
11657 +#endif
11658 +
11659 +#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32
11660 +#error an illegal block size has been specified
11661 +#endif
11662 +
11663 +// upr(x,n): rotates bytes within words by n positions, moving bytes
11664 +// to higher index positions with wrap around into low positions
11665 +// ups(x,n): moves bytes by n positions to higher index positions in
11666 +// words but without wrap around
11667 +// bval(x,n): extracts a byte from a word
11668 +
11669 +#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n))))
11670 +#define ups(x,n) ((x) << 8 * (n))
11671 +#define bval(x,n) ((unsigned char)((x) >> 8 * (n)))
11672 +#define bytes2word(b0, b1, b2, b3) \
11673 + ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0))
11674 +
11675 +
11676 +/* little endian processor without data alignment restrictions: AES_LE_OK */
11677 +/* original code: i386 */
11678 +#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386)
11679 +#define AES_LE_OK 1
11680 +/* added (tested): alpha --jjo */
11681 +#elif defined(__alpha__)|| defined (__alpha)
11682 +#define AES_LE_OK 1
11683 +/* added (tested): ia64 --jjo */
11684 +#elif defined(__ia64__)|| defined (__ia64)
11685 +#define AES_LE_OK 1
11686 +#endif
11687 +
11688 +#ifdef AES_LE_OK
11689 +/* little endian processor without data alignment restrictions */
11690 +#define word_in(x) *(u_int32_t*)(x)
11691 +#define const_word_in(x) *(const u_int32_t*)(x)
11692 +#define word_out(x,v) *(u_int32_t*)(x) = (v)
11693 +#define const_word_out(x,v) *(const u_int32_t*)(x) = (v)
11694 +#else
11695 +/* slower but generic big endian or with data alignment restrictions */
11696 +/* some additional "const" touches to stop "gcc -Wcast-qual" complains --jjo */
11697 +#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))
11698 +#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))
11699 +#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)
11700 +#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)
11701 +#endif
11702 +
11703 +// Disable at least some poor combinations of options
11704 +
11705 +#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
11706 +#define FIXED_TABLES
11707 +#undef UNROLL
11708 +#undef ONE_LR_TABLE
11709 +#undef FOUR_LR_TABLES
11710 +#undef ONE_IM_TABLE
11711 +#undef FOUR_IM_TABLES
11712 +#elif !defined(FOUR_TABLES)
11713 +#ifdef FOUR_LR_TABLES
11714 +#undef FOUR_LR_TABLES
11715 +#define ONE_LR_TABLE
11716 +#endif
11717 +#ifdef FOUR_IM_TABLES
11718 +#undef FOUR_IM_TABLES
11719 +#define ONE_IM_TABLE
11720 +#endif
11721 +#elif !defined(AES_BLOCK_SIZE)
11722 +#if defined(UNROLL)
11723 +#define PARTIAL_UNROLL
11724 +#undef UNROLL
11725 +#endif
11726 +#endif
11727 +
11728 +// the finite field modular polynomial and elements
11729 +
11730 +#define ff_poly 0x011b
11731 +#define ff_hi 0x80
11732 +
11733 +// multiply four bytes in GF(2^8) by 'x' {02} in parallel
11734 +
11735 +#define m1 0x80808080
11736 +#define m2 0x7f7f7f7f
11737 +#define m3 0x0000001b
11738 +#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3))
11739 +
11740 +// The following defines provide alternative definitions of FFmulX that might
11741 +// give improved performance if a fast 32-bit multiply is not available. Note
11742 +// that a temporary variable u needs to be defined where FFmulX is used.
11743 +
11744 +// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
11745 +// #define m4 0x1b1b1b1b
11746 +// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
11747 +
11748 +// perform column mix operation on four bytes in parallel
11749 +
11750 +#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1))
11751 +
11752 +#if defined(FIXED_TABLES)
11753 +
11754 +// the S-Box table
11755 +
11756 +static const unsigned char s_box[256] =
11757 +{
11758 + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
11759 + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
11760 + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
11761 + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
11762 + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
11763 + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
11764 + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
11765 + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
11766 + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
11767 + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
11768 + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
11769 + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
11770 + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
11771 + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
11772 + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
11773 + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
11774 + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
11775 + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
11776 + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
11777 + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
11778 + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
11779 + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
11780 + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
11781 + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
11782 + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
11783 + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
11784 + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
11785 + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
11786 + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
11787 + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
11788 + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
11789 + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
11790 +};
11791 +
11792 +// the inverse S-Box table
11793 +
11794 +static const unsigned char inv_s_box[256] =
11795 +{
11796 + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
11797 + 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
11798 + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
11799 + 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
11800 + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
11801 + 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
11802 + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
11803 + 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
11804 + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
11805 + 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
11806 + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
11807 + 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
11808 + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
11809 + 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
11810 + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
11811 + 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
11812 + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
11813 + 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
11814 + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
11815 + 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
11816 + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
11817 + 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
11818 + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
11819 + 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
11820 + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
11821 + 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
11822 + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
11823 + 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
11824 + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
11825 + 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
11826 + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
11827 + 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
11828 +};
11829 +
11830 +#define w0(p) 0x000000##p
11831 +
11832 +// Number of elements required in this table for different
11833 +// block and key lengths is:
11834 +//
11835 +// Nk = 4 6 8
11836 +// ----------
11837 +// Nb = 4 | 10 8 7
11838 +// 6 | 19 12 11
11839 +// 8 | 29 19 14
11840 +//
11841 +// this table can be a table of bytes if the key schedule
11842 +// code is adjusted accordingly
11843 +
11844 +static const u_int32_t rcon_tab[29] =
11845 +{
11846 + w0(01), w0(02), w0(04), w0(08),
11847 + w0(10), w0(20), w0(40), w0(80),
11848 + w0(1b), w0(36), w0(6c), w0(d8),
11849 + w0(ab), w0(4d), w0(9a), w0(2f),
11850 + w0(5e), w0(bc), w0(63), w0(c6),
11851 + w0(97), w0(35), w0(6a), w0(d4),
11852 + w0(b3), w0(7d), w0(fa), w0(ef),
11853 + w0(c5)
11854 +};
11855 +
11856 +#undef w0
11857 +
11858 +#define r0(p,q,r,s) 0x##p##q##r##s
11859 +#define r1(p,q,r,s) 0x##q##r##s##p
11860 +#define r2(p,q,r,s) 0x##r##s##p##q
11861 +#define r3(p,q,r,s) 0x##s##p##q##r
11862 +#define w0(p) 0x000000##p
11863 +#define w1(p) 0x0000##p##00
11864 +#define w2(p) 0x00##p##0000
11865 +#define w3(p) 0x##p##000000
11866 +
11867 +#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES))
11868 +
11869 +// data for forward tables (other than last round)
11870 +
11871 +#define f_table \
11872 + r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\
11873 + r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\
11874 + r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\
11875 + r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\
11876 + r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\
11877 + r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\
11878 + r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\
11879 + r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\
11880 + r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\
11881 + r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\
11882 + r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\
11883 + r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\
11884 + r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\
11885 + r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\
11886 + r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\
11887 + r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\
11888 + r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\
11889 + r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\
11890 + r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\
11891 + r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\
11892 + r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\
11893 + r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\
11894 + r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\
11895 + r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\
11896 + r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\
11897 + r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\
11898 + r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\
11899 + r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\
11900 + r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\
11901 + r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\
11902 + r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\
11903 + r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\
11904 + r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\
11905 + r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\
11906 + r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\
11907 + r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\
11908 + r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\
11909 + r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\
11910 + r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\
11911 + r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\
11912 + r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\
11913 + r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\
11914 + r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\
11915 + r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\
11916 + r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\
11917 + r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\
11918 + r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\
11919 + r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\
11920 + r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\
11921 + r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\
11922 + r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\
11923 + r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\
11924 + r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\
11925 + r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\
11926 + r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\
11927 + r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\
11928 + r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\
11929 + r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\
11930 + r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\
11931 + r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\
11932 + r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\
11933 + r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\
11934 + r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\
11935 + r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c)
11936 +
11937 +// data for inverse tables (other than last round)
11938 +
11939 +#define i_table \
11940 + r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\
11941 + r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\
11942 + r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\
11943 + r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\
11944 + r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\
11945 + r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\
11946 + r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\
11947 + r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\
11948 + r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\
11949 + r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\
11950 + r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\
11951 + r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\
11952 + r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\
11953 + r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\
11954 + r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\
11955 + r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\
11956 + r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\
11957 + r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\
11958 + r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\
11959 + r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\
11960 + r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\
11961 + r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\
11962 + r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\
11963 + r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\
11964 + r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\
11965 + r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\
11966 + r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\
11967 + r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\
11968 + r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\
11969 + r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\
11970 + r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\
11971 + r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\
11972 + r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\
11973 + r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\
11974 + r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\
11975 + r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\
11976 + r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\
11977 + r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\
11978 + r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\
11979 + r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\
11980 + r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\
11981 + r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\
11982 + r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\
11983 + r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\
11984 + r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\
11985 + r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\
11986 + r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\
11987 + r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\
11988 + r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\
11989 + r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\
11990 + r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\
11991 + r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\
11992 + r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\
11993 + r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\
11994 + r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\
11995 + r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\
11996 + r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\
11997 + r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\
11998 + r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\
11999 + r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\
12000 + r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\
12001 + r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\
12002 + r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\
12003 + r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0)
12004 +
12005 +// generate the required tables in the desired endian format
12006 +
12007 +#undef r
12008 +#define r r0
12009 +
12010 +#if defined(ONE_TABLE)
12011 +static const u_int32_t ft_tab[256] =
12012 + { f_table };
12013 +#elif defined(FOUR_TABLES)
12014 +static const u_int32_t ft_tab[4][256] =
12015 +{ { f_table },
12016 +#undef r
12017 +#define r r1
12018 + { f_table },
12019 +#undef r
12020 +#define r r2
12021 + { f_table },
12022 +#undef r
12023 +#define r r3
12024 + { f_table }
12025 +};
12026 +#endif
12027 +
12028 +#undef r
12029 +#define r r0
12030 +#if defined(ONE_TABLE)
12031 +static const u_int32_t it_tab[256] =
12032 + { i_table };
12033 +#elif defined(FOUR_TABLES)
12034 +static const u_int32_t it_tab[4][256] =
12035 +{ { i_table },
12036 +#undef r
12037 +#define r r1
12038 + { i_table },
12039 +#undef r
12040 +#define r r2
12041 + { i_table },
12042 +#undef r
12043 +#define r r3
12044 + { i_table }
12045 +};
12046 +#endif
12047 +
12048 +#endif
12049 +
12050 +#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES))
12051 +
12052 +// data for inverse tables (last round)
12053 +
12054 +#define li_table \
12055 + w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\
12056 + w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\
12057 + w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\
12058 + w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\
12059 + w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\
12060 + w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\
12061 + w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\
12062 + w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\
12063 + w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\
12064 + w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\
12065 + w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\
12066 + w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\
12067 + w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\
12068 + w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\
12069 + w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\
12070 + w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\
12071 + w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\
12072 + w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\
12073 + w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\
12074 + w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\
12075 + w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\
12076 + w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\
12077 + w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\
12078 + w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\
12079 + w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\
12080 + w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\
12081 + w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\
12082 + w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\
12083 + w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\
12084 + w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\
12085 + w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\
12086 + w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d),
12087 +
12088 +// generate the required tables in the desired endian format
12089 +
12090 +#undef r
12091 +#define r(p,q,r,s) w0(q)
12092 +#if defined(ONE_LR_TABLE)
12093 +static const u_int32_t fl_tab[256] =
12094 + { f_table };
12095 +#elif defined(FOUR_LR_TABLES)
12096 +static const u_int32_t fl_tab[4][256] =
12097 +{ { f_table },
12098 +#undef r
12099 +#define r(p,q,r,s) w1(q)
12100 + { f_table },
12101 +#undef r
12102 +#define r(p,q,r,s) w2(q)
12103 + { f_table },
12104 +#undef r
12105 +#define r(p,q,r,s) w3(q)
12106 + { f_table }
12107 +};
12108 +#endif
12109 +
12110 +#undef w
12111 +#define w w0
12112 +#if defined(ONE_LR_TABLE)
12113 +static const u_int32_t il_tab[256] =
12114 + { li_table };
12115 +#elif defined(FOUR_LR_TABLES)
12116 +static const u_int32_t il_tab[4][256] =
12117 +{ { li_table },
12118 +#undef w
12119 +#define w w1
12120 + { li_table },
12121 +#undef w
12122 +#define w w2
12123 + { li_table },
12124 +#undef w
12125 +#define w w3
12126 + { li_table }
12127 +};
12128 +#endif
12129 +
12130 +#endif
12131 +
12132 +#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES))
12133 +
12134 +#define m_table \
12135 + r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\
12136 + r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\
12137 + r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\
12138 + r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\
12139 + r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\
12140 + r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\
12141 + r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\
12142 + r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\
12143 + r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\
12144 + r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\
12145 + r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\
12146 + r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\
12147 + r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\
12148 + r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\
12149 + r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\
12150 + r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\
12151 + r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\
12152 + r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\
12153 + r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\
12154 + r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\
12155 + r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\
12156 + r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\
12157 + r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\
12158 + r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\
12159 + r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\
12160 + r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\
12161 + r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\
12162 + r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\
12163 + r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\
12164 + r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\
12165 + r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\
12166 + r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\
12167 + r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\
12168 + r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\
12169 + r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\
12170 + r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\
12171 + r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\
12172 + r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\
12173 + r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\
12174 + r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\
12175 + r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\
12176 + r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\
12177 + r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\
12178 + r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\
12179 + r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\
12180 + r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\
12181 + r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\
12182 + r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\
12183 + r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\
12184 + r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\
12185 + r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\
12186 + r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\
12187 + r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\
12188 + r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\
12189 + r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\
12190 + r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\
12191 + r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\
12192 + r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\
12193 + r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\
12194 + r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\
12195 + r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\
12196 + r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\
12197 + r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\
12198 + r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d)
12199 +
12200 +#undef r
12201 +#define r r0
12202 +
12203 +#if defined(ONE_IM_TABLE)
12204 +static const u_int32_t im_tab[256] =
12205 + { m_table };
12206 +#elif defined(FOUR_IM_TABLES)
12207 +static const u_int32_t im_tab[4][256] =
12208 +{ { m_table },
12209 +#undef r
12210 +#define r r1
12211 + { m_table },
12212 +#undef r
12213 +#define r r2
12214 + { m_table },
12215 +#undef r
12216 +#define r r3
12217 + { m_table }
12218 +};
12219 +#endif
12220 +
12221 +#endif
12222 +
12223 +#else
12224 +
12225 +static int tab_gen = 0;
12226 +
12227 +static unsigned char s_box[256]; // the S box
12228 +static unsigned char inv_s_box[256]; // the inverse S box
12229 +static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants
12230 +
12231 +#if defined(ONE_TABLE)
12232 +static u_int32_t ft_tab[256];
12233 +static u_int32_t it_tab[256];
12234 +#elif defined(FOUR_TABLES)
12235 +static u_int32_t ft_tab[4][256];
12236 +static u_int32_t it_tab[4][256];
12237 +#endif
12238 +
12239 +#if defined(ONE_LR_TABLE)
12240 +static u_int32_t fl_tab[256];
12241 +static u_int32_t il_tab[256];
12242 +#elif defined(FOUR_LR_TABLES)
12243 +static u_int32_t fl_tab[4][256];
12244 +static u_int32_t il_tab[4][256];
12245 +#endif
12246 +
12247 +#if defined(ONE_IM_TABLE)
12248 +static u_int32_t im_tab[256];
12249 +#elif defined(FOUR_IM_TABLES)
12250 +static u_int32_t im_tab[4][256];
12251 +#endif
12252 +
12253 +// Generate the tables for the dynamic table option
12254 +
12255 +#if !defined(FF_TABLES)
12256 +
12257 +// It will generally be sensible to use tables to compute finite
12258 +// field multiplies and inverses but where memory is scarse this
12259 +// code might sometimes be better.
12260 +
12261 +// return 2 ^ (n - 1) where n is the bit number of the highest bit
12262 +// set in x with x in the range 1 < x < 0x00000200. This form is
12263 +// used so that locals within FFinv can be bytes rather than words
12264 +
12265 +static unsigned char hibit(const u_int32_t x)
12266 +{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2));
12267 +
12268 + r |= (r >> 2);
12269 + r |= (r >> 4);
12270 + return (r + 1) >> 1;
12271 +}
12272 +
12273 +// return the inverse of the finite field element x
12274 +
12275 +static unsigned char FFinv(const unsigned char x)
12276 +{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
12277 +
12278 + if(x < 2) return x;
12279 +
12280 + for(;;)
12281 + {
12282 + if(!n1) return v1;
12283 +
12284 + while(n2 >= n1)
12285 + {
12286 + n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
12287 + }
12288 +
12289 + if(!n2) return v2;
12290 +
12291 + while(n1 >= n2)
12292 + {
12293 + n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
12294 + }
12295 + }
12296 +}
12297 +
12298 +// define the finite field multiplies required for Rijndael
12299 +
12300 +#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0))
12301 +#define FFmul03(x) ((x) ^ FFmul02(x))
12302 +#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x))))
12303 +#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x))))
12304 +#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x))))
12305 +#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x)))
12306 +
12307 +#else
12308 +
12309 +#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
12310 +
12311 +#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
12312 +#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
12313 +#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
12314 +#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
12315 +#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
12316 +#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
12317 +
12318 +#endif
12319 +
12320 +// The forward and inverse affine transformations used in the S-box
12321 +
12322 +#define fwd_affine(x) \
12323 + (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8)))
12324 +
12325 +#define inv_affine(x) \
12326 + (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8)))
12327 +
12328 +static void gen_tabs(void)
12329 +{ u_int32_t i, w;
12330 +
12331 +#if defined(FF_TABLES)
12332 +
12333 + unsigned char pow[512], log[256];
12334 +
12335 + // log and power tables for GF(2^8) finite field with
12336 + // 0x011b as modular polynomial - the simplest primitive
12337 + // root is 0x03, used here to generate the tables
12338 +
12339 + i = 0; w = 1;
12340 + do
12341 + {
12342 + pow[i] = (unsigned char)w;
12343 + pow[i + 255] = (unsigned char)w;
12344 + log[w] = (unsigned char)i++;
12345 + w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
12346 + }
12347 + while (w != 1);
12348 +
12349 +#endif
12350 +
12351 + for(i = 0, w = 1; i < AES_RC_LENGTH; ++i)
12352 + {
12353 + rcon_tab[i] = bytes2word(w, 0, 0, 0);
12354 + w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
12355 + }
12356 +
12357 + for(i = 0; i < 256; ++i)
12358 + { unsigned char b;
12359 +
12360 + s_box[i] = b = fwd_affine(FFinv((unsigned char)i));
12361 +
12362 + w = bytes2word(b, 0, 0, 0);
12363 +#if defined(ONE_LR_TABLE)
12364 + fl_tab[i] = w;
12365 +#elif defined(FOUR_LR_TABLES)
12366 + fl_tab[0][i] = w;
12367 + fl_tab[1][i] = upr(w,1);
12368 + fl_tab[2][i] = upr(w,2);
12369 + fl_tab[3][i] = upr(w,3);
12370 +#endif
12371 + w = bytes2word(FFmul02(b), b, b, FFmul03(b));
12372 +#if defined(ONE_TABLE)
12373 + ft_tab[i] = w;
12374 +#elif defined(FOUR_TABLES)
12375 + ft_tab[0][i] = w;
12376 + ft_tab[1][i] = upr(w,1);
12377 + ft_tab[2][i] = upr(w,2);
12378 + ft_tab[3][i] = upr(w,3);
12379 +#endif
12380 + inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i));
12381 +
12382 + w = bytes2word(b, 0, 0, 0);
12383 +#if defined(ONE_LR_TABLE)
12384 + il_tab[i] = w;
12385 +#elif defined(FOUR_LR_TABLES)
12386 + il_tab[0][i] = w;
12387 + il_tab[1][i] = upr(w,1);
12388 + il_tab[2][i] = upr(w,2);
12389 + il_tab[3][i] = upr(w,3);
12390 +#endif
12391 + w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b));
12392 +#if defined(ONE_TABLE)
12393 + it_tab[i] = w;
12394 +#elif defined(FOUR_TABLES)
12395 + it_tab[0][i] = w;
12396 + it_tab[1][i] = upr(w,1);
12397 + it_tab[2][i] = upr(w,2);
12398 + it_tab[3][i] = upr(w,3);
12399 +#endif
12400 +#if defined(ONE_IM_TABLE)
12401 + im_tab[b] = w;
12402 +#elif defined(FOUR_IM_TABLES)
12403 + im_tab[0][b] = w;
12404 + im_tab[1][b] = upr(w,1);
12405 + im_tab[2][b] = upr(w,2);
12406 + im_tab[3][b] = upr(w,3);
12407 +#endif
12408 +
12409 + }
12410 +}
12411 +
12412 +#endif
12413 +
12414 +#define no_table(x,box,vf,rf,c) bytes2word( \
12415 + box[bval(vf(x,0,c),rf(0,c))], \
12416 + box[bval(vf(x,1,c),rf(1,c))], \
12417 + box[bval(vf(x,2,c),rf(2,c))], \
12418 + box[bval(vf(x,3,c),rf(3,c))])
12419 +
12420 +#define one_table(x,op,tab,vf,rf,c) \
12421 + ( tab[bval(vf(x,0,c),rf(0,c))] \
12422 + ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
12423 + ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
12424 + ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
12425 +
12426 +#define four_tables(x,tab,vf,rf,c) \
12427 + ( tab[0][bval(vf(x,0,c),rf(0,c))] \
12428 + ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
12429 + ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
12430 + ^ tab[3][bval(vf(x,3,c),rf(3,c))])
12431 +
12432 +#define vf1(x,r,c) (x)
12433 +#define rf1(r,c) (r)
12434 +#define rf2(r,c) ((r-c)&3)
12435 +
12436 +#if defined(FOUR_LR_TABLES)
12437 +#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
12438 +#elif defined(ONE_LR_TABLE)
12439 +#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
12440 +#else
12441 +#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
12442 +#endif
12443 +
12444 +#if defined(FOUR_IM_TABLES)
12445 +#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
12446 +#elif defined(ONE_IM_TABLE)
12447 +#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
12448 +#else
12449 +#define inv_mcol(x) \
12450 + (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
12451 + f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
12452 +#endif
12453 +
12454 +// Subroutine to set the block size (if variable) in bytes, legal
12455 +// values being 16, 24 and 32.
12456 +
12457 +#if defined(AES_BLOCK_SIZE)
12458 +#define nc (AES_BLOCK_SIZE / 4)
12459 +#else
12460 +#define nc (cx->aes_Ncol)
12461 +
12462 +void aes_set_blk(aes_context *cx, int n_bytes)
12463 +{
12464 +#if !defined(FIXED_TABLES)
12465 + if(!tab_gen) { gen_tabs(); tab_gen = 1; }
12466 +#endif
12467 +
12468 + switch(n_bytes) {
12469 + case 32: /* bytes */
12470 + case 256: /* bits */
12471 + nc = 8;
12472 + break;
12473 + case 24: /* bytes */
12474 + case 192: /* bits */
12475 + nc = 6;
12476 + break;
12477 + case 16: /* bytes */
12478 + case 128: /* bits */
12479 + default:
12480 + nc = 4;
12481 + break;
12482 + }
12483 +}
12484 +
12485 +#endif
12486 +
12487 +// Initialise the key schedule from the user supplied key. The key
12488 +// length is now specified in bytes - 16, 24 or 32 as appropriate.
12489 +// This corresponds to bit lengths of 128, 192 and 256 bits, and
12490 +// to Nk values of 4, 6 and 8 respectively.
12491 +
12492 +#define mx(t,f) (*t++ = inv_mcol(*f),f++)
12493 +#define cp(t,f) *t++ = *f++
12494 +
12495 +#if AES_BLOCK_SIZE == 16
12496 +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s)
12497 +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s)
12498 +#elif AES_BLOCK_SIZE == 24
12499 +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
12500 + cp(d,s); cp(d,s)
12501 +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
12502 + mx(d,s); mx(d,s)
12503 +#elif AES_BLOCK_SIZE == 32
12504 +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
12505 + cp(d,s); cp(d,s); cp(d,s); cp(d,s)
12506 +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
12507 + mx(d,s); mx(d,s); mx(d,s); mx(d,s)
12508 +#else
12509 +
12510 +#define cpy(d,s) \
12511 +switch(nc) \
12512 +{ case 8: cp(d,s); cp(d,s); \
12513 + case 6: cp(d,s); cp(d,s); \
12514 + case 4: cp(d,s); cp(d,s); \
12515 + cp(d,s); cp(d,s); \
12516 +}
12517 +
12518 +#define mix(d,s) \
12519 +switch(nc) \
12520 +{ case 8: mx(d,s); mx(d,s); \
12521 + case 6: mx(d,s); mx(d,s); \
12522 + case 4: mx(d,s); mx(d,s); \
12523 + mx(d,s); mx(d,s); \
12524 +}
12525 +
12526 +#endif
12527 +
12528 +void aes_set_key(aes_context *cx, const unsigned char in_key[], int n_bytes, const int f)
12529 +{ u_int32_t *kf, *kt, rci;
12530 +
12531 +#if !defined(FIXED_TABLES)
12532 + if(!tab_gen) { gen_tabs(); tab_gen = 1; }
12533 +#endif
12534 +
12535 + switch(n_bytes) {
12536 + case 32: /* bytes */
12537 + case 256: /* bits */
12538 + cx->aes_Nkey = 8;
12539 + break;
12540 + case 24: /* bytes */
12541 + case 192: /* bits */
12542 + cx->aes_Nkey = 6;
12543 + break;
12544 + case 16: /* bytes */
12545 + case 128: /* bits */
12546 + default:
12547 + cx->aes_Nkey = 4;
12548 + break;
12549 + }
12550 +
12551 + cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6;
12552 +
12553 + cx->aes_e_key[0] = const_word_in(in_key );
12554 + cx->aes_e_key[1] = const_word_in(in_key + 4);
12555 + cx->aes_e_key[2] = const_word_in(in_key + 8);
12556 + cx->aes_e_key[3] = const_word_in(in_key + 12);
12557 +
12558 + kf = cx->aes_e_key;
12559 + kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey;
12560 + rci = 0;
12561 +
12562 + switch(cx->aes_Nkey)
12563 + {
12564 + case 4: do
12565 + { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++];
12566 + kf[5] = kf[1] ^ kf[4];
12567 + kf[6] = kf[2] ^ kf[5];
12568 + kf[7] = kf[3] ^ kf[6];
12569 + kf += 4;
12570 + }
12571 + while(kf < kt);
12572 + break;
12573 +
12574 + case 6: cx->aes_e_key[4] = const_word_in(in_key + 16);
12575 + cx->aes_e_key[5] = const_word_in(in_key + 20);
12576 + do
12577 + { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++];
12578 + kf[ 7] = kf[1] ^ kf[ 6];
12579 + kf[ 8] = kf[2] ^ kf[ 7];
12580 + kf[ 9] = kf[3] ^ kf[ 8];
12581 + kf[10] = kf[4] ^ kf[ 9];
12582 + kf[11] = kf[5] ^ kf[10];
12583 + kf += 6;
12584 + }
12585 + while(kf < kt);
12586 + break;
12587 +
12588 + case 8: cx->aes_e_key[4] = const_word_in(in_key + 16);
12589 + cx->aes_e_key[5] = const_word_in(in_key + 20);
12590 + cx->aes_e_key[6] = const_word_in(in_key + 24);
12591 + cx->aes_e_key[7] = const_word_in(in_key + 28);
12592 + do
12593 + { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++];
12594 + kf[ 9] = kf[1] ^ kf[ 8];
12595 + kf[10] = kf[2] ^ kf[ 9];
12596 + kf[11] = kf[3] ^ kf[10];
12597 + kf[12] = kf[4] ^ ls_box(kf[11],0);
12598 + kf[13] = kf[5] ^ kf[12];
12599 + kf[14] = kf[6] ^ kf[13];
12600 + kf[15] = kf[7] ^ kf[14];
12601 + kf += 8;
12602 + }
12603 + while (kf < kt);
12604 + break;
12605 + }
12606 +
12607 + if(!f)
12608 + { u_int32_t i;
12609 +
12610 + kt = cx->aes_d_key + nc * cx->aes_Nrnd;
12611 + kf = cx->aes_e_key;
12612 +
12613 + cpy(kt, kf); kt -= 2 * nc;
12614 +
12615 + for(i = 1; i < cx->aes_Nrnd; ++i)
12616 + {
12617 +#if defined(ONE_TABLE) || defined(FOUR_TABLES)
12618 +#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES)
12619 + u_int32_t f2, f4, f8, f9;
12620 +#endif
12621 + mix(kt, kf);
12622 +#else
12623 + cpy(kt, kf);
12624 +#endif
12625 + kt -= 2 * nc;
12626 + }
12627 +
12628 + cpy(kt, kf);
12629 + }
12630 +}
12631 +
12632 +// y = output word, x = input word, r = row, c = column
12633 +// for r = 0, 1, 2 and 3 = column accessed for row r
12634 +
12635 +#if defined(ARRAYS)
12636 +#define s(x,c) x[c]
12637 +#else
12638 +#define s(x,c) x##c
12639 +#endif
12640 +
12641 +// I am grateful to Frank Yellin for the following constructions
12642 +// which, given the column (c) of the output state variable that
12643 +// is being computed, return the input state variables which are
12644 +// needed for each row (r) of the state
12645 +
12646 +// For the fixed block size options, compilers reduce these two
12647 +// expressions to fixed variable references. For variable block
12648 +// size code conditional clauses will sometimes be returned
12649 +
12650 +#define unused 77 // Sunset Strip
12651 +
12652 +#define fwd_var(x,r,c) \
12653 + ( r==0 ? \
12654 + ( c==0 ? s(x,0) \
12655 + : c==1 ? s(x,1) \
12656 + : c==2 ? s(x,2) \
12657 + : c==3 ? s(x,3) \
12658 + : c==4 ? s(x,4) \
12659 + : c==5 ? s(x,5) \
12660 + : c==6 ? s(x,6) \
12661 + : s(x,7)) \
12662 + : r==1 ? \
12663 + ( c==0 ? s(x,1) \
12664 + : c==1 ? s(x,2) \
12665 + : c==2 ? s(x,3) \
12666 + : c==3 ? nc==4 ? s(x,0) : s(x,4) \
12667 + : c==4 ? s(x,5) \
12668 + : c==5 ? nc==8 ? s(x,6) : s(x,0) \
12669 + : c==6 ? s(x,7) \
12670 + : s(x,0)) \
12671 + : r==2 ? \
12672 + ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
12673 + : c==1 ? nc==8 ? s(x,4) : s(x,3) \
12674 + : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
12675 + : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
12676 + : c==4 ? nc==8 ? s(x,7) : s(x,0) \
12677 + : c==5 ? nc==8 ? s(x,0) : s(x,1) \
12678 + : c==6 ? s(x,1) \
12679 + : s(x,2)) \
12680 + : \
12681 + ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
12682 + : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
12683 + : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
12684 + : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
12685 + : c==4 ? nc==8 ? s(x,0) : s(x,1) \
12686 + : c==5 ? nc==8 ? s(x,1) : s(x,2) \
12687 + : c==6 ? s(x,2) \
12688 + : s(x,3)))
12689 +
12690 +#define inv_var(x,r,c) \
12691 + ( r==0 ? \
12692 + ( c==0 ? s(x,0) \
12693 + : c==1 ? s(x,1) \
12694 + : c==2 ? s(x,2) \
12695 + : c==3 ? s(x,3) \
12696 + : c==4 ? s(x,4) \
12697 + : c==5 ? s(x,5) \
12698 + : c==6 ? s(x,6) \
12699 + : s(x,7)) \
12700 + : r==1 ? \
12701 + ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \
12702 + : c==1 ? s(x,0) \
12703 + : c==2 ? s(x,1) \
12704 + : c==3 ? s(x,2) \
12705 + : c==4 ? s(x,3) \
12706 + : c==5 ? s(x,4) \
12707 + : c==6 ? s(x,5) \
12708 + : s(x,6)) \
12709 + : r==2 ? \
12710 + ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
12711 + : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
12712 + : c==2 ? nc==8 ? s(x,7) : s(x,0) \
12713 + : c==3 ? nc==8 ? s(x,0) : s(x,1) \
12714 + : c==4 ? nc==8 ? s(x,1) : s(x,2) \
12715 + : c==5 ? nc==8 ? s(x,2) : s(x,3) \
12716 + : c==6 ? s(x,3) \
12717 + : s(x,4)) \
12718 + : \
12719 + ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \
12720 + : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
12721 + : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
12722 + : c==3 ? nc==8 ? s(x,7) : s(x,0) \
12723 + : c==4 ? nc==8 ? s(x,0) : s(x,1) \
12724 + : c==5 ? nc==8 ? s(x,1) : s(x,2) \
12725 + : c==6 ? s(x,2) \
12726 + : s(x,3)))
12727 +
12728 +#define si(y,x,k,c) s(y,c) = const_word_in(x + 4 * c) ^ k[c]
12729 +#define so(y,x,c) word_out(y + 4 * c, s(x,c))
12730 +
12731 +#if defined(FOUR_TABLES)
12732 +#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
12733 +#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
12734 +#elif defined(ONE_TABLE)
12735 +#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
12736 +#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
12737 +#else
12738 +#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
12739 +#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
12740 +#endif
12741 +
12742 +#if defined(FOUR_LR_TABLES)
12743 +#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
12744 +#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
12745 +#elif defined(ONE_LR_TABLE)
12746 +#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
12747 +#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
12748 +#else
12749 +#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
12750 +#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
12751 +#endif
12752 +
12753 +#if AES_BLOCK_SIZE == 16
12754 +
12755 +#if defined(ARRAYS)
12756 +#define locals(y,x) x[4],y[4]
12757 +#else
12758 +#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
12759 +// the following defines prevent the compiler requiring the declaration
12760 +// of generated but unused variables in the fwd_var and inv_var macros
12761 +#define b04 unused
12762 +#define b05 unused
12763 +#define b06 unused
12764 +#define b07 unused
12765 +#define b14 unused
12766 +#define b15 unused
12767 +#define b16 unused
12768 +#define b17 unused
12769 +#endif
12770 +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
12771 + s(y,2) = s(x,2); s(y,3) = s(x,3);
12772 +#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)
12773 +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
12774 +#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)
12775 +
12776 +#elif AES_BLOCK_SIZE == 24
12777 +
12778 +#if defined(ARRAYS)
12779 +#define locals(y,x) x[6],y[6]
12780 +#else
12781 +#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
12782 + y##0,y##1,y##2,y##3,y##4,y##5
12783 +#define b06 unused
12784 +#define b07 unused
12785 +#define b16 unused
12786 +#define b17 unused
12787 +#endif
12788 +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
12789 + s(y,2) = s(x,2); s(y,3) = s(x,3); \
12790 + s(y,4) = s(x,4); s(y,5) = s(x,5);
12791 +#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
12792 + si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
12793 +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
12794 + so(y,x,3); so(y,x,4); so(y,x,5)
12795 +#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
12796 + rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
12797 +#else
12798 +
12799 +#if defined(ARRAYS)
12800 +#define locals(y,x) x[8],y[8]
12801 +#else
12802 +#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
12803 + y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
12804 +#endif
12805 +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
12806 + s(y,2) = s(x,2); s(y,3) = s(x,3); \
12807 + s(y,4) = s(x,4); s(y,5) = s(x,5); \
12808 + s(y,6) = s(x,6); s(y,7) = s(x,7);
12809 +
12810 +#if AES_BLOCK_SIZE == 32
12811 +
12812 +#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); \
12813 + si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
12814 +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
12815 + so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
12816 +#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); \
12817 + rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
12818 +#else
12819 +
12820 +#define state_in(y,x,k) \
12821 +switch(nc) \
12822 +{ case 8: si(y,x,k,7); si(y,x,k,6); \
12823 + case 6: si(y,x,k,5); si(y,x,k,4); \
12824 + case 4: si(y,x,k,3); si(y,x,k,2); \
12825 + si(y,x,k,1); si(y,x,k,0); \
12826 +}
12827 +
12828 +#define state_out(y,x) \
12829 +switch(nc) \
12830 +{ case 8: so(y,x,7); so(y,x,6); \
12831 + case 6: so(y,x,5); so(y,x,4); \
12832 + case 4: so(y,x,3); so(y,x,2); \
12833 + so(y,x,1); so(y,x,0); \
12834 +}
12835 +
12836 +#if defined(FAST_VARIABLE)
12837 +
12838 +#define round(rm,y,x,k) \
12839 +switch(nc) \
12840 +{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
12841 + rm(y,x,k,5); rm(y,x,k,4); \
12842 + rm(y,x,k,3); rm(y,x,k,2); \
12843 + rm(y,x,k,1); rm(y,x,k,0); \
12844 + break; \
12845 + case 6: rm(y,x,k,5); rm(y,x,k,4); \
12846 + rm(y,x,k,3); rm(y,x,k,2); \
12847 + rm(y,x,k,1); rm(y,x,k,0); \
12848 + break; \
12849 + case 4: rm(y,x,k,3); rm(y,x,k,2); \
12850 + rm(y,x,k,1); rm(y,x,k,0); \
12851 + break; \
12852 +}
12853 +#else
12854 +
12855 +#define round(rm,y,x,k) \
12856 +switch(nc) \
12857 +{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
12858 + case 6: rm(y,x,k,5); rm(y,x,k,4); \
12859 + case 4: rm(y,x,k,3); rm(y,x,k,2); \
12860 + rm(y,x,k,1); rm(y,x,k,0); \
12861 +}
12862 +
12863 +#endif
12864 +
12865 +#endif
12866 +#endif
12867 +
12868 +void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
12869 +{ u_int32_t locals(b0, b1);
12870 + const u_int32_t *kp = cx->aes_e_key;
12871 +
12872 +#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
12873 + u_int32_t f2;
12874 +#endif
12875 +
12876 + state_in(b0, in_blk, kp); kp += nc;
12877 +
12878 +#if defined(UNROLL)
12879 +
12880 + switch(cx->aes_Nrnd)
12881 + {
12882 + case 14: round(fwd_rnd, b1, b0, kp );
12883 + round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
12884 + case 12: round(fwd_rnd, b1, b0, kp );
12885 + round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
12886 + case 10: round(fwd_rnd, b1, b0, kp );
12887 + round(fwd_rnd, b0, b1, kp + nc);
12888 + round(fwd_rnd, b1, b0, kp + 2 * nc);
12889 + round(fwd_rnd, b0, b1, kp + 3 * nc);
12890 + round(fwd_rnd, b1, b0, kp + 4 * nc);
12891 + round(fwd_rnd, b0, b1, kp + 5 * nc);
12892 + round(fwd_rnd, b1, b0, kp + 6 * nc);
12893 + round(fwd_rnd, b0, b1, kp + 7 * nc);
12894 + round(fwd_rnd, b1, b0, kp + 8 * nc);
12895 + round(fwd_lrnd, b0, b1, kp + 9 * nc);
12896 + }
12897 +
12898 +#elif defined(PARTIAL_UNROLL)
12899 + { u_int32_t rnd;
12900 +
12901 + for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
12902 + {
12903 + round(fwd_rnd, b1, b0, kp);
12904 + round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc;
12905 + }
12906 +
12907 + round(fwd_rnd, b1, b0, kp);
12908 + round(fwd_lrnd, b0, b1, kp + nc);
12909 + }
12910 +#else
12911 + { u_int32_t rnd;
12912 +
12913 + for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
12914 + {
12915 + round(fwd_rnd, b1, b0, kp);
12916 + l_copy(b0, b1); kp += nc;
12917 + }
12918 +
12919 + round(fwd_lrnd, b0, b1, kp);
12920 + }
12921 +#endif
12922 +
12923 + state_out(out_blk, b0);
12924 +}
12925 +
12926 +void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
12927 +{ u_int32_t locals(b0, b1);
12928 + const u_int32_t *kp = cx->aes_d_key;
12929 +
12930 +#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
12931 + u_int32_t f2, f4, f8, f9;
12932 +#endif
12933 +
12934 + state_in(b0, in_blk, kp); kp += nc;
12935 +
12936 +#if defined(UNROLL)
12937 +
12938 + switch(cx->aes_Nrnd)
12939 + {
12940 + case 14: round(inv_rnd, b1, b0, kp );
12941 + round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
12942 + case 12: round(inv_rnd, b1, b0, kp );
12943 + round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
12944 + case 10: round(inv_rnd, b1, b0, kp );
12945 + round(inv_rnd, b0, b1, kp + nc);
12946 + round(inv_rnd, b1, b0, kp + 2 * nc);
12947 + round(inv_rnd, b0, b1, kp + 3 * nc);
12948 + round(inv_rnd, b1, b0, kp + 4 * nc);
12949 + round(inv_rnd, b0, b1, kp + 5 * nc);
12950 + round(inv_rnd, b1, b0, kp + 6 * nc);
12951 + round(inv_rnd, b0, b1, kp + 7 * nc);
12952 + round(inv_rnd, b1, b0, kp + 8 * nc);
12953 + round(inv_lrnd, b0, b1, kp + 9 * nc);
12954 + }
12955 +
12956 +#elif defined(PARTIAL_UNROLL)
12957 + { u_int32_t rnd;
12958 +
12959 + for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
12960 + {
12961 + round(inv_rnd, b1, b0, kp);
12962 + round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc;
12963 + }
12964 +
12965 + round(inv_rnd, b1, b0, kp);
12966 + round(inv_lrnd, b0, b1, kp + nc);
12967 + }
12968 +#else
12969 + { u_int32_t rnd;
12970 +
12971 + for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
12972 + {
12973 + round(inv_rnd, b1, b0, kp);
12974 + l_copy(b0, b1); kp += nc;
12975 + }
12976 +
12977 + round(inv_lrnd, b0, b1, kp);
12978 + }
12979 +#endif
12980 +
12981 + state_out(out_blk, b0);
12982 +}
12983 --- /dev/null Tue Mar 11 13:02:56 2003
12984 +++ linux/net/ipsec/aes/aes_cbc.c Mon Feb 9 13:51:03 2004
12985 @@ -0,0 +1,46 @@
12986 +/*
12987 +// I retain copyright in this code but I encourage its free use provided
12988 +// that I don't carry any responsibility for the results. I am especially
12989 +// happy to see it used in free and open source software. If you do use
12990 +// it I would appreciate an acknowledgement of its origin in the code or
12991 +// the product that results and I would also appreciate knowing a little
12992 +// about the use to which it is being put. I am grateful to Frank Yellin
12993 +// for some ideas that are used in this implementation.
12994 +//
12995 +// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
12996 +//
12997 +// This is an implementation of the AES encryption algorithm (Rijndael)
12998 +// designed by Joan Daemen and Vincent Rijmen. This version is designed
12999 +// to provide both fixed and dynamic block and key lengths and can also
13000 +// run with either big or little endian internal byte order (see aes.h).
13001 +// It inputs block and key lengths in bytes with the legal values being
13002 +// 16, 24 and 32.
13003 +*
13004 +*/
13005 +
13006 +#ifdef __KERNEL__
13007 +#include <linux/types.h>
13008 +#else
13009 +#include <sys/types.h>
13010 +#endif
13011 +#include "crypto/aes_cbc.h"
13012 +#include "crypto/cbc_generic.h"
13013 +
13014 +/* returns bool success */
13015 +int AES_set_key(aes_context *aes_ctx, const u_int8_t *key, int keysize) {
13016 + aes_set_key(aes_ctx, key, keysize, 0);
13017 + return 1;
13018 +}
13019 +CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
13020 +
13021 +
13022 +/*
13023 + * $Log: aes_cbc.c,v $
13024 + * Revision 1.2 2004/07/10 07:48:40 mcr
13025 + * Moved from linux/crypto/ciphers/aes/aes_cbc.c,v
13026 + *
13027 + * Revision 1.1 2004/04/06 02:48:12 mcr
13028 + * pullup of AES cipher from alg-branch.
13029 + *
13030 + *
13031 + */
13032 --- /dev/null Tue Mar 11 13:02:56 2003
13033 +++ linux/net/ipsec/aes/aes_xcbc_mac.c Mon Feb 9 13:51:03 2004
13034 @@ -0,0 +1,67 @@
13035 +#ifdef __KERNEL__
13036 +#include <linux/types.h>
13037 +#include <linux/kernel.h>
13038 +#define AES_DEBUG(x)
13039 +#else
13040 +#include <stdio.h>
13041 +#include <sys/types.h>
13042 +#define AES_DEBUG(x) x
13043 +#endif
13044 +
13045 +#include "crypto/aes.h"
13046 +#include "crypto/aes_xcbc_mac.h"
13047 +
13048 +int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen)
13049 +{
13050 + int ret=1;
13051 + aes_block kn[3] = {
13052 + { 0x01010101, 0x01010101, 0x01010101, 0x01010101 },
13053 + { 0x02020202, 0x02020202, 0x02020202, 0x02020202 },
13054 + { 0x03030303, 0x03030303, 0x03030303, 0x03030303 },
13055 + };
13056 + aes_set_key(&ctxm->ctx_k1, key, keylen, 0);
13057 + aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[0], (u_int8_t *) kn[0]);
13058 + aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[1], (u_int8_t *) ctxm->k2);
13059 + aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[2], (u_int8_t *) ctxm->k3);
13060 + aes_set_key(&ctxm->ctx_k1, (u_int8_t *) kn[0], 16, 0);
13061 + return ret;
13062 +}
13063 +static void do_pad_xor(u_int8_t *out, const u_int8_t *in, int len) {
13064 + int pos=0;
13065 + for (pos=1; pos <= 16; pos++, in++, out++) {
13066 + if (pos <= len)
13067 + *out ^= *in;
13068 + if (pos > len) {
13069 + AES_DEBUG(printf("put 0x80 at pos=%d\n", pos));
13070 + *out ^= 0x80;
13071 + break;
13072 + }
13073 + }
13074 +}
13075 +static void xor_block(aes_block res, const aes_block op) {
13076 + res[0] ^= op[0];
13077 + res[1] ^= op[1];
13078 + res[2] ^= op[2];
13079 + res[3] ^= op[3];
13080 +}
13081 +int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]) {
13082 + int ret=ilen;
13083 + u_int32_t out[4] = { 0, 0, 0, 0 };
13084 + for (; ilen > 16 ; ilen-=16) {
13085 + xor_block(out, (const u_int32_t*) &in[0]);
13086 + aes_encrypt(&ctxm->ctx_k1, in, (u_int8_t *)&out[0]);
13087 + in+=16;
13088 + }
13089 + do_pad_xor((u_int8_t *)&out, in, ilen);
13090 + if (ilen==16) {
13091 + AES_DEBUG(printf("using k3\n"));
13092 + xor_block(out, ctxm->k3);
13093 + }
13094 + else
13095 + {
13096 + AES_DEBUG(printf("using k2\n"));
13097 + xor_block(out, ctxm->k2);
13098 + }
13099 + aes_encrypt(&ctxm->ctx_k1, (u_int8_t *)out, hash);
13100 + return ret;
13101 +}
13102 --- /dev/null Tue Mar 11 13:02:56 2003
13103 +++ linux/net/ipsec/aes/ipsec_alg_aes.c Mon Feb 9 13:51:03 2004
13104 @@ -0,0 +1,299 @@
13105 +/*
13106 + * ipsec_alg AES cipher stubs
13107 + *
13108 + * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
13109 + *
13110 + * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
13111 + *
13112 + * This program is free software; you can redistribute it and/or modify it
13113 + * under the terms of the GNU General Public License as published by the
13114 + * Free Software Foundation; either version 2 of the License, or (at your
13115 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13116 + *
13117 + * This program is distributed in the hope that it will be useful, but
13118 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13119 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13120 + * for more details.
13121 + *
13122 + * Fixes by:
13123 + * PK: Pawel Krawczyk <kravietz@aba.krakow.pl>
13124 + * Fixes list:
13125 + * PK: make XCBC comply with latest draft (keylength)
13126 + *
13127 + */
13128 +#ifndef AUTOCONF_INCLUDED
13129 +#include <linux/config.h>
13130 +#endif
13131 +#include <linux/version.h>
13132 +
13133 +/*
13134 + * special case: ipsec core modular with this static algo inside:
13135 + * must avoid MODULE magic for this file
13136 + */
13137 +#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_AES)
13138 +#undef MODULE
13139 +#endif
13140 +
13141 +#include <linux/module.h>
13142 +#include <linux/init.h>
13143 +
13144 +#include <linux/kernel.h> /* printk() */
13145 +#include <linux/errno.h> /* error codes */
13146 +#include <linux/types.h> /* size_t */
13147 +#include <linux/string.h>
13148 +
13149 +/* Check if __exit is defined, if not null it */
13150 +#ifndef __exit
13151 +#define __exit
13152 +#endif
13153 +
13154 +/* Low freeswan header coupling */
13155 +#include "openswan/ipsec_alg.h"
13156 +#include "crypto/aes_cbc.h"
13157 +
13158 +#define CONFIG_KLIPS_ENC_AES_MAC 1
13159 +
13160 +#define AES_CONTEXT_T aes_context
13161 +static int debug_aes=0;
13162 +static int test_aes=0;
13163 +static int excl_aes=0;
13164 +static int keyminbits=0;
13165 +static int keymaxbits=0;
13166 +#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13167 +MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
13168 +#ifdef module_param
13169 +module_param(debug_aes,int,0664);
13170 +module_param(test_aes,int,0664);
13171 +module_param(excl_aes,int,0664);
13172 +module_param(keyminbits,int,0664);
13173 +module_param(keymaxbits,int,0664);
13174 +#else
13175 +MODULE_PARM(debug_aes, "i");
13176 +MODULE_PARM(test_aes, "i");
13177 +MODULE_PARM(excl_aes, "i");
13178 +MODULE_PARM(keyminbits, "i");
13179 +MODULE_PARM(keymaxbits, "i");
13180 +#endif
13181 +#endif
13182 +
13183 +#if CONFIG_KLIPS_ENC_AES_MAC
13184 +#include "crypto/aes_xcbc_mac.h"
13185 +
13186 +/*
13187 + * Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt).
13188 + * We use 9 for non-modular algorithm and none for modular, thus
13189 + * forcing user to specify one on module load. -kravietz
13190 + */
13191 +#ifdef MODULE
13192 +static int auth_id=0;
13193 +#else
13194 +static int auth_id=9;
13195 +#endif
13196 +#if 0
13197 +#ifdef MODULE_PARM
13198 +MODULE_PARM(auth_id, "i");
13199 +#else
13200 +module_param(auth_id,int,0664);
13201 +#endif
13202 +#endif
13203 +#endif
13204 +
13205 +#define ESP_AES 12 /* truely _constant_ :) */
13206 +
13207 +/* 128, 192 or 256 */
13208 +#define ESP_AES_KEY_SZ_MIN 16 /* 128 bit secret key */
13209 +#define ESP_AES_KEY_SZ_MAX 32 /* 256 bit secret key */
13210 +#define ESP_AES_CBC_BLK_LEN 16 /* AES-CBC block size */
13211 +
13212 +/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt
13213 + * -kravietz
13214 + */
13215 +#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
13216 +#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
13217 +
13218 +static int _aes_set_key(struct ipsec_alg_enc *alg,
13219 + __u8 * key_e, const __u8 * key,
13220 + size_t keysize)
13221 +{
13222 + int ret;
13223 + AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
13224 + ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL;
13225 + if (debug_aes > 0)
13226 + printk(KERN_DEBUG "klips_debug:_aes_set_key:"
13227 + "ret=%d key_e=%p key=%p keysize=%ld\n",
13228 + ret, key_e, key, (unsigned long int) keysize);
13229 + return ret;
13230 +}
13231 +
13232 +static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e,
13233 + __u8 * in, int ilen, const __u8 * iv,
13234 + int encrypt)
13235 +{
13236 + AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
13237 + if (debug_aes > 0)
13238 + printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
13239 + "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
13240 + key_e, in, ilen, iv, encrypt);
13241 + return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt);
13242 +}
13243 +#if CONFIG_KLIPS_ENC_AES_MAC
13244 +static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
13245 + aes_context_mac *ctxm=(aes_context_mac *)key_a;
13246 + return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL;
13247 +}
13248 +static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
13249 + int ret;
13250 + char hash_buf[16];
13251 + aes_context_mac *ctxm=(aes_context_mac *)key_a;
13252 + ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf);
13253 + memcpy(hash, hash_buf, hashlen);
13254 + return ret;
13255 +}
13256 +static struct ipsec_alg_auth ipsec_alg_AES_MAC = {
13257 + ixt_common: { ixt_version: IPSEC_ALG_VERSION,
13258 + ixt_refcnt: ATOMIC_INIT(0),
13259 + ixt_name: "aes_mac",
13260 + ixt_blocksize: ESP_AES_MAC_BLK_LEN,
13261 + ixt_support: {
13262 + ias_exttype: IPSEC_ALG_TYPE_AUTH,
13263 + ias_id: 0,
13264 + ias_keyminbits: ESP_AES_MAC_KEY_SZ*8,
13265 + ias_keymaxbits: ESP_AES_MAC_KEY_SZ*8,
13266 + },
13267 + },
13268 +#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13269 + ixt_module: THIS_MODULE,
13270 +#endif
13271 + ixt_a_keylen: ESP_AES_MAC_KEY_SZ,
13272 + ixt_a_ctx_size: sizeof(aes_context_mac),
13273 + ixt_a_hmac_set_key: _aes_mac_set_key,
13274 + ixt_a_hmac_hash:_aes_mac_hash,
13275 +};
13276 +#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13277 +static struct ipsec_alg_enc ipsec_alg_AES = {
13278 + ixt_common: { ixt_version: IPSEC_ALG_VERSION,
13279 + ixt_refcnt: ATOMIC_INIT(0),
13280 + ixt_name: "aes",
13281 + ixt_blocksize: ESP_AES_CBC_BLK_LEN,
13282 + ixt_support: {
13283 + ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
13284 + //ias_ivlen: 128,
13285 + ias_id: ESP_AES,
13286 + ias_keyminbits: ESP_AES_KEY_SZ_MIN*8,
13287 + ias_keymaxbits: ESP_AES_KEY_SZ_MAX*8,
13288 + },
13289 + },
13290 +#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13291 + ixt_module: THIS_MODULE,
13292 +#endif
13293 + ixt_e_keylen: ESP_AES_KEY_SZ_MAX,
13294 + ixt_e_ctx_size: sizeof(AES_CONTEXT_T),
13295 + ixt_e_set_key: _aes_set_key,
13296 + ixt_e_cbc_encrypt:_aes_cbc_encrypt,
13297 +};
13298 +
13299 +#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13300 +IPSEC_ALG_MODULE_INIT_MOD( ipsec_aes_init )
13301 +#else
13302 +IPSEC_ALG_MODULE_INIT_STATIC( ipsec_aes_init )
13303 +#endif
13304 +{
13305 + int ret, test_ret;
13306 +
13307 + if (keyminbits)
13308 + ipsec_alg_AES.ixt_common.ixt_support.ias_keyminbits=keyminbits;
13309 + if (keymaxbits) {
13310 + ipsec_alg_AES.ixt_common.ixt_support.ias_keymaxbits=keymaxbits;
13311 + if (keymaxbits*8>ipsec_alg_AES.ixt_common.ixt_support.ias_keymaxbits)
13312 + ipsec_alg_AES.ixt_e_keylen=keymaxbits*8;
13313 + }
13314 + if (excl_aes) ipsec_alg_AES.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
13315 + ret=register_ipsec_alg_enc(&ipsec_alg_AES);
13316 + printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
13317 + ipsec_alg_AES.ixt_common.ixt_support.ias_exttype,
13318 + ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13319 + ipsec_alg_AES.ixt_common.ixt_name,
13320 + ret);
13321 + if (ret==0 && test_aes) {
13322 + test_ret=ipsec_alg_test(
13323 + ipsec_alg_AES.ixt_common.ixt_support.ias_exttype ,
13324 + ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13325 + test_aes);
13326 + printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
13327 + ipsec_alg_AES.ixt_common.ixt_support.ias_exttype ,
13328 + ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13329 + test_ret);
13330 + }
13331 +#if CONFIG_KLIPS_ENC_AES_MAC
13332 + if (auth_id!=0){
13333 + int ret;
13334 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id=auth_id;
13335 + ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC);
13336 + printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
13337 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13338 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13339 + ipsec_alg_AES_MAC.ixt_common.ixt_name,
13340 + ret);
13341 + if (ret==0 && test_aes) {
13342 + test_ret=ipsec_alg_test(
13343 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13344 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13345 + test_aes);
13346 + printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
13347 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13348 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13349 + test_ret);
13350 + }
13351 + } else {
13352 + printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id);
13353 + }
13354 +#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13355 + return ret;
13356 +}
13357 +
13358 +#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13359 +IPSEC_ALG_MODULE_EXIT_MOD( ipsec_aes_fini )
13360 +#else
13361 +IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_aes_fini )
13362 +#endif
13363 +{
13364 +#if CONFIG_KLIPS_ENC_AES_MAC
13365 + if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC);
13366 +#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13367 + unregister_ipsec_alg_enc(&ipsec_alg_AES);
13368 + return;
13369 +}
13370 +#ifdef MODULE_LICENSE
13371 +MODULE_LICENSE("GPL");
13372 +#endif
13373 +
13374 +#if 0 /* +NOT_YET */
13375 +#ifndef MODULE
13376 +/*
13377 + * This is intended for static module setups, currently
13378 + * doesn't work for modular ipsec.o with static algos inside
13379 + */
13380 +static int setup_keybits(const char *str)
13381 +{
13382 + unsigned aux;
13383 + char *end;
13384 +
13385 + aux = simple_strtoul(str,&end,0);
13386 + if (aux != 128 && aux != 192 && aux != 256)
13387 + return 0;
13388 + keyminbits = aux;
13389 +
13390 + if (*end == 0 || *end != ',')
13391 + return 1;
13392 + str=end+1;
13393 + aux = simple_strtoul(str, NULL, 0);
13394 + if (aux != 128 && aux != 192 && aux != 256)
13395 + return 0;
13396 + if (aux >= keyminbits)
13397 + keymaxbits = aux;
13398 + return 1;
13399 +}
13400 +__setup("ipsec_aes_keybits=", setup_keybits);
13401 +#endif
13402 +#endif
13403 +
13404 --- /dev/null Tue Mar 11 13:02:56 2003
13405 +++ linux/net/ipsec/alg/Config.alg_aes.in Mon Feb 9 13:51:03 2004
13406 @@ -0,0 +1,3 @@
13407 +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
13408 + tristate ' AES encryption algorithm' CONFIG_IPSEC_ENC_AES
13409 +fi
13410 --- /dev/null Tue Mar 11 13:02:56 2003
13411 +++ linux/net/ipsec/alg/Config.alg_cryptoapi.in Mon Feb 9 13:51:03 2004
13412 @@ -0,0 +1,6 @@
13413 +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
13414 + dep_tristate ' CRYPTOAPI ciphers support (needs cryptoapi patch)' CONFIG_IPSEC_ALG_CRYPTOAPI $CONFIG_CRYPTO
13415 + if [ "$CONFIG_IPSEC_ALG_CRYPTOAPI" != "n" ]; then
13416 + bool ' CRYPTOAPI proprietary ciphers ' CONFIG_IPSEC_ALG_NON_LIBRE
13417 + fi
13418 +fi
13419 --- /dev/null Tue Mar 11 13:02:56 2003
13420 +++ linux/net/ipsec/alg/Config.in Mon Feb 9 13:51:03 2004
13421 @@ -0,0 +1,3 @@
13422 +#Placeholder
13423 +source net/ipsec/alg/Config.alg_aes.in
13424 +source net/ipsec/alg/Config.alg_cryptoapi.in
13425 --- /dev/null Tue Mar 11 13:02:56 2003
13426 +++ linux/net/ipsec/alg/Makefile.alg_aes Mon Feb 9 13:51:03 2004
13427 @@ -0,0 +1,18 @@
13428 +MOD_AES := ipsec_aes.o
13429 +
13430 +ALG_MODULES += $(MOD_AES)
13431 +ALG_SUBDIRS += libaes
13432 +
13433 +obj-$(CONFIG_IPSEC_ALG_AES) += $(MOD_AES)
13434 +static_init-func-$(CONFIG_IPSEC_ALG_AES)+= ipsec_aes_init
13435 +alg_obj-$(CONFIG_IPSEC_ALG_AES) += ipsec_alg_aes.o
13436 +
13437 +AES_OBJS := ipsec_alg_aes.o $(LIBCRYPTO)/libaes/libaes.a
13438 +
13439 +
13440 +$(MOD_AES): $(AES_OBJS)
13441 + $(LD) $(EXTRA_LDFLAGS) -r $(AES_OBJS) -o $@
13442 +
13443 +$(LIBCRYPTO)/libaes/libaes.a:
13444 + $(MAKE) -C $(LIBCRYPTO)/libaes CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' libaes.a
13445 +
13446 --- /dev/null Tue Mar 11 13:02:56 2003
13447 +++ linux/net/ipsec/alg/Makefile.alg_cryptoapi Mon Feb 9 13:51:03 2004
13448 @@ -0,0 +1,14 @@
13449 +MOD_CRYPTOAPI := ipsec_cryptoapi.o
13450 +
13451 +ifneq ($(wildcard $(TOPDIR)/include/linux/crypto.h),)
13452 +ALG_MODULES += $(MOD_CRYPTOAPI)
13453 +obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += $(MOD_CRYPTOAPI)
13454 +static_init-func-$(CONFIG_IPSEC_ALG_CRYPTOAPI)+= ipsec_cryptoapi_init
13455 +alg_obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += ipsec_alg_cryptoapi.o
13456 +else
13457 +$(warning "Linux CryptoAPI (2.4.22+ or 2.6.x) not found, not building ipsec_cryptoapi.o")
13458 +endif
13459 +
13460 +CRYPTOAPI_OBJS := ipsec_alg_cryptoapi.o
13461 +$(MOD_CRYPTOAPI): $(CRYPTOAPI_OBJS)
13462 + $(LD) -r $(CRYPTOAPI_OBJS) -o $@
13463 --- /dev/null Tue Mar 11 13:02:56 2003
13464 +++ linux/net/ipsec/alg/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
13465 @@ -0,0 +1,442 @@
13466 +/*
13467 + * ipsec_alg to linux cryptoapi GLUE
13468 + *
13469 + * Authors: CODE.ar TEAM
13470 + * Harpo MAxx <harpo@linuxmendoza.org.ar>
13471 + * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
13472 + * Luciano Ruete <docemeses@softhome.net>
13473 + *
13474 + * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
13475 + *
13476 + * This program is free software; you can redistribute it and/or modify it
13477 + * under the terms of the GNU General Public License as published by the
13478 + * Free Software Foundation; either version 2 of the License, or (at your
13479 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13480 + *
13481 + * This program is distributed in the hope that it will be useful, but
13482 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13483 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13484 + * for more details.
13485 + *
13486 + * Example usage:
13487 + * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
13488 + * modprobe ipsec_cryptoapi
13489 + * modprobe ipsec_cryptoapi test=1
13490 + * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
13491 + * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
13492 + * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
13493 + * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
13494 + */
13495 +#ifndef AUTOCONF_INCLUDED
13496 +#include <linux/config.h>
13497 +#endif
13498 +#include <linux/version.h>
13499 +
13500 +/*
13501 + * special case: ipsec core modular with this static algo inside:
13502 + * must avoid MODULE magic for this file
13503 + */
13504 +#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI
13505 +#undef MODULE
13506 +#endif
13507 +
13508 +#include <linux/module.h>
13509 +#include <linux/init.h>
13510 +
13511 +#include <linux/kernel.h> /* printk() */
13512 +#include <linux/errno.h> /* error codes */
13513 +#include <linux/types.h> /* size_t */
13514 +#include <linux/string.h>
13515 +
13516 +/* Check if __exit is defined, if not null it */
13517 +#ifndef __exit
13518 +#define __exit
13519 +#endif
13520 +
13521 +/* warn the innocent */
13522 +#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
13523 +#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
13524 +#define NO_CRYPTOAPI_SUPPORT
13525 +#endif
13526 +/* Low freeswan header coupling */
13527 +#include "openswan/ipsec_alg.h"
13528 +
13529 +#include <linux/crypto.h>
13530 +#ifdef CRYPTO_API_VERSION_CODE
13531 +#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
13532 +#define NO_CRYPTOAPI_SUPPORT
13533 +#endif
13534 +
13535 +#ifdef NO_CRYPTOAPI_SUPPORT
13536 +#warning "Building an unusable module :P"
13537 +/* Catch old CryptoAPI by not allowing module to load */
13538 +IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
13539 +{
13540 + printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
13541 + return -EINVAL;
13542 +}
13543 +#else
13544 +#include <asm/scatterlist.h>
13545 +#include <asm/pgtable.h>
13546 +#include <linux/mm.h>
13547 +
13548 +#define CIPHERNAME_AES "aes"
13549 +#define CIPHERNAME_3DES "des3_ede"
13550 +#define CIPHERNAME_BLOWFISH "blowfish"
13551 +#define CIPHERNAME_CAST "cast5"
13552 +#define CIPHERNAME_SERPENT "serpent"
13553 +#define CIPHERNAME_TWOFISH "twofish"
13554 +
13555 +#define ESP_3DES 3
13556 +#define ESP_AES 12
13557 +#define ESP_BLOWFISH 7 /* truely _constant_ :) */
13558 +#define ESP_CAST 6 /* quite constant :) */
13559 +#define ESP_SERPENT 252 /* from ipsec drafts */
13560 +#define ESP_TWOFISH 253 /* from ipsec drafts */
13561 +
13562 +#define AH_MD5 2
13563 +#define AH_SHA 3
13564 +#define DIGESTNAME_MD5 "md5"
13565 +#define DIGESTNAME_SHA1 "sha1"
13566 +
13567 +MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
13568 +static int debug=0;
13569 +static int test=0;
13570 +static int excl=0;
13571 +#ifdef module_param
13572 +module_param(debug, int, 0664);
13573 +module_param(test, int, 0664);
13574 +module_param(excl, int, 0664);
13575 +#else
13576 +MODULE_PARM(debug, "i");
13577 +MODULE_PARM(test, "i");
13578 +MODULE_PARM(excl, "i");
13579 +#endif
13580 +
13581 +static int noauto = 0;
13582 +#ifdef module_param
13583 +module_param(noauto,int, 0664);
13584 +#else
13585 +MODULE_PARM(noauto,"i");
13586 +#endif
13587 +MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
13588 +
13589 +static int des_ede3[] = {-1, -1};
13590 +static int aes[] = {-1, -1};
13591 +static int blowfish[] = {-1, -1};
13592 +static int cast[] = {-1, -1};
13593 +static int serpent[] = {-1, -1};
13594 +static int twofish[] = {-1, -1};
13595 +
13596 +#ifdef module_param_array
13597 +module_param_array(des_ede3,int,NULL,0);
13598 +module_param_array(aes,int,NULL,0);
13599 +module_param_array(blowfish,int,NULL,0);
13600 +module_param_array(cast,int,NULL,0);
13601 +module_param_array(serpent,int,NULL,0);
13602 +module_param_array(twofish,int,NULL,0);
13603 +#else
13604 +MODULE_PARM(des_ede3,"1-2i");
13605 +MODULE_PARM(aes,"1-2i");
13606 +MODULE_PARM(blowfish,"1-2i");
13607 +MODULE_PARM(cast,"1-2i");
13608 +MODULE_PARM(serpent,"1-2i");
13609 +MODULE_PARM(twofish,"1-2i");
13610 +#endif
13611 +MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
13612 +MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
13613 +MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
13614 +MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
13615 +MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
13616 +MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
13617 +
13618 +struct ipsec_alg_capi_cipher {
13619 + const char *ciphername; /* cryptoapi's ciphername */
13620 + unsigned blocksize;
13621 + unsigned short minbits;
13622 + unsigned short maxbits;
13623 + int *parm; /* lkm param for this cipher */
13624 + struct ipsec_alg_enc alg; /* note it's not a pointer */
13625 +};
13626 +static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
13627 + { CIPHERNAME_AES , 16, 128, 256, aes , { ixt_alg_id: ESP_AES, }},
13628 + { CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }},
13629 + { CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }},
13630 + { CIPHERNAME_CAST , 8, 128, 128, cast , { ixt_alg_id: ESP_CAST, }},
13631 + { CIPHERNAME_BLOWFISH , 8, 96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }},
13632 + { CIPHERNAME_3DES , 8, 192, 192, des_ede3,{ ixt_alg_id: ESP_3DES, }},
13633 + { NULL, 0, 0, 0, NULL, {} }
13634 +};
13635 +#ifdef NOT_YET
13636 +struct ipsec_alg_capi_digest {
13637 + const char *digestname; /* cryptoapi's digestname */
13638 + struct digest_implementation *di;
13639 + struct ipsec_alg_auth alg; /* note it's not a pointer */
13640 +};
13641 +static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
13642 + { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
13643 + { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
13644 + { NULL, NULL, {} }
13645 +};
13646 +#endif
13647 +/*
13648 + * "generic" linux cryptoapi setup_cipher() function
13649 + */
13650 +int setup_cipher(const char *ciphername)
13651 +{
13652 + return crypto_alg_available(ciphername, 0);
13653 +}
13654 +
13655 +/*
13656 + * setups ipsec_alg_capi_cipher "hyper" struct components, calling
13657 + * register_ipsec_alg for cointaned ipsec_alg object
13658 + */
13659 +static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
13660 +static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
13661 +static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
13662 +
13663 +static int
13664 +setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
13665 +{
13666 + int ret;
13667 + cptr->alg.ixt_version = IPSEC_ALG_VERSION;
13668 + cptr->alg.ixt_module = THIS_MODULE;
13669 + atomic_set (& cptr->alg.ixt_refcnt, 0);
13670 + strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name));
13671 +
13672 + cptr->alg.ixt_blocksize=cptr->blocksize;
13673 + cptr->alg.ixt_keyminbits=cptr->minbits;
13674 + cptr->alg.ixt_keymaxbits=cptr->maxbits;
13675 + cptr->alg.ixt_state = 0;
13676 + if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL;
13677 + cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8;
13678 + cptr->alg.ixt_e_ctx_size = 0;
13679 + cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT;
13680 + cptr->alg.ixt_e_new_key = _capi_new_key;
13681 + cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
13682 + cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
13683 + cptr->alg.ixt_data = cptr;
13684 +
13685 + ret=register_ipsec_alg_enc(&cptr->alg);
13686 + printk("setup_ipsec_alg_capi_cipher(): "
13687 + "alg_type=%d alg_id=%d name=%s "
13688 + "keyminbits=%d keymaxbits=%d, ret=%d\n",
13689 + cptr->alg.ixt_alg_type,
13690 + cptr->alg.ixt_alg_id,
13691 + cptr->alg.ixt_name,
13692 + cptr->alg.ixt_keyminbits,
13693 + cptr->alg.ixt_keymaxbits,
13694 + ret);
13695 + return ret;
13696 +}
13697 +/*
13698 + * called in ipsec_sa_wipe() time, will destroy key contexts
13699 + * and do 1 unbind()
13700 + */
13701 +static void
13702 +_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
13703 +{
13704 + struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
13705 +
13706 + if (debug > 0)
13707 + printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
13708 + "name=%s key_e=%p \n",
13709 + alg->ixt_name, key_e);
13710 + if (!key_e) {
13711 + printk(KERN_ERR "klips_debug: _capi_destroy_key:"
13712 + "name=%s NULL key_e!\n",
13713 + alg->ixt_name);
13714 + return;
13715 + }
13716 + crypto_free_tfm(tfm);
13717 +}
13718 +
13719 +/*
13720 + * create new key context, need alg->ixt_data to know which
13721 + * (of many) cipher inside this module is the target
13722 + */
13723 +static __u8 *
13724 +_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
13725 +{
13726 + struct ipsec_alg_capi_cipher *cptr;
13727 + struct crypto_tfm *tfm=NULL;
13728 +
13729 + cptr = alg->ixt_data;
13730 + if (!cptr) {
13731 + printk(KERN_ERR "_capi_new_key(): "
13732 + "NULL ixt_data (?!) for \"%s\" algo\n"
13733 + , alg->ixt_name);
13734 + goto err;
13735 + }
13736 + if (debug > 0)
13737 + printk(KERN_DEBUG "klips_debug:_capi_new_key:"
13738 + "name=%s cptr=%p key=%p keysize=%d\n",
13739 + alg->ixt_name, cptr, key, keylen);
13740 +
13741 + /*
13742 + * alloc tfm
13743 + */
13744 + tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
13745 + if (!tfm) {
13746 + printk(KERN_ERR "_capi_new_key(): "
13747 + "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
13748 + , alg->ixt_name, cptr->ciphername);
13749 + goto err;
13750 + }
13751 + if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
13752 + printk(KERN_ERR "_capi_new_key(): "
13753 + "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
13754 + , alg->ixt_name, keylen);
13755 + crypto_free_tfm(tfm);
13756 + tfm=NULL;
13757 + }
13758 +err:
13759 + if (debug > 0)
13760 + printk(KERN_DEBUG "klips_debug:_capi_new_key:"
13761 + "name=%s key=%p keylen=%d tfm=%p\n",
13762 + alg->ixt_name, key, keylen, tfm);
13763 + return (__u8 *) tfm;
13764 +}
13765 +/*
13766 + * core encryption function: will use cx->ci to call actual cipher's
13767 + * cbc function
13768 + */
13769 +static int
13770 +_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
13771 + int error =0;
13772 + struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
13773 + struct scatterlist sg = {
13774 + .page = virt_to_page(in),
13775 + .offset = (unsigned long)(in) % PAGE_SIZE,
13776 + .length=ilen,
13777 + };
13778 + if (debug > 1)
13779 + printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
13780 + "key_e=%p "
13781 + "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
13782 + , key_e
13783 + , in, in, ilen, iv, encrypt);
13784 + crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
13785 + if (encrypt)
13786 + error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
13787 + else
13788 + error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
13789 + if (debug > 1)
13790 + printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
13791 + "error=%d\n"
13792 + , error);
13793 + return (error<0)? error : ilen;
13794 +}
13795 +/*
13796 + * main initialization loop: for each cipher in list, do
13797 + * 1) setup cryptoapi cipher else continue
13798 + * 2) register ipsec_alg object
13799 + */
13800 +static int
13801 +setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
13802 +{
13803 + struct ipsec_alg_capi_cipher *cptr;
13804 + /* foreach cipher in list ... */
13805 + for (cptr=clist;cptr->ciphername;cptr++) {
13806 + /*
13807 + * see if cipher has been disabled (0) or
13808 + * if noauto set and not enabled (1)
13809 + */
13810 + if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
13811 + if (debug>0)
13812 + printk(KERN_INFO "setup_cipher_list(): "
13813 + "ciphername=%s skipped at user request: "
13814 + "noauto=%d parm[0]=%d parm[1]=%d\n"
13815 + , cptr->ciphername
13816 + , noauto
13817 + , cptr->parm[0]
13818 + , cptr->parm[1]);
13819 + continue;
13820 + }
13821 + /*
13822 + * use a local ci to avoid touching cptr->ci,
13823 + * if register ipsec_alg success then bind cipher
13824 + */
13825 + if( setup_cipher(cptr->ciphername) ) {
13826 + if (debug > 0)
13827 + printk(KERN_DEBUG "klips_debug:"
13828 + "setup_cipher_list():"
13829 + "ciphername=%s found\n"
13830 + , cptr->ciphername);
13831 + if (setup_ipsec_alg_capi_cipher(cptr) == 0) {
13832 +
13833 +
13834 + } else {
13835 + printk(KERN_ERR "klips_debug:"
13836 + "setup_cipher_list():"
13837 + "ciphername=%s failed ipsec_alg_register\n"
13838 + , cptr->ciphername);
13839 + }
13840 + } else {
13841 + if (debug>0)
13842 + printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n",
13843 + cptr->ciphername);
13844 + }
13845 + }
13846 + return 0;
13847 +}
13848 +/*
13849 + * deregister ipsec_alg objects and unbind ciphers
13850 + */
13851 +static int
13852 +unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
13853 +{
13854 + struct ipsec_alg_capi_cipher *cptr;
13855 + /* foreach cipher in list ... */
13856 + for (cptr=clist;cptr->ciphername;cptr++) {
13857 + if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
13858 + unregister_ipsec_alg_enc(&cptr->alg);
13859 + }
13860 + }
13861 + return 0;
13862 +}
13863 +/*
13864 + * test loop for registered algos
13865 + */
13866 +static int
13867 +test_cipher_list (struct ipsec_alg_capi_cipher* clist)
13868 +{
13869 + int test_ret;
13870 + struct ipsec_alg_capi_cipher *cptr;
13871 + /* foreach cipher in list ... */
13872 + for (cptr=clist;cptr->ciphername;cptr++) {
13873 + if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
13874 + test_ret=ipsec_alg_test(
13875 + cptr->alg.ixt_alg_type,
13876 + cptr->alg.ixt_alg_id,
13877 + test);
13878 + printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
13879 + cptr->alg.ixt_alg_type,
13880 + cptr->alg.ixt_alg_id,
13881 + test_ret);
13882 + }
13883 + }
13884 + return 0;
13885 +}
13886 +
13887 +IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
13888 +{
13889 + int ret, test_ret;
13890 + if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
13891 + return -EPROTONOSUPPORT;
13892 + if (ret==0 && test) {
13893 + test_ret=test_cipher_list(alg_capi_carray);
13894 + }
13895 + return ret;
13896 +}
13897 +IPSEC_ALG_MODULE_EXIT( ipsec_cryptoapi_fini )
13898 +{
13899 + unsetup_cipher_list(alg_capi_carray);
13900 + return;
13901 +}
13902 +#ifdef MODULE_LICENSE
13903 +MODULE_LICENSE("GPL");
13904 +#endif
13905 +
13906 +EXPORT_NO_SYMBOLS;
13907 +#endif /* NO_CRYPTOAPI_SUPPORT */
13908 --- /dev/null Tue Mar 11 13:02:56 2003
13909 +++ linux/net/ipsec/alg/scripts/mk-static_init.c.sh Mon Feb 9 13:51:03 2004
13910 @@ -0,0 +1,18 @@
13911 +#!/bin/sh
13912 +cat << EOF
13913 +#include <linux/kernel.h>
13914 +#include <linux/list.h>
13915 +#include "freeswan/ipsec_alg.h"
13916 +$(for i in $*; do
13917 + test -z "$i" && continue
13918 + echo "extern int $i(void);"
13919 +done)
13920 +void ipsec_alg_static_init(void){
13921 + int __attribute__ ((unused)) err=0;
13922 +$(for i in $*; do
13923 + test -z "$i" && continue
13924 + echo " if ((err=$i()) < 0)"
13925 + echo " printk(KERN_WARNING \"$i() returned %d\", err);"
13926 +done)
13927 +}
13928 +EOF
13929 --- /dev/null Tue Mar 11 13:02:56 2003
13930 +++ linux/net/ipsec/anyaddr.c Mon Feb 9 13:51:03 2004
13931 @@ -0,0 +1,150 @@
13932 +/*
13933 + * special addresses
13934 + * Copyright (C) 2000 Henry Spencer.
13935 + *
13936 + * This library is free software; you can redistribute it and/or modify it
13937 + * under the terms of the GNU Library General Public License as published by
13938 + * the Free Software Foundation; either version 2 of the License, or (at your
13939 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
13940 + *
13941 + * This library is distributed in the hope that it will be useful, but
13942 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13943 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13944 + * License for more details.
13945 + *
13946 + * RCSID $Id: anyaddr.c,v 1.10 2004/07/10 07:43:47 mcr Exp $
13947 + */
13948 +#include "openswan.h"
13949 +
13950 +/* these are mostly fallbacks for the no-IPv6-support-in-library case */
13951 +#ifndef IN6ADDR_ANY_INIT
13952 +#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
13953 +#endif
13954 +#ifndef IN6ADDR_LOOPBACK_INIT
13955 +#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}
13956 +#endif
13957 +
13958 +static struct in6_addr v6any = IN6ADDR_ANY_INIT;
13959 +static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT;
13960 +
13961 +/*
13962 + - anyaddr - initialize to the any-address value
13963 + */
13964 +err_t /* NULL for success, else string literal */
13965 +anyaddr(af, dst)
13966 +int af; /* address family */
13967 +ip_address *dst;
13968 +{
13969 + uint32_t v4any = htonl(INADDR_ANY);
13970 +
13971 + switch (af) {
13972 + case AF_INET:
13973 + return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst);
13974 + break;
13975 + case AF_INET6:
13976 + return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst);
13977 + break;
13978 + default:
13979 + return "unknown address family in anyaddr/unspecaddr";
13980 + break;
13981 + }
13982 +}
13983 +
13984 +/*
13985 + - unspecaddr - initialize to the unspecified-address value
13986 + */
13987 +err_t /* NULL for success, else string literal */
13988 +unspecaddr(af, dst)
13989 +int af; /* address family */
13990 +ip_address *dst;
13991 +{
13992 + return anyaddr(af, dst);
13993 +}
13994 +
13995 +/*
13996 + - loopbackaddr - initialize to the loopback-address value
13997 + */
13998 +err_t /* NULL for success, else string literal */
13999 +loopbackaddr(af, dst)
14000 +int af; /* address family */
14001 +ip_address *dst;
14002 +{
14003 + uint32_t v4loop = htonl(INADDR_LOOPBACK);
14004 +
14005 + switch (af) {
14006 + case AF_INET:
14007 + return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst);
14008 + break;
14009 + case AF_INET6:
14010 + return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst);
14011 + break;
14012 + default:
14013 + return "unknown address family in loopbackaddr";
14014 + break;
14015 + }
14016 +}
14017 +
14018 +/*
14019 + - isanyaddr - test for the any-address value
14020 + */
14021 +int
14022 +isanyaddr(src)
14023 +const ip_address *src;
14024 +{
14025 + uint32_t v4any = htonl(INADDR_ANY);
14026 + int cmp;
14027 +
14028 + switch (src->u.v4.sin_family) {
14029 + case AF_INET:
14030 + cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any));
14031 + break;
14032 + case AF_INET6:
14033 + cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any));
14034 + break;
14035 +
14036 + case 0:
14037 + /* a zeroed structure is considered any address */
14038 + return 1;
14039 +
14040 + default:
14041 + return 0;
14042 + break;
14043 + }
14044 +
14045 + return (cmp == 0) ? 1 : 0;
14046 +}
14047 +
14048 +/*
14049 + - isunspecaddr - test for the unspecified-address value
14050 + */
14051 +int
14052 +isunspecaddr(src)
14053 +const ip_address *src;
14054 +{
14055 + return isanyaddr(src);
14056 +}
14057 +
14058 +/*
14059 + - isloopbackaddr - test for the loopback-address value
14060 + */
14061 +int
14062 +isloopbackaddr(src)
14063 +const ip_address *src;
14064 +{
14065 + uint32_t v4loop = htonl(INADDR_LOOPBACK);
14066 + int cmp;
14067 +
14068 + switch (src->u.v4.sin_family) {
14069 + case AF_INET:
14070 + cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop));
14071 + break;
14072 + case AF_INET6:
14073 + cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop));
14074 + break;
14075 + default:
14076 + return 0;
14077 + break;
14078 + }
14079 +
14080 + return (cmp == 0) ? 1 : 0;
14081 +}
14082 --- /dev/null Tue Mar 11 13:02:56 2003
14083 +++ linux/net/ipsec/datatot.c Mon Feb 9 13:51:03 2004
14084 @@ -0,0 +1,234 @@
14085 +/*
14086 + * convert from binary data (e.g. key) to text form
14087 + * Copyright (C) 2000 Henry Spencer.
14088 + *
14089 + * This library is free software; you can redistribute it and/or modify it
14090 + * under the terms of the GNU Library General Public License as published by
14091 + * the Free Software Foundation; either version 2 of the License, or (at your
14092 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
14093 + *
14094 + * This library is distributed in the hope that it will be useful, but
14095 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14096 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14097 + * License for more details.
14098 + *
14099 + * RCSID $Id: datatot.c,v 1.9 2005/08/30 21:15:26 mcr Exp $
14100 + */
14101 +#include "openswan.h"
14102 +
14103 +static void convert(const char *src, size_t nreal, int format, char *out);
14104 +
14105 +/*
14106 + - datatot - convert data bytes to text
14107 + */
14108 +size_t /* true length (with NUL) for success */
14109 +datatot(src, srclen, format, dst, dstlen)
14110 +const unsigned char *src;
14111 +size_t srclen;
14112 +int format; /* character indicating what format */
14113 +char *dst; /* need not be valid if dstlen is 0 */
14114 +size_t dstlen;
14115 +{
14116 + size_t inblocksize; /* process this many bytes at a time */
14117 + size_t outblocksize; /* producing this many */
14118 + size_t breakevery; /* add a _ every this many (0 means don't) */
14119 + size_t sincebreak; /* output bytes since last _ */
14120 + char breakchar; /* character used to break between groups */
14121 + unsigned char inblock[10]; /* enough for any format */
14122 + char outblock[10]; /* enough for any format */
14123 + char fake[1]; /* fake output area for dstlen == 0 */
14124 + size_t needed; /* return value */
14125 + char *stop; /* where the terminating NUL will go */
14126 + size_t ntodo; /* remaining input */
14127 + size_t nreal;
14128 + char *out;
14129 + char *prefix;
14130 +
14131 + breakevery = 0;
14132 + breakchar = '_';
14133 +
14134 + switch (format) {
14135 + case 0:
14136 + case 'h':
14137 + format = 'x';
14138 + breakevery = 8;
14139 + /* FALLTHROUGH */
14140 + case 'x':
14141 + inblocksize = 1;
14142 + outblocksize = 2;
14143 + prefix = "0x";
14144 + break;
14145 + case ':':
14146 + format = 'x';
14147 + breakevery = 2;
14148 + breakchar = ':';
14149 + /* FALLTHROUGH */
14150 + case 16:
14151 + inblocksize = 1;
14152 + outblocksize = 2;
14153 + prefix = "";
14154 + format = 'x';
14155 + break;
14156 + case 's':
14157 + inblocksize = 3;
14158 + outblocksize = 4;
14159 + prefix = "0s";
14160 + break;
14161 + case 64: /* beware, equals ' ' */
14162 + inblocksize = 3;
14163 + outblocksize = 4;
14164 + prefix = "";
14165 + format = 's';
14166 + break;
14167 + default:
14168 + return 0;
14169 + break;
14170 + }
14171 +
14172 + user_assert(inblocksize < sizeof(inblock));
14173 + user_assert(outblocksize < sizeof(outblock));
14174 + user_assert(breakevery % outblocksize == 0);
14175 +
14176 + if (srclen == 0)
14177 + return 0;
14178 + ntodo = srclen;
14179 +
14180 + if (dstlen == 0) { /* dispose of awkward special case */
14181 + dst = fake;
14182 + dstlen = 1;
14183 + }
14184 + stop = dst + dstlen - 1;
14185 +
14186 + nreal = strlen(prefix);
14187 + needed = nreal; /* for starters */
14188 + if (dstlen <= nreal) { /* prefix won't fit */
14189 + strncpy(dst, prefix, dstlen - 1);
14190 + dst += dstlen - 1;
14191 + } else {
14192 + strcpy(dst, prefix);
14193 + dst += nreal;
14194 + }
14195 +
14196 + user_assert(dst <= stop);
14197 + sincebreak = 0;
14198 +
14199 + while (ntodo > 0) {
14200 + if (ntodo < inblocksize) { /* incomplete input */
14201 + memset(inblock, 0, sizeof(inblock));
14202 + memcpy(inblock, src, ntodo);
14203 + src = inblock;
14204 + nreal = ntodo;
14205 + ntodo = inblocksize;
14206 + } else
14207 + nreal = inblocksize;
14208 + out = (outblocksize > stop - dst) ? outblock : dst;
14209 +
14210 + convert((const char *)src, nreal, format, out);
14211 + needed += outblocksize;
14212 + sincebreak += outblocksize;
14213 + if (dst < stop) {
14214 + if (out != dst) {
14215 + user_assert(outblocksize > stop - dst);
14216 + memcpy(dst, out, stop - dst);
14217 + dst = stop;
14218 + } else
14219 + dst += outblocksize;
14220 + }
14221 +
14222 + src += inblocksize;
14223 + ntodo -= inblocksize;
14224 + if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) {
14225 + if (dst < stop)
14226 + *dst++ = breakchar;
14227 + needed++;
14228 + sincebreak = 0;
14229 + }
14230 + }
14231 +
14232 + user_assert(dst <= stop);
14233 + *dst++ = '\0';
14234 + needed++;
14235 +
14236 + return needed;
14237 +}
14238 +
14239 +/*
14240 + - convert - convert one input block to one output block
14241 + */
14242 +static void
14243 +convert(src, nreal, format, out)
14244 +const char *src;
14245 +size_t nreal; /* how much of the input block is real */
14246 +int format;
14247 +char *out;
14248 +{
14249 + static char hex[] = "0123456789abcdef";
14250 + static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
14251 + "abcdefghijklmnopqrstuvwxyz"
14252 + "0123456789+/";
14253 + unsigned char c;
14254 + unsigned char c1, c2, c3;
14255 +
14256 + user_assert(nreal > 0);
14257 + switch (format) {
14258 + case 'x':
14259 + user_assert(nreal == 1);
14260 + c = (unsigned char)*src;
14261 + *out++ = hex[c >> 4];
14262 + *out++ = hex[c & 0xf];
14263 + break;
14264 + case 's':
14265 + c1 = (unsigned char)*src++;
14266 + c2 = (unsigned char)*src++;
14267 + c3 = (unsigned char)*src++;
14268 + *out++ = base64[c1 >> 2]; /* top 6 bits of c1 */
14269 + c = (c1 & 0x3) << 4; /* bottom 2 of c1... */
14270 + c |= c2 >> 4; /* ...top 4 of c2 */
14271 + *out++ = base64[c];
14272 + if (nreal == 1)
14273 + *out++ = '=';
14274 + else {
14275 + c = (c2 & 0xf) << 2; /* bottom 4 of c2... */
14276 + c |= c3 >> 6; /* ...top 2 of c3 */
14277 + *out++ = base64[c];
14278 + }
14279 + if (nreal <= 2)
14280 + *out++ = '=';
14281 + else
14282 + *out++ = base64[c3 & 0x3f]; /* bottom 6 of c3 */
14283 + break;
14284 + default:
14285 + user_assert(nreal == 0); /* unknown format */
14286 + break;
14287 + }
14288 +}
14289 +
14290 +/*
14291 + - datatoa - convert data to ASCII
14292 + * backward-compatibility synonym for datatot
14293 + */
14294 +size_t /* true length (with NUL) for success */
14295 +datatoa(src, srclen, format, dst, dstlen)
14296 +const unsigned char *src;
14297 +size_t srclen;
14298 +int format; /* character indicating what format */
14299 +char *dst; /* need not be valid if dstlen is 0 */
14300 +size_t dstlen;
14301 +{
14302 + return datatot(src, srclen, format, dst, dstlen);
14303 +}
14304 +
14305 +/*
14306 + - bytestoa - convert data bytes to ASCII
14307 + * backward-compatibility synonym for datatot
14308 + */
14309 +size_t /* true length (with NUL) for success */
14310 +bytestoa(src, srclen, format, dst, dstlen)
14311 +const unsigned char *src;
14312 +size_t srclen;
14313 +int format; /* character indicating what format */
14314 +char *dst; /* need not be valid if dstlen is 0 */
14315 +size_t dstlen;
14316 +{
14317 + return datatot(src, srclen, format, dst, dstlen);
14318 +}
14319 --- /dev/null Tue Mar 11 13:02:56 2003
14320 +++ linux/net/ipsec/defconfig Mon Feb 9 13:51:03 2004
14321 @@ -0,0 +1,147 @@
14322 +
14323 +#
14324 +# RCSID $Id: defconfig,v 1.30 2005/09/15 02:31:12 paul Exp $
14325 +#
14326 +
14327 +#
14328 +# Openswan IPSec implementation, KLIPS kernel config defaults
14329 +#
14330 +
14331 +#
14332 +# First, lets override stuff already set or not in the kernel config.
14333 +#
14334 +# We can't even think about leaving this off...
14335 +CONFIG_INET=y
14336 +
14337 +#
14338 +# This must be on for subnet protection.
14339 +CONFIG_IP_FORWARD=y
14340 +
14341 +# Shut off IPSEC masquerading if it has been enabled, since it will
14342 +# break the compile. IPPROTO_ESP and IPPROTO_AH were included in
14343 +# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h.
14344 +CONFIG_IP_MASQUERADE_IPSEC=n
14345 +
14346 +#
14347 +# Next, lets set the recommended FreeS/WAN configuration.
14348 +#
14349 +
14350 +# To config as static (preferred), 'y'. To config as module, 'm'.
14351 +CONFIG_KLIPS=m
14352 +
14353 +# To do tunnel mode IPSec, this must be enabled.
14354 +CONFIG_KLIPS_IPIP=y
14355 +
14356 +# To enable authentication, say 'y'. (Highly recommended)
14357 +CONFIG_KLIPS_AH=y
14358 +
14359 +# Authentication algorithm(s):
14360 +CONFIG_KLIPS_AUTH_HMAC_MD5=y
14361 +CONFIG_KLIPS_AUTH_HMAC_SHA1=y
14362 +
14363 +# To enable encryption, say 'y'. (Highly recommended)
14364 +CONFIG_KLIPS_ESP=y
14365 +
14366 +# modular algo extensions (and new ALGOs)
14367 +CONFIG_KLIPS_ALG=y
14368 +
14369 +# Encryption algorithm(s):
14370 +CONFIG_KLIPS_ENC_3DES=y
14371 +CONFIG_KLIPS_ENC_AES=y
14372 +
14373 +# Use CryptoAPI for ALG? - by default, no.
14374 +CONFIG_KLIPS_ENC_CRYPTOAPI=n
14375 +
14376 +# IP Compression: new, probably still has minor bugs.
14377 +CONFIG_KLIPS_IPCOMP=y
14378 +
14379 +# To enable userspace-switchable KLIPS debugging, say 'y'.
14380 +CONFIG_KLIPS_DEBUG=y
14381 +
14382 +#
14383 +#
14384 +# $Log: defconfig,v $
14385 +# Revision 1.30 2005/09/15 02:31:12 paul
14386 +# Changed a FreeS/WAN occurance to Openswan
14387 +#
14388 +# Revision 1.29 2005/08/24 22:10:05 mcr
14389 +# do not list NAT_TRAVERSAL as a default for KLIPS,
14390 +# let it live in the packaging "MODULE_DEF_CONFIG" files.
14391 +#
14392 +# Revision 1.28 2005/05/11 03:15:42 mcr
14393 +# adjusted makefiles to sanely build modules properly.
14394 +#
14395 +# Revision 1.27 2005/03/20 03:00:05 mcr
14396 +# default configuration should enable NAT_TRAVERSAL.
14397 +#
14398 +# Revision 1.26 2004/07/10 19:11:18 mcr
14399 +# CONFIG_IPSEC -> CONFIG_KLIPS.
14400 +#
14401 +# Revision 1.25 2004/07/05 01:03:53 mcr
14402 +# fix for adding cryptoapi code.
14403 +# keep it off for now, since UMLs do not have it yet.
14404 +#
14405 +# Revision 1.24 2004/04/06 02:49:25 mcr
14406 +# pullup of algo code from alg-branch.
14407 +#
14408 +# Revision 1.23.2.2 2004/04/05 04:30:46 mcr
14409 +# patches for alg-branch to compile/work with 2.x openswan
14410 +#
14411 +# Revision 1.23.2.1 2003/12/22 15:25:52 jjo
14412 +# . Merged algo-0.8.1-rc11-test1 into alg-branch
14413 +#
14414 +# Revision 1.23 2003/12/10 01:14:27 mcr
14415 +# NAT-traversal patches to KLIPS.
14416 +#
14417 +# Revision 1.22 2003/02/24 19:37:27 mcr
14418 +# changed default compilation mode to static.
14419 +#
14420 +# Revision 1.21 2002/04/24 07:36:27 mcr
14421 +# Moved from ./klips/net/ipsec/defconfig,v
14422 +#
14423 +# Revision 1.20 2002/04/02 04:07:40 mcr
14424 +# default build is now 'm'odule for KLIPS
14425 +#
14426 +# Revision 1.19 2002/03/08 18:57:17 rgb
14427 +# Added a blank line at the beginning of the file to make it easier for
14428 +# other projects to patch ./arch/i386/defconfig, for example
14429 +# LIDS+grSecurity requested by Jason Pattie.
14430 +#
14431 +# Revision 1.18 2000/11/30 17:26:56 rgb
14432 +# Cleaned out unused options and enabled ipcomp by default.
14433 +#
14434 +# Revision 1.17 2000/09/15 11:37:01 rgb
14435 +# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
14436 +# IPCOMP zlib deflate code.
14437 +#
14438 +# Revision 1.16 2000/09/08 19:12:55 rgb
14439 +# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
14440 +#
14441 +# Revision 1.15 2000/05/24 19:37:13 rgb
14442 +# *** empty log message ***
14443 +#
14444 +# Revision 1.14 2000/05/11 21:14:57 henry
14445 +# just commenting the FOOBAR=y lines out is not enough
14446 +#
14447 +# Revision 1.13 2000/05/10 20:17:58 rgb
14448 +# Comment out netlink defaults, which are no longer needed.
14449 +#
14450 +# Revision 1.12 2000/05/10 19:13:38 rgb
14451 +# Added configure option to shut off no eroute passthrough.
14452 +#
14453 +# Revision 1.11 2000/03/16 07:09:46 rgb
14454 +# Hardcode PF_KEYv2 support.
14455 +# Disable IPSEC_ICMP by default.
14456 +# Remove DES config option from defaults file.
14457 +#
14458 +# Revision 1.10 2000/01/11 03:09:42 rgb
14459 +# Added a default of 'y' to PF_KEYv2 keying I/F.
14460 +#
14461 +# Revision 1.9 1999/05/08 21:23:12 rgb
14462 +# Added support for 2.2.x kernels.
14463 +#
14464 +# Revision 1.8 1999/04/06 04:54:25 rgb
14465 +# Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
14466 +# patch shell fixes.
14467 +#
14468 +#
14469 --- /dev/null Tue Mar 11 13:02:56 2003
14470 +++ linux/net/ipsec/deflate.c Mon Feb 9 13:51:03 2004
14471 @@ -0,0 +1,1351 @@
14472 +/* deflate.c -- compress data using the deflation algorithm
14473 + * Copyright (C) 1995-2002 Jean-loup Gailly.
14474 + * For conditions of distribution and use, see copyright notice in zlib.h
14475 + */
14476 +
14477 +/*
14478 + * ALGORITHM
14479 + *
14480 + * The "deflation" process depends on being able to identify portions
14481 + * of the input text which are identical to earlier input (within a
14482 + * sliding window trailing behind the input currently being processed).
14483 + *
14484 + * The most straightforward technique turns out to be the fastest for
14485 + * most input files: try all possible matches and select the longest.
14486 + * The key feature of this algorithm is that insertions into the string
14487 + * dictionary are very simple and thus fast, and deletions are avoided
14488 + * completely. Insertions are performed at each input character, whereas
14489 + * string matches are performed only when the previous match ends. So it
14490 + * is preferable to spend more time in matches to allow very fast string
14491 + * insertions and avoid deletions. The matching algorithm for small
14492 + * strings is inspired from that of Rabin & Karp. A brute force approach
14493 + * is used to find longer strings when a small match has been found.
14494 + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
14495 + * (by Leonid Broukhis).
14496 + * A previous version of this file used a more sophisticated algorithm
14497 + * (by Fiala and Greene) which is guaranteed to run in linear amortized
14498 + * time, but has a larger average cost, uses more memory and is patented.
14499 + * However the F&G algorithm may be faster for some highly redundant
14500 + * files if the parameter max_chain_length (described below) is too large.
14501 + *
14502 + * ACKNOWLEDGEMENTS
14503 + *
14504 + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
14505 + * I found it in 'freeze' written by Leonid Broukhis.
14506 + * Thanks to many people for bug reports and testing.
14507 + *
14508 + * REFERENCES
14509 + *
14510 + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
14511 + * Available in ftp://ds.internic.net/rfc/rfc1951.txt
14512 + *
14513 + * A description of the Rabin and Karp algorithm is given in the book
14514 + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
14515 + *
14516 + * Fiala,E.R., and Greene,D.H.
14517 + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
14518 + *
14519 + */
14520 +
14521 +/* @(#) $Id: deflate.c,v 1.4 2004/07/10 07:48:37 mcr Exp $ */
14522 +
14523 +#include "deflate.h"
14524 +
14525 +local const char deflate_copyright[] =
14526 + " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly ";
14527 +/*
14528 + If you use the zlib library in a product, an acknowledgment is welcome
14529 + in the documentation of your product. If for some reason you cannot
14530 + include such an acknowledgment, I would appreciate that you keep this
14531 + copyright string in the executable of your product.
14532 + */
14533 +
14534 +/* ===========================================================================
14535 + * Function prototypes.
14536 + */
14537 +typedef enum {
14538 + need_more, /* block not completed, need more input or more output */
14539 + block_done, /* block flush performed */
14540 + finish_started, /* finish started, need only more output at next deflate */
14541 + finish_done /* finish done, accept no more input or output */
14542 +} block_state;
14543 +
14544 +typedef block_state (*compress_func) OF((deflate_state *s, int flush));
14545 +/* Compression function. Returns the block state after the call. */
14546 +
14547 +local void fill_window OF((deflate_state *s));
14548 +local block_state deflate_stored OF((deflate_state *s, int flush));
14549 +local block_state deflate_fast OF((deflate_state *s, int flush));
14550 +local block_state deflate_slow OF((deflate_state *s, int flush));
14551 +local void lm_init OF((deflate_state *s));
14552 +local void putShortMSB OF((deflate_state *s, uInt b));
14553 +local void flush_pending OF((z_streamp strm));
14554 +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
14555 +#ifdef ASMV
14556 + void match_init OF((void)); /* asm code initialization */
14557 + uInt longest_match OF((deflate_state *s, IPos cur_match));
14558 +#else
14559 +local uInt longest_match OF((deflate_state *s, IPos cur_match));
14560 +#endif
14561 +
14562 +#ifdef DEBUG
14563 +local void check_match OF((deflate_state *s, IPos start, IPos match,
14564 + int length));
14565 +#endif
14566 +
14567 +/* ===========================================================================
14568 + * Local data
14569 + */
14570 +
14571 +#define NIL 0
14572 +/* Tail of hash chains */
14573 +
14574 +#ifndef TOO_FAR
14575 +# define TOO_FAR 4096
14576 +#endif
14577 +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
14578 +
14579 +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
14580 +/* Minimum amount of lookahead, except at the end of the input file.
14581 + * See deflate.c for comments about the MIN_MATCH+1.
14582 + */
14583 +
14584 +/* Values for max_lazy_match, good_match and max_chain_length, depending on
14585 + * the desired pack level (0..9). The values given below have been tuned to
14586 + * exclude worst case performance for pathological files. Better values may be
14587 + * found for specific files.
14588 + */
14589 +typedef struct config_s {
14590 + ush good_length; /* reduce lazy search above this match length */
14591 + ush max_lazy; /* do not perform lazy search above this match length */
14592 + ush nice_length; /* quit search above this match length */
14593 + ush max_chain;
14594 + compress_func func;
14595 +} config;
14596 +
14597 +local const config configuration_table[10] = {
14598 +/* good lazy nice chain */
14599 +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
14600 +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
14601 +/* 2 */ {4, 5, 16, 8, deflate_fast},
14602 +/* 3 */ {4, 6, 32, 32, deflate_fast},
14603 +
14604 +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
14605 +/* 5 */ {8, 16, 32, 32, deflate_slow},
14606 +/* 6 */ {8, 16, 128, 128, deflate_slow},
14607 +/* 7 */ {8, 32, 128, 256, deflate_slow},
14608 +/* 8 */ {32, 128, 258, 1024, deflate_slow},
14609 +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
14610 +
14611 +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
14612 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
14613 + * meaning.
14614 + */
14615 +
14616 +#define EQUAL 0
14617 +/* result of memcmp for equal strings */
14618 +
14619 +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
14620 +
14621 +/* ===========================================================================
14622 + * Update a hash value with the given input byte
14623 + * IN assertion: all calls to to UPDATE_HASH are made with consecutive
14624 + * input characters, so that a running hash key can be computed from the
14625 + * previous key instead of complete recalculation each time.
14626 + */
14627 +#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
14628 +
14629 +
14630 +/* ===========================================================================
14631 + * Insert string str in the dictionary and set match_head to the previous head
14632 + * of the hash chain (the most recent string with same hash key). Return
14633 + * the previous length of the hash chain.
14634 + * If this file is compiled with -DFASTEST, the compression level is forced
14635 + * to 1, and no hash chains are maintained.
14636 + * IN assertion: all calls to to INSERT_STRING are made with consecutive
14637 + * input characters and the first MIN_MATCH bytes of str are valid
14638 + * (except for the last MIN_MATCH-1 bytes of the input file).
14639 + */
14640 +#ifdef FASTEST
14641 +#define INSERT_STRING(s, str, match_head) \
14642 + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
14643 + match_head = s->head[s->ins_h], \
14644 + s->head[s->ins_h] = (Pos)(str))
14645 +#else
14646 +#define INSERT_STRING(s, str, match_head) \
14647 + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
14648 + s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
14649 + s->head[s->ins_h] = (Pos)(str))
14650 +#endif
14651 +
14652 +/* ===========================================================================
14653 + * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
14654 + * prev[] will be initialized on the fly.
14655 + */
14656 +#define CLEAR_HASH(s) \
14657 + s->head[s->hash_size-1] = NIL; \
14658 + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
14659 +
14660 +/* ========================================================================= */
14661 +int ZEXPORT deflateInit_(strm, level, version, stream_size)
14662 + z_streamp strm;
14663 + int level;
14664 + const char *version;
14665 + int stream_size;
14666 +{
14667 + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
14668 + Z_DEFAULT_STRATEGY, version, stream_size);
14669 + /* To do: ignore strm->next_in if we use it as window */
14670 +}
14671 +
14672 +/* ========================================================================= */
14673 +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
14674 + version, stream_size)
14675 + z_streamp strm;
14676 + int level;
14677 + int method;
14678 + int windowBits;
14679 + int memLevel;
14680 + int strategy;
14681 + const char *version;
14682 + int stream_size;
14683 +{
14684 + deflate_state *s;
14685 + int noheader = 0;
14686 + static const char* my_version = ZLIB_VERSION;
14687 +
14688 + ushf *overlay;
14689 + /* We overlay pending_buf and d_buf+l_buf. This works since the average
14690 + * output size for (length,distance) codes is <= 24 bits.
14691 + */
14692 +
14693 + if (version == Z_NULL || version[0] != my_version[0] ||
14694 + stream_size != sizeof(z_stream)) {
14695 + return Z_VERSION_ERROR;
14696 + }
14697 + if (strm == Z_NULL) return Z_STREAM_ERROR;
14698 +
14699 + strm->msg = Z_NULL;
14700 + if (strm->zalloc == Z_NULL) {
14701 + return Z_STREAM_ERROR;
14702 +/* strm->zalloc = zcalloc;
14703 + strm->opaque = (voidpf)0;*/
14704 + }
14705 + if (strm->zfree == Z_NULL) return Z_STREAM_ERROR; /* strm->zfree = zcfree; */
14706 +
14707 + if (level == Z_DEFAULT_COMPRESSION) level = 6;
14708 +#ifdef FASTEST
14709 + level = 1;
14710 +#endif
14711 +
14712 + if (windowBits < 0) { /* undocumented feature: suppress zlib header */
14713 + noheader = 1;
14714 + windowBits = -windowBits;
14715 + }
14716 + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
14717 + windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
14718 + strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
14719 + return Z_STREAM_ERROR;
14720 + }
14721 + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
14722 + if (s == Z_NULL) return Z_MEM_ERROR;
14723 + strm->state = (struct internal_state FAR *)s;
14724 + s->strm = strm;
14725 +
14726 + s->noheader = noheader;
14727 + s->w_bits = windowBits;
14728 + s->w_size = 1 << s->w_bits;
14729 + s->w_mask = s->w_size - 1;
14730 +
14731 + s->hash_bits = memLevel + 7;
14732 + s->hash_size = 1 << s->hash_bits;
14733 + s->hash_mask = s->hash_size - 1;
14734 + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
14735 +
14736 + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
14737 + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
14738 + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
14739 +
14740 + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
14741 +
14742 + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
14743 + s->pending_buf = (uchf *) overlay;
14744 + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
14745 +
14746 + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
14747 + s->pending_buf == Z_NULL) {
14748 + strm->msg = ERR_MSG(Z_MEM_ERROR);
14749 + deflateEnd (strm);
14750 + return Z_MEM_ERROR;
14751 + }
14752 + s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
14753 + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
14754 +
14755 + s->level = level;
14756 + s->strategy = strategy;
14757 + s->method = (Byte)method;
14758 +
14759 + return deflateReset(strm);
14760 +}
14761 +
14762 +/* ========================================================================= */
14763 +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
14764 + z_streamp strm;
14765 + const Bytef *dictionary;
14766 + uInt dictLength;
14767 +{
14768 + deflate_state *s;
14769 + uInt length = dictLength;
14770 + uInt n;
14771 + IPos hash_head = 0;
14772 +
14773 + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
14774 + strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
14775 +
14776 + s = strm->state;
14777 + strm->adler = adler32(strm->adler, dictionary, dictLength);
14778 +
14779 + if (length < MIN_MATCH) return Z_OK;
14780 + if (length > MAX_DIST(s)) {
14781 + length = MAX_DIST(s);
14782 +#ifndef USE_DICT_HEAD
14783 + dictionary += dictLength - length; /* use the tail of the dictionary */
14784 +#endif
14785 + }
14786 + zmemcpy(s->window, dictionary, length);
14787 + s->strstart = length;
14788 + s->block_start = (long)length;
14789 +
14790 + /* Insert all strings in the hash table (except for the last two bytes).
14791 + * s->lookahead stays null, so s->ins_h will be recomputed at the next
14792 + * call of fill_window.
14793 + */
14794 + s->ins_h = s->window[0];
14795 + UPDATE_HASH(s, s->ins_h, s->window[1]);
14796 + for (n = 0; n <= length - MIN_MATCH; n++) {
14797 + INSERT_STRING(s, n, hash_head);
14798 + }
14799 + if (hash_head) hash_head = 0; /* to make compiler happy */
14800 + return Z_OK;
14801 +}
14802 +
14803 +/* ========================================================================= */
14804 +int ZEXPORT deflateReset (strm)
14805 + z_streamp strm;
14806 +{
14807 + deflate_state *s;
14808 +
14809 + if (strm == Z_NULL || strm->state == Z_NULL ||
14810 + strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
14811 +
14812 + strm->total_in = strm->total_out = 0;
14813 + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
14814 + strm->data_type = Z_UNKNOWN;
14815 +
14816 + s = (deflate_state *)strm->state;
14817 + s->pending = 0;
14818 + s->pending_out = s->pending_buf;
14819 +
14820 + if (s->noheader < 0) {
14821 + s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
14822 + }
14823 + s->status = s->noheader ? BUSY_STATE : INIT_STATE;
14824 + strm->adler = 1;
14825 + s->last_flush = Z_NO_FLUSH;
14826 +
14827 + _tr_init(s);
14828 + lm_init(s);
14829 +
14830 + return Z_OK;
14831 +}
14832 +
14833 +/* ========================================================================= */
14834 +int ZEXPORT deflateParams(strm, level, strategy)
14835 + z_streamp strm;
14836 + int level;
14837 + int strategy;
14838 +{
14839 + deflate_state *s;
14840 + compress_func func;
14841 + int err = Z_OK;
14842 +
14843 + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
14844 + s = strm->state;
14845 +
14846 + if (level == Z_DEFAULT_COMPRESSION) {
14847 + level = 6;
14848 + }
14849 + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
14850 + return Z_STREAM_ERROR;
14851 + }
14852 + func = configuration_table[s->level].func;
14853 +
14854 + if (func != configuration_table[level].func && strm->total_in != 0) {
14855 + /* Flush the last buffer: */
14856 + err = deflate(strm, Z_PARTIAL_FLUSH);
14857 + }
14858 + if (s->level != level) {
14859 + s->level = level;
14860 + s->max_lazy_match = configuration_table[level].max_lazy;
14861 + s->good_match = configuration_table[level].good_length;
14862 + s->nice_match = configuration_table[level].nice_length;
14863 + s->max_chain_length = configuration_table[level].max_chain;
14864 + }
14865 + s->strategy = strategy;
14866 + return err;
14867 +}
14868 +
14869 +/* =========================================================================
14870 + * Put a short in the pending buffer. The 16-bit value is put in MSB order.
14871 + * IN assertion: the stream state is correct and there is enough room in
14872 + * pending_buf.
14873 + */
14874 +local void putShortMSB (s, b)
14875 + deflate_state *s;
14876 + uInt b;
14877 +{
14878 + put_byte(s, (Byte)(b >> 8));
14879 + put_byte(s, (Byte)(b & 0xff));
14880 +}
14881 +
14882 +/* =========================================================================
14883 + * Flush as much pending output as possible. All deflate() output goes
14884 + * through this function so some applications may wish to modify it
14885 + * to avoid allocating a large strm->next_out buffer and copying into it.
14886 + * (See also read_buf()).
14887 + */
14888 +local void flush_pending(strm)
14889 + z_streamp strm;
14890 +{
14891 + unsigned len = strm->state->pending;
14892 +
14893 + if (len > strm->avail_out) len = strm->avail_out;
14894 + if (len == 0) return;
14895 +
14896 + zmemcpy(strm->next_out, strm->state->pending_out, len);
14897 + strm->next_out += len;
14898 + strm->state->pending_out += len;
14899 + strm->total_out += len;
14900 + strm->avail_out -= len;
14901 + strm->state->pending -= len;
14902 + if (strm->state->pending == 0) {
14903 + strm->state->pending_out = strm->state->pending_buf;
14904 + }
14905 +}
14906 +
14907 +/* ========================================================================= */
14908 +int ZEXPORT deflate (strm, flush)
14909 + z_streamp strm;
14910 + int flush;
14911 +{
14912 + int old_flush; /* value of flush param for previous deflate call */
14913 + deflate_state *s;
14914 +
14915 + if (strm == Z_NULL || strm->state == Z_NULL ||
14916 + flush > Z_FINISH || flush < 0) {
14917 + return Z_STREAM_ERROR;
14918 + }
14919 + s = strm->state;
14920 +
14921 + if (strm->next_out == Z_NULL ||
14922 + (strm->next_in == Z_NULL && strm->avail_in != 0) ||
14923 + (s->status == FINISH_STATE && flush != Z_FINISH)) {
14924 + ERR_RETURN(strm, Z_STREAM_ERROR);
14925 + }
14926 + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
14927 +
14928 + s->strm = strm; /* just in case */
14929 + old_flush = s->last_flush;
14930 + s->last_flush = flush;
14931 +
14932 + /* Write the zlib header */
14933 + if (s->status == INIT_STATE) {
14934 +
14935 + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
14936 + uInt level_flags = (s->level-1) >> 1;
14937 +
14938 + if (level_flags > 3) level_flags = 3;
14939 + header |= (level_flags << 6);
14940 + if (s->strstart != 0) header |= PRESET_DICT;
14941 + header += 31 - (header % 31);
14942 +
14943 + s->status = BUSY_STATE;
14944 + putShortMSB(s, header);
14945 +
14946 + /* Save the adler32 of the preset dictionary: */
14947 + if (s->strstart != 0) {
14948 + putShortMSB(s, (uInt)(strm->adler >> 16));
14949 + putShortMSB(s, (uInt)(strm->adler & 0xffff));
14950 + }
14951 + strm->adler = 1L;
14952 + }
14953 +
14954 + /* Flush as much pending output as possible */
14955 + if (s->pending != 0) {
14956 + flush_pending(strm);
14957 + if (strm->avail_out == 0) {
14958 + /* Since avail_out is 0, deflate will be called again with
14959 + * more output space, but possibly with both pending and
14960 + * avail_in equal to zero. There won't be anything to do,
14961 + * but this is not an error situation so make sure we
14962 + * return OK instead of BUF_ERROR at next call of deflate:
14963 + */
14964 + s->last_flush = -1;
14965 + return Z_OK;
14966 + }
14967 +
14968 + /* Make sure there is something to do and avoid duplicate consecutive
14969 + * flushes. For repeated and useless calls with Z_FINISH, we keep
14970 + * returning Z_STREAM_END instead of Z_BUFF_ERROR.
14971 + */
14972 + } else if (strm->avail_in == 0 && flush <= old_flush &&
14973 + flush != Z_FINISH) {
14974 + ERR_RETURN(strm, Z_BUF_ERROR);
14975 + }
14976 +
14977 + /* User must not provide more input after the first FINISH: */
14978 + if (s->status == FINISH_STATE && strm->avail_in != 0) {
14979 + ERR_RETURN(strm, Z_BUF_ERROR);
14980 + }
14981 +
14982 + /* Start a new block or continue the current one.
14983 + */
14984 + if (strm->avail_in != 0 || s->lookahead != 0 ||
14985 + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
14986 + block_state bstate;
14987 +
14988 + bstate = (*(configuration_table[s->level].func))(s, flush);
14989 +
14990 + if (bstate == finish_started || bstate == finish_done) {
14991 + s->status = FINISH_STATE;
14992 + }
14993 + if (bstate == need_more || bstate == finish_started) {
14994 + if (strm->avail_out == 0) {
14995 + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
14996 + }
14997 + return Z_OK;
14998 + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
14999 + * of deflate should use the same flush parameter to make sure
15000 + * that the flush is complete. So we don't have to output an
15001 + * empty block here, this will be done at next call. This also
15002 + * ensures that for a very small output buffer, we emit at most
15003 + * one empty block.
15004 + */
15005 + }
15006 + if (bstate == block_done) {
15007 + if (flush == Z_PARTIAL_FLUSH) {
15008 + _tr_align(s);
15009 + } else { /* FULL_FLUSH or SYNC_FLUSH */
15010 + _tr_stored_block(s, (char*)0, 0L, 0);
15011 + /* For a full flush, this empty block will be recognized
15012 + * as a special marker by inflate_sync().
15013 + */
15014 + if (flush == Z_FULL_FLUSH) {
15015 + CLEAR_HASH(s); /* forget history */
15016 + }
15017 + }
15018 + flush_pending(strm);
15019 + if (strm->avail_out == 0) {
15020 + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
15021 + return Z_OK;
15022 + }
15023 + }
15024 + }
15025 + Assert(strm->avail_out > 0, "bug2");
15026 +
15027 + if (flush != Z_FINISH) return Z_OK;
15028 + if (s->noheader) return Z_STREAM_END;
15029 +
15030 + /* Write the zlib trailer (adler32) */
15031 + putShortMSB(s, (uInt)(strm->adler >> 16));
15032 + putShortMSB(s, (uInt)(strm->adler & 0xffff));
15033 + flush_pending(strm);
15034 + /* If avail_out is zero, the application will call deflate again
15035 + * to flush the rest.
15036 + */
15037 + s->noheader = -1; /* write the trailer only once! */
15038 + return s->pending != 0 ? Z_OK : Z_STREAM_END;
15039 +}
15040 +
15041 +/* ========================================================================= */
15042 +int ZEXPORT deflateEnd (strm)
15043 + z_streamp strm;
15044 +{
15045 + int status;
15046 +
15047 + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
15048 +
15049 + status = strm->state->status;
15050 + if (status != INIT_STATE && status != BUSY_STATE &&
15051 + status != FINISH_STATE) {
15052 + return Z_STREAM_ERROR;
15053 + }
15054 +
15055 + /* Deallocate in reverse order of allocations: */
15056 + TRY_FREE(strm, strm->state->pending_buf);
15057 + TRY_FREE(strm, strm->state->head);
15058 + TRY_FREE(strm, strm->state->prev);
15059 + TRY_FREE(strm, strm->state->window);
15060 +
15061 + ZFREE(strm, strm->state);
15062 + strm->state = Z_NULL;
15063 +
15064 + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
15065 +}
15066 +
15067 +/* =========================================================================
15068 + * Copy the source state to the destination state.
15069 + * To simplify the source, this is not supported for 16-bit MSDOS (which
15070 + * doesn't have enough memory anyway to duplicate compression states).
15071 + */
15072 +int ZEXPORT deflateCopy (dest, source)
15073 + z_streamp dest;
15074 + z_streamp source;
15075 +{
15076 +#ifdef MAXSEG_64K
15077 + return Z_STREAM_ERROR;
15078 +#else
15079 + deflate_state *ds;
15080 + deflate_state *ss;
15081 + ushf *overlay;
15082 +
15083 +
15084 + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
15085 + return Z_STREAM_ERROR;
15086 + }
15087 +
15088 + ss = source->state;
15089 +
15090 + *dest = *source;
15091 +
15092 + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
15093 + if (ds == Z_NULL) return Z_MEM_ERROR;
15094 + dest->state = (struct internal_state FAR *) ds;
15095 + *ds = *ss;
15096 + ds->strm = dest;
15097 +
15098 + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
15099 + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
15100 + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
15101 + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
15102 + ds->pending_buf = (uchf *) overlay;
15103 +
15104 + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
15105 + ds->pending_buf == Z_NULL) {
15106 + deflateEnd (dest);
15107 + return Z_MEM_ERROR;
15108 + }
15109 + /* following zmemcpy do not work for 16-bit MSDOS */
15110 + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
15111 + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
15112 + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
15113 + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
15114 +
15115 + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
15116 + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
15117 + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
15118 +
15119 + ds->l_desc.dyn_tree = ds->dyn_ltree;
15120 + ds->d_desc.dyn_tree = ds->dyn_dtree;
15121 + ds->bl_desc.dyn_tree = ds->bl_tree;
15122 +
15123 + return Z_OK;
15124 +#endif
15125 +}
15126 +
15127 +/* ===========================================================================
15128 + * Read a new buffer from the current input stream, update the adler32
15129 + * and total number of bytes read. All deflate() input goes through
15130 + * this function so some applications may wish to modify it to avoid
15131 + * allocating a large strm->next_in buffer and copying from it.
15132 + * (See also flush_pending()).
15133 + */
15134 +local int read_buf(strm, buf, size)
15135 + z_streamp strm;
15136 + Bytef *buf;
15137 + unsigned size;
15138 +{
15139 + unsigned len = strm->avail_in;
15140 +
15141 + if (len > size) len = size;
15142 + if (len == 0) return 0;
15143 +
15144 + strm->avail_in -= len;
15145 +
15146 + if (!strm->state->noheader) {
15147 + strm->adler = adler32(strm->adler, strm->next_in, len);
15148 + }
15149 + zmemcpy(buf, strm->next_in, len);
15150 + strm->next_in += len;
15151 + strm->total_in += len;
15152 +
15153 + return (int)len;
15154 +}
15155 +
15156 +/* ===========================================================================
15157 + * Initialize the "longest match" routines for a new zlib stream
15158 + */
15159 +local void lm_init (s)
15160 + deflate_state *s;
15161 +{
15162 + s->window_size = (ulg)2L*s->w_size;
15163 +
15164 + CLEAR_HASH(s);
15165 +
15166 + /* Set the default configuration parameters:
15167 + */
15168 + s->max_lazy_match = configuration_table[s->level].max_lazy;
15169 + s->good_match = configuration_table[s->level].good_length;
15170 + s->nice_match = configuration_table[s->level].nice_length;
15171 + s->max_chain_length = configuration_table[s->level].max_chain;
15172 +
15173 + s->strstart = 0;
15174 + s->block_start = 0L;
15175 + s->lookahead = 0;
15176 + s->match_length = s->prev_length = MIN_MATCH-1;
15177 + s->match_available = 0;
15178 + s->ins_h = 0;
15179 +#ifdef ASMV
15180 + match_init(); /* initialize the asm code */
15181 +#endif
15182 +}
15183 +
15184 +/* ===========================================================================
15185 + * Set match_start to the longest match starting at the given string and
15186 + * return its length. Matches shorter or equal to prev_length are discarded,
15187 + * in which case the result is equal to prev_length and match_start is
15188 + * garbage.
15189 + * IN assertions: cur_match is the head of the hash chain for the current
15190 + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
15191 + * OUT assertion: the match length is not greater than s->lookahead.
15192 + */
15193 +#ifndef ASMV
15194 +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
15195 + * match.S. The code will be functionally equivalent.
15196 + */
15197 +#ifndef FASTEST
15198 +local uInt longest_match(s, cur_match)
15199 + deflate_state *s;
15200 + IPos cur_match; /* current match */
15201 +{
15202 + unsigned chain_length = s->max_chain_length;/* max hash chain length */
15203 + register Bytef *scan = s->window + s->strstart; /* current string */
15204 + register Bytef *match; /* matched string */
15205 + register int len; /* length of current match */
15206 + int best_len = s->prev_length; /* best match length so far */
15207 + int nice_match = s->nice_match; /* stop if match long enough */
15208 + IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
15209 + s->strstart - (IPos)MAX_DIST(s) : NIL;
15210 + /* Stop when cur_match becomes <= limit. To simplify the code,
15211 + * we prevent matches with the string of window index 0.
15212 + */
15213 + Posf *prev = s->prev;
15214 + uInt wmask = s->w_mask;
15215 +
15216 +#ifdef UNALIGNED_OK
15217 + /* Compare two bytes at a time. Note: this is not always beneficial.
15218 + * Try with and without -DUNALIGNED_OK to check.
15219 + */
15220 + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
15221 + register ush scan_start = *(ushf*)scan;
15222 + register ush scan_end = *(ushf*)(scan+best_len-1);
15223 +#else
15224 + register Bytef *strend = s->window + s->strstart + MAX_MATCH;
15225 + register Byte scan_end1 = scan[best_len-1];
15226 + register Byte scan_end = scan[best_len];
15227 +#endif
15228 +
15229 + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
15230 + * It is easy to get rid of this optimization if necessary.
15231 + */
15232 + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
15233 +
15234 + /* Do not waste too much time if we already have a good match: */
15235 + if (s->prev_length >= s->good_match) {
15236 + chain_length >>= 2;
15237 + }
15238 + /* Do not look for matches beyond the end of the input. This is necessary
15239 + * to make deflate deterministic.
15240 + */
15241 + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
15242 +
15243 + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
15244 +
15245 + do {
15246 + Assert(cur_match < s->strstart, "no future");
15247 + match = s->window + cur_match;
15248 +
15249 + /* Skip to next match if the match length cannot increase
15250 + * or if the match length is less than 2:
15251 + */
15252 +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
15253 + /* This code assumes sizeof(unsigned short) == 2. Do not use
15254 + * UNALIGNED_OK if your compiler uses a different size.
15255 + */
15256 + if (*(ushf*)(match+best_len-1) != scan_end ||
15257 + *(ushf*)match != scan_start) continue;
15258 +
15259 + /* It is not necessary to compare scan[2] and match[2] since they are
15260 + * always equal when the other bytes match, given that the hash keys
15261 + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
15262 + * strstart+3, +5, ... up to strstart+257. We check for insufficient
15263 + * lookahead only every 4th comparison; the 128th check will be made
15264 + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
15265 + * necessary to put more guard bytes at the end of the window, or
15266 + * to check more often for insufficient lookahead.
15267 + */
15268 + Assert(scan[2] == match[2], "scan[2]?");
15269 + scan++, match++;
15270 + do {
15271 + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15272 + *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15273 + *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15274 + *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15275 + scan < strend);
15276 + /* The funny "do {}" generates better code on most compilers */
15277 +
15278 + /* Here, scan <= window+strstart+257 */
15279 + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15280 + if (*scan == *match) scan++;
15281 +
15282 + len = (MAX_MATCH - 1) - (int)(strend-scan);
15283 + scan = strend - (MAX_MATCH-1);
15284 +
15285 +#else /* UNALIGNED_OK */
15286 +
15287 + if (match[best_len] != scan_end ||
15288 + match[best_len-1] != scan_end1 ||
15289 + *match != *scan ||
15290 + *++match != scan[1]) continue;
15291 +
15292 + /* The check at best_len-1 can be removed because it will be made
15293 + * again later. (This heuristic is not always a win.)
15294 + * It is not necessary to compare scan[2] and match[2] since they
15295 + * are always equal when the other bytes match, given that
15296 + * the hash keys are equal and that HASH_BITS >= 8.
15297 + */
15298 + scan += 2, match++;
15299 + Assert(*scan == *match, "match[2]?");
15300 +
15301 + /* We check for insufficient lookahead only every 8th comparison;
15302 + * the 256th check will be made at strstart+258.
15303 + */
15304 + do {
15305 + } while (*++scan == *++match && *++scan == *++match &&
15306 + *++scan == *++match && *++scan == *++match &&
15307 + *++scan == *++match && *++scan == *++match &&
15308 + *++scan == *++match && *++scan == *++match &&
15309 + scan < strend);
15310 +
15311 + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15312 +
15313 + len = MAX_MATCH - (int)(strend - scan);
15314 + scan = strend - MAX_MATCH;
15315 +
15316 +#endif /* UNALIGNED_OK */
15317 +
15318 + if (len > best_len) {
15319 + s->match_start = cur_match;
15320 + best_len = len;
15321 + if (len >= nice_match) break;
15322 +#ifdef UNALIGNED_OK
15323 + scan_end = *(ushf*)(scan+best_len-1);
15324 +#else
15325 + scan_end1 = scan[best_len-1];
15326 + scan_end = scan[best_len];
15327 +#endif
15328 + }
15329 + } while ((cur_match = prev[cur_match & wmask]) > limit
15330 + && --chain_length != 0);
15331 +
15332 + if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
15333 + return s->lookahead;
15334 +}
15335 +
15336 +#else /* FASTEST */
15337 +/* ---------------------------------------------------------------------------
15338 + * Optimized version for level == 1 only
15339 + */
15340 +local uInt longest_match(s, cur_match)
15341 + deflate_state *s;
15342 + IPos cur_match; /* current match */
15343 +{
15344 + register Bytef *scan = s->window + s->strstart; /* current string */
15345 + register Bytef *match; /* matched string */
15346 + register int len; /* length of current match */
15347 + register Bytef *strend = s->window + s->strstart + MAX_MATCH;
15348 +
15349 + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
15350 + * It is easy to get rid of this optimization if necessary.
15351 + */
15352 + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
15353 +
15354 + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
15355 +
15356 + Assert(cur_match < s->strstart, "no future");
15357 +
15358 + match = s->window + cur_match;
15359 +
15360 + /* Return failure if the match length is less than 2:
15361 + */
15362 + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
15363 +
15364 + /* The check at best_len-1 can be removed because it will be made
15365 + * again later. (This heuristic is not always a win.)
15366 + * It is not necessary to compare scan[2] and match[2] since they
15367 + * are always equal when the other bytes match, given that
15368 + * the hash keys are equal and that HASH_BITS >= 8.
15369 + */
15370 + scan += 2, match += 2;
15371 + Assert(*scan == *match, "match[2]?");
15372 +
15373 + /* We check for insufficient lookahead only every 8th comparison;
15374 + * the 256th check will be made at strstart+258.
15375 + */
15376 + do {
15377 + } while (*++scan == *++match && *++scan == *++match &&
15378 + *++scan == *++match && *++scan == *++match &&
15379 + *++scan == *++match && *++scan == *++match &&
15380 + *++scan == *++match && *++scan == *++match &&
15381 + scan < strend);
15382 +
15383 + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15384 +
15385 + len = MAX_MATCH - (int)(strend - scan);
15386 +
15387 + if (len < MIN_MATCH) return MIN_MATCH - 1;
15388 +
15389 + s->match_start = cur_match;
15390 + return len <= s->lookahead ? len : s->lookahead;
15391 +}
15392 +#endif /* FASTEST */
15393 +#endif /* ASMV */
15394 +
15395 +#ifdef DEBUG
15396 +/* ===========================================================================
15397 + * Check that the match at match_start is indeed a match.
15398 + */
15399 +local void check_match(s, start, match, length)
15400 + deflate_state *s;
15401 + IPos start, match;
15402 + int length;
15403 +{
15404 + /* check that the match is indeed a match */
15405 + if (zmemcmp(s->window + match,
15406 + s->window + start, length) != EQUAL) {
15407 + fprintf(stderr, " start %u, match %u, length %d\n",
15408 + start, match, length);
15409 + do {
15410 + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
15411 + } while (--length != 0);
15412 + z_error("invalid match");
15413 + }
15414 + if (z_verbose > 1) {
15415 + fprintf(stderr,"\\[%d,%d]", start-match, length);
15416 + do { putc(s->window[start++], stderr); } while (--length != 0);
15417 + }
15418 +}
15419 +#else
15420 +# define check_match(s, start, match, length)
15421 +#endif
15422 +
15423 +/* ===========================================================================
15424 + * Fill the window when the lookahead becomes insufficient.
15425 + * Updates strstart and lookahead.
15426 + *
15427 + * IN assertion: lookahead < MIN_LOOKAHEAD
15428 + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
15429 + * At least one byte has been read, or avail_in == 0; reads are
15430 + * performed for at least two bytes (required for the zip translate_eol
15431 + * option -- not supported here).
15432 + */
15433 +local void fill_window(s)
15434 + deflate_state *s;
15435 +{
15436 + register unsigned n, m;
15437 + register Posf *p;
15438 + unsigned more; /* Amount of free space at the end of the window. */
15439 + uInt wsize = s->w_size;
15440 +
15441 + do {
15442 + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
15443 +
15444 + /* Deal with !@#$% 64K limit: */
15445 + if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
15446 + more = wsize;
15447 +
15448 + } else if (more == (unsigned)(-1)) {
15449 + /* Very unlikely, but possible on 16 bit machine if strstart == 0
15450 + * and lookahead == 1 (input done one byte at time)
15451 + */
15452 + more--;
15453 +
15454 + /* If the window is almost full and there is insufficient lookahead,
15455 + * move the upper half to the lower one to make room in the upper half.
15456 + */
15457 + } else if (s->strstart >= wsize+MAX_DIST(s)) {
15458 +
15459 + zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
15460 + s->match_start -= wsize;
15461 + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
15462 + s->block_start -= (long) wsize;
15463 +
15464 + /* Slide the hash table (could be avoided with 32 bit values
15465 + at the expense of memory usage). We slide even when level == 0
15466 + to keep the hash table consistent if we switch back to level > 0
15467 + later. (Using level 0 permanently is not an optimal usage of
15468 + zlib, so we don't care about this pathological case.)
15469 + */
15470 + n = s->hash_size;
15471 + p = &s->head[n];
15472 + do {
15473 + m = *--p;
15474 + *p = (Pos)(m >= wsize ? m-wsize : NIL);
15475 + } while (--n);
15476 +
15477 + n = wsize;
15478 +#ifndef FASTEST
15479 + p = &s->prev[n];
15480 + do {
15481 + m = *--p;
15482 + *p = (Pos)(m >= wsize ? m-wsize : NIL);
15483 + /* If n is not on any hash chain, prev[n] is garbage but
15484 + * its value will never be used.
15485 + */
15486 + } while (--n);
15487 +#endif
15488 + more += wsize;
15489 + }
15490 + if (s->strm->avail_in == 0) return;
15491 +
15492 + /* If there was no sliding:
15493 + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
15494 + * more == window_size - lookahead - strstart
15495 + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
15496 + * => more >= window_size - 2*WSIZE + 2
15497 + * In the BIG_MEM or MMAP case (not yet supported),
15498 + * window_size == input_size + MIN_LOOKAHEAD &&
15499 + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
15500 + * Otherwise, window_size == 2*WSIZE so more >= 2.
15501 + * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
15502 + */
15503 + Assert(more >= 2, "more < 2");
15504 +
15505 + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
15506 + s->lookahead += n;
15507 +
15508 + /* Initialize the hash value now that we have some input: */
15509 + if (s->lookahead >= MIN_MATCH) {
15510 + s->ins_h = s->window[s->strstart];
15511 + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
15512 +#if MIN_MATCH != 3
15513 + Call UPDATE_HASH() MIN_MATCH-3 more times
15514 +#endif
15515 + }
15516 + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
15517 + * but this is not important since only literal bytes will be emitted.
15518 + */
15519 +
15520 + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
15521 +}
15522 +
15523 +/* ===========================================================================
15524 + * Flush the current block, with given end-of-file flag.
15525 + * IN assertion: strstart is set to the end of the current match.
15526 + */
15527 +#define FLUSH_BLOCK_ONLY(s, eof) { \
15528 + _tr_flush_block(s, (s->block_start >= 0L ? \
15529 + (charf *)&s->window[(unsigned)s->block_start] : \
15530 + (charf *)Z_NULL), \
15531 + (ulg)((long)s->strstart - s->block_start), \
15532 + (eof)); \
15533 + s->block_start = s->strstart; \
15534 + flush_pending(s->strm); \
15535 + Tracev((stderr,"[FLUSH]")); \
15536 +}
15537 +
15538 +/* Same but force premature exit if necessary. */
15539 +#define FLUSH_BLOCK(s, eof) { \
15540 + FLUSH_BLOCK_ONLY(s, eof); \
15541 + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
15542 +}
15543 +
15544 +/* ===========================================================================
15545 + * Copy without compression as much as possible from the input stream, return
15546 + * the current block state.
15547 + * This function does not insert new strings in the dictionary since
15548 + * uncompressible data is probably not useful. This function is used
15549 + * only for the level=0 compression option.
15550 + * NOTE: this function should be optimized to avoid extra copying from
15551 + * window to pending_buf.
15552 + */
15553 +local block_state deflate_stored(s, flush)
15554 + deflate_state *s;
15555 + int flush;
15556 +{
15557 + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
15558 + * to pending_buf_size, and each stored block has a 5 byte header:
15559 + */
15560 + ulg max_block_size = 0xffff;
15561 + ulg max_start;
15562 +
15563 + if (max_block_size > s->pending_buf_size - 5) {
15564 + max_block_size = s->pending_buf_size - 5;
15565 + }
15566 +
15567 + /* Copy as much as possible from input to output: */
15568 + for (;;) {
15569 + /* Fill the window as much as possible: */
15570 + if (s->lookahead <= 1) {
15571 +
15572 + Assert(s->strstart < s->w_size+MAX_DIST(s) ||
15573 + s->block_start >= (long)s->w_size, "slide too late");
15574 +
15575 + fill_window(s);
15576 + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
15577 +
15578 + if (s->lookahead == 0) break; /* flush the current block */
15579 + }
15580 + Assert(s->block_start >= 0L, "block gone");
15581 +
15582 + s->strstart += s->lookahead;
15583 + s->lookahead = 0;
15584 +
15585 + /* Emit a stored block if pending_buf will be full: */
15586 + max_start = s->block_start + max_block_size;
15587 + if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
15588 + /* strstart == 0 is possible when wraparound on 16-bit machine */
15589 + s->lookahead = (uInt)(s->strstart - max_start);
15590 + s->strstart = (uInt)max_start;
15591 + FLUSH_BLOCK(s, 0);
15592 + }
15593 + /* Flush if we may have to slide, otherwise block_start may become
15594 + * negative and the data will be gone:
15595 + */
15596 + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
15597 + FLUSH_BLOCK(s, 0);
15598 + }
15599 + }
15600 + FLUSH_BLOCK(s, flush == Z_FINISH);
15601 + return flush == Z_FINISH ? finish_done : block_done;
15602 +}
15603 +
15604 +/* ===========================================================================
15605 + * Compress as much as possible from the input stream, return the current
15606 + * block state.
15607 + * This function does not perform lazy evaluation of matches and inserts
15608 + * new strings in the dictionary only for unmatched strings or for short
15609 + * matches. It is used only for the fast compression options.
15610 + */
15611 +local block_state deflate_fast(s, flush)
15612 + deflate_state *s;
15613 + int flush;
15614 +{
15615 + IPos hash_head = NIL; /* head of the hash chain */
15616 + int bflush; /* set if current block must be flushed */
15617 +
15618 + for (;;) {
15619 + /* Make sure that we always have enough lookahead, except
15620 + * at the end of the input file. We need MAX_MATCH bytes
15621 + * for the next match, plus MIN_MATCH bytes to insert the
15622 + * string following the next match.
15623 + */
15624 + if (s->lookahead < MIN_LOOKAHEAD) {
15625 + fill_window(s);
15626 + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
15627 + return need_more;
15628 + }
15629 + if (s->lookahead == 0) break; /* flush the current block */
15630 + }
15631 +
15632 + /* Insert the string window[strstart .. strstart+2] in the
15633 + * dictionary, and set hash_head to the head of the hash chain:
15634 + */
15635 + if (s->lookahead >= MIN_MATCH) {
15636 + INSERT_STRING(s, s->strstart, hash_head);
15637 + }
15638 +
15639 + /* Find the longest match, discarding those <= prev_length.
15640 + * At this point we have always match_length < MIN_MATCH
15641 + */
15642 + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
15643 + /* To simplify the code, we prevent matches with the string
15644 + * of window index 0 (in particular we have to avoid a match
15645 + * of the string with itself at the start of the input file).
15646 + */
15647 + if (s->strategy != Z_HUFFMAN_ONLY) {
15648 + s->match_length = longest_match (s, hash_head);
15649 + }
15650 + /* longest_match() sets match_start */
15651 + }
15652 + if (s->match_length >= MIN_MATCH) {
15653 + check_match(s, s->strstart, s->match_start, s->match_length);
15654 +
15655 + _tr_tally_dist(s, s->strstart - s->match_start,
15656 + s->match_length - MIN_MATCH, bflush);
15657 +
15658 + s->lookahead -= s->match_length;
15659 +
15660 + /* Insert new strings in the hash table only if the match length
15661 + * is not too large. This saves time but degrades compression.
15662 + */
15663 +#ifndef FASTEST
15664 + if (s->match_length <= s->max_insert_length &&
15665 + s->lookahead >= MIN_MATCH) {
15666 + s->match_length--; /* string at strstart already in hash table */
15667 + do {
15668 + s->strstart++;
15669 + INSERT_STRING(s, s->strstart, hash_head);
15670 + /* strstart never exceeds WSIZE-MAX_MATCH, so there are
15671 + * always MIN_MATCH bytes ahead.
15672 + */
15673 + } while (--s->match_length != 0);
15674 + s->strstart++;
15675 + } else
15676 +#endif
15677 + {
15678 + s->strstart += s->match_length;
15679 + s->match_length = 0;
15680 + s->ins_h = s->window[s->strstart];
15681 + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
15682 +#if MIN_MATCH != 3
15683 + Call UPDATE_HASH() MIN_MATCH-3 more times
15684 +#endif
15685 + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
15686 + * matter since it will be recomputed at next deflate call.
15687 + */
15688 + }
15689 + } else {
15690 + /* No match, output a literal byte */
15691 + Tracevv((stderr,"%c", s->window[s->strstart]));
15692 + _tr_tally_lit (s, s->window[s->strstart], bflush);
15693 + s->lookahead--;
15694 + s->strstart++;
15695 + }
15696 + if (bflush) FLUSH_BLOCK(s, 0);
15697 + }
15698 + FLUSH_BLOCK(s, flush == Z_FINISH);
15699 + return flush == Z_FINISH ? finish_done : block_done;
15700 +}
15701 +
15702 +/* ===========================================================================
15703 + * Same as above, but achieves better compression. We use a lazy
15704 + * evaluation for matches: a match is finally adopted only if there is
15705 + * no better match at the next window position.
15706 + */
15707 +local block_state deflate_slow(s, flush)
15708 + deflate_state *s;
15709 + int flush;
15710 +{
15711 + IPos hash_head = NIL; /* head of hash chain */
15712 + int bflush; /* set if current block must be flushed */
15713 +
15714 + /* Process the input block. */
15715 + for (;;) {
15716 + /* Make sure that we always have enough lookahead, except
15717 + * at the end of the input file. We need MAX_MATCH bytes
15718 + * for the next match, plus MIN_MATCH bytes to insert the
15719 + * string following the next match.
15720 + */
15721 + if (s->lookahead < MIN_LOOKAHEAD) {
15722 + fill_window(s);
15723 + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
15724 + return need_more;
15725 + }
15726 + if (s->lookahead == 0) break; /* flush the current block */
15727 + }
15728 +
15729 + /* Insert the string window[strstart .. strstart+2] in the
15730 + * dictionary, and set hash_head to the head of the hash chain:
15731 + */
15732 + if (s->lookahead >= MIN_MATCH) {
15733 + INSERT_STRING(s, s->strstart, hash_head);
15734 + }
15735 +
15736 + /* Find the longest match, discarding those <= prev_length.
15737 + */
15738 + s->prev_length = s->match_length, s->prev_match = s->match_start;
15739 + s->match_length = MIN_MATCH-1;
15740 +
15741 + if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
15742 + 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 <= 5 && (s->strategy == Z_FILTERED ||
15753 + (s->match_length == MIN_MATCH &&
15754 + s->strstart - s->match_start > TOO_FAR))) {
15755 +
15756 + /* If prev_match is also MIN_MATCH, match_start is garbage
15757 + * but we will ignore the current match anyway.
15758 + */
15759 + s->match_length = MIN_MATCH-1;
15760 + }
15761 + }
15762 + /* If there was a match at the previous step and the current
15763 + * match is not better, output the previous match:
15764 + */
15765 + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
15766 + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
15767 + /* Do not insert strings in hash table beyond this. */
15768 +
15769 + check_match(s, s->strstart-1, s->prev_match, s->prev_length);
15770 +
15771 + _tr_tally_dist(s, s->strstart -1 - s->prev_match,
15772 + s->prev_length - MIN_MATCH, bflush);
15773 +
15774 + /* Insert in hash table all strings up to the end of the match.
15775 + * strstart-1 and strstart are already inserted. If there is not
15776 + * enough lookahead, the last two strings are not inserted in
15777 + * the hash table.
15778 + */
15779 + s->lookahead -= s->prev_length-1;
15780 + s->prev_length -= 2;
15781 + do {
15782 + if (++s->strstart <= max_insert) {
15783 + INSERT_STRING(s, s->strstart, hash_head);
15784 + }
15785 + } while (--s->prev_length != 0);
15786 + s->match_available = 0;
15787 + s->match_length = MIN_MATCH-1;
15788 + s->strstart++;
15789 +
15790 + if (bflush) FLUSH_BLOCK(s, 0);
15791 +
15792 + } else if (s->match_available) {
15793 + /* If there was no match at the previous position, output a
15794 + * single literal. If there was a match but the current match
15795 + * is longer, truncate the previous match to a single literal.
15796 + */
15797 + Tracevv((stderr,"%c", s->window[s->strstart-1]));
15798 + _tr_tally_lit(s, s->window[s->strstart-1], bflush);
15799 + if (bflush) {
15800 + FLUSH_BLOCK_ONLY(s, 0);
15801 + }
15802 + s->strstart++;
15803 + s->lookahead--;
15804 + if (s->strm->avail_out == 0) return need_more;
15805 + } else {
15806 + /* There is no previous match to compare with, wait for
15807 + * the next step to decide.
15808 + */
15809 + s->match_available = 1;
15810 + s->strstart++;
15811 + s->lookahead--;
15812 + }
15813 + }
15814 + Assert (flush != Z_NO_FLUSH, "no flush?");
15815 + if (s->match_available) {
15816 + Tracevv((stderr,"%c", s->window[s->strstart-1]));
15817 + _tr_tally_lit(s, s->window[s->strstart-1], bflush);
15818 + s->match_available = 0;
15819 + }
15820 + FLUSH_BLOCK(s, flush == Z_FINISH);
15821 + return flush == Z_FINISH ? finish_done : block_done;
15822 +}
15823 --- /dev/null Tue Mar 11 13:02:56 2003
15824 +++ linux/net/ipsec/deflate.h Mon Feb 9 13:51:03 2004
15825 @@ -0,0 +1,318 @@
15826 +/* deflate.h -- internal compression state
15827 + * Copyright (C) 1995-2002 Jean-loup Gailly
15828 + * For conditions of distribution and use, see copyright notice in zlib.h
15829 + */
15830 +
15831 +/* WARNING: this file should *not* be used by applications. It is
15832 + part of the implementation of the compression library and is
15833 + subject to change. Applications should only use zlib.h.
15834 + */
15835 +
15836 +/* @(#) $Id: deflate.h,v 1.5 2004/07/10 07:48:38 mcr Exp $ */
15837 +
15838 +#ifndef _DEFLATE_H
15839 +#define _DEFLATE_H
15840 +
15841 +#include "zlib/zutil.h"
15842 +
15843 +/* ===========================================================================
15844 + * Internal compression state.
15845 + */
15846 +
15847 +#define LENGTH_CODES 29
15848 +/* number of length codes, not counting the special END_BLOCK code */
15849 +
15850 +#define LITERALS 256
15851 +/* number of literal bytes 0..255 */
15852 +
15853 +#define L_CODES (LITERALS+1+LENGTH_CODES)
15854 +/* number of Literal or Length codes, including the END_BLOCK code */
15855 +
15856 +#define D_CODES 30
15857 +/* number of distance codes */
15858 +
15859 +#define BL_CODES 19
15860 +/* number of codes used to transfer the bit lengths */
15861 +
15862 +#define HEAP_SIZE (2*L_CODES+1)
15863 +/* maximum heap size */
15864 +
15865 +#define MAX_BITS 15
15866 +/* All codes must not exceed MAX_BITS bits */
15867 +
15868 +#define INIT_STATE 42
15869 +#define BUSY_STATE 113
15870 +#define FINISH_STATE 666
15871 +/* Stream status */
15872 +
15873 +
15874 +/* Data structure describing a single value and its code string. */
15875 +typedef struct ct_data_s {
15876 + union {
15877 + ush freq; /* frequency count */
15878 + ush code; /* bit string */
15879 + } fc;
15880 + union {
15881 + ush dad; /* father node in Huffman tree */
15882 + ush len; /* length of bit string */
15883 + } dl;
15884 +} FAR ct_data;
15885 +
15886 +#define Freq fc.freq
15887 +#define Code fc.code
15888 +#define Dad dl.dad
15889 +#define Len dl.len
15890 +
15891 +typedef struct static_tree_desc_s static_tree_desc;
15892 +
15893 +typedef struct tree_desc_s {
15894 + ct_data *dyn_tree; /* the dynamic tree */
15895 + int max_code; /* largest code with non zero frequency */
15896 + static_tree_desc *stat_desc; /* the corresponding static tree */
15897 +} FAR tree_desc;
15898 +
15899 +typedef ush Pos;
15900 +typedef Pos FAR Posf;
15901 +typedef unsigned IPos;
15902 +
15903 +/* A Pos is an index in the character window. We use short instead of int to
15904 + * save space in the various tables. IPos is used only for parameter passing.
15905 + */
15906 +
15907 +typedef struct internal_state {
15908 + z_streamp strm; /* pointer back to this zlib stream */
15909 + int status; /* as the name implies */
15910 + Bytef *pending_buf; /* output still pending */
15911 + ulg pending_buf_size; /* size of pending_buf */
15912 + Bytef *pending_out; /* next pending byte to output to the stream */
15913 + int pending; /* nb of bytes in the pending buffer */
15914 + int noheader; /* suppress zlib header and adler32 */
15915 + Byte data_type; /* UNKNOWN, BINARY or ASCII */
15916 + Byte method; /* STORED (for zip only) or DEFLATED */
15917 + int last_flush; /* value of flush param for previous deflate call */
15918 +
15919 + /* used by deflate.c: */
15920 +
15921 + uInt w_size; /* LZ77 window size (32K by default) */
15922 + uInt w_bits; /* log2(w_size) (8..16) */
15923 + uInt w_mask; /* w_size - 1 */
15924 +
15925 + Bytef *window;
15926 + /* Sliding window. Input bytes are read into the second half of the window,
15927 + * and move to the first half later to keep a dictionary of at least wSize
15928 + * bytes. With this organization, matches are limited to a distance of
15929 + * wSize-MAX_MATCH bytes, but this ensures that IO is always
15930 + * performed with a length multiple of the block size. Also, it limits
15931 + * the window size to 64K, which is quite useful on MSDOS.
15932 + * To do: use the user input buffer as sliding window.
15933 + */
15934 +
15935 + ulg window_size;
15936 + /* Actual size of window: 2*wSize, except when the user input buffer
15937 + * is directly used as sliding window.
15938 + */
15939 +
15940 + Posf *prev;
15941 + /* Link to older string with same hash index. To limit the size of this
15942 + * array to 64K, this link is maintained only for the last 32K strings.
15943 + * An index in this array is thus a window index modulo 32K.
15944 + */
15945 +
15946 + Posf *head; /* Heads of the hash chains or NIL. */
15947 +
15948 + uInt ins_h; /* hash index of string to be inserted */
15949 + uInt hash_size; /* number of elements in hash table */
15950 + uInt hash_bits; /* log2(hash_size) */
15951 + uInt hash_mask; /* hash_size-1 */
15952 +
15953 + uInt hash_shift;
15954 + /* Number of bits by which ins_h must be shifted at each input
15955 + * step. It must be such that after MIN_MATCH steps, the oldest
15956 + * byte no longer takes part in the hash key, that is:
15957 + * hash_shift * MIN_MATCH >= hash_bits
15958 + */
15959 +
15960 + long block_start;
15961 + /* Window position at the beginning of the current output block. Gets
15962 + * negative when the window is moved backwards.
15963 + */
15964 +
15965 + uInt match_length; /* length of best match */
15966 + IPos prev_match; /* previous match */
15967 + int match_available; /* set if previous match exists */
15968 + uInt strstart; /* start of string to insert */
15969 + uInt match_start; /* start of matching string */
15970 + uInt lookahead; /* number of valid bytes ahead in window */
15971 +
15972 + uInt prev_length;
15973 + /* Length of the best match at previous step. Matches not greater than this
15974 + * are discarded. This is used in the lazy match evaluation.
15975 + */
15976 +
15977 + uInt max_chain_length;
15978 + /* To speed up deflation, hash chains are never searched beyond this
15979 + * length. A higher limit improves compression ratio but degrades the
15980 + * speed.
15981 + */
15982 +
15983 + uInt max_lazy_match;
15984 + /* Attempt to find a better match only when the current match is strictly
15985 + * smaller than this value. This mechanism is used only for compression
15986 + * levels >= 4.
15987 + */
15988 +# define max_insert_length max_lazy_match
15989 + /* Insert new strings in the hash table only if the match length is not
15990 + * greater than this length. This saves time but degrades compression.
15991 + * max_insert_length is used only for compression levels <= 3.
15992 + */
15993 +
15994 + int level; /* compression level (1..9) */
15995 + int strategy; /* favor or force Huffman coding*/
15996 +
15997 + uInt good_match;
15998 + /* Use a faster search when the previous match is longer than this */
15999 +
16000 + int nice_match; /* Stop searching when current match exceeds this */
16001 +
16002 + /* used by trees.c: */
16003 + /* Didn't use ct_data typedef below to supress compiler warning */
16004 + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
16005 + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
16006 + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
16007 +
16008 + struct tree_desc_s l_desc; /* desc. for literal tree */
16009 + struct tree_desc_s d_desc; /* desc. for distance tree */
16010 + struct tree_desc_s bl_desc; /* desc. for bit length tree */
16011 +
16012 + ush bl_count[MAX_BITS+1];
16013 + /* number of codes at each bit length for an optimal tree */
16014 +
16015 + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
16016 + int heap_len; /* number of elements in the heap */
16017 + int heap_max; /* element of largest frequency */
16018 + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
16019 + * The same heap array is used to build all trees.
16020 + */
16021 +
16022 + uch depth[2*L_CODES+1];
16023 + /* Depth of each subtree used as tie breaker for trees of equal frequency
16024 + */
16025 +
16026 + uchf *l_buf; /* buffer for literals or lengths */
16027 +
16028 + uInt lit_bufsize;
16029 + /* Size of match buffer for literals/lengths. There are 4 reasons for
16030 + * limiting lit_bufsize to 64K:
16031 + * - frequencies can be kept in 16 bit counters
16032 + * - if compression is not successful for the first block, all input
16033 + * data is still in the window so we can still emit a stored block even
16034 + * when input comes from standard input. (This can also be done for
16035 + * all blocks if lit_bufsize is not greater than 32K.)
16036 + * - if compression is not successful for a file smaller than 64K, we can
16037 + * even emit a stored file instead of a stored block (saving 5 bytes).
16038 + * This is applicable only for zip (not gzip or zlib).
16039 + * - creating new Huffman trees less frequently may not provide fast
16040 + * adaptation to changes in the input data statistics. (Take for
16041 + * example a binary file with poorly compressible code followed by
16042 + * a highly compressible string table.) Smaller buffer sizes give
16043 + * fast adaptation but have of course the overhead of transmitting
16044 + * trees more frequently.
16045 + * - I can't count above 4
16046 + */
16047 +
16048 + uInt last_lit; /* running index in l_buf */
16049 +
16050 + ushf *d_buf;
16051 + /* Buffer for distances. To simplify the code, d_buf and l_buf have
16052 + * the same number of elements. To use different lengths, an extra flag
16053 + * array would be necessary.
16054 + */
16055 +
16056 + ulg opt_len; /* bit length of current block with optimal trees */
16057 + ulg static_len; /* bit length of current block with static trees */
16058 + uInt matches; /* number of string matches in current block */
16059 + int last_eob_len; /* bit length of EOB code for last block */
16060 +
16061 +#ifdef DEBUG
16062 + ulg compressed_len; /* total bit length of compressed file mod 2^32 */
16063 + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
16064 +#endif
16065 +
16066 + ush bi_buf;
16067 + /* Output buffer. bits are inserted starting at the bottom (least
16068 + * significant bits).
16069 + */
16070 + int bi_valid;
16071 + /* Number of valid bits in bi_buf. All bits above the last valid bit
16072 + * are always zero.
16073 + */
16074 +
16075 +} FAR deflate_state;
16076 +
16077 +/* Output a byte on the stream.
16078 + * IN assertion: there is enough room in pending_buf.
16079 + */
16080 +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
16081 +
16082 +
16083 +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
16084 +/* Minimum amount of lookahead, except at the end of the input file.
16085 + * See deflate.c for comments about the MIN_MATCH+1.
16086 + */
16087 +
16088 +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
16089 +/* In order to simplify the code, particularly on 16 bit machines, match
16090 + * distances are limited to MAX_DIST instead of WSIZE.
16091 + */
16092 +
16093 + /* in trees.c */
16094 +void _tr_init OF((deflate_state *s));
16095 +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
16096 +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
16097 + int eof));
16098 +void _tr_align OF((deflate_state *s));
16099 +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
16100 + int eof));
16101 +
16102 +#define d_code(dist) \
16103 + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
16104 +/* Mapping from a distance to a distance code. dist is the distance - 1 and
16105 + * must not have side effects. _dist_code[256] and _dist_code[257] are never
16106 + * used.
16107 + */
16108 +
16109 +#ifndef DEBUG
16110 +/* Inline versions of _tr_tally for speed: */
16111 +
16112 +#if defined(GEN_TREES_H) || !defined(STDC)
16113 + extern uch _length_code[];
16114 + extern uch _dist_code[];
16115 +#else
16116 + extern const uch _length_code[];
16117 + extern const uch _dist_code[];
16118 +#endif
16119 +
16120 +# define _tr_tally_lit(s, c, flush) \
16121 + { uch cc = (c); \
16122 + s->d_buf[s->last_lit] = 0; \
16123 + s->l_buf[s->last_lit++] = cc; \
16124 + s->dyn_ltree[cc].Freq++; \
16125 + flush = (s->last_lit == s->lit_bufsize-1); \
16126 + }
16127 +# define _tr_tally_dist(s, distance, length, flush) \
16128 + { uch len = (length); \
16129 + ush dist = (distance); \
16130 + s->d_buf[s->last_lit] = dist; \
16131 + s->l_buf[s->last_lit++] = len; \
16132 + dist--; \
16133 + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
16134 + s->dyn_dtree[d_code(dist)].Freq++; \
16135 + flush = (s->last_lit == s->lit_bufsize-1); \
16136 + }
16137 +#else
16138 +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
16139 +# define _tr_tally_dist(s, distance, length, flush) \
16140 + flush = _tr_tally(s, distance, length)
16141 +#endif
16142 +
16143 +#endif /* _DEFLATE_H */
16144 --- /dev/null Tue Mar 11 13:02:56 2003
16145 +++ linux/net/ipsec/des/COPYRIGHT Mon Feb 9 13:51:03 2004
16146 @@ -0,0 +1,50 @@
16147 +Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
16148 +All rights reserved.
16149 +
16150 +This package is an DES implementation written by Eric Young (eay@cryptsoft.com).
16151 +The implementation was written so as to conform with MIT's libdes.
16152 +
16153 +This library is free for commercial and non-commercial use as long as
16154 +the following conditions are aheared to. The following conditions
16155 +apply to all code found in this distribution.
16156 +
16157 +Copyright remains Eric Young's, and as such any Copyright notices in
16158 +the code are not to be removed.
16159 +If this package is used in a product, Eric Young should be given attribution
16160 +as the author of that the SSL library. This can be in the form of a textual
16161 +message at program startup or in documentation (online or textual) provided
16162 +with the package.
16163 +
16164 +Redistribution and use in source and binary forms, with or without
16165 +modification, are permitted provided that the following conditions
16166 +are met:
16167 +1. Redistributions of source code must retain the copyright
16168 + notice, this list of conditions and the following disclaimer.
16169 +2. Redistributions in binary form must reproduce the above copyright
16170 + notice, this list of conditions and the following disclaimer in the
16171 + documentation and/or other materials provided with the distribution.
16172 +3. All advertising materials mentioning features or use of this software
16173 + must display the following acknowledgement:
16174 + This product includes software developed by Eric Young (eay@cryptsoft.com)
16175 +
16176 +THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
16177 +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16178 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16179 +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16180 +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
16181 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
16182 +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
16183 +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
16184 +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
16185 +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
16186 +SUCH DAMAGE.
16187 +
16188 +The license and distribution terms for any publically available version or
16189 +derivative of this code cannot be changed. i.e. this code cannot simply be
16190 +copied and put under another distrubution license
16191 +[including the GNU Public License.]
16192 +
16193 +The reason behind this being stated in this direct manner is past
16194 +experience in code simply being copied and the attribution removed
16195 +from it and then being distributed as part of other packages. This
16196 +implementation was a non-trivial and unpaid effort.
16197 --- /dev/null Tue Mar 11 13:02:56 2003
16198 +++ linux/net/ipsec/des/INSTALL Mon Feb 9 13:51:03 2004
16199 @@ -0,0 +1,69 @@
16200 +Check the CC and CFLAGS lines in the makefile
16201 +
16202 +If your C library does not support the times(3) function, change the
16203 +#define TIMES to
16204 +#undef TIMES in speed.c
16205 +If it does, check the HZ value for the times(3) function.
16206 +If your system does not define CLK_TCK it will be assumed to
16207 +be 100.0.
16208 +
16209 +If possible use gcc v 2.7.?
16210 +Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc)
16211 +In recent times, some system compilers give better performace.
16212 +
16213 +type 'make'
16214 +
16215 +run './destest' to check things are ok.
16216 +run './rpw' to check the tty code for reading passwords works.
16217 +run './speed' to see how fast those optimisations make the library run :-)
16218 +run './des_opts' to determin the best compile time options.
16219 +
16220 +The output from des_opts should be put in the makefile options and des_enc.c
16221 +should be rebuilt. For 64 bit computers, do not use the DES_PTR option.
16222 +For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int'
16223 +and then you can use the 'DES_PTR' option.
16224 +
16225 +The file options.txt has the options listed for best speed on quite a
16226 +few systems. Look and the options (UNROLL, PTR, RISC2 etc) and then
16227 +turn on the relevent option in the Makefile
16228 +
16229 +There are some special Makefile targets that make life easier.
16230 +make cc - standard cc build
16231 +make gcc - standard gcc build
16232 +make x86-elf - x86 assembler (elf), linux-elf.
16233 +make x86-out - x86 assembler (a.out), FreeBSD
16234 +make x86-solaris- x86 assembler
16235 +make x86-bsdi - x86 assembler (a.out with primative assembler).
16236 +
16237 +If at all possible use the assembler (for Windows NT/95, use
16238 +asm/win32.obj to link with). The x86 assembler is very very fast.
16239 +
16240 +A make install will by default install
16241 +libdes.a in /usr/local/lib/libdes.a
16242 +des in /usr/local/bin/des
16243 +des_crypt.man in /usr/local/man/man3/des_crypt.3
16244 +des.man in /usr/local/man/man1/des.1
16245 +des.h in /usr/include/des.h
16246 +
16247 +des(1) should be compatible with sunOS's but I have been unable to
16248 +test it.
16249 +
16250 +These routines should compile on MSDOS, most 32bit and 64bit version
16251 +of Unix (BSD and SYSV) and VMS, without modification.
16252 +The only problems should be #include files that are in the wrong places.
16253 +
16254 +These routines can be compiled under MSDOS.
16255 +I have successfully encrypted files using des(1) under MSDOS and then
16256 +decrypted the files on a SparcStation.
16257 +I have been able to compile and test the routines with
16258 +Microsoft C v 5.1 and Turbo C v 2.0.
16259 +The code in this library is in no way optimised for the 16bit
16260 +operation of MSDOS.
16261 +
16262 +When building for glibc, ignore all of the above and just unpack into
16263 +glibc-1.??/des and then gmake as per normal.
16264 +
16265 +As a final note on performace. Certain CPUs like sparcs and Alpha often give
16266 +a %10 speed difference depending on the link order. It is rather anoying
16267 +when one program reports 'x' DES encrypts a second and another reports
16268 +'x*0.9' the speed.
16269 --- /dev/null Tue Mar 11 13:02:56 2003
16270 +++ linux/net/ipsec/des/Makefile Mon Feb 9 13:51:03 2004
16271 @@ -0,0 +1,60 @@
16272 +# Makefile for KLIPS kernel code as a module for 2.6 kernels
16273 +#
16274 +# Makefile for KLIPS kernel code as a module
16275 +# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
16276 +# Copyright (C) 2002-2004 Michael Richardson <mcr@freeswan.org>
16277 +#
16278 +# This program is free software; you can redistribute it and/or modify it
16279 +# under the terms of the GNU General Public License as published by the
16280 +# Free Software Foundation; either version 2 of the License, or (at your
16281 +# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16282 +#
16283 +# This program is distributed in the hope that it will be useful, but
16284 +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16285 +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16286 +# for more details.
16287 +#
16288 +# RCSID $Id: Makefile.fs2_6,v 1.3 2005/08/12 14:13:59 mcr Exp $
16289 +#
16290 +# Note! Dependencies are done automagically by 'make dep', which also
16291 +# removes any old dependencies. DON'T put your own dependencies here
16292 +# unless it's something special (ie not a .c file).
16293 +#
16294 +
16295 +obj-$(CONFIG_KLIPS_ENC_3DES) += ipsec_alg_3des.o
16296 +obj-$(CONFIG_KLIPS_ENC_3DES) += cbc_enc.o
16297 +obj-$(CONFIG_KLIPS_ENC_3DES) += ecb_enc.o
16298 +obj-$(CONFIG_KLIPS_ENC_3DES) += set_key.o
16299 +
16300 +ifeq ($(strip ${SUBARCH}),)
16301 +SUBARCH:=${ARCH}
16302 +endif
16303 +
16304 +# the assembly version expects frame pointers, which are
16305 +# optional in many kernel builds. If you want speed, you should
16306 +# probably use cryptoapi code instead.
16307 +USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
16308 +ifeq (${USEASSEMBLY},i386y)
16309 +obj-$(CONFIG_KLIPS_ENC_3DES) += dx86unix.o
16310 +else
16311 +obj-$(CONFIG_KLIPS_ENC_3DES) += des_enc.o
16312 +endif
16313 +
16314 +#
16315 +# $Log: Makefile.fs2_6,v $
16316 +# Revision 1.3 2005/08/12 14:13:59 mcr
16317 +# do not use assembly code with there are no frame pointers,
16318 +# as it does not have the right linkages.
16319 +#
16320 +# Revision 1.2 2005/04/29 05:13:07 mcr
16321 +# 3DES algorithm code.
16322 +#
16323 +# Revision 1.1 2004/08/17 03:27:30 mcr
16324 +# klips 2.6 edits.
16325 +#
16326 +#
16327 +# Local Variables:
16328 +# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
16329 +# End Variables:
16330 +#
16331 +
16332 --- /dev/null Tue Mar 11 13:02:56 2003
16333 +++ linux/net/ipsec/des/README Mon Feb 9 13:51:03 2004
16334 @@ -0,0 +1,54 @@
16335 +
16336 + libdes, Version 4.01 10-Jan-97
16337 +
16338 + Copyright (c) 1997, Eric Young
16339 + All rights reserved.
16340 +
16341 + This program is free software; you can redistribute it and/or modify
16342 + it under the terms specified in COPYRIGHT.
16343 +
16344 +--
16345 +The primary ftp site for this library is
16346 +ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz
16347 +libdes is now also shipped with SSLeay. Primary ftp site of
16348 +ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz
16349 +
16350 +The best way to build this library is to build it as part of SSLeay.
16351 +
16352 +This kit builds a DES encryption library and a DES encryption program.
16353 +It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb,
16354 +triple cfb, desx, and MIT's pcbc encryption modes and also has a fast
16355 +implementation of crypt(3).
16356 +It contains support routines to read keys from a terminal,
16357 +generate a random key, generate a key from an arbitrary length string,
16358 +read/write encrypted data from/to a file descriptor.
16359 +
16360 +The implementation was written so as to conform with the manual entry
16361 +for the des_crypt(3) library routines from MIT's project Athena.
16362 +
16363 +destest should be run after compilation to test the des routines.
16364 +rpw should be run after compilation to test the read password routines.
16365 +The des program is a replacement for the sun des command. I believe it
16366 +conforms to the sun version.
16367 +
16368 +The Imakefile is setup for use in the kerberos distribution.
16369 +
16370 +These routines are best compiled with gcc or any other good
16371 +optimising compiler.
16372 +Just turn you optimiser up to the highest settings and run destest
16373 +after the build to make sure everything works.
16374 +
16375 +I believe these routines are close to the fastest and most portable DES
16376 +routines that use small lookup tables (4.5k) that are publicly available.
16377 +The fcrypt routine is faster than ufc's fcrypt (when compiling with
16378 +gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines
16379 +(on a sun3/260 168 vs 336). It is a function of CPU on chip cache size.
16380 +[ 10-Jan-97 and a function of an incorrect speed testing program in
16381 + ufc which gave much better test figures that reality ].
16382 +
16383 +It is worth noting that on sparc and Alpha CPUs, performance of the DES
16384 +library can vary by upto %10 due to the positioning of files after application
16385 +linkage.
16386 +
16387 +Eric Young (eay@cryptsoft.com)
16388 +
16389 --- /dev/null Tue Mar 11 13:02:56 2003
16390 +++ linux/net/ipsec/des/README.freeswan Mon Feb 9 13:51:03 2004
16391 @@ -0,0 +1,33 @@
16392 +The only changes the FreeS/WAN project has made to libdes-lite 4.04b are:
16393 +
16394 +We #ifdef-ed the declaration of DES_LONG in des.h, so it's more efficient
16395 +on the Alpha, instead of just noting the issue in a comment.
16396 +
16397 +We #ifdef-ed out the des_options() function in ecb_enc.c, because we don't
16398 +use it, and its call to sprintf() can cause subtle difficulties when KLIPS
16399 +is built as a module (depending on details of Linux configuration options).
16400 +
16401 +We changed some instances of CC=$(CC) in the Makefile to CC='$(CC)' to make
16402 +it cope better with Linux kernel Makefile stupidities, and took out an
16403 +explicit CC=gcc (unwise on systems with strange compilers).
16404 +
16405 +We deleted some references to <stdio.h> and <stdlib.h>, and a declaration
16406 +of one function found only in the full libdes (not in libdes-lite), to
16407 +avoid dragging in bits of stdio/stdlib unnecessarily. (Our thanks to Hans
16408 +Schultz for spotting this and pointing out the fixes.)
16409 +
16410 +We deleted a couple of .obj files in the asm subdirectory, which appear to
16411 +have been included in the original library by accident.
16412 +
16413 +We have added an include of our Makefile.inc file, to permit overriding
16414 +things like choice of compiler (although the libdes Makefile would
16415 +probably need some work to make this effective).
16416 +
16417 +
16418 +
16419 +Note that Eric Young is no longer at the email address listed in these
16420 +files, and is (alas) no longer working on free crypto software.
16421 +
16422 +
16423 +
16424 +This file is RCSID $Id: README.freeswan,v 1.12 2004/07/10 08:06:51 mcr Exp $
16425 --- /dev/null Tue Mar 11 13:02:56 2003
16426 +++ linux/net/ipsec/des/VERSION Mon Feb 9 13:51:03 2004
16427 @@ -0,0 +1,406 @@
16428 +Version 4.04
16429 + Fixed a few tests in destest. Also added x86 assember for
16430 + des_ncbc_encrypt() which is the standard cbc mode function.
16431 + This makes a very very large performace difference.
16432 + Ariel Glenn ariel@columbia.edu reports that the terminal
16433 + 'turn echo off' can return (errno == EINVAL) under solaris
16434 + when redirection is used. So I now catch that as well as ENOTTY.
16435 +
16436 +
16437 +Version 4.03
16438 + Left a static out of enc_write.c, which caused to buffer to be
16439 + continiously malloc()ed. Does anyone use these functions? I keep
16440 + on feeling like removing them since I only had these in there
16441 + for a version of kerberised login. Anyway, this was pointed out
16442 + by Theo de Raadt <deraadt@cvs.openbsd.org>
16443 + The 'n' bit ofb code was wrong, it was not shifting the shift
16444 + register. It worked correctly for n == 64. Thanks to
16445 + Gigi Ankeny <Gigi.Ankeny@Eng.Sun.COM> for pointing this one out.
16446 +
16447 +Version 4.02
16448 + I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)'
16449 + when checking for weak keys which is wrong :-(, pointed out by
16450 + Markus F.X.J. Oberhumer <markus.oberhumer@jk.uni-linz.ac.at>.
16451 +
16452 +Version 4.01
16453 + Even faster inner loop in the DES assembler for x86 and a modification
16454 + for IP/FP which is faster on x86. Both of these changes are
16455 + from Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>. His
16456 + changes make the assembler run %40 faster on a pentium. This is just
16457 + a case of getting the instruction sequence 'just right'.
16458 + All credit to 'Svend' :-)
16459 + Quite a few special x86 'make' targets.
16460 + A libdes-l (lite) distribution.
16461 +
16462 +Version 4.00
16463 + After a bit of a pause, I'll up the major version number since this
16464 + is mostly a performace release. I've added x86 assembler and
16465 + added more options for performance. A %28 speedup for gcc
16466 + on a pentium and the assembler is a %50 speedup.
16467 + MIPS CPU's, sparc and Alpha are the main CPU's with speedups.
16468 + Run des_opts to work out which options should be used.
16469 + DES_RISC1/DES_RISC2 use alternative inner loops which use
16470 + more registers but should give speedups on any CPU that does
16471 + dual issue (pentium). DES_UNROLL unrolls the inner loop,
16472 + which costs in code size.
16473 +
16474 +Version 3.26
16475 + I've finally removed one of the shifts in D_ENCRYPT. This
16476 + meant I've changed the des_SPtrans table (spr.h), the set_key()
16477 + function and some things in des_enc.c. This has definitly
16478 + made things faster :-). I've known about this one for some
16479 + time but I've been too lazy to follow it up :-).
16480 + Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^..
16481 + instead of L^=((..)|(..)|(..).. This should save a register at
16482 + least.
16483 + Assember for x86. The file to replace is des_enc.c, which is replaced
16484 + by one of the assembler files found in asm. Look at des/asm/readme
16485 + for more info.
16486 +
16487 + /* Modification to fcrypt so it can be compiled to support
16488 + HPUX 10.x's long password format, define -DLONGCRYPT to use this.
16489 + Thanks to Jens Kupferschmidt <bt1cu@hpboot.rz.uni-leipzig.de>. */
16490 +
16491 + SIGWINCH case put in des_read_passwd() so the function does not
16492 + 'exit' if this function is recieved.
16493 +
16494 +Version 3.25 17/07/96
16495 + Modified read_pwd.c so that stdin can be read if not a tty.
16496 + Thanks to Jeff Barber <jeffb@issl.atl.hp.com> for the patches.
16497 + des_init_random_number_generator() shortened due to VMS linker
16498 + limits.
16499 + Added RSA's DESX cbc mode. It is a form of cbc encryption, with 2
16500 + 8 byte quantites xored before and after encryption.
16501 + des_xcbc_encryption() - the name is funny to preserve the des_
16502 + prefix on all functions.
16503 +
16504 +Version 3.24 20/04/96
16505 + The DES_PTR macro option checked and used by SSLeay configuration
16506 +
16507 +Version 3.23 11/04/96
16508 + Added DES_LONG. If defined to 'unsigned int' on the DEC Alpha,
16509 + it gives a %20 speedup :-)
16510 + Fixed the problem with des.pl under perl5. The patches were
16511 + sent by Ed Kubaitis (ejk@uiuc.edu).
16512 + if fcrypt.c, changed values to handle illegal salt values the way
16513 + normal crypt() implementations do. Some programs apparently use
16514 + them :-(. The patch was sent by Bjorn Gronvall <bg@sics.se>
16515 +
16516 +Version 3.22 29/11/95
16517 + Bug in des(1), an error with the uuencoding stuff when the
16518 + 'data' is small, thanks to Geoff Keating <keagchon@mehta.anu.edu.au>
16519 + for the patch.
16520 +
16521 +Version 3.21 22/11/95
16522 + After some emailing back and forth with
16523 + Colin Plumb <colin@nyx10.cs.du.edu>, I've tweaked a few things
16524 + and in a future version I will probably put in some of the
16525 + optimisation he suggested for use with the DES_USE_PTR option.
16526 + Extra routines from Mark Murray <mark@grondar.za> for use in
16527 + freeBSD. They mostly involve random number generation for use
16528 + with kerberos. They involve evil machine specific system calls
16529 + etc so I would normally suggest pushing this stuff into the
16530 + application and/or using RAND_seed()/RAND_bytes() if you are
16531 + using this DES library as part of SSLeay.
16532 + Redone the read_pw() function so that it is cleaner and
16533 + supports termios, thanks to Sameer Parekh <sameer@c2.org>
16534 + for the initial patches for this.
16535 + Renamed 3ecb_encrypt() to ecb3_encrypt(). This has been
16536 + done just to make things more consistent.
16537 + I have also now added triple DES versions of cfb and ofb.
16538 +
16539 +Version 3.20
16540 + Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com,
16541 + my des_random_seed() function was only copying 4 bytes of the
16542 + passed seed into the init structure. It is now fixed to copy 8.
16543 + My own suggestion is to used something like MD5 :-)
16544 +
16545 +Version 3.19
16546 + While looking at my code one day, I though, why do I keep on
16547 + calling des_encrypt(in,out,ks,enc) when every function that
16548 + calls it has in and out the same. So I dropped the 'out'
16549 + parameter, people should not be using this function.
16550 +
16551 +Version 3.18 30/08/95
16552 + Fixed a few bit with the distribution and the filenames.
16553 + 3.17 had been munged via a move to DOS and back again.
16554 + NO CODE CHANGES
16555 +
16556 +Version 3.17 14/07/95
16557 + Fixed ede3 cbc which I had broken in 3.16. I have also
16558 + removed some unneeded variables in 7-8 of the routines.
16559 +
16560 +Version 3.16 26/06/95
16561 + Added des_encrypt2() which does not use IP/FP, used by triple
16562 + des routines. Tweaked things a bit elsewhere. %13 speedup on
16563 + sparc and %6 on a R4400 for ede3 cbc mode.
16564 +
16565 +Version 3.15 06/06/95
16566 + Added des_ncbc_encrypt(), it is des_cbc mode except that it is
16567 + 'normal' and copies the new iv value back over the top of the
16568 + passed parameter.
16569 + CHANGED des_ede3_cbc_encrypt() so that it too now overwrites
16570 + the iv. THIS WILL BREAK EXISTING CODE, but since this function
16571 + only new, I feel I can change it, not so with des_cbc_encrypt :-(.
16572 + I need to update the documentation.
16573 +
16574 +Version 3.14 31/05/95
16575 + New release upon the world, as part of my SSL implementation.
16576 + New copyright and usage stuff. Basically free for all to use
16577 + as long as you say it came from me :-)
16578 +
16579 +Version 3.13 31/05/95
16580 + A fix in speed.c, if HZ is not defined, I set it to 100.0
16581 + which is reasonable for most unixes except SunOS 4.x.
16582 + I now have a #ifdef sun but timing for SunOS 4.x looked very
16583 + good :-(. At my last job where I used SunOS 4.x, it was
16584 + defined to be 60.0 (look at the old INSTALL documentation), at
16585 + the last release had it changed to 100.0 since I now work with
16586 + Solaris2 and SVR4 boxes.
16587 + Thanks to Rory Chisholm <rchishol@math.ethz.ch> for pointing this
16588 + one out.
16589 +
16590 +Version 3.12 08/05/95
16591 + As pointed out by The Crypt Keeper <tck@bend.UCSD.EDU>,
16592 + my D_ENCRYPT macro in crypt() had an un-necessary variable.
16593 + It has been removed.
16594 +
16595 +Version 3.11 03/05/95
16596 + Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys
16597 + and one iv. It is a standard and I needed it for my SSL code.
16598 + It makes more sense to use this for triple DES than
16599 + 3cbc_encrypt(). I have also added (or should I say tested :-)
16600 + cfb64_encrypt() which is cfb64 but it will encrypt a partial
16601 + number of bytes - 3 bytes in 3 bytes out. Again this is for
16602 + my SSL library, as a form of encryption to use with SSL
16603 + telnet.
16604 +
16605 +Version 3.10 22/03/95
16606 + Fixed a bug in 3cbc_encrypt() :-(. When making repeated calls
16607 + to cbc3_encrypt, the 2 iv values that were being returned to
16608 + be used in the next call were reversed :-(.
16609 + Many thanks to Bill Wade <wade@Stoner.COM> for pointing out
16610 + this error.
16611 +
16612 +Version 3.09 01/02/95
16613 + Fixed des_random_key to far more random, it was rather feeble
16614 + with regards to picking the initial seed. The problem was
16615 + pointed out by Olaf Kirch <okir@monad.swb.de>.
16616 +
16617 +Version 3.08 14/12/94
16618 + Added Makefile.PL so libdes can be built into perl5.
16619 + Changed des_locl.h so RAND is always defined.
16620 +
16621 +Version 3.07 05/12/94
16622 + Added GNUmake and stuff so the library can be build with
16623 + glibc.
16624 +
16625 +Version 3.06 30/08/94
16626 + Added rpc_enc.c which contains _des_crypt. This is for use in
16627 + secure_rpc v 4.0
16628 + Finally fixed the cfb_enc problems.
16629 + Fixed a few parameter parsing bugs in des (-3 and -b), thanks
16630 + to Rob McMillan <R.McMillan@its.gu.edu.au>
16631 +
16632 +Version 3.05 21/04/94
16633 + for unsigned long l; gcc does not produce ((l>>34) == 0)
16634 + This causes bugs in cfb_enc.
16635 + Thanks to Hadmut Danisch <danisch@ira.uka.de>
16636 +
16637 +Version 3.04 20/04/94
16638 + Added a version number to des.c and libdes.a
16639 +
16640 +Version 3.03 12/01/94
16641 + Fixed a bug in non zero iv in 3cbc_enc.
16642 +
16643 +Version 3.02 29/10/93
16644 + I now work in a place where there are 6+ architectures and 14+
16645 + OS versions :-).
16646 + Fixed TERMIO definition so the most sys V boxes will work :-)
16647 +
16648 +Release upon comp.sources.misc
16649 +Version 3.01 08/10/93
16650 + Added des_3cbc_encrypt()
16651 +
16652 +Version 3.00 07/10/93
16653 + Fixed up documentation.
16654 + quad_cksum definitely compatible with MIT's now.
16655 +
16656 +Version 2.30 24/08/93
16657 + Triple DES now defaults to triple cbc but can do triple ecb
16658 + with the -b flag.
16659 + Fixed some MSDOS uuen/uudecoding problems, thanks to
16660 + Added prototypes.
16661 +
16662 +Version 2.22 29/06/93
16663 + Fixed a bug in des_is_weak_key() which stopped it working :-(
16664 + thanks to engineering@MorningStar.Com.
16665 +
16666 +Version 2.21 03/06/93
16667 + des(1) with no arguments gives quite a bit of help.
16668 + Added -c (generate ckecksum) flag to des(1).
16669 + Added -3 (triple DES) flag to des(1).
16670 + Added cfb and ofb routines to the library.
16671 +
16672 +Version 2.20 11/03/93
16673 + Added -u (uuencode) flag to des(1).
16674 + I have been playing with byte order in quad_cksum to make it
16675 + compatible with MIT's version. All I can say is avid this
16676 + function if possible since MIT's output is endian dependent.
16677 +
16678 +Version 2.12 14/10/92
16679 + Added MSDOS specific macro in ecb_encrypt which gives a %70
16680 + speed up when the code is compiled with turbo C.
16681 +
16682 +Version 2.11 12/10/92
16683 + Speedup in set_key (recoding of PC-1)
16684 + I now do it in 47 simple operations, down from 60.
16685 + Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
16686 + for motivating me to look for a faster system :-)
16687 + The speedup is probably less that 1% but it is still 13
16688 + instructions less :-).
16689 +
16690 +Version 2.10 06/10/92
16691 + The code now works on the 64bit ETA10 and CRAY without modifications or
16692 + #defines. I believe the code should work on any machine that
16693 + defines long, int or short to be 8 bytes long.
16694 + Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu)
16695 + for helping me fix the code to run on 64bit machines (he had
16696 + access to an ETA10).
16697 + Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov>
16698 + for testing the routines on a CRAY.
16699 + read_password.c has been renamed to read_passwd.c
16700 + string_to_key.c has been renamed to string2key.c
16701 +
16702 +Version 2.00 14/09/92
16703 + Made mods so that the library should work on 64bit CPU's.
16704 + Removed all my uchar and ulong defs. To many different
16705 + versions of unix define them in their header files in too many
16706 + different combinations :-)
16707 + IRIX - Sillicon Graphics mods (mostly in read_password.c).
16708 + Thanks to Andrew Daviel (advax@erich.triumf.ca)
16709 +
16710 +Version 1.99 26/08/92
16711 + Fixed a bug or 2 in enc_read.c
16712 + Fixed a bug in enc_write.c
16713 + Fixed a pseudo bug in fcrypt.c (very obscure).
16714 +
16715 +Version 1.98 31/07/92
16716 + Support for the ETA10. This is a strange machine that defines
16717 + longs and ints as 8 bytes and shorts as 4 bytes.
16718 + Since I do evil things with long * that assume that they are 4
16719 + bytes. Look in the Makefile for the option to compile for
16720 + this machine. quad_cksum appears to have problems but I
16721 + will don't have the time to fix it right now, and this is not
16722 + a function that uses DES and so will not effect the main uses
16723 + of the library.
16724 +
16725 +Version 1.97 20/05/92 eay
16726 + Fixed the Imakefile and made some changes to des.h to fix some
16727 + problems when building this package with Kerberos v 4.
16728 +
16729 +Version 1.96 18/05/92 eay
16730 + Fixed a small bug in string_to_key() where problems could
16731 + occur if des_check_key was set to true and the string
16732 + generated a weak key.
16733 +
16734 +Patch2 posted to comp.sources.misc
16735 +Version 1.95 13/05/92 eay
16736 + Added an alternative version of the D_ENCRYPT macro in
16737 + ecb_encrypt and fcrypt. Depending on the compiler, one version or the
16738 + other will be faster. This was inspired by
16739 + Dana How <how@isl.stanford.edu>, and her pointers about doing the
16740 + *(ulong *)((uchar *)ptr+(value&0xfc))
16741 + vs
16742 + ptr[value&0x3f]
16743 + to stop the C compiler doing a <<2 to convert the long array index.
16744 +
16745 +Version 1.94 05/05/92 eay
16746 + Fixed an incompatibility between my string_to_key and the MIT
16747 + version. When the key is longer than 8 chars, I was wrapping
16748 + with a different method. To use the old version, define
16749 + OLD_STR_TO_KEY in the makefile. Thanks to
16750 + viktor@newsu.shearson.com (Viktor Dukhovni).
16751 +
16752 +Version 1.93 28/04/92 eay
16753 + Fixed the VMS mods so that echo is now turned off in
16754 + read_password. Thanks again to brennan@coco.cchs.su.oz.AU.
16755 + MSDOS support added. The routines can be compiled with
16756 + Turbo C (v2.0) and MSC (v5.1). Make sure MSDOS is defined.
16757 +
16758 +Patch1 posted to comp.sources.misc
16759 +Version 1.92 13/04/92 eay
16760 + Changed D_ENCRYPT so that the rotation of R occurs outside of
16761 + the loop. This required rotating all the longs in sp.h (now
16762 + called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
16763 + speed.c has been changed so it will work without SIGALRM. If
16764 + times(3) is not present it will try to use ftime() instead.
16765 +
16766 +Version 1.91 08/04/92 eay
16767 + Added -E/-D options to des(1) so it can use string_to_key.
16768 + Added SVR4 mods suggested by witr@rwwa.COM
16769 + Added VMS mods suggested by brennan@coco.cchs.su.oz.AU. If
16770 + anyone knows how to turn of tty echo in VMS please tell me or
16771 + implement it yourself :-).
16772 + Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS
16773 + does not like IN/OUT being used.
16774 +
16775 +Libdes posted to comp.sources.misc
16776 +Version 1.9 24/03/92 eay
16777 + Now contains a fast small crypt replacement.
16778 + Added des(1) command.
16779 + Added des_rw_mode so people can use cbc encryption with
16780 + enc_read and enc_write.
16781 +
16782 +Version 1.8 15/10/91 eay
16783 + Bug in cbc_cksum.
16784 + Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this
16785 + one out.
16786 +
16787 +Version 1.7 24/09/91 eay
16788 + Fixed set_key :-)
16789 + set_key is 4 times faster and takes less space.
16790 + There are a few minor changes that could be made.
16791 +
16792 +Version 1.6 19/09/1991 eay
16793 + Finally go IP and FP finished.
16794 + Now I need to fix set_key.
16795 + This version is quite a bit faster that 1.51
16796 +
16797 +Version 1.52 15/06/1991 eay
16798 + 20% speedup in ecb_encrypt by changing the E bit selection
16799 + to use 2 32bit words. This also required modification of the
16800 + sp table. There is still a way to speedup the IP and IP-1
16801 + (hints from outer@sq.com) still working on this one :-(.
16802 +
16803 +Version 1.51 07/06/1991 eay
16804 + Faster des_encrypt by loop unrolling
16805 + Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu)
16806 +
16807 +Version 1.50 28/05/1991 eay
16808 + Optimised the code a bit more for the sparc. I have improved the
16809 + speed of the inner des_encrypt by speeding up the initial and
16810 + final permutations.
16811 +
16812 +Version 1.40 23/10/1990 eay
16813 + Fixed des_random_key, it did not produce a random key :-(
16814 +
16815 +Version 1.30 2/10/1990 eay
16816 + Have made des_quad_cksum the same as MIT's, the full package
16817 + should be compatible with MIT's
16818 + Have tested on a DECstation 3100
16819 + Still need to fix des_set_key (make it faster).
16820 + Does des_cbc_encrypts at 70.5k/sec on a 3100.
16821 +
16822 +Version 1.20 18/09/1990 eay
16823 + Fixed byte order dependencies.
16824 + Fixed (I hope) all the word alignment problems.
16825 + Speedup in des_ecb_encrypt.
16826 +
16827 +Version 1.10 11/09/1990 eay
16828 + Added des_enc_read and des_enc_write.
16829 + Still need to fix des_quad_cksum.
16830 + Still need to document des_enc_read and des_enc_write.
16831 +
16832 +Version 1.00 27/08/1990 eay
16833 +
16834 --- /dev/null Tue Mar 11 13:02:56 2003
16835 +++ linux/net/ipsec/des/asm/des-586.pl Mon Feb 9 13:51:03 2004
16836 @@ -0,0 +1,251 @@
16837 +#!/usr/local/bin/perl
16838 +#
16839 +# The inner loop instruction sequence and the IP/FP modifications are from
16840 +# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
16841 +#
16842 +
16843 +push(@INC,"perlasm","../../perlasm");
16844 +require "x86asm.pl";
16845 +require "cbc.pl";
16846 +require "desboth.pl";
16847 +
16848 +# base code is in microsft
16849 +# op dest, source
16850 +# format.
16851 +#
16852 +
16853 +&asm_init($ARGV[0],"des-586.pl");
16854 +
16855 +$L="edi";
16856 +$R="esi";
16857 +
16858 +&external_label("des_SPtrans");
16859 +&des_encrypt("des_encrypt",1);
16860 +&des_encrypt("des_encrypt2",0);
16861 +&des_encrypt3("des_encrypt3",1);
16862 +&des_encrypt3("des_decrypt3",0);
16863 +&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
16864 +&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
16865 +
16866 +&asm_finish();
16867 +
16868 +sub des_encrypt
16869 + {
16870 + local($name,$do_ip)=@_;
16871 +
16872 + &function_begin_B($name,"EXTRN _des_SPtrans:DWORD");
16873 +
16874 + &push("esi");
16875 + &push("edi");
16876 +
16877 + &comment("");
16878 + &comment("Load the 2 words");
16879 + $ks="ebp";
16880 +
16881 + if ($do_ip)
16882 + {
16883 + &mov($R,&wparam(0));
16884 + &xor( "ecx", "ecx" );
16885 +
16886 + &push("ebx");
16887 + &push("ebp");
16888 +
16889 + &mov("eax",&DWP(0,$R,"",0));
16890 + &mov("ebx",&wparam(2)); # get encrypt flag
16891 + &mov($L,&DWP(4,$R,"",0));
16892 + &comment("");
16893 + &comment("IP");
16894 + &IP_new("eax",$L,$R,3);
16895 + }
16896 + else
16897 + {
16898 + &mov("eax",&wparam(0));
16899 + &xor( "ecx", "ecx" );
16900 +
16901 + &push("ebx");
16902 + &push("ebp");
16903 +
16904 + &mov($R,&DWP(0,"eax","",0));
16905 + &mov("ebx",&wparam(2)); # get encrypt flag
16906 + &rotl($R,3);
16907 + &mov($L,&DWP(4,"eax","",0));
16908 + &rotl($L,3);
16909 + }
16910 +
16911 + &mov( $ks, &wparam(1) );
16912 + &cmp("ebx","0");
16913 + &je(&label("start_decrypt"));
16914 +
16915 + for ($i=0; $i<16; $i+=2)
16916 + {
16917 + &comment("");
16918 + &comment("Round $i");
16919 + &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
16920 +
16921 + &comment("");
16922 + &comment("Round ".sprintf("%d",$i+1));
16923 + &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
16924 + }
16925 + &jmp(&label("end"));
16926 +
16927 + &set_label("start_decrypt");
16928 +
16929 + for ($i=15; $i>0; $i-=2)
16930 + {
16931 + &comment("");
16932 + &comment("Round $i");
16933 + &D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
16934 + &comment("");
16935 + &comment("Round ".sprintf("%d",$i-1));
16936 + &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
16937 + }
16938 +
16939 + &set_label("end");
16940 +
16941 + if ($do_ip)
16942 + {
16943 + &comment("");
16944 + &comment("FP");
16945 + &mov("edx",&wparam(0));
16946 + &FP_new($L,$R,"eax",3);
16947 +
16948 + &mov(&DWP(0,"edx","",0),"eax");
16949 + &mov(&DWP(4,"edx","",0),$R);
16950 + }
16951 + else
16952 + {
16953 + &comment("");
16954 + &comment("Fixup");
16955 + &rotr($L,3); # r
16956 + &mov("eax",&wparam(0));
16957 + &rotr($R,3); # l
16958 + &mov(&DWP(0,"eax","",0),$L);
16959 + &mov(&DWP(4,"eax","",0),$R);
16960 + }
16961 +
16962 + &pop("ebp");
16963 + &pop("ebx");
16964 + &pop("edi");
16965 + &pop("esi");
16966 + &ret();
16967 +
16968 + &function_end_B($name);
16969 + }
16970 +
16971 +sub D_ENCRYPT
16972 + {
16973 + local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
16974 +
16975 + &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
16976 + &xor( $tmp1, $tmp1);
16977 + &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
16978 + &xor( $u, $R);
16979 + &xor( $t, $R);
16980 + &and( $u, "0xfcfcfcfc" );
16981 + &and( $t, "0xcfcfcfcf" );
16982 + &movb( &LB($tmp1), &LB($u) );
16983 + &movb( &LB($tmp2), &HB($u) );
16984 + &rotr( $t, 4 );
16985 + &mov( $ks, &DWP(" $desSP",$tmp1,"",0));
16986 + &movb( &LB($tmp1), &LB($t) );
16987 + &xor( $L, $ks);
16988 + &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
16989 + &xor( $L, $ks); ######
16990 + &movb( &LB($tmp2), &HB($t) );
16991 + &shr( $u, 16);
16992 + &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
16993 + &xor( $L, $ks); ######
16994 + &movb( &LB($tmp1), &HB($u) );
16995 + &shr( $t, 16);
16996 + &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
16997 + &xor( $L, $ks);
16998 + &mov( $ks, &wparam(1) );
16999 + &movb( &LB($tmp2), &HB($t) );
17000 + &and( $u, "0xff" );
17001 + &and( $t, "0xff" );
17002 + &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
17003 + &xor( $L, $tmp1);
17004 + &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
17005 + &xor( $L, $tmp1);
17006 + &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
17007 + &xor( $L, $tmp1);
17008 + &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
17009 + &xor( $L, $tmp1);
17010 + }
17011 +
17012 +sub n2a
17013 + {
17014 + sprintf("%d",$_[0]);
17015 + }
17016 +
17017 +# now has a side affect of rotating $a by $shift
17018 +sub R_PERM_OP
17019 + {
17020 + local($a,$b,$tt,$shift,$mask,$last)=@_;
17021 +
17022 + &rotl( $a, $shift ) if ($shift != 0);
17023 + &mov( $tt, $a );
17024 + &xor( $a, $b );
17025 + &and( $a, $mask );
17026 + if (!$last eq $b)
17027 + {
17028 + &xor( $b, $a );
17029 + &xor( $tt, $a );
17030 + }
17031 + else
17032 + {
17033 + &xor( $tt, $a );
17034 + &xor( $b, $a );
17035 + }
17036 + &comment("");
17037 + }
17038 +
17039 +sub IP_new
17040 + {
17041 + local($l,$r,$tt,$lr)=@_;
17042 +
17043 + &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
17044 + &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
17045 + &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
17046 + &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
17047 + &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
17048 +
17049 + if ($lr != 3)
17050 + {
17051 + if (($lr-3) < 0)
17052 + { &rotr($tt, 3-$lr); }
17053 + else { &rotl($tt, $lr-3); }
17054 + }
17055 + if ($lr != 2)
17056 + {
17057 + if (($lr-2) < 0)
17058 + { &rotr($r, 2-$lr); }
17059 + else { &rotl($r, $lr-2); }
17060 + }
17061 + }
17062 +
17063 +sub FP_new
17064 + {
17065 + local($l,$r,$tt,$lr)=@_;
17066 +
17067 + if ($lr != 2)
17068 + {
17069 + if (($lr-2) < 0)
17070 + { &rotl($r, 2-$lr); }
17071 + else { &rotr($r, $lr-2); }
17072 + }
17073 + if ($lr != 3)
17074 + {
17075 + if (($lr-3) < 0)
17076 + { &rotl($l, 3-$lr); }
17077 + else { &rotr($l, $lr-3); }
17078 + }
17079 +
17080 + &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
17081 + &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
17082 + &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
17083 + &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
17084 + &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
17085 + &rotr($tt , 4);
17086 + }
17087 +
17088 --- /dev/null Tue Mar 11 13:02:56 2003
17089 +++ linux/net/ipsec/des/asm/des686.pl Mon Feb 9 13:51:03 2004
17090 @@ -0,0 +1,230 @@
17091 +#!/usr/local/bin/perl
17092 +
17093 +$prog="des686.pl";
17094 +
17095 +# base code is in microsft
17096 +# op dest, source
17097 +# format.
17098 +#
17099 +
17100 +# WILL NOT WORK ANYMORE WITH desboth.pl
17101 +require "desboth.pl";
17102 +
17103 +if ( ($ARGV[0] eq "elf"))
17104 + { require "x86unix.pl"; }
17105 +elsif ( ($ARGV[0] eq "a.out"))
17106 + { $aout=1; require "x86unix.pl"; }
17107 +elsif ( ($ARGV[0] eq "sol"))
17108 + { $sol=1; require "x86unix.pl"; }
17109 +elsif ( ($ARGV[0] eq "cpp"))
17110 + { $cpp=1; require "x86unix.pl"; }
17111 +elsif ( ($ARGV[0] eq "win32"))
17112 + { require "x86ms.pl"; }
17113 +else
17114 + {
17115 + print STDERR <<"EOF";
17116 +Pick one target type from
17117 + elf - linux, FreeBSD etc
17118 + a.out - old linux
17119 + sol - x86 solaris
17120 + cpp - format so x86unix.cpp can be used
17121 + win32 - Windows 95/Windows NT
17122 +EOF
17123 + exit(1);
17124 + }
17125 +
17126 +&comment("Don't even think of reading this code");
17127 +&comment("It was automatically generated by $prog");
17128 +&comment("Which is a perl program used to generate the x86 assember for");
17129 +&comment("any of elf, a.out, Win32, or Solaris");
17130 +&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
17131 +&comment("eric <eay\@cryptsoft.com>");
17132 +&comment("");
17133 +
17134 +&file("dx86xxxx");
17135 +
17136 +$L="edi";
17137 +$R="esi";
17138 +
17139 +&des_encrypt("des_encrypt",1);
17140 +&des_encrypt("des_encrypt2",0);
17141 +
17142 +&des_encrypt3("des_encrypt3",1);
17143 +&des_encrypt3("des_decrypt3",0);
17144 +
17145 +&file_end();
17146 +
17147 +sub des_encrypt
17148 + {
17149 + local($name,$do_ip)=@_;
17150 +
17151 + &function_begin($name,"EXTRN _des_SPtrans:DWORD");
17152 +
17153 + &comment("");
17154 + &comment("Load the 2 words");
17155 + &mov("eax",&wparam(0));
17156 + &mov($L,&DWP(0,"eax","",0));
17157 + &mov($R,&DWP(4,"eax","",0));
17158 +
17159 + $ksp=&wparam(1);
17160 +
17161 + if ($do_ip)
17162 + {
17163 + &comment("");
17164 + &comment("IP");
17165 + &IP_new($L,$R,"eax");
17166 + }
17167 +
17168 + &comment("");
17169 + &comment("fixup rotate");
17170 + &rotl($R,3);
17171 + &rotl($L,3);
17172 + &exch($L,$R);
17173 +
17174 + &comment("");
17175 + &comment("load counter, key_schedule and enc flag");
17176 + &mov("eax",&wparam(2)); # get encrypt flag
17177 + &mov("ebp",&wparam(1)); # get ks
17178 + &cmp("eax","0");
17179 + &je(&label("start_decrypt"));
17180 +
17181 + # encrypting part
17182 +
17183 + for ($i=0; $i<16; $i+=2)
17184 + {
17185 + &comment("");
17186 + &comment("Round $i");
17187 + &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17188 +
17189 + &comment("");
17190 + &comment("Round ".sprintf("%d",$i+1));
17191 + &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17192 + }
17193 + &jmp(&label("end"));
17194 +
17195 + &set_label("start_decrypt");
17196 +
17197 + for ($i=15; $i>0; $i-=2)
17198 + {
17199 + &comment("");
17200 + &comment("Round $i");
17201 + &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17202 + &comment("");
17203 + &comment("Round ".sprintf("%d",$i-1));
17204 + &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17205 + }
17206 +
17207 + &set_label("end");
17208 +
17209 + &comment("");
17210 + &comment("Fixup");
17211 + &rotr($L,3); # r
17212 + &rotr($R,3); # l
17213 +
17214 + if ($do_ip)
17215 + {
17216 + &comment("");
17217 + &comment("FP");
17218 + &FP_new($R,$L,"eax");
17219 + }
17220 +
17221 + &mov("eax",&wparam(0));
17222 + &mov(&DWP(0,"eax","",0),$L);
17223 + &mov(&DWP(4,"eax","",0),$R);
17224 +
17225 + &function_end($name);
17226 + }
17227 +
17228 +
17229 +# The logic is to load R into 2 registers and operate on both at the same time.
17230 +# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'
17231 +# while also masking the other copy and doing a lookup. We then also accumulate the
17232 +# L value in 2 registers then combine them at the end.
17233 +sub D_ENCRYPT
17234 + {
17235 + local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;
17236 +
17237 + &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
17238 + &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
17239 + &xor( $u, $R );
17240 + &xor( $t, $R );
17241 + &rotr( $t, 4 );
17242 +
17243 + # the numbers at the end of the line are origional instruction order
17244 + &mov( $tmp2, $u ); # 1 2
17245 + &mov( $tmp1, $t ); # 1 1
17246 + &and( $tmp2, "0xfc" ); # 1 4
17247 + &and( $tmp1, "0xfc" ); # 1 3
17248 + &shr( $t, 8 ); # 1 5
17249 + &xor( $L, &DWP("0x100+$desSP",$tmp1,"",0)); # 1 7
17250 + &shr( $u, 8 ); # 1 6
17251 + &mov( $tmp1, &DWP(" $desSP",$tmp2,"",0)); # 1 8
17252 +
17253 + &mov( $tmp2, $u ); # 2 2
17254 + &xor( $L, $tmp1 ); # 1 9
17255 + &and( $tmp2, "0xfc" ); # 2 4
17256 + &mov( $tmp1, $t ); # 2 1
17257 + &and( $tmp1, "0xfc" ); # 2 3
17258 + &shr( $t, 8 ); # 2 5
17259 + &xor( $L, &DWP("0x300+$desSP",$tmp1,"",0)); # 2 7
17260 + &shr( $u, 8 ); # 2 6
17261 + &mov( $tmp1, &DWP("0x200+$desSP",$tmp2,"",0)); # 2 8
17262 + &mov( $tmp2, $u ); # 3 2
17263 +
17264 + &xor( $L, $tmp1 ); # 2 9
17265 + &and( $tmp2, "0xfc" ); # 3 4
17266 +
17267 + &mov( $tmp1, $t ); # 3 1
17268 + &shr( $u, 8 ); # 3 6
17269 + &and( $tmp1, "0xfc" ); # 3 3
17270 + &shr( $t, 8 ); # 3 5
17271 + &xor( $L, &DWP("0x500+$desSP",$tmp1,"",0)); # 3 7
17272 + &mov( $tmp1, &DWP("0x400+$desSP",$tmp2,"",0)); # 3 8
17273 +
17274 + &and( $t, "0xfc" ); # 4 1
17275 + &xor( $L, $tmp1 ); # 3 9
17276 +
17277 + &and( $u, "0xfc" ); # 4 2
17278 + &xor( $L, &DWP("0x700+$desSP",$t,"",0)); # 4 3
17279 + &xor( $L, &DWP("0x600+$desSP",$u,"",0)); # 4 4
17280 + }
17281 +
17282 +sub PERM_OP
17283 + {
17284 + local($a,$b,$tt,$shift,$mask)=@_;
17285 +
17286 + &mov( $tt, $a );
17287 + &shr( $tt, $shift );
17288 + &xor( $tt, $b );
17289 + &and( $tt, $mask );
17290 + &xor( $b, $tt );
17291 + &shl( $tt, $shift );
17292 + &xor( $a, $tt );
17293 + }
17294 +
17295 +sub IP_new
17296 + {
17297 + local($l,$r,$tt)=@_;
17298 +
17299 + &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
17300 + &PERM_OP($l,$r,$tt,16,"0x0000ffff");
17301 + &PERM_OP($r,$l,$tt, 2,"0x33333333");
17302 + &PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
17303 + &PERM_OP($r,$l,$tt, 1,"0x55555555");
17304 + }
17305 +
17306 +sub FP_new
17307 + {
17308 + local($l,$r,$tt)=@_;
17309 +
17310 + &PERM_OP($l,$r,$tt, 1,"0x55555555");
17311 + &PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
17312 + &PERM_OP($l,$r,$tt, 2,"0x33333333");
17313 + &PERM_OP($r,$l,$tt,16,"0x0000ffff");
17314 + &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
17315 + }
17316 +
17317 +sub n2a
17318 + {
17319 + sprintf("%d",$_[0]);
17320 + }
17321 --- /dev/null Tue Mar 11 13:02:56 2003
17322 +++ linux/net/ipsec/des/asm/desboth.pl Mon Feb 9 13:51:03 2004
17323 @@ -0,0 +1,79 @@
17324 +#!/usr/local/bin/perl
17325 +
17326 +$L="edi";
17327 +$R="esi";
17328 +
17329 +sub des_encrypt3
17330 + {
17331 + local($name,$enc)=@_;
17332 +
17333 + &function_begin_B($name,"");
17334 + &push("ebx");
17335 + &mov("ebx",&wparam(0));
17336 +
17337 + &push("ebp");
17338 + &push("esi");
17339 +
17340 + &push("edi");
17341 +
17342 + &comment("");
17343 + &comment("Load the data words");
17344 + &mov($L,&DWP(0,"ebx","",0));
17345 + &mov($R,&DWP(4,"ebx","",0));
17346 + &stack_push(3);
17347 +
17348 + &comment("");
17349 + &comment("IP");
17350 + &IP_new($L,$R,"edx",0);
17351 +
17352 + # put them back
17353 +
17354 + if ($enc)
17355 + {
17356 + &mov(&DWP(4,"ebx","",0),$R);
17357 + &mov("eax",&wparam(1));
17358 + &mov(&DWP(0,"ebx","",0),"edx");
17359 + &mov("edi",&wparam(2));
17360 + &mov("esi",&wparam(3));
17361 + }
17362 + else
17363 + {
17364 + &mov(&DWP(4,"ebx","",0),$R);
17365 + &mov("esi",&wparam(1));
17366 + &mov(&DWP(0,"ebx","",0),"edx");
17367 + &mov("edi",&wparam(2));
17368 + &mov("eax",&wparam(3));
17369 + }
17370 + &mov(&swtmp(2), (($enc)?"1":"0"));
17371 + &mov(&swtmp(1), "eax");
17372 + &mov(&swtmp(0), "ebx");
17373 + &call("des_encrypt2");
17374 + &mov(&swtmp(2), (($enc)?"0":"1"));
17375 + &mov(&swtmp(1), "edi");
17376 + &mov(&swtmp(0), "ebx");
17377 + &call("des_encrypt2");
17378 + &mov(&swtmp(2), (($enc)?"1":"0"));
17379 + &mov(&swtmp(1), "esi");
17380 + &mov(&swtmp(0), "ebx");
17381 + &call("des_encrypt2");
17382 +
17383 + &stack_pop(3);
17384 + &mov($L,&DWP(0,"ebx","",0));
17385 + &mov($R,&DWP(4,"ebx","",0));
17386 +
17387 + &comment("");
17388 + &comment("FP");
17389 + &FP_new($L,$R,"eax",0);
17390 +
17391 + &mov(&DWP(0,"ebx","",0),"eax");
17392 + &mov(&DWP(4,"ebx","",0),$R);
17393 +
17394 + &pop("edi");
17395 + &pop("esi");
17396 + &pop("ebp");
17397 + &pop("ebx");
17398 + &ret();
17399 + &function_end_B($name);
17400 + }
17401 +
17402 +
17403 --- /dev/null Tue Mar 11 13:02:56 2003
17404 +++ linux/net/ipsec/des/asm/readme Mon Feb 9 13:51:03 2004
17405 @@ -0,0 +1,131 @@
17406 +First up, let me say I don't like writing in assembler. It is not portable,
17407 +dependant on the particular CPU architecture release and is generally a pig
17408 +to debug and get right. Having said that, the x86 architecture is probably
17409 +the most important for speed due to number of boxes and since
17410 +it appears to be the worst architecture to to get
17411 +good C compilers for. So due to this, I have lowered myself to do
17412 +assembler for the inner DES routines in libdes :-).
17413 +
17414 +The file to implement in assembler is des_enc.c. Replace the following
17415 +4 functions
17416 +des_encrypt(DES_LONG data[2],des_key_schedule ks, int encrypt);
17417 +des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt);
17418 +des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
17419 +des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
17420 +
17421 +They encrypt/decrypt the 64 bits held in 'data' using
17422 +the 'ks' key schedules. The only difference between the 4 functions is that
17423 +des_encrypt2() does not perform IP() or FP() on the data (this is an
17424 +optimization for when doing triple DES and des_encrypt3() and des_decrypt3()
17425 +perform triple des. The triple DES routines are in here because it does
17426 +make a big difference to have them located near the des_encrypt2 function
17427 +at link time..
17428 +
17429 +Now as we all know, there are lots of different operating systems running on
17430 +x86 boxes, and unfortunately they normally try to make sure their assembler
17431 +formating is not the same as the other peoples.
17432 +The 4 main formats I know of are
17433 +Microsoft Windows 95/Windows NT
17434 +Elf Includes Linux and FreeBSD(?).
17435 +a.out The older Linux.
17436 +Solaris Same as Elf but different comments :-(.
17437 +
17438 +Now I was not overly keen to write 4 different copies of the same code,
17439 +so I wrote a few perl routines to output the correct assembler, given
17440 +a target assembler type. This code is ugly and is just a hack.
17441 +The libraries are x86unix.pl and x86ms.pl.
17442 +des586.pl, des686.pl and des-som[23].pl are the programs to actually
17443 +generate the assembler.
17444 +
17445 +So to generate elf assembler
17446 +perl des-som3.pl elf >dx86-elf.s
17447 +For Windows 95/NT
17448 +perl des-som2.pl win32 >win32.asm
17449 +
17450 +[ update 4 Jan 1996 ]
17451 +I have added another way to do things.
17452 +perl des-som3.pl cpp >dx86-cpp.s
17453 +generates a file that will be included by dx86unix.cpp when it is compiled.
17454 +To build for elf, a.out, solaris, bsdi etc,
17455 +cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o
17456 +cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o
17457 +cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o
17458 +cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o
17459 +This was done to cut down the number of files in the distribution.
17460 +
17461 +Now the ugly part. I acquired my copy of Intels
17462 +"Optimization's For Intel's 32-Bit Processors" and found a few interesting
17463 +things. First, the aim of the exersize is to 'extract' one byte at a time
17464 +from a word and do an array lookup. This involves getting the byte from
17465 +the 4 locations in the word and moving it to a new word and doing the lookup.
17466 +The most obvious way to do this is
17467 +xor eax, eax # clear word
17468 +movb al, cl # get low byte
17469 +xor edi DWORD PTR 0x100+des_SP[eax] # xor in word
17470 +movb al, ch # get next byte
17471 +xor edi DWORD PTR 0x300+des_SP[eax] # xor in word
17472 +shr ecx 16
17473 +which seems ok. For the pentium, this system appears to be the best.
17474 +One has to do instruction interleaving to keep both functional units
17475 +operating, but it is basically very efficient.
17476 +
17477 +Now the crunch. When a full register is used after a partial write, eg.
17478 +mov al, cl
17479 +xor edi, DWORD PTR 0x100+des_SP[eax]
17480 +386 - 1 cycle stall
17481 +486 - 1 cycle stall
17482 +586 - 0 cycle stall
17483 +686 - at least 7 cycle stall (page 22 of the above mentioned document).
17484 +
17485 +So the technique that produces the best results on a pentium, according to
17486 +the documentation, will produce hideous results on a pentium pro.
17487 +
17488 +To get around this, des686.pl will generate code that is not as fast on
17489 +a pentium, should be very good on a pentium pro.
17490 +mov eax, ecx # copy word
17491 +shr ecx, 8 # line up next byte
17492 +and eax, 0fch # mask byte
17493 +xor edi DWORD PTR 0x100+des_SP[eax] # xor in array lookup
17494 +mov eax, ecx # get word
17495 +shr ecx 8 # line up next byte
17496 +and eax, 0fch # mask byte
17497 +xor edi DWORD PTR 0x300+des_SP[eax] # xor in array lookup
17498 +
17499 +Due to the execution units in the pentium, this actually works quite well.
17500 +For a pentium pro it should be very good. This is the type of output
17501 +Visual C++ generates.
17502 +
17503 +There is a third option. instead of using
17504 +mov al, ch
17505 +which is bad on the pentium pro, one may be able to use
17506 +movzx eax, ch
17507 +which may not incur the partial write penalty. On the pentium,
17508 +this instruction takes 4 cycles so is not worth using but on the
17509 +pentium pro it appears it may be worth while. I need access to one to
17510 +experiment :-).
17511 +
17512 +eric (20 Oct 1996)
17513 +
17514 +22 Nov 1996 - I have asked people to run the 2 different version on pentium
17515 +pros and it appears that the intel documentation is wrong. The
17516 +mov al,bh is still faster on a pentium pro, so just use the des586.pl
17517 +install des686.pl
17518 +
17519 +3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these
17520 +functions into des_enc.c because it does make a massive performance
17521 +difference on some boxes to have the functions code located close to
17522 +the des_encrypt2() function.
17523 +
17524 +9 Jan 1997 - des-som2.pl is now the correct perl script to use for
17525 +pentiums. It contains an inner loop from
17526 +Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at
17527 +273,000 per second. He had a previous version at 250,000 and the best
17528 +I was able to get was 203,000. The content has not changed, this is all
17529 +due to instruction sequencing (and actual instructions choice) which is able
17530 +to keep both functional units of the pentium going.
17531 +We may have lost the ugly register usage restrictions when x86 went 32 bit
17532 +but for the pentium it has been replaced by evil instruction ordering tricks.
17533 +
17534 +13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf.
17535 +raw DES at 281,000 per second on a pentium 100.
17536 +
17537 --- /dev/null Tue Mar 11 13:02:56 2003
17538 +++ linux/net/ipsec/des/cbc_enc.c Mon Feb 9 13:51:03 2004
17539 @@ -0,0 +1,135 @@
17540 +/* crypto/des/cbc_enc.c */
17541 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
17542 + * All rights reserved.
17543 + *
17544 + * This package is an SSL implementation written
17545 + * by Eric Young (eay@cryptsoft.com).
17546 + * The implementation was written so as to conform with Netscapes SSL.
17547 + *
17548 + * This library is free for commercial and non-commercial use as long as
17549 + * the following conditions are aheared to. The following conditions
17550 + * apply to all code found in this distribution, be it the RC4, RSA,
17551 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
17552 + * included with this distribution is covered by the same copyright terms
17553 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
17554 + *
17555 + * Copyright remains Eric Young's, and as such any Copyright notices in
17556 + * the code are not to be removed.
17557 + * If this package is used in a product, Eric Young should be given attribution
17558 + * as the author of the parts of the library used.
17559 + * This can be in the form of a textual message at program startup or
17560 + * in documentation (online or textual) provided with the package.
17561 + *
17562 + * Redistribution and use in source and binary forms, with or without
17563 + * modification, are permitted provided that the following conditions
17564 + * are met:
17565 + * 1. Redistributions of source code must retain the copyright
17566 + * notice, this list of conditions and the following disclaimer.
17567 + * 2. Redistributions in binary form must reproduce the above copyright
17568 + * notice, this list of conditions and the following disclaimer in the
17569 + * documentation and/or other materials provided with the distribution.
17570 + * 3. All advertising materials mentioning features or use of this software
17571 + * must display the following acknowledgement:
17572 + * "This product includes cryptographic software written by
17573 + * Eric Young (eay@cryptsoft.com)"
17574 + * The word 'cryptographic' can be left out if the rouines from the library
17575 + * being used are not cryptographic related :-).
17576 + * 4. If you include any Windows specific code (or a derivative thereof) from
17577 + * the apps directory (application code) you must include an acknowledgement:
17578 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
17579 + *
17580 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
17581 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17582 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17583 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17584 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17585 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
17586 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
17587 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
17588 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
17589 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
17590 + * SUCH DAMAGE.
17591 + *
17592 + * The licence and distribution terms for any publically available version or
17593 + * derivative of this code cannot be changed. i.e. this code cannot simply be
17594 + * copied and put under another distribution licence
17595 + * [including the GNU Public Licence.]
17596 + */
17597 +
17598 +#include "des/des_locl.h"
17599 +
17600 +void des_cbc_encrypt(input, output, length, schedule, ivec, enc)
17601 +des_cblock (*input);
17602 +des_cblock (*output);
17603 +long length;
17604 +des_key_schedule schedule;
17605 +des_cblock (*ivec);
17606 +int enc;
17607 + {
17608 + register DES_LONG tin0,tin1;
17609 + register DES_LONG tout0,tout1,xor0,xor1;
17610 + register unsigned char *in,*out;
17611 + register long l=length;
17612 + DES_LONG tin[2];
17613 + unsigned char *iv;
17614 +
17615 + in=(unsigned char *)input;
17616 + out=(unsigned char *)output;
17617 + iv=(unsigned char *)ivec;
17618 +
17619 + if (enc)
17620 + {
17621 + c2l(iv,tout0);
17622 + c2l(iv,tout1);
17623 + for (l-=8; l>=0; l-=8)
17624 + {
17625 + c2l(in,tin0);
17626 + c2l(in,tin1);
17627 + tin0^=tout0; tin[0]=tin0;
17628 + tin1^=tout1; tin[1]=tin1;
17629 + des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
17630 + tout0=tin[0]; l2c(tout0,out);
17631 + tout1=tin[1]; l2c(tout1,out);
17632 + }
17633 + if (l != -8)
17634 + {
17635 + c2ln(in,tin0,tin1,l+8);
17636 + tin0^=tout0; tin[0]=tin0;
17637 + tin1^=tout1; tin[1]=tin1;
17638 + des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
17639 + tout0=tin[0]; l2c(tout0,out);
17640 + tout1=tin[1]; l2c(tout1,out);
17641 + }
17642 + }
17643 + else
17644 + {
17645 + c2l(iv,xor0);
17646 + c2l(iv,xor1);
17647 + for (l-=8; l>=0; l-=8)
17648 + {
17649 + c2l(in,tin0); tin[0]=tin0;
17650 + c2l(in,tin1); tin[1]=tin1;
17651 + des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
17652 + tout0=tin[0]^xor0;
17653 + tout1=tin[1]^xor1;
17654 + l2c(tout0,out);
17655 + l2c(tout1,out);
17656 + xor0=tin0;
17657 + xor1=tin1;
17658 + }
17659 + if (l != -8)
17660 + {
17661 + c2l(in,tin0); tin[0]=tin0;
17662 + c2l(in,tin1); tin[1]=tin1;
17663 + des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
17664 + tout0=tin[0]^xor0;
17665 + tout1=tin[1]^xor1;
17666 + l2cn(tout0,tout1,out,l+8);
17667 + /* xor0=tin0;
17668 + xor1=tin1; */
17669 + }
17670 + }
17671 + tin0=tin1=tout0=tout1=xor0=xor1=0;
17672 + tin[0]=tin[1]=0;
17673 + }
17674 +
17675 --- /dev/null Tue Mar 11 13:02:56 2003
17676 +++ linux/net/ipsec/des/des.doc Mon Feb 9 13:51:03 2004
17677 @@ -0,0 +1,505 @@
17678 +The DES library.
17679 +
17680 +Please note that this library was originally written to operate with
17681 +eBones, a version of Kerberos that had had encryption removed when it left
17682 +the USA and then put back in. As such there are some routines that I will
17683 +advise not using but they are still in the library for historical reasons.
17684 +For all calls that have an 'input' and 'output' variables, they can be the
17685 +same.
17686 +
17687 +This library requires the inclusion of 'des.h'.
17688 +
17689 +All of the encryption functions take what is called a des_key_schedule as an
17690 +argument. A des_key_schedule is an expanded form of the des key.
17691 +A des_key is 8 bytes of odd parity, the type used to hold the key is a
17692 +des_cblock. A des_cblock is an array of 8 bytes, often in this library
17693 +description I will refer to input bytes when the function specifies
17694 +des_cblock's as input or output, this just means that the variable should
17695 +be a multiple of 8 bytes.
17696 +
17697 +The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to
17698 +specify decryption. The functions and global variable are as follows:
17699 +
17700 +int des_check_key;
17701 + DES keys are supposed to be odd parity. If this variable is set to
17702 + a non-zero value, des_set_key() will check that the key has odd
17703 + parity and is not one of the known weak DES keys. By default this
17704 + variable is turned off;
17705 +
17706 +void des_set_odd_parity(
17707 +des_cblock *key );
17708 + This function takes a DES key (8 bytes) and sets the parity to odd.
17709 +
17710 +int des_is_weak_key(
17711 +des_cblock *key );
17712 + This function returns a non-zero value if the DES key passed is a
17713 + weak, DES key. If it is a weak key, don't use it, try a different
17714 + one. If you are using 'random' keys, the chances of hitting a weak
17715 + key are 1/2^52 so it is probably not worth checking for them.
17716 +
17717 +int des_set_key(
17718 +des_cblock *key,
17719 +des_key_schedule schedule);
17720 + Des_set_key converts an 8 byte DES key into a des_key_schedule.
17721 + A des_key_schedule is an expanded form of the key which is used to
17722 + perform actual encryption. It can be regenerated from the DES key
17723 + so it only needs to be kept when encryption or decryption is about
17724 + to occur. Don't save or pass around des_key_schedule's since they
17725 + are CPU architecture dependent, DES keys are not. If des_check_key
17726 + is non zero, zero is returned if the key has the wrong parity or
17727 + the key is a weak key, else 1 is returned.
17728 +
17729 +int des_key_sched(
17730 +des_cblock *key,
17731 +des_key_schedule schedule);
17732 + An alternative name for des_set_key().
17733 +
17734 +int des_rw_mode; /* defaults to DES_PCBC_MODE */
17735 + This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default).
17736 + This specifies the function to use in the enc_read() and enc_write()
17737 + functions.
17738 +
17739 +void des_encrypt(
17740 +unsigned long *data,
17741 +des_key_schedule ks,
17742 +int enc);
17743 + This is the DES encryption function that gets called by just about
17744 + every other DES routine in the library. You should not use this
17745 + function except to implement 'modes' of DES. I say this because the
17746 + functions that call this routine do the conversion from 'char *' to
17747 + long, and this needs to be done to make sure 'non-aligned' memory
17748 + access do not occur. The characters are loaded 'little endian',
17749 + have a look at my source code for more details on how I use this
17750 + function.
17751 + Data is a pointer to 2 unsigned long's and ks is the
17752 + des_key_schedule to use. enc, is non zero specifies encryption,
17753 + zero if decryption.
17754 +
17755 +void des_encrypt2(
17756 +unsigned long *data,
17757 +des_key_schedule ks,
17758 +int enc);
17759 + This functions is the same as des_encrypt() except that the DES
17760 + initial permutation (IP) and final permutation (FP) have been left
17761 + out. As for des_encrypt(), you should not use this function.
17762 + It is used by the routines in my library that implement triple DES.
17763 + IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same
17764 + as des_encrypt() des_encrypt() des_encrypt() except faster :-).
17765 +
17766 +void des_ecb_encrypt(
17767 +des_cblock *input,
17768 +des_cblock *output,
17769 +des_key_schedule ks,
17770 +int enc);
17771 + This is the basic Electronic Code Book form of DES, the most basic
17772 + form. Input is encrypted into output using the key represented by
17773 + ks. If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise
17774 + decryption occurs. Input is 8 bytes long and output is 8 bytes.
17775 + (the des_cblock structure is 8 chars).
17776 +
17777 +void des_ecb3_encrypt(
17778 +des_cblock *input,
17779 +des_cblock *output,
17780 +des_key_schedule ks1,
17781 +des_key_schedule ks2,
17782 +des_key_schedule ks3,
17783 +int enc);
17784 + This is the 3 key EDE mode of ECB DES. What this means is that
17785 + the 8 bytes of input is encrypted with ks1, decrypted with ks2 and
17786 + then encrypted again with ks3, before being put into output;
17787 + C=E(ks3,D(ks2,E(ks1,M))). There is a macro, des_ecb2_encrypt()
17788 + that only takes 2 des_key_schedules that implements,
17789 + C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1.
17790 +
17791 +void des_cbc_encrypt(
17792 +des_cblock *input,
17793 +des_cblock *output,
17794 +long length,
17795 +des_key_schedule ks,
17796 +des_cblock *ivec,
17797 +int enc);
17798 + This routine implements DES in Cipher Block Chaining mode.
17799 + Input, which should be a multiple of 8 bytes is encrypted
17800 + (or decrypted) to output which will also be a multiple of 8 bytes.
17801 + The number of bytes is in length (and from what I've said above,
17802 + should be a multiple of 8). If length is not a multiple of 8, I'm
17803 + not being held responsible :-). ivec is the initialisation vector.
17804 + This function does not modify this variable. To correctly implement
17805 + cbc mode, you need to do one of 2 things; copy the last 8 bytes of
17806 + cipher text for use as the next ivec in your application,
17807 + or use des_ncbc_encrypt().
17808 + Only this routine has this problem with updating the ivec, all
17809 + other routines that are implementing cbc mode update ivec.
17810 +
17811 +void des_ncbc_encrypt(
17812 +des_cblock *input,
17813 +des_cblock *output,
17814 +long length,
17815 +des_key_schedule sk,
17816 +des_cblock *ivec,
17817 +int enc);
17818 + For historical reasons, des_cbc_encrypt() did not update the
17819 + ivec with the value requires so that subsequent calls to
17820 + des_cbc_encrypt() would 'chain'. This was needed so that the same
17821 + 'length' values would not need to be used when decrypting.
17822 + des_ncbc_encrypt() does the right thing. It is the same as
17823 + des_cbc_encrypt accept that ivec is updates with the correct value
17824 + to pass in subsequent calls to des_ncbc_encrypt(). I advise using
17825 + des_ncbc_encrypt() instead of des_cbc_encrypt();
17826 +
17827 +void des_xcbc_encrypt(
17828 +des_cblock *input,
17829 +des_cblock *output,
17830 +long length,
17831 +des_key_schedule sk,
17832 +des_cblock *ivec,
17833 +des_cblock *inw,
17834 +des_cblock *outw,
17835 +int enc);
17836 + This is RSA's DESX mode of DES. It uses inw and outw to
17837 + 'whiten' the encryption. inw and outw are secret (unlike the iv)
17838 + and are as such, part of the key. So the key is sort of 24 bytes.
17839 + This is much better than cbc des.
17840 +
17841 +void des_3cbc_encrypt(
17842 +des_cblock *input,
17843 +des_cblock *output,
17844 +long length,
17845 +des_key_schedule sk1,
17846 +des_key_schedule sk2,
17847 +des_cblock *ivec1,
17848 +des_cblock *ivec2,
17849 +int enc);
17850 + This function is flawed, do not use it. I have left it in the
17851 + library because it is used in my des(1) program and will function
17852 + correctly when used by des(1). If I removed the function, people
17853 + could end up unable to decrypt files.
17854 + This routine implements outer triple cbc encryption using 2 ks and
17855 + 2 ivec's. Use des_ede2_cbc_encrypt() instead.
17856 +
17857 +void des_ede3_cbc_encrypt(
17858 +des_cblock *input,
17859 +des_cblock *output,
17860 +long length,
17861 +des_key_schedule ks1,
17862 +des_key_schedule ks2,
17863 +des_key_schedule ks3,
17864 +des_cblock *ivec,
17865 +int enc);
17866 + This function implements inner triple CBC DES encryption with 3
17867 + keys. What this means is that each 'DES' operation
17868 + inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))).
17869 + Again, this is cbc mode so an ivec is requires.
17870 + This mode is used by SSL.
17871 + There is also a des_ede2_cbc_encrypt() that only uses 2
17872 + des_key_schedule's, the first being reused for the final
17873 + encryption. C=E(ks1,D(ks2,E(ks1,M))). This form of triple DES
17874 + is used by the RSAref library.
17875 +
17876 +void des_pcbc_encrypt(
17877 +des_cblock *input,
17878 +des_cblock *output,
17879 +long length,
17880 +des_key_schedule ks,
17881 +des_cblock *ivec,
17882 +int enc);
17883 + This is Propagating Cipher Block Chaining mode of DES. It is used
17884 + by Kerberos v4. It's parameters are the same as des_ncbc_encrypt().
17885 +
17886 +void des_cfb_encrypt(
17887 +unsigned char *in,
17888 +unsigned char *out,
17889 +int numbits,
17890 +long length,
17891 +des_key_schedule ks,
17892 +des_cblock *ivec,
17893 +int enc);
17894 + Cipher Feedback Back mode of DES. This implementation 'feeds back'
17895 + in numbit blocks. The input (and output) is in multiples of numbits
17896 + bits. numbits should to be a multiple of 8 bits. Length is the
17897 + number of bytes input. If numbits is not a multiple of 8 bits,
17898 + the extra bits in the bytes will be considered padding. So if
17899 + numbits is 12, for each 2 input bytes, the 4 high bits of the
17900 + second byte will be ignored. So to encode 72 bits when using
17901 + a numbits of 12 take 12 bytes. To encode 72 bits when using
17902 + numbits of 9 will take 16 bytes. To encode 80 bits when using
17903 + numbits of 16 will take 10 bytes. etc, etc. This padding will
17904 + apply to both input and output.
17905 +
17906 +
17907 +void des_cfb64_encrypt(
17908 +unsigned char *in,
17909 +unsigned char *out,
17910 +long length,
17911 +des_key_schedule ks,
17912 +des_cblock *ivec,
17913 +int *num,
17914 +int enc);
17915 + This is one of the more useful functions in this DES library, it
17916 + implements CFB mode of DES with 64bit feedback. Why is this
17917 + useful you ask? Because this routine will allow you to encrypt an
17918 + arbitrary number of bytes, no 8 byte padding. Each call to this
17919 + routine will encrypt the input bytes to output and then update ivec
17920 + and num. num contains 'how far' we are though ivec. If this does
17921 + not make much sense, read more about cfb mode of DES :-).
17922 +
17923 +void des_ede3_cfb64_encrypt(
17924 +unsigned char *in,
17925 +unsigned char *out,
17926 +long length,
17927 +des_key_schedule ks1,
17928 +des_key_schedule ks2,
17929 +des_key_schedule ks3,
17930 +des_cblock *ivec,
17931 +int *num,
17932 +int enc);
17933 + Same as des_cfb64_encrypt() accept that the DES operation is
17934 + triple DES. As usual, there is a macro for
17935 + des_ede2_cfb64_encrypt() which reuses ks1.
17936 +
17937 +void des_ofb_encrypt(
17938 +unsigned char *in,
17939 +unsigned char *out,
17940 +int numbits,
17941 +long length,
17942 +des_key_schedule ks,
17943 +des_cblock *ivec);
17944 + This is a implementation of Output Feed Back mode of DES. It is
17945 + the same as des_cfb_encrypt() in that numbits is the size of the
17946 + units dealt with during input and output (in bits).
17947 +
17948 +void des_ofb64_encrypt(
17949 +unsigned char *in,
17950 +unsigned char *out,
17951 +long length,
17952 +des_key_schedule ks,
17953 +des_cblock *ivec,
17954 +int *num);
17955 + The same as des_cfb64_encrypt() except that it is Output Feed Back
17956 + mode.
17957 +
17958 +void des_ede3_ofb64_encrypt(
17959 +unsigned char *in,
17960 +unsigned char *out,
17961 +long length,
17962 +des_key_schedule ks1,
17963 +des_key_schedule ks2,
17964 +des_key_schedule ks3,
17965 +des_cblock *ivec,
17966 +int *num);
17967 + Same as des_ofb64_encrypt() accept that the DES operation is
17968 + triple DES. As usual, there is a macro for
17969 + des_ede2_ofb64_encrypt() which reuses ks1.
17970 +
17971 +int des_read_pw_string(
17972 +char *buf,
17973 +int length,
17974 +char *prompt,
17975 +int verify);
17976 + This routine is used to get a password from the terminal with echo
17977 + turned off. Buf is where the string will end up and length is the
17978 + size of buf. Prompt is a string presented to the 'user' and if
17979 + verify is set, the key is asked for twice and unless the 2 copies
17980 + match, an error is returned. A return code of -1 indicates a
17981 + system error, 1 failure due to use interaction, and 0 is success.
17982 +
17983 +unsigned long des_cbc_cksum(
17984 +des_cblock *input,
17985 +des_cblock *output,
17986 +long length,
17987 +des_key_schedule ks,
17988 +des_cblock *ivec);
17989 + This function produces an 8 byte checksum from input that it puts in
17990 + output and returns the last 4 bytes as a long. The checksum is
17991 + generated via cbc mode of DES in which only the last 8 byes are
17992 + kept. I would recommend not using this function but instead using
17993 + the EVP_Digest routines, or at least using MD5 or SHA. This
17994 + function is used by Kerberos v4 so that is why it stays in the
17995 + library.
17996 +
17997 +char *des_fcrypt(
17998 +const char *buf,
17999 +const char *salt
18000 +char *ret);
18001 + This is my fast version of the unix crypt(3) function. This version
18002 + takes only a small amount of space relative to other fast
18003 + crypt() implementations. This is different to the normal crypt
18004 + in that the third parameter is the buffer that the return value
18005 + is written into. It needs to be at least 14 bytes long. This
18006 + function is thread safe, unlike the normal crypt.
18007 +
18008 +char *crypt(
18009 +const char *buf,
18010 +const char *salt);
18011 + This function calls des_fcrypt() with a static array passed as the
18012 + third parameter. This emulates the normal non-thread safe semantics
18013 + of crypt(3).
18014 +
18015 +void des_string_to_key(
18016 +char *str,
18017 +des_cblock *key);
18018 + This function takes str and converts it into a DES key. I would
18019 + recommend using MD5 instead and use the first 8 bytes of output.
18020 + When I wrote the first version of these routines back in 1990, MD5
18021 + did not exist but I feel these routines are still sound. This
18022 + routines is compatible with the one in MIT's libdes.
18023 +
18024 +void des_string_to_2keys(
18025 +char *str,
18026 +des_cblock *key1,
18027 +des_cblock *key2);
18028 + This function takes str and converts it into 2 DES keys.
18029 + I would recommend using MD5 and using the 16 bytes as the 2 keys.
18030 + I have nothing against these 2 'string_to_key' routines, it's just
18031 + that if you say that your encryption key is generated by using the
18032 + 16 bytes of an MD5 hash, every-one knows how you generated your
18033 + keys.
18034 +
18035 +int des_read_password(
18036 +des_cblock *key,
18037 +char *prompt,
18038 +int verify);
18039 + This routine combines des_read_pw_string() with des_string_to_key().
18040 +
18041 +int des_read_2passwords(
18042 +des_cblock *key1,
18043 +des_cblock *key2,
18044 +char *prompt,
18045 +int verify);
18046 + This routine combines des_read_pw_string() with des_string_to_2key().
18047 +
18048 +void des_random_seed(
18049 +des_cblock key);
18050 + This routine sets a starting point for des_random_key().
18051 +
18052 +void des_random_key(
18053 +des_cblock ret);
18054 + This function return a random key. Make sure to 'seed' the random
18055 + number generator (with des_random_seed()) before using this function.
18056 + I personally now use a MD5 based random number system.
18057 +
18058 +int des_enc_read(
18059 +int fd,
18060 +char *buf,
18061 +int len,
18062 +des_key_schedule ks,
18063 +des_cblock *iv);
18064 + This function will write to a file descriptor the encrypted data
18065 + from buf. This data will be preceded by a 4 byte 'byte count' and
18066 + will be padded out to 8 bytes. The encryption is either CBC of
18067 + PCBC depending on the value of des_rw_mode. If it is DES_PCBC_MODE,
18068 + pcbc is used, if DES_CBC_MODE, cbc is used. The default is to use
18069 + DES_PCBC_MODE.
18070 +
18071 +int des_enc_write(
18072 +int fd,
18073 +char *buf,
18074 +int len,
18075 +des_key_schedule ks,
18076 +des_cblock *iv);
18077 + This routines read stuff written by des_enc_read() and decrypts it.
18078 + I have used these routines quite a lot but I don't believe they are
18079 + suitable for non-blocking io. If you are after a full
18080 + authentication/encryption over networks, have a look at SSL instead.
18081 +
18082 +unsigned long des_quad_cksum(
18083 +des_cblock *input,
18084 +des_cblock *output,
18085 +long length,
18086 +int out_count,
18087 +des_cblock *seed);
18088 + This is a function from Kerberos v4 that is not anything to do with
18089 + DES but was needed. It is a cksum that is quicker to generate than
18090 + des_cbc_cksum(); I personally would use MD5 routines now.
18091 +=====
18092 +Modes of DES
18093 +Quite a bit of the following information has been taken from
18094 + AS 2805.5.2
18095 + Australian Standard
18096 + Electronic funds transfer - Requirements for interfaces,
18097 + Part 5.2: Modes of operation for an n-bit block cipher algorithm
18098 + Appendix A
18099 +
18100 +There are several different modes in which DES can be used, they are
18101 +as follows.
18102 +
18103 +Electronic Codebook Mode (ECB) (des_ecb_encrypt())
18104 +- 64 bits are enciphered at a time.
18105 +- The order of the blocks can be rearranged without detection.
18106 +- The same plaintext block always produces the same ciphertext block
18107 + (for the same key) making it vulnerable to a 'dictionary attack'.
18108 +- An error will only affect one ciphertext block.
18109 +
18110 +Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
18111 +- a multiple of 64 bits are enciphered at a time.
18112 +- The CBC mode produces the same ciphertext whenever the same
18113 + plaintext is encrypted using the same key and starting variable.
18114 +- The chaining operation makes the ciphertext blocks dependent on the
18115 + current and all preceding plaintext blocks and therefore blocks can not
18116 + be rearranged.
18117 +- The use of different starting variables prevents the same plaintext
18118 + enciphering to the same ciphertext.
18119 +- An error will affect the current and the following ciphertext blocks.
18120 +
18121 +Cipher Feedback Mode (CFB) (des_cfb_encrypt())
18122 +- a number of bits (j) <= 64 are enciphered at a time.
18123 +- The CFB mode produces the same ciphertext whenever the same
18124 + plaintext is encrypted using the same key and starting variable.
18125 +- The chaining operation makes the ciphertext variables dependent on the
18126 + current and all preceding variables and therefore j-bit variables are
18127 + chained together and can not be rearranged.
18128 +- The use of different starting variables prevents the same plaintext
18129 + enciphering to the same ciphertext.
18130 +- The strength of the CFB mode depends on the size of k (maximal if
18131 + j == k). In my implementation this is always the case.
18132 +- Selection of a small value for j will require more cycles through
18133 + the encipherment algorithm per unit of plaintext and thus cause
18134 + greater processing overheads.
18135 +- Only multiples of j bits can be enciphered.
18136 +- An error will affect the current and the following ciphertext variables.
18137 +
18138 +Output Feedback Mode (OFB) (des_ofb_encrypt())
18139 +- a number of bits (j) <= 64 are enciphered at a time.
18140 +- The OFB mode produces the same ciphertext whenever the same
18141 + plaintext enciphered using the same key and starting variable. More
18142 + over, in the OFB mode the same key stream is produced when the same
18143 + key and start variable are used. Consequently, for security reasons
18144 + a specific start variable should be used only once for a given key.
18145 +- The absence of chaining makes the OFB more vulnerable to specific attacks.
18146 +- The use of different start variables values prevents the same
18147 + plaintext enciphering to the same ciphertext, by producing different
18148 + key streams.
18149 +- Selection of a small value for j will require more cycles through
18150 + the encipherment algorithm per unit of plaintext and thus cause
18151 + greater processing overheads.
18152 +- Only multiples of j bits can be enciphered.
18153 +- OFB mode of operation does not extend ciphertext errors in the
18154 + resultant plaintext output. Every bit error in the ciphertext causes
18155 + only one bit to be in error in the deciphered plaintext.
18156 +- OFB mode is not self-synchronising. If the two operation of
18157 + encipherment and decipherment get out of synchronism, the system needs
18158 + to be re-initialised.
18159 +- Each re-initialisation should use a value of the start variable
18160 + different from the start variable values used before with the same
18161 + key. The reason for this is that an identical bit stream would be
18162 + produced each time from the same parameters. This would be
18163 + susceptible to a ' known plaintext' attack.
18164 +
18165 +Triple ECB Mode (des_ecb3_encrypt())
18166 +- Encrypt with key1, decrypt with key2 and encrypt with key3 again.
18167 +- As for ECB encryption but increases the key length to 168 bits.
18168 + There are theoretic attacks that can be used that make the effective
18169 + key length 112 bits, but this attack also requires 2^56 blocks of
18170 + memory, not very likely, even for the NSA.
18171 +- If both keys are the same it is equivalent to encrypting once with
18172 + just one key.
18173 +- If the first and last key are the same, the key length is 112 bits.
18174 + There are attacks that could reduce the key space to 55 bit's but it
18175 + requires 2^56 blocks of memory.
18176 +- If all 3 keys are the same, this is effectively the same as normal
18177 + ecb mode.
18178 +
18179 +Triple CBC Mode (des_ede3_cbc_encrypt())
18180 +- Encrypt with key1, decrypt with key2 and then encrypt with key3.
18181 +- As for CBC encryption but increases the key length to 168 bits with
18182 + the same restrictions as for triple ecb mode.
18183 --- /dev/null Tue Mar 11 13:02:56 2003
18184 +++ linux/net/ipsec/des/des_enc.c Mon Feb 9 13:51:03 2004
18185 @@ -0,0 +1,502 @@
18186 +/* crypto/des/des_enc.c */
18187 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18188 + * All rights reserved.
18189 + *
18190 + * This package is an SSL implementation written
18191 + * by Eric Young (eay@cryptsoft.com).
18192 + * The implementation was written so as to conform with Netscapes SSL.
18193 + *
18194 + * This library is free for commercial and non-commercial use as long as
18195 + * the following conditions are aheared to. The following conditions
18196 + * apply to all code found in this distribution, be it the RC4, RSA,
18197 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18198 + * included with this distribution is covered by the same copyright terms
18199 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18200 + *
18201 + * Copyright remains Eric Young's, and as such any Copyright notices in
18202 + * the code are not to be removed.
18203 + * If this package is used in a product, Eric Young should be given attribution
18204 + * as the author of the parts of the library used.
18205 + * This can be in the form of a textual message at program startup or
18206 + * in documentation (online or textual) provided with the package.
18207 + *
18208 + * Redistribution and use in source and binary forms, with or without
18209 + * modification, are permitted provided that the following conditions
18210 + * are met:
18211 + * 1. Redistributions of source code must retain the copyright
18212 + * notice, this list of conditions and the following disclaimer.
18213 + * 2. Redistributions in binary form must reproduce the above copyright
18214 + * notice, this list of conditions and the following disclaimer in the
18215 + * documentation and/or other materials provided with the distribution.
18216 + * 3. All advertising materials mentioning features or use of this software
18217 + * must display the following acknowledgement:
18218 + * "This product includes cryptographic software written by
18219 + * Eric Young (eay@cryptsoft.com)"
18220 + * The word 'cryptographic' can be left out if the rouines from the library
18221 + * being used are not cryptographic related :-).
18222 + * 4. If you include any Windows specific code (or a derivative thereof) from
18223 + * the apps directory (application code) you must include an acknowledgement:
18224 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18225 + *
18226 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18227 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18228 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18229 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18230 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18231 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18232 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18233 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18234 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18235 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18236 + * SUCH DAMAGE.
18237 + *
18238 + * The licence and distribution terms for any publically available version or
18239 + * derivative of this code cannot be changed. i.e. this code cannot simply be
18240 + * copied and put under another distribution licence
18241 + * [including the GNU Public Licence.]
18242 + */
18243 +
18244 +#include "des/des_locl.h"
18245 +
18246 +void des_encrypt(data, ks, enc)
18247 +DES_LONG *data;
18248 +des_key_schedule ks;
18249 +int enc;
18250 + {
18251 + register DES_LONG l,r,t,u;
18252 +#ifdef DES_PTR
18253 + register unsigned char *des_SP=(unsigned char *)des_SPtrans;
18254 +#endif
18255 +#ifndef DES_UNROLL
18256 + register int i;
18257 +#endif
18258 + register DES_LONG *s;
18259 +
18260 + r=data[0];
18261 + l=data[1];
18262 +
18263 + IP(r,l);
18264 + /* Things have been modified so that the initial rotate is
18265 + * done outside the loop. This required the
18266 + * des_SPtrans values in sp.h to be rotated 1 bit to the right.
18267 + * One perl script later and things have a 5% speed up on a sparc2.
18268 + * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
18269 + * for pointing this out. */
18270 + /* clear the top bits on machines with 8byte longs */
18271 + /* shift left by 2 */
18272 + r=ROTATE(r,29)&0xffffffffL;
18273 + l=ROTATE(l,29)&0xffffffffL;
18274 +
18275 + s=(DES_LONG *)ks;
18276 + /* I don't know if it is worth the effort of loop unrolling the
18277 + * inner loop */
18278 + if (enc)
18279 + {
18280 +#ifdef DES_UNROLL
18281 + D_ENCRYPT(l,r, 0); /* 1 */
18282 + D_ENCRYPT(r,l, 2); /* 2 */
18283 + D_ENCRYPT(l,r, 4); /* 3 */
18284 + D_ENCRYPT(r,l, 6); /* 4 */
18285 + D_ENCRYPT(l,r, 8); /* 5 */
18286 + D_ENCRYPT(r,l,10); /* 6 */
18287 + D_ENCRYPT(l,r,12); /* 7 */
18288 + D_ENCRYPT(r,l,14); /* 8 */
18289 + D_ENCRYPT(l,r,16); /* 9 */
18290 + D_ENCRYPT(r,l,18); /* 10 */
18291 + D_ENCRYPT(l,r,20); /* 11 */
18292 + D_ENCRYPT(r,l,22); /* 12 */
18293 + D_ENCRYPT(l,r,24); /* 13 */
18294 + D_ENCRYPT(r,l,26); /* 14 */
18295 + D_ENCRYPT(l,r,28); /* 15 */
18296 + D_ENCRYPT(r,l,30); /* 16 */
18297 +#else
18298 + for (i=0; i<32; i+=8)
18299 + {
18300 + D_ENCRYPT(l,r,i+0); /* 1 */
18301 + D_ENCRYPT(r,l,i+2); /* 2 */
18302 + D_ENCRYPT(l,r,i+4); /* 3 */
18303 + D_ENCRYPT(r,l,i+6); /* 4 */
18304 + }
18305 +#endif
18306 + }
18307 + else
18308 + {
18309 +#ifdef DES_UNROLL
18310 + D_ENCRYPT(l,r,30); /* 16 */
18311 + D_ENCRYPT(r,l,28); /* 15 */
18312 + D_ENCRYPT(l,r,26); /* 14 */
18313 + D_ENCRYPT(r,l,24); /* 13 */
18314 + D_ENCRYPT(l,r,22); /* 12 */
18315 + D_ENCRYPT(r,l,20); /* 11 */
18316 + D_ENCRYPT(l,r,18); /* 10 */
18317 + D_ENCRYPT(r,l,16); /* 9 */
18318 + D_ENCRYPT(l,r,14); /* 8 */
18319 + D_ENCRYPT(r,l,12); /* 7 */
18320 + D_ENCRYPT(l,r,10); /* 6 */
18321 + D_ENCRYPT(r,l, 8); /* 5 */
18322 + D_ENCRYPT(l,r, 6); /* 4 */
18323 + D_ENCRYPT(r,l, 4); /* 3 */
18324 + D_ENCRYPT(l,r, 2); /* 2 */
18325 + D_ENCRYPT(r,l, 0); /* 1 */
18326 +#else
18327 + for (i=30; i>0; i-=8)
18328 + {
18329 + D_ENCRYPT(l,r,i-0); /* 16 */
18330 + D_ENCRYPT(r,l,i-2); /* 15 */
18331 + D_ENCRYPT(l,r,i-4); /* 14 */
18332 + D_ENCRYPT(r,l,i-6); /* 13 */
18333 + }
18334 +#endif
18335 + }
18336 +
18337 + /* rotate and clear the top bits on machines with 8byte longs */
18338 + l=ROTATE(l,3)&0xffffffffL;
18339 + r=ROTATE(r,3)&0xffffffffL;
18340 +
18341 + FP(r,l);
18342 + data[0]=l;
18343 + data[1]=r;
18344 + l=r=t=u=0;
18345 + }
18346 +
18347 +void des_encrypt2(data, ks, enc)
18348 +DES_LONG *data;
18349 +des_key_schedule ks;
18350 +int enc;
18351 + {
18352 + register DES_LONG l,r,t,u;
18353 +#ifdef DES_PTR
18354 + register unsigned char *des_SP=(unsigned char *)des_SPtrans;
18355 +#endif
18356 +#ifndef DES_UNROLL
18357 + register int i;
18358 +#endif
18359 + register DES_LONG *s;
18360 +
18361 + r=data[0];
18362 + l=data[1];
18363 +
18364 + /* Things have been modified so that the initial rotate is
18365 + * done outside the loop. This required the
18366 + * des_SPtrans values in sp.h to be rotated 1 bit to the right.
18367 + * One perl script later and things have a 5% speed up on a sparc2.
18368 + * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
18369 + * for pointing this out. */
18370 + /* clear the top bits on machines with 8byte longs */
18371 + r=ROTATE(r,29)&0xffffffffL;
18372 + l=ROTATE(l,29)&0xffffffffL;
18373 +
18374 + s=(DES_LONG *)ks;
18375 + /* I don't know if it is worth the effort of loop unrolling the
18376 + * inner loop */
18377 + if (enc)
18378 + {
18379 +#ifdef DES_UNROLL
18380 + D_ENCRYPT(l,r, 0); /* 1 */
18381 + D_ENCRYPT(r,l, 2); /* 2 */
18382 + D_ENCRYPT(l,r, 4); /* 3 */
18383 + D_ENCRYPT(r,l, 6); /* 4 */
18384 + D_ENCRYPT(l,r, 8); /* 5 */
18385 + D_ENCRYPT(r,l,10); /* 6 */
18386 + D_ENCRYPT(l,r,12); /* 7 */
18387 + D_ENCRYPT(r,l,14); /* 8 */
18388 + D_ENCRYPT(l,r,16); /* 9 */
18389 + D_ENCRYPT(r,l,18); /* 10 */
18390 + D_ENCRYPT(l,r,20); /* 11 */
18391 + D_ENCRYPT(r,l,22); /* 12 */
18392 + D_ENCRYPT(l,r,24); /* 13 */
18393 + D_ENCRYPT(r,l,26); /* 14 */
18394 + D_ENCRYPT(l,r,28); /* 15 */
18395 + D_ENCRYPT(r,l,30); /* 16 */
18396 +#else
18397 + for (i=0; i<32; i+=8)
18398 + {
18399 + D_ENCRYPT(l,r,i+0); /* 1 */
18400 + D_ENCRYPT(r,l,i+2); /* 2 */
18401 + D_ENCRYPT(l,r,i+4); /* 3 */
18402 + D_ENCRYPT(r,l,i+6); /* 4 */
18403 + }
18404 +#endif
18405 + }
18406 + else
18407 + {
18408 +#ifdef DES_UNROLL
18409 + D_ENCRYPT(l,r,30); /* 16 */
18410 + D_ENCRYPT(r,l,28); /* 15 */
18411 + D_ENCRYPT(l,r,26); /* 14 */
18412 + D_ENCRYPT(r,l,24); /* 13 */
18413 + D_ENCRYPT(l,r,22); /* 12 */
18414 + D_ENCRYPT(r,l,20); /* 11 */
18415 + D_ENCRYPT(l,r,18); /* 10 */
18416 + D_ENCRYPT(r,l,16); /* 9 */
18417 + D_ENCRYPT(l,r,14); /* 8 */
18418 + D_ENCRYPT(r,l,12); /* 7 */
18419 + D_ENCRYPT(l,r,10); /* 6 */
18420 + D_ENCRYPT(r,l, 8); /* 5 */
18421 + D_ENCRYPT(l,r, 6); /* 4 */
18422 + D_ENCRYPT(r,l, 4); /* 3 */
18423 + D_ENCRYPT(l,r, 2); /* 2 */
18424 + D_ENCRYPT(r,l, 0); /* 1 */
18425 +#else
18426 + for (i=30; i>0; i-=8)
18427 + {
18428 + D_ENCRYPT(l,r,i-0); /* 16 */
18429 + D_ENCRYPT(r,l,i-2); /* 15 */
18430 + D_ENCRYPT(l,r,i-4); /* 14 */
18431 + D_ENCRYPT(r,l,i-6); /* 13 */
18432 + }
18433 +#endif
18434 + }
18435 + /* rotate and clear the top bits on machines with 8byte longs */
18436 + data[0]=ROTATE(l,3)&0xffffffffL;
18437 + data[1]=ROTATE(r,3)&0xffffffffL;
18438 + l=r=t=u=0;
18439 + }
18440 +
18441 +void des_encrypt3(data,ks1,ks2,ks3)
18442 +DES_LONG *data;
18443 +des_key_schedule ks1;
18444 +des_key_schedule ks2;
18445 +des_key_schedule ks3;
18446 + {
18447 + register DES_LONG l,r;
18448 +
18449 + l=data[0];
18450 + r=data[1];
18451 + IP(l,r);
18452 + data[0]=l;
18453 + data[1]=r;
18454 + des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
18455 + des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
18456 + des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
18457 + l=data[0];
18458 + r=data[1];
18459 + FP(r,l);
18460 + data[0]=l;
18461 + data[1]=r;
18462 + }
18463 +
18464 +void des_decrypt3(data,ks1,ks2,ks3)
18465 +DES_LONG *data;
18466 +des_key_schedule ks1;
18467 +des_key_schedule ks2;
18468 +des_key_schedule ks3;
18469 + {
18470 + register DES_LONG l,r;
18471 +
18472 + l=data[0];
18473 + r=data[1];
18474 + IP(l,r);
18475 + data[0]=l;
18476 + data[1]=r;
18477 + des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
18478 + des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
18479 + des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
18480 + l=data[0];
18481 + r=data[1];
18482 + FP(r,l);
18483 + data[0]=l;
18484 + data[1]=r;
18485 + }
18486 +
18487 +#ifndef DES_DEFAULT_OPTIONS
18488 +
18489 +void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
18490 +des_cblock (*input);
18491 +des_cblock (*output);
18492 +long length;
18493 +des_key_schedule schedule;
18494 +des_cblock (*ivec);
18495 +int enc;
18496 + {
18497 + register DES_LONG tin0,tin1;
18498 + register DES_LONG tout0,tout1,xor0,xor1;
18499 + register unsigned char *in,*out;
18500 + register long l=length;
18501 + DES_LONG tin[2];
18502 + unsigned char *iv;
18503 +
18504 + in=(unsigned char *)input;
18505 + out=(unsigned char *)output;
18506 + iv=(unsigned char *)ivec;
18507 +
18508 + if (enc)
18509 + {
18510 + c2l(iv,tout0);
18511 + c2l(iv,tout1);
18512 + for (l-=8; l>=0; l-=8)
18513 + {
18514 + c2l(in,tin0);
18515 + c2l(in,tin1);
18516 + tin0^=tout0; tin[0]=tin0;
18517 + tin1^=tout1; tin[1]=tin1;
18518 + des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
18519 + tout0=tin[0]; l2c(tout0,out);
18520 + tout1=tin[1]; l2c(tout1,out);
18521 + }
18522 + if (l != -8)
18523 + {
18524 + c2ln(in,tin0,tin1,l+8);
18525 + tin0^=tout0; tin[0]=tin0;
18526 + tin1^=tout1; tin[1]=tin1;
18527 + des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
18528 + tout0=tin[0]; l2c(tout0,out);
18529 + tout1=tin[1]; l2c(tout1,out);
18530 + }
18531 + iv=(unsigned char *)ivec;
18532 + l2c(tout0,iv);
18533 + l2c(tout1,iv);
18534 + }
18535 + else
18536 + {
18537 + c2l(iv,xor0);
18538 + c2l(iv,xor1);
18539 + for (l-=8; l>=0; l-=8)
18540 + {
18541 + c2l(in,tin0); tin[0]=tin0;
18542 + c2l(in,tin1); tin[1]=tin1;
18543 + des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
18544 + tout0=tin[0]^xor0;
18545 + tout1=tin[1]^xor1;
18546 + l2c(tout0,out);
18547 + l2c(tout1,out);
18548 + xor0=tin0;
18549 + xor1=tin1;
18550 + }
18551 + if (l != -8)
18552 + {
18553 + c2l(in,tin0); tin[0]=tin0;
18554 + c2l(in,tin1); tin[1]=tin1;
18555 + des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
18556 + tout0=tin[0]^xor0;
18557 + tout1=tin[1]^xor1;
18558 + l2cn(tout0,tout1,out,l+8);
18559 + xor0=tin0;
18560 + xor1=tin1;
18561 + }
18562 +
18563 + iv=(unsigned char *)ivec;
18564 + l2c(xor0,iv);
18565 + l2c(xor1,iv);
18566 + }
18567 + tin0=tin1=tout0=tout1=xor0=xor1=0;
18568 + tin[0]=tin[1]=0;
18569 + }
18570 +
18571 +void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc)
18572 +des_cblock (*input);
18573 +des_cblock (*output);
18574 +long length;
18575 +des_key_schedule ks1;
18576 +des_key_schedule ks2;
18577 +des_key_schedule ks3;
18578 +des_cblock (*ivec);
18579 +int enc;
18580 + {
18581 + register DES_LONG tin0,tin1;
18582 + register DES_LONG tout0,tout1,xor0,xor1;
18583 + register unsigned char *in,*out;
18584 + register long l=length;
18585 + DES_LONG tin[2];
18586 + unsigned char *iv;
18587 +
18588 + in=(unsigned char *)input;
18589 + out=(unsigned char *)output;
18590 + iv=(unsigned char *)ivec;
18591 +
18592 + if (enc)
18593 + {
18594 + c2l(iv,tout0);
18595 + c2l(iv,tout1);
18596 + for (l-=8; l>=0; l-=8)
18597 + {
18598 + c2l(in,tin0);
18599 + c2l(in,tin1);
18600 + tin0^=tout0;
18601 + tin1^=tout1;
18602 +
18603 + tin[0]=tin0;
18604 + tin[1]=tin1;
18605 + des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
18606 + tout0=tin[0];
18607 + tout1=tin[1];
18608 +
18609 + l2c(tout0,out);
18610 + l2c(tout1,out);
18611 + }
18612 + if (l != -8)
18613 + {
18614 + c2ln(in,tin0,tin1,l+8);
18615 + tin0^=tout0;
18616 + tin1^=tout1;
18617 +
18618 + tin[0]=tin0;
18619 + tin[1]=tin1;
18620 + des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
18621 + tout0=tin[0];
18622 + tout1=tin[1];
18623 +
18624 + l2c(tout0,out);
18625 + l2c(tout1,out);
18626 + }
18627 + iv=(unsigned char *)ivec;
18628 + l2c(tout0,iv);
18629 + l2c(tout1,iv);
18630 + }
18631 + else
18632 + {
18633 + register DES_LONG t0,t1;
18634 +
18635 + c2l(iv,xor0);
18636 + c2l(iv,xor1);
18637 + for (l-=8; l>=0; l-=8)
18638 + {
18639 + c2l(in,tin0);
18640 + c2l(in,tin1);
18641 +
18642 + t0=tin0;
18643 + t1=tin1;
18644 +
18645 + tin[0]=tin0;
18646 + tin[1]=tin1;
18647 + des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
18648 + tout0=tin[0];
18649 + tout1=tin[1];
18650 +
18651 + tout0^=xor0;
18652 + tout1^=xor1;
18653 + l2c(tout0,out);
18654 + l2c(tout1,out);
18655 + xor0=t0;
18656 + xor1=t1;
18657 + }
18658 + if (l != -8)
18659 + {
18660 + c2l(in,tin0);
18661 + c2l(in,tin1);
18662 +
18663 + t0=tin0;
18664 + t1=tin1;
18665 +
18666 + tin[0]=tin0;
18667 + tin[1]=tin1;
18668 + des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
18669 + tout0=tin[0];
18670 + tout1=tin[1];
18671 +
18672 + tout0^=xor0;
18673 + tout1^=xor1;
18674 + l2cn(tout0,tout1,out,l+8);
18675 + xor0=t0;
18676 + xor1=t1;
18677 + }
18678 +
18679 + iv=(unsigned char *)ivec;
18680 + l2c(xor0,iv);
18681 + l2c(xor1,iv);
18682 + }
18683 + tin0=tin1=tout0=tout1=xor0=xor1=0;
18684 + tin[0]=tin[1]=0;
18685 + }
18686 +
18687 +#endif /* DES_DEFAULT_OPTIONS */
18688 --- /dev/null Tue Mar 11 13:02:56 2003
18689 +++ linux/net/ipsec/des/des_opts.c Mon Feb 9 13:51:03 2004
18690 @@ -0,0 +1,620 @@
18691 +/* crypto/des/des_opts.c */
18692 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18693 + * All rights reserved.
18694 + *
18695 + * This package is an SSL implementation written
18696 + * by Eric Young (eay@cryptsoft.com).
18697 + * The implementation was written so as to conform with Netscapes SSL.
18698 + *
18699 + * This library is free for commercial and non-commercial use as long as
18700 + * the following conditions are aheared to. The following conditions
18701 + * apply to all code found in this distribution, be it the RC4, RSA,
18702 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18703 + * included with this distribution is covered by the same copyright terms
18704 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18705 + *
18706 + * Copyright remains Eric Young's, and as such any Copyright notices in
18707 + * the code are not to be removed.
18708 + * If this package is used in a product, Eric Young should be given attribution
18709 + * as the author of the parts of the library used.
18710 + * This can be in the form of a textual message at program startup or
18711 + * in documentation (online or textual) provided with the package.
18712 + *
18713 + * Redistribution and use in source and binary forms, with or without
18714 + * modification, are permitted provided that the following conditions
18715 + * are met:
18716 + * 1. Redistributions of source code must retain the copyright
18717 + * notice, this list of conditions and the following disclaimer.
18718 + * 2. Redistributions in binary form must reproduce the above copyright
18719 + * notice, this list of conditions and the following disclaimer in the
18720 + * documentation and/or other materials provided with the distribution.
18721 + * 3. All advertising materials mentioning features or use of this software
18722 + * must display the following acknowledgement:
18723 + * "This product includes cryptographic software written by
18724 + * Eric Young (eay@cryptsoft.com)"
18725 + * The word 'cryptographic' can be left out if the rouines from the library
18726 + * being used are not cryptographic related :-).
18727 + * 4. If you include any Windows specific code (or a derivative thereof) from
18728 + * the apps directory (application code) you must include an acknowledgement:
18729 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18730 + *
18731 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18732 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18733 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18734 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18735 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18736 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18737 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18738 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18739 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18740 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18741 + * SUCH DAMAGE.
18742 + *
18743 + * The licence and distribution terms for any publically available version or
18744 + * derivative of this code cannot be changed. i.e. this code cannot simply be
18745 + * copied and put under another distribution licence
18746 + * [including the GNU Public Licence.]
18747 + */
18748 +
18749 +/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
18750 + * This is for machines with 64k code segment size restrictions. */
18751 +
18752 +#ifndef MSDOS
18753 +#define TIMES
18754 +#endif
18755 +
18756 +#include <stdio.h>
18757 +#ifndef MSDOS
18758 +#include <unistd.h>
18759 +#else
18760 +#include <io.h>
18761 +extern void exit();
18762 +#endif
18763 +#include <signal.h>
18764 +#ifndef VMS
18765 +#ifndef _IRIX
18766 +#include <time.h>
18767 +#endif
18768 +#ifdef TIMES
18769 +#include <sys/types.h>
18770 +#include <sys/times.h>
18771 +#endif
18772 +#else /* VMS */
18773 +#include <types.h>
18774 +struct tms {
18775 + time_t tms_utime;
18776 + time_t tms_stime;
18777 + time_t tms_uchild; /* I dunno... */
18778 + time_t tms_uchildsys; /* so these names are a guess :-) */
18779 + }
18780 +#endif
18781 +#ifndef TIMES
18782 +#include <sys/timeb.h>
18783 +#endif
18784 +
18785 +#ifdef sun
18786 +#include <limits.h>
18787 +#include <sys/param.h>
18788 +#endif
18789 +
18790 +#include "des/des_locl.h"
18791 +#include "des/spr.h"
18792 +
18793 +#define DES_DEFAULT_OPTIONS
18794 +
18795 +#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4)
18796 +#define PART1
18797 +#define PART2
18798 +#define PART3
18799 +#define PART4
18800 +#endif
18801 +
18802 +#ifdef PART1
18803 +
18804 +#undef DES_UNROLL
18805 +#undef DES_RISC1
18806 +#undef DES_RISC2
18807 +#undef DES_PTR
18808 +#undef D_ENCRYPT
18809 +#define des_encrypt des_encrypt_u4_cisc_idx
18810 +#define des_encrypt2 des_encrypt2_u4_cisc_idx
18811 +#define des_encrypt3 des_encrypt3_u4_cisc_idx
18812 +#define des_decrypt3 des_decrypt3_u4_cisc_idx
18813 +#undef HEADER_DES_LOCL_H
18814 +#include "des_enc.c"
18815 +
18816 +#define DES_UNROLL
18817 +#undef DES_RISC1
18818 +#undef DES_RISC2
18819 +#undef DES_PTR
18820 +#undef D_ENCRYPT
18821 +#undef des_encrypt
18822 +#undef des_encrypt2
18823 +#undef des_encrypt3
18824 +#undef des_decrypt3
18825 +#define des_encrypt des_encrypt_u16_cisc_idx
18826 +#define des_encrypt2 des_encrypt2_u16_cisc_idx
18827 +#define des_encrypt3 des_encrypt3_u16_cisc_idx
18828 +#define des_decrypt3 des_decrypt3_u16_cisc_idx
18829 +#undef HEADER_DES_LOCL_H
18830 +#include "des_enc.c"
18831 +
18832 +#undef DES_UNROLL
18833 +#define DES_RISC1
18834 +#undef DES_RISC2
18835 +#undef DES_PTR
18836 +#undef D_ENCRYPT
18837 +#undef des_encrypt
18838 +#undef des_encrypt2
18839 +#undef des_encrypt3
18840 +#undef des_decrypt3
18841 +#define des_encrypt des_encrypt_u4_risc1_idx
18842 +#define des_encrypt2 des_encrypt2_u4_risc1_idx
18843 +#define des_encrypt3 des_encrypt3_u4_risc1_idx
18844 +#define des_decrypt3 des_decrypt3_u4_risc1_idx
18845 +#undef HEADER_DES_LOCL_H
18846 +#include "des_enc.c"
18847 +
18848 +#endif
18849 +
18850 +#ifdef PART2
18851 +
18852 +#undef DES_UNROLL
18853 +#undef DES_RISC1
18854 +#define DES_RISC2
18855 +#undef DES_PTR
18856 +#undef D_ENCRYPT
18857 +#undef des_encrypt
18858 +#undef des_encrypt2
18859 +#undef des_encrypt3
18860 +#undef des_decrypt3
18861 +#define des_encrypt des_encrypt_u4_risc2_idx
18862 +#define des_encrypt2 des_encrypt2_u4_risc2_idx
18863 +#define des_encrypt3 des_encrypt3_u4_risc2_idx
18864 +#define des_decrypt3 des_decrypt3_u4_risc2_idx
18865 +#undef HEADER_DES_LOCL_H
18866 +#include "des_enc.c"
18867 +
18868 +#define DES_UNROLL
18869 +#define DES_RISC1
18870 +#undef DES_RISC2
18871 +#undef DES_PTR
18872 +#undef D_ENCRYPT
18873 +#undef des_encrypt
18874 +#undef des_encrypt2
18875 +#undef des_encrypt3
18876 +#undef des_decrypt3
18877 +#define des_encrypt des_encrypt_u16_risc1_idx
18878 +#define des_encrypt2 des_encrypt2_u16_risc1_idx
18879 +#define des_encrypt3 des_encrypt3_u16_risc1_idx
18880 +#define des_decrypt3 des_decrypt3_u16_risc1_idx
18881 +#undef HEADER_DES_LOCL_H
18882 +#include "des_enc.c"
18883 +
18884 +#define DES_UNROLL
18885 +#undef DES_RISC1
18886 +#define DES_RISC2
18887 +#undef DES_PTR
18888 +#undef D_ENCRYPT
18889 +#undef des_encrypt
18890 +#undef des_encrypt2
18891 +#undef des_encrypt3
18892 +#undef des_decrypt3
18893 +#define des_encrypt des_encrypt_u16_risc2_idx
18894 +#define des_encrypt2 des_encrypt2_u16_risc2_idx
18895 +#define des_encrypt3 des_encrypt3_u16_risc2_idx
18896 +#define des_decrypt3 des_decrypt3_u16_risc2_idx
18897 +#undef HEADER_DES_LOCL_H
18898 +#include "des_enc.c"
18899 +
18900 +#endif
18901 +
18902 +#ifdef PART3
18903 +
18904 +#undef DES_UNROLL
18905 +#undef DES_RISC1
18906 +#undef DES_RISC2
18907 +#define DES_PTR
18908 +#undef D_ENCRYPT
18909 +#undef des_encrypt
18910 +#undef des_encrypt2
18911 +#undef des_encrypt3
18912 +#undef des_decrypt3
18913 +#define des_encrypt des_encrypt_u4_cisc_ptr
18914 +#define des_encrypt2 des_encrypt2_u4_cisc_ptr
18915 +#define des_encrypt3 des_encrypt3_u4_cisc_ptr
18916 +#define des_decrypt3 des_decrypt3_u4_cisc_ptr
18917 +#undef HEADER_DES_LOCL_H
18918 +#include "des_enc.c"
18919 +
18920 +#define DES_UNROLL
18921 +#undef DES_RISC1
18922 +#undef DES_RISC2
18923 +#define DES_PTR
18924 +#undef D_ENCRYPT
18925 +#undef des_encrypt
18926 +#undef des_encrypt2
18927 +#undef des_encrypt3
18928 +#undef des_decrypt3
18929 +#define des_encrypt des_encrypt_u16_cisc_ptr
18930 +#define des_encrypt2 des_encrypt2_u16_cisc_ptr
18931 +#define des_encrypt3 des_encrypt3_u16_cisc_ptr
18932 +#define des_decrypt3 des_decrypt3_u16_cisc_ptr
18933 +#undef HEADER_DES_LOCL_H
18934 +#include "des_enc.c"
18935 +
18936 +#undef DES_UNROLL
18937 +#define DES_RISC1
18938 +#undef DES_RISC2
18939 +#define DES_PTR
18940 +#undef D_ENCRYPT
18941 +#undef des_encrypt
18942 +#undef des_encrypt2
18943 +#undef des_encrypt3
18944 +#undef des_decrypt3
18945 +#define des_encrypt des_encrypt_u4_risc1_ptr
18946 +#define des_encrypt2 des_encrypt2_u4_risc1_ptr
18947 +#define des_encrypt3 des_encrypt3_u4_risc1_ptr
18948 +#define des_decrypt3 des_decrypt3_u4_risc1_ptr
18949 +#undef HEADER_DES_LOCL_H
18950 +#include "des_enc.c"
18951 +
18952 +#endif
18953 +
18954 +#ifdef PART4
18955 +
18956 +#undef DES_UNROLL
18957 +#undef DES_RISC1
18958 +#define DES_RISC2
18959 +#define DES_PTR
18960 +#undef D_ENCRYPT
18961 +#undef des_encrypt
18962 +#undef des_encrypt2
18963 +#undef des_encrypt3
18964 +#undef des_decrypt3
18965 +#define des_encrypt des_encrypt_u4_risc2_ptr
18966 +#define des_encrypt2 des_encrypt2_u4_risc2_ptr
18967 +#define des_encrypt3 des_encrypt3_u4_risc2_ptr
18968 +#define des_decrypt3 des_decrypt3_u4_risc2_ptr
18969 +#undef HEADER_DES_LOCL_H
18970 +#include "des_enc.c"
18971 +
18972 +#define DES_UNROLL
18973 +#define DES_RISC1
18974 +#undef DES_RISC2
18975 +#define DES_PTR
18976 +#undef D_ENCRYPT
18977 +#undef des_encrypt
18978 +#undef des_encrypt2
18979 +#undef des_encrypt3
18980 +#undef des_decrypt3
18981 +#define des_encrypt des_encrypt_u16_risc1_ptr
18982 +#define des_encrypt2 des_encrypt2_u16_risc1_ptr
18983 +#define des_encrypt3 des_encrypt3_u16_risc1_ptr
18984 +#define des_decrypt3 des_decrypt3_u16_risc1_ptr
18985 +#undef HEADER_DES_LOCL_H
18986 +#include "des_enc.c"
18987 +
18988 +#define DES_UNROLL
18989 +#undef DES_RISC1
18990 +#define DES_RISC2
18991 +#define DES_PTR
18992 +#undef D_ENCRYPT
18993 +#undef des_encrypt
18994 +#undef des_encrypt2
18995 +#undef des_encrypt3
18996 +#undef des_decrypt3
18997 +#define des_encrypt des_encrypt_u16_risc2_ptr
18998 +#define des_encrypt2 des_encrypt2_u16_risc2_ptr
18999 +#define des_encrypt3 des_encrypt3_u16_risc2_ptr
19000 +#define des_decrypt3 des_decrypt3_u16_risc2_ptr
19001 +#undef HEADER_DES_LOCL_H
19002 +#include "des_enc.c"
19003 +
19004 +#endif
19005 +
19006 +/* The following if from times(3) man page. It may need to be changed */
19007 +#ifndef HZ
19008 +# ifndef CLK_TCK
19009 +# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
19010 +# ifndef VMS
19011 +# define HZ 100.0
19012 +# else /* VMS */
19013 +# define HZ 100.0
19014 +# endif
19015 +# else /* _BSD_CLK_TCK_ */
19016 +# define HZ ((double)_BSD_CLK_TCK_)
19017 +# endif
19018 +# else /* CLK_TCK */
19019 +# define HZ ((double)CLK_TCK)
19020 +# endif
19021 +#endif
19022 +
19023 +#define BUFSIZE ((long)1024)
19024 +long run=0;
19025 +
19026 +#ifndef NOPROTO
19027 +double Time_F(int s);
19028 +#else
19029 +double Time_F();
19030 +#endif
19031 +
19032 +#ifdef SIGALRM
19033 +#if defined(__STDC__) || defined(sgi)
19034 +#define SIGRETTYPE void
19035 +#else
19036 +#define SIGRETTYPE int
19037 +#endif
19038 +
19039 +#ifndef NOPROTO
19040 +SIGRETTYPE sig_done(int sig);
19041 +#else
19042 +SIGRETTYPE sig_done();
19043 +#endif
19044 +
19045 +SIGRETTYPE sig_done(sig)
19046 +int sig;
19047 + {
19048 + signal(SIGALRM,sig_done);
19049 + run=0;
19050 +#ifdef LINT
19051 + sig=sig;
19052 +#endif
19053 + }
19054 +#endif
19055 +
19056 +#define START 0
19057 +#define STOP 1
19058 +
19059 +double Time_F(s)
19060 +int s;
19061 + {
19062 + double ret;
19063 +#ifdef TIMES
19064 + static struct tms tstart,tend;
19065 +
19066 + if (s == START)
19067 + {
19068 + times(&tstart);
19069 + return(0);
19070 + }
19071 + else
19072 + {
19073 + times(&tend);
19074 + ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
19075 + return((ret == 0.0)?1e-6:ret);
19076 + }
19077 +#else /* !times() */
19078 + static struct timeb tstart,tend;
19079 + long i;
19080 +
19081 + if (s == START)
19082 + {
19083 + ftime(&tstart);
19084 + return(0);
19085 + }
19086 + else
19087 + {
19088 + ftime(&tend);
19089 + i=(long)tend.millitm-(long)tstart.millitm;
19090 + ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
19091 + return((ret == 0.0)?1e-6:ret);
19092 + }
19093 +#endif
19094 + }
19095 +
19096 +#ifdef SIGALRM
19097 +#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
19098 +#else
19099 +#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
19100 +#endif
19101 +
19102 +#define time_it(func,name,index) \
19103 + print_name(name); \
19104 + Time_F(START); \
19105 + for (count=0,run=1; COND(cb); count++) \
19106 + { \
19107 + unsigned long d[2]; \
19108 + func(d,&(sch[0]),DES_ENCRYPT); \
19109 + } \
19110 + tm[index]=Time_F(STOP); \
19111 + fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
19112 + tm[index]=((double)COUNT(cb))/tm[index];
19113 +
19114 +#define print_it(name,index) \
19115 + fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
19116 + tm[index]*8,1.0e6/tm[index]);
19117 +
19118 +int main(argc,argv)
19119 +int argc;
19120 +char **argv;
19121 + {
19122 + long count;
19123 + static unsigned char buf[BUFSIZE];
19124 + static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
19125 + static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
19126 + static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
19127 + des_key_schedule sch,sch2,sch3;
19128 + double d,tm[16],max=0;
19129 + int rank[16];
19130 + char *str[16];
19131 + int max_idx=0,i,num=0,j;
19132 +#ifndef SIGALARM
19133 + long ca,cb,cc,cd,ce;
19134 +#endif
19135 +
19136 + for (i=0; i<12; i++)
19137 + {
19138 + tm[i]=0.0;
19139 + rank[i]=0;
19140 + }
19141 +
19142 +#ifndef TIMES
19143 + fprintf(stderr,"To get the most acurate results, try to run this\n");
19144 + fprintf(stderr,"program when this computer is idle.\n");
19145 +#endif
19146 +
19147 + des_set_key((C_Block *)key,sch);
19148 + des_set_key((C_Block *)key2,sch2);
19149 + des_set_key((C_Block *)key3,sch3);
19150 +
19151 +#ifndef SIGALRM
19152 + fprintf(stderr,"First we calculate the approximate speed ...\n");
19153 + des_set_key((C_Block *)key,sch);
19154 + count=10;
19155 + do {
19156 + long i;
19157 + unsigned long data[2];
19158 +
19159 + count*=2;
19160 + Time_F(START);
19161 + for (i=count; i; i--)
19162 + des_encrypt(data,&(sch[0]),DES_ENCRYPT);
19163 + d=Time_F(STOP);
19164 + } while (d < 3.0);
19165 + ca=count;
19166 + cb=count*3;
19167 + cc=count*3*8/BUFSIZE+1;
19168 + cd=count*8/BUFSIZE+1;
19169 +
19170 + ce=count/20+1;
19171 +#define COND(d) (count != (d))
19172 +#define COUNT(d) (d)
19173 +#else
19174 +#define COND(c) (run)
19175 +#define COUNT(d) (count)
19176 + signal(SIGALRM,sig_done);
19177 + alarm(10);
19178 +#endif
19179 +
19180 +#ifdef PART1
19181 + time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0);
19182 + time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1);
19183 + time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2);
19184 + num+=3;
19185 +#endif
19186 +#ifdef PART2
19187 + time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3);
19188 + time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4);
19189 + time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5);
19190 + num+=3;
19191 +#endif
19192 +#ifdef PART3
19193 + time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6);
19194 + time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7);
19195 + time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8);
19196 + num+=3;
19197 +#endif
19198 +#ifdef PART4
19199 + time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9);
19200 + time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10);
19201 + time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11);
19202 + num+=3;
19203 +#endif
19204 +
19205 +#ifdef PART1
19206 + str[0]=" 4 c i";
19207 + print_it("des_encrypt_u4_cisc_idx ",0);
19208 + max=tm[0];
19209 + max_idx=0;
19210 + str[1]="16 c i";
19211 + print_it("des_encrypt_u16_cisc_idx ",1);
19212 + if (max < tm[1]) { max=tm[1]; max_idx=1; }
19213 + str[2]=" 4 r1 i";
19214 + print_it("des_encrypt_u4_risc1_idx ",2);
19215 + if (max < tm[2]) { max=tm[2]; max_idx=2; }
19216 +#endif
19217 +#ifdef PART2
19218 + str[3]="16 r1 i";
19219 + print_it("des_encrypt_u16_risc1_idx",3);
19220 + if (max < tm[3]) { max=tm[3]; max_idx=3; }
19221 + str[4]=" 4 r2 i";
19222 + print_it("des_encrypt_u4_risc2_idx ",4);
19223 + if (max < tm[4]) { max=tm[4]; max_idx=4; }
19224 + str[5]="16 r2 i";
19225 + print_it("des_encrypt_u16_risc2_idx",5);
19226 + if (max < tm[5]) { max=tm[5]; max_idx=5; }
19227 +#endif
19228 +#ifdef PART3
19229 + str[6]=" 4 c p";
19230 + print_it("des_encrypt_u4_cisc_ptr ",6);
19231 + if (max < tm[6]) { max=tm[6]; max_idx=6; }
19232 + str[7]="16 c p";
19233 + print_it("des_encrypt_u16_cisc_ptr ",7);
19234 + if (max < tm[7]) { max=tm[7]; max_idx=7; }
19235 + str[8]=" 4 r1 p";
19236 + print_it("des_encrypt_u4_risc1_ptr ",8);
19237 + if (max < tm[8]) { max=tm[8]; max_idx=8; }
19238 +#endif
19239 +#ifdef PART4
19240 + str[9]="16 r1 p";
19241 + print_it("des_encrypt_u16_risc1_ptr",9);
19242 + if (max < tm[9]) { max=tm[9]; max_idx=9; }
19243 + str[10]=" 4 r2 p";
19244 + print_it("des_encrypt_u4_risc2_ptr ",10);
19245 + if (max < tm[10]) { max=tm[10]; max_idx=10; }
19246 + str[11]="16 r2 p";
19247 + print_it("des_encrypt_u16_risc2_ptr",11);
19248 + if (max < tm[11]) { max=tm[11]; max_idx=11; }
19249 +#endif
19250 + printf("options des ecb/s\n");
19251 + printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
19252 + d=tm[max_idx];
19253 + tm[max_idx]= -2.0;
19254 + max= -1.0;
19255 + for (;;)
19256 + {
19257 + for (i=0; i<12; i++)
19258 + {
19259 + if (max < tm[i]) { max=tm[i]; j=i; }
19260 + }
19261 + if (max < 0.0) break;
19262 + printf("%s %12.2f %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
19263 + tm[j]= -2.0;
19264 + max= -1.0;
19265 + }
19266 +
19267 + switch (max_idx)
19268 + {
19269 + case 0:
19270 + printf("-DDES_DEFAULT_OPTIONS\n");
19271 + break;
19272 + case 1:
19273 + printf("-DDES_UNROLL\n");
19274 + break;
19275 + case 2:
19276 + printf("-DDES_RISC1\n");
19277 + break;
19278 + case 3:
19279 + printf("-DDES_UNROLL -DDES_RISC1\n");
19280 + break;
19281 + case 4:
19282 + printf("-DDES_RISC2\n");
19283 + break;
19284 + case 5:
19285 + printf("-DDES_UNROLL -DDES_RISC2\n");
19286 + break;
19287 + case 6:
19288 + printf("-DDES_PTR\n");
19289 + break;
19290 + case 7:
19291 + printf("-DDES_UNROLL -DDES_PTR\n");
19292 + break;
19293 + case 8:
19294 + printf("-DDES_RISC1 -DDES_PTR\n");
19295 + break;
19296 + case 9:
19297 + printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n");
19298 + break;
19299 + case 10:
19300 + printf("-DDES_RISC2 -DDES_PTR\n");
19301 + break;
19302 + case 11:
19303 + printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n");
19304 + break;
19305 + }
19306 + exit(0);
19307 +#if defined(LINT) || defined(MSDOS)
19308 + return(0);
19309 +#endif
19310 + }
19311 --- /dev/null Tue Mar 11 13:02:56 2003
19312 +++ linux/net/ipsec/des/dx86unix.S Mon Feb 9 13:51:03 2004
19313 @@ -0,0 +1,3160 @@
19314 +/*
19315 + * This file was originally generated by Michael Richardson <mcr@freeswan.org>
19316 + * via the perl scripts found in the ASM subdir. It remains copyright of
19317 + * Eric Young, see the file COPYRIGHT.
19318 + *
19319 + * This was last done on October 9, 2002.
19320 + *
19321 + * While this file does not need to go through cpp, we pass it through
19322 + * CPP by naming it dx86unix.S instead of dx86unix.s because there is
19323 + * a bug in Rules.make for .s builds - specifically it references EXTRA_CFLAGS
19324 + * which may contain stuff that AS doesn't understand instead of
19325 + * referencing EXTRA_AFLAGS.
19326 + */
19327 +
19328 + .file "dx86unix.S"
19329 + .version "01.01"
19330 +.text
19331 + .align 16
19332 +.globl des_encrypt
19333 + .type des_encrypt , @function
19334 +des_encrypt:
19335 + pushl %esi
19336 + pushl %edi
19337 +
19338 +
19339 + movl 12(%esp), %esi
19340 + xorl %ecx, %ecx
19341 + pushl %ebx
19342 + pushl %ebp
19343 + movl (%esi), %eax
19344 + movl 28(%esp), %ebx
19345 + movl 4(%esi), %edi
19346 +
19347 +
19348 + roll $4, %eax
19349 + movl %eax, %esi
19350 + xorl %edi, %eax
19351 + andl $0xf0f0f0f0, %eax
19352 + xorl %eax, %esi
19353 + xorl %eax, %edi
19354 +
19355 + roll $20, %edi
19356 + movl %edi, %eax
19357 + xorl %esi, %edi
19358 + andl $0xfff0000f, %edi
19359 + xorl %edi, %eax
19360 + xorl %edi, %esi
19361 +
19362 + roll $14, %eax
19363 + movl %eax, %edi
19364 + xorl %esi, %eax
19365 + andl $0x33333333, %eax
19366 + xorl %eax, %edi
19367 + xorl %eax, %esi
19368 +
19369 + roll $22, %esi
19370 + movl %esi, %eax
19371 + xorl %edi, %esi
19372 + andl $0x03fc03fc, %esi
19373 + xorl %esi, %eax
19374 + xorl %esi, %edi
19375 +
19376 + roll $9, %eax
19377 + movl %eax, %esi
19378 + xorl %edi, %eax
19379 + andl $0xaaaaaaaa, %eax
19380 + xorl %eax, %esi
19381 + xorl %eax, %edi
19382 +
19383 +.byte 209
19384 +.byte 199
19385 + movl 24(%esp), %ebp
19386 + cmpl $0, %ebx
19387 + je .L000start_decrypt
19388 +
19389 +
19390 + movl (%ebp), %eax
19391 + xorl %ebx, %ebx
19392 + movl 4(%ebp), %edx
19393 + xorl %esi, %eax
19394 + xorl %esi, %edx
19395 + andl $0xfcfcfcfc, %eax
19396 + andl $0xcfcfcfcf, %edx
19397 + movb %al, %bl
19398 + movb %ah, %cl
19399 + rorl $4, %edx
19400 + movl des_SPtrans(%ebx),%ebp
19401 + movb %dl, %bl
19402 + xorl %ebp, %edi
19403 + movl 0x200+des_SPtrans(%ecx),%ebp
19404 + xorl %ebp, %edi
19405 + movb %dh, %cl
19406 + shrl $16, %eax
19407 + movl 0x100+des_SPtrans(%ebx),%ebp
19408 + xorl %ebp, %edi
19409 + movb %ah, %bl
19410 + shrl $16, %edx
19411 + movl 0x300+des_SPtrans(%ecx),%ebp
19412 + xorl %ebp, %edi
19413 + movl 24(%esp), %ebp
19414 + movb %dh, %cl
19415 + andl $0xff, %eax
19416 + andl $0xff, %edx
19417 + movl 0x600+des_SPtrans(%ebx),%ebx
19418 + xorl %ebx, %edi
19419 + movl 0x700+des_SPtrans(%ecx),%ebx
19420 + xorl %ebx, %edi
19421 + movl 0x400+des_SPtrans(%eax),%ebx
19422 + xorl %ebx, %edi
19423 + movl 0x500+des_SPtrans(%edx),%ebx
19424 + xorl %ebx, %edi
19425 +
19426 +
19427 + movl 8(%ebp), %eax
19428 + xorl %ebx, %ebx
19429 + movl 12(%ebp), %edx
19430 + xorl %edi, %eax
19431 + xorl %edi, %edx
19432 + andl $0xfcfcfcfc, %eax
19433 + andl $0xcfcfcfcf, %edx
19434 + movb %al, %bl
19435 + movb %ah, %cl
19436 + rorl $4, %edx
19437 + movl des_SPtrans(%ebx),%ebp
19438 + movb %dl, %bl
19439 + xorl %ebp, %esi
19440 + movl 0x200+des_SPtrans(%ecx),%ebp
19441 + xorl %ebp, %esi
19442 + movb %dh, %cl
19443 + shrl $16, %eax
19444 + movl 0x100+des_SPtrans(%ebx),%ebp
19445 + xorl %ebp, %esi
19446 + movb %ah, %bl
19447 + shrl $16, %edx
19448 + movl 0x300+des_SPtrans(%ecx),%ebp
19449 + xorl %ebp, %esi
19450 + movl 24(%esp), %ebp
19451 + movb %dh, %cl
19452 + andl $0xff, %eax
19453 + andl $0xff, %edx
19454 + movl 0x600+des_SPtrans(%ebx),%ebx
19455 + xorl %ebx, %esi
19456 + movl 0x700+des_SPtrans(%ecx),%ebx
19457 + xorl %ebx, %esi
19458 + movl 0x400+des_SPtrans(%eax),%ebx
19459 + xorl %ebx, %esi
19460 + movl 0x500+des_SPtrans(%edx),%ebx
19461 + xorl %ebx, %esi
19462 +
19463 +
19464 + movl 16(%ebp), %eax
19465 + xorl %ebx, %ebx
19466 + movl 20(%ebp), %edx
19467 + xorl %esi, %eax
19468 + xorl %esi, %edx
19469 + andl $0xfcfcfcfc, %eax
19470 + andl $0xcfcfcfcf, %edx
19471 + movb %al, %bl
19472 + movb %ah, %cl
19473 + rorl $4, %edx
19474 + movl des_SPtrans(%ebx),%ebp
19475 + movb %dl, %bl
19476 + xorl %ebp, %edi
19477 + movl 0x200+des_SPtrans(%ecx),%ebp
19478 + xorl %ebp, %edi
19479 + movb %dh, %cl
19480 + shrl $16, %eax
19481 + movl 0x100+des_SPtrans(%ebx),%ebp
19482 + xorl %ebp, %edi
19483 + movb %ah, %bl
19484 + shrl $16, %edx
19485 + movl 0x300+des_SPtrans(%ecx),%ebp
19486 + xorl %ebp, %edi
19487 + movl 24(%esp), %ebp
19488 + movb %dh, %cl
19489 + andl $0xff, %eax
19490 + andl $0xff, %edx
19491 + movl 0x600+des_SPtrans(%ebx),%ebx
19492 + xorl %ebx, %edi
19493 + movl 0x700+des_SPtrans(%ecx),%ebx
19494 + xorl %ebx, %edi
19495 + movl 0x400+des_SPtrans(%eax),%ebx
19496 + xorl %ebx, %edi
19497 + movl 0x500+des_SPtrans(%edx),%ebx
19498 + xorl %ebx, %edi
19499 +
19500 +
19501 + movl 24(%ebp), %eax
19502 + xorl %ebx, %ebx
19503 + movl 28(%ebp), %edx
19504 + xorl %edi, %eax
19505 + xorl %edi, %edx
19506 + andl $0xfcfcfcfc, %eax
19507 + andl $0xcfcfcfcf, %edx
19508 + movb %al, %bl
19509 + movb %ah, %cl
19510 + rorl $4, %edx
19511 + movl des_SPtrans(%ebx),%ebp
19512 + movb %dl, %bl
19513 + xorl %ebp, %esi
19514 + movl 0x200+des_SPtrans(%ecx),%ebp
19515 + xorl %ebp, %esi
19516 + movb %dh, %cl
19517 + shrl $16, %eax
19518 + movl 0x100+des_SPtrans(%ebx),%ebp
19519 + xorl %ebp, %esi
19520 + movb %ah, %bl
19521 + shrl $16, %edx
19522 + movl 0x300+des_SPtrans(%ecx),%ebp
19523 + xorl %ebp, %esi
19524 + movl 24(%esp), %ebp
19525 + movb %dh, %cl
19526 + andl $0xff, %eax
19527 + andl $0xff, %edx
19528 + movl 0x600+des_SPtrans(%ebx),%ebx
19529 + xorl %ebx, %esi
19530 + movl 0x700+des_SPtrans(%ecx),%ebx
19531 + xorl %ebx, %esi
19532 + movl 0x400+des_SPtrans(%eax),%ebx
19533 + xorl %ebx, %esi
19534 + movl 0x500+des_SPtrans(%edx),%ebx
19535 + xorl %ebx, %esi
19536 +
19537 +
19538 + movl 32(%ebp), %eax
19539 + xorl %ebx, %ebx
19540 + movl 36(%ebp), %edx
19541 + xorl %esi, %eax
19542 + xorl %esi, %edx
19543 + andl $0xfcfcfcfc, %eax
19544 + andl $0xcfcfcfcf, %edx
19545 + movb %al, %bl
19546 + movb %ah, %cl
19547 + rorl $4, %edx
19548 + movl des_SPtrans(%ebx),%ebp
19549 + movb %dl, %bl
19550 + xorl %ebp, %edi
19551 + movl 0x200+des_SPtrans(%ecx),%ebp
19552 + xorl %ebp, %edi
19553 + movb %dh, %cl
19554 + shrl $16, %eax
19555 + movl 0x100+des_SPtrans(%ebx),%ebp
19556 + xorl %ebp, %edi
19557 + movb %ah, %bl
19558 + shrl $16, %edx
19559 + movl 0x300+des_SPtrans(%ecx),%ebp
19560 + xorl %ebp, %edi
19561 + movl 24(%esp), %ebp
19562 + movb %dh, %cl
19563 + andl $0xff, %eax
19564 + andl $0xff, %edx
19565 + movl 0x600+des_SPtrans(%ebx),%ebx
19566 + xorl %ebx, %edi
19567 + movl 0x700+des_SPtrans(%ecx),%ebx
19568 + xorl %ebx, %edi
19569 + movl 0x400+des_SPtrans(%eax),%ebx
19570 + xorl %ebx, %edi
19571 + movl 0x500+des_SPtrans(%edx),%ebx
19572 + xorl %ebx, %edi
19573 +
19574 +
19575 + movl 40(%ebp), %eax
19576 + xorl %ebx, %ebx
19577 + movl 44(%ebp), %edx
19578 + xorl %edi, %eax
19579 + xorl %edi, %edx
19580 + andl $0xfcfcfcfc, %eax
19581 + andl $0xcfcfcfcf, %edx
19582 + movb %al, %bl
19583 + movb %ah, %cl
19584 + rorl $4, %edx
19585 + movl des_SPtrans(%ebx),%ebp
19586 + movb %dl, %bl
19587 + xorl %ebp, %esi
19588 + movl 0x200+des_SPtrans(%ecx),%ebp
19589 + xorl %ebp, %esi
19590 + movb %dh, %cl
19591 + shrl $16, %eax
19592 + movl 0x100+des_SPtrans(%ebx),%ebp
19593 + xorl %ebp, %esi
19594 + movb %ah, %bl
19595 + shrl $16, %edx
19596 + movl 0x300+des_SPtrans(%ecx),%ebp
19597 + xorl %ebp, %esi
19598 + movl 24(%esp), %ebp
19599 + movb %dh, %cl
19600 + andl $0xff, %eax
19601 + andl $0xff, %edx
19602 + movl 0x600+des_SPtrans(%ebx),%ebx
19603 + xorl %ebx, %esi
19604 + movl 0x700+des_SPtrans(%ecx),%ebx
19605 + xorl %ebx, %esi
19606 + movl 0x400+des_SPtrans(%eax),%ebx
19607 + xorl %ebx, %esi
19608 + movl 0x500+des_SPtrans(%edx),%ebx
19609 + xorl %ebx, %esi
19610 +
19611 +
19612 + movl 48(%ebp), %eax
19613 + xorl %ebx, %ebx
19614 + movl 52(%ebp), %edx
19615 + xorl %esi, %eax
19616 + xorl %esi, %edx
19617 + andl $0xfcfcfcfc, %eax
19618 + andl $0xcfcfcfcf, %edx
19619 + movb %al, %bl
19620 + movb %ah, %cl
19621 + rorl $4, %edx
19622 + movl des_SPtrans(%ebx),%ebp
19623 + movb %dl, %bl
19624 + xorl %ebp, %edi
19625 + movl 0x200+des_SPtrans(%ecx),%ebp
19626 + xorl %ebp, %edi
19627 + movb %dh, %cl
19628 + shrl $16, %eax
19629 + movl 0x100+des_SPtrans(%ebx),%ebp
19630 + xorl %ebp, %edi
19631 + movb %ah, %bl
19632 + shrl $16, %edx
19633 + movl 0x300+des_SPtrans(%ecx),%ebp
19634 + xorl %ebp, %edi
19635 + movl 24(%esp), %ebp
19636 + movb %dh, %cl
19637 + andl $0xff, %eax
19638 + andl $0xff, %edx
19639 + movl 0x600+des_SPtrans(%ebx),%ebx
19640 + xorl %ebx, %edi
19641 + movl 0x700+des_SPtrans(%ecx),%ebx
19642 + xorl %ebx, %edi
19643 + movl 0x400+des_SPtrans(%eax),%ebx
19644 + xorl %ebx, %edi
19645 + movl 0x500+des_SPtrans(%edx),%ebx
19646 + xorl %ebx, %edi
19647 +
19648 +
19649 + movl 56(%ebp), %eax
19650 + xorl %ebx, %ebx
19651 + movl 60(%ebp), %edx
19652 + xorl %edi, %eax
19653 + xorl %edi, %edx
19654 + andl $0xfcfcfcfc, %eax
19655 + andl $0xcfcfcfcf, %edx
19656 + movb %al, %bl
19657 + movb %ah, %cl
19658 + rorl $4, %edx
19659 + movl des_SPtrans(%ebx),%ebp
19660 + movb %dl, %bl
19661 + xorl %ebp, %esi
19662 + movl 0x200+des_SPtrans(%ecx),%ebp
19663 + xorl %ebp, %esi
19664 + movb %dh, %cl
19665 + shrl $16, %eax
19666 + movl 0x100+des_SPtrans(%ebx),%ebp
19667 + xorl %ebp, %esi
19668 + movb %ah, %bl
19669 + shrl $16, %edx
19670 + movl 0x300+des_SPtrans(%ecx),%ebp
19671 + xorl %ebp, %esi
19672 + movl 24(%esp), %ebp
19673 + movb %dh, %cl
19674 + andl $0xff, %eax
19675 + andl $0xff, %edx
19676 + movl 0x600+des_SPtrans(%ebx),%ebx
19677 + xorl %ebx, %esi
19678 + movl 0x700+des_SPtrans(%ecx),%ebx
19679 + xorl %ebx, %esi
19680 + movl 0x400+des_SPtrans(%eax),%ebx
19681 + xorl %ebx, %esi
19682 + movl 0x500+des_SPtrans(%edx),%ebx
19683 + xorl %ebx, %esi
19684 +
19685 +
19686 + movl 64(%ebp), %eax
19687 + xorl %ebx, %ebx
19688 + movl 68(%ebp), %edx
19689 + xorl %esi, %eax
19690 + xorl %esi, %edx
19691 + andl $0xfcfcfcfc, %eax
19692 + andl $0xcfcfcfcf, %edx
19693 + movb %al, %bl
19694 + movb %ah, %cl
19695 + rorl $4, %edx
19696 + movl des_SPtrans(%ebx),%ebp
19697 + movb %dl, %bl
19698 + xorl %ebp, %edi
19699 + movl 0x200+des_SPtrans(%ecx),%ebp
19700 + xorl %ebp, %edi
19701 + movb %dh, %cl
19702 + shrl $16, %eax
19703 + movl 0x100+des_SPtrans(%ebx),%ebp
19704 + xorl %ebp, %edi
19705 + movb %ah, %bl
19706 + shrl $16, %edx
19707 + movl 0x300+des_SPtrans(%ecx),%ebp
19708 + xorl %ebp, %edi
19709 + movl 24(%esp), %ebp
19710 + movb %dh, %cl
19711 + andl $0xff, %eax
19712 + andl $0xff, %edx
19713 + movl 0x600+des_SPtrans(%ebx),%ebx
19714 + xorl %ebx, %edi
19715 + movl 0x700+des_SPtrans(%ecx),%ebx
19716 + xorl %ebx, %edi
19717 + movl 0x400+des_SPtrans(%eax),%ebx
19718 + xorl %ebx, %edi
19719 + movl 0x500+des_SPtrans(%edx),%ebx
19720 + xorl %ebx, %edi
19721 +
19722 +
19723 + movl 72(%ebp), %eax
19724 + xorl %ebx, %ebx
19725 + movl 76(%ebp), %edx
19726 + xorl %edi, %eax
19727 + xorl %edi, %edx
19728 + andl $0xfcfcfcfc, %eax
19729 + andl $0xcfcfcfcf, %edx
19730 + movb %al, %bl
19731 + movb %ah, %cl
19732 + rorl $4, %edx
19733 + movl des_SPtrans(%ebx),%ebp
19734 + movb %dl, %bl
19735 + xorl %ebp, %esi
19736 + movl 0x200+des_SPtrans(%ecx),%ebp
19737 + xorl %ebp, %esi
19738 + movb %dh, %cl
19739 + shrl $16, %eax
19740 + movl 0x100+des_SPtrans(%ebx),%ebp
19741 + xorl %ebp, %esi
19742 + movb %ah, %bl
19743 + shrl $16, %edx
19744 + movl 0x300+des_SPtrans(%ecx),%ebp
19745 + xorl %ebp, %esi
19746 + movl 24(%esp), %ebp
19747 + movb %dh, %cl
19748 + andl $0xff, %eax
19749 + andl $0xff, %edx
19750 + movl 0x600+des_SPtrans(%ebx),%ebx
19751 + xorl %ebx, %esi
19752 + movl 0x700+des_SPtrans(%ecx),%ebx
19753 + xorl %ebx, %esi
19754 + movl 0x400+des_SPtrans(%eax),%ebx
19755 + xorl %ebx, %esi
19756 + movl 0x500+des_SPtrans(%edx),%ebx
19757 + xorl %ebx, %esi
19758 +
19759 +
19760 + movl 80(%ebp), %eax
19761 + xorl %ebx, %ebx
19762 + movl 84(%ebp), %edx
19763 + xorl %esi, %eax
19764 + xorl %esi, %edx
19765 + andl $0xfcfcfcfc, %eax
19766 + andl $0xcfcfcfcf, %edx
19767 + movb %al, %bl
19768 + movb %ah, %cl
19769 + rorl $4, %edx
19770 + movl des_SPtrans(%ebx),%ebp
19771 + movb %dl, %bl
19772 + xorl %ebp, %edi
19773 + movl 0x200+des_SPtrans(%ecx),%ebp
19774 + xorl %ebp, %edi
19775 + movb %dh, %cl
19776 + shrl $16, %eax
19777 + movl 0x100+des_SPtrans(%ebx),%ebp
19778 + xorl %ebp, %edi
19779 + movb %ah, %bl
19780 + shrl $16, %edx
19781 + movl 0x300+des_SPtrans(%ecx),%ebp
19782 + xorl %ebp, %edi
19783 + movl 24(%esp), %ebp
19784 + movb %dh, %cl
19785 + andl $0xff, %eax
19786 + andl $0xff, %edx
19787 + movl 0x600+des_SPtrans(%ebx),%ebx
19788 + xorl %ebx, %edi
19789 + movl 0x700+des_SPtrans(%ecx),%ebx
19790 + xorl %ebx, %edi
19791 + movl 0x400+des_SPtrans(%eax),%ebx
19792 + xorl %ebx, %edi
19793 + movl 0x500+des_SPtrans(%edx),%ebx
19794 + xorl %ebx, %edi
19795 +
19796 +
19797 + movl 88(%ebp), %eax
19798 + xorl %ebx, %ebx
19799 + movl 92(%ebp), %edx
19800 + xorl %edi, %eax
19801 + xorl %edi, %edx
19802 + andl $0xfcfcfcfc, %eax
19803 + andl $0xcfcfcfcf, %edx
19804 + movb %al, %bl
19805 + movb %ah, %cl
19806 + rorl $4, %edx
19807 + movl des_SPtrans(%ebx),%ebp
19808 + movb %dl, %bl
19809 + xorl %ebp, %esi
19810 + movl 0x200+des_SPtrans(%ecx),%ebp
19811 + xorl %ebp, %esi
19812 + movb %dh, %cl
19813 + shrl $16, %eax
19814 + movl 0x100+des_SPtrans(%ebx),%ebp
19815 + xorl %ebp, %esi
19816 + movb %ah, %bl
19817 + shrl $16, %edx
19818 + movl 0x300+des_SPtrans(%ecx),%ebp
19819 + xorl %ebp, %esi
19820 + movl 24(%esp), %ebp
19821 + movb %dh, %cl
19822 + andl $0xff, %eax
19823 + andl $0xff, %edx
19824 + movl 0x600+des_SPtrans(%ebx),%ebx
19825 + xorl %ebx, %esi
19826 + movl 0x700+des_SPtrans(%ecx),%ebx
19827 + xorl %ebx, %esi
19828 + movl 0x400+des_SPtrans(%eax),%ebx
19829 + xorl %ebx, %esi
19830 + movl 0x500+des_SPtrans(%edx),%ebx
19831 + xorl %ebx, %esi
19832 +
19833 +
19834 + movl 96(%ebp), %eax
19835 + xorl %ebx, %ebx
19836 + movl 100(%ebp), %edx
19837 + xorl %esi, %eax
19838 + xorl %esi, %edx
19839 + andl $0xfcfcfcfc, %eax
19840 + andl $0xcfcfcfcf, %edx
19841 + movb %al, %bl
19842 + movb %ah, %cl
19843 + rorl $4, %edx
19844 + movl des_SPtrans(%ebx),%ebp
19845 + movb %dl, %bl
19846 + xorl %ebp, %edi
19847 + movl 0x200+des_SPtrans(%ecx),%ebp
19848 + xorl %ebp, %edi
19849 + movb %dh, %cl
19850 + shrl $16, %eax
19851 + movl 0x100+des_SPtrans(%ebx),%ebp
19852 + xorl %ebp, %edi
19853 + movb %ah, %bl
19854 + shrl $16, %edx
19855 + movl 0x300+des_SPtrans(%ecx),%ebp
19856 + xorl %ebp, %edi
19857 + movl 24(%esp), %ebp
19858 + movb %dh, %cl
19859 + andl $0xff, %eax
19860 + andl $0xff, %edx
19861 + movl 0x600+des_SPtrans(%ebx),%ebx
19862 + xorl %ebx, %edi
19863 + movl 0x700+des_SPtrans(%ecx),%ebx
19864 + xorl %ebx, %edi
19865 + movl 0x400+des_SPtrans(%eax),%ebx
19866 + xorl %ebx, %edi
19867 + movl 0x500+des_SPtrans(%edx),%ebx
19868 + xorl %ebx, %edi
19869 +
19870 +
19871 + movl 104(%ebp), %eax
19872 + xorl %ebx, %ebx
19873 + movl 108(%ebp), %edx
19874 + xorl %edi, %eax
19875 + xorl %edi, %edx
19876 + andl $0xfcfcfcfc, %eax
19877 + andl $0xcfcfcfcf, %edx
19878 + movb %al, %bl
19879 + movb %ah, %cl
19880 + rorl $4, %edx
19881 + movl des_SPtrans(%ebx),%ebp
19882 + movb %dl, %bl
19883 + xorl %ebp, %esi
19884 + movl 0x200+des_SPtrans(%ecx),%ebp
19885 + xorl %ebp, %esi
19886 + movb %dh, %cl
19887 + shrl $16, %eax
19888 + movl 0x100+des_SPtrans(%ebx),%ebp
19889 + xorl %ebp, %esi
19890 + movb %ah, %bl
19891 + shrl $16, %edx
19892 + movl 0x300+des_SPtrans(%ecx),%ebp
19893 + xorl %ebp, %esi
19894 + movl 24(%esp), %ebp
19895 + movb %dh, %cl
19896 + andl $0xff, %eax
19897 + andl $0xff, %edx
19898 + movl 0x600+des_SPtrans(%ebx),%ebx
19899 + xorl %ebx, %esi
19900 + movl 0x700+des_SPtrans(%ecx),%ebx
19901 + xorl %ebx, %esi
19902 + movl 0x400+des_SPtrans(%eax),%ebx
19903 + xorl %ebx, %esi
19904 + movl 0x500+des_SPtrans(%edx),%ebx
19905 + xorl %ebx, %esi
19906 +
19907 +
19908 + movl 112(%ebp), %eax
19909 + xorl %ebx, %ebx
19910 + movl 116(%ebp), %edx
19911 + xorl %esi, %eax
19912 + xorl %esi, %edx
19913 + andl $0xfcfcfcfc, %eax
19914 + andl $0xcfcfcfcf, %edx
19915 + movb %al, %bl
19916 + movb %ah, %cl
19917 + rorl $4, %edx
19918 + movl des_SPtrans(%ebx),%ebp
19919 + movb %dl, %bl
19920 + xorl %ebp, %edi
19921 + movl 0x200+des_SPtrans(%ecx),%ebp
19922 + xorl %ebp, %edi
19923 + movb %dh, %cl
19924 + shrl $16, %eax
19925 + movl 0x100+des_SPtrans(%ebx),%ebp
19926 + xorl %ebp, %edi
19927 + movb %ah, %bl
19928 + shrl $16, %edx
19929 + movl 0x300+des_SPtrans(%ecx),%ebp
19930 + xorl %ebp, %edi
19931 + movl 24(%esp), %ebp
19932 + movb %dh, %cl
19933 + andl $0xff, %eax
19934 + andl $0xff, %edx
19935 + movl 0x600+des_SPtrans(%ebx),%ebx
19936 + xorl %ebx, %edi
19937 + movl 0x700+des_SPtrans(%ecx),%ebx
19938 + xorl %ebx, %edi
19939 + movl 0x400+des_SPtrans(%eax),%ebx
19940 + xorl %ebx, %edi
19941 + movl 0x500+des_SPtrans(%edx),%ebx
19942 + xorl %ebx, %edi
19943 +
19944 +
19945 + movl 120(%ebp), %eax
19946 + xorl %ebx, %ebx
19947 + movl 124(%ebp), %edx
19948 + xorl %edi, %eax
19949 + xorl %edi, %edx
19950 + andl $0xfcfcfcfc, %eax
19951 + andl $0xcfcfcfcf, %edx
19952 + movb %al, %bl
19953 + movb %ah, %cl
19954 + rorl $4, %edx
19955 + movl des_SPtrans(%ebx),%ebp
19956 + movb %dl, %bl
19957 + xorl %ebp, %esi
19958 + movl 0x200+des_SPtrans(%ecx),%ebp
19959 + xorl %ebp, %esi
19960 + movb %dh, %cl
19961 + shrl $16, %eax
19962 + movl 0x100+des_SPtrans(%ebx),%ebp
19963 + xorl %ebp, %esi
19964 + movb %ah, %bl
19965 + shrl $16, %edx
19966 + movl 0x300+des_SPtrans(%ecx),%ebp
19967 + xorl %ebp, %esi
19968 + movl 24(%esp), %ebp
19969 + movb %dh, %cl
19970 + andl $0xff, %eax
19971 + andl $0xff, %edx
19972 + movl 0x600+des_SPtrans(%ebx),%ebx
19973 + xorl %ebx, %esi
19974 + movl 0x700+des_SPtrans(%ecx),%ebx
19975 + xorl %ebx, %esi
19976 + movl 0x400+des_SPtrans(%eax),%ebx
19977 + xorl %ebx, %esi
19978 + movl 0x500+des_SPtrans(%edx),%ebx
19979 + xorl %ebx, %esi
19980 + jmp .L001end
19981 +.L000start_decrypt:
19982 +
19983 +
19984 + movl 120(%ebp), %eax
19985 + xorl %ebx, %ebx
19986 + movl 124(%ebp), %edx
19987 + xorl %esi, %eax
19988 + xorl %esi, %edx
19989 + andl $0xfcfcfcfc, %eax
19990 + andl $0xcfcfcfcf, %edx
19991 + movb %al, %bl
19992 + movb %ah, %cl
19993 + rorl $4, %edx
19994 + movl des_SPtrans(%ebx),%ebp
19995 + movb %dl, %bl
19996 + xorl %ebp, %edi
19997 + movl 0x200+des_SPtrans(%ecx),%ebp
19998 + xorl %ebp, %edi
19999 + movb %dh, %cl
20000 + shrl $16, %eax
20001 + movl 0x100+des_SPtrans(%ebx),%ebp
20002 + xorl %ebp, %edi
20003 + movb %ah, %bl
20004 + shrl $16, %edx
20005 + movl 0x300+des_SPtrans(%ecx),%ebp
20006 + xorl %ebp, %edi
20007 + movl 24(%esp), %ebp
20008 + movb %dh, %cl
20009 + andl $0xff, %eax
20010 + andl $0xff, %edx
20011 + movl 0x600+des_SPtrans(%ebx),%ebx
20012 + xorl %ebx, %edi
20013 + movl 0x700+des_SPtrans(%ecx),%ebx
20014 + xorl %ebx, %edi
20015 + movl 0x400+des_SPtrans(%eax),%ebx
20016 + xorl %ebx, %edi
20017 + movl 0x500+des_SPtrans(%edx),%ebx
20018 + xorl %ebx, %edi
20019 +
20020 +
20021 + movl 112(%ebp), %eax
20022 + xorl %ebx, %ebx
20023 + movl 116(%ebp), %edx
20024 + xorl %edi, %eax
20025 + xorl %edi, %edx
20026 + andl $0xfcfcfcfc, %eax
20027 + andl $0xcfcfcfcf, %edx
20028 + movb %al, %bl
20029 + movb %ah, %cl
20030 + rorl $4, %edx
20031 + movl des_SPtrans(%ebx),%ebp
20032 + movb %dl, %bl
20033 + xorl %ebp, %esi
20034 + movl 0x200+des_SPtrans(%ecx),%ebp
20035 + xorl %ebp, %esi
20036 + movb %dh, %cl
20037 + shrl $16, %eax
20038 + movl 0x100+des_SPtrans(%ebx),%ebp
20039 + xorl %ebp, %esi
20040 + movb %ah, %bl
20041 + shrl $16, %edx
20042 + movl 0x300+des_SPtrans(%ecx),%ebp
20043 + xorl %ebp, %esi
20044 + movl 24(%esp), %ebp
20045 + movb %dh, %cl
20046 + andl $0xff, %eax
20047 + andl $0xff, %edx
20048 + movl 0x600+des_SPtrans(%ebx),%ebx
20049 + xorl %ebx, %esi
20050 + movl 0x700+des_SPtrans(%ecx),%ebx
20051 + xorl %ebx, %esi
20052 + movl 0x400+des_SPtrans(%eax),%ebx
20053 + xorl %ebx, %esi
20054 + movl 0x500+des_SPtrans(%edx),%ebx
20055 + xorl %ebx, %esi
20056 +
20057 +
20058 + movl 104(%ebp), %eax
20059 + xorl %ebx, %ebx
20060 + movl 108(%ebp), %edx
20061 + xorl %esi, %eax
20062 + xorl %esi, %edx
20063 + andl $0xfcfcfcfc, %eax
20064 + andl $0xcfcfcfcf, %edx
20065 + movb %al, %bl
20066 + movb %ah, %cl
20067 + rorl $4, %edx
20068 + movl des_SPtrans(%ebx),%ebp
20069 + movb %dl, %bl
20070 + xorl %ebp, %edi
20071 + movl 0x200+des_SPtrans(%ecx),%ebp
20072 + xorl %ebp, %edi
20073 + movb %dh, %cl
20074 + shrl $16, %eax
20075 + movl 0x100+des_SPtrans(%ebx),%ebp
20076 + xorl %ebp, %edi
20077 + movb %ah, %bl
20078 + shrl $16, %edx
20079 + movl 0x300+des_SPtrans(%ecx),%ebp
20080 + xorl %ebp, %edi
20081 + movl 24(%esp), %ebp
20082 + movb %dh, %cl
20083 + andl $0xff, %eax
20084 + andl $0xff, %edx
20085 + movl 0x600+des_SPtrans(%ebx),%ebx
20086 + xorl %ebx, %edi
20087 + movl 0x700+des_SPtrans(%ecx),%ebx
20088 + xorl %ebx, %edi
20089 + movl 0x400+des_SPtrans(%eax),%ebx
20090 + xorl %ebx, %edi
20091 + movl 0x500+des_SPtrans(%edx),%ebx
20092 + xorl %ebx, %edi
20093 +
20094 +
20095 + movl 96(%ebp), %eax
20096 + xorl %ebx, %ebx
20097 + movl 100(%ebp), %edx
20098 + xorl %edi, %eax
20099 + xorl %edi, %edx
20100 + andl $0xfcfcfcfc, %eax
20101 + andl $0xcfcfcfcf, %edx
20102 + movb %al, %bl
20103 + movb %ah, %cl
20104 + rorl $4, %edx
20105 + movl des_SPtrans(%ebx),%ebp
20106 + movb %dl, %bl
20107 + xorl %ebp, %esi
20108 + movl 0x200+des_SPtrans(%ecx),%ebp
20109 + xorl %ebp, %esi
20110 + movb %dh, %cl
20111 + shrl $16, %eax
20112 + movl 0x100+des_SPtrans(%ebx),%ebp
20113 + xorl %ebp, %esi
20114 + movb %ah, %bl
20115 + shrl $16, %edx
20116 + movl 0x300+des_SPtrans(%ecx),%ebp
20117 + xorl %ebp, %esi
20118 + movl 24(%esp), %ebp
20119 + movb %dh, %cl
20120 + andl $0xff, %eax
20121 + andl $0xff, %edx
20122 + movl 0x600+des_SPtrans(%ebx),%ebx
20123 + xorl %ebx, %esi
20124 + movl 0x700+des_SPtrans(%ecx),%ebx
20125 + xorl %ebx, %esi
20126 + movl 0x400+des_SPtrans(%eax),%ebx
20127 + xorl %ebx, %esi
20128 + movl 0x500+des_SPtrans(%edx),%ebx
20129 + xorl %ebx, %esi
20130 +
20131 +
20132 + movl 88(%ebp), %eax
20133 + xorl %ebx, %ebx
20134 + movl 92(%ebp), %edx
20135 + xorl %esi, %eax
20136 + xorl %esi, %edx
20137 + andl $0xfcfcfcfc, %eax
20138 + andl $0xcfcfcfcf, %edx
20139 + movb %al, %bl
20140 + movb %ah, %cl
20141 + rorl $4, %edx
20142 + movl des_SPtrans(%ebx),%ebp
20143 + movb %dl, %bl
20144 + xorl %ebp, %edi
20145 + movl 0x200+des_SPtrans(%ecx),%ebp
20146 + xorl %ebp, %edi
20147 + movb %dh, %cl
20148 + shrl $16, %eax
20149 + movl 0x100+des_SPtrans(%ebx),%ebp
20150 + xorl %ebp, %edi
20151 + movb %ah, %bl
20152 + shrl $16, %edx
20153 + movl 0x300+des_SPtrans(%ecx),%ebp
20154 + xorl %ebp, %edi
20155 + movl 24(%esp), %ebp
20156 + movb %dh, %cl
20157 + andl $0xff, %eax
20158 + andl $0xff, %edx
20159 + movl 0x600+des_SPtrans(%ebx),%ebx
20160 + xorl %ebx, %edi
20161 + movl 0x700+des_SPtrans(%ecx),%ebx
20162 + xorl %ebx, %edi
20163 + movl 0x400+des_SPtrans(%eax),%ebx
20164 + xorl %ebx, %edi
20165 + movl 0x500+des_SPtrans(%edx),%ebx
20166 + xorl %ebx, %edi
20167 +
20168 +
20169 + movl 80(%ebp), %eax
20170 + xorl %ebx, %ebx
20171 + movl 84(%ebp), %edx
20172 + xorl %edi, %eax
20173 + xorl %edi, %edx
20174 + andl $0xfcfcfcfc, %eax
20175 + andl $0xcfcfcfcf, %edx
20176 + movb %al, %bl
20177 + movb %ah, %cl
20178 + rorl $4, %edx
20179 + movl des_SPtrans(%ebx),%ebp
20180 + movb %dl, %bl
20181 + xorl %ebp, %esi
20182 + movl 0x200+des_SPtrans(%ecx),%ebp
20183 + xorl %ebp, %esi
20184 + movb %dh, %cl
20185 + shrl $16, %eax
20186 + movl 0x100+des_SPtrans(%ebx),%ebp
20187 + xorl %ebp, %esi
20188 + movb %ah, %bl
20189 + shrl $16, %edx
20190 + movl 0x300+des_SPtrans(%ecx),%ebp
20191 + xorl %ebp, %esi
20192 + movl 24(%esp), %ebp
20193 + movb %dh, %cl
20194 + andl $0xff, %eax
20195 + andl $0xff, %edx
20196 + movl 0x600+des_SPtrans(%ebx),%ebx
20197 + xorl %ebx, %esi
20198 + movl 0x700+des_SPtrans(%ecx),%ebx
20199 + xorl %ebx, %esi
20200 + movl 0x400+des_SPtrans(%eax),%ebx
20201 + xorl %ebx, %esi
20202 + movl 0x500+des_SPtrans(%edx),%ebx
20203 + xorl %ebx, %esi
20204 +
20205 +
20206 + movl 72(%ebp), %eax
20207 + xorl %ebx, %ebx
20208 + movl 76(%ebp), %edx
20209 + xorl %esi, %eax
20210 + xorl %esi, %edx
20211 + andl $0xfcfcfcfc, %eax
20212 + andl $0xcfcfcfcf, %edx
20213 + movb %al, %bl
20214 + movb %ah, %cl
20215 + rorl $4, %edx
20216 + movl des_SPtrans(%ebx),%ebp
20217 + movb %dl, %bl
20218 + xorl %ebp, %edi
20219 + movl 0x200+des_SPtrans(%ecx),%ebp
20220 + xorl %ebp, %edi
20221 + movb %dh, %cl
20222 + shrl $16, %eax
20223 + movl 0x100+des_SPtrans(%ebx),%ebp
20224 + xorl %ebp, %edi
20225 + movb %ah, %bl
20226 + shrl $16, %edx
20227 + movl 0x300+des_SPtrans(%ecx),%ebp
20228 + xorl %ebp, %edi
20229 + movl 24(%esp), %ebp
20230 + movb %dh, %cl
20231 + andl $0xff, %eax
20232 + andl $0xff, %edx
20233 + movl 0x600+des_SPtrans(%ebx),%ebx
20234 + xorl %ebx, %edi
20235 + movl 0x700+des_SPtrans(%ecx),%ebx
20236 + xorl %ebx, %edi
20237 + movl 0x400+des_SPtrans(%eax),%ebx
20238 + xorl %ebx, %edi
20239 + movl 0x500+des_SPtrans(%edx),%ebx
20240 + xorl %ebx, %edi
20241 +
20242 +
20243 + movl 64(%ebp), %eax
20244 + xorl %ebx, %ebx
20245 + movl 68(%ebp), %edx
20246 + xorl %edi, %eax
20247 + xorl %edi, %edx
20248 + andl $0xfcfcfcfc, %eax
20249 + andl $0xcfcfcfcf, %edx
20250 + movb %al, %bl
20251 + movb %ah, %cl
20252 + rorl $4, %edx
20253 + movl des_SPtrans(%ebx),%ebp
20254 + movb %dl, %bl
20255 + xorl %ebp, %esi
20256 + movl 0x200+des_SPtrans(%ecx),%ebp
20257 + xorl %ebp, %esi
20258 + movb %dh, %cl
20259 + shrl $16, %eax
20260 + movl 0x100+des_SPtrans(%ebx),%ebp
20261 + xorl %ebp, %esi
20262 + movb %ah, %bl
20263 + shrl $16, %edx
20264 + movl 0x300+des_SPtrans(%ecx),%ebp
20265 + xorl %ebp, %esi
20266 + movl 24(%esp), %ebp
20267 + movb %dh, %cl
20268 + andl $0xff, %eax
20269 + andl $0xff, %edx
20270 + movl 0x600+des_SPtrans(%ebx),%ebx
20271 + xorl %ebx, %esi
20272 + movl 0x700+des_SPtrans(%ecx),%ebx
20273 + xorl %ebx, %esi
20274 + movl 0x400+des_SPtrans(%eax),%ebx
20275 + xorl %ebx, %esi
20276 + movl 0x500+des_SPtrans(%edx),%ebx
20277 + xorl %ebx, %esi
20278 +
20279 +
20280 + movl 56(%ebp), %eax
20281 + xorl %ebx, %ebx
20282 + movl 60(%ebp), %edx
20283 + xorl %esi, %eax
20284 + xorl %esi, %edx
20285 + andl $0xfcfcfcfc, %eax
20286 + andl $0xcfcfcfcf, %edx
20287 + movb %al, %bl
20288 + movb %ah, %cl
20289 + rorl $4, %edx
20290 + movl des_SPtrans(%ebx),%ebp
20291 + movb %dl, %bl
20292 + xorl %ebp, %edi
20293 + movl 0x200+des_SPtrans(%ecx),%ebp
20294 + xorl %ebp, %edi
20295 + movb %dh, %cl
20296 + shrl $16, %eax
20297 + movl 0x100+des_SPtrans(%ebx),%ebp
20298 + xorl %ebp, %edi
20299 + movb %ah, %bl
20300 + shrl $16, %edx
20301 + movl 0x300+des_SPtrans(%ecx),%ebp
20302 + xorl %ebp, %edi
20303 + movl 24(%esp), %ebp
20304 + movb %dh, %cl
20305 + andl $0xff, %eax
20306 + andl $0xff, %edx
20307 + movl 0x600+des_SPtrans(%ebx),%ebx
20308 + xorl %ebx, %edi
20309 + movl 0x700+des_SPtrans(%ecx),%ebx
20310 + xorl %ebx, %edi
20311 + movl 0x400+des_SPtrans(%eax),%ebx
20312 + xorl %ebx, %edi
20313 + movl 0x500+des_SPtrans(%edx),%ebx
20314 + xorl %ebx, %edi
20315 +
20316 +
20317 + movl 48(%ebp), %eax
20318 + xorl %ebx, %ebx
20319 + movl 52(%ebp), %edx
20320 + xorl %edi, %eax
20321 + xorl %edi, %edx
20322 + andl $0xfcfcfcfc, %eax
20323 + andl $0xcfcfcfcf, %edx
20324 + movb %al, %bl
20325 + movb %ah, %cl
20326 + rorl $4, %edx
20327 + movl des_SPtrans(%ebx),%ebp
20328 + movb %dl, %bl
20329 + xorl %ebp, %esi
20330 + movl 0x200+des_SPtrans(%ecx),%ebp
20331 + xorl %ebp, %esi
20332 + movb %dh, %cl
20333 + shrl $16, %eax
20334 + movl 0x100+des_SPtrans(%ebx),%ebp
20335 + xorl %ebp, %esi
20336 + movb %ah, %bl
20337 + shrl $16, %edx
20338 + movl 0x300+des_SPtrans(%ecx),%ebp
20339 + xorl %ebp, %esi
20340 + movl 24(%esp), %ebp
20341 + movb %dh, %cl
20342 + andl $0xff, %eax
20343 + andl $0xff, %edx
20344 + movl 0x600+des_SPtrans(%ebx),%ebx
20345 + xorl %ebx, %esi
20346 + movl 0x700+des_SPtrans(%ecx),%ebx
20347 + xorl %ebx, %esi
20348 + movl 0x400+des_SPtrans(%eax),%ebx
20349 + xorl %ebx, %esi
20350 + movl 0x500+des_SPtrans(%edx),%ebx
20351 + xorl %ebx, %esi
20352 +
20353 +
20354 + movl 40(%ebp), %eax
20355 + xorl %ebx, %ebx
20356 + movl 44(%ebp), %edx
20357 + xorl %esi, %eax
20358 + xorl %esi, %edx
20359 + andl $0xfcfcfcfc, %eax
20360 + andl $0xcfcfcfcf, %edx
20361 + movb %al, %bl
20362 + movb %ah, %cl
20363 + rorl $4, %edx
20364 + movl des_SPtrans(%ebx),%ebp
20365 + movb %dl, %bl
20366 + xorl %ebp, %edi
20367 + movl 0x200+des_SPtrans(%ecx),%ebp
20368 + xorl %ebp, %edi
20369 + movb %dh, %cl
20370 + shrl $16, %eax
20371 + movl 0x100+des_SPtrans(%ebx),%ebp
20372 + xorl %ebp, %edi
20373 + movb %ah, %bl
20374 + shrl $16, %edx
20375 + movl 0x300+des_SPtrans(%ecx),%ebp
20376 + xorl %ebp, %edi
20377 + movl 24(%esp), %ebp
20378 + movb %dh, %cl
20379 + andl $0xff, %eax
20380 + andl $0xff, %edx
20381 + movl 0x600+des_SPtrans(%ebx),%ebx
20382 + xorl %ebx, %edi
20383 + movl 0x700+des_SPtrans(%ecx),%ebx
20384 + xorl %ebx, %edi
20385 + movl 0x400+des_SPtrans(%eax),%ebx
20386 + xorl %ebx, %edi
20387 + movl 0x500+des_SPtrans(%edx),%ebx
20388 + xorl %ebx, %edi
20389 +
20390 +
20391 + movl 32(%ebp), %eax
20392 + xorl %ebx, %ebx
20393 + movl 36(%ebp), %edx
20394 + xorl %edi, %eax
20395 + xorl %edi, %edx
20396 + andl $0xfcfcfcfc, %eax
20397 + andl $0xcfcfcfcf, %edx
20398 + movb %al, %bl
20399 + movb %ah, %cl
20400 + rorl $4, %edx
20401 + movl des_SPtrans(%ebx),%ebp
20402 + movb %dl, %bl
20403 + xorl %ebp, %esi
20404 + movl 0x200+des_SPtrans(%ecx),%ebp
20405 + xorl %ebp, %esi
20406 + movb %dh, %cl
20407 + shrl $16, %eax
20408 + movl 0x100+des_SPtrans(%ebx),%ebp
20409 + xorl %ebp, %esi
20410 + movb %ah, %bl
20411 + shrl $16, %edx
20412 + movl 0x300+des_SPtrans(%ecx),%ebp
20413 + xorl %ebp, %esi
20414 + movl 24(%esp), %ebp
20415 + movb %dh, %cl
20416 + andl $0xff, %eax
20417 + andl $0xff, %edx
20418 + movl 0x600+des_SPtrans(%ebx),%ebx
20419 + xorl %ebx, %esi
20420 + movl 0x700+des_SPtrans(%ecx),%ebx
20421 + xorl %ebx, %esi
20422 + movl 0x400+des_SPtrans(%eax),%ebx
20423 + xorl %ebx, %esi
20424 + movl 0x500+des_SPtrans(%edx),%ebx
20425 + xorl %ebx, %esi
20426 +
20427 +
20428 + movl 24(%ebp), %eax
20429 + xorl %ebx, %ebx
20430 + movl 28(%ebp), %edx
20431 + xorl %esi, %eax
20432 + xorl %esi, %edx
20433 + andl $0xfcfcfcfc, %eax
20434 + andl $0xcfcfcfcf, %edx
20435 + movb %al, %bl
20436 + movb %ah, %cl
20437 + rorl $4, %edx
20438 + movl des_SPtrans(%ebx),%ebp
20439 + movb %dl, %bl
20440 + xorl %ebp, %edi
20441 + movl 0x200+des_SPtrans(%ecx),%ebp
20442 + xorl %ebp, %edi
20443 + movb %dh, %cl
20444 + shrl $16, %eax
20445 + movl 0x100+des_SPtrans(%ebx),%ebp
20446 + xorl %ebp, %edi
20447 + movb %ah, %bl
20448 + shrl $16, %edx
20449 + movl 0x300+des_SPtrans(%ecx),%ebp
20450 + xorl %ebp, %edi
20451 + movl 24(%esp), %ebp
20452 + movb %dh, %cl
20453 + andl $0xff, %eax
20454 + andl $0xff, %edx
20455 + movl 0x600+des_SPtrans(%ebx),%ebx
20456 + xorl %ebx, %edi
20457 + movl 0x700+des_SPtrans(%ecx),%ebx
20458 + xorl %ebx, %edi
20459 + movl 0x400+des_SPtrans(%eax),%ebx
20460 + xorl %ebx, %edi
20461 + movl 0x500+des_SPtrans(%edx),%ebx
20462 + xorl %ebx, %edi
20463 +
20464 +
20465 + movl 16(%ebp), %eax
20466 + xorl %ebx, %ebx
20467 + movl 20(%ebp), %edx
20468 + xorl %edi, %eax
20469 + xorl %edi, %edx
20470 + andl $0xfcfcfcfc, %eax
20471 + andl $0xcfcfcfcf, %edx
20472 + movb %al, %bl
20473 + movb %ah, %cl
20474 + rorl $4, %edx
20475 + movl des_SPtrans(%ebx),%ebp
20476 + movb %dl, %bl
20477 + xorl %ebp, %esi
20478 + movl 0x200+des_SPtrans(%ecx),%ebp
20479 + xorl %ebp, %esi
20480 + movb %dh, %cl
20481 + shrl $16, %eax
20482 + movl 0x100+des_SPtrans(%ebx),%ebp
20483 + xorl %ebp, %esi
20484 + movb %ah, %bl
20485 + shrl $16, %edx
20486 + movl 0x300+des_SPtrans(%ecx),%ebp
20487 + xorl %ebp, %esi
20488 + movl 24(%esp), %ebp
20489 + movb %dh, %cl
20490 + andl $0xff, %eax
20491 + andl $0xff, %edx
20492 + movl 0x600+des_SPtrans(%ebx),%ebx
20493 + xorl %ebx, %esi
20494 + movl 0x700+des_SPtrans(%ecx),%ebx
20495 + xorl %ebx, %esi
20496 + movl 0x400+des_SPtrans(%eax),%ebx
20497 + xorl %ebx, %esi
20498 + movl 0x500+des_SPtrans(%edx),%ebx
20499 + xorl %ebx, %esi
20500 +
20501 +
20502 + movl 8(%ebp), %eax
20503 + xorl %ebx, %ebx
20504 + movl 12(%ebp), %edx
20505 + xorl %esi, %eax
20506 + xorl %esi, %edx
20507 + andl $0xfcfcfcfc, %eax
20508 + andl $0xcfcfcfcf, %edx
20509 + movb %al, %bl
20510 + movb %ah, %cl
20511 + rorl $4, %edx
20512 + movl des_SPtrans(%ebx),%ebp
20513 + movb %dl, %bl
20514 + xorl %ebp, %edi
20515 + movl 0x200+des_SPtrans(%ecx),%ebp
20516 + xorl %ebp, %edi
20517 + movb %dh, %cl
20518 + shrl $16, %eax
20519 + movl 0x100+des_SPtrans(%ebx),%ebp
20520 + xorl %ebp, %edi
20521 + movb %ah, %bl
20522 + shrl $16, %edx
20523 + movl 0x300+des_SPtrans(%ecx),%ebp
20524 + xorl %ebp, %edi
20525 + movl 24(%esp), %ebp
20526 + movb %dh, %cl
20527 + andl $0xff, %eax
20528 + andl $0xff, %edx
20529 + movl 0x600+des_SPtrans(%ebx),%ebx
20530 + xorl %ebx, %edi
20531 + movl 0x700+des_SPtrans(%ecx),%ebx
20532 + xorl %ebx, %edi
20533 + movl 0x400+des_SPtrans(%eax),%ebx
20534 + xorl %ebx, %edi
20535 + movl 0x500+des_SPtrans(%edx),%ebx
20536 + xorl %ebx, %edi
20537 +
20538 +
20539 + movl (%ebp), %eax
20540 + xorl %ebx, %ebx
20541 + movl 4(%ebp), %edx
20542 + xorl %edi, %eax
20543 + xorl %edi, %edx
20544 + andl $0xfcfcfcfc, %eax
20545 + andl $0xcfcfcfcf, %edx
20546 + movb %al, %bl
20547 + movb %ah, %cl
20548 + rorl $4, %edx
20549 + movl des_SPtrans(%ebx),%ebp
20550 + movb %dl, %bl
20551 + xorl %ebp, %esi
20552 + movl 0x200+des_SPtrans(%ecx),%ebp
20553 + xorl %ebp, %esi
20554 + movb %dh, %cl
20555 + shrl $16, %eax
20556 + movl 0x100+des_SPtrans(%ebx),%ebp
20557 + xorl %ebp, %esi
20558 + movb %ah, %bl
20559 + shrl $16, %edx
20560 + movl 0x300+des_SPtrans(%ecx),%ebp
20561 + xorl %ebp, %esi
20562 + movl 24(%esp), %ebp
20563 + movb %dh, %cl
20564 + andl $0xff, %eax
20565 + andl $0xff, %edx
20566 + movl 0x600+des_SPtrans(%ebx),%ebx
20567 + xorl %ebx, %esi
20568 + movl 0x700+des_SPtrans(%ecx),%ebx
20569 + xorl %ebx, %esi
20570 + movl 0x400+des_SPtrans(%eax),%ebx
20571 + xorl %ebx, %esi
20572 + movl 0x500+des_SPtrans(%edx),%ebx
20573 + xorl %ebx, %esi
20574 +.L001end:
20575 +
20576 +
20577 + movl 20(%esp), %edx
20578 +.byte 209
20579 +.byte 206
20580 + movl %edi, %eax
20581 + xorl %esi, %edi
20582 + andl $0xaaaaaaaa, %edi
20583 + xorl %edi, %eax
20584 + xorl %edi, %esi
20585 +
20586 + roll $23, %eax
20587 + movl %eax, %edi
20588 + xorl %esi, %eax
20589 + andl $0x03fc03fc, %eax
20590 + xorl %eax, %edi
20591 + xorl %eax, %esi
20592 +
20593 + roll $10, %edi
20594 + movl %edi, %eax
20595 + xorl %esi, %edi
20596 + andl $0x33333333, %edi
20597 + xorl %edi, %eax
20598 + xorl %edi, %esi
20599 +
20600 + roll $18, %esi
20601 + movl %esi, %edi
20602 + xorl %eax, %esi
20603 + andl $0xfff0000f, %esi
20604 + xorl %esi, %edi
20605 + xorl %esi, %eax
20606 +
20607 + roll $12, %edi
20608 + movl %edi, %esi
20609 + xorl %eax, %edi
20610 + andl $0xf0f0f0f0, %edi
20611 + xorl %edi, %esi
20612 + xorl %edi, %eax
20613 +
20614 + rorl $4, %eax
20615 + movl %eax, (%edx)
20616 + movl %esi, 4(%edx)
20617 + popl %ebp
20618 + popl %ebx
20619 + popl %edi
20620 + popl %esi
20621 + ret
20622 +.des_encrypt_end:
20623 + .size des_encrypt , .des_encrypt_end-des_encrypt
20624 +.ident "desasm.pl"
20625 +.text
20626 + .align 16
20627 +.globl des_encrypt2
20628 + .type des_encrypt2 , @function
20629 +des_encrypt2:
20630 + pushl %esi
20631 + pushl %edi
20632 +
20633 +
20634 + movl 12(%esp), %eax
20635 + xorl %ecx, %ecx
20636 + pushl %ebx
20637 + pushl %ebp
20638 + movl (%eax), %esi
20639 + movl 28(%esp), %ebx
20640 + roll $3, %esi
20641 + movl 4(%eax), %edi
20642 + roll $3, %edi
20643 + movl 24(%esp), %ebp
20644 + cmpl $0, %ebx
20645 + je .L002start_decrypt
20646 +
20647 +
20648 + movl (%ebp), %eax
20649 + xorl %ebx, %ebx
20650 + movl 4(%ebp), %edx
20651 + xorl %esi, %eax
20652 + xorl %esi, %edx
20653 + andl $0xfcfcfcfc, %eax
20654 + andl $0xcfcfcfcf, %edx
20655 + movb %al, %bl
20656 + movb %ah, %cl
20657 + rorl $4, %edx
20658 + movl des_SPtrans(%ebx),%ebp
20659 + movb %dl, %bl
20660 + xorl %ebp, %edi
20661 + movl 0x200+des_SPtrans(%ecx),%ebp
20662 + xorl %ebp, %edi
20663 + movb %dh, %cl
20664 + shrl $16, %eax
20665 + movl 0x100+des_SPtrans(%ebx),%ebp
20666 + xorl %ebp, %edi
20667 + movb %ah, %bl
20668 + shrl $16, %edx
20669 + movl 0x300+des_SPtrans(%ecx),%ebp
20670 + xorl %ebp, %edi
20671 + movl 24(%esp), %ebp
20672 + movb %dh, %cl
20673 + andl $0xff, %eax
20674 + andl $0xff, %edx
20675 + movl 0x600+des_SPtrans(%ebx),%ebx
20676 + xorl %ebx, %edi
20677 + movl 0x700+des_SPtrans(%ecx),%ebx
20678 + xorl %ebx, %edi
20679 + movl 0x400+des_SPtrans(%eax),%ebx
20680 + xorl %ebx, %edi
20681 + movl 0x500+des_SPtrans(%edx),%ebx
20682 + xorl %ebx, %edi
20683 +
20684 +
20685 + movl 8(%ebp), %eax
20686 + xorl %ebx, %ebx
20687 + movl 12(%ebp), %edx
20688 + xorl %edi, %eax
20689 + xorl %edi, %edx
20690 + andl $0xfcfcfcfc, %eax
20691 + andl $0xcfcfcfcf, %edx
20692 + movb %al, %bl
20693 + movb %ah, %cl
20694 + rorl $4, %edx
20695 + movl des_SPtrans(%ebx),%ebp
20696 + movb %dl, %bl
20697 + xorl %ebp, %esi
20698 + movl 0x200+des_SPtrans(%ecx),%ebp
20699 + xorl %ebp, %esi
20700 + movb %dh, %cl
20701 + shrl $16, %eax
20702 + movl 0x100+des_SPtrans(%ebx),%ebp
20703 + xorl %ebp, %esi
20704 + movb %ah, %bl
20705 + shrl $16, %edx
20706 + movl 0x300+des_SPtrans(%ecx),%ebp
20707 + xorl %ebp, %esi
20708 + movl 24(%esp), %ebp
20709 + movb %dh, %cl
20710 + andl $0xff, %eax
20711 + andl $0xff, %edx
20712 + movl 0x600+des_SPtrans(%ebx),%ebx
20713 + xorl %ebx, %esi
20714 + movl 0x700+des_SPtrans(%ecx),%ebx
20715 + xorl %ebx, %esi
20716 + movl 0x400+des_SPtrans(%eax),%ebx
20717 + xorl %ebx, %esi
20718 + movl 0x500+des_SPtrans(%edx),%ebx
20719 + xorl %ebx, %esi
20720 +
20721 +
20722 + movl 16(%ebp), %eax
20723 + xorl %ebx, %ebx
20724 + movl 20(%ebp), %edx
20725 + xorl %esi, %eax
20726 + xorl %esi, %edx
20727 + andl $0xfcfcfcfc, %eax
20728 + andl $0xcfcfcfcf, %edx
20729 + movb %al, %bl
20730 + movb %ah, %cl
20731 + rorl $4, %edx
20732 + movl des_SPtrans(%ebx),%ebp
20733 + movb %dl, %bl
20734 + xorl %ebp, %edi
20735 + movl 0x200+des_SPtrans(%ecx),%ebp
20736 + xorl %ebp, %edi
20737 + movb %dh, %cl
20738 + shrl $16, %eax
20739 + movl 0x100+des_SPtrans(%ebx),%ebp
20740 + xorl %ebp, %edi
20741 + movb %ah, %bl
20742 + shrl $16, %edx
20743 + movl 0x300+des_SPtrans(%ecx),%ebp
20744 + xorl %ebp, %edi
20745 + movl 24(%esp), %ebp
20746 + movb %dh, %cl
20747 + andl $0xff, %eax
20748 + andl $0xff, %edx
20749 + movl 0x600+des_SPtrans(%ebx),%ebx
20750 + xorl %ebx, %edi
20751 + movl 0x700+des_SPtrans(%ecx),%ebx
20752 + xorl %ebx, %edi
20753 + movl 0x400+des_SPtrans(%eax),%ebx
20754 + xorl %ebx, %edi
20755 + movl 0x500+des_SPtrans(%edx),%ebx
20756 + xorl %ebx, %edi
20757 +
20758 +
20759 + movl 24(%ebp), %eax
20760 + xorl %ebx, %ebx
20761 + movl 28(%ebp), %edx
20762 + xorl %edi, %eax
20763 + xorl %edi, %edx
20764 + andl $0xfcfcfcfc, %eax
20765 + andl $0xcfcfcfcf, %edx
20766 + movb %al, %bl
20767 + movb %ah, %cl
20768 + rorl $4, %edx
20769 + movl des_SPtrans(%ebx),%ebp
20770 + movb %dl, %bl
20771 + xorl %ebp, %esi
20772 + movl 0x200+des_SPtrans(%ecx),%ebp
20773 + xorl %ebp, %esi
20774 + movb %dh, %cl
20775 + shrl $16, %eax
20776 + movl 0x100+des_SPtrans(%ebx),%ebp
20777 + xorl %ebp, %esi
20778 + movb %ah, %bl
20779 + shrl $16, %edx
20780 + movl 0x300+des_SPtrans(%ecx),%ebp
20781 + xorl %ebp, %esi
20782 + movl 24(%esp), %ebp
20783 + movb %dh, %cl
20784 + andl $0xff, %eax
20785 + andl $0xff, %edx
20786 + movl 0x600+des_SPtrans(%ebx),%ebx
20787 + xorl %ebx, %esi
20788 + movl 0x700+des_SPtrans(%ecx),%ebx
20789 + xorl %ebx, %esi
20790 + movl 0x400+des_SPtrans(%eax),%ebx
20791 + xorl %ebx, %esi
20792 + movl 0x500+des_SPtrans(%edx),%ebx
20793 + xorl %ebx, %esi
20794 +
20795 +
20796 + movl 32(%ebp), %eax
20797 + xorl %ebx, %ebx
20798 + movl 36(%ebp), %edx
20799 + xorl %esi, %eax
20800 + xorl %esi, %edx
20801 + andl $0xfcfcfcfc, %eax
20802 + andl $0xcfcfcfcf, %edx
20803 + movb %al, %bl
20804 + movb %ah, %cl
20805 + rorl $4, %edx
20806 + movl des_SPtrans(%ebx),%ebp
20807 + movb %dl, %bl
20808 + xorl %ebp, %edi
20809 + movl 0x200+des_SPtrans(%ecx),%ebp
20810 + xorl %ebp, %edi
20811 + movb %dh, %cl
20812 + shrl $16, %eax
20813 + movl 0x100+des_SPtrans(%ebx),%ebp
20814 + xorl %ebp, %edi
20815 + movb %ah, %bl
20816 + shrl $16, %edx
20817 + movl 0x300+des_SPtrans(%ecx),%ebp
20818 + xorl %ebp, %edi
20819 + movl 24(%esp), %ebp
20820 + movb %dh, %cl
20821 + andl $0xff, %eax
20822 + andl $0xff, %edx
20823 + movl 0x600+des_SPtrans(%ebx),%ebx
20824 + xorl %ebx, %edi
20825 + movl 0x700+des_SPtrans(%ecx),%ebx
20826 + xorl %ebx, %edi
20827 + movl 0x400+des_SPtrans(%eax),%ebx
20828 + xorl %ebx, %edi
20829 + movl 0x500+des_SPtrans(%edx),%ebx
20830 + xorl %ebx, %edi
20831 +
20832 +
20833 + movl 40(%ebp), %eax
20834 + xorl %ebx, %ebx
20835 + movl 44(%ebp), %edx
20836 + xorl %edi, %eax
20837 + xorl %edi, %edx
20838 + andl $0xfcfcfcfc, %eax
20839 + andl $0xcfcfcfcf, %edx
20840 + movb %al, %bl
20841 + movb %ah, %cl
20842 + rorl $4, %edx
20843 + movl des_SPtrans(%ebx),%ebp
20844 + movb %dl, %bl
20845 + xorl %ebp, %esi
20846 + movl 0x200+des_SPtrans(%ecx),%ebp
20847 + xorl %ebp, %esi
20848 + movb %dh, %cl
20849 + shrl $16, %eax
20850 + movl 0x100+des_SPtrans(%ebx),%ebp
20851 + xorl %ebp, %esi
20852 + movb %ah, %bl
20853 + shrl $16, %edx
20854 + movl 0x300+des_SPtrans(%ecx),%ebp
20855 + xorl %ebp, %esi
20856 + movl 24(%esp), %ebp
20857 + movb %dh, %cl
20858 + andl $0xff, %eax
20859 + andl $0xff, %edx
20860 + movl 0x600+des_SPtrans(%ebx),%ebx
20861 + xorl %ebx, %esi
20862 + movl 0x700+des_SPtrans(%ecx),%ebx
20863 + xorl %ebx, %esi
20864 + movl 0x400+des_SPtrans(%eax),%ebx
20865 + xorl %ebx, %esi
20866 + movl 0x500+des_SPtrans(%edx),%ebx
20867 + xorl %ebx, %esi
20868 +
20869 +
20870 + movl 48(%ebp), %eax
20871 + xorl %ebx, %ebx
20872 + movl 52(%ebp), %edx
20873 + xorl %esi, %eax
20874 + xorl %esi, %edx
20875 + andl $0xfcfcfcfc, %eax
20876 + andl $0xcfcfcfcf, %edx
20877 + movb %al, %bl
20878 + movb %ah, %cl
20879 + rorl $4, %edx
20880 + movl des_SPtrans(%ebx),%ebp
20881 + movb %dl, %bl
20882 + xorl %ebp, %edi
20883 + movl 0x200+des_SPtrans(%ecx),%ebp
20884 + xorl %ebp, %edi
20885 + movb %dh, %cl
20886 + shrl $16, %eax
20887 + movl 0x100+des_SPtrans(%ebx),%ebp
20888 + xorl %ebp, %edi
20889 + movb %ah, %bl
20890 + shrl $16, %edx
20891 + movl 0x300+des_SPtrans(%ecx),%ebp
20892 + xorl %ebp, %edi
20893 + movl 24(%esp), %ebp
20894 + movb %dh, %cl
20895 + andl $0xff, %eax
20896 + andl $0xff, %edx
20897 + movl 0x600+des_SPtrans(%ebx),%ebx
20898 + xorl %ebx, %edi
20899 + movl 0x700+des_SPtrans(%ecx),%ebx
20900 + xorl %ebx, %edi
20901 + movl 0x400+des_SPtrans(%eax),%ebx
20902 + xorl %ebx, %edi
20903 + movl 0x500+des_SPtrans(%edx),%ebx
20904 + xorl %ebx, %edi
20905 +
20906 +
20907 + movl 56(%ebp), %eax
20908 + xorl %ebx, %ebx
20909 + movl 60(%ebp), %edx
20910 + xorl %edi, %eax
20911 + xorl %edi, %edx
20912 + andl $0xfcfcfcfc, %eax
20913 + andl $0xcfcfcfcf, %edx
20914 + movb %al, %bl
20915 + movb %ah, %cl
20916 + rorl $4, %edx
20917 + movl des_SPtrans(%ebx),%ebp
20918 + movb %dl, %bl
20919 + xorl %ebp, %esi
20920 + movl 0x200+des_SPtrans(%ecx),%ebp
20921 + xorl %ebp, %esi
20922 + movb %dh, %cl
20923 + shrl $16, %eax
20924 + movl 0x100+des_SPtrans(%ebx),%ebp
20925 + xorl %ebp, %esi
20926 + movb %ah, %bl
20927 + shrl $16, %edx
20928 + movl 0x300+des_SPtrans(%ecx),%ebp
20929 + xorl %ebp, %esi
20930 + movl 24(%esp), %ebp
20931 + movb %dh, %cl
20932 + andl $0xff, %eax
20933 + andl $0xff, %edx
20934 + movl 0x600+des_SPtrans(%ebx),%ebx
20935 + xorl %ebx, %esi
20936 + movl 0x700+des_SPtrans(%ecx),%ebx
20937 + xorl %ebx, %esi
20938 + movl 0x400+des_SPtrans(%eax),%ebx
20939 + xorl %ebx, %esi
20940 + movl 0x500+des_SPtrans(%edx),%ebx
20941 + xorl %ebx, %esi
20942 +
20943 +
20944 + movl 64(%ebp), %eax
20945 + xorl %ebx, %ebx
20946 + movl 68(%ebp), %edx
20947 + xorl %esi, %eax
20948 + xorl %esi, %edx
20949 + andl $0xfcfcfcfc, %eax
20950 + andl $0xcfcfcfcf, %edx
20951 + movb %al, %bl
20952 + movb %ah, %cl
20953 + rorl $4, %edx
20954 + movl des_SPtrans(%ebx),%ebp
20955 + movb %dl, %bl
20956 + xorl %ebp, %edi
20957 + movl 0x200+des_SPtrans(%ecx),%ebp
20958 + xorl %ebp, %edi
20959 + movb %dh, %cl
20960 + shrl $16, %eax
20961 + movl 0x100+des_SPtrans(%ebx),%ebp
20962 + xorl %ebp, %edi
20963 + movb %ah, %bl
20964 + shrl $16, %edx
20965 + movl 0x300+des_SPtrans(%ecx),%ebp
20966 + xorl %ebp, %edi
20967 + movl 24(%esp), %ebp
20968 + movb %dh, %cl
20969 + andl $0xff, %eax
20970 + andl $0xff, %edx
20971 + movl 0x600+des_SPtrans(%ebx),%ebx
20972 + xorl %ebx, %edi
20973 + movl 0x700+des_SPtrans(%ecx),%ebx
20974 + xorl %ebx, %edi
20975 + movl 0x400+des_SPtrans(%eax),%ebx
20976 + xorl %ebx, %edi
20977 + movl 0x500+des_SPtrans(%edx),%ebx
20978 + xorl %ebx, %edi
20979 +
20980 +
20981 + movl 72(%ebp), %eax
20982 + xorl %ebx, %ebx
20983 + movl 76(%ebp), %edx
20984 + xorl %edi, %eax
20985 + xorl %edi, %edx
20986 + andl $0xfcfcfcfc, %eax
20987 + andl $0xcfcfcfcf, %edx
20988 + movb %al, %bl
20989 + movb %ah, %cl
20990 + rorl $4, %edx
20991 + movl des_SPtrans(%ebx),%ebp
20992 + movb %dl, %bl
20993 + xorl %ebp, %esi
20994 + movl 0x200+des_SPtrans(%ecx),%ebp
20995 + xorl %ebp, %esi
20996 + movb %dh, %cl
20997 + shrl $16, %eax
20998 + movl 0x100+des_SPtrans(%ebx),%ebp
20999 + xorl %ebp, %esi
21000 + movb %ah, %bl
21001 + shrl $16, %edx
21002 + movl 0x300+des_SPtrans(%ecx),%ebp
21003 + xorl %ebp, %esi
21004 + movl 24(%esp), %ebp
21005 + movb %dh, %cl
21006 + andl $0xff, %eax
21007 + andl $0xff, %edx
21008 + movl 0x600+des_SPtrans(%ebx),%ebx
21009 + xorl %ebx, %esi
21010 + movl 0x700+des_SPtrans(%ecx),%ebx
21011 + xorl %ebx, %esi
21012 + movl 0x400+des_SPtrans(%eax),%ebx
21013 + xorl %ebx, %esi
21014 + movl 0x500+des_SPtrans(%edx),%ebx
21015 + xorl %ebx, %esi
21016 +
21017 +
21018 + movl 80(%ebp), %eax
21019 + xorl %ebx, %ebx
21020 + movl 84(%ebp), %edx
21021 + xorl %esi, %eax
21022 + xorl %esi, %edx
21023 + andl $0xfcfcfcfc, %eax
21024 + andl $0xcfcfcfcf, %edx
21025 + movb %al, %bl
21026 + movb %ah, %cl
21027 + rorl $4, %edx
21028 + movl des_SPtrans(%ebx),%ebp
21029 + movb %dl, %bl
21030 + xorl %ebp, %edi
21031 + movl 0x200+des_SPtrans(%ecx),%ebp
21032 + xorl %ebp, %edi
21033 + movb %dh, %cl
21034 + shrl $16, %eax
21035 + movl 0x100+des_SPtrans(%ebx),%ebp
21036 + xorl %ebp, %edi
21037 + movb %ah, %bl
21038 + shrl $16, %edx
21039 + movl 0x300+des_SPtrans(%ecx),%ebp
21040 + xorl %ebp, %edi
21041 + movl 24(%esp), %ebp
21042 + movb %dh, %cl
21043 + andl $0xff, %eax
21044 + andl $0xff, %edx
21045 + movl 0x600+des_SPtrans(%ebx),%ebx
21046 + xorl %ebx, %edi
21047 + movl 0x700+des_SPtrans(%ecx),%ebx
21048 + xorl %ebx, %edi
21049 + movl 0x400+des_SPtrans(%eax),%ebx
21050 + xorl %ebx, %edi
21051 + movl 0x500+des_SPtrans(%edx),%ebx
21052 + xorl %ebx, %edi
21053 +
21054 +
21055 + movl 88(%ebp), %eax
21056 + xorl %ebx, %ebx
21057 + movl 92(%ebp), %edx
21058 + xorl %edi, %eax
21059 + xorl %edi, %edx
21060 + andl $0xfcfcfcfc, %eax
21061 + andl $0xcfcfcfcf, %edx
21062 + movb %al, %bl
21063 + movb %ah, %cl
21064 + rorl $4, %edx
21065 + movl des_SPtrans(%ebx),%ebp
21066 + movb %dl, %bl
21067 + xorl %ebp, %esi
21068 + movl 0x200+des_SPtrans(%ecx),%ebp
21069 + xorl %ebp, %esi
21070 + movb %dh, %cl
21071 + shrl $16, %eax
21072 + movl 0x100+des_SPtrans(%ebx),%ebp
21073 + xorl %ebp, %esi
21074 + movb %ah, %bl
21075 + shrl $16, %edx
21076 + movl 0x300+des_SPtrans(%ecx),%ebp
21077 + xorl %ebp, %esi
21078 + movl 24(%esp), %ebp
21079 + movb %dh, %cl
21080 + andl $0xff, %eax
21081 + andl $0xff, %edx
21082 + movl 0x600+des_SPtrans(%ebx),%ebx
21083 + xorl %ebx, %esi
21084 + movl 0x700+des_SPtrans(%ecx),%ebx
21085 + xorl %ebx, %esi
21086 + movl 0x400+des_SPtrans(%eax),%ebx
21087 + xorl %ebx, %esi
21088 + movl 0x500+des_SPtrans(%edx),%ebx
21089 + xorl %ebx, %esi
21090 +
21091 +
21092 + movl 96(%ebp), %eax
21093 + xorl %ebx, %ebx
21094 + movl 100(%ebp), %edx
21095 + xorl %esi, %eax
21096 + xorl %esi, %edx
21097 + andl $0xfcfcfcfc, %eax
21098 + andl $0xcfcfcfcf, %edx
21099 + movb %al, %bl
21100 + movb %ah, %cl
21101 + rorl $4, %edx
21102 + movl des_SPtrans(%ebx),%ebp
21103 + movb %dl, %bl
21104 + xorl %ebp, %edi
21105 + movl 0x200+des_SPtrans(%ecx),%ebp
21106 + xorl %ebp, %edi
21107 + movb %dh, %cl
21108 + shrl $16, %eax
21109 + movl 0x100+des_SPtrans(%ebx),%ebp
21110 + xorl %ebp, %edi
21111 + movb %ah, %bl
21112 + shrl $16, %edx
21113 + movl 0x300+des_SPtrans(%ecx),%ebp
21114 + xorl %ebp, %edi
21115 + movl 24(%esp), %ebp
21116 + movb %dh, %cl
21117 + andl $0xff, %eax
21118 + andl $0xff, %edx
21119 + movl 0x600+des_SPtrans(%ebx),%ebx
21120 + xorl %ebx, %edi
21121 + movl 0x700+des_SPtrans(%ecx),%ebx
21122 + xorl %ebx, %edi
21123 + movl 0x400+des_SPtrans(%eax),%ebx
21124 + xorl %ebx, %edi
21125 + movl 0x500+des_SPtrans(%edx),%ebx
21126 + xorl %ebx, %edi
21127 +
21128 +
21129 + movl 104(%ebp), %eax
21130 + xorl %ebx, %ebx
21131 + movl 108(%ebp), %edx
21132 + xorl %edi, %eax
21133 + xorl %edi, %edx
21134 + andl $0xfcfcfcfc, %eax
21135 + andl $0xcfcfcfcf, %edx
21136 + movb %al, %bl
21137 + movb %ah, %cl
21138 + rorl $4, %edx
21139 + movl des_SPtrans(%ebx),%ebp
21140 + movb %dl, %bl
21141 + xorl %ebp, %esi
21142 + movl 0x200+des_SPtrans(%ecx),%ebp
21143 + xorl %ebp, %esi
21144 + movb %dh, %cl
21145 + shrl $16, %eax
21146 + movl 0x100+des_SPtrans(%ebx),%ebp
21147 + xorl %ebp, %esi
21148 + movb %ah, %bl
21149 + shrl $16, %edx
21150 + movl 0x300+des_SPtrans(%ecx),%ebp
21151 + xorl %ebp, %esi
21152 + movl 24(%esp), %ebp
21153 + movb %dh, %cl
21154 + andl $0xff, %eax
21155 + andl $0xff, %edx
21156 + movl 0x600+des_SPtrans(%ebx),%ebx
21157 + xorl %ebx, %esi
21158 + movl 0x700+des_SPtrans(%ecx),%ebx
21159 + xorl %ebx, %esi
21160 + movl 0x400+des_SPtrans(%eax),%ebx
21161 + xorl %ebx, %esi
21162 + movl 0x500+des_SPtrans(%edx),%ebx
21163 + xorl %ebx, %esi
21164 +
21165 +
21166 + movl 112(%ebp), %eax
21167 + xorl %ebx, %ebx
21168 + movl 116(%ebp), %edx
21169 + xorl %esi, %eax
21170 + xorl %esi, %edx
21171 + andl $0xfcfcfcfc, %eax
21172 + andl $0xcfcfcfcf, %edx
21173 + movb %al, %bl
21174 + movb %ah, %cl
21175 + rorl $4, %edx
21176 + movl des_SPtrans(%ebx),%ebp
21177 + movb %dl, %bl
21178 + xorl %ebp, %edi
21179 + movl 0x200+des_SPtrans(%ecx),%ebp
21180 + xorl %ebp, %edi
21181 + movb %dh, %cl
21182 + shrl $16, %eax
21183 + movl 0x100+des_SPtrans(%ebx),%ebp
21184 + xorl %ebp, %edi
21185 + movb %ah, %bl
21186 + shrl $16, %edx
21187 + movl 0x300+des_SPtrans(%ecx),%ebp
21188 + xorl %ebp, %edi
21189 + movl 24(%esp), %ebp
21190 + movb %dh, %cl
21191 + andl $0xff, %eax
21192 + andl $0xff, %edx
21193 + movl 0x600+des_SPtrans(%ebx),%ebx
21194 + xorl %ebx, %edi
21195 + movl 0x700+des_SPtrans(%ecx),%ebx
21196 + xorl %ebx, %edi
21197 + movl 0x400+des_SPtrans(%eax),%ebx
21198 + xorl %ebx, %edi
21199 + movl 0x500+des_SPtrans(%edx),%ebx
21200 + xorl %ebx, %edi
21201 +
21202 +
21203 + movl 120(%ebp), %eax
21204 + xorl %ebx, %ebx
21205 + movl 124(%ebp), %edx
21206 + xorl %edi, %eax
21207 + xorl %edi, %edx
21208 + andl $0xfcfcfcfc, %eax
21209 + andl $0xcfcfcfcf, %edx
21210 + movb %al, %bl
21211 + movb %ah, %cl
21212 + rorl $4, %edx
21213 + movl des_SPtrans(%ebx),%ebp
21214 + movb %dl, %bl
21215 + xorl %ebp, %esi
21216 + movl 0x200+des_SPtrans(%ecx),%ebp
21217 + xorl %ebp, %esi
21218 + movb %dh, %cl
21219 + shrl $16, %eax
21220 + movl 0x100+des_SPtrans(%ebx),%ebp
21221 + xorl %ebp, %esi
21222 + movb %ah, %bl
21223 + shrl $16, %edx
21224 + movl 0x300+des_SPtrans(%ecx),%ebp
21225 + xorl %ebp, %esi
21226 + movl 24(%esp), %ebp
21227 + movb %dh, %cl
21228 + andl $0xff, %eax
21229 + andl $0xff, %edx
21230 + movl 0x600+des_SPtrans(%ebx),%ebx
21231 + xorl %ebx, %esi
21232 + movl 0x700+des_SPtrans(%ecx),%ebx
21233 + xorl %ebx, %esi
21234 + movl 0x400+des_SPtrans(%eax),%ebx
21235 + xorl %ebx, %esi
21236 + movl 0x500+des_SPtrans(%edx),%ebx
21237 + xorl %ebx, %esi
21238 + jmp .L003end
21239 +.L002start_decrypt:
21240 +
21241 +
21242 + movl 120(%ebp), %eax
21243 + xorl %ebx, %ebx
21244 + movl 124(%ebp), %edx
21245 + xorl %esi, %eax
21246 + xorl %esi, %edx
21247 + andl $0xfcfcfcfc, %eax
21248 + andl $0xcfcfcfcf, %edx
21249 + movb %al, %bl
21250 + movb %ah, %cl
21251 + rorl $4, %edx
21252 + movl des_SPtrans(%ebx),%ebp
21253 + movb %dl, %bl
21254 + xorl %ebp, %edi
21255 + movl 0x200+des_SPtrans(%ecx),%ebp
21256 + xorl %ebp, %edi
21257 + movb %dh, %cl
21258 + shrl $16, %eax
21259 + movl 0x100+des_SPtrans(%ebx),%ebp
21260 + xorl %ebp, %edi
21261 + movb %ah, %bl
21262 + shrl $16, %edx
21263 + movl 0x300+des_SPtrans(%ecx),%ebp
21264 + xorl %ebp, %edi
21265 + movl 24(%esp), %ebp
21266 + movb %dh, %cl
21267 + andl $0xff, %eax
21268 + andl $0xff, %edx
21269 + movl 0x600+des_SPtrans(%ebx),%ebx
21270 + xorl %ebx, %edi
21271 + movl 0x700+des_SPtrans(%ecx),%ebx
21272 + xorl %ebx, %edi
21273 + movl 0x400+des_SPtrans(%eax),%ebx
21274 + xorl %ebx, %edi
21275 + movl 0x500+des_SPtrans(%edx),%ebx
21276 + xorl %ebx, %edi
21277 +
21278 +
21279 + movl 112(%ebp), %eax
21280 + xorl %ebx, %ebx
21281 + movl 116(%ebp), %edx
21282 + xorl %edi, %eax
21283 + xorl %edi, %edx
21284 + andl $0xfcfcfcfc, %eax
21285 + andl $0xcfcfcfcf, %edx
21286 + movb %al, %bl
21287 + movb %ah, %cl
21288 + rorl $4, %edx
21289 + movl des_SPtrans(%ebx),%ebp
21290 + movb %dl, %bl
21291 + xorl %ebp, %esi
21292 + movl 0x200+des_SPtrans(%ecx),%ebp
21293 + xorl %ebp, %esi
21294 + movb %dh, %cl
21295 + shrl $16, %eax
21296 + movl 0x100+des_SPtrans(%ebx),%ebp
21297 + xorl %ebp, %esi
21298 + movb %ah, %bl
21299 + shrl $16, %edx
21300 + movl 0x300+des_SPtrans(%ecx),%ebp
21301 + xorl %ebp, %esi
21302 + movl 24(%esp), %ebp
21303 + movb %dh, %cl
21304 + andl $0xff, %eax
21305 + andl $0xff, %edx
21306 + movl 0x600+des_SPtrans(%ebx),%ebx
21307 + xorl %ebx, %esi
21308 + movl 0x700+des_SPtrans(%ecx),%ebx
21309 + xorl %ebx, %esi
21310 + movl 0x400+des_SPtrans(%eax),%ebx
21311 + xorl %ebx, %esi
21312 + movl 0x500+des_SPtrans(%edx),%ebx
21313 + xorl %ebx, %esi
21314 +
21315 +
21316 + movl 104(%ebp), %eax
21317 + xorl %ebx, %ebx
21318 + movl 108(%ebp), %edx
21319 + xorl %esi, %eax
21320 + xorl %esi, %edx
21321 + andl $0xfcfcfcfc, %eax
21322 + andl $0xcfcfcfcf, %edx
21323 + movb %al, %bl
21324 + movb %ah, %cl
21325 + rorl $4, %edx
21326 + movl des_SPtrans(%ebx),%ebp
21327 + movb %dl, %bl
21328 + xorl %ebp, %edi
21329 + movl 0x200+des_SPtrans(%ecx),%ebp
21330 + xorl %ebp, %edi
21331 + movb %dh, %cl
21332 + shrl $16, %eax
21333 + movl 0x100+des_SPtrans(%ebx),%ebp
21334 + xorl %ebp, %edi
21335 + movb %ah, %bl
21336 + shrl $16, %edx
21337 + movl 0x300+des_SPtrans(%ecx),%ebp
21338 + xorl %ebp, %edi
21339 + movl 24(%esp), %ebp
21340 + movb %dh, %cl
21341 + andl $0xff, %eax
21342 + andl $0xff, %edx
21343 + movl 0x600+des_SPtrans(%ebx),%ebx
21344 + xorl %ebx, %edi
21345 + movl 0x700+des_SPtrans(%ecx),%ebx
21346 + xorl %ebx, %edi
21347 + movl 0x400+des_SPtrans(%eax),%ebx
21348 + xorl %ebx, %edi
21349 + movl 0x500+des_SPtrans(%edx),%ebx
21350 + xorl %ebx, %edi
21351 +
21352 +
21353 + movl 96(%ebp), %eax
21354 + xorl %ebx, %ebx
21355 + movl 100(%ebp), %edx
21356 + xorl %edi, %eax
21357 + xorl %edi, %edx
21358 + andl $0xfcfcfcfc, %eax
21359 + andl $0xcfcfcfcf, %edx
21360 + movb %al, %bl
21361 + movb %ah, %cl
21362 + rorl $4, %edx
21363 + movl des_SPtrans(%ebx),%ebp
21364 + movb %dl, %bl
21365 + xorl %ebp, %esi
21366 + movl 0x200+des_SPtrans(%ecx),%ebp
21367 + xorl %ebp, %esi
21368 + movb %dh, %cl
21369 + shrl $16, %eax
21370 + movl 0x100+des_SPtrans(%ebx),%ebp
21371 + xorl %ebp, %esi
21372 + movb %ah, %bl
21373 + shrl $16, %edx
21374 + movl 0x300+des_SPtrans(%ecx),%ebp
21375 + xorl %ebp, %esi
21376 + movl 24(%esp), %ebp
21377 + movb %dh, %cl
21378 + andl $0xff, %eax
21379 + andl $0xff, %edx
21380 + movl 0x600+des_SPtrans(%ebx),%ebx
21381 + xorl %ebx, %esi
21382 + movl 0x700+des_SPtrans(%ecx),%ebx
21383 + xorl %ebx, %esi
21384 + movl 0x400+des_SPtrans(%eax),%ebx
21385 + xorl %ebx, %esi
21386 + movl 0x500+des_SPtrans(%edx),%ebx
21387 + xorl %ebx, %esi
21388 +
21389 +
21390 + movl 88(%ebp), %eax
21391 + xorl %ebx, %ebx
21392 + movl 92(%ebp), %edx
21393 + xorl %esi, %eax
21394 + xorl %esi, %edx
21395 + andl $0xfcfcfcfc, %eax
21396 + andl $0xcfcfcfcf, %edx
21397 + movb %al, %bl
21398 + movb %ah, %cl
21399 + rorl $4, %edx
21400 + movl des_SPtrans(%ebx),%ebp
21401 + movb %dl, %bl
21402 + xorl %ebp, %edi
21403 + movl 0x200+des_SPtrans(%ecx),%ebp
21404 + xorl %ebp, %edi
21405 + movb %dh, %cl
21406 + shrl $16, %eax
21407 + movl 0x100+des_SPtrans(%ebx),%ebp
21408 + xorl %ebp, %edi
21409 + movb %ah, %bl
21410 + shrl $16, %edx
21411 + movl 0x300+des_SPtrans(%ecx),%ebp
21412 + xorl %ebp, %edi
21413 + movl 24(%esp), %ebp
21414 + movb %dh, %cl
21415 + andl $0xff, %eax
21416 + andl $0xff, %edx
21417 + movl 0x600+des_SPtrans(%ebx),%ebx
21418 + xorl %ebx, %edi
21419 + movl 0x700+des_SPtrans(%ecx),%ebx
21420 + xorl %ebx, %edi
21421 + movl 0x400+des_SPtrans(%eax),%ebx
21422 + xorl %ebx, %edi
21423 + movl 0x500+des_SPtrans(%edx),%ebx
21424 + xorl %ebx, %edi
21425 +
21426 +
21427 + movl 80(%ebp), %eax
21428 + xorl %ebx, %ebx
21429 + movl 84(%ebp), %edx
21430 + xorl %edi, %eax
21431 + xorl %edi, %edx
21432 + andl $0xfcfcfcfc, %eax
21433 + andl $0xcfcfcfcf, %edx
21434 + movb %al, %bl
21435 + movb %ah, %cl
21436 + rorl $4, %edx
21437 + movl des_SPtrans(%ebx),%ebp
21438 + movb %dl, %bl
21439 + xorl %ebp, %esi
21440 + movl 0x200+des_SPtrans(%ecx),%ebp
21441 + xorl %ebp, %esi
21442 + movb %dh, %cl
21443 + shrl $16, %eax
21444 + movl 0x100+des_SPtrans(%ebx),%ebp
21445 + xorl %ebp, %esi
21446 + movb %ah, %bl
21447 + shrl $16, %edx
21448 + movl 0x300+des_SPtrans(%ecx),%ebp
21449 + xorl %ebp, %esi
21450 + movl 24(%esp), %ebp
21451 + movb %dh, %cl
21452 + andl $0xff, %eax
21453 + andl $0xff, %edx
21454 + movl 0x600+des_SPtrans(%ebx),%ebx
21455 + xorl %ebx, %esi
21456 + movl 0x700+des_SPtrans(%ecx),%ebx
21457 + xorl %ebx, %esi
21458 + movl 0x400+des_SPtrans(%eax),%ebx
21459 + xorl %ebx, %esi
21460 + movl 0x500+des_SPtrans(%edx),%ebx
21461 + xorl %ebx, %esi
21462 +
21463 +
21464 + movl 72(%ebp), %eax
21465 + xorl %ebx, %ebx
21466 + movl 76(%ebp), %edx
21467 + xorl %esi, %eax
21468 + xorl %esi, %edx
21469 + andl $0xfcfcfcfc, %eax
21470 + andl $0xcfcfcfcf, %edx
21471 + movb %al, %bl
21472 + movb %ah, %cl
21473 + rorl $4, %edx
21474 + movl des_SPtrans(%ebx),%ebp
21475 + movb %dl, %bl
21476 + xorl %ebp, %edi
21477 + movl 0x200+des_SPtrans(%ecx),%ebp
21478 + xorl %ebp, %edi
21479 + movb %dh, %cl
21480 + shrl $16, %eax
21481 + movl 0x100+des_SPtrans(%ebx),%ebp
21482 + xorl %ebp, %edi
21483 + movb %ah, %bl
21484 + shrl $16, %edx
21485 + movl 0x300+des_SPtrans(%ecx),%ebp
21486 + xorl %ebp, %edi
21487 + movl 24(%esp), %ebp
21488 + movb %dh, %cl
21489 + andl $0xff, %eax
21490 + andl $0xff, %edx
21491 + movl 0x600+des_SPtrans(%ebx),%ebx
21492 + xorl %ebx, %edi
21493 + movl 0x700+des_SPtrans(%ecx),%ebx
21494 + xorl %ebx, %edi
21495 + movl 0x400+des_SPtrans(%eax),%ebx
21496 + xorl %ebx, %edi
21497 + movl 0x500+des_SPtrans(%edx),%ebx
21498 + xorl %ebx, %edi
21499 +
21500 +
21501 + movl 64(%ebp), %eax
21502 + xorl %ebx, %ebx
21503 + movl 68(%ebp), %edx
21504 + xorl %edi, %eax
21505 + xorl %edi, %edx
21506 + andl $0xfcfcfcfc, %eax
21507 + andl $0xcfcfcfcf, %edx
21508 + movb %al, %bl
21509 + movb %ah, %cl
21510 + rorl $4, %edx
21511 + movl des_SPtrans(%ebx),%ebp
21512 + movb %dl, %bl
21513 + xorl %ebp, %esi
21514 + movl 0x200+des_SPtrans(%ecx),%ebp
21515 + xorl %ebp, %esi
21516 + movb %dh, %cl
21517 + shrl $16, %eax
21518 + movl 0x100+des_SPtrans(%ebx),%ebp
21519 + xorl %ebp, %esi
21520 + movb %ah, %bl
21521 + shrl $16, %edx
21522 + movl 0x300+des_SPtrans(%ecx),%ebp
21523 + xorl %ebp, %esi
21524 + movl 24(%esp), %ebp
21525 + movb %dh, %cl
21526 + andl $0xff, %eax
21527 + andl $0xff, %edx
21528 + movl 0x600+des_SPtrans(%ebx),%ebx
21529 + xorl %ebx, %esi
21530 + movl 0x700+des_SPtrans(%ecx),%ebx
21531 + xorl %ebx, %esi
21532 + movl 0x400+des_SPtrans(%eax),%ebx
21533 + xorl %ebx, %esi
21534 + movl 0x500+des_SPtrans(%edx),%ebx
21535 + xorl %ebx, %esi
21536 +
21537 +
21538 + movl 56(%ebp), %eax
21539 + xorl %ebx, %ebx
21540 + movl 60(%ebp), %edx
21541 + xorl %esi, %eax
21542 + xorl %esi, %edx
21543 + andl $0xfcfcfcfc, %eax
21544 + andl $0xcfcfcfcf, %edx
21545 + movb %al, %bl
21546 + movb %ah, %cl
21547 + rorl $4, %edx
21548 + movl des_SPtrans(%ebx),%ebp
21549 + movb %dl, %bl
21550 + xorl %ebp, %edi
21551 + movl 0x200+des_SPtrans(%ecx),%ebp
21552 + xorl %ebp, %edi
21553 + movb %dh, %cl
21554 + shrl $16, %eax
21555 + movl 0x100+des_SPtrans(%ebx),%ebp
21556 + xorl %ebp, %edi
21557 + movb %ah, %bl
21558 + shrl $16, %edx
21559 + movl 0x300+des_SPtrans(%ecx),%ebp
21560 + xorl %ebp, %edi
21561 + movl 24(%esp), %ebp
21562 + movb %dh, %cl
21563 + andl $0xff, %eax
21564 + andl $0xff, %edx
21565 + movl 0x600+des_SPtrans(%ebx),%ebx
21566 + xorl %ebx, %edi
21567 + movl 0x700+des_SPtrans(%ecx),%ebx
21568 + xorl %ebx, %edi
21569 + movl 0x400+des_SPtrans(%eax),%ebx
21570 + xorl %ebx, %edi
21571 + movl 0x500+des_SPtrans(%edx),%ebx
21572 + xorl %ebx, %edi
21573 +
21574 +
21575 + movl 48(%ebp), %eax
21576 + xorl %ebx, %ebx
21577 + movl 52(%ebp), %edx
21578 + xorl %edi, %eax
21579 + xorl %edi, %edx
21580 + andl $0xfcfcfcfc, %eax
21581 + andl $0xcfcfcfcf, %edx
21582 + movb %al, %bl
21583 + movb %ah, %cl
21584 + rorl $4, %edx
21585 + movl des_SPtrans(%ebx),%ebp
21586 + movb %dl, %bl
21587 + xorl %ebp, %esi
21588 + movl 0x200+des_SPtrans(%ecx),%ebp
21589 + xorl %ebp, %esi
21590 + movb %dh, %cl
21591 + shrl $16, %eax
21592 + movl 0x100+des_SPtrans(%ebx),%ebp
21593 + xorl %ebp, %esi
21594 + movb %ah, %bl
21595 + shrl $16, %edx
21596 + movl 0x300+des_SPtrans(%ecx),%ebp
21597 + xorl %ebp, %esi
21598 + movl 24(%esp), %ebp
21599 + movb %dh, %cl
21600 + andl $0xff, %eax
21601 + andl $0xff, %edx
21602 + movl 0x600+des_SPtrans(%ebx),%ebx
21603 + xorl %ebx, %esi
21604 + movl 0x700+des_SPtrans(%ecx),%ebx
21605 + xorl %ebx, %esi
21606 + movl 0x400+des_SPtrans(%eax),%ebx
21607 + xorl %ebx, %esi
21608 + movl 0x500+des_SPtrans(%edx),%ebx
21609 + xorl %ebx, %esi
21610 +
21611 +
21612 + movl 40(%ebp), %eax
21613 + xorl %ebx, %ebx
21614 + movl 44(%ebp), %edx
21615 + xorl %esi, %eax
21616 + xorl %esi, %edx
21617 + andl $0xfcfcfcfc, %eax
21618 + andl $0xcfcfcfcf, %edx
21619 + movb %al, %bl
21620 + movb %ah, %cl
21621 + rorl $4, %edx
21622 + movl des_SPtrans(%ebx),%ebp
21623 + movb %dl, %bl
21624 + xorl %ebp, %edi
21625 + movl 0x200+des_SPtrans(%ecx),%ebp
21626 + xorl %ebp, %edi
21627 + movb %dh, %cl
21628 + shrl $16, %eax
21629 + movl 0x100+des_SPtrans(%ebx),%ebp
21630 + xorl %ebp, %edi
21631 + movb %ah, %bl
21632 + shrl $16, %edx
21633 + movl 0x300+des_SPtrans(%ecx),%ebp
21634 + xorl %ebp, %edi
21635 + movl 24(%esp), %ebp
21636 + movb %dh, %cl
21637 + andl $0xff, %eax
21638 + andl $0xff, %edx
21639 + movl 0x600+des_SPtrans(%ebx),%ebx
21640 + xorl %ebx, %edi
21641 + movl 0x700+des_SPtrans(%ecx),%ebx
21642 + xorl %ebx, %edi
21643 + movl 0x400+des_SPtrans(%eax),%ebx
21644 + xorl %ebx, %edi
21645 + movl 0x500+des_SPtrans(%edx),%ebx
21646 + xorl %ebx, %edi
21647 +
21648 +
21649 + movl 32(%ebp), %eax
21650 + xorl %ebx, %ebx
21651 + movl 36(%ebp), %edx
21652 + xorl %edi, %eax
21653 + xorl %edi, %edx
21654 + andl $0xfcfcfcfc, %eax
21655 + andl $0xcfcfcfcf, %edx
21656 + movb %al, %bl
21657 + movb %ah, %cl
21658 + rorl $4, %edx
21659 + movl des_SPtrans(%ebx),%ebp
21660 + movb %dl, %bl
21661 + xorl %ebp, %esi
21662 + movl 0x200+des_SPtrans(%ecx),%ebp
21663 + xorl %ebp, %esi
21664 + movb %dh, %cl
21665 + shrl $16, %eax
21666 + movl 0x100+des_SPtrans(%ebx),%ebp
21667 + xorl %ebp, %esi
21668 + movb %ah, %bl
21669 + shrl $16, %edx
21670 + movl 0x300+des_SPtrans(%ecx),%ebp
21671 + xorl %ebp, %esi
21672 + movl 24(%esp), %ebp
21673 + movb %dh, %cl
21674 + andl $0xff, %eax
21675 + andl $0xff, %edx
21676 + movl 0x600+des_SPtrans(%ebx),%ebx
21677 + xorl %ebx, %esi
21678 + movl 0x700+des_SPtrans(%ecx),%ebx
21679 + xorl %ebx, %esi
21680 + movl 0x400+des_SPtrans(%eax),%ebx
21681 + xorl %ebx, %esi
21682 + movl 0x500+des_SPtrans(%edx),%ebx
21683 + xorl %ebx, %esi
21684 +
21685 +
21686 + movl 24(%ebp), %eax
21687 + xorl %ebx, %ebx
21688 + movl 28(%ebp), %edx
21689 + xorl %esi, %eax
21690 + xorl %esi, %edx
21691 + andl $0xfcfcfcfc, %eax
21692 + andl $0xcfcfcfcf, %edx
21693 + movb %al, %bl
21694 + movb %ah, %cl
21695 + rorl $4, %edx
21696 + movl des_SPtrans(%ebx),%ebp
21697 + movb %dl, %bl
21698 + xorl %ebp, %edi
21699 + movl 0x200+des_SPtrans(%ecx),%ebp
21700 + xorl %ebp, %edi
21701 + movb %dh, %cl
21702 + shrl $16, %eax
21703 + movl 0x100+des_SPtrans(%ebx),%ebp
21704 + xorl %ebp, %edi
21705 + movb %ah, %bl
21706 + shrl $16, %edx
21707 + movl 0x300+des_SPtrans(%ecx),%ebp
21708 + xorl %ebp, %edi
21709 + movl 24(%esp), %ebp
21710 + movb %dh, %cl
21711 + andl $0xff, %eax
21712 + andl $0xff, %edx
21713 + movl 0x600+des_SPtrans(%ebx),%ebx
21714 + xorl %ebx, %edi
21715 + movl 0x700+des_SPtrans(%ecx),%ebx
21716 + xorl %ebx, %edi
21717 + movl 0x400+des_SPtrans(%eax),%ebx
21718 + xorl %ebx, %edi
21719 + movl 0x500+des_SPtrans(%edx),%ebx
21720 + xorl %ebx, %edi
21721 +
21722 +
21723 + movl 16(%ebp), %eax
21724 + xorl %ebx, %ebx
21725 + movl 20(%ebp), %edx
21726 + xorl %edi, %eax
21727 + xorl %edi, %edx
21728 + andl $0xfcfcfcfc, %eax
21729 + andl $0xcfcfcfcf, %edx
21730 + movb %al, %bl
21731 + movb %ah, %cl
21732 + rorl $4, %edx
21733 + movl des_SPtrans(%ebx),%ebp
21734 + movb %dl, %bl
21735 + xorl %ebp, %esi
21736 + movl 0x200+des_SPtrans(%ecx),%ebp
21737 + xorl %ebp, %esi
21738 + movb %dh, %cl
21739 + shrl $16, %eax
21740 + movl 0x100+des_SPtrans(%ebx),%ebp
21741 + xorl %ebp, %esi
21742 + movb %ah, %bl
21743 + shrl $16, %edx
21744 + movl 0x300+des_SPtrans(%ecx),%ebp
21745 + xorl %ebp, %esi
21746 + movl 24(%esp), %ebp
21747 + movb %dh, %cl
21748 + andl $0xff, %eax
21749 + andl $0xff, %edx
21750 + movl 0x600+des_SPtrans(%ebx),%ebx
21751 + xorl %ebx, %esi
21752 + movl 0x700+des_SPtrans(%ecx),%ebx
21753 + xorl %ebx, %esi
21754 + movl 0x400+des_SPtrans(%eax),%ebx
21755 + xorl %ebx, %esi
21756 + movl 0x500+des_SPtrans(%edx),%ebx
21757 + xorl %ebx, %esi
21758 +
21759 +
21760 + movl 8(%ebp), %eax
21761 + xorl %ebx, %ebx
21762 + movl 12(%ebp), %edx
21763 + xorl %esi, %eax
21764 + xorl %esi, %edx
21765 + andl $0xfcfcfcfc, %eax
21766 + andl $0xcfcfcfcf, %edx
21767 + movb %al, %bl
21768 + movb %ah, %cl
21769 + rorl $4, %edx
21770 + movl des_SPtrans(%ebx),%ebp
21771 + movb %dl, %bl
21772 + xorl %ebp, %edi
21773 + movl 0x200+des_SPtrans(%ecx),%ebp
21774 + xorl %ebp, %edi
21775 + movb %dh, %cl
21776 + shrl $16, %eax
21777 + movl 0x100+des_SPtrans(%ebx),%ebp
21778 + xorl %ebp, %edi
21779 + movb %ah, %bl
21780 + shrl $16, %edx
21781 + movl 0x300+des_SPtrans(%ecx),%ebp
21782 + xorl %ebp, %edi
21783 + movl 24(%esp), %ebp
21784 + movb %dh, %cl
21785 + andl $0xff, %eax
21786 + andl $0xff, %edx
21787 + movl 0x600+des_SPtrans(%ebx),%ebx
21788 + xorl %ebx, %edi
21789 + movl 0x700+des_SPtrans(%ecx),%ebx
21790 + xorl %ebx, %edi
21791 + movl 0x400+des_SPtrans(%eax),%ebx
21792 + xorl %ebx, %edi
21793 + movl 0x500+des_SPtrans(%edx),%ebx
21794 + xorl %ebx, %edi
21795 +
21796 +
21797 + movl (%ebp), %eax
21798 + xorl %ebx, %ebx
21799 + movl 4(%ebp), %edx
21800 + xorl %edi, %eax
21801 + xorl %edi, %edx
21802 + andl $0xfcfcfcfc, %eax
21803 + andl $0xcfcfcfcf, %edx
21804 + movb %al, %bl
21805 + movb %ah, %cl
21806 + rorl $4, %edx
21807 + movl des_SPtrans(%ebx),%ebp
21808 + movb %dl, %bl
21809 + xorl %ebp, %esi
21810 + movl 0x200+des_SPtrans(%ecx),%ebp
21811 + xorl %ebp, %esi
21812 + movb %dh, %cl
21813 + shrl $16, %eax
21814 + movl 0x100+des_SPtrans(%ebx),%ebp
21815 + xorl %ebp, %esi
21816 + movb %ah, %bl
21817 + shrl $16, %edx
21818 + movl 0x300+des_SPtrans(%ecx),%ebp
21819 + xorl %ebp, %esi
21820 + movl 24(%esp), %ebp
21821 + movb %dh, %cl
21822 + andl $0xff, %eax
21823 + andl $0xff, %edx
21824 + movl 0x600+des_SPtrans(%ebx),%ebx
21825 + xorl %ebx, %esi
21826 + movl 0x700+des_SPtrans(%ecx),%ebx
21827 + xorl %ebx, %esi
21828 + movl 0x400+des_SPtrans(%eax),%ebx
21829 + xorl %ebx, %esi
21830 + movl 0x500+des_SPtrans(%edx),%ebx
21831 + xorl %ebx, %esi
21832 +.L003end:
21833 +
21834 +
21835 + rorl $3, %edi
21836 + movl 20(%esp), %eax
21837 + rorl $3, %esi
21838 + movl %edi, (%eax)
21839 + movl %esi, 4(%eax)
21840 + popl %ebp
21841 + popl %ebx
21842 + popl %edi
21843 + popl %esi
21844 + ret
21845 +.des_encrypt2_end:
21846 + .size des_encrypt2 , .des_encrypt2_end-des_encrypt2
21847 +.ident "desasm.pl"
21848 +.text
21849 + .align 16
21850 +.globl des_encrypt3
21851 + .type des_encrypt3 , @function
21852 +des_encrypt3:
21853 + pushl %ebx
21854 + movl 8(%esp), %ebx
21855 + pushl %ebp
21856 + pushl %esi
21857 + pushl %edi
21858 +
21859 +
21860 + movl (%ebx), %edi
21861 + movl 4(%ebx), %esi
21862 + subl $12, %esp
21863 +
21864 +
21865 + roll $4, %edi
21866 + movl %edi, %edx
21867 + xorl %esi, %edi
21868 + andl $0xf0f0f0f0, %edi
21869 + xorl %edi, %edx
21870 + xorl %edi, %esi
21871 +
21872 + roll $20, %esi
21873 + movl %esi, %edi
21874 + xorl %edx, %esi
21875 + andl $0xfff0000f, %esi
21876 + xorl %esi, %edi
21877 + xorl %esi, %edx
21878 +
21879 + roll $14, %edi
21880 + movl %edi, %esi
21881 + xorl %edx, %edi
21882 + andl $0x33333333, %edi
21883 + xorl %edi, %esi
21884 + xorl %edi, %edx
21885 +
21886 + roll $22, %edx
21887 + movl %edx, %edi
21888 + xorl %esi, %edx
21889 + andl $0x03fc03fc, %edx
21890 + xorl %edx, %edi
21891 + xorl %edx, %esi
21892 +
21893 + roll $9, %edi
21894 + movl %edi, %edx
21895 + xorl %esi, %edi
21896 + andl $0xaaaaaaaa, %edi
21897 + xorl %edi, %edx
21898 + xorl %edi, %esi
21899 +
21900 + rorl $3, %edx
21901 + rorl $2, %esi
21902 + movl %esi, 4(%ebx)
21903 + movl 36(%esp), %eax
21904 + movl %edx, (%ebx)
21905 + movl 40(%esp), %edi
21906 + movl 44(%esp), %esi
21907 + movl $1, 8(%esp)
21908 + movl %eax, 4(%esp)
21909 + movl %ebx, (%esp)
21910 + call des_encrypt2
21911 + movl $0, 8(%esp)
21912 + movl %edi, 4(%esp)
21913 + movl %ebx, (%esp)
21914 + call des_encrypt2
21915 + movl $1, 8(%esp)
21916 + movl %esi, 4(%esp)
21917 + movl %ebx, (%esp)
21918 + call des_encrypt2
21919 + addl $12, %esp
21920 + movl (%ebx), %edi
21921 + movl 4(%ebx), %esi
21922 +
21923 +
21924 + roll $2, %esi
21925 + roll $3, %edi
21926 + movl %edi, %eax
21927 + xorl %esi, %edi
21928 + andl $0xaaaaaaaa, %edi
21929 + xorl %edi, %eax
21930 + xorl %edi, %esi
21931 +
21932 + roll $23, %eax
21933 + movl %eax, %edi
21934 + xorl %esi, %eax
21935 + andl $0x03fc03fc, %eax
21936 + xorl %eax, %edi
21937 + xorl %eax, %esi
21938 +
21939 + roll $10, %edi
21940 + movl %edi, %eax
21941 + xorl %esi, %edi
21942 + andl $0x33333333, %edi
21943 + xorl %edi, %eax
21944 + xorl %edi, %esi
21945 +
21946 + roll $18, %esi
21947 + movl %esi, %edi
21948 + xorl %eax, %esi
21949 + andl $0xfff0000f, %esi
21950 + xorl %esi, %edi
21951 + xorl %esi, %eax
21952 +
21953 + roll $12, %edi
21954 + movl %edi, %esi
21955 + xorl %eax, %edi
21956 + andl $0xf0f0f0f0, %edi
21957 + xorl %edi, %esi
21958 + xorl %edi, %eax
21959 +
21960 + rorl $4, %eax
21961 + movl %eax, (%ebx)
21962 + movl %esi, 4(%ebx)
21963 + popl %edi
21964 + popl %esi
21965 + popl %ebp
21966 + popl %ebx
21967 + ret
21968 +.des_encrypt3_end:
21969 + .size des_encrypt3 , .des_encrypt3_end-des_encrypt3
21970 +.ident "desasm.pl"
21971 +.text
21972 + .align 16
21973 +.globl des_decrypt3
21974 + .type des_decrypt3 , @function
21975 +des_decrypt3:
21976 + pushl %ebx
21977 + movl 8(%esp), %ebx
21978 + pushl %ebp
21979 + pushl %esi
21980 + pushl %edi
21981 +
21982 +
21983 + movl (%ebx), %edi
21984 + movl 4(%ebx), %esi
21985 + subl $12, %esp
21986 +
21987 +
21988 + roll $4, %edi
21989 + movl %edi, %edx
21990 + xorl %esi, %edi
21991 + andl $0xf0f0f0f0, %edi
21992 + xorl %edi, %edx
21993 + xorl %edi, %esi
21994 +
21995 + roll $20, %esi
21996 + movl %esi, %edi
21997 + xorl %edx, %esi
21998 + andl $0xfff0000f, %esi
21999 + xorl %esi, %edi
22000 + xorl %esi, %edx
22001 +
22002 + roll $14, %edi
22003 + movl %edi, %esi
22004 + xorl %edx, %edi
22005 + andl $0x33333333, %edi
22006 + xorl %edi, %esi
22007 + xorl %edi, %edx
22008 +
22009 + roll $22, %edx
22010 + movl %edx, %edi
22011 + xorl %esi, %edx
22012 + andl $0x03fc03fc, %edx
22013 + xorl %edx, %edi
22014 + xorl %edx, %esi
22015 +
22016 + roll $9, %edi
22017 + movl %edi, %edx
22018 + xorl %esi, %edi
22019 + andl $0xaaaaaaaa, %edi
22020 + xorl %edi, %edx
22021 + xorl %edi, %esi
22022 +
22023 + rorl $3, %edx
22024 + rorl $2, %esi
22025 + movl %esi, 4(%ebx)
22026 + movl 36(%esp), %esi
22027 + movl %edx, (%ebx)
22028 + movl 40(%esp), %edi
22029 + movl 44(%esp), %eax
22030 + movl $0, 8(%esp)
22031 + movl %eax, 4(%esp)
22032 + movl %ebx, (%esp)
22033 + call des_encrypt2
22034 + movl $1, 8(%esp)
22035 + movl %edi, 4(%esp)
22036 + movl %ebx, (%esp)
22037 + call des_encrypt2
22038 + movl $0, 8(%esp)
22039 + movl %esi, 4(%esp)
22040 + movl %ebx, (%esp)
22041 + call des_encrypt2
22042 + addl $12, %esp
22043 + movl (%ebx), %edi
22044 + movl 4(%ebx), %esi
22045 +
22046 +
22047 + roll $2, %esi
22048 + roll $3, %edi
22049 + movl %edi, %eax
22050 + xorl %esi, %edi
22051 + andl $0xaaaaaaaa, %edi
22052 + xorl %edi, %eax
22053 + xorl %edi, %esi
22054 +
22055 + roll $23, %eax
22056 + movl %eax, %edi
22057 + xorl %esi, %eax
22058 + andl $0x03fc03fc, %eax
22059 + xorl %eax, %edi
22060 + xorl %eax, %esi
22061 +
22062 + roll $10, %edi
22063 + movl %edi, %eax
22064 + xorl %esi, %edi
22065 + andl $0x33333333, %edi
22066 + xorl %edi, %eax
22067 + xorl %edi, %esi
22068 +
22069 + roll $18, %esi
22070 + movl %esi, %edi
22071 + xorl %eax, %esi
22072 + andl $0xfff0000f, %esi
22073 + xorl %esi, %edi
22074 + xorl %esi, %eax
22075 +
22076 + roll $12, %edi
22077 + movl %edi, %esi
22078 + xorl %eax, %edi
22079 + andl $0xf0f0f0f0, %edi
22080 + xorl %edi, %esi
22081 + xorl %edi, %eax
22082 +
22083 + rorl $4, %eax
22084 + movl %eax, (%ebx)
22085 + movl %esi, 4(%ebx)
22086 + popl %edi
22087 + popl %esi
22088 + popl %ebp
22089 + popl %ebx
22090 + ret
22091 +.des_decrypt3_end:
22092 + .size des_decrypt3 , .des_decrypt3_end-des_decrypt3
22093 +.ident "desasm.pl"
22094 +.text
22095 + .align 16
22096 +.globl des_ncbc_encrypt
22097 + .type des_ncbc_encrypt , @function
22098 +des_ncbc_encrypt:
22099 +
22100 + pushl %ebp
22101 + pushl %ebx
22102 + pushl %esi
22103 + pushl %edi
22104 + movl 28(%esp), %ebp
22105 +
22106 + movl 36(%esp), %ebx
22107 + movl (%ebx), %esi
22108 + movl 4(%ebx), %edi
22109 + pushl %edi
22110 + pushl %esi
22111 + pushl %edi
22112 + pushl %esi
22113 + movl %esp, %ebx
22114 + movl 36(%esp), %esi
22115 + movl 40(%esp), %edi
22116 +
22117 + movl 56(%esp), %ecx
22118 +
22119 + pushl %ecx
22120 +
22121 + movl 52(%esp), %eax
22122 + pushl %eax
22123 + pushl %ebx
22124 + cmpl $0, %ecx
22125 + jz .L004decrypt
22126 + andl $4294967288, %ebp
22127 + movl 12(%esp), %eax
22128 + movl 16(%esp), %ebx
22129 + jz .L005encrypt_finish
22130 +.L006encrypt_loop:
22131 + movl (%esi), %ecx
22132 + movl 4(%esi), %edx
22133 + xorl %ecx, %eax
22134 + xorl %edx, %ebx
22135 + movl %eax, 12(%esp)
22136 + movl %ebx, 16(%esp)
22137 + call des_encrypt
22138 + movl 12(%esp), %eax
22139 + movl 16(%esp), %ebx
22140 + movl %eax, (%edi)
22141 + movl %ebx, 4(%edi)
22142 + addl $8, %esi
22143 + addl $8, %edi
22144 + subl $8, %ebp
22145 + jnz .L006encrypt_loop
22146 +.L005encrypt_finish:
22147 + movl 56(%esp), %ebp
22148 + andl $7, %ebp
22149 + jz .L007finish
22150 + xorl %ecx, %ecx
22151 + xorl %edx, %edx
22152 + movl .L008cbc_enc_jmp_table(,%ebp,4),%ebp
22153 + jmp *%ebp
22154 +.L009ej7:
22155 + movb 6(%esi), %dh
22156 + sall $8, %edx
22157 +.L010ej6:
22158 + movb 5(%esi), %dh
22159 +.L011ej5:
22160 + movb 4(%esi), %dl
22161 +.L012ej4:
22162 + movl (%esi), %ecx
22163 + jmp .L013ejend
22164 +.L014ej3:
22165 + movb 2(%esi), %ch
22166 + sall $8, %ecx
22167 +.L015ej2:
22168 + movb 1(%esi), %ch
22169 +.L016ej1:
22170 + movb (%esi), %cl
22171 +.L013ejend:
22172 + xorl %ecx, %eax
22173 + xorl %edx, %ebx
22174 + movl %eax, 12(%esp)
22175 + movl %ebx, 16(%esp)
22176 + call des_encrypt
22177 + movl 12(%esp), %eax
22178 + movl 16(%esp), %ebx
22179 + movl %eax, (%edi)
22180 + movl %ebx, 4(%edi)
22181 + jmp .L007finish
22182 +.align 16
22183 +.L004decrypt:
22184 + andl $4294967288, %ebp
22185 + movl 20(%esp), %eax
22186 + movl 24(%esp), %ebx
22187 + jz .L017decrypt_finish
22188 +.L018decrypt_loop:
22189 + movl (%esi), %eax
22190 + movl 4(%esi), %ebx
22191 + movl %eax, 12(%esp)
22192 + movl %ebx, 16(%esp)
22193 + call des_encrypt
22194 + movl 12(%esp), %eax
22195 + movl 16(%esp), %ebx
22196 + movl 20(%esp), %ecx
22197 + movl 24(%esp), %edx
22198 + xorl %eax, %ecx
22199 + xorl %ebx, %edx
22200 + movl (%esi), %eax
22201 + movl 4(%esi), %ebx
22202 + movl %ecx, (%edi)
22203 + movl %edx, 4(%edi)
22204 + movl %eax, 20(%esp)
22205 + movl %ebx, 24(%esp)
22206 + addl $8, %esi
22207 + addl $8, %edi
22208 + subl $8, %ebp
22209 + jnz .L018decrypt_loop
22210 +.L017decrypt_finish:
22211 + movl 56(%esp), %ebp
22212 + andl $7, %ebp
22213 + jz .L007finish
22214 + movl (%esi), %eax
22215 + movl 4(%esi), %ebx
22216 + movl %eax, 12(%esp)
22217 + movl %ebx, 16(%esp)
22218 + call des_encrypt
22219 + movl 12(%esp), %eax
22220 + movl 16(%esp), %ebx
22221 + movl 20(%esp), %ecx
22222 + movl 24(%esp), %edx
22223 + xorl %eax, %ecx
22224 + xorl %ebx, %edx
22225 + movl (%esi), %eax
22226 + movl 4(%esi), %ebx
22227 +.L019dj7:
22228 + rorl $16, %edx
22229 + movb %dl, 6(%edi)
22230 + shrl $16, %edx
22231 +.L020dj6:
22232 + movb %dh, 5(%edi)
22233 +.L021dj5:
22234 + movb %dl, 4(%edi)
22235 +.L022dj4:
22236 + movl %ecx, (%edi)
22237 + jmp .L023djend
22238 +.L024dj3:
22239 + rorl $16, %ecx
22240 + movb %cl, 2(%edi)
22241 + sall $16, %ecx
22242 +.L025dj2:
22243 + movb %ch, 1(%esi)
22244 +.L026dj1:
22245 + movb %cl, (%esi)
22246 +.L023djend:
22247 + jmp .L007finish
22248 +.align 16
22249 +.L007finish:
22250 + movl 64(%esp), %ecx
22251 + addl $28, %esp
22252 + movl %eax, (%ecx)
22253 + movl %ebx, 4(%ecx)
22254 + popl %edi
22255 + popl %esi
22256 + popl %ebx
22257 + popl %ebp
22258 + ret
22259 +.align 16
22260 +.L008cbc_enc_jmp_table:
22261 + .long 0
22262 + .long .L016ej1
22263 + .long .L015ej2
22264 + .long .L014ej3
22265 + .long .L012ej4
22266 + .long .L011ej5
22267 + .long .L010ej6
22268 + .long .L009ej7
22269 +.align 16
22270 +.L027cbc_dec_jmp_table:
22271 + .long 0
22272 + .long .L026dj1
22273 + .long .L025dj2
22274 + .long .L024dj3
22275 + .long .L022dj4
22276 + .long .L021dj5
22277 + .long .L020dj6
22278 + .long .L019dj7
22279 +.des_ncbc_encrypt_end:
22280 + .size des_ncbc_encrypt , .des_ncbc_encrypt_end-des_ncbc_encrypt
22281 +.ident "desasm.pl"
22282 +.text
22283 + .align 16
22284 +.globl des_ede3_cbc_encrypt
22285 + .type des_ede3_cbc_encrypt , @function
22286 +des_ede3_cbc_encrypt:
22287 +
22288 + pushl %ebp
22289 + pushl %ebx
22290 + pushl %esi
22291 + pushl %edi
22292 + movl 28(%esp), %ebp
22293 +
22294 + movl 44(%esp), %ebx
22295 + movl (%ebx), %esi
22296 + movl 4(%ebx), %edi
22297 + pushl %edi
22298 + pushl %esi
22299 + pushl %edi
22300 + pushl %esi
22301 + movl %esp, %ebx
22302 + movl 36(%esp), %esi
22303 + movl 40(%esp), %edi
22304 +
22305 + movl 64(%esp), %ecx
22306 +
22307 + movl 56(%esp), %eax
22308 + pushl %eax
22309 +
22310 + movl 56(%esp), %eax
22311 + pushl %eax
22312 +
22313 + movl 56(%esp), %eax
22314 + pushl %eax
22315 + pushl %ebx
22316 + cmpl $0, %ecx
22317 + jz .L028decrypt
22318 + andl $4294967288, %ebp
22319 + movl 16(%esp), %eax
22320 + movl 20(%esp), %ebx
22321 + jz .L029encrypt_finish
22322 +.L030encrypt_loop:
22323 + movl (%esi), %ecx
22324 + movl 4(%esi), %edx
22325 + xorl %ecx, %eax
22326 + xorl %edx, %ebx
22327 + movl %eax, 16(%esp)
22328 + movl %ebx, 20(%esp)
22329 + call des_encrypt3
22330 + movl 16(%esp), %eax
22331 + movl 20(%esp), %ebx
22332 + movl %eax, (%edi)
22333 + movl %ebx, 4(%edi)
22334 + addl $8, %esi
22335 + addl $8, %edi
22336 + subl $8, %ebp
22337 + jnz .L030encrypt_loop
22338 +.L029encrypt_finish:
22339 + movl 60(%esp), %ebp
22340 + andl $7, %ebp
22341 + jz .L031finish
22342 + xorl %ecx, %ecx
22343 + xorl %edx, %edx
22344 + movl .L032cbc_enc_jmp_table(,%ebp,4),%ebp
22345 + jmp *%ebp
22346 +.L033ej7:
22347 + movb 6(%esi), %dh
22348 + sall $8, %edx
22349 +.L034ej6:
22350 + movb 5(%esi), %dh
22351 +.L035ej5:
22352 + movb 4(%esi), %dl
22353 +.L036ej4:
22354 + movl (%esi), %ecx
22355 + jmp .L037ejend
22356 +.L038ej3:
22357 + movb 2(%esi), %ch
22358 + sall $8, %ecx
22359 +.L039ej2:
22360 + movb 1(%esi), %ch
22361 +.L040ej1:
22362 + movb (%esi), %cl
22363 +.L037ejend:
22364 + xorl %ecx, %eax
22365 + xorl %edx, %ebx
22366 + movl %eax, 16(%esp)
22367 + movl %ebx, 20(%esp)
22368 + call des_encrypt3
22369 + movl 16(%esp), %eax
22370 + movl 20(%esp), %ebx
22371 + movl %eax, (%edi)
22372 + movl %ebx, 4(%edi)
22373 + jmp .L031finish
22374 +.align 16
22375 +.L028decrypt:
22376 + andl $4294967288, %ebp
22377 + movl 24(%esp), %eax
22378 + movl 28(%esp), %ebx
22379 + jz .L041decrypt_finish
22380 +.L042decrypt_loop:
22381 + movl (%esi), %eax
22382 + movl 4(%esi), %ebx
22383 + movl %eax, 16(%esp)
22384 + movl %ebx, 20(%esp)
22385 + call des_decrypt3
22386 + movl 16(%esp), %eax
22387 + movl 20(%esp), %ebx
22388 + movl 24(%esp), %ecx
22389 + movl 28(%esp), %edx
22390 + xorl %eax, %ecx
22391 + xorl %ebx, %edx
22392 + movl (%esi), %eax
22393 + movl 4(%esi), %ebx
22394 + movl %ecx, (%edi)
22395 + movl %edx, 4(%edi)
22396 + movl %eax, 24(%esp)
22397 + movl %ebx, 28(%esp)
22398 + addl $8, %esi
22399 + addl $8, %edi
22400 + subl $8, %ebp
22401 + jnz .L042decrypt_loop
22402 +.L041decrypt_finish:
22403 + movl 60(%esp), %ebp
22404 + andl $7, %ebp
22405 + jz .L031finish
22406 + movl (%esi), %eax
22407 + movl 4(%esi), %ebx
22408 + movl %eax, 16(%esp)
22409 + movl %ebx, 20(%esp)
22410 + call des_decrypt3
22411 + movl 16(%esp), %eax
22412 + movl 20(%esp), %ebx
22413 + movl 24(%esp), %ecx
22414 + movl 28(%esp), %edx
22415 + xorl %eax, %ecx
22416 + xorl %ebx, %edx
22417 + movl (%esi), %eax
22418 + movl 4(%esi), %ebx
22419 +.L043dj7:
22420 + rorl $16, %edx
22421 + movb %dl, 6(%edi)
22422 + shrl $16, %edx
22423 +.L044dj6:
22424 + movb %dh, 5(%edi)
22425 +.L045dj5:
22426 + movb %dl, 4(%edi)
22427 +.L046dj4:
22428 + movl %ecx, (%edi)
22429 + jmp .L047djend
22430 +.L048dj3:
22431 + rorl $16, %ecx
22432 + movb %cl, 2(%edi)
22433 + sall $16, %ecx
22434 +.L049dj2:
22435 + movb %ch, 1(%esi)
22436 +.L050dj1:
22437 + movb %cl, (%esi)
22438 +.L047djend:
22439 + jmp .L031finish
22440 +.align 16
22441 +.L031finish:
22442 + movl 76(%esp), %ecx
22443 + addl $32, %esp
22444 + movl %eax, (%ecx)
22445 + movl %ebx, 4(%ecx)
22446 + popl %edi
22447 + popl %esi
22448 + popl %ebx
22449 + popl %ebp
22450 + ret
22451 +.align 16
22452 +.L032cbc_enc_jmp_table:
22453 + .long 0
22454 + .long .L040ej1
22455 + .long .L039ej2
22456 + .long .L038ej3
22457 + .long .L036ej4
22458 + .long .L035ej5
22459 + .long .L034ej6
22460 + .long .L033ej7
22461 +.align 16
22462 +.L051cbc_dec_jmp_table:
22463 + .long 0
22464 + .long .L050dj1
22465 + .long .L049dj2
22466 + .long .L048dj3
22467 + .long .L046dj4
22468 + .long .L045dj5
22469 + .long .L044dj6
22470 + .long .L043dj7
22471 +.des_ede3_cbc_encrypt_end:
22472 + .size des_ede3_cbc_encrypt , .des_ede3_cbc_encrypt_end-des_ede3_cbc_encrypt
22473 +.ident "desasm.pl"
22474 --- /dev/null Tue Mar 11 13:02:56 2003
22475 +++ linux/net/ipsec/des/ecb_enc.c Mon Feb 9 13:51:03 2004
22476 @@ -0,0 +1,128 @@
22477 +/* crypto/des/ecb_enc.c */
22478 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
22479 + * All rights reserved.
22480 + *
22481 + * This package is an SSL implementation written
22482 + * by Eric Young (eay@cryptsoft.com).
22483 + * The implementation was written so as to conform with Netscapes SSL.
22484 + *
22485 + * This library is free for commercial and non-commercial use as long as
22486 + * the following conditions are aheared to. The following conditions
22487 + * apply to all code found in this distribution, be it the RC4, RSA,
22488 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
22489 + * included with this distribution is covered by the same copyright terms
22490 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
22491 + *
22492 + * Copyright remains Eric Young's, and as such any Copyright notices in
22493 + * the code are not to be removed.
22494 + * If this package is used in a product, Eric Young should be given attribution
22495 + * as the author of the parts of the library used.
22496 + * This can be in the form of a textual message at program startup or
22497 + * in documentation (online or textual) provided with the package.
22498 + *
22499 + * Redistribution and use in source and binary forms, with or without
22500 + * modification, are permitted provided that the following conditions
22501 + * are met:
22502 + * 1. Redistributions of source code must retain the copyright
22503 + * notice, this list of conditions and the following disclaimer.
22504 + * 2. Redistributions in binary form must reproduce the above copyright
22505 + * notice, this list of conditions and the following disclaimer in the
22506 + * documentation and/or other materials provided with the distribution.
22507 + * 3. All advertising materials mentioning features or use of this software
22508 + * must display the following acknowledgement:
22509 + * "This product includes cryptographic software written by
22510 + * Eric Young (eay@cryptsoft.com)"
22511 + * The word 'cryptographic' can be left out if the rouines from the library
22512 + * being used are not cryptographic related :-).
22513 + * 4. If you include any Windows specific code (or a derivative thereof) from
22514 + * the apps directory (application code) you must include an acknowledgement:
22515 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
22516 + *
22517 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
22518 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22519 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22520 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22521 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22522 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22523 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22524 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22525 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22526 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22527 + * SUCH DAMAGE.
22528 + *
22529 + * The licence and distribution terms for any publically available version or
22530 + * derivative of this code cannot be changed. i.e. this code cannot simply be
22531 + * copied and put under another distribution licence
22532 + * [including the GNU Public Licence.]
22533 + */
22534 +
22535 +#include "des/des_locl.h"
22536 +#include "des/spr.h"
22537 +
22538 +char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay";
22539 +char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998";
22540 +
22541 +/* RCSID $Id: ecb_enc.c,v 1.8 2004/08/04 15:57:22 mcr Exp $ */
22542 +/* This function ifdef'ed out for FreeS/WAN project. */
22543 +#ifdef notdef
22544 +char *des_options()
22545 + {
22546 + static int init=1;
22547 + static char buf[32];
22548 +
22549 + if (init)
22550 + {
22551 + char *ptr,*unroll,*risc,*size;
22552 +
22553 + init=0;
22554 +#ifdef DES_PTR
22555 + ptr="ptr";
22556 +#else
22557 + ptr="idx";
22558 +#endif
22559 +#if defined(DES_RISC1) || defined(DES_RISC2)
22560 +#ifdef DES_RISC1
22561 + risc="risc1";
22562 +#endif
22563 +#ifdef DES_RISC2
22564 + risc="risc2";
22565 +#endif
22566 +#else
22567 + risc="cisc";
22568 +#endif
22569 +#ifdef DES_UNROLL
22570 + unroll="16";
22571 +#else
22572 + unroll="4";
22573 +#endif
22574 + if (sizeof(DES_LONG) != sizeof(long))
22575 + size="int";
22576 + else
22577 + size="long";
22578 + sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);
22579 + }
22580 + return(buf);
22581 + }
22582 +#endif
22583 +
22584 +
22585 +void des_ecb_encrypt(input, output, ks, enc)
22586 +des_cblock (*input);
22587 +des_cblock (*output);
22588 +des_key_schedule ks;
22589 +int enc;
22590 + {
22591 + register DES_LONG l;
22592 + register unsigned char *in,*out;
22593 + DES_LONG ll[2];
22594 +
22595 + in=(unsigned char *)input;
22596 + out=(unsigned char *)output;
22597 + c2l(in,l); ll[0]=l;
22598 + c2l(in,l); ll[1]=l;
22599 + des_encrypt(ll,ks,enc);
22600 + l=ll[0]; l2c(l,out);
22601 + l=ll[1]; l2c(l,out);
22602 + l=ll[0]=ll[1]=0;
22603 + }
22604 +
22605 --- /dev/null Tue Mar 11 13:02:56 2003
22606 +++ linux/net/ipsec/des/ipsec_alg_3des.c Mon Feb 9 13:51:03 2004
22607 @@ -0,0 +1,182 @@
22608 +/*
22609 + * ipsec_alg 3DES cipher stubs
22610 + *
22611 + * Copyright (C) 2005 Michael Richardson <mcr@xelerance.com>
22612 + *
22613 + * Adapted from ipsec_alg_aes.c by JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
22614 + *
22615 + * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
22616 + *
22617 + * This program is free software; you can redistribute it and/or modify it
22618 + * under the terms of the GNU General Public License as published by the
22619 + * Free Software Foundation; either version 2 of the License, or (at your
22620 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
22621 + *
22622 + * This program is distributed in the hope that it will be useful, but
22623 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22624 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22625 + * for more details.
22626 + *
22627 + */
22628 +#ifndef AUTOCONF_INCLUDED
22629 +#include <linux/config.h>
22630 +#endif
22631 +#include <linux/version.h>
22632 +
22633 +/*
22634 + * special case: ipsec core modular with this static algo inside:
22635 + * must avoid MODULE magic for this file
22636 + */
22637 +#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_3DES)
22638 +#undef MODULE
22639 +#endif
22640 +
22641 +#include <linux/module.h>
22642 +#include <linux/init.h>
22643 +
22644 +#include <linux/kernel.h> /* printk() */
22645 +#include <linux/errno.h> /* error codes */
22646 +#include <linux/types.h> /* size_t */
22647 +#include <linux/string.h>
22648 +
22649 +/* Low freeswan header coupling */
22650 +#include "openswan/ipsec_xform.h"
22651 +#include "openswan/ipsec_alg.h"
22652 +#include "crypto/des.h"
22653 +#include "openswan/ipsec_alg_3des.h"
22654 +
22655 +#define AES_CONTEXT_T aes_context
22656 +static int debug_3des=0;
22657 +static int test_3des=0;
22658 +static int excl_3des=0;
22659 +
22660 +#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
22661 +MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
22662 +#ifdef module_param
22663 +module_param(debug_3des, int, 0664);
22664 +module_param(test_des, int, 0664);
22665 +module_param(excl_des, int, 0664);
22666 +#else
22667 +MODULE_PARM(debug_3des, "i");
22668 +MODULE_PARM(test_des, "i");
22669 +MODULE_PARM(excl_des, "i");
22670 +#endif
22671 +#endif
22672 +
22673 +#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
22674 +#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
22675 +
22676 +static int _3des_set_key(struct ipsec_alg_enc *alg,
22677 + __u8 * key_e, const __u8 * key,
22678 + size_t keysize)
22679 +{
22680 + int ret = 0;
22681 + TripleDES_context *ctx = (TripleDES_context*)key_e;
22682 +
22683 + if(keysize != 192/8) {
22684 + return EINVAL;
22685 + }
22686 +
22687 + des_set_key((des_cblock *)(key + DES_KEY_SZ*0), ctx->s1);
22688 + des_set_key((des_cblock *)(key + DES_KEY_SZ*1), ctx->s2);
22689 + des_set_key((des_cblock *)(key + DES_KEY_SZ*2), ctx->s3);
22690 +
22691 + if (debug_3des > 0)
22692 + printk(KERN_DEBUG "klips_debug:_3des_set_key:"
22693 + "ret=%d key_e=%p key=%p keysize=%ld\n",
22694 + ret, key_e, key, (unsigned long int) keysize);
22695 + return ret;
22696 +}
22697 +
22698 +static int _3des_cbc_encrypt(struct ipsec_alg_enc *alg,
22699 + __u8 * key_e,
22700 + __u8 * in,
22701 + int ilen, const __u8 * iv,
22702 + int encrypt)
22703 +{
22704 + TripleDES_context *ctx=(TripleDES_context*)key_e;
22705 + des_cblock miv;
22706 +
22707 + memcpy(&miv, iv, sizeof(miv));
22708 +
22709 + if (debug_3des > 0)
22710 + printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
22711 + "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
22712 + key_e, in, ilen, iv, encrypt);
22713 +
22714 + des_ede3_cbc_encrypt((des_cblock *)in,
22715 + (des_cblock *)in,
22716 + ilen,
22717 + ctx->s1,
22718 + ctx->s2,
22719 + ctx->s3,
22720 + &miv, encrypt);
22721 + return 1;
22722 +}
22723 +
22724 +static struct ipsec_alg_enc ipsec_alg_3DES = {
22725 + ixt_common: { ixt_version: IPSEC_ALG_VERSION,
22726 + ixt_refcnt: ATOMIC_INIT(0),
22727 + ixt_name: "3des",
22728 + ixt_blocksize: ESP_3DES_CBC_BLK_LEN,
22729 + ixt_support: {
22730 + ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
22731 + ias_id: ESP_3DES,
22732 + //ias_ivlen: 64,
22733 + ias_keyminbits: ESP_3DES_KEY_SZ*8,
22734 + ias_keymaxbits: ESP_3DES_KEY_SZ*8,
22735 + },
22736 + },
22737 +#if defined(MODULE_KLIPS_ENC_3DES_MODULE)
22738 + ixt_module: THIS_MODULE,
22739 +#endif
22740 + ixt_e_keylen: ESP_3DES_KEY_SZ*8,
22741 + ixt_e_ctx_size: sizeof(TripleDES_context),
22742 + ixt_e_set_key: _3des_set_key,
22743 + ixt_e_cbc_encrypt:_3des_cbc_encrypt,
22744 +};
22745 +
22746 +#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
22747 +IPSEC_ALG_MODULE_INIT_MOD( ipsec_3des_init )
22748 +#else
22749 +IPSEC_ALG_MODULE_INIT_STATIC( ipsec_3des_init )
22750 +#endif
22751 +{
22752 + int ret, test_ret;
22753 +
22754 + if (excl_3des) ipsec_alg_3DES.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
22755 + ret=register_ipsec_alg_enc(&ipsec_alg_3DES);
22756 + printk("ipsec_3des_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
22757 + ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
22758 + ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
22759 + ipsec_alg_3DES.ixt_common.ixt_name,
22760 + ret);
22761 + if (ret==0 && test_3des) {
22762 + test_ret=ipsec_alg_test(
22763 + ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
22764 + ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
22765 + test_3des);
22766 + printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
22767 + ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
22768 + ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
22769 + test_ret);
22770 + }
22771 + return ret;
22772 +}
22773 +
22774 +#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
22775 +IPSEC_ALG_MODULE_EXIT_MOD( ipsec_3des_fini )
22776 +#else
22777 +IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_3des_fini )
22778 +#endif
22779 +{
22780 + unregister_ipsec_alg_enc(&ipsec_alg_3DES);
22781 + return;
22782 +}
22783 +
22784 +/* Dual, because 3des code is 4-clause BSD licensed */
22785 +#ifdef MODULE_LICENSE
22786 +MODULE_LICENSE("Dual BSD/GPL");
22787 +#endif
22788 +
22789 +
22790 --- /dev/null Tue Mar 11 13:02:56 2003
22791 +++ linux/net/ipsec/des/set_key.c Mon Feb 9 13:51:03 2004
22792 @@ -0,0 +1,246 @@
22793 +/* crypto/des/set_key.c */
22794 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
22795 + * All rights reserved.
22796 + *
22797 + * This package is an SSL implementation written
22798 + * by Eric Young (eay@cryptsoft.com).
22799 + * The implementation was written so as to conform with Netscapes SSL.
22800 + *
22801 + * This library is free for commercial and non-commercial use as long as
22802 + * the following conditions are aheared to. The following conditions
22803 + * apply to all code found in this distribution, be it the RC4, RSA,
22804 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
22805 + * included with this distribution is covered by the same copyright terms
22806 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
22807 + *
22808 + * Copyright remains Eric Young's, and as such any Copyright notices in
22809 + * the code are not to be removed.
22810 + * If this package is used in a product, Eric Young should be given attribution
22811 + * as the author of the parts of the library used.
22812 + * This can be in the form of a textual message at program startup or
22813 + * in documentation (online or textual) provided with the package.
22814 + *
22815 + * Redistribution and use in source and binary forms, with or without
22816 + * modification, are permitted provided that the following conditions
22817 + * are met:
22818 + * 1. Redistributions of source code must retain the copyright
22819 + * notice, this list of conditions and the following disclaimer.
22820 + * 2. Redistributions in binary form must reproduce the above copyright
22821 + * notice, this list of conditions and the following disclaimer in the
22822 + * documentation and/or other materials provided with the distribution.
22823 + * 3. All advertising materials mentioning features or use of this software
22824 + * must display the following acknowledgement:
22825 + * "This product includes cryptographic software written by
22826 + * Eric Young (eay@cryptsoft.com)"
22827 + * The word 'cryptographic' can be left out if the rouines from the library
22828 + * being used are not cryptographic related :-).
22829 + * 4. If you include any Windows specific code (or a derivative thereof) from
22830 + * the apps directory (application code) you must include an acknowledgement:
22831 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
22832 + *
22833 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
22834 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22835 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22836 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22837 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22838 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22839 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22840 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22841 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22842 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22843 + * SUCH DAMAGE.
22844 + *
22845 + * The licence and distribution terms for any publically available version or
22846 + * derivative of this code cannot be changed. i.e. this code cannot simply be
22847 + * copied and put under another distribution licence
22848 + * [including the GNU Public Licence.]
22849 + */
22850 +
22851 +/* set_key.c v 1.4 eay 24/9/91
22852 + * 1.4 Speed up by 400% :-)
22853 + * 1.3 added register declarations.
22854 + * 1.2 unrolled make_key_sched a bit more
22855 + * 1.1 added norm_expand_bits
22856 + * 1.0 First working version
22857 + */
22858 +#include "des/des_locl.h"
22859 +#include "des/podd.h"
22860 +#include "des/sk.h"
22861 +
22862 +#ifndef NOPROTO
22863 +static int check_parity(des_cblock (*key));
22864 +#else
22865 +static int check_parity();
22866 +#endif
22867 +
22868 +int des_check_key=0;
22869 +
22870 +void des_set_odd_parity(key)
22871 +des_cblock (*key);
22872 + {
22873 + int i;
22874 +
22875 + for (i=0; i<DES_KEY_SZ; i++)
22876 + (*key)[i]=odd_parity[(*key)[i]];
22877 + }
22878 +
22879 +static int check_parity(key)
22880 +des_cblock (*key);
22881 + {
22882 + int i;
22883 +
22884 + for (i=0; i<DES_KEY_SZ; i++)
22885 + {
22886 + if ((*key)[i] != odd_parity[(*key)[i]])
22887 + return(0);
22888 + }
22889 + return(1);
22890 + }
22891 +
22892 +/* Weak and semi week keys as take from
22893 + * %A D.W. Davies
22894 + * %A W.L. Price
22895 + * %T Security for Computer Networks
22896 + * %I John Wiley & Sons
22897 + * %D 1984
22898 + * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
22899 + * (and actual cblock values).
22900 + */
22901 +#define NUM_WEAK_KEY 16
22902 +static des_cblock weak_keys[NUM_WEAK_KEY]={
22903 + /* weak keys */
22904 + {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
22905 + {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
22906 + {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
22907 + {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
22908 + /* semi-weak keys */
22909 + {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
22910 + {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
22911 + {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
22912 + {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
22913 + {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
22914 + {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
22915 + {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
22916 + {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
22917 + {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
22918 + {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
22919 + {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
22920 + {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
22921 +
22922 +int des_is_weak_key(key)
22923 +des_cblock (*key);
22924 + {
22925 + int i;
22926 +
22927 + for (i=0; i<NUM_WEAK_KEY; i++)
22928 + /* Added == 0 to comparision, I obviously don't run
22929 + * this section very often :-(, thanks to
22930 + * engineering@MorningStar.Com for the fix
22931 + * eay 93/06/29
22932 + * Another problem, I was comparing only the first 4
22933 + * bytes, 97/03/18 */
22934 + if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1);
22935 + return(0);
22936 + }
22937 +
22938 +/* NOW DEFINED IN des_local.h
22939 + * See ecb_encrypt.c for a pseudo description of these macros.
22940 + * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
22941 + * (b)^=(t),\
22942 + * (a)=((a)^((t)<<(n))))
22943 + */
22944 +
22945 +#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
22946 + (a)=(a)^(t)^(t>>(16-(n))))
22947 +
22948 +/* return 0 if key parity is odd (correct),
22949 + * return -1 if key parity error,
22950 + * return -2 if illegal weak key.
22951 + */
22952 +int des_set_key(key, schedule)
22953 +des_cblock (*key);
22954 +des_key_schedule schedule;
22955 + {
22956 + static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
22957 + register DES_LONG c,d,t,s,t2;
22958 + register unsigned char *in;
22959 + register DES_LONG *k;
22960 + register int i;
22961 +
22962 + if (des_check_key)
22963 + {
22964 + if (!check_parity(key))
22965 + return(-1);
22966 +
22967 + if (des_is_weak_key(key))
22968 + return(-2);
22969 + }
22970 +
22971 + k=(DES_LONG *)schedule;
22972 + in=(unsigned char *)key;
22973 +
22974 + c2l(in,c);
22975 + c2l(in,d);
22976 +
22977 + /* do PC1 in 60 simple operations */
22978 +/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
22979 + HPERM_OP(c,t,-2, 0xcccc0000L);
22980 + HPERM_OP(c,t,-1, 0xaaaa0000L);
22981 + HPERM_OP(c,t, 8, 0x00ff0000L);
22982 + HPERM_OP(c,t,-1, 0xaaaa0000L);
22983 + HPERM_OP(d,t,-8, 0xff000000L);
22984 + HPERM_OP(d,t, 8, 0x00ff0000L);
22985 + HPERM_OP(d,t, 2, 0x33330000L);
22986 + d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
22987 + d=(d>>8)|((c&0xf0000000L)>>4);
22988 + c&=0x0fffffffL; */
22989 +
22990 + /* I now do it in 47 simple operations :-)
22991 + * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
22992 + * for the inspiration. :-) */
22993 + PERM_OP (d,c,t,4,0x0f0f0f0fL);
22994 + HPERM_OP(c,t,-2,0xcccc0000L);
22995 + HPERM_OP(d,t,-2,0xcccc0000L);
22996 + PERM_OP (d,c,t,1,0x55555555L);
22997 + PERM_OP (c,d,t,8,0x00ff00ffL);
22998 + PERM_OP (d,c,t,1,0x55555555L);
22999 + d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
23000 + ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
23001 + c&=0x0fffffffL;
23002 +
23003 + for (i=0; i<ITERATIONS; i++)
23004 + {
23005 + if (shifts2[i])
23006 + { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
23007 + else
23008 + { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
23009 + c&=0x0fffffffL;
23010 + d&=0x0fffffffL;
23011 + /* could be a few less shifts but I am to lazy at this
23012 + * point in time to investigate */
23013 + s= des_skb[0][ (c )&0x3f ]|
23014 + des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
23015 + des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
23016 + des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
23017 + ((c>>22L)&0x38)];
23018 + t= des_skb[4][ (d )&0x3f ]|
23019 + des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
23020 + des_skb[6][ (d>>15L)&0x3f ]|
23021 + des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
23022 +
23023 + /* table contained 0213 4657 */
23024 + t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
23025 + *(k++)=ROTATE(t2,30)&0xffffffffL;
23026 +
23027 + t2=((s>>16L)|(t&0xffff0000L));
23028 + *(k++)=ROTATE(t2,26)&0xffffffffL;
23029 + }
23030 + return(0);
23031 + }
23032 +
23033 +int des_key_sched(key, schedule)
23034 +des_cblock (*key);
23035 +des_key_schedule schedule;
23036 + {
23037 + return(des_set_key(key,schedule));
23038 + }
23039 --- /dev/null Tue Mar 11 13:02:56 2003
23040 +++ linux/net/ipsec/goodmask.c Mon Feb 9 13:51:03 2004
23041 @@ -0,0 +1,100 @@
23042 +/*
23043 + * minor utilities for subnet-mask manipulation
23044 + * Copyright (C) 1998, 1999 Henry Spencer.
23045 + *
23046 + * This library is free software; you can redistribute it and/or modify it
23047 + * under the terms of the GNU Library General Public License as published by
23048 + * the Free Software Foundation; either version 2 of the License, or (at your
23049 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
23050 + *
23051 + * This library is distributed in the hope that it will be useful, but
23052 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23053 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
23054 + * License for more details.
23055 + *
23056 + * RCSID $Id: goodmask.c,v 1.12 2004/07/10 07:43:47 mcr Exp $
23057 + */
23058 +#include "openswan.h"
23059 +
23060 +#ifndef ABITS
23061 +#define ABITS 32 /* bits in an IPv4 address */
23062 +#endif
23063 +
23064 +/*
23065 + - goodmask - is this a good (^1*0*$) subnet mask?
23066 + * You are not expected to understand this. See Henry S. Warren Jr,
23067 + * "Functions realizable with word-parallel logical and two's-complement
23068 + * addition instructions", CACM 20.6 (June 1977), p.439.
23069 + */
23070 +int /* predicate */
23071 +goodmask(mask)
23072 +struct in_addr mask;
23073 +{
23074 + unsigned long x = ntohl(mask.s_addr);
23075 + /* clear rightmost contiguous string of 1-bits */
23076 +# define CRCS1B(x) (((x|(x-1))+1)&x)
23077 +# define TOPBIT (1UL << 31)
23078 +
23079 + /* either zero, or has one string of 1-bits which is left-justified */
23080 + if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT)))
23081 + return 1;
23082 + return 0;
23083 +}
23084 +
23085 +/*
23086 + - masktobits - how many bits in this mask?
23087 + * The algorithm is essentially a binary search, but highly optimized
23088 + * for this particular task.
23089 + */
23090 +int /* -1 means !goodmask() */
23091 +masktobits(mask)
23092 +struct in_addr mask;
23093 +{
23094 + unsigned long m = ntohl(mask.s_addr);
23095 + int masklen;
23096 +
23097 + if (!goodmask(mask))
23098 + return -1;
23099 +
23100 + if (m&0x00000001UL)
23101 + return 32;
23102 + masklen = 0;
23103 + if (m&(0x0000ffffUL<<1)) { /* <<1 for 1-origin numbering */
23104 + masklen |= 0x10;
23105 + m <<= 16;
23106 + }
23107 + if (m&(0x00ff0000UL<<1)) {
23108 + masklen |= 0x08;
23109 + m <<= 8;
23110 + }
23111 + if (m&(0x0f000000UL<<1)) {
23112 + masklen |= 0x04;
23113 + m <<= 4;
23114 + }
23115 + if (m&(0x30000000UL<<1)) {
23116 + masklen |= 0x02;
23117 + m <<= 2;
23118 + }
23119 + if (m&(0x40000000UL<<1))
23120 + masklen |= 0x01;
23121 +
23122 + return masklen;
23123 +}
23124 +
23125 +/*
23126 + - bitstomask - return a mask with this many high bits on
23127 + */
23128 +struct in_addr
23129 +bitstomask(n)
23130 +int n;
23131 +{
23132 + struct in_addr result;
23133 +
23134 + if (n > 0 && n <= ABITS)
23135 + result.s_addr = htonl(~((1UL << (ABITS - n)) - 1));
23136 + else if (n == 0)
23137 + result.s_addr = 0;
23138 + else
23139 + result.s_addr = 0; /* best error report we can do */
23140 + return result;
23141 +}
23142 --- /dev/null Tue Mar 11 13:02:56 2003
23143 +++ linux/net/ipsec/infblock.c Mon Feb 9 13:51:03 2004
23144 @@ -0,0 +1,403 @@
23145 +/* infblock.c -- interpret and process block types to last block
23146 + * Copyright (C) 1995-2002 Mark Adler
23147 + * For conditions of distribution and use, see copyright notice in zlib.h
23148 + */
23149 +
23150 +#include <zlib/zutil.h>
23151 +#include "infblock.h"
23152 +#include "inftrees.h"
23153 +#include "infcodes.h"
23154 +#include "infutil.h"
23155 +
23156 +struct inflate_codes_state {int dummy;}; /* for buggy compilers */
23157 +
23158 +/* simplify the use of the inflate_huft type with some defines */
23159 +#define exop word.what.Exop
23160 +#define bits word.what.Bits
23161 +
23162 +/* Table for deflate from PKZIP's appnote.txt. */
23163 +local const uInt border[] = { /* Order of the bit length code lengths */
23164 + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
23165 +
23166 +/*
23167 + Notes beyond the 1.93a appnote.txt:
23168 +
23169 + 1. Distance pointers never point before the beginning of the output
23170 + stream.
23171 + 2. Distance pointers can point back across blocks, up to 32k away.
23172 + 3. There is an implied maximum of 7 bits for the bit length table and
23173 + 15 bits for the actual data.
23174 + 4. If only one code exists, then it is encoded using one bit. (Zero
23175 + would be more efficient, but perhaps a little confusing.) If two
23176 + codes exist, they are coded using one bit each (0 and 1).
23177 + 5. There is no way of sending zero distance codes--a dummy must be
23178 + sent if there are none. (History: a pre 2.0 version of PKZIP would
23179 + store blocks with no distance codes, but this was discovered to be
23180 + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
23181 + zero distance codes, which is sent as one code of zero bits in
23182 + length.
23183 + 6. There are up to 286 literal/length codes. Code 256 represents the
23184 + end-of-block. Note however that the static length tree defines
23185 + 288 codes just to fill out the Huffman codes. Codes 286 and 287
23186 + cannot be used though, since there is no length base or extra bits
23187 + defined for them. Similarily, there are up to 30 distance codes.
23188 + However, static trees define 32 codes (all 5 bits) to fill out the
23189 + Huffman codes, but the last two had better not show up in the data.
23190 + 7. Unzip can check dynamic Huffman blocks for complete code sets.
23191 + The exception is that a single code would not be complete (see #4).
23192 + 8. The five bits following the block type is really the number of
23193 + literal codes sent minus 257.
23194 + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
23195 + (1+6+6). Therefore, to output three times the length, you output
23196 + three codes (1+1+1), whereas to output four times the same length,
23197 + you only need two codes (1+3). Hmm.
23198 + 10. In the tree reconstruction algorithm, Code = Code + Increment
23199 + only if BitLength(i) is not zero. (Pretty obvious.)
23200 + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
23201 + 12. Note: length code 284 can represent 227-258, but length code 285
23202 + really is 258. The last length deserves its own, short code
23203 + since it gets used a lot in very redundant files. The length
23204 + 258 is special since 258 - 3 (the min match length) is 255.
23205 + 13. The literal/length and distance code bit lengths are read as a
23206 + single stream of lengths. It is possible (and advantageous) for
23207 + a repeat code (16, 17, or 18) to go across the boundary between
23208 + the two sets of lengths.
23209 + */
23210 +
23211 +
23212 +void inflate_blocks_reset(s, z, c)
23213 +inflate_blocks_statef *s;
23214 +z_streamp z;
23215 +uLongf *c;
23216 +{
23217 + if (c != Z_NULL)
23218 + *c = s->check;
23219 + if (s->mode == BTREE || s->mode == DTREE)
23220 + ZFREE(z, s->sub.trees.blens);
23221 + if (s->mode == CODES)
23222 + inflate_codes_free(s->sub.decode.codes, z);
23223 + s->mode = TYPE;
23224 + s->bitk = 0;
23225 + s->bitb = 0;
23226 + s->read = s->write = s->window;
23227 + if (s->checkfn != Z_NULL)
23228 + z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
23229 + Tracev((stderr, "inflate: blocks reset\n"));
23230 +}
23231 +
23232 +
23233 +inflate_blocks_statef *inflate_blocks_new(z, c, w)
23234 +z_streamp z;
23235 +check_func c;
23236 +uInt w;
23237 +{
23238 + inflate_blocks_statef *s;
23239 +
23240 + if ((s = (inflate_blocks_statef *)ZALLOC
23241 + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
23242 + return s;
23243 + if ((s->hufts =
23244 + (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
23245 + {
23246 + ZFREE(z, s);
23247 + return Z_NULL;
23248 + }
23249 + if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
23250 + {
23251 + ZFREE(z, s->hufts);
23252 + ZFREE(z, s);
23253 + return Z_NULL;
23254 + }
23255 + s->end = s->window + w;
23256 + s->checkfn = c;
23257 + s->mode = TYPE;
23258 + Tracev((stderr, "inflate: blocks allocated\n"));
23259 + inflate_blocks_reset(s, z, Z_NULL);
23260 + return s;
23261 +}
23262 +
23263 +
23264 +int inflate_blocks(s, z, r)
23265 +inflate_blocks_statef *s;
23266 +z_streamp z;
23267 +int r;
23268 +{
23269 + uInt t; /* temporary storage */
23270 + uLong b; /* bit buffer */
23271 + uInt k; /* bits in bit buffer */
23272 + Bytef *p; /* input data pointer */
23273 + uInt n; /* bytes available there */
23274 + Bytef *q; /* output window write pointer */
23275 + uInt m; /* bytes to end of window or read pointer */
23276 +
23277 + /* copy input/output information to locals (UPDATE macro restores) */
23278 + LOAD
23279 +
23280 + /* process input based on current state */
23281 + while (1) switch (s->mode)
23282 + {
23283 + case TYPE:
23284 + NEEDBITS(3)
23285 + t = (uInt)b & 7;
23286 + s->last = t & 1;
23287 + switch (t >> 1)
23288 + {
23289 + case 0: /* stored */
23290 + Tracev((stderr, "inflate: stored block%s\n",
23291 + s->last ? " (last)" : ""));
23292 + DUMPBITS(3)
23293 + t = k & 7; /* go to byte boundary */
23294 + DUMPBITS(t)
23295 + s->mode = LENS; /* get length of stored block */
23296 + break;
23297 + case 1: /* fixed */
23298 + Tracev((stderr, "inflate: fixed codes block%s\n",
23299 + s->last ? " (last)" : ""));
23300 + {
23301 + uInt bl, bd;
23302 + inflate_huft *tl, *td;
23303 +
23304 + inflate_trees_fixed(&bl, &bd, &tl, &td, z);
23305 + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
23306 + if (s->sub.decode.codes == Z_NULL)
23307 + {
23308 + r = Z_MEM_ERROR;
23309 + LEAVE
23310 + }
23311 + }
23312 + DUMPBITS(3)
23313 + s->mode = CODES;
23314 + break;
23315 + case 2: /* dynamic */
23316 + Tracev((stderr, "inflate: dynamic codes block%s\n",
23317 + s->last ? " (last)" : ""));
23318 + DUMPBITS(3)
23319 + s->mode = TABLE;
23320 + break;
23321 + case 3: /* illegal */
23322 + DUMPBITS(3)
23323 + s->mode = BAD;
23324 + z->msg = (char*)"invalid block type";
23325 + r = Z_DATA_ERROR;
23326 + LEAVE
23327 + }
23328 + break;
23329 + case LENS:
23330 + NEEDBITS(32)
23331 + if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
23332 + {
23333 + s->mode = BAD;
23334 + z->msg = (char*)"invalid stored block lengths";
23335 + r = Z_DATA_ERROR;
23336 + LEAVE
23337 + }
23338 + s->sub.left = (uInt)b & 0xffff;
23339 + b = k = 0; /* dump bits */
23340 + Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
23341 + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
23342 + break;
23343 + case STORED:
23344 + if (n == 0)
23345 + LEAVE
23346 + NEEDOUT
23347 + t = s->sub.left;
23348 + if (t > n) t = n;
23349 + if (t > m) t = m;
23350 + zmemcpy(q, p, t);
23351 + p += t; n -= t;
23352 + q += t; m -= t;
23353 + if ((s->sub.left -= t) != 0)
23354 + break;
23355 + Tracev((stderr, "inflate: stored end, %lu total out\n",
23356 + z->total_out + (q >= s->read ? q - s->read :
23357 + (s->end - s->read) + (q - s->window))));
23358 + s->mode = s->last ? DRY : TYPE;
23359 + break;
23360 + case TABLE:
23361 + NEEDBITS(14)
23362 + s->sub.trees.table = t = (uInt)b & 0x3fff;
23363 +#ifndef PKZIP_BUG_WORKAROUND
23364 + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
23365 + {
23366 + s->mode = BAD;
23367 + z->msg = (char*)"too many length or distance symbols";
23368 + r = Z_DATA_ERROR;
23369 + LEAVE
23370 + }
23371 +#endif
23372 + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
23373 + if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
23374 + {
23375 + r = Z_MEM_ERROR;
23376 + LEAVE
23377 + }
23378 + DUMPBITS(14)
23379 + s->sub.trees.index = 0;
23380 + Tracev((stderr, "inflate: table sizes ok\n"));
23381 + s->mode = BTREE;
23382 + case BTREE:
23383 + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
23384 + {
23385 + NEEDBITS(3)
23386 + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
23387 + DUMPBITS(3)
23388 + }
23389 + while (s->sub.trees.index < 19)
23390 + s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
23391 + s->sub.trees.bb = 7;
23392 + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
23393 + &s->sub.trees.tb, s->hufts, z);
23394 + if (t != Z_OK)
23395 + {
23396 + r = t;
23397 + if (r == Z_DATA_ERROR)
23398 + {
23399 + ZFREE(z, s->sub.trees.blens);
23400 + s->mode = BAD;
23401 + }
23402 + LEAVE
23403 + }
23404 + s->sub.trees.index = 0;
23405 + Tracev((stderr, "inflate: bits tree ok\n"));
23406 + s->mode = DTREE;
23407 + case DTREE:
23408 + while (t = s->sub.trees.table,
23409 + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
23410 + {
23411 + inflate_huft *h;
23412 + uInt i, j, c;
23413 +
23414 + t = s->sub.trees.bb;
23415 + NEEDBITS(t)
23416 + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
23417 + t = h->bits;
23418 + c = h->base;
23419 + if (c < 16)
23420 + {
23421 + DUMPBITS(t)
23422 + s->sub.trees.blens[s->sub.trees.index++] = c;
23423 + }
23424 + else /* c == 16..18 */
23425 + {
23426 + i = c == 18 ? 7 : c - 14;
23427 + j = c == 18 ? 11 : 3;
23428 + NEEDBITS(t + i)
23429 + DUMPBITS(t)
23430 + j += (uInt)b & inflate_mask[i];
23431 + DUMPBITS(i)
23432 + i = s->sub.trees.index;
23433 + t = s->sub.trees.table;
23434 + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
23435 + (c == 16 && i < 1))
23436 + {
23437 + ZFREE(z, s->sub.trees.blens);
23438 + s->mode = BAD;
23439 + z->msg = (char*)"invalid bit length repeat";
23440 + r = Z_DATA_ERROR;
23441 + LEAVE
23442 + }
23443 + c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
23444 + do {
23445 + s->sub.trees.blens[i++] = c;
23446 + } while (--j);
23447 + s->sub.trees.index = i;
23448 + }
23449 + }
23450 + s->sub.trees.tb = Z_NULL;
23451 + {
23452 + uInt bl, bd;
23453 + inflate_huft *tl, *td;
23454 + inflate_codes_statef *c;
23455 +
23456 + bl = 9; /* must be <= 9 for lookahead assumptions */
23457 + bd = 6; /* must be <= 9 for lookahead assumptions */
23458 + t = s->sub.trees.table;
23459 + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
23460 + s->sub.trees.blens, &bl, &bd, &tl, &td,
23461 + s->hufts, z);
23462 + if (t != Z_OK)
23463 + {
23464 + if (t == (uInt)Z_DATA_ERROR)
23465 + {
23466 + ZFREE(z, s->sub.trees.blens);
23467 + s->mode = BAD;
23468 + }
23469 + r = t;
23470 + LEAVE
23471 + }
23472 + Tracev((stderr, "inflate: trees ok\n"));
23473 + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
23474 + {
23475 + r = Z_MEM_ERROR;
23476 + LEAVE
23477 + }
23478 + s->sub.decode.codes = c;
23479 + }
23480 + ZFREE(z, s->sub.trees.blens);
23481 + s->mode = CODES;
23482 + case CODES:
23483 + UPDATE
23484 + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
23485 + return inflate_flush(s, z, r);
23486 + r = Z_OK;
23487 + inflate_codes_free(s->sub.decode.codes, z);
23488 + LOAD
23489 + Tracev((stderr, "inflate: codes end, %lu total out\n",
23490 + z->total_out + (q >= s->read ? q - s->read :
23491 + (s->end - s->read) + (q - s->window))));
23492 + if (!s->last)
23493 + {
23494 + s->mode = TYPE;
23495 + break;
23496 + }
23497 + s->mode = DRY;
23498 + case DRY:
23499 + FLUSH
23500 + if (s->read != s->write)
23501 + LEAVE
23502 + s->mode = DONE;
23503 + case DONE:
23504 + r = Z_STREAM_END;
23505 + LEAVE
23506 + case BAD:
23507 + r = Z_DATA_ERROR;
23508 + LEAVE
23509 + default:
23510 + r = Z_STREAM_ERROR;
23511 + LEAVE
23512 + }
23513 +}
23514 +
23515 +
23516 +int inflate_blocks_free(s, z)
23517 +inflate_blocks_statef *s;
23518 +z_streamp z;
23519 +{
23520 + inflate_blocks_reset(s, z, Z_NULL);
23521 + ZFREE(z, s->window);
23522 + ZFREE(z, s->hufts);
23523 + ZFREE(z, s);
23524 + Tracev((stderr, "inflate: blocks freed\n"));
23525 + return Z_OK;
23526 +}
23527 +
23528 +
23529 +void inflate_set_dictionary(s, d, n)
23530 +inflate_blocks_statef *s;
23531 +const Bytef *d;
23532 +uInt n;
23533 +{
23534 + zmemcpy(s->window, d, n);
23535 + s->read = s->write = s->window + n;
23536 +}
23537 +
23538 +
23539 +/* Returns true if inflate is currently at the end of a block generated
23540 + * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
23541 + * IN assertion: s != Z_NULL
23542 + */
23543 +int inflate_blocks_sync_point(s)
23544 +inflate_blocks_statef *s;
23545 +{
23546 + return s->mode == LENS;
23547 +}
23548 --- /dev/null Tue Mar 11 13:02:56 2003
23549 +++ linux/net/ipsec/infblock.h Mon Feb 9 13:51:03 2004
23550 @@ -0,0 +1,39 @@
23551 +/* infblock.h -- header to use infblock.c
23552 + * Copyright (C) 1995-2002 Mark Adler
23553 + * For conditions of distribution and use, see copyright notice in zlib.h
23554 + */
23555 +
23556 +/* WARNING: this file should *not* be used by applications. It is
23557 + part of the implementation of the compression library and is
23558 + subject to change. Applications should only use zlib.h.
23559 + */
23560 +
23561 +struct inflate_blocks_state;
23562 +typedef struct inflate_blocks_state FAR inflate_blocks_statef;
23563 +
23564 +extern inflate_blocks_statef * inflate_blocks_new OF((
23565 + z_streamp z,
23566 + check_func c, /* check function */
23567 + uInt w)); /* window size */
23568 +
23569 +extern int inflate_blocks OF((
23570 + inflate_blocks_statef *,
23571 + z_streamp ,
23572 + int)); /* initial return code */
23573 +
23574 +extern void inflate_blocks_reset OF((
23575 + inflate_blocks_statef *,
23576 + z_streamp ,
23577 + uLongf *)); /* check value on output */
23578 +
23579 +extern int inflate_blocks_free OF((
23580 + inflate_blocks_statef *,
23581 + z_streamp));
23582 +
23583 +extern void inflate_set_dictionary OF((
23584 + inflate_blocks_statef *s,
23585 + const Bytef *d, /* dictionary */
23586 + uInt n)); /* dictionary length */
23587 +
23588 +extern int inflate_blocks_sync_point OF((
23589 + inflate_blocks_statef *s));
23590 --- /dev/null Tue Mar 11 13:02:56 2003
23591 +++ linux/net/ipsec/infcodes.c Mon Feb 9 13:51:03 2004
23592 @@ -0,0 +1,251 @@
23593 +/* infcodes.c -- process literals and length/distance pairs
23594 + * Copyright (C) 1995-2002 Mark Adler
23595 + * For conditions of distribution and use, see copyright notice in zlib.h
23596 + */
23597 +
23598 +#include <zlib/zutil.h>
23599 +#include "inftrees.h"
23600 +#include "infblock.h"
23601 +#include "infcodes.h"
23602 +#include "infutil.h"
23603 +#include "inffast.h"
23604 +
23605 +/* simplify the use of the inflate_huft type with some defines */
23606 +#define exop word.what.Exop
23607 +#define bits word.what.Bits
23608 +
23609 +typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
23610 + START, /* x: set up for LEN */
23611 + LEN, /* i: get length/literal/eob next */
23612 + LENEXT, /* i: getting length extra (have base) */
23613 + DIST, /* i: get distance next */
23614 + DISTEXT, /* i: getting distance extra */
23615 + COPY, /* o: copying bytes in window, waiting for space */
23616 + LIT, /* o: got literal, waiting for output space */
23617 + WASH, /* o: got eob, possibly still output waiting */
23618 + END, /* x: got eob and all data flushed */
23619 + BADCODE} /* x: got error */
23620 +inflate_codes_mode;
23621 +
23622 +/* inflate codes private state */
23623 +struct inflate_codes_state {
23624 +
23625 + /* mode */
23626 + inflate_codes_mode mode; /* current inflate_codes mode */
23627 +
23628 + /* mode dependent information */
23629 + uInt len;
23630 + union {
23631 + struct {
23632 + inflate_huft *tree; /* pointer into tree */
23633 + uInt need; /* bits needed */
23634 + } code; /* if LEN or DIST, where in tree */
23635 + uInt lit; /* if LIT, literal */
23636 + struct {
23637 + uInt get; /* bits to get for extra */
23638 + uInt dist; /* distance back to copy from */
23639 + } copy; /* if EXT or COPY, where and how much */
23640 + } sub; /* submode */
23641 +
23642 + /* mode independent information */
23643 + Byte lbits; /* ltree bits decoded per branch */
23644 + Byte dbits; /* dtree bits decoder per branch */
23645 + inflate_huft *ltree; /* literal/length/eob tree */
23646 + inflate_huft *dtree; /* distance tree */
23647 +
23648 +};
23649 +
23650 +
23651 +inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
23652 +uInt bl, bd;
23653 +inflate_huft *tl;
23654 +inflate_huft *td; /* need separate declaration for Borland C++ */
23655 +z_streamp z;
23656 +{
23657 + inflate_codes_statef *c;
23658 +
23659 + if ((c = (inflate_codes_statef *)
23660 + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
23661 + {
23662 + c->mode = START;
23663 + c->lbits = (Byte)bl;
23664 + c->dbits = (Byte)bd;
23665 + c->ltree = tl;
23666 + c->dtree = td;
23667 + Tracev((stderr, "inflate: codes new\n"));
23668 + }
23669 + return c;
23670 +}
23671 +
23672 +
23673 +int inflate_codes(s, z, r)
23674 +inflate_blocks_statef *s;
23675 +z_streamp z;
23676 +int r;
23677 +{
23678 + uInt j; /* temporary storage */
23679 + inflate_huft *t; /* temporary pointer */
23680 + uInt e; /* extra bits or operation */
23681 + uLong b; /* bit buffer */
23682 + uInt k; /* bits in bit buffer */
23683 + Bytef *p; /* input data pointer */
23684 + uInt n; /* bytes available there */
23685 + Bytef *q; /* output window write pointer */
23686 + uInt m; /* bytes to end of window or read pointer */
23687 + Bytef *f; /* pointer to copy strings from */
23688 + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
23689 +
23690 + /* copy input/output information to locals (UPDATE macro restores) */
23691 + LOAD
23692 +
23693 + /* process input and output based on current state */
23694 + while (1) switch (c->mode)
23695 + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
23696 + case START: /* x: set up for LEN */
23697 +#ifndef SLOW
23698 + if (m >= 258 && n >= 10)
23699 + {
23700 + UPDATE
23701 + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
23702 + LOAD
23703 + if (r != Z_OK)
23704 + {
23705 + c->mode = r == Z_STREAM_END ? WASH : BADCODE;
23706 + break;
23707 + }
23708 + }
23709 +#endif /* !SLOW */
23710 + c->sub.code.need = c->lbits;
23711 + c->sub.code.tree = c->ltree;
23712 + c->mode = LEN;
23713 + case LEN: /* i: get length/literal/eob next */
23714 + j = c->sub.code.need;
23715 + NEEDBITS(j)
23716 + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
23717 + DUMPBITS(t->bits)
23718 + e = (uInt)(t->exop);
23719 + if (e == 0) /* literal */
23720 + {
23721 + c->sub.lit = t->base;
23722 + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
23723 + "inflate: literal '%c'\n" :
23724 + "inflate: literal 0x%02x\n", t->base));
23725 + c->mode = LIT;
23726 + break;
23727 + }
23728 + if (e & 16) /* length */
23729 + {
23730 + c->sub.copy.get = e & 15;
23731 + c->len = t->base;
23732 + c->mode = LENEXT;
23733 + break;
23734 + }
23735 + if ((e & 64) == 0) /* next table */
23736 + {
23737 + c->sub.code.need = e;
23738 + c->sub.code.tree = t + t->base;
23739 + break;
23740 + }
23741 + if (e & 32) /* end of block */
23742 + {
23743 + Tracevv((stderr, "inflate: end of block\n"));
23744 + c->mode = WASH;
23745 + break;
23746 + }
23747 + c->mode = BADCODE; /* invalid code */
23748 + z->msg = (char*)"invalid literal/length code";
23749 + r = Z_DATA_ERROR;
23750 + LEAVE
23751 + case LENEXT: /* i: getting length extra (have base) */
23752 + j = c->sub.copy.get;
23753 + NEEDBITS(j)
23754 + c->len += (uInt)b & inflate_mask[j];
23755 + DUMPBITS(j)
23756 + c->sub.code.need = c->dbits;
23757 + c->sub.code.tree = c->dtree;
23758 + Tracevv((stderr, "inflate: length %u\n", c->len));
23759 + c->mode = DIST;
23760 + case DIST: /* i: get distance next */
23761 + j = c->sub.code.need;
23762 + NEEDBITS(j)
23763 + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
23764 + DUMPBITS(t->bits)
23765 + e = (uInt)(t->exop);
23766 + if (e & 16) /* distance */
23767 + {
23768 + c->sub.copy.get = e & 15;
23769 + c->sub.copy.dist = t->base;
23770 + c->mode = DISTEXT;
23771 + break;
23772 + }
23773 + if ((e & 64) == 0) /* next table */
23774 + {
23775 + c->sub.code.need = e;
23776 + c->sub.code.tree = t + t->base;
23777 + break;
23778 + }
23779 + c->mode = BADCODE; /* invalid code */
23780 + z->msg = (char*)"invalid distance code";
23781 + r = Z_DATA_ERROR;
23782 + LEAVE
23783 + case DISTEXT: /* i: getting distance extra */
23784 + j = c->sub.copy.get;
23785 + NEEDBITS(j)
23786 + c->sub.copy.dist += (uInt)b & inflate_mask[j];
23787 + DUMPBITS(j)
23788 + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
23789 + c->mode = COPY;
23790 + case COPY: /* o: copying bytes in window, waiting for space */
23791 + f = q - c->sub.copy.dist;
23792 + while (f < s->window) /* modulo window size-"while" instead */
23793 + f += s->end - s->window; /* of "if" handles invalid distances */
23794 + while (c->len)
23795 + {
23796 + NEEDOUT
23797 + OUTBYTE(*f++)
23798 + if (f == s->end)
23799 + f = s->window;
23800 + c->len--;
23801 + }
23802 + c->mode = START;
23803 + break;
23804 + case LIT: /* o: got literal, waiting for output space */
23805 + NEEDOUT
23806 + OUTBYTE(c->sub.lit)
23807 + c->mode = START;
23808 + break;
23809 + case WASH: /* o: got eob, possibly more output */
23810 + if (k > 7) /* return unused byte, if any */
23811 + {
23812 + Assert(k < 16, "inflate_codes grabbed too many bytes")
23813 + k -= 8;
23814 + n++;
23815 + p--; /* can always return one */
23816 + }
23817 + FLUSH
23818 + if (s->read != s->write)
23819 + LEAVE
23820 + c->mode = END;
23821 + case END:
23822 + r = Z_STREAM_END;
23823 + LEAVE
23824 + case BADCODE: /* x: got error */
23825 + r = Z_DATA_ERROR;
23826 + LEAVE
23827 + default:
23828 + r = Z_STREAM_ERROR;
23829 + LEAVE
23830 + }
23831 +#ifdef NEED_DUMMY_RETURN
23832 + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
23833 +#endif
23834 +}
23835 +
23836 +
23837 +void inflate_codes_free(c, z)
23838 +inflate_codes_statef *c;
23839 +z_streamp z;
23840 +{
23841 + ZFREE(z, c);
23842 + Tracev((stderr, "inflate: codes free\n"));
23843 +}
23844 --- /dev/null Tue Mar 11 13:02:56 2003
23845 +++ linux/net/ipsec/infcodes.h Mon Feb 9 13:51:03 2004
23846 @@ -0,0 +1,31 @@
23847 +/* infcodes.h -- header to use infcodes.c
23848 + * Copyright (C) 1995-2002 Mark Adler
23849 + * For conditions of distribution and use, see copyright notice in zlib.h
23850 + */
23851 +
23852 +/* WARNING: this file should *not* be used by applications. It is
23853 + part of the implementation of the compression library and is
23854 + subject to change. Applications should only use zlib.h.
23855 + */
23856 +
23857 +#ifndef _INFCODES_H
23858 +#define _INFCODES_H
23859 +
23860 +struct inflate_codes_state;
23861 +typedef struct inflate_codes_state FAR inflate_codes_statef;
23862 +
23863 +extern inflate_codes_statef *inflate_codes_new OF((
23864 + uInt, uInt,
23865 + inflate_huft *, inflate_huft *,
23866 + z_streamp ));
23867 +
23868 +extern int inflate_codes OF((
23869 + inflate_blocks_statef *,
23870 + z_streamp ,
23871 + int));
23872 +
23873 +extern void inflate_codes_free OF((
23874 + inflate_codes_statef *,
23875 + z_streamp ));
23876 +
23877 +#endif /* _INFCODES_H */
23878 --- /dev/null Tue Mar 11 13:02:56 2003
23879 +++ linux/net/ipsec/inffast.c Mon Feb 9 13:51:03 2004
23880 @@ -0,0 +1,183 @@
23881 +/* inffast.c -- process literals and length/distance pairs fast
23882 + * Copyright (C) 1995-2002 Mark Adler
23883 + * For conditions of distribution and use, see copyright notice in zlib.h
23884 + */
23885 +
23886 +#include <zlib/zutil.h>
23887 +#include "inftrees.h"
23888 +#include "infblock.h"
23889 +#include "infcodes.h"
23890 +#include "infutil.h"
23891 +#include "inffast.h"
23892 +
23893 +struct inflate_codes_state {int dummy;}; /* for buggy compilers */
23894 +
23895 +/* simplify the use of the inflate_huft type with some defines */
23896 +#define exop word.what.Exop
23897 +#define bits word.what.Bits
23898 +
23899 +/* macros for bit input with no checking and for returning unused bytes */
23900 +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
23901 +#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
23902 +
23903 +/* Called with number of bytes left to write in window at least 258
23904 + (the maximum string length) and number of input bytes available
23905 + at least ten. The ten bytes are six bytes for the longest length/
23906 + distance pair plus four bytes for overloading the bit buffer. */
23907 +
23908 +int inflate_fast(bl, bd, tl, td, s, z)
23909 +uInt bl, bd;
23910 +inflate_huft *tl;
23911 +inflate_huft *td; /* need separate declaration for Borland C++ */
23912 +inflate_blocks_statef *s;
23913 +z_streamp z;
23914 +{
23915 + inflate_huft *t; /* temporary pointer */
23916 + uInt e; /* extra bits or operation */
23917 + uLong b; /* bit buffer */
23918 + uInt k; /* bits in bit buffer */
23919 + Bytef *p; /* input data pointer */
23920 + uInt n; /* bytes available there */
23921 + Bytef *q; /* output window write pointer */
23922 + uInt m; /* bytes to end of window or read pointer */
23923 + uInt ml; /* mask for literal/length tree */
23924 + uInt md; /* mask for distance tree */
23925 + uInt c; /* bytes to copy */
23926 + uInt d; /* distance back to copy from */
23927 + Bytef *r; /* copy source pointer */
23928 +
23929 + /* load input, output, bit values */
23930 + LOAD
23931 +
23932 + /* initialize masks */
23933 + ml = inflate_mask[bl];
23934 + md = inflate_mask[bd];
23935 +
23936 + /* do until not enough input or output space for fast loop */
23937 + do { /* assume called with m >= 258 && n >= 10 */
23938 + /* get literal/length code */
23939 + GRABBITS(20) /* max bits for literal/length code */
23940 + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
23941 + {
23942 + DUMPBITS(t->bits)
23943 + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
23944 + "inflate: * literal '%c'\n" :
23945 + "inflate: * literal 0x%02x\n", t->base));
23946 + *q++ = (Byte)t->base;
23947 + m--;
23948 + continue;
23949 + }
23950 + do {
23951 + DUMPBITS(t->bits)
23952 + if (e & 16)
23953 + {
23954 + /* get extra bits for length */
23955 + e &= 15;
23956 + c = t->base + ((uInt)b & inflate_mask[e]);
23957 + DUMPBITS(e)
23958 + Tracevv((stderr, "inflate: * length %u\n", c));
23959 +
23960 + /* decode distance base of block to copy */
23961 + GRABBITS(15); /* max bits for distance code */
23962 + e = (t = td + ((uInt)b & md))->exop;
23963 + do {
23964 + DUMPBITS(t->bits)
23965 + if (e & 16)
23966 + {
23967 + /* get extra bits to add to distance base */
23968 + e &= 15;
23969 + GRABBITS(e) /* get extra bits (up to 13) */
23970 + d = t->base + ((uInt)b & inflate_mask[e]);
23971 + DUMPBITS(e)
23972 + Tracevv((stderr, "inflate: * distance %u\n", d));
23973 +
23974 + /* do the copy */
23975 + m -= c;
23976 + r = q - d;
23977 + if (r < s->window) /* wrap if needed */
23978 + {
23979 + do {
23980 + r += s->end - s->window; /* force pointer in window */
23981 + } while (r < s->window); /* covers invalid distances */
23982 + e = s->end - r;
23983 + if (c > e)
23984 + {
23985 + c -= e; /* wrapped copy */
23986 + do {
23987 + *q++ = *r++;
23988 + } while (--e);
23989 + r = s->window;
23990 + do {
23991 + *q++ = *r++;
23992 + } while (--c);
23993 + }
23994 + else /* normal copy */
23995 + {
23996 + *q++ = *r++; c--;
23997 + *q++ = *r++; c--;
23998 + do {
23999 + *q++ = *r++;
24000 + } while (--c);
24001 + }
24002 + }
24003 + else /* normal copy */
24004 + {
24005 + *q++ = *r++; c--;
24006 + *q++ = *r++; c--;
24007 + do {
24008 + *q++ = *r++;
24009 + } while (--c);
24010 + }
24011 + break;
24012 + }
24013 + else if ((e & 64) == 0)
24014 + {
24015 + t += t->base;
24016 + e = (t += ((uInt)b & inflate_mask[e]))->exop;
24017 + }
24018 + else
24019 + {
24020 + z->msg = (char*)"invalid distance code";
24021 + UNGRAB
24022 + UPDATE
24023 + return Z_DATA_ERROR;
24024 + }
24025 + } while (1);
24026 + break;
24027 + }
24028 + if ((e & 64) == 0)
24029 + {
24030 + t += t->base;
24031 + if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
24032 + {
24033 + DUMPBITS(t->bits)
24034 + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
24035 + "inflate: * literal '%c'\n" :
24036 + "inflate: * literal 0x%02x\n", t->base));
24037 + *q++ = (Byte)t->base;
24038 + m--;
24039 + break;
24040 + }
24041 + }
24042 + else if (e & 32)
24043 + {
24044 + Tracevv((stderr, "inflate: * end of block\n"));
24045 + UNGRAB
24046 + UPDATE
24047 + return Z_STREAM_END;
24048 + }
24049 + else
24050 + {
24051 + z->msg = (char*)"invalid literal/length code";
24052 + UNGRAB
24053 + UPDATE
24054 + return Z_DATA_ERROR;
24055 + }
24056 + } while (1);
24057 + } while (m >= 258 && n >= 10);
24058 +
24059 + /* not enough input or output--restore pointers and return */
24060 + UNGRAB
24061 + UPDATE
24062 + return Z_OK;
24063 +}
24064 --- /dev/null Tue Mar 11 13:02:56 2003
24065 +++ linux/net/ipsec/inffast.h Mon Feb 9 13:51:03 2004
24066 @@ -0,0 +1,22 @@
24067 +/* inffast.h -- header to use inffast.c
24068 + * Copyright (C) 1995-2002 Mark Adler
24069 + * For conditions of distribution and use, see copyright notice in zlib.h
24070 + */
24071 +
24072 +/* WARNING: this file should *not* be used by applications. It is
24073 + part of the implementation of the compression library and is
24074 + subject to change. Applications should only use zlib.h.
24075 + */
24076 +
24077 +#ifndef _INFFAST_H
24078 +#define _INFFAST_H
24079 +
24080 +extern int inflate_fast OF((
24081 + uInt,
24082 + uInt,
24083 + inflate_huft *,
24084 + inflate_huft *,
24085 + inflate_blocks_statef *,
24086 + z_streamp ));
24087 +
24088 +#endif /* _INFFAST_H */
24089 --- /dev/null Tue Mar 11 13:02:56 2003
24090 +++ linux/net/ipsec/inffixed.h Mon Feb 9 13:51:03 2004
24091 @@ -0,0 +1,151 @@
24092 +/* inffixed.h -- table for decoding fixed codes
24093 + * Generated automatically by the maketree.c program
24094 + */
24095 +
24096 +/* WARNING: this file should *not* be used by applications. It is
24097 + part of the implementation of the compression library and is
24098 + subject to change. Applications should only use zlib.h.
24099 + */
24100 +
24101 +local uInt fixed_bl = 9;
24102 +local uInt fixed_bd = 5;
24103 +local inflate_huft fixed_tl[] = {
24104 + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
24105 + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
24106 + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
24107 + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
24108 + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
24109 + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
24110 + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
24111 + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
24112 + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
24113 + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
24114 + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
24115 + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
24116 + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
24117 + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
24118 + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
24119 + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
24120 + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
24121 + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
24122 + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
24123 + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
24124 + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
24125 + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
24126 + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
24127 + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
24128 + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
24129 + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
24130 + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
24131 + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
24132 + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
24133 + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
24134 + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
24135 + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
24136 + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
24137 + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
24138 + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
24139 + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
24140 + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
24141 + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
24142 + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
24143 + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
24144 + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
24145 + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
24146 + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
24147 + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
24148 + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
24149 + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
24150 + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
24151 + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
24152 + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
24153 + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
24154 + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
24155 + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
24156 + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
24157 + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
24158 + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
24159 + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
24160 + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
24161 + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
24162 + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
24163 + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
24164 + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
24165 + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
24166 + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
24167 + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
24168 + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
24169 + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
24170 + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
24171 + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
24172 + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
24173 + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
24174 + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
24175 + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
24176 + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
24177 + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
24178 + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
24179 + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
24180 + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
24181 + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
24182 + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
24183 + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
24184 + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
24185 + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
24186 + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
24187 + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
24188 + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
24189 + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
24190 + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
24191 + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
24192 + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
24193 + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
24194 + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
24195 + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
24196 + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
24197 + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
24198 + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
24199 + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
24200 + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
24201 + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
24202 + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
24203 + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
24204 + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
24205 + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
24206 + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
24207 + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
24208 + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
24209 + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
24210 + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
24211 + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
24212 + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
24213 + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
24214 + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
24215 + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
24216 + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
24217 + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
24218 + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
24219 + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
24220 + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
24221 + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
24222 + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
24223 + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
24224 + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
24225 + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
24226 + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
24227 + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
24228 + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
24229 + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
24230 + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
24231 + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
24232 + };
24233 +local inflate_huft fixed_td[] = {
24234 + {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
24235 + {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
24236 + {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
24237 + {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
24238 + {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
24239 + {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
24240 + {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
24241 + {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
24242 + };
24243 --- /dev/null Tue Mar 11 13:02:56 2003
24244 +++ linux/net/ipsec/inflate.c Mon Feb 9 13:51:03 2004
24245 @@ -0,0 +1,368 @@
24246 +/* inflate.c -- zlib interface to inflate modules
24247 + * Copyright (C) 1995-2002 Mark Adler
24248 + * For conditions of distribution and use, see copyright notice in zlib.h
24249 + */
24250 +
24251 +#include <zlib/zutil.h>
24252 +#include "infblock.h"
24253 +
24254 +struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
24255 +
24256 +typedef enum {
24257 + METHOD, /* waiting for method byte */
24258 + FLAG, /* waiting for flag byte */
24259 + DICT4, /* four dictionary check bytes to go */
24260 + DICT3, /* three dictionary check bytes to go */
24261 + DICT2, /* two dictionary check bytes to go */
24262 + DICT1, /* one dictionary check byte to go */
24263 + DICT0, /* waiting for inflateSetDictionary */
24264 + BLOCKS, /* decompressing blocks */
24265 + CHECK4, /* four check bytes to go */
24266 + CHECK3, /* three check bytes to go */
24267 + CHECK2, /* two check bytes to go */
24268 + CHECK1, /* one check byte to go */
24269 + DONE, /* finished check, done */
24270 + BAD} /* got an error--stay here */
24271 +inflate_mode;
24272 +
24273 +/* inflate private state */
24274 +struct internal_state {
24275 +
24276 + /* mode */
24277 + inflate_mode mode; /* current inflate mode */
24278 +
24279 + /* mode dependent information */
24280 + union {
24281 + uInt method; /* if FLAGS, method byte */
24282 + struct {
24283 + uLong was; /* computed check value */
24284 + uLong need; /* stream check value */
24285 + } check; /* if CHECK, check values to compare */
24286 + uInt marker; /* if BAD, inflateSync's marker bytes count */
24287 + } sub; /* submode */
24288 +
24289 + /* mode independent information */
24290 + int nowrap; /* flag for no wrapper */
24291 + uInt wbits; /* log2(window size) (8..15, defaults to 15) */
24292 + inflate_blocks_statef
24293 + *blocks; /* current inflate_blocks state */
24294 +
24295 +};
24296 +
24297 +
24298 +int ZEXPORT inflateReset(z)
24299 +z_streamp z;
24300 +{
24301 + if (z == Z_NULL || z->state == Z_NULL)
24302 + return Z_STREAM_ERROR;
24303 + z->total_in = z->total_out = 0;
24304 + z->msg = Z_NULL;
24305 + z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
24306 + inflate_blocks_reset(z->state->blocks, z, Z_NULL);
24307 + Tracev((stderr, "inflate: reset\n"));
24308 + return Z_OK;
24309 +}
24310 +
24311 +
24312 +int ZEXPORT inflateEnd(z)
24313 +z_streamp z;
24314 +{
24315 + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
24316 + return Z_STREAM_ERROR;
24317 + if (z->state->blocks != Z_NULL)
24318 + inflate_blocks_free(z->state->blocks, z);
24319 + ZFREE(z, z->state);
24320 + z->state = Z_NULL;
24321 + Tracev((stderr, "inflate: end\n"));
24322 + return Z_OK;
24323 +}
24324 +
24325 +
24326 +int ZEXPORT inflateInit2_(z, w, version, stream_size)
24327 +z_streamp z;
24328 +int w;
24329 +const char *version;
24330 +int stream_size;
24331 +{
24332 + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
24333 + stream_size != sizeof(z_stream))
24334 + return Z_VERSION_ERROR;
24335 +
24336 + /* initialize state */
24337 + if (z == Z_NULL)
24338 + return Z_STREAM_ERROR;
24339 + z->msg = Z_NULL;
24340 + if (z->zalloc == Z_NULL)
24341 + {
24342 + return Z_STREAM_ERROR;
24343 +/* z->zalloc = zcalloc;
24344 + z->opaque = (voidpf)0;
24345 +*/
24346 + }
24347 + if (z->zfree == Z_NULL) return Z_STREAM_ERROR; /* z->zfree = zcfree; */
24348 + if ((z->state = (struct internal_state FAR *)
24349 + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
24350 + return Z_MEM_ERROR;
24351 + z->state->blocks = Z_NULL;
24352 +
24353 + /* handle undocumented nowrap option (no zlib header or check) */
24354 + z->state->nowrap = 0;
24355 + if (w < 0)
24356 + {
24357 + w = - w;
24358 + z->state->nowrap = 1;
24359 + }
24360 +
24361 + /* set window size */
24362 + if (w < 8 || w > 15)
24363 + {
24364 + inflateEnd(z);
24365 + return Z_STREAM_ERROR;
24366 + }
24367 + z->state->wbits = (uInt)w;
24368 +
24369 + /* create inflate_blocks state */
24370 + if ((z->state->blocks =
24371 + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
24372 + == Z_NULL)
24373 + {
24374 + inflateEnd(z);
24375 + return Z_MEM_ERROR;
24376 + }
24377 + Tracev((stderr, "inflate: allocated\n"));
24378 +
24379 + /* reset state */
24380 + inflateReset(z);
24381 + return Z_OK;
24382 +}
24383 +
24384 +
24385 +int ZEXPORT inflateInit_(z, version, stream_size)
24386 +z_streamp z;
24387 +const char *version;
24388 +int stream_size;
24389 +{
24390 + return inflateInit2_(z, DEF_WBITS, version, stream_size);
24391 +}
24392 +
24393 +
24394 +#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
24395 +#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
24396 +
24397 +int ZEXPORT inflate(z, f)
24398 +z_streamp z;
24399 +int f;
24400 +{
24401 + int r;
24402 + uInt b;
24403 +
24404 + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
24405 + return Z_STREAM_ERROR;
24406 + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
24407 + r = Z_BUF_ERROR;
24408 + while (1) switch (z->state->mode)
24409 + {
24410 + case METHOD:
24411 + NEEDBYTE
24412 + if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
24413 + {
24414 + z->state->mode = BAD;
24415 + z->msg = (char*)"unknown compression method";
24416 + z->state->sub.marker = 5; /* can't try inflateSync */
24417 + break;
24418 + }
24419 + if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
24420 + {
24421 + z->state->mode = BAD;
24422 + z->msg = (char*)"invalid window size";
24423 + z->state->sub.marker = 5; /* can't try inflateSync */
24424 + break;
24425 + }
24426 + z->state->mode = FLAG;
24427 + case FLAG:
24428 + NEEDBYTE
24429 + b = NEXTBYTE;
24430 + if (((z->state->sub.method << 8) + b) % 31)
24431 + {
24432 + z->state->mode = BAD;
24433 + z->msg = (char*)"incorrect header check";
24434 + z->state->sub.marker = 5; /* can't try inflateSync */
24435 + break;
24436 + }
24437 + Tracev((stderr, "inflate: zlib header ok\n"));
24438 + if (!(b & PRESET_DICT))
24439 + {
24440 + z->state->mode = BLOCKS;
24441 + break;
24442 + }
24443 + z->state->mode = DICT4;
24444 + case DICT4:
24445 + NEEDBYTE
24446 + z->state->sub.check.need = (uLong)NEXTBYTE << 24;
24447 + z->state->mode = DICT3;
24448 + case DICT3:
24449 + NEEDBYTE
24450 + z->state->sub.check.need += (uLong)NEXTBYTE << 16;
24451 + z->state->mode = DICT2;
24452 + case DICT2:
24453 + NEEDBYTE
24454 + z->state->sub.check.need += (uLong)NEXTBYTE << 8;
24455 + z->state->mode = DICT1;
24456 + case DICT1:
24457 + NEEDBYTE
24458 + z->state->sub.check.need += (uLong)NEXTBYTE;
24459 + z->adler = z->state->sub.check.need;
24460 + z->state->mode = DICT0;
24461 + return Z_NEED_DICT;
24462 + case DICT0:
24463 + z->state->mode = BAD;
24464 + z->msg = (char*)"need dictionary";
24465 + z->state->sub.marker = 0; /* can try inflateSync */
24466 + return Z_STREAM_ERROR;
24467 + case BLOCKS:
24468 + r = inflate_blocks(z->state->blocks, z, r);
24469 + if (r == Z_DATA_ERROR)
24470 + {
24471 + z->state->mode = BAD;
24472 + z->state->sub.marker = 0; /* can try inflateSync */
24473 + break;
24474 + }
24475 + if (r == Z_OK)
24476 + r = f;
24477 + if (r != Z_STREAM_END)
24478 + return r;
24479 + r = f;
24480 + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
24481 + if (z->state->nowrap)
24482 + {
24483 + z->state->mode = DONE;
24484 + break;
24485 + }
24486 + z->state->mode = CHECK4;
24487 + case CHECK4:
24488 + NEEDBYTE
24489 + z->state->sub.check.need = (uLong)NEXTBYTE << 24;
24490 + z->state->mode = CHECK3;
24491 + case CHECK3:
24492 + NEEDBYTE
24493 + z->state->sub.check.need += (uLong)NEXTBYTE << 16;
24494 + z->state->mode = CHECK2;
24495 + case CHECK2:
24496 + NEEDBYTE
24497 + z->state->sub.check.need += (uLong)NEXTBYTE << 8;
24498 + z->state->mode = CHECK1;
24499 + case CHECK1:
24500 + NEEDBYTE
24501 + z->state->sub.check.need += (uLong)NEXTBYTE;
24502 +
24503 + if (z->state->sub.check.was != z->state->sub.check.need)
24504 + {
24505 + z->state->mode = BAD;
24506 + z->msg = (char*)"incorrect data check";
24507 + z->state->sub.marker = 5; /* can't try inflateSync */
24508 + break;
24509 + }
24510 + Tracev((stderr, "inflate: zlib check ok\n"));
24511 + z->state->mode = DONE;
24512 + case DONE:
24513 + return Z_STREAM_END;
24514 + case BAD:
24515 + return Z_DATA_ERROR;
24516 + default:
24517 + return Z_STREAM_ERROR;
24518 + }
24519 +#ifdef NEED_DUMMY_RETURN
24520 + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
24521 +#endif
24522 +}
24523 +
24524 +
24525 +int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
24526 +z_streamp z;
24527 +const Bytef *dictionary;
24528 +uInt dictLength;
24529 +{
24530 + uInt length = dictLength;
24531 +
24532 + if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
24533 + return Z_STREAM_ERROR;
24534 +
24535 + if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
24536 + z->adler = 1L;
24537 +
24538 + if (length >= ((uInt)1<<z->state->wbits))
24539 + {
24540 + length = (1<<z->state->wbits)-1;
24541 + dictionary += dictLength - length;
24542 + }
24543 + inflate_set_dictionary(z->state->blocks, dictionary, length);
24544 + z->state->mode = BLOCKS;
24545 + return Z_OK;
24546 +}
24547 +
24548 +
24549 +int ZEXPORT inflateSync(z)
24550 +z_streamp z;
24551 +{
24552 + uInt n; /* number of bytes to look at */
24553 + Bytef *p; /* pointer to bytes */
24554 + uInt m; /* number of marker bytes found in a row */
24555 + uLong r, w; /* temporaries to save total_in and total_out */
24556 +
24557 + /* set up */
24558 + if (z == Z_NULL || z->state == Z_NULL)
24559 + return Z_STREAM_ERROR;
24560 + if (z->state->mode != BAD)
24561 + {
24562 + z->state->mode = BAD;
24563 + z->state->sub.marker = 0;
24564 + }
24565 + if ((n = z->avail_in) == 0)
24566 + return Z_BUF_ERROR;
24567 + p = z->next_in;
24568 + m = z->state->sub.marker;
24569 +
24570 + /* search */
24571 + while (n && m < 4)
24572 + {
24573 + static const Byte mark[4] = {0, 0, 0xff, 0xff};
24574 + if (*p == mark[m])
24575 + m++;
24576 + else if (*p)
24577 + m = 0;
24578 + else
24579 + m = 4 - m;
24580 + p++, n--;
24581 + }
24582 +
24583 + /* restore */
24584 + z->total_in += p - z->next_in;
24585 + z->next_in = p;
24586 + z->avail_in = n;
24587 + z->state->sub.marker = m;
24588 +
24589 + /* return no joy or set up to restart on a new block */
24590 + if (m != 4)
24591 + return Z_DATA_ERROR;
24592 + r = z->total_in; w = z->total_out;
24593 + inflateReset(z);
24594 + z->total_in = r; z->total_out = w;
24595 + z->state->mode = BLOCKS;
24596 + return Z_OK;
24597 +}
24598 +
24599 +
24600 +/* Returns true if inflate is currently at the end of a block generated
24601 + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
24602 + * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
24603 + * but removes the length bytes of the resulting empty stored block. When
24604 + * decompressing, PPP checks that at the end of input packet, inflate is
24605 + * waiting for these length bytes.
24606 + */
24607 +int ZEXPORT inflateSyncPoint(z)
24608 +z_streamp z;
24609 +{
24610 + if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
24611 + return Z_STREAM_ERROR;
24612 + return inflate_blocks_sync_point(z->state->blocks);
24613 +}
24614 --- /dev/null Tue Mar 11 13:02:56 2003
24615 +++ linux/net/ipsec/inftrees.c Mon Feb 9 13:51:03 2004
24616 @@ -0,0 +1,454 @@
24617 +/* inftrees.c -- generate Huffman trees for efficient decoding
24618 + * Copyright (C) 1995-2002 Mark Adler
24619 + * For conditions of distribution and use, see copyright notice in zlib.h
24620 + */
24621 +
24622 +#include <zlib/zutil.h>
24623 +#include "inftrees.h"
24624 +
24625 +#if !defined(BUILDFIXED) && !defined(STDC)
24626 +# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
24627 +#endif
24628 +
24629 +local const char inflate_copyright[] =
24630 + " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
24631 +/*
24632 + If you use the zlib library in a product, an acknowledgment is welcome
24633 + in the documentation of your product. If for some reason you cannot
24634 + include such an acknowledgment, I would appreciate that you keep this
24635 + copyright string in the executable of your product.
24636 + */
24637 +struct internal_state {int dummy;}; /* for buggy compilers */
24638 +
24639 +/* simplify the use of the inflate_huft type with some defines */
24640 +#define exop word.what.Exop
24641 +#define bits word.what.Bits
24642 +
24643 +
24644 +local int huft_build OF((
24645 + uIntf *, /* code lengths in bits */
24646 + uInt, /* number of codes */
24647 + uInt, /* number of "simple" codes */
24648 + const uIntf *, /* list of base values for non-simple codes */
24649 + const uIntf *, /* list of extra bits for non-simple codes */
24650 + inflate_huft * FAR*,/* result: starting table */
24651 + uIntf *, /* maximum lookup bits (returns actual) */
24652 + inflate_huft *, /* space for trees */
24653 + uInt *, /* hufts used in space */
24654 + uIntf * )); /* space for values */
24655 +
24656 +/* Tables for deflate from PKZIP's appnote.txt. */
24657 +local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
24658 + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
24659 + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
24660 + /* see note #13 above about 258 */
24661 +local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
24662 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
24663 + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
24664 +local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
24665 + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
24666 + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
24667 + 8193, 12289, 16385, 24577};
24668 +local const uInt cpdext[30] = { /* Extra bits for distance codes */
24669 + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
24670 + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
24671 + 12, 12, 13, 13};
24672 +
24673 +/*
24674 + Huffman code decoding is performed using a multi-level table lookup.
24675 + The fastest way to decode is to simply build a lookup table whose
24676 + size is determined by the longest code. However, the time it takes
24677 + to build this table can also be a factor if the data being decoded
24678 + is not very long. The most common codes are necessarily the
24679 + shortest codes, so those codes dominate the decoding time, and hence
24680 + the speed. The idea is you can have a shorter table that decodes the
24681 + shorter, more probable codes, and then point to subsidiary tables for
24682 + the longer codes. The time it costs to decode the longer codes is
24683 + then traded against the time it takes to make longer tables.
24684 +
24685 + This results of this trade are in the variables lbits and dbits
24686 + below. lbits is the number of bits the first level table for literal/
24687 + length codes can decode in one step, and dbits is the same thing for
24688 + the distance codes. Subsequent tables are also less than or equal to
24689 + those sizes. These values may be adjusted either when all of the
24690 + codes are shorter than that, in which case the longest code length in
24691 + bits is used, or when the shortest code is *longer* than the requested
24692 + table size, in which case the length of the shortest code in bits is
24693 + used.
24694 +
24695 + There are two different values for the two tables, since they code a
24696 + different number of possibilities each. The literal/length table
24697 + codes 286 possible values, or in a flat code, a little over eight
24698 + bits. The distance table codes 30 possible values, or a little less
24699 + than five bits, flat. The optimum values for speed end up being
24700 + about one bit more than those, so lbits is 8+1 and dbits is 5+1.
24701 + The optimum values may differ though from machine to machine, and
24702 + possibly even between compilers. Your mileage may vary.
24703 + */
24704 +
24705 +
24706 +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
24707 +#define BMAX 15 /* maximum bit length of any code */
24708 +
24709 +local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
24710 +uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
24711 +uInt n; /* number of codes (assumed <= 288) */
24712 +uInt s; /* number of simple-valued codes (0..s-1) */
24713 +const uIntf *d; /* list of base values for non-simple codes */
24714 +const uIntf *e; /* list of extra bits for non-simple codes */
24715 +inflate_huft * FAR *t; /* result: starting table */
24716 +uIntf *m; /* maximum lookup bits, returns actual */
24717 +inflate_huft *hp; /* space for trees */
24718 +uInt *hn; /* hufts used in space */
24719 +uIntf *v; /* working area: values in order of bit length */
24720 +/* Given a list of code lengths and a maximum table size, make a set of
24721 + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
24722 + if the given code set is incomplete (the tables are still built in this
24723 + case), or Z_DATA_ERROR if the input is invalid. */
24724 +{
24725 +
24726 + uInt a; /* counter for codes of length k */
24727 + uInt c[BMAX+1]; /* bit length count table */
24728 + uInt f; /* i repeats in table every f entries */
24729 + int g; /* maximum code length */
24730 + int h; /* table level */
24731 + register uInt i; /* counter, current code */
24732 + register uInt j; /* counter */
24733 + register int k; /* number of bits in current code */
24734 + int l; /* bits per table (returned in m) */
24735 + uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
24736 + register uIntf *p; /* pointer into c[], b[], or v[] */
24737 + inflate_huft *q; /* points to current table */
24738 + struct inflate_huft_s r; /* table entry for structure assignment */
24739 + inflate_huft *u[BMAX]; /* table stack */
24740 + register int w; /* bits before this table == (l * h) */
24741 + uInt x[BMAX+1]; /* bit offsets, then code stack */
24742 + uIntf *xp; /* pointer into x */
24743 + int y; /* number of dummy codes added */
24744 + uInt z; /* number of entries in current table */
24745 +
24746 +
24747 + /* Generate counts for each bit length */
24748 + p = c;
24749 +#define C0 *p++ = 0;
24750 +#define C2 C0 C0 C0 C0
24751 +#define C4 C2 C2 C2 C2
24752 + C4 /* clear c[]--assume BMAX+1 is 16 */
24753 + p = b; i = n;
24754 + do {
24755 + c[*p++]++; /* assume all entries <= BMAX */
24756 + } while (--i);
24757 + if (c[0] == n) /* null input--all zero length codes */
24758 + {
24759 + *t = (inflate_huft *)Z_NULL;
24760 + *m = 0;
24761 + return Z_OK;
24762 + }
24763 +
24764 +
24765 + /* Find minimum and maximum length, bound *m by those */
24766 + l = *m;
24767 + for (j = 1; j <= BMAX; j++)
24768 + if (c[j])
24769 + break;
24770 + k = j; /* minimum code length */
24771 + if ((uInt)l < j)
24772 + l = j;
24773 + for (i = BMAX; i; i--)
24774 + if (c[i])
24775 + break;
24776 + g = i; /* maximum code length */
24777 + if ((uInt)l > i)
24778 + l = i;
24779 + *m = l;
24780 +
24781 +
24782 + /* Adjust last length count to fill out codes, if needed */
24783 + for (y = 1 << j; j < i; j++, y <<= 1)
24784 + if ((y -= c[j]) < 0)
24785 + return Z_DATA_ERROR;
24786 + if ((y -= c[i]) < 0)
24787 + return Z_DATA_ERROR;
24788 + c[i] += y;
24789 +
24790 +
24791 + /* Generate starting offsets into the value table for each length */
24792 + x[1] = j = 0;
24793 + p = c + 1; xp = x + 2;
24794 + while (--i) { /* note that i == g from above */
24795 + *xp++ = (j += *p++);
24796 + }
24797 +
24798 +
24799 + /* Make a table of values in order of bit lengths */
24800 + p = b; i = 0;
24801 + do {
24802 + if ((j = *p++) != 0)
24803 + v[x[j]++] = i;
24804 + } while (++i < n);
24805 + n = x[g]; /* set n to length of v */
24806 +
24807 +
24808 + /* Generate the Huffman codes and for each, make the table entries */
24809 + x[0] = i = 0; /* first Huffman code is zero */
24810 + p = v; /* grab values in bit order */
24811 + h = -1; /* no tables yet--level -1 */
24812 + w = -l; /* bits decoded == (l * h) */
24813 + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
24814 + q = (inflate_huft *)Z_NULL; /* ditto */
24815 + z = 0; /* ditto */
24816 +
24817 + /* go through the bit lengths (k already is bits in shortest code) */
24818 + for (; k <= g; k++)
24819 + {
24820 + a = c[k];
24821 + while (a--)
24822 + {
24823 + /* here i is the Huffman code of length k bits for value *p */
24824 + /* make tables up to required level */
24825 + while (k > w + l)
24826 + {
24827 + h++;
24828 + w += l; /* previous table always l bits */
24829 +
24830 + /* compute minimum size table less than or equal to l bits */
24831 + z = g - w;
24832 + z = z > (uInt)l ? l : z; /* table size upper limit */
24833 + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
24834 + { /* too few codes for k-w bit table */
24835 + f -= a + 1; /* deduct codes from patterns left */
24836 + xp = c + k;
24837 + if (j < z)
24838 + while (++j < z) /* try smaller tables up to z bits */
24839 + {
24840 + if ((f <<= 1) <= *++xp)
24841 + break; /* enough codes to use up j bits */
24842 + f -= *xp; /* else deduct codes from patterns */
24843 + }
24844 + }
24845 + z = 1 << j; /* table entries for j-bit table */
24846 +
24847 + /* allocate new table */
24848 + if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
24849 + return Z_DATA_ERROR; /* overflow of MANY */
24850 + u[h] = q = hp + *hn;
24851 + *hn += z;
24852 +
24853 + /* connect to last table, if there is one */
24854 + if (h)
24855 + {
24856 + x[h] = i; /* save pattern for backing up */
24857 + r.bits = (Byte)l; /* bits to dump before this table */
24858 + r.exop = (Byte)j; /* bits in this table */
24859 + j = i >> (w - l);
24860 + r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
24861 + u[h-1][j] = r; /* connect to last table */
24862 + }
24863 + else
24864 + *t = q; /* first table is returned result */
24865 + }
24866 +
24867 + /* set up table entry in r */
24868 + r.bits = (Byte)(k - w);
24869 + if (p >= v + n)
24870 + r.exop = 128 + 64; /* out of values--invalid code */
24871 + else if (*p < s)
24872 + {
24873 + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
24874 + r.base = *p++; /* simple code is just the value */
24875 + }
24876 + else
24877 + {
24878 + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
24879 + r.base = d[*p++ - s];
24880 + }
24881 +
24882 + /* fill code-like entries with r */
24883 + f = 1 << (k - w);
24884 + for (j = i >> w; j < z; j += f)
24885 + q[j] = r;
24886 +
24887 + /* backwards increment the k-bit code i */
24888 + for (j = 1 << (k - 1); i & j; j >>= 1)
24889 + i ^= j;
24890 + i ^= j;
24891 +
24892 + /* backup over finished tables */
24893 + mask = (1 << w) - 1; /* needed on HP, cc -O bug */
24894 + while ((i & mask) != x[h])
24895 + {
24896 + h--; /* don't need to update q */
24897 + w -= l;
24898 + mask = (1 << w) - 1;
24899 + }
24900 + }
24901 + }
24902 +
24903 +
24904 + /* Return Z_BUF_ERROR if we were given an incomplete table */
24905 + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
24906 +}
24907 +
24908 +
24909 +int inflate_trees_bits(c, bb, tb, hp, z)
24910 +uIntf *c; /* 19 code lengths */
24911 +uIntf *bb; /* bits tree desired/actual depth */
24912 +inflate_huft * FAR *tb; /* bits tree result */
24913 +inflate_huft *hp; /* space for trees */
24914 +z_streamp z; /* for messages */
24915 +{
24916 + int r;
24917 + uInt hn = 0; /* hufts used in space */
24918 + uIntf *v; /* work area for huft_build */
24919 +
24920 + if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
24921 + return Z_MEM_ERROR;
24922 + r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
24923 + tb, bb, hp, &hn, v);
24924 + if (r == Z_DATA_ERROR)
24925 + z->msg = (char*)"oversubscribed dynamic bit lengths tree";
24926 + else if (r == Z_BUF_ERROR || *bb == 0)
24927 + {
24928 + z->msg = (char*)"incomplete dynamic bit lengths tree";
24929 + r = Z_DATA_ERROR;
24930 + }
24931 + ZFREE(z, v);
24932 + return r;
24933 +}
24934 +
24935 +
24936 +int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
24937 +uInt nl; /* number of literal/length codes */
24938 +uInt nd; /* number of distance codes */
24939 +uIntf *c; /* that many (total) code lengths */
24940 +uIntf *bl; /* literal desired/actual bit depth */
24941 +uIntf *bd; /* distance desired/actual bit depth */
24942 +inflate_huft * FAR *tl; /* literal/length tree result */
24943 +inflate_huft * FAR *td; /* distance tree result */
24944 +inflate_huft *hp; /* space for trees */
24945 +z_streamp z; /* for messages */
24946 +{
24947 + int r;
24948 + uInt hn = 0; /* hufts used in space */
24949 + uIntf *v; /* work area for huft_build */
24950 +
24951 + /* allocate work area */
24952 + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
24953 + return Z_MEM_ERROR;
24954 +
24955 + /* build literal/length tree */
24956 + r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
24957 + if (r != Z_OK || *bl == 0)
24958 + {
24959 + if (r == Z_DATA_ERROR)
24960 + z->msg = (char*)"oversubscribed literal/length tree";
24961 + else if (r != Z_MEM_ERROR)
24962 + {
24963 + z->msg = (char*)"incomplete literal/length tree";
24964 + r = Z_DATA_ERROR;
24965 + }
24966 + ZFREE(z, v);
24967 + return r;
24968 + }
24969 +
24970 + /* build distance tree */
24971 + r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
24972 + if (r != Z_OK || (*bd == 0 && nl > 257))
24973 + {
24974 + if (r == Z_DATA_ERROR)
24975 + z->msg = (char*)"oversubscribed distance tree";
24976 + else if (r == Z_BUF_ERROR) {
24977 +#ifdef PKZIP_BUG_WORKAROUND
24978 + r = Z_OK;
24979 + }
24980 +#else
24981 + z->msg = (char*)"incomplete distance tree";
24982 + r = Z_DATA_ERROR;
24983 + }
24984 + else if (r != Z_MEM_ERROR)
24985 + {
24986 + z->msg = (char*)"empty distance tree with lengths";
24987 + r = Z_DATA_ERROR;
24988 + }
24989 + ZFREE(z, v);
24990 + return r;
24991 +#endif
24992 + }
24993 +
24994 + /* done */
24995 + ZFREE(z, v);
24996 + return Z_OK;
24997 +}
24998 +
24999 +
25000 +/* build fixed tables only once--keep them here */
25001 +#ifdef BUILDFIXED
25002 +local int fixed_built = 0;
25003 +#define FIXEDH 544 /* number of hufts used by fixed tables */
25004 +local inflate_huft fixed_mem[FIXEDH];
25005 +local uInt fixed_bl;
25006 +local uInt fixed_bd;
25007 +local inflate_huft *fixed_tl;
25008 +local inflate_huft *fixed_td;
25009 +#else
25010 +#include "inffixed.h"
25011 +#endif
25012 +
25013 +
25014 +int inflate_trees_fixed(bl, bd, tl, td, z)
25015 +uIntf *bl; /* literal desired/actual bit depth */
25016 +uIntf *bd; /* distance desired/actual bit depth */
25017 +inflate_huft * FAR *tl; /* literal/length tree result */
25018 +inflate_huft * FAR *td; /* distance tree result */
25019 +z_streamp z; /* for memory allocation */
25020 +{
25021 +#ifdef BUILDFIXED
25022 + /* build fixed tables if not already */
25023 + if (!fixed_built)
25024 + {
25025 + int k; /* temporary variable */
25026 + uInt f = 0; /* number of hufts used in fixed_mem */
25027 + uIntf *c; /* length list for huft_build */
25028 + uIntf *v; /* work area for huft_build */
25029 +
25030 + /* allocate memory */
25031 + if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25032 + return Z_MEM_ERROR;
25033 + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25034 + {
25035 + ZFREE(z, c);
25036 + return Z_MEM_ERROR;
25037 + }
25038 +
25039 + /* literal table */
25040 + for (k = 0; k < 144; k++)
25041 + c[k] = 8;
25042 + for (; k < 256; k++)
25043 + c[k] = 9;
25044 + for (; k < 280; k++)
25045 + c[k] = 7;
25046 + for (; k < 288; k++)
25047 + c[k] = 8;
25048 + fixed_bl = 9;
25049 + huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
25050 + fixed_mem, &f, v);
25051 +
25052 + /* distance table */
25053 + for (k = 0; k < 30; k++)
25054 + c[k] = 5;
25055 + fixed_bd = 5;
25056 + huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
25057 + fixed_mem, &f, v);
25058 +
25059 + /* done */
25060 + ZFREE(z, v);
25061 + ZFREE(z, c);
25062 + fixed_built = 1;
25063 + }
25064 +#endif
25065 + *bl = fixed_bl;
25066 + *bd = fixed_bd;
25067 + *tl = fixed_tl;
25068 + *td = fixed_td;
25069 + return Z_OK;
25070 +}
25071 --- /dev/null Tue Mar 11 13:02:56 2003
25072 +++ linux/net/ipsec/inftrees.h Mon Feb 9 13:51:03 2004
25073 @@ -0,0 +1,63 @@
25074 +/* inftrees.h -- header to use inftrees.c
25075 + * Copyright (C) 1995-2002 Mark Adler
25076 + * For conditions of distribution and use, see copyright notice in zlib.h
25077 + */
25078 +
25079 +/* WARNING: this file should *not* be used by applications. It is
25080 + part of the implementation of the compression library and is
25081 + subject to change. Applications should only use zlib.h.
25082 + */
25083 +
25084 +/* Huffman code lookup table entry--this entry is four bytes for machines
25085 + that have 16-bit pointers (e.g. PC's in the small or medium model). */
25086 +
25087 +#ifndef _INFTREES_H
25088 +#define _INFTREES_H
25089 +
25090 +typedef struct inflate_huft_s FAR inflate_huft;
25091 +
25092 +struct inflate_huft_s {
25093 + union {
25094 + struct {
25095 + Byte Exop; /* number of extra bits or operation */
25096 + Byte Bits; /* number of bits in this code or subcode */
25097 + } what;
25098 + uInt pad; /* pad structure to a power of 2 (4 bytes for */
25099 + } word; /* 16-bit, 8 bytes for 32-bit int's) */
25100 + uInt base; /* literal, length base, distance base,
25101 + or table offset */
25102 +};
25103 +
25104 +/* Maximum size of dynamic tree. The maximum found in a long but non-
25105 + exhaustive search was 1004 huft structures (850 for length/literals
25106 + and 154 for distances, the latter actually the result of an
25107 + exhaustive search). The actual maximum is not known, but the
25108 + value below is more than safe. */
25109 +#define MANY 1440
25110 +
25111 +extern int inflate_trees_bits OF((
25112 + uIntf *, /* 19 code lengths */
25113 + uIntf *, /* bits tree desired/actual depth */
25114 + inflate_huft * FAR *, /* bits tree result */
25115 + inflate_huft *, /* space for trees */
25116 + z_streamp)); /* for messages */
25117 +
25118 +extern int inflate_trees_dynamic OF((
25119 + uInt, /* number of literal/length codes */
25120 + uInt, /* number of distance codes */
25121 + uIntf *, /* that many (total) code lengths */
25122 + uIntf *, /* literal desired/actual bit depth */
25123 + uIntf *, /* distance desired/actual bit depth */
25124 + inflate_huft * FAR *, /* literal/length tree result */
25125 + inflate_huft * FAR *, /* distance tree result */
25126 + inflate_huft *, /* space for trees */
25127 + z_streamp)); /* for messages */
25128 +
25129 +extern int inflate_trees_fixed OF((
25130 + uIntf *, /* literal desired/actual bit depth */
25131 + uIntf *, /* distance desired/actual bit depth */
25132 + inflate_huft * FAR *, /* literal/length tree result */
25133 + inflate_huft * FAR *, /* distance tree result */
25134 + z_streamp)); /* for memory allocation */
25135 +
25136 +#endif /* _INFTREES_H */
25137 --- /dev/null Tue Mar 11 13:02:56 2003
25138 +++ linux/net/ipsec/infutil.c Mon Feb 9 13:51:03 2004
25139 @@ -0,0 +1,87 @@
25140 +/* inflate_util.c -- data and routines common to blocks and codes
25141 + * Copyright (C) 1995-2002 Mark Adler
25142 + * For conditions of distribution and use, see copyright notice in zlib.h
25143 + */
25144 +
25145 +#include <zlib/zutil.h>
25146 +#include "infblock.h"
25147 +#include "inftrees.h"
25148 +#include "infcodes.h"
25149 +#include "infutil.h"
25150 +
25151 +struct inflate_codes_state {int dummy;}; /* for buggy compilers */
25152 +
25153 +/* And'ing with mask[n] masks the lower n bits */
25154 +uInt inflate_mask[17] = {
25155 + 0x0000,
25156 + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
25157 + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
25158 +};
25159 +
25160 +
25161 +/* copy as much as possible from the sliding window to the output area */
25162 +int inflate_flush(s, z, r)
25163 +inflate_blocks_statef *s;
25164 +z_streamp z;
25165 +int r;
25166 +{
25167 + uInt n;
25168 + Bytef *p;
25169 + Bytef *q;
25170 +
25171 + /* local copies of source and destination pointers */
25172 + p = z->next_out;
25173 + q = s->read;
25174 +
25175 + /* compute number of bytes to copy as far as end of window */
25176 + n = (uInt)((q <= s->write ? s->write : s->end) - q);
25177 + if (n > z->avail_out) n = z->avail_out;
25178 + if (n && r == Z_BUF_ERROR) r = Z_OK;
25179 +
25180 + /* update counters */
25181 + z->avail_out -= n;
25182 + z->total_out += n;
25183 +
25184 + /* update check information */
25185 + if (s->checkfn != Z_NULL)
25186 + z->adler = s->check = (*s->checkfn)(s->check, q, n);
25187 +
25188 + /* copy as far as end of window */
25189 + zmemcpy(p, q, n);
25190 + p += n;
25191 + q += n;
25192 +
25193 + /* see if more to copy at beginning of window */
25194 + if (q == s->end)
25195 + {
25196 + /* wrap pointers */
25197 + q = s->window;
25198 + if (s->write == s->end)
25199 + s->write = s->window;
25200 +
25201 + /* compute bytes to copy */
25202 + n = (uInt)(s->write - q);
25203 + if (n > z->avail_out) n = z->avail_out;
25204 + if (n && r == Z_BUF_ERROR) r = Z_OK;
25205 +
25206 + /* update counters */
25207 + z->avail_out -= n;
25208 + z->total_out += n;
25209 +
25210 + /* update check information */
25211 + if (s->checkfn != Z_NULL)
25212 + z->adler = s->check = (*s->checkfn)(s->check, q, n);
25213 +
25214 + /* copy */
25215 + zmemcpy(p, q, n);
25216 + p += n;
25217 + q += n;
25218 + }
25219 +
25220 + /* update pointers */
25221 + z->next_out = p;
25222 + s->read = q;
25223 +
25224 + /* done */
25225 + return r;
25226 +}
25227 --- /dev/null Tue Mar 11 13:02:56 2003
25228 +++ linux/net/ipsec/infutil.h Mon Feb 9 13:51:03 2004
25229 @@ -0,0 +1,98 @@
25230 +/* infutil.h -- types and macros common to blocks and codes
25231 + * Copyright (C) 1995-2002 Mark Adler
25232 + * For conditions of distribution and use, see copyright notice in zlib.h
25233 + */
25234 +
25235 +/* WARNING: this file should *not* be used by applications. It is
25236 + part of the implementation of the compression library and is
25237 + subject to change. Applications should only use zlib.h.
25238 + */
25239 +
25240 +#ifndef _INFUTIL_H
25241 +#define _INFUTIL_H
25242 +
25243 +typedef enum {
25244 + TYPE, /* get type bits (3, including end bit) */
25245 + LENS, /* get lengths for stored */
25246 + STORED, /* processing stored block */
25247 + TABLE, /* get table lengths */
25248 + BTREE, /* get bit lengths tree for a dynamic block */
25249 + DTREE, /* get length, distance trees for a dynamic block */
25250 + CODES, /* processing fixed or dynamic block */
25251 + DRY, /* output remaining window bytes */
25252 + DONE, /* finished last block, done */
25253 + BAD} /* got a data error--stuck here */
25254 +inflate_block_mode;
25255 +
25256 +/* inflate blocks semi-private state */
25257 +struct inflate_blocks_state {
25258 +
25259 + /* mode */
25260 + inflate_block_mode mode; /* current inflate_block mode */
25261 +
25262 + /* mode dependent information */
25263 + union {
25264 + uInt left; /* if STORED, bytes left to copy */
25265 + struct {
25266 + uInt table; /* table lengths (14 bits) */
25267 + uInt index; /* index into blens (or border) */
25268 + uIntf *blens; /* bit lengths of codes */
25269 + uInt bb; /* bit length tree depth */
25270 + inflate_huft *tb; /* bit length decoding tree */
25271 + } trees; /* if DTREE, decoding info for trees */
25272 + struct {
25273 + inflate_codes_statef
25274 + *codes;
25275 + } decode; /* if CODES, current state */
25276 + } sub; /* submode */
25277 + uInt last; /* true if this block is the last block */
25278 +
25279 + /* mode independent information */
25280 + uInt bitk; /* bits in bit buffer */
25281 + uLong bitb; /* bit buffer */
25282 + inflate_huft *hufts; /* single malloc for tree space */
25283 + Bytef *window; /* sliding window */
25284 + Bytef *end; /* one byte after sliding window */
25285 + Bytef *read; /* window read pointer */
25286 + Bytef *write; /* window write pointer */
25287 + check_func checkfn; /* check function */
25288 + uLong check; /* check on output */
25289 +
25290 +};
25291 +
25292 +
25293 +/* defines for inflate input/output */
25294 +/* update pointers and return */
25295 +#define UPDBITS {s->bitb=b;s->bitk=k;}
25296 +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
25297 +#define UPDOUT {s->write=q;}
25298 +#define UPDATE {UPDBITS UPDIN UPDOUT}
25299 +#define LEAVE {UPDATE return inflate_flush(s,z,r);}
25300 +/* get bytes and bits */
25301 +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
25302 +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
25303 +#define NEXTBYTE (n--,*p++)
25304 +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
25305 +#define DUMPBITS(j) {b>>=(j);k-=(j);}
25306 +/* output bytes */
25307 +#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
25308 +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
25309 +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
25310 +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
25311 +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
25312 +#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
25313 +/* load local pointers */
25314 +#define LOAD {LOADIN LOADOUT}
25315 +
25316 +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
25317 +extern uInt inflate_mask[17];
25318 +
25319 +/* copy as much as possible from the sliding window to the output area */
25320 +extern int inflate_flush OF((
25321 + inflate_blocks_statef *,
25322 + z_streamp ,
25323 + int));
25324 +
25325 +struct internal_state {int dummy;}; /* for buggy compilers */
25326 +
25327 +#endif /* _INFUTIL_H */
25328 --- /dev/null Tue Mar 11 13:02:56 2003
25329 +++ linux/net/ipsec/initaddr.c Mon Feb 9 13:51:03 2004
25330 @@ -0,0 +1,50 @@
25331 +/*
25332 + * initialize address structure
25333 + * Copyright (C) 2000 Henry Spencer.
25334 + *
25335 + * This library is free software; you can redistribute it and/or modify it
25336 + * under the terms of the GNU Library General Public License as published by
25337 + * the Free Software Foundation; either version 2 of the License, or (at your
25338 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
25339 + *
25340 + * This library is distributed in the hope that it will be useful, but
25341 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25342 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
25343 + * License for more details.
25344 + *
25345 + * RCSID $Id: initaddr.c,v 1.6 2004/07/10 07:43:47 mcr Exp $
25346 + */
25347 +#include "openswan.h"
25348 +
25349 +/*
25350 + - initaddr - initialize ip_address from bytes
25351 + */
25352 +err_t /* NULL for success, else string literal */
25353 +initaddr(src, srclen, af, dst)
25354 +const unsigned char *src;
25355 +size_t srclen;
25356 +int af; /* address family */
25357 +ip_address *dst;
25358 +{
25359 + switch (af) {
25360 + case AF_INET:
25361 + if (srclen != 4)
25362 + return "IPv4 address must be exactly 4 bytes";
25363 + dst->u.v4.sin_family = af;
25364 + dst->u.v4.sin_port = 0; /* unused */
25365 + memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen);
25366 + break;
25367 + case AF_INET6:
25368 + if (srclen != 16)
25369 + return "IPv6 address must be exactly 16 bytes";
25370 + dst->u.v6.sin6_family = af;
25371 + dst->u.v6.sin6_flowinfo = 0; /* unused */
25372 + dst->u.v6.sin6_port = 0; /* unused */
25373 + memcpy((char *)&dst->u.v6.sin6_addr, src, srclen);
25374 + break;
25375 + default:
25376 + return "unknown address family in initaddr";
25377 + break;
25378 + }
25379 + return NULL;
25380 +}
25381 --- /dev/null Tue Mar 11 13:02:56 2003
25382 +++ linux/net/ipsec/ipcomp.c Mon Feb 9 13:51:03 2004
25383 @@ -0,0 +1,704 @@
25384 +/*
25385 + * IPCOMP zlib interface code.
25386 + * implementation of RFC 3173.
25387 + *
25388 + * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
25389 + * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
25390 + *
25391 + * This program is free software; you can redistribute it and/or modify it
25392 + * under the terms of the GNU General Public License as published by the
25393 + * Free Software Foundation; either version 2 of the License, or (at your
25394 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
25395 + *
25396 + * This program is distributed in the hope that it will be useful, but
25397 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25398 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25399 + * for more details.
25400 + */
25401 +
25402 +char ipcomp_c_version[] = "RCSID $Id: ipcomp.c,v 1.41.2.3 2006/04/20 15:46:58 mcr Exp $";
25403 +
25404 +/* SSS */
25405 +
25406 +#ifndef AUTOCONF_INCLUDED
25407 +#include <linux/config.h>
25408 +#endif
25409 +#include <linux/version.h>
25410 +
25411 +#define __NO_VERSION__
25412 +#include <linux/module.h>
25413 +#include <linux/kernel.h> /* printk() */
25414 +
25415 +#include "openswan/ipsec_param.h"
25416 +
25417 +#ifdef MALLOC_SLAB
25418 +# include <linux/slab.h> /* kmalloc() */
25419 +#else /* MALLOC_SLAB */
25420 +# include <linux/malloc.h> /* kmalloc() */
25421 +#endif /* MALLOC_SLAB */
25422 +#include <linux/errno.h> /* error codes */
25423 +#include <linux/types.h>
25424 +#include <linux/netdevice.h>
25425 +#include <linux/ip.h>
25426 +#include <linux/skbuff.h>
25427 +
25428 +#include <linux/netdevice.h> /* struct device, and other headers */
25429 +#include <linux/etherdevice.h> /* eth_type_trans */
25430 +#include <linux/ip.h> /* struct iphdr */
25431 +#include <linux/skbuff.h>
25432 +#include <asm/uaccess.h>
25433 +#include <asm/checksum.h>
25434 +
25435 +#include <openswan.h>
25436 +
25437 +#include <net/ip.h>
25438 +
25439 +#include "openswan/ipsec_kern24.h"
25440 +#include "openswan/radij.h"
25441 +#include "openswan/ipsec_encap.h"
25442 +#include "openswan/ipsec_sa.h"
25443 +
25444 +#include "openswan/ipsec_xform.h"
25445 +#include "openswan/ipsec_tunnel.h"
25446 +#include "openswan/ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */
25447 +#include "openswan/ipsec_proto.h"
25448 +#include "openswan/ipcomp.h"
25449 +#include "zlib/zlib.h"
25450 +#include "zlib/zutil.h"
25451 +
25452 +#include <openswan/pfkeyv2.h> /* SADB_X_CALG_DEFLATE */
25453 +
25454 +#ifdef CONFIG_KLIPS_DEBUG
25455 +int sysctl_ipsec_debug_ipcomp = 0;
25456 +#endif /* CONFIG_KLIPS_DEBUG */
25457 +
25458 +static
25459 +struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask);
25460 +
25461 +static
25462 +voidpf my_zcalloc(voidpf opaque, uInt items, uInt size)
25463 +{
25464 + return (voidpf) kmalloc(items*size, GFP_ATOMIC);
25465 +}
25466 +
25467 +static
25468 +void my_zfree(voidpf opaque, voidpf address)
25469 +{
25470 + kfree(address);
25471 +}
25472 +
25473 +/*
25474 + * We use this function because sometimes we want to pass a negative offset
25475 + * into skb_put(), this does not work on 64bit platforms because long to
25476 + * unsigned int casting.
25477 + */
25478 +static inline unsigned char *
25479 +safe_skb_put(struct sk_buff *skb, int extend)
25480 +{
25481 + unsigned char *ptr;
25482 +
25483 + if (extend>0) {
25484 + // increase the size of the packet
25485 + ptr = skb_put(skb, extend);
25486 + } else {
25487 + // shrink the size of the packet
25488 + ptr = skb->tail;
25489 + skb_trim (skb, skb->len + extend);
25490 + }
25491 +
25492 + return ptr;
25493 +}
25494 +
25495 +struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
25496 +{
25497 + struct iphdr *iph;
25498 + unsigned int iphlen, pyldsz, cpyldsz;
25499 + unsigned char *buffer;
25500 + z_stream zs;
25501 + int zresult;
25502 +
25503 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25504 + "klips_debug:skb_compress: .\n");
25505 +
25506 + if(skb == NULL) {
25507 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25508 + "klips_debug:skb_compress: "
25509 + "passed in NULL skb, returning ERROR.\n");
25510 + if(flags != NULL) {
25511 + *flags |= IPCOMP_PARMERROR;
25512 + }
25513 + return skb;
25514 + }
25515 +
25516 + if(ips == NULL) {
25517 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25518 + "klips_debug:skb_compress: "
25519 + "passed in NULL ipsec_sa needed for cpi, returning ERROR.\n");
25520 + if(flags) {
25521 + *flags |= IPCOMP_PARMERROR;
25522 + }
25523 + return skb;
25524 + }
25525 +
25526 + if (flags == NULL) {
25527 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25528 + "klips_debug:skb_compress: "
25529 + "passed in NULL flags, returning ERROR.\n");
25530 + ipsec_kfree_skb(skb);
25531 + return NULL;
25532 + }
25533 +
25534 +#ifdef NET_21
25535 + iph = skb->nh.iph;
25536 +#else /* NET_21 */
25537 + iph = skb->ip_hdr;
25538 +#endif /* NET_21 */
25539 +
25540 + switch (iph->protocol) {
25541 + case IPPROTO_COMP:
25542 + case IPPROTO_AH:
25543 + case IPPROTO_ESP:
25544 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25545 + "klips_debug:skb_compress: "
25546 + "skipping compression of packet with ip protocol %d.\n",
25547 + iph->protocol);
25548 + *flags |= IPCOMP_UNCOMPRESSABLE;
25549 + return skb;
25550 + }
25551 +
25552 + /* Don't compress packets already fragmented */
25553 + if (iph->frag_off & __constant_htons(IP_MF | IP_OFFSET)) {
25554 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25555 + "klips_debug:skb_compress: "
25556 + "skipping compression of fragmented packet.\n");
25557 + *flags |= IPCOMP_UNCOMPRESSABLE;
25558 + return skb;
25559 + }
25560 +
25561 + iphlen = iph->ihl << 2;
25562 + pyldsz = ntohs(iph->tot_len) - iphlen;
25563 +
25564 + /* Don't compress less than 90 bytes (rfc 2394) */
25565 + if (pyldsz < 90) {
25566 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25567 + "klips_debug:skb_compress: "
25568 + "skipping compression of tiny packet, len=%d.\n",
25569 + pyldsz);
25570 + *flags |= IPCOMP_UNCOMPRESSABLE;
25571 + return skb;
25572 + }
25573 +
25574 + /* Adaptive decision */
25575 + if (ips->ips_comp_adapt_skip) {
25576 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25577 + "klips_debug:skb_compress: "
25578 + "skipping compression: ips_comp_adapt_skip=%d.\n",
25579 + ips->ips_comp_adapt_skip);
25580 + ips->ips_comp_adapt_skip--;
25581 + *flags |= IPCOMP_UNCOMPRESSABLE;
25582 + return skb;
25583 + }
25584 +
25585 + zs.zalloc = my_zcalloc;
25586 + zs.zfree = my_zfree;
25587 + zs.opaque = 0;
25588 +
25589 + /* We want to use deflateInit2 because we don't want the adler
25590 + header. */
25591 + zresult = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -11,
25592 + DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
25593 + if (zresult != Z_OK) {
25594 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25595 + "klips_error:skb_compress: "
25596 + "deflateInit2() returned error %d (%s), "
25597 + "skipping compression.\n",
25598 + zresult,
25599 + zs.msg ? zs.msg : zError(zresult));
25600 + *flags |= IPCOMP_COMPRESSIONERROR;
25601 + return skb;
25602 + }
25603 +
25604 +
25605 + /* Max output size. Result should be max this size.
25606 + * Implementation specific tweak:
25607 + * If it's not at least 32 bytes and 6.25% smaller than
25608 + * the original packet, it's probably not worth wasting
25609 + * the receiver's CPU cycles decompressing it.
25610 + * Your mileage may vary.
25611 + */
25612 + cpyldsz = pyldsz - sizeof(struct ipcomphdr) - (pyldsz <= 512 ? 32 : pyldsz >> 4);
25613 +
25614 + buffer = kmalloc(cpyldsz, GFP_ATOMIC);
25615 + if (!buffer) {
25616 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25617 + "klips_error:skb_compress: "
25618 + "unable to kmalloc(%d, GFP_ATOMIC), "
25619 + "skipping compression.\n",
25620 + cpyldsz);
25621 + *flags |= IPCOMP_COMPRESSIONERROR;
25622 + deflateEnd(&zs);
25623 + return skb;
25624 + }
25625 +
25626 +#ifdef CONFIG_KLIPS_DEBUG
25627 + if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
25628 + __u8 *c;
25629 +
25630 + c = (__u8*)iph + iphlen;
25631 + ipsec_dmp_block("compress before", c, pyldsz);
25632 + }
25633 +#endif /* CONFIG_KLIPS_DEBUG */
25634 +
25635 + zs.next_in = (char *) iph + iphlen; /* start of payload */
25636 + zs.avail_in = pyldsz;
25637 + zs.next_out = buffer; /* start of compressed payload */
25638 + zs.avail_out = cpyldsz;
25639 +
25640 + /* Finish compression in one step */
25641 + zresult = deflate(&zs, Z_FINISH);
25642 +
25643 + /* Free all dynamically allocated buffers */
25644 + deflateEnd(&zs);
25645 + if (zresult != Z_STREAM_END) {
25646 + *flags |= IPCOMP_UNCOMPRESSABLE;
25647 + kfree(buffer);
25648 +
25649 + /* Adjust adaptive counters */
25650 + if (++(ips->ips_comp_adapt_tries) == IPCOMP_ADAPT_INITIAL_TRIES) {
25651 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25652 + "klips_debug:skb_compress: "
25653 + "first %d packets didn't compress, "
25654 + "skipping next %d\n",
25655 + IPCOMP_ADAPT_INITIAL_TRIES,
25656 + IPCOMP_ADAPT_INITIAL_SKIP);
25657 + ips->ips_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP;
25658 + }
25659 + else if (ips->ips_comp_adapt_tries == IPCOMP_ADAPT_INITIAL_TRIES + IPCOMP_ADAPT_SUBSEQ_TRIES) {
25660 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25661 + "klips_debug:skb_compress: "
25662 + "next %d packets didn't compress, "
25663 + "skipping next %d\n",
25664 + IPCOMP_ADAPT_SUBSEQ_TRIES,
25665 + IPCOMP_ADAPT_SUBSEQ_SKIP);
25666 + ips->ips_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP;
25667 + ips->ips_comp_adapt_tries = IPCOMP_ADAPT_INITIAL_TRIES;
25668 + }
25669 +
25670 + return skb;
25671 + }
25672 +
25673 + /* resulting compressed size */
25674 + cpyldsz -= zs.avail_out;
25675 +
25676 + /* Insert IPCOMP header */
25677 + ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_nh = iph->protocol;
25678 + ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_flags = 0;
25679 + /* use the bottom 16 bits of the spi for the cpi. The top 16 bits are
25680 + for internal reference only. */
25681 + ((struct ipcomphdr*) (((char*)iph) + iphlen))->ipcomp_cpi = htons((__u16)(ntohl(ips->ips_said.spi) & 0x0000ffff));
25682 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25683 + "klips_debug:skb_compress: "
25684 + "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: raw=%d, comp=%d.\n",
25685 + ntohl(ips->ips_said.spi),
25686 + ntohl(ips->ips_said.spi) & 0x0000ffff,
25687 + ntohs(((struct ipcomphdr*)(((char*)iph)+iphlen))->ipcomp_cpi),
25688 + pyldsz,
25689 + cpyldsz);
25690 +
25691 + /* Update IP header */
25692 + iph->protocol = IPPROTO_COMP;
25693 + iph->tot_len = htons(iphlen + sizeof(struct ipcomphdr) + cpyldsz);
25694 +#if 1 /* XXX checksum is done by ipsec_tunnel ? */
25695 + iph->check = 0;
25696 + iph->check = ip_fast_csum((char *) iph, iph->ihl);
25697 +#endif
25698 +
25699 + /* Copy compressed payload */
25700 + memcpy((char *) iph + iphlen + sizeof(struct ipcomphdr),
25701 + buffer,
25702 + cpyldsz);
25703 + kfree(buffer);
25704 +
25705 + /* Update skb length/tail by "unputting" the shrinkage */
25706 + safe_skb_put (skb, cpyldsz + sizeof(struct ipcomphdr) - pyldsz);
25707 +
25708 +#ifdef CONFIG_KLIPS_DEBUG
25709 + if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
25710 + __u8 *c;
25711 +
25712 + c = (__u8*)iph + iphlen + sizeof(struct ipcomphdr);
25713 + ipsec_dmp_block("compress result", c, cpyldsz);
25714 + }
25715 +#endif /* CONFIG_KLIPS_DEBUG */
25716 +
25717 + ips->ips_comp_adapt_skip = 0;
25718 + ips->ips_comp_adapt_tries = 0;
25719 +
25720 + return skb;
25721 +}
25722 +
25723 +struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
25724 +{
25725 + struct sk_buff *nskb = NULL;
25726 +
25727 + /* original ip header */
25728 + struct iphdr *oiph, *iph;
25729 + unsigned int iphlen, pyldsz, cpyldsz;
25730 + z_stream zs;
25731 + int zresult;
25732 +
25733 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25734 + "klips_debug:skb_decompress: .\n");
25735 +
25736 + if(!skb) {
25737 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25738 + "klips_error:skb_decompress: "
25739 + "passed in NULL skb, returning ERROR.\n");
25740 + if (flags) *flags |= IPCOMP_PARMERROR;
25741 + return skb;
25742 + }
25743 +
25744 + if(!ips && sysctl_ipsec_inbound_policy_check) {
25745 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25746 + "klips_error:skb_decompress: "
25747 + "passed in NULL ipsec_sa needed for comp alg, returning ERROR.\n");
25748 + if (flags) *flags |= IPCOMP_PARMERROR;
25749 + return skb;
25750 + }
25751 +
25752 + if (!flags) {
25753 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25754 + "klips_error:skb_decompress: "
25755 + "passed in NULL flags, returning ERROR.\n");
25756 + ipsec_kfree_skb(skb);
25757 + return NULL;
25758 + }
25759 +
25760 +#ifdef NET_21
25761 + oiph = skb->nh.iph;
25762 +#else /* NET_21 */
25763 + oiph = skb->ip_hdr;
25764 +#endif /* NET_21 */
25765 +
25766 + iphlen = oiph->ihl << 2;
25767 +
25768 + if (oiph->protocol != IPPROTO_COMP) {
25769 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25770 + "klips_error:skb_decompress: "
25771 + "called with non-IPCOMP packet (protocol=%d),"
25772 + "skipping decompression.\n",
25773 + oiph->protocol);
25774 + *flags |= IPCOMP_PARMERROR;
25775 + return skb;
25776 + }
25777 +
25778 + if ( (((struct ipcomphdr*)((char*) oiph + iphlen))->ipcomp_flags != 0)
25779 + || ((((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi
25780 + != htons(SADB_X_CALG_DEFLATE))
25781 + && sysctl_ipsec_inbound_policy_check
25782 + && (!ips || (ips && (ips->ips_encalg != SADB_X_CALG_DEFLATE)))) ) {
25783 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25784 + "klips_error:skb_decompress: "
25785 + "called with incompatible IPCOMP packet (flags=%d, "
25786 + "cpi=%d), ips-compalg=%d, skipping decompression.\n",
25787 + ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags),
25788 + ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi),
25789 + ips ? ips->ips_encalg : 0);
25790 + *flags |= IPCOMP_PARMERROR;
25791 +
25792 + return skb;
25793 + }
25794 +
25795 + if (ntohs(oiph->frag_off) & ~0x4000) {
25796 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25797 + "klips_error:skb_decompress: "
25798 + "called with fragmented IPCOMP packet, "
25799 + "skipping decompression.\n");
25800 + *flags |= IPCOMP_PARMERROR;
25801 + return skb;
25802 + }
25803 +
25804 + /* original compressed payload size */
25805 + cpyldsz = ntohs(oiph->tot_len) - iphlen - sizeof(struct ipcomphdr);
25806 +
25807 + zs.zalloc = my_zcalloc;
25808 + zs.zfree = my_zfree;
25809 + zs.opaque = 0;
25810 +
25811 + zs.next_in = (char *) oiph + iphlen + sizeof(struct ipcomphdr);
25812 + zs.avail_in = cpyldsz;
25813 +
25814 + /* Maybe we should be a bit conservative about memory
25815 + requirements and use inflateInit2 */
25816 + /* Beware, that this might make us unable to decompress packets
25817 + from other implementations - HINT: check PGPnet source code */
25818 + /* We want to use inflateInit2 because we don't want the adler
25819 + header. */
25820 + zresult = inflateInit2(&zs, -15);
25821 + if (zresult != Z_OK) {
25822 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25823 + "klips_error:skb_decompress: "
25824 + "inflateInit2() returned error %d (%s), "
25825 + "skipping decompression.\n",
25826 + zresult,
25827 + zs.msg ? zs.msg : zError(zresult));
25828 + *flags |= IPCOMP_DECOMPRESSIONERROR;
25829 +
25830 + return skb;
25831 + }
25832 +
25833 + /* We have no way of knowing the exact length of the resulting
25834 + decompressed output before we have actually done the decompression.
25835 + For now, we guess that the packet will not be bigger than the
25836 + attached ipsec device's mtu or 16260, whichever is biggest.
25837 + This may be wrong, since the sender's mtu may be bigger yet.
25838 + XXX This must be dealt with later XXX
25839 + */
25840 +
25841 + /* max payload size */
25842 + pyldsz = skb->dev ? (skb->dev->mtu < 16260 ? 16260 : skb->dev->mtu)
25843 + : (65520 - iphlen);
25844 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25845 + "klips_debug:skb_decompress: "
25846 + "max payload size: %d\n", pyldsz);
25847 +
25848 + while (pyldsz > (cpyldsz + sizeof(struct ipcomphdr)) &&
25849 + (nskb = skb_copy_ipcomp(skb,
25850 + pyldsz - cpyldsz - sizeof(struct ipcomphdr),
25851 + GFP_ATOMIC)) == NULL) {
25852 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25853 + "klips_error:skb_decompress: "
25854 + "unable to skb_copy_ipcomp(skb, %d, GFP_ATOMIC), "
25855 + "trying with less payload size.\n",
25856 + (int)(pyldsz - cpyldsz - sizeof(struct ipcomphdr)));
25857 + pyldsz >>=1;
25858 + }
25859 +
25860 + if (!nskb) {
25861 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25862 + "klips_error:skb_decompress: "
25863 + "unable to allocate memory, dropping packet.\n");
25864 + *flags |= IPCOMP_DECOMPRESSIONERROR;
25865 + inflateEnd(&zs);
25866 +
25867 + return skb;
25868 + }
25869 +
25870 +#ifdef CONFIG_KLIPS_DEBUG
25871 + if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
25872 + __u8 *c;
25873 +
25874 + c = (__u8*)oiph + iphlen + sizeof(struct ipcomphdr);
25875 + ipsec_dmp_block("decompress before", c, cpyldsz);
25876 + }
25877 +#endif /* CONFIG_KLIPS_DEBUG */
25878 +
25879 +#ifdef NET_21
25880 + iph = nskb->nh.iph;
25881 +#else /* NET_21 */
25882 + iph = nskb->ip_hdr;
25883 +#endif /* NET_21 */
25884 + zs.next_out = (char *)iph + iphlen;
25885 + zs.avail_out = pyldsz;
25886 +
25887 + zresult = inflate(&zs, Z_SYNC_FLUSH);
25888 +
25889 + /* work around a bug in zlib, which sometimes wants to taste an extra
25890 + * byte when being used in the (undocumented) raw deflate mode.
25891 + */
25892 + if (zresult == Z_OK && !zs.avail_in && zs.avail_out) {
25893 + __u8 zerostuff = 0;
25894 +
25895 + zs.next_in = &zerostuff;
25896 + zs.avail_in = 1;
25897 + zresult = inflate(&zs, Z_FINISH);
25898 + }
25899 +
25900 + inflateEnd(&zs);
25901 + if (zresult != Z_STREAM_END) {
25902 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25903 + "klips_error:skb_decompress: "
25904 + "inflate() returned error %d (%s), "
25905 + "skipping decompression.\n",
25906 + zresult,
25907 + zs.msg ? zs.msg : zError(zresult));
25908 + *flags |= IPCOMP_DECOMPRESSIONERROR;
25909 + ipsec_kfree_skb(nskb);
25910 +
25911 + return skb;
25912 + }
25913 +
25914 + /* Update IP header */
25915 + /* resulting decompressed size */
25916 + pyldsz -= zs.avail_out;
25917 + iph->tot_len = htons(iphlen + pyldsz);
25918 + iph->protocol = ((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_nh;
25919 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25920 + "klips_debug:skb_decompress: "
25921 + "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n",
25922 + ips ? ntohl(ips->ips_said.spi) : 0,
25923 + ips ? ntohl(ips->ips_said.spi) & 0x0000ffff : 0,
25924 + ntohs(((struct ipcomphdr*)(((char*)oiph)+iphlen))->ipcomp_cpi),
25925 + cpyldsz,
25926 + pyldsz,
25927 + iph->protocol);
25928 +
25929 +#if 1 /* XXX checksum is done by ipsec_rcv ? */
25930 + iph->check = 0;
25931 + iph->check = ip_fast_csum((char*) iph, iph->ihl);
25932 +#endif
25933 +
25934 + /* Update skb length/tail by "unputting" the unused data area */
25935 + safe_skb_put(nskb, -zs.avail_out);
25936 +
25937 + ipsec_kfree_skb(skb);
25938 +
25939 + if (iph->protocol == IPPROTO_COMP)
25940 + {
25941 +#ifdef CONFIG_KLIPS_DEBUG
25942 + if(sysctl_ipsec_debug_ipcomp)
25943 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25944 + "klips_debug:skb_decompress: "
25945 + "Eh? inner packet is also compressed, dropping.\n");
25946 +#endif /* CONFIG_KLIPS_DEBUG */
25947 +
25948 + ipsec_kfree_skb(nskb);
25949 + return NULL;
25950 + }
25951 +
25952 +#ifdef CONFIG_KLIPS_DEBUG
25953 + if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
25954 + __u8 *c;
25955 +
25956 + c = (__u8*)iph + iphlen;
25957 + ipsec_dmp_block("decompress result", c, pyldsz);
25958 + }
25959 +#endif /* CONFIG_KLIPS_DEBUG */
25960 +
25961 + return nskb;
25962 +}
25963 +
25964 +
25965 +/* this is derived from skb_copy() in linux 2.2.14 */
25966 +/* May be incompatible with other kernel versions!! */
25967 +static
25968 +struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask)
25969 +{
25970 + struct sk_buff *n;
25971 + struct iphdr *iph;
25972 + unsigned long offset;
25973 + unsigned int iphlen;
25974 +
25975 + if(!skb) {
25976 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
25977 + "klips_debug:skb_copy_ipcomp: "
25978 + "passed in NULL skb, returning NULL.\n");
25979 + return NULL;
25980 + }
25981 +
25982 + /*
25983 + * Allocate the copy buffer
25984 + */
25985 +
25986 +#ifdef NET_21
25987 + iph = skb->nh.iph;
25988 +#else /* NET_21 */
25989 + iph = skb->ip_hdr;
25990 +#endif /* NET_21 */
25991 + if (!iph) return NULL;
25992 + iphlen = iph->ihl << 2;
25993 +
25994 + n=alloc_skb(skb->end - skb->head + data_growth, gfp_mask);
25995 + if(n==NULL)
25996 + return NULL;
25997 +
25998 + /*
25999 + * Shift between the two data areas in bytes
26000 + */
26001 +
26002 + offset=n->head-skb->head;
26003 +
26004 + /* Set the data pointer */
26005 + skb_reserve(n,skb->data-skb->head);
26006 + /* Set the tail pointer and length */
26007 + safe_skb_put(n,skb->len+data_growth);
26008 + /* Copy the bytes up to and including the ip header */
26009 + memcpy(n->head,
26010 + skb->head,
26011 + ((char *)iph - (char *)skb->head) + iphlen);
26012 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
26013 + n->list=NULL;
26014 +#endif
26015 + n->next=NULL;
26016 + n->prev=NULL;
26017 + n->sk=NULL;
26018 + n->dev=skb->dev;
26019 + if (skb->h.raw)
26020 + n->h.raw=skb->h.raw+offset;
26021 + else
26022 + n->h.raw=NULL;
26023 + n->protocol=skb->protocol;
26024 +#ifdef NET_21
26025 + n->csum = 0;
26026 + n->priority=skb->priority;
26027 + n->dst=dst_clone(skb->dst);
26028 + n->nh.raw=skb->nh.raw+offset;
26029 +#ifndef NETDEV_23
26030 + n->is_clone=0;
26031 +#endif /* NETDEV_23 */
26032 + atomic_set(&n->users, 1);
26033 + n->destructor = NULL;
26034 +#ifdef HAVE_SOCK_SECURITY
26035 + n->security=skb->security;
26036 +#endif
26037 + memcpy(n->cb, skb->cb, sizeof(skb->cb));
26038 +#ifdef CONFIG_IP_FIREWALL
26039 + n->fwmark = skb->fwmark;
26040 +#endif
26041 +#else /* NET_21 */
26042 + n->link3=NULL;
26043 + n->when=skb->when;
26044 + n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
26045 + n->saddr=skb->saddr;
26046 + n->daddr=skb->daddr;
26047 + n->raddr=skb->raddr;
26048 + n->seq=skb->seq;
26049 + n->end_seq=skb->end_seq;
26050 + n->ack_seq=skb->ack_seq;
26051 + n->acked=skb->acked;
26052 + n->free=1;
26053 + n->arp=skb->arp;
26054 + n->tries=0;
26055 + n->lock=0;
26056 + n->users=0;
26057 + memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
26058 +#endif /* NET_21 */
26059 + if (skb->mac.raw)
26060 + n->mac.raw=skb->mac.raw+offset;
26061 + else
26062 + n->mac.raw=NULL;
26063 +#ifndef NETDEV_23
26064 + n->used=skb->used;
26065 +#endif /* !NETDEV_23 */
26066 + n->pkt_type=skb->pkt_type;
26067 +#ifndef NETDEV_23
26068 + n->pkt_bridged=skb->pkt_bridged;
26069 +#endif /* NETDEV_23 */
26070 + n->ip_summed=0;
26071 +#ifdef HAVE_TSTAMP
26072 + n->tstamp = skb->tstamp;
26073 +#else
26074 + n->stamp=skb->stamp;
26075 +#endif
26076 +#ifndef NETDEV_23 /* this seems to have been removed in 2.4 */
26077 +#if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE)
26078 + n->shapelatency=skb->shapelatency; /* Latency on frame */
26079 + n->shapeclock=skb->shapeclock; /* Time it should go out */
26080 + n->shapelen=skb->shapelen; /* Frame length in clocks */
26081 + n->shapestamp=skb->shapestamp; /* Stamp for shaper */
26082 + n->shapepend=skb->shapepend; /* Pending */
26083 +#endif /* defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) */
26084 +#endif /* NETDEV_23 */
26085 +
26086 + return n;
26087 +}
26088 --- /dev/null Tue Mar 11 13:02:56 2003
26089 +++ linux/net/ipsec/ipsec_ah.c Mon Feb 9 13:51:03 2004
26090 @@ -0,0 +1,404 @@
26091 +/*
26092 + * processing code for AH
26093 + * Copyright (C) 2003-2004 Michael Richardson <mcr@xelerance.com>
26094 + *
26095 + * This program is free software; you can redistribute it and/or modify it
26096 + * under the terms of the GNU General Public License as published by the
26097 + * Free Software Foundation; either version 2 of the License, or (at your
26098 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
26099 + *
26100 + * This program is distributed in the hope that it will be useful, but
26101 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26102 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26103 + * for more details.
26104 + */
26105 +
26106 +char ipsec_ah_c_version[] = "RCSID $Id: ipsec_ah.c,v 1.12.2.1 2006/02/15 05:35:14 paul Exp $";
26107 +#ifndef AUTOCONF_INCLUDED
26108 +#include <linux/config.h>
26109 +#endif
26110 +#include <linux/version.h>
26111 +
26112 +#define __NO_VERSION__
26113 +#include <linux/module.h>
26114 +#include <linux/kernel.h> /* printk() */
26115 +
26116 +#include "openswan/ipsec_param.h"
26117 +
26118 +#ifdef MALLOC_SLAB
26119 +# include <linux/slab.h> /* kmalloc() */
26120 +#else /* MALLOC_SLAB */
26121 +# include <linux/malloc.h> /* kmalloc() */
26122 +#endif /* MALLOC_SLAB */
26123 +#include <linux/errno.h> /* error codes */
26124 +#include <linux/types.h> /* size_t */
26125 +#include <linux/interrupt.h> /* mark_bh */
26126 +
26127 +#include <linux/netdevice.h> /* struct device, and other headers */
26128 +#include <linux/etherdevice.h> /* eth_type_trans */
26129 +#include <linux/ip.h> /* struct iphdr */
26130 +#include <linux/skbuff.h>
26131 +#include <openswan.h>
26132 +#ifdef SPINLOCK
26133 +# ifdef SPINLOCK_23
26134 +# include <linux/spinlock.h> /* *lock* */
26135 +# else /* SPINLOCK_23 */
26136 +# include <asm/spinlock.h> /* *lock* */
26137 +# endif /* SPINLOCK_23 */
26138 +#endif /* SPINLOCK */
26139 +
26140 +#include <net/ip.h>
26141 +#include <net/protocol.h>
26142 +
26143 +#include "openswan/radij.h"
26144 +#include "openswan/ipsec_encap.h"
26145 +#include "openswan/ipsec_sa.h"
26146 +
26147 +#include "openswan/ipsec_radij.h"
26148 +#include "openswan/ipsec_xform.h"
26149 +#include "openswan/ipsec_tunnel.h"
26150 +#include "openswan/ipsec_rcv.h"
26151 +#include "openswan/ipsec_xmit.h"
26152 +
26153 +#include "openswan/ipsec_auth.h"
26154 +#include "openswan/ipsec_ah.h"
26155 +#include "openswan/ipsec_proto.h"
26156 +
26157 +__u32 zeroes[AH_AMAX];
26158 +
26159 +enum ipsec_rcv_value
26160 +ipsec_rcv_ah_checks(struct ipsec_rcv_state *irs,
26161 + struct sk_buff *skb)
26162 +{
26163 + int ahminlen;
26164 +
26165 + ahminlen = irs->hard_header_len + sizeof(struct iphdr);
26166 +
26167 + /* take care not to deref this pointer until we check the minlen though */
26168 + irs->protostuff.ahstuff.ahp = (struct ahhdr *)skb->h.raw;
26169 +
26170 + if((skb->len < ahminlen+sizeof(struct ahhdr)) ||
26171 + (skb->len < ahminlen+(irs->protostuff.ahstuff.ahp->ah_hl << 2))) {
26172 + KLIPS_PRINT(debug_rcv & DB_RX_INAU,
26173 + "klips_debug:ipsec_rcv: "
26174 + "runt ah packet of skb->len=%d received from %s, dropped.\n",
26175 + skb->len,
26176 + irs->ipsaddr_txt);
26177 + if(irs->stats) {
26178 + irs->stats->rx_errors++;
26179 + }
26180 + return IPSEC_RCV_BADLEN;
26181 + }
26182 +
26183 + irs->said.spi = irs->protostuff.ahstuff.ahp->ah_spi;
26184 +
26185 + /* XXX we only support the one 12-byte authenticator for now */
26186 + if(irs->protostuff.ahstuff.ahp->ah_hl != ((AHHMAC_HASHLEN+AHHMAC_RPLLEN) >> 2)) {
26187 + KLIPS_PRINT(debug_rcv & DB_RX_INAU,
26188 + "klips_debug:ipsec_rcv: "
26189 + "bad authenticator length %ld, expected %lu from %s.\n",
26190 + (long)(irs->protostuff.ahstuff.ahp->ah_hl << 2),
26191 + (unsigned long) sizeof(struct ahhdr),
26192 + irs->ipsaddr_txt);
26193 + if(irs->stats) {
26194 + irs->stats->rx_errors++;
26195 + }
26196 + return IPSEC_RCV_BADLEN;
26197 + }
26198 +
26199 + return IPSEC_RCV_OK;
26200 +}
26201 +
26202 +
26203 +enum ipsec_rcv_value
26204 +ipsec_rcv_ah_setup_auth(struct ipsec_rcv_state *irs,
26205 + struct sk_buff *skb,
26206 + __u32 *replay,
26207 + unsigned char **authenticator)
26208 +{
26209 + struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26210 +
26211 + *replay = ntohl(ahp->ah_rpl);
26212 + *authenticator = ahp->ah_data;
26213 +
26214 + return IPSEC_RCV_OK;
26215 +}
26216 +
26217 +enum ipsec_rcv_value
26218 +ipsec_rcv_ah_authcalc(struct ipsec_rcv_state *irs,
26219 + struct sk_buff *skb)
26220 +{
26221 + struct auth_alg *aa;
26222 + struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26223 + union {
26224 + MD5_CTX md5;
26225 + SHA1_CTX sha1;
26226 + } tctx;
26227 + struct iphdr ipo;
26228 + int ahhlen;
26229 +
26230 + aa = irs->authfuncs;
26231 +
26232 + /* copy the initialized keying material */
26233 + memcpy(&tctx, irs->ictx, irs->ictx_len);
26234 +
26235 + ipo = *irs->ipp;
26236 + ipo.tos = 0; /* mutable RFC 2402 3.3.3.1.1.1 */
26237 + ipo.frag_off = 0;
26238 + ipo.ttl = 0;
26239 + ipo.check = 0;
26240 +
26241 +
26242 + /* do the sanitized header */
26243 + (*aa->update)((void*)&tctx, (caddr_t)&ipo, sizeof(struct iphdr));
26244 +
26245 + /* XXX we didn't do the options here! */
26246 +
26247 + /* now do the AH header itself */
26248 + ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
26249 + (*aa->update)((void*)&tctx, (caddr_t)ahp, ahhlen - AHHMAC_HASHLEN);
26250 +
26251 + /* now, do some zeroes */
26252 + (*aa->update)((void*)&tctx, (caddr_t)zeroes, AHHMAC_HASHLEN);
26253 +
26254 + /* finally, do the packet contents themselves */
26255 + (*aa->update)((void*)&tctx,
26256 + (caddr_t)skb->h.raw + ahhlen,
26257 + skb->len - ahhlen);
26258 +
26259 + (*aa->final)(irs->hash, (void *)&tctx);
26260 +
26261 + memcpy(&tctx, irs->octx, irs->octx_len);
26262 +
26263 + (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
26264 + (*aa->final)(irs->hash, (void *)&tctx);
26265 +
26266 + return IPSEC_RCV_OK;
26267 +}
26268 +
26269 +enum ipsec_rcv_value
26270 +ipsec_rcv_ah_decap(struct ipsec_rcv_state *irs)
26271 +{
26272 + struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26273 + struct sk_buff *skb;
26274 + int ahhlen;
26275 +
26276 + skb=irs->skb;
26277 +
26278 + ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
26279 +
26280 + irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - ahhlen);
26281 + irs->next_header = ahp->ah_nh;
26282 +
26283 + /*
26284 + * move the IP header forward by the size of the AH header, which
26285 + * will remove the the AH header from the packet.
26286 + */
26287 + memmove((void *)(skb->nh.raw + ahhlen),
26288 + (void *)(skb->nh.raw), irs->iphlen);
26289 +
26290 + ipsec_rcv_dmp("ah postmove", skb->data, skb->len);
26291 +
26292 + /* skb_pull below, will move up by ahhlen */
26293 +
26294 + /* XXX not clear how this can happen, as the message indicates */
26295 + if(skb->len < ahhlen) {
26296 + printk(KERN_WARNING
26297 + "klips_error:ipsec_rcv: "
26298 + "tried to skb_pull ahhlen=%d, %d available. This should never happen, please report.\n",
26299 + ahhlen,
26300 + (int)(skb->len));
26301 + return IPSEC_RCV_DECAPFAIL;
26302 + }
26303 + skb_pull(skb, ahhlen);
26304 +
26305 + skb->nh.raw = skb->nh.raw + ahhlen;
26306 + irs->ipp = skb->nh.iph;
26307 +
26308 + ipsec_rcv_dmp("ah postpull", (void *)skb->nh.iph, skb->len);
26309 +
26310 + return IPSEC_RCV_OK;
26311 +}
26312 +
26313 +enum ipsec_xmit_value
26314 +ipsec_xmit_ah_setup(struct ipsec_xmit_state *ixs)
26315 +{
26316 + struct iphdr ipo;
26317 + struct ahhdr *ahp;
26318 + __u8 hash[AH_AMAX];
26319 + union {
26320 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
26321 + MD5_CTX md5;
26322 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
26323 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
26324 + SHA1_CTX sha1;
26325 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
26326 + } tctx;
26327 + unsigned char *dat = (unsigned char *)ixs->iph;
26328 +
26329 + ahp = (struct ahhdr *)(dat + ixs->iphlen);
26330 + ahp->ah_spi = ixs->ipsp->ips_said.spi;
26331 + ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
26332 + ahp->ah_rv = 0;
26333 + ahp->ah_nh = ixs->iph->protocol;
26334 + ahp->ah_hl = (sizeof(struct ahhdr) >> 2) - sizeof(__u64)/sizeof(__u32);
26335 + ixs->iph->protocol = IPPROTO_AH;
26336 + ipsec_xmit_dmp("ahp", (char*)ahp, sizeof(*ahp));
26337 +
26338 + ipo = *ixs->iph;
26339 + ipo.tos = 0;
26340 + ipo.frag_off = 0;
26341 + ipo.ttl = 0;
26342 + ipo.check = 0;
26343 + ipsec_xmit_dmp("ipo", (char*)&ipo, sizeof(ipo));
26344 +
26345 + switch(ixs->ipsp->ips_authalg) {
26346 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
26347 + case AH_MD5:
26348 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
26349 + ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
26350 + osMD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
26351 + ipsec_xmit_dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
26352 + osMD5Update(&tctx.md5, (unsigned char *)ahp,
26353 + sizeof(struct ahhdr) - sizeof(ahp->ah_data));
26354 + ipsec_xmit_dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
26355 + osMD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
26356 + ipsec_xmit_dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
26357 + osMD5Update(&tctx.md5, dat + ixs->iphlen + sizeof(struct ahhdr),
26358 + ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
26359 + ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
26360 + osMD5Final(hash, &tctx.md5);
26361 + ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
26362 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
26363 + ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
26364 + osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
26365 + ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
26366 + osMD5Final(hash, &tctx.md5);
26367 + ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
26368 +
26369 + memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
26370 +
26371 + /* paranoid */
26372 + memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
26373 + memset((caddr_t)hash, 0, sizeof(*hash));
26374 + break;
26375 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
26376 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
26377 + case AH_SHA:
26378 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
26379 + SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
26380 + SHA1Update(&tctx.sha1, (unsigned char *)ahp, sizeof(struct ahhdr) - sizeof(ahp->ah_data));
26381 + SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
26382 + SHA1Update(&tctx.sha1, dat + ixs->iphlen + sizeof(struct ahhdr),
26383 + ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
26384 + SHA1Final(hash, &tctx.sha1);
26385 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
26386 + SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
26387 + SHA1Final(hash, &tctx.sha1);
26388 +
26389 + memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
26390 +
26391 + /* paranoid */
26392 + memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
26393 + memset((caddr_t)hash, 0, sizeof(*hash));
26394 + break;
26395 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
26396 + default:
26397 + ixs->stats->tx_errors++;
26398 + return IPSEC_XMIT_AH_BADALG;
26399 + }
26400 +#ifdef NET_21
26401 + ixs->skb->h.raw = (unsigned char*)ahp;
26402 +#endif /* NET_21 */
26403 +
26404 + return IPSEC_XMIT_OK;
26405 +}
26406 +
26407 +struct xform_functions ah_xform_funcs[]={
26408 + { rcv_checks: ipsec_rcv_ah_checks,
26409 + rcv_setup_auth: ipsec_rcv_ah_setup_auth,
26410 + rcv_calc_auth: ipsec_rcv_ah_authcalc,
26411 + rcv_decrypt: ipsec_rcv_ah_decap,
26412 +
26413 + xmit_setup: ipsec_xmit_ah_setup,
26414 + xmit_headroom: sizeof(struct ahhdr),
26415 + xmit_needtailroom: 0,
26416 + },
26417 +};
26418 +
26419 +
26420 +#ifndef CONFIG_XFRM_ALTERNATE_STACK
26421 +#ifdef NET_26
26422 +struct inet_protocol ah_protocol = {
26423 + .handler = ipsec_rcv,
26424 + .no_policy = 1,
26425 +};
26426 +#else
26427 +struct inet_protocol ah_protocol =
26428 +{
26429 + ipsec_rcv, /* AH handler */
26430 + NULL, /* TUNNEL error control */
26431 +#ifdef NETDEV_25
26432 + 1, /* no policy */
26433 +#else
26434 + 0, /* next */
26435 + IPPROTO_AH, /* protocol ID */
26436 + 0, /* copy */
26437 + NULL, /* data */
26438 + "AH" /* name */
26439 +#endif
26440 +};
26441 +#endif /* NET_26 */
26442 +#endif /* CONFIG_XFRM_ALTERNATE_STACK */
26443 +
26444 +/*
26445 + * $Log: ipsec_ah.c,v $
26446 + * Revision 1.12.2.1 2006/02/15 05:35:14 paul
26447 + * Patch by David McCullough <davidm@snapgear.com>
26448 + * If you setup a tunnel without ESP it doesn't work. It used to work in
26449 + * an older openswan version but stopped when klips was modified to deal
26450 + * with the pulled IP header on the received SKB's.
26451 + *
26452 + * The code in ipsec_ah.c still thinks the IP header is there and runs the
26453 + * hash on the incorrect data.
26454 + *
26455 + * Revision 1.12 2005/04/29 05:10:22 mcr
26456 + * removed from extraenous includes to make unit testing easier.
26457 + *
26458 + * Revision 1.11 2005/04/15 19:50:55 mcr
26459 + * adjustments to use proper skb fields for data.
26460 + *
26461 + * Revision 1.10 2004/09/14 00:22:57 mcr
26462 + * adjustment of MD5* functions.
26463 + *
26464 + * Revision 1.9 2004/09/13 02:22:47 mcr
26465 + * #define inet_protocol if necessary.
26466 + *
26467 + * Revision 1.8 2004/09/06 18:35:48 mcr
26468 + * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
26469 + * so adjust for that.
26470 + *
26471 + * Revision 1.7 2004/08/22 05:00:48 mcr
26472 + * if we choose to compile the file, we want the contents,
26473 + * so don't pull any punches.
26474 + *
26475 + * Revision 1.6 2004/08/17 03:27:23 mcr
26476 + * klips 2.6 edits.
26477 + *
26478 + * Revision 1.5 2004/08/14 03:28:24 mcr
26479 + * fixed log comment to remove warning about embedded comment.
26480 + *
26481 + * Revision 1.4 2004/08/04 15:57:07 mcr
26482 + * moved des .h files to include/des/ *
26483 + * included 2.6 protocol specific things
26484 + * started at NAT-T support, but it will require a kernel patch.
26485 + *
26486 + * Revision 1.3 2004/07/10 19:11:18 mcr
26487 + * CONFIG_IPSEC -> CONFIG_KLIPS.
26488 + *
26489 + * Revision 1.2 2004/04/06 02:49:25 mcr
26490 + * pullup of algo code from alg-branch.
26491 + *
26492 + *
26493 + *
26494 + */
26495 --- /dev/null Tue Mar 11 13:02:56 2003
26496 +++ linux/net/ipsec/ipsec_alg.c Mon Feb 9 13:51:03 2004
26497 @@ -0,0 +1,1044 @@
26498 +/*
26499 + * Modular extensions service and registration functions
26500 + *
26501 + * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
26502 + *
26503 + * Version: 0.8.1
26504 + *
26505 + * ipsec_alg.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
26506 + *
26507 + * This program is free software; you can redistribute it and/or modify it
26508 + * under the terms of the GNU General Public License as published by the
26509 + * Free Software Foundation; either version 2 of the License, or (at your
26510 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
26511 + *
26512 + * This program is distributed in the hope that it will be useful, but
26513 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26514 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26515 + * for more details.
26516 + *
26517 + */
26518 +#define __NO_VERSION__
26519 +
26520 +#if defined (MODULE)
26521 +#include <linux/module.h>
26522 +#endif
26523 +
26524 +#include <linux/kernel.h> /* printk() */
26525 +
26526 +#include <linux/netdevice.h> /* struct device, and other headers */
26527 +#include <linux/etherdevice.h> /* eth_type_trans */
26528 +#include <linux/ip.h> /* struct iphdr */
26529 +#include <linux/skbuff.h>
26530 +#include <linux/socket.h>
26531 +#include <linux/in.h>
26532 +#include <linux/types.h>
26533 +#include <linux/string.h> /* memcmp() */
26534 +#include <linux/random.h> /* get_random_bytes() */
26535 +#include <linux/errno.h> /* error codes */
26536 +#ifdef SPINLOCK
26537 +# ifdef SPINLOCK_23
26538 +# include <linux/spinlock.h> /* *lock* */
26539 +# else /* SPINLOCK_23 */
26540 +# include <asm/spinlock.h> /* *lock* */
26541 +# endif /* SPINLOCK_23 */
26542 +#endif /* SPINLOCK */
26543 +
26544 +#include "openswan/ipsec_param.h"
26545 +#include <openswan.h>
26546 +#include "openswan/ipsec_sa.h"
26547 +#include "openswan/radij.h"
26548 +#include "openswan/ipsec_encap.h"
26549 +#include "openswan/ipsec_radij.h"
26550 +#include "openswan/ipsec_xform.h"
26551 +#include "openswan/ipsec_tunnel.h"
26552 +#include "openswan/ipsec_rcv.h"
26553 +#if defined(CONFIG_KLIPS_ESP) || defined(CONFIG_KLIPS_AH)
26554 +# include "openswan/ipsec_ah.h"
26555 +#endif /* defined(CONFIG_KLIPS_ESP) || defined(CONFIG_KLIPS_AH) */
26556 +#ifdef CONFIG_KLIPS_ESP
26557 +# include "openswan/ipsec_esp.h"
26558 +#endif /* !CONFIG_KLIPS_ESP */
26559 +#ifdef CONFIG_KLIPS_IPCOMP
26560 +# include "openswan/ipcomp.h"
26561 +#endif /* CONFIG_KLIPS_COMP */
26562 +
26563 +#include <openswan/pfkeyv2.h>
26564 +#include <openswan/pfkey.h>
26565 +
26566 +#include "openswan/ipsec_alg.h"
26567 +#include "openswan/ipsec_proto.h"
26568 +
26569 +#if SADB_EALG_MAX < 255
26570 +#warning Compiling with limited ESP support ( SADB_EALG_MAX < 256 )
26571 +#endif
26572 +
26573 +static rwlock_t ipsec_alg_lock = RW_LOCK_UNLOCKED;
26574 +#define IPSEC_ALG_HASHSZ 16 /* must be power of 2, even 2^0=1 */
26575 +static struct list_head ipsec_alg_hash_table[IPSEC_ALG_HASHSZ];
26576 +
26577 +/* Old gcc's will fail here */
26578 +#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) \
26579 + ; goto out; } while(0)
26580 +
26581 +#ifdef NET_26
26582 +/*
26583 + * Must be already protected by lock
26584 + */
26585 +static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt)
26586 +{
26587 +#ifdef MODULE
26588 + if (ixt->ixt_module)
26589 + try_module_get(ixt->ixt_module);
26590 +#endif
26591 + atomic_inc(&ixt->ixt_refcnt);
26592 +}
26593 +static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
26594 + atomic_dec(&ixt->ixt_refcnt);
26595 +#ifdef MODULE
26596 + if (ixt->ixt_module)
26597 + module_put(ixt->ixt_module);
26598 +#endif
26599 +}
26600 +
26601 +#else
26602 +
26603 +/*
26604 + * Must be already protected by lock
26605 + */
26606 +static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt) {
26607 +#ifdef MODULE
26608 + if (ixt->ixt_module) {
26609 + __MOD_INC_USE_COUNT(ixt->ixt_module);
26610 + }
26611 +#endif
26612 + atomic_inc(&ixt->ixt_refcnt);
26613 +}
26614 +static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
26615 + atomic_dec(&ixt->ixt_refcnt);
26616 +#ifdef MODULE
26617 + if (ixt->ixt_module)
26618 + __MOD_DEC_USE_COUNT(ixt->ixt_module);
26619 +#endif
26620 +}
26621 +#endif
26622 +
26623 +/*
26624 + * simple hash function, optimized for 0-hash (1 list) special
26625 + * case
26626 + */
26627 +#if IPSEC_ALG_HASHSZ > 1
26628 +static inline unsigned ipsec_alg_hashfn(int alg_type, int alg_id) {
26629 + return ((alg_type^alg_id)&(IPSEC_ALG_HASHSZ-1));
26630 +}
26631 +#else
26632 +#define ipsec_alg_hashfn(x,y) (0)
26633 +#endif
26634 +
26635 +/*****************************************************************
26636 + *
26637 + * INTERNAL table handling: insert, delete, find
26638 + *
26639 + *****************************************************************/
26640 +
26641 +/*
26642 + * hash table initialization, called from ipsec_alg_init()
26643 + */
26644 +static void ipsec_alg_hash_init(void) {
26645 + struct list_head *head = ipsec_alg_hash_table;
26646 + int i = IPSEC_ALG_HASHSZ;
26647 + do {
26648 + INIT_LIST_HEAD(head);
26649 + head++;
26650 + i--;
26651 + } while (i);
26652 +}
26653 +/*
26654 + * hash list lookup by {alg_type, alg_id} and table head,
26655 + * must be already protected by lock
26656 + */
26657 +static struct ipsec_alg *__ipsec_alg_find(unsigned alg_type, unsigned alg_id, struct list_head * head) {
26658 + struct list_head *p;
26659 + struct ipsec_alg *ixt=NULL;
26660 + for (p=head->next; p!=head; p=p->next) {
26661 + ixt = list_entry(p, struct ipsec_alg, ixt_list);
26662 + if (ixt->ixt_alg_type == alg_type && ixt->ixt_alg_id==alg_id) {
26663 + goto out;
26664 + }
26665 + }
26666 + ixt=NULL;
26667 +out:
26668 + return ixt;
26669 +}
26670 +/*
26671 + * inserts (in front) a new entry in hash table,
26672 + * called from ipsec_alg_register() when new algorithm is registered.
26673 + */
26674 +static int ipsec_alg_insert(struct ipsec_alg *ixt) {
26675 + int ret=-EINVAL;
26676 + unsigned hashval=ipsec_alg_hashfn(ixt->ixt_alg_type, ixt->ixt_alg_id);
26677 + struct list_head *head= ipsec_alg_hash_table + hashval;
26678 + struct ipsec_alg *ixt_cur;
26679 +
26680 + /* new element must be virgin ... */
26681 + if (ixt->ixt_list.next != &ixt->ixt_list ||
26682 + ixt->ixt_list.prev != &ixt->ixt_list) {
26683 + printk(KERN_ERR "ipsec_alg_insert: ixt object \"%s\" "
26684 + "list head not initialized\n",
26685 + ixt->ixt_name);
26686 + return ret;
26687 + }
26688 + write_lock_bh(&ipsec_alg_lock);
26689 +
26690 + ixt_cur = __ipsec_alg_find(ixt->ixt_alg_type, ixt->ixt_alg_id, head);
26691 +
26692 + /* if previous (current) ipsec_alg found check excl flag of _anyone_ */
26693 + if (ixt_cur
26694 + && ((ixt->ixt_state|ixt_cur->ixt_state) & IPSEC_ALG_ST_EXCL)) {
26695 + barf_out("ipsec_alg for alg_type=%d, alg_id=%d already exist. "
26696 + "Not loaded (ret=%d).\n",
26697 + ixt->ixt_alg_type,
26698 + ixt->ixt_alg_id, ret=-EEXIST);
26699 + }
26700 + list_add(&ixt->ixt_list, head);
26701 + ixt->ixt_state |= IPSEC_ALG_ST_REGISTERED;
26702 + ret=0;
26703 +out:
26704 + write_unlock_bh(&ipsec_alg_lock);
26705 + return ret;
26706 +}
26707 +
26708 +/*
26709 + * deletes an existing entry in hash table,
26710 + * called from ipsec_alg_unregister() when algorithm is unregistered.
26711 + */
26712 +static int ipsec_alg_delete(struct ipsec_alg *ixt) {
26713 + write_lock_bh(&ipsec_alg_lock);
26714 + list_del(&ixt->ixt_list);
26715 + write_unlock_bh(&ipsec_alg_lock);
26716 + return 0;
26717 +}
26718 +
26719 +/*
26720 + * here @user context (read-only when @kernel bh context)
26721 + * -> no bh disabling
26722 + *
26723 + * called from ipsec_sa_init() -> ipsec_alg_sa_init()
26724 + */
26725 +static struct ipsec_alg *ipsec_alg_get(int alg_type, int alg_id)
26726 +{
26727 + unsigned hashval=ipsec_alg_hashfn(alg_type, alg_id);
26728 + struct list_head *head= ipsec_alg_hash_table + hashval;
26729 + struct ipsec_alg *ixt;
26730 +
26731 + read_lock(&ipsec_alg_lock);
26732 + ixt=__ipsec_alg_find(alg_type, alg_id, head);
26733 + if (ixt) __ipsec_alg_usage_inc(ixt);
26734 + read_unlock(&ipsec_alg_lock);
26735 +
26736 + return ixt;
26737 +}
26738 +
26739 +static void ipsec_alg_put(struct ipsec_alg *ixt) {
26740 + __ipsec_alg_usage_dec((struct ipsec_alg *)ixt);
26741 +}
26742 +
26743 +/*****************************************************************
26744 + *
26745 + * INTERFACE for ENC services: key creation, encrypt function
26746 + *
26747 + *****************************************************************/
26748 +
26749 +/*
26750 + * main encrypt service entry point
26751 + * called from ipsec_rcv() with encrypt=IPSEC_ALG_DECRYPT and
26752 + * ipsec_tunnel_start_xmit with encrypt=IPSEC_ALG_ENCRYPT
26753 + */
26754 +int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 * idat,
26755 + int ilen, const __u8 * iv, int encrypt)
26756 +{
26757 + int ret;
26758 + struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
26759 +#ifdef CONFIG_KLIPS_DEBUG
26760 + int debug_flag = (encrypt==IPSEC_ALG_ENCRYPT ?
26761 + debug_tunnel : debug_rcv);
26762 +#endif
26763 +
26764 + KLIPS_PRINT(debug_flag,
26765 + "klips_debug:ipsec_alg_esp_encrypt: "
26766 + "entering with encalg=%d, ixt_e=%p\n",
26767 + sa_p->ips_encalg, ixt_e);
26768 + if (ixt_e == NULL) {
26769 + KLIPS_ERROR(debug_flag,
26770 + "klips_debug:ipsec_alg_esp_encrypt: "
26771 + "NULL ipsec_alg_enc object\n");
26772 + return -1;
26773 + }
26774 + KLIPS_PRINT(debug_flag,
26775 + "klips_debug:ipsec_alg_esp_encrypt: "
26776 + "calling cbc_encrypt encalg=%d "
26777 + "ips_key_e=%p idat=%p ilen=%d iv=%p, encrypt=%d\n",
26778 + sa_p->ips_encalg,
26779 + sa_p->ips_key_e, idat, ilen, iv, encrypt);
26780 + ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, sa_p->ips_key_e, idat,
26781 + ilen, iv, encrypt);
26782 + KLIPS_PRINT(debug_flag,
26783 + "klips_debug:ipsec_alg_esp_encrypt: "
26784 + "returned ret=%d\n",
26785 + ret);
26786 + return ret;
26787 +}
26788 +
26789 +/*
26790 + * encryption key context creation function
26791 + * called from pfkey_v2_parser.c:pfkey_ips_init()
26792 + */
26793 +int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p) {
26794 + int ret=-EINVAL;
26795 + int keyminbits, keymaxbits;
26796 + caddr_t ekp;
26797 + struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
26798 +
26799 + KLIPS_PRINT(debug_pfkey,
26800 + "klips_debug:ipsec_alg_enc_key_create: "
26801 + "entering with encalg=%d ixt_e=%p\n",
26802 + sa_p->ips_encalg, ixt_e);
26803 + if (!ixt_e) {
26804 + KLIPS_PRINT(debug_pfkey,
26805 + "klips_debug:ipsec_alg_enc_key_create: "
26806 + "NULL ipsec_alg_enc object\n");
26807 + return -EPROTO;
26808 + }
26809 +
26810 + /*
26811 + * grRRR... DES 7bits jurassic stuff ... f*ckk --jjo
26812 + */
26813 + switch(ixt_e->ixt_common.ixt_support.ias_id) {
26814 + case ESP_3DES:
26815 + keyminbits=keymaxbits=192;break;
26816 + case ESP_DES:
26817 + keyminbits=keymaxbits=64;break;
26818 + default:
26819 + keyminbits=ixt_e->ixt_common.ixt_support.ias_keyminbits;
26820 + keymaxbits=ixt_e->ixt_common.ixt_support.ias_keymaxbits;
26821 + }
26822 + if(sa_p->ips_key_bits_e<keyminbits ||
26823 + sa_p->ips_key_bits_e>keymaxbits) {
26824 + KLIPS_PRINT(debug_pfkey,
26825 + "klips_debug:ipsec_alg_enc_key_create: "
26826 + "incorrect encryption key size for id=%d: %d bits -- "
26827 + "must be between %d,%d bits\n" /*octets (bytes)\n"*/,
26828 + ixt_e->ixt_common.ixt_support.ias_id,
26829 + sa_p->ips_key_bits_e, keyminbits, keymaxbits);
26830 + ret=-EINVAL;
26831 + goto ixt_out;
26832 + }
26833 + /* save encryption key pointer */
26834 + ekp = sa_p->ips_key_e;
26835 +
26836 +
26837 + if (ixt_e->ixt_e_new_key) {
26838 + sa_p->ips_key_e = ixt_e->ixt_e_new_key(ixt_e,
26839 + ekp, sa_p->ips_key_bits_e/8);
26840 + ret = (sa_p->ips_key_e)? 0 : -EINVAL;
26841 + } else {
26842 + if((sa_p->ips_key_e = (caddr_t)
26843 + kmalloc((sa_p->ips_key_e_size = ixt_e->ixt_e_ctx_size),
26844 + GFP_ATOMIC)) == NULL) {
26845 + ret=-ENOMEM;
26846 + goto ixt_out;
26847 + }
26848 + /* zero-out key_e */
26849 + memset(sa_p->ips_key_e, 0, sa_p->ips_key_e_size);
26850 +
26851 + /* I cast here to allow more decoupling in alg module */
26852 + KLIPS_PRINT(debug_pfkey,
26853 + "klips_debug:ipsec_alg_enc_key_create: about to call:"
26854 + "set_key(key_e=%p, ekp=%p, key_size=%d)\n",
26855 + (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
26856 + ret = ixt_e->ixt_e_set_key(ixt_e, (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
26857 + }
26858 + /* paranoid */
26859 + memset(ekp, 0, sa_p->ips_key_bits_e/8);
26860 + kfree(ekp);
26861 +ixt_out:
26862 + return ret;
26863 +}
26864 +
26865 +/***************************************************************
26866 + *
26867 + * INTERFACE for AUTH services: key creation, hash functions
26868 + *
26869 + ***************************************************************/
26870 +
26871 +/*
26872 + * auth key context creation function
26873 + * called from pfkey_v2_parser.c:pfkey_ips_init()
26874 + */
26875 +int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p) {
26876 + int ret=-EINVAL;
26877 + struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
26878 + int keyminbits, keymaxbits;
26879 + unsigned char *akp;
26880 + unsigned int aks;
26881 + KLIPS_PRINT(debug_pfkey,
26882 + "klips_debug:ipsec_alg_auth_key_create: "
26883 + "entering with authalg=%d ixt_a=%p\n",
26884 + sa_p->ips_authalg, ixt_a);
26885 + if (!ixt_a) {
26886 + KLIPS_PRINT(debug_pfkey,
26887 + "klips_debug:ipsec_alg_auth_key_create: "
26888 + "NULL ipsec_alg_auth object\n");
26889 + return -EPROTO;
26890 + }
26891 + keyminbits=ixt_a->ixt_common.ixt_support.ias_keyminbits;
26892 + keymaxbits=ixt_a->ixt_common.ixt_support.ias_keymaxbits;
26893 + if(sa_p->ips_key_bits_a<keyminbits || sa_p->ips_key_bits_a>keymaxbits) {
26894 + KLIPS_PRINT(debug_pfkey,
26895 + "klips_debug:ipsec_alg_auth_key_create: incorrect auth"
26896 + "key size: %d bits -- must be between %d,%d bits\n"/*octets (bytes)\n"*/,
26897 + sa_p->ips_key_bits_a, keyminbits, keymaxbits);
26898 + ret=-EINVAL;
26899 + goto ixt_out;
26900 + }
26901 + /* save auth key pointer */
26902 + sa_p->ips_auth_bits = ixt_a->ixt_a_keylen * 8; /* XXX XXX */
26903 + akp = sa_p->ips_key_a;
26904 + aks = sa_p->ips_key_a_size;
26905 +
26906 + /* will hold: 2 ctx and a blocksize buffer: kb */
26907 + sa_p->ips_key_a_size = ixt_a->ixt_a_ctx_size;
26908 + if((sa_p->ips_key_a =
26909 + (caddr_t) kmalloc(sa_p->ips_key_a_size, GFP_ATOMIC)) == NULL) {
26910 + ret=-ENOMEM;
26911 + goto ixt_out;
26912 + }
26913 + ixt_a->ixt_a_hmac_set_key(ixt_a, sa_p->ips_key_a, akp, sa_p->ips_key_bits_a/8); /* XXX XXX */
26914 + ret=0;
26915 + memset(akp, 0, aks);
26916 + kfree(akp);
26917 +
26918 +ixt_out:
26919 + return ret;
26920 +}
26921 +
26922 +
26923 +int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp,
26924 + int len, __u8 *hash, int hashlen)
26925 +{
26926 + struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
26927 + if (!ixt_a) {
26928 + KLIPS_PRINT(debug_pfkey,
26929 + "klips_debug:ipsec_sa_esp_hash: "
26930 + "NULL ipsec_alg_auth object\n");
26931 + return -EPROTO;
26932 + }
26933 + KLIPS_PRINT(debug_tunnel|debug_rcv,
26934 + "klips_debug:ipsec_sa_esp_hash: "
26935 + "hashing %p (%d bytes) to %p (%d bytes)\n",
26936 + espp, len,
26937 + hash, hashlen);
26938 + ixt_a->ixt_a_hmac_hash(ixt_a,
26939 + sa_p->ips_key_a,
26940 + espp, len,
26941 + hash, hashlen);
26942 + return 0;
26943 +}
26944 +
26945 +/***************************************************************
26946 + *
26947 + * INTERFACE for module loading,testing, and unloading
26948 + *
26949 + ***************************************************************/
26950 +
26951 +/* validation for registering (enc) module */
26952 +static int check_enc(struct ipsec_alg_enc *ixt)
26953 +{
26954 + int ret=-EINVAL;
26955 + if (ixt->ixt_common.ixt_blocksize==0) /* || ixt->ixt_common.ixt_blocksize%2) need for ESP_NULL */
26956 + barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_common.ixt_blocksize);
26957 + if (ixt->ixt_common.ixt_support.ias_keyminbits==0
26958 + && ixt->ixt_common.ixt_support.ias_keymaxbits==0
26959 + && ixt->ixt_e_keylen==0)
26960 + goto zero_key_ok;
26961 +
26962 + if (ixt->ixt_common.ixt_support.ias_keyminbits==0)
26963 + barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_common.ixt_support.ias_keyminbits);
26964 +
26965 + if (ixt->ixt_common.ixt_support.ias_keymaxbits==0)
26966 + barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_common.ixt_support.ias_keymaxbits);
26967 +
26968 + if (ixt->ixt_e_keylen==0)
26969 + barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_e_keylen);
26970 +
26971 +zero_key_ok:
26972 + if (ixt->ixt_e_ctx_size==0 && ixt->ixt_e_new_key == NULL)
26973 + barf_out(KERN_ERR "invalid key_e_size=%d and ixt_e_new_key=NULL\n", ixt->ixt_e_ctx_size);
26974 + if (ixt->ixt_e_cbc_encrypt==NULL)
26975 + barf_out(KERN_ERR "e_cbc_encrypt() must be not NULL\n");
26976 + ret=0;
26977 +out:
26978 + return ret;
26979 +}
26980 +
26981 +/* validation for registering (auth) module */
26982 +static int check_auth(struct ipsec_alg_auth *ixt)
26983 +{
26984 + int ret=-EINVAL;
26985 + if (ixt->ixt_common.ixt_support.ias_id==0 || ixt->ixt_common.ixt_support.ias_id > SADB_AALG_MAX)
26986 + barf_out("invalid alg_id=%d > %d (SADB_AALG_MAX)\n",
26987 + ixt->ixt_common.ixt_support.ias_id, SADB_AALG_MAX);
26988 +
26989 + if (ixt->ixt_common.ixt_blocksize==0
26990 + || ixt->ixt_common.ixt_blocksize%2)
26991 + barf_out(KERN_ERR "invalid blocksize=%d\n",
26992 + ixt->ixt_common.ixt_blocksize);
26993 +
26994 + if (ixt->ixt_common.ixt_blocksize>AH_BLKLEN_MAX)
26995 + barf_out(KERN_ERR "sorry blocksize=%d > %d. "
26996 + "Please increase AH_BLKLEN_MAX and recompile\n",
26997 + ixt->ixt_common.ixt_blocksize,
26998 + AH_BLKLEN_MAX);
26999 + if (ixt->ixt_common.ixt_support.ias_keyminbits==0 && ixt->ixt_common.ixt_support.ias_keymaxbits==0 && ixt->ixt_a_keylen==0)
27000 + goto zero_key_ok;
27001 + if (ixt->ixt_common.ixt_support.ias_keyminbits==0)
27002 + barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_common.ixt_support.ias_keyminbits);
27003 + if (ixt->ixt_common.ixt_support.ias_keymaxbits==0)
27004 + barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_common.ixt_support.ias_keymaxbits);
27005 + if (ixt->ixt_common.ixt_support.ias_keymaxbits!=ixt->ixt_common.ixt_support.ias_keyminbits)
27006 + barf_out(KERN_ERR "keymaxbits must equal keyminbits (not sure).\n");
27007 + if (ixt->ixt_a_keylen==0)
27008 + barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_a_keylen);
27009 +zero_key_ok:
27010 + if (ixt->ixt_a_ctx_size==0)
27011 + barf_out(KERN_ERR "invalid a_ctx_size=%d\n", ixt->ixt_a_ctx_size);
27012 + if (ixt->ixt_a_hmac_set_key==NULL)
27013 + barf_out(KERN_ERR "a_hmac_set_key() must be not NULL\n");
27014 + if (ixt->ixt_a_hmac_hash==NULL)
27015 + barf_out(KERN_ERR "a_hmac_hash() must be not NULL\n");
27016 + ret=0;
27017 +out:
27018 + return ret;
27019 +}
27020 +
27021 +/*
27022 + * Generic (enc, auth) registration entry point
27023 + */
27024 +int register_ipsec_alg(struct ipsec_alg *ixt)
27025 +{
27026 + int ret=-EINVAL;
27027 + /* Validation */
27028 + if (ixt==NULL)
27029 + barf_out("NULL ipsec_alg object passed\n");
27030 + if ((ixt->ixt_version&0xffffff00) != (IPSEC_ALG_VERSION&0xffffff00))
27031 + barf_out("incorrect version: %d.%d.%d-%d, "
27032 + "must be %d.%d.%d[-%d]\n",
27033 + IPSEC_ALG_VERSION_QUAD(ixt->ixt_version),
27034 + IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION));
27035 +
27036 + switch(ixt->ixt_alg_type) {
27037 + case IPSEC_ALG_TYPE_AUTH:
27038 + if ((ret=check_auth((struct ipsec_alg_auth *)ixt)<0))
27039 + goto out;
27040 + break;
27041 + case IPSEC_ALG_TYPE_ENCRYPT:
27042 + if ((ret=check_enc((struct ipsec_alg_enc *)ixt)<0))
27043 + goto out;
27044 + /*
27045 + * Adapted two lines below:
27046 + * ivlen == 0 is possible (NULL enc has blocksize==1)
27047 + *
27048 + * fixed NULL support by David De Reu <DeReu@tComLabs.com>
27049 + */
27050 + if (ixt->ixt_support.ias_ivlen == 0
27051 + && ixt->ixt_blocksize > 1) {
27052 + ixt->ixt_support.ias_ivlen = ixt->ixt_blocksize*8;
27053 + }
27054 + break;
27055 + default:
27056 + barf_out("alg_type=%d not supported\n", ixt->ixt_alg_type);
27057 + }
27058 + INIT_LIST_HEAD(&ixt->ixt_list);
27059 + ret = ipsec_alg_insert(ixt);
27060 + if (ret<0)
27061 + barf_out(KERN_WARNING "ipsec_alg for alg_id=%d failed."
27062 + "Not loaded (ret=%d).\n",
27063 + ixt->ixt_support.ias_id, ret);
27064 +
27065 +
27066 + ret = pfkey_list_insert_supported((struct ipsec_alg_supported *)&ixt->ixt_support
27067 + , &(pfkey_supported_list[SADB_SATYPE_ESP]));
27068 +
27069 + if (ret==0) {
27070 + ixt->ixt_state |= IPSEC_ALG_ST_SUPP;
27071 + /* send register event to userspace */
27072 + pfkey_register_reply(SADB_SATYPE_ESP, NULL);
27073 + } else
27074 + printk(KERN_ERR "pfkey_list_insert_supported returned %d. "
27075 + "Loading anyway.\n", ret);
27076 + ret=0;
27077 +out:
27078 + return ret;
27079 +}
27080 +
27081 +/*
27082 + * unregister ipsec_alg object from own tables, if
27083 + * success => calls pfkey_list_remove_supported()
27084 + */
27085 +int unregister_ipsec_alg(struct ipsec_alg *ixt) {
27086 + int ret= -EINVAL;
27087 + switch(ixt->ixt_alg_type) {
27088 + case IPSEC_ALG_TYPE_AUTH:
27089 + case IPSEC_ALG_TYPE_ENCRYPT:
27090 + break;
27091 + default:
27092 + /* this is not a typo :) */
27093 + barf_out("frog found in list (\"%s\"): ixt_p=NULL\n",
27094 + ixt->ixt_name);
27095 + }
27096 +
27097 + ret=ipsec_alg_delete(ixt);
27098 + if (ixt->ixt_state&IPSEC_ALG_ST_SUPP) {
27099 + ixt->ixt_state &= ~IPSEC_ALG_ST_SUPP;
27100 + pfkey_list_remove_supported((struct ipsec_alg_supported *)&ixt->ixt_support
27101 + , &(pfkey_supported_list[SADB_SATYPE_ESP]));
27102 +
27103 + /* send register event to userspace */
27104 + pfkey_register_reply(SADB_SATYPE_ESP, NULL);
27105 + }
27106 +
27107 +out:
27108 + return ret;
27109 +}
27110 +
27111 +/*
27112 + * Must be called from user context
27113 + * used at module load type for testing algo implementation
27114 + */
27115 +static int ipsec_alg_test_encrypt(int enc_alg, int test) {
27116 + int ret;
27117 + caddr_t buf = NULL;
27118 + int iv_size, keysize, key_e_size;
27119 + struct ipsec_alg_enc *ixt_e;
27120 + void *tmp_key_e = NULL;
27121 + #define BUFSZ 1024
27122 + #define MARGIN 0
27123 + #define test_enc (buf+MARGIN)
27124 + #define test_dec (test_enc+BUFSZ+MARGIN)
27125 + #define test_tmp (test_dec+BUFSZ+MARGIN)
27126 + #define test_key_e (test_tmp+BUFSZ+MARGIN)
27127 + #define test_iv (test_key_e+key_e_size+MARGIN)
27128 + #define test_key (test_iv+iv_size+MARGIN)
27129 + #define test_size (BUFSZ*3+key_e_size+iv_size+keysize+MARGIN*7)
27130 + ixt_e=(struct ipsec_alg_enc *)ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, enc_alg);
27131 + if (ixt_e==NULL) {
27132 + KLIPS_PRINT(1,
27133 + "klips_debug: ipsec_alg_test_encrypt: "
27134 + "encalg=%d object not found\n",
27135 + enc_alg);
27136 + ret=-EINVAL;
27137 + goto out;
27138 + }
27139 + iv_size=ixt_e->ixt_common.ixt_support.ias_ivlen / 8;
27140 + key_e_size=ixt_e->ixt_e_ctx_size;
27141 + keysize=ixt_e->ixt_e_keylen;
27142 + KLIPS_PRINT(1,
27143 + "klips_debug: ipsec_alg_test_encrypt: "
27144 + "enc_alg=%d blocksize=%d key_e_size=%d keysize=%d\n",
27145 + enc_alg, iv_size, key_e_size, keysize);
27146 + if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
27147 + ret= -ENOMEM;
27148 + goto out;
27149 + }
27150 + get_random_bytes(test_key, keysize);
27151 + get_random_bytes(test_iv, iv_size);
27152 + if (ixt_e->ixt_e_new_key) {
27153 + tmp_key_e = ixt_e->ixt_e_new_key(ixt_e, test_key, keysize);
27154 + ret = tmp_key_e ? 0 : -EINVAL;
27155 + } else {
27156 + tmp_key_e = test_key_e;
27157 + ret = ixt_e->ixt_e_set_key(ixt_e, test_key_e, test_key, keysize);
27158 + }
27159 + if (ret < 0)
27160 + goto out;
27161 + get_random_bytes(test_enc, BUFSZ);
27162 + memcpy(test_tmp, test_enc, BUFSZ);
27163 + ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_enc, BUFSZ, test_iv, 1);
27164 + printk(KERN_INFO
27165 + "klips_info: ipsec_alg_test_encrypt: "
27166 + "cbc_encrypt=1 ret=%d\n",
27167 + ret);
27168 + ret=memcmp(test_enc, test_tmp, BUFSZ);
27169 + printk(KERN_INFO
27170 + "klips_info: ipsec_alg_test_encrypt: "
27171 + "memcmp(enc, tmp) ret=%d: %s\n", ret,
27172 + ret!=0? "OK. (encr->DIFFers)" : "FAIL! (encr->SAME)" );
27173 + memcpy(test_dec, test_enc, BUFSZ);
27174 + ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_dec, BUFSZ, test_iv, 0);
27175 + printk(KERN_INFO
27176 + "klips_info: ipsec_alg_test_encrypt: "
27177 + "cbc_encrypt=0 ret=%d\n", ret);
27178 + ret=memcmp(test_dec, test_tmp, BUFSZ);
27179 + printk(KERN_INFO
27180 + "klips_info: ipsec_alg_test_encrypt: "
27181 + "memcmp(dec,tmp) ret=%d: %s\n", ret,
27182 + ret==0? "OK. (encr->decr->SAME)" : "FAIL! (encr->decr->DIFFers)" );
27183 + {
27184 + /* Shamelessly taken from drivers/md sources O:) */
27185 + unsigned long now;
27186 + int i, count, max=0;
27187 + int encrypt, speed;
27188 + for (encrypt=0; encrypt <2;encrypt ++) {
27189 + for (i = 0; i < 5; i++) {
27190 + now = jiffies;
27191 + count = 0;
27192 + while (jiffies == now) {
27193 + mb();
27194 + ixt_e->ixt_e_cbc_encrypt(ixt_e,
27195 + tmp_key_e, test_tmp,
27196 + BUFSZ, test_iv, encrypt);
27197 + mb();
27198 + count++;
27199 + mb();
27200 + }
27201 + if (count > max)
27202 + max = count;
27203 + }
27204 + speed = max * (HZ * BUFSZ / 1024);
27205 + printk(KERN_INFO
27206 + "klips_info: ipsec_alg_test_encrypt: "
27207 + "%s %s speed=%d KB/s\n",
27208 + ixt_e->ixt_common.ixt_name,
27209 + encrypt? "encrypt": "decrypt", speed);
27210 + }
27211 + }
27212 +out:
27213 + if (tmp_key_e && ixt_e->ixt_e_destroy_key) ixt_e->ixt_e_destroy_key(ixt_e, tmp_key_e);
27214 + if (buf) kfree(buf);
27215 + if (ixt_e) ipsec_alg_put((struct ipsec_alg *)ixt_e);
27216 + return ret;
27217 + #undef test_enc
27218 + #undef test_dec
27219 + #undef test_tmp
27220 + #undef test_key_e
27221 + #undef test_iv
27222 + #undef test_key
27223 + #undef test_size
27224 +}
27225 +
27226 +/*
27227 + * Must be called from user context
27228 + * used at module load type for testing algo implementation
27229 + */
27230 +static int ipsec_alg_test_auth(int auth_alg, int test) {
27231 + int ret;
27232 + caddr_t buf = NULL;
27233 + int blocksize, keysize, key_a_size;
27234 + struct ipsec_alg_auth *ixt_a;
27235 + #define BUFSZ 1024
27236 + #define MARGIN 0
27237 + #define test_auth (buf+MARGIN)
27238 + #define test_key_a (test_auth+BUFSZ+MARGIN)
27239 + #define test_key (test_key_a+key_a_size+MARGIN)
27240 + #define test_hash (test_key+keysize+MARGIN)
27241 + #define test_size (BUFSZ+key_a_size+keysize+AHHMAC_HASHLEN+MARGIN*4)
27242 + ixt_a=(struct ipsec_alg_auth *)ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, auth_alg);
27243 + if (ixt_a==NULL) {
27244 + KLIPS_PRINT(1,
27245 + "klips_debug: ipsec_alg_test_auth: "
27246 + "encalg=%d object not found\n",
27247 + auth_alg);
27248 + ret=-EINVAL;
27249 + goto out;
27250 + }
27251 + blocksize=ixt_a->ixt_common.ixt_blocksize;
27252 + key_a_size=ixt_a->ixt_a_ctx_size;
27253 + keysize=ixt_a->ixt_a_keylen;
27254 + KLIPS_PRINT(1,
27255 + "klips_debug: ipsec_alg_test_auth: "
27256 + "auth_alg=%d blocksize=%d key_a_size=%d keysize=%d\n",
27257 + auth_alg, blocksize, key_a_size, keysize);
27258 + if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
27259 + ret= -ENOMEM;
27260 + goto out;
27261 + }
27262 + get_random_bytes(test_key, keysize);
27263 + ret = ixt_a->ixt_a_hmac_set_key(ixt_a, test_key_a, test_key, keysize);
27264 + if (ret < 0 )
27265 + goto out;
27266 + get_random_bytes(test_auth, BUFSZ);
27267 + ret=ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
27268 + printk(KERN_INFO
27269 + "klips_info: ipsec_alg_test_auth: "
27270 + "ret=%d\n", ret);
27271 + {
27272 + /* Shamelessly taken from drivers/md sources O:) */
27273 + unsigned long now;
27274 + int i, count, max=0;
27275 + int speed;
27276 + for (i = 0; i < 5; i++) {
27277 + now = jiffies;
27278 + count = 0;
27279 + while (jiffies == now) {
27280 + mb();
27281 + ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
27282 + mb();
27283 + count++;
27284 + mb();
27285 + }
27286 + if (count > max)
27287 + max = count;
27288 + }
27289 + speed = max * (HZ * BUFSZ / 1024);
27290 + printk(KERN_INFO
27291 + "klips_info: ipsec_alg_test_auth: "
27292 + "%s hash speed=%d KB/s\n",
27293 + ixt_a->ixt_common.ixt_name,
27294 + speed);
27295 + }
27296 +out:
27297 + if (buf) kfree(buf);
27298 + if (ixt_a) ipsec_alg_put((struct ipsec_alg *)ixt_a);
27299 + return ret;
27300 + #undef test_auth
27301 + #undef test_key_a
27302 + #undef test_key
27303 + #undef test_hash
27304 + #undef test_size
27305 +}
27306 +
27307 +int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int test) {
27308 + switch(alg_type) {
27309 + case IPSEC_ALG_TYPE_ENCRYPT:
27310 + return ipsec_alg_test_encrypt(alg_id, test);
27311 + break;
27312 + case IPSEC_ALG_TYPE_AUTH:
27313 + return ipsec_alg_test_auth(alg_id, test);
27314 + break;
27315 + }
27316 + printk(KERN_ERR "klips_info: ipsec_alg_test() called incorrectly: "
27317 + "alg_type=%d alg_id=%d\n",
27318 + alg_type, alg_id);
27319 + return -EINVAL;
27320 +}
27321 +
27322 +int ipsec_alg_init(void) {
27323 + KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
27324 + "KLIPS alg v=%d.%d.%d-%d (EALG_MAX=%d, AALG_MAX=%d)\n",
27325 + IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION),
27326 + SADB_EALG_MAX, SADB_AALG_MAX);
27327 + /* Initialize tables */
27328 + write_lock_bh(&ipsec_alg_lock);
27329 + ipsec_alg_hash_init();
27330 + write_unlock_bh(&ipsec_alg_lock);
27331 +
27332 + /* Initialize static algos */
27333 + KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
27334 + "calling ipsec_alg_static_init()\n");
27335 +
27336 + /* If we are suppose to use our AES, and don't have
27337 + * CryptoAPI enabled...
27338 + */
27339 +#if defined(CONFIG_KLIPS_ENC_AES) && CONFIG_KLIPS_ENC_AES && !defined(CONFIG_KLIPS_ENC_AES_MODULE)
27340 +#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
27341 +#warning "Using built-in AES rather than CryptoAPI AES"
27342 +#endif
27343 + {
27344 + extern int ipsec_aes_init(void);
27345 + ipsec_aes_init();
27346 + }
27347 +#endif
27348 +
27349 +#if defined(CONFIG_KLIPS_ENC_3DES) && CONFIG_KLIPS_ENC_3DES && !defined(CONFIG_KLIPS_ENC_3DES_MODULE)
27350 +#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
27351 +#warning "Using built-in 3des rather than CryptoAPI 3des"
27352 +#endif
27353 + {
27354 + extern int ipsec_3des_init(void);
27355 + ipsec_3des_init();
27356 + }
27357 +#endif
27358 +
27359 + /* If we are doing CryptoAPI, then init */
27360 +#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI && !defined(CONFIG_KLIPS_ENC_CRYPTOAPI_MODULE)
27361 + {
27362 + extern int ipsec_cryptoapi_init(void);
27363 + ipsec_cryptoapi_init();
27364 + }
27365 +#endif
27366 +
27367 +
27368 + return 0;
27369 +}
27370 +
27371 +/**********************************************
27372 + *
27373 + * INTERFACE for ipsec_sa init and wipe
27374 + *
27375 + **********************************************/
27376 +
27377 +/*
27378 + * Called from pluto -> pfkey_v2_parser.c:pfkey_ipsec_sa_init()
27379 + */
27380 +int ipsec_alg_sa_init(struct ipsec_sa *sa_p) {
27381 + struct ipsec_alg_enc *ixt_e;
27382 + struct ipsec_alg_auth *ixt_a;
27383 +
27384 + /* Only ESP for now ... */
27385 + if (sa_p->ips_said.proto != IPPROTO_ESP)
27386 + return -EPROTONOSUPPORT;
27387 +
27388 + KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_init() :"
27389 + "entering for encalg=%d, authalg=%d\n",
27390 + sa_p->ips_encalg, sa_p->ips_authalg);
27391 +
27392 + if ((ixt_e=(struct ipsec_alg_enc *)
27393 + ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, sa_p->ips_encalg))) {
27394 + KLIPS_PRINT(debug_pfkey,
27395 + "klips_debug: ipsec_alg_sa_init() :"
27396 + "found ipsec_alg (ixt_e=%p) for encalg=%d\n",
27397 + ixt_e, sa_p->ips_encalg);
27398 + sa_p->ips_alg_enc=ixt_e;
27399 + }
27400 +
27401 + if ((ixt_a=(struct ipsec_alg_auth *)
27402 + ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, sa_p->ips_authalg))) {
27403 + KLIPS_PRINT(debug_pfkey,
27404 + "klips_debug: ipsec_alg_sa_init() :"
27405 + "found ipsec_alg (ixt_a=%p) for auth=%d\n",
27406 + ixt_a, sa_p->ips_authalg);
27407 + sa_p->ips_alg_auth=ixt_a;
27408 + }
27409 + return 0;
27410 +}
27411 +
27412 +/*
27413 + * Called from pluto -> ipsec_sa.c:ipsec_sa_delchain()
27414 + */
27415 +int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p) {
27416 + struct ipsec_alg *ixt;
27417 + if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_enc)) {
27418 + KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
27419 + "unlinking for encalg=%d\n",
27420 + ixt->ixt_support.ias_id);
27421 + ipsec_alg_put(ixt);
27422 + }
27423 + if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_auth)) {
27424 + KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
27425 + "unlinking for authalg=%d\n",
27426 + ixt->ixt_support.ias_id);
27427 + ipsec_alg_put(ixt);
27428 + }
27429 + return 0;
27430 +}
27431 +
27432 +IPSEC_PROCFS_DEBUG_NO_STATIC
27433 +int
27434 +ipsec_xform_get_info(char *buffer,
27435 + char **start,
27436 + off_t offset,
27437 + int length IPSEC_PROC_LAST_ARG)
27438 +{
27439 + int len = 0;
27440 + off_t begin = 0;
27441 + int i;
27442 + struct list_head *head;
27443 + struct ipsec_alg *ixt;
27444 +
27445 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
27446 + "klips_debug:ipsec_tncfg_get_info: "
27447 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
27448 + buffer,
27449 + *start,
27450 + (int)offset,
27451 + length);
27452 +
27453 + for(i = 0, head = ipsec_alg_hash_table;
27454 + i<IPSEC_ALG_HASHSZ;
27455 + i++, head++)
27456 + {
27457 + struct list_head *p;
27458 + for (p=head->next; p!=head; p=p->next)
27459 + {
27460 + ixt = list_entry(p, struct ipsec_alg, ixt_list);
27461 + len += ipsec_snprintf(buffer+len, length-len,
27462 + "VERSION=%d TYPE=%d ID=%d NAME=%s REFCNT=%d ",
27463 + ixt->ixt_version, ixt->ixt_alg_type, ixt->ixt_support.ias_id,
27464 + ixt->ixt_name, ixt->ixt_refcnt);
27465 +
27466 + len += ipsec_snprintf(buffer+len, length-len,
27467 + "STATE=%08x BLOCKSIZE=%d IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
27468 + ixt->ixt_state, ixt->ixt_blocksize,
27469 + ixt->ixt_support.ias_ivlen, ixt->ixt_support.ias_keyminbits, ixt->ixt_support.ias_keymaxbits);
27470 +
27471 + len += ipsec_snprintf(buffer+len, length-len,
27472 + "IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
27473 + ixt->ixt_support.ias_ivlen, ixt->ixt_support.ias_keyminbits, ixt->ixt_support.ias_keymaxbits);
27474 +
27475 + switch(ixt->ixt_alg_type)
27476 + {
27477 + case IPSEC_ALG_TYPE_AUTH:
27478 + {
27479 + struct ipsec_alg_auth *auth = (struct ipsec_alg_auth *)ixt;
27480 +
27481 + len += ipsec_snprintf(buffer+len, length-len,
27482 + "KEYLEN=%d CTXSIZE=%d AUTHLEN=%d ",
27483 + auth->ixt_a_keylen, auth->ixt_a_ctx_size,
27484 + auth->ixt_a_authlen);
27485 + break;
27486 + }
27487 + case IPSEC_ALG_TYPE_ENCRYPT:
27488 + {
27489 + struct ipsec_alg_enc *enc = (struct ipsec_alg_enc *)ixt;
27490 + len += ipsec_snprintf(buffer+len, length-len,
27491 + "KEYLEN=%d CTXSIZE=%d ",
27492 + enc->ixt_e_keylen, enc->ixt_e_ctx_size);
27493 +
27494 + break;
27495 + }
27496 + }
27497 +
27498 + len += ipsec_snprintf(buffer+len, length-len, "\n");
27499 + }
27500 + }
27501 +
27502 + *start = buffer + (offset - begin); /* Start of wanted data */
27503 + len -= (offset - begin); /* Start slop */
27504 + if (len > length)
27505 + len = length;
27506 + return len;
27507 +}
27508 +
27509 +
27510 +/*
27511 + * As the author of this module, I ONLY ALLOW using it from
27512 + * GPL (or same LICENSE TERMS as kernel source) modules.
27513 + *
27514 + * In respect to hardware crypto engines this means:
27515 + * * Closed-source device drivers ARE NOT ALLOWED to use
27516 + * this interface.
27517 + * * Closed-source VHDL/Verilog firmware running on
27518 + * the crypto hardware device IS ALLOWED to use this interface
27519 + * via a GPL (or same LICENSE TERMS as kernel source) device driver.
27520 + * --Juan Jose Ciarlante 20/03/2002 (thanks RGB for the correct wording)
27521 + */
27522 +
27523 +/*
27524 + * These symbols can only be used from GPL modules
27525 + * for now, I'm disabling this because it creates false
27526 + * symbol problems for old modutils.
27527 + */
27528 +
27529 +#ifdef CONFIG_MODULES
27530 +#ifndef NET_26
27531 +#if 0
27532 +#ifndef EXPORT_SYMBOL_GPL
27533 +#undef EXPORT_SYMBOL_GPL
27534 +#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
27535 +#endif
27536 +#endif
27537 +EXPORT_SYMBOL(register_ipsec_alg);
27538 +EXPORT_SYMBOL(unregister_ipsec_alg);
27539 +EXPORT_SYMBOL(ipsec_alg_test);
27540 +#endif
27541 +#endif
27542 --- /dev/null Tue Mar 11 13:02:56 2003
27543 +++ linux/net/ipsec/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
27544 @@ -0,0 +1,450 @@
27545 +/*
27546 + * ipsec_alg to linux cryptoapi GLUE
27547 + *
27548 + * Authors: CODE.ar TEAM
27549 + * Harpo MAxx <harpo@linuxmendoza.org.ar>
27550 + * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
27551 + * Luciano Ruete <docemeses@softhome.net>
27552 + *
27553 + * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
27554 + *
27555 + * This program is free software; you can redistribute it and/or modify it
27556 + * under the terms of the GNU General Public License as published by the
27557 + * Free Software Foundation; either version 2 of the License, or (at your
27558 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
27559 + *
27560 + * This program is distributed in the hope that it will be useful, but
27561 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27562 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27563 + * for more details.
27564 + *
27565 + * Example usage:
27566 + * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
27567 + * modprobe ipsec_cryptoapi
27568 + * modprobe ipsec_cryptoapi test=1
27569 + * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
27570 + * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
27571 + * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
27572 + * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
27573 + */
27574 +#ifndef AUTOCONF_INCLUDED
27575 +#include <linux/config.h>
27576 +#endif
27577 +#include <linux/version.h>
27578 +
27579 +/*
27580 + * special case: ipsec core modular with this static algo inside:
27581 + * must avoid MODULE magic for this file
27582 + */
27583 +#if CONFIG_KLIPS_MODULE && CONFIG_KLIPS_ENC_CRYPTOAPI
27584 +#undef MODULE
27585 +#endif
27586 +
27587 +#include <linux/module.h>
27588 +#include <linux/init.h>
27589 +
27590 +#include <linux/kernel.h> /* printk() */
27591 +#include <linux/errno.h> /* error codes */
27592 +#include <linux/types.h> /* size_t */
27593 +#include <linux/string.h>
27594 +
27595 +/* Check if __exit is defined, if not null it */
27596 +#ifndef __exit
27597 +#define __exit
27598 +#endif
27599 +
27600 +/* warn the innocent */
27601 +#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
27602 +#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
27603 +#define NO_CRYPTOAPI_SUPPORT
27604 +#endif
27605 +
27606 +#include "openswan.h"
27607 +#include "openswan/ipsec_alg.h"
27608 +#include "openswan/ipsec_policy.h"
27609 +
27610 +#include <linux/crypto.h>
27611 +#ifdef CRYPTO_API_VERSION_CODE
27612 +#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
27613 +#define NO_CRYPTOAPI_SUPPORT
27614 +#endif
27615 +
27616 +#ifdef NO_CRYPTOAPI_SUPPORT
27617 +#warning "Building an unusable module :P"
27618 +/* Catch old CryptoAPI by not allowing module to load */
27619 +IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
27620 +{
27621 + printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
27622 + return -EINVAL;
27623 +}
27624 +#else
27625 +#include <asm/scatterlist.h>
27626 +#include <asm/pgtable.h>
27627 +#include <linux/mm.h>
27628 +
27629 +#define CIPHERNAME_AES "aes"
27630 +#define CIPHERNAME_1DES "des"
27631 +#define CIPHERNAME_3DES "des3_ede"
27632 +#define CIPHERNAME_BLOWFISH "blowfish"
27633 +#define CIPHERNAME_CAST "cast5"
27634 +#define CIPHERNAME_SERPENT "serpent"
27635 +#define CIPHERNAME_TWOFISH "twofish"
27636 +
27637 +#define ESP_SERPENT 252 /* from ipsec drafts */
27638 +#define ESP_TWOFISH 253 /* from ipsec drafts */
27639 +
27640 +#define DIGESTNAME_MD5 "md5"
27641 +#define DIGESTNAME_SHA1 "sha1"
27642 +
27643 +MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
27644 +static int debug_crypto=0;
27645 +static int test_crypto=0;
27646 +static int excl_crypto=0;
27647 +#ifdef module_param
27648 +module_param(debug_crypto, int, 0664);
27649 +module_param(test_crypto, int, 0664);
27650 +module_param(excl_crypto, int, 0664);
27651 +#else
27652 +MODULE_PARM(debug_crypto, "i");
27653 +MODULE_PARM(test_crypto, "i");
27654 +MODULE_PARM(excl_crypto, "i");
27655 +#endif
27656 +
27657 +static int noauto = 0;
27658 +MODULE_PARM(noauto,"i");
27659 +MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
27660 +
27661 +#ifdef CONFIG_KLIPS_ENC_1DES
27662 +static int des_ede1[] = {-1, -1};
27663 +#endif
27664 +static int des_ede3[] = {-1, -1};
27665 +static int aes[] = {-1, -1};
27666 +static int blowfish[] = {-1, -1};
27667 +static int cast[] = {-1, -1};
27668 +static int serpent[] = {-1, -1};
27669 +static int twofish[] = {-1, -1};
27670 +
27671 +#ifdef module_param_array
27672 +#ifdef CONFIG_KLIPS_ENC_1DES
27673 +module_param_array(des_ede1,int,NULL,0);
27674 +#endif
27675 +module_param_array(des_ede3,int,NULL,0);
27676 +module_param_array(aes,int,NULL,0);
27677 +module_param_array(blowfish,int,NULL,0);
27678 +module_param_array(cast,int,NULL,0);
27679 +module_param_array(serpent,int,NULL,0);
27680 +module_param_array(twofish,int,NULL,0);
27681 +#else
27682 +#ifdef CONFIG_KLIPS_ENC_1DES
27683 +MODULE_PARM(des_ede1,"1-2i");
27684 +#endif
27685 +MODULE_PARM(des_ede3,"1-2i");
27686 +MODULE_PARM(aes,"1-2i");
27687 +MODULE_PARM(blowfish,"1-2i");
27688 +MODULE_PARM(cast,"1-2i");
27689 +MODULE_PARM(serpent,"1-2i");
27690 +MODULE_PARM(twofish,"1-2i");
27691 +#endif
27692 +MODULE_PARM_DESC(des_ede1, "0: disable | 1: force_enable | min,max: dontuse");
27693 +MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
27694 +MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
27695 +MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
27696 +MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
27697 +MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
27698 +MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
27699 +
27700 +struct ipsec_alg_capi_cipher {
27701 + const char *ciphername; /* cryptoapi's ciphername */
27702 + unsigned blocksize;
27703 + unsigned short minbits;
27704 + unsigned short maxbits;
27705 + int *parm; /* lkm param for this cipher */
27706 + struct ipsec_alg_enc alg; /* note it's not a pointer */
27707 +};
27708 +
27709 +static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
27710 + { CIPHERNAME_AES, 16, 128, 256, aes, { ixt_common:{ ixt_support:{ ias_id: ESP_AES}}}},
27711 + { CIPHERNAME_TWOFISH, 16, 128, 256, twofish, { ixt_common:{ ixt_support:{ ias_id: ESP_TWOFISH,}}}},
27712 + { CIPHERNAME_SERPENT, 16, 128, 256, serpent, { ixt_common:{ ixt_support:{ ias_id: ESP_SERPENT,}}}},
27713 + { CIPHERNAME_CAST, 8, 128, 128, cast , { ixt_common:{ ixt_support:{ ias_id: ESP_CAST,}}}},
27714 + { CIPHERNAME_BLOWFISH, 8, 96, 448, blowfish, { ixt_common:{ ixt_support:{ ias_id: ESP_BLOWFISH,}}}},
27715 + { CIPHERNAME_3DES, 8, 192, 192, des_ede3, { ixt_common:{ ixt_support:{ ias_id: ESP_3DES,}}}},
27716 +#ifdef CONFIG_KLIPS_ENC_1DES
27717 + { CIPHERNAME_1DES, 8, 64, 64, des_ede1, { ixt_common:{ ixt_support:{ ias_id: ESP_DES,}}}},
27718 +#endif
27719 + { NULL, 0, 0, 0, NULL, {} }
27720 +};
27721 +
27722 +#ifdef NOT_YET
27723 +struct ipsec_alg_capi_digest {
27724 + const char *digestname; /* cryptoapi's digestname */
27725 + struct digest_implementation *di;
27726 + struct ipsec_alg_auth alg; /* note it's not a pointer */
27727 +};
27728 +static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
27729 + { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
27730 + { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
27731 + { NULL, NULL, {} }
27732 +};
27733 +#endif
27734 +/*
27735 + * "generic" linux cryptoapi setup_cipher() function
27736 + */
27737 +int setup_cipher(const char *ciphername)
27738 +{
27739 + return crypto_alg_available(ciphername, 0);
27740 +}
27741 +
27742 +/*
27743 + * setups ipsec_alg_capi_cipher "hyper" struct components, calling
27744 + * register_ipsec_alg for cointaned ipsec_alg object
27745 + */
27746 +static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
27747 +static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
27748 +static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
27749 +
27750 +static int
27751 +setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
27752 +{
27753 + int ret;
27754 + cptr->alg.ixt_common.ixt_version = IPSEC_ALG_VERSION;
27755 + cptr->alg.ixt_common.ixt_module = THIS_MODULE;
27756 + atomic_set (& cptr->alg.ixt_common.ixt_refcnt, 0);
27757 + strncpy (cptr->alg.ixt_common.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_common.ixt_name));
27758 +
27759 + cptr->alg.ixt_common.ixt_blocksize=cptr->blocksize;
27760 + cptr->alg.ixt_common.ixt_support.ias_keyminbits=cptr->minbits;
27761 + cptr->alg.ixt_common.ixt_support.ias_keymaxbits=cptr->maxbits;
27762 + cptr->alg.ixt_common.ixt_state = 0;
27763 + if (excl_crypto) cptr->alg.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
27764 + cptr->alg.ixt_e_keylen=cptr->alg.ixt_common.ixt_support.ias_keymaxbits/8;
27765 + cptr->alg.ixt_e_ctx_size = 0;
27766 + cptr->alg.ixt_common.ixt_support.ias_exttype = IPSEC_ALG_TYPE_ENCRYPT;
27767 + cptr->alg.ixt_e_new_key = _capi_new_key;
27768 + cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
27769 + cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
27770 + cptr->alg.ixt_common.ixt_data = cptr;
27771 +
27772 + ret=register_ipsec_alg_enc(&cptr->alg);
27773 + printk(KERN_INFO "KLIPS cryptoapi interface: "
27774 + "alg_type=%d alg_id=%d name=%s "
27775 + "keyminbits=%d keymaxbits=%d, %s(%d)\n",
27776 + cptr->alg.ixt_common.ixt_support.ias_exttype,
27777 + cptr->alg.ixt_common.ixt_support.ias_id,
27778 + cptr->alg.ixt_common.ixt_name,
27779 + cptr->alg.ixt_common.ixt_support.ias_keyminbits,
27780 + cptr->alg.ixt_common.ixt_support.ias_keymaxbits,
27781 + ret ? "not found" : "found", ret);
27782 + return ret;
27783 +}
27784 +/*
27785 + * called in ipsec_sa_wipe() time, will destroy key contexts
27786 + * and do 1 unbind()
27787 + */
27788 +static void
27789 +_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
27790 +{
27791 + struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
27792 +
27793 + if (debug_crypto > 0)
27794 + printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
27795 + "name=%s key_e=%p \n",
27796 + alg->ixt_common.ixt_name, key_e);
27797 + if (!key_e) {
27798 + printk(KERN_ERR "klips_debug: _capi_destroy_key:"
27799 + "name=%s NULL key_e!\n",
27800 + alg->ixt_common.ixt_name);
27801 + return;
27802 + }
27803 + crypto_free_tfm(tfm);
27804 +}
27805 +
27806 +/*
27807 + * create new key context, need alg->ixt_data to know which
27808 + * (of many) cipher inside this module is the target
27809 + */
27810 +static __u8 *
27811 +_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
27812 +{
27813 + struct ipsec_alg_capi_cipher *cptr;
27814 + struct crypto_tfm *tfm=NULL;
27815 +
27816 + cptr = alg->ixt_common.ixt_data;
27817 + if (!cptr) {
27818 + printk(KERN_ERR "_capi_new_key(): "
27819 + "NULL ixt_data (?!) for \"%s\" algo\n"
27820 + , alg->ixt_common.ixt_name);
27821 + goto err;
27822 + }
27823 + if (debug_crypto > 0)
27824 + printk(KERN_DEBUG "klips_debug:_capi_new_key:"
27825 + "name=%s cptr=%p key=%p keysize=%d\n",
27826 + alg->ixt_common.ixt_name, cptr, key, keylen);
27827 +
27828 + /*
27829 + * alloc tfm
27830 + */
27831 + tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
27832 + if (!tfm) {
27833 + printk(KERN_ERR "_capi_new_key(): "
27834 + "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
27835 + , alg->ixt_common.ixt_name, cptr->ciphername);
27836 + goto err;
27837 + }
27838 + if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
27839 + printk(KERN_ERR "_capi_new_key(): "
27840 + "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
27841 + , alg->ixt_common.ixt_name, keylen);
27842 + crypto_free_tfm(tfm);
27843 + tfm=NULL;
27844 + }
27845 +err:
27846 + if (debug_crypto > 0)
27847 + printk(KERN_DEBUG "klips_debug:_capi_new_key:"
27848 + "name=%s key=%p keylen=%d tfm=%p\n",
27849 + alg->ixt_common.ixt_name, key, keylen, tfm);
27850 + return (__u8 *) tfm;
27851 +}
27852 +/*
27853 + * core encryption function: will use cx->ci to call actual cipher's
27854 + * cbc function
27855 + */
27856 +static int
27857 +_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
27858 + int error =0;
27859 + struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
27860 + struct scatterlist sg = {
27861 + .page = virt_to_page(in),
27862 + .offset = (unsigned long)(in) % PAGE_SIZE,
27863 + .length=ilen,
27864 + };
27865 + if (debug_crypto > 1)
27866 + printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
27867 + "key_e=%p "
27868 + "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
27869 + , key_e
27870 + , in, in, ilen, iv, encrypt);
27871 + crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
27872 + if (encrypt)
27873 + error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
27874 + else
27875 + error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
27876 + if (debug_crypto > 1)
27877 + printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
27878 + "error=%d\n"
27879 + , error);
27880 + return (error<0)? error : ilen;
27881 +}
27882 +/*
27883 + * main initialization loop: for each cipher in list, do
27884 + * 1) setup cryptoapi cipher else continue
27885 + * 2) register ipsec_alg object
27886 + */
27887 +static int
27888 +setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
27889 +{
27890 + struct ipsec_alg_capi_cipher *cptr;
27891 + /* foreach cipher in list ... */
27892 + for (cptr=clist;cptr->ciphername;cptr++) {
27893 + /*
27894 + * see if cipher has been disabled (0) or
27895 + * if noauto set and not enabled (1)
27896 + */
27897 + if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
27898 + if (debug_crypto>0)
27899 + printk(KERN_INFO "setup_cipher_list(): "
27900 + "ciphername=%s skipped at user request: "
27901 + "noauto=%d parm[0]=%d parm[1]=%d\n"
27902 + , cptr->ciphername
27903 + , noauto
27904 + , cptr->parm[0]
27905 + , cptr->parm[1]);
27906 + continue;
27907 + }
27908 + /*
27909 + * use a local ci to avoid touching cptr->ci,
27910 + * if register ipsec_alg success then bind cipher
27911 + */
27912 + if(cptr->alg.ixt_common.ixt_support.ias_name == NULL) {
27913 + cptr->alg.ixt_common.ixt_support.ias_name = cptr->ciphername;
27914 + }
27915 +
27916 + if( setup_cipher(cptr->ciphername) ) {
27917 + if (debug_crypto > 0)
27918 + printk(KERN_DEBUG "klips_debug:"
27919 + "setup_cipher_list():"
27920 + "ciphername=%s found\n"
27921 + , cptr->ciphername);
27922 +
27923 + if (setup_ipsec_alg_capi_cipher(cptr) != 0) {
27924 + printk(KERN_ERR "klips_debug:"
27925 + "setup_cipher_list():"
27926 + "ciphername=%s failed ipsec_alg_register\n"
27927 + , cptr->ciphername);
27928 + }
27929 + } else {
27930 + printk(KERN_INFO "KLIPS: lookup for ciphername=%s: not found \n",
27931 + cptr->ciphername);
27932 + }
27933 + }
27934 + return 0;
27935 +}
27936 +/*
27937 + * deregister ipsec_alg objects and unbind ciphers
27938 + */
27939 +static int
27940 +unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
27941 +{
27942 + struct ipsec_alg_capi_cipher *cptr;
27943 + /* foreach cipher in list ... */
27944 + for (cptr=clist;cptr->ciphername;cptr++) {
27945 + if (cptr->alg.ixt_common.ixt_state & IPSEC_ALG_ST_REGISTERED) {
27946 + unregister_ipsec_alg_enc(&cptr->alg);
27947 + }
27948 + }
27949 + return 0;
27950 +}
27951 +/*
27952 + * test loop for registered algos
27953 + */
27954 +static int
27955 +test_cipher_list (struct ipsec_alg_capi_cipher* clist)
27956 +{
27957 + int test_ret;
27958 + struct ipsec_alg_capi_cipher *cptr;
27959 + /* foreach cipher in list ... */
27960 + for (cptr=clist;cptr->ciphername;cptr++) {
27961 + if (cptr->alg.ixt_common.ixt_state & IPSEC_ALG_ST_REGISTERED) {
27962 + test_ret=ipsec_alg_test(
27963 + cptr->alg.ixt_common.ixt_support.ias_exttype,
27964 + cptr->alg.ixt_common.ixt_support.ias_id,
27965 + test_crypto);
27966 + printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
27967 + cptr->alg.ixt_common.ixt_support.ias_exttype,
27968 + cptr->alg.ixt_common.ixt_support.ias_id,
27969 + test_ret);
27970 + }
27971 + }
27972 + return 0;
27973 +}
27974 +
27975 +IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
27976 +{
27977 + int ret, test_ret;
27978 + if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
27979 + return -EPROTONOSUPPORT;
27980 + if (ret==0 && test_crypto) {
27981 + test_ret=test_cipher_list(alg_capi_carray);
27982 + }
27983 + return ret;
27984 +}
27985 +IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_cryptoapi_fini )
27986 +{
27987 + unsetup_cipher_list(alg_capi_carray);
27988 + return;
27989 +}
27990 +#ifdef MODULE_LICENSE
27991 +MODULE_LICENSE("GPL");
27992 +#endif
27993 +
27994 +#endif /* NO_CRYPTOAPI_SUPPORT */
27995 --- /dev/null Tue Mar 11 13:02:56 2003
27996 +++ linux/net/ipsec/ipsec_esp.c Mon Feb 9 13:51:03 2004
27997 @@ -0,0 +1,599 @@
27998 +/*
27999 + * processing code for ESP
28000 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
28001 + *
28002 + * This program is free software; you can redistribute it and/or modify it
28003 + * under the terms of the GNU General Public License as published by the
28004 + * Free Software Foundation; either version 2 of the License, or (at your
28005 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
28006 + *
28007 + * This program is distributed in the hope that it will be useful, but
28008 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28009 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28010 + * for more details.
28011 + */
28012 +
28013 +char ipsec_esp_c_version[] = "RCSID $Id: ipsec_esp.c,v 1.13.2.4 2006/05/06 03:07:38 ken Exp $";
28014 +#ifndef AUTOCONF_INCLUDED
28015 +#include <linux/config.h>
28016 +#endif
28017 +#include <linux/version.h>
28018 +
28019 +#define __NO_VERSION__
28020 +#include <linux/module.h>
28021 +#include <linux/kernel.h> /* printk() */
28022 +
28023 +#include "openswan/ipsec_param.h"
28024 +
28025 +#ifdef MALLOC_SLAB
28026 +# include <linux/slab.h> /* kmalloc() */
28027 +#else /* MALLOC_SLAB */
28028 +# include <linux/malloc.h> /* kmalloc() */
28029 +#endif /* MALLOC_SLAB */
28030 +#include <linux/errno.h> /* error codes */
28031 +#include <linux/types.h> /* size_t */
28032 +#include <linux/interrupt.h> /* mark_bh */
28033 +
28034 +#include <linux/netdevice.h> /* struct device, and other headers */
28035 +#include <linux/etherdevice.h> /* eth_type_trans */
28036 +#include <linux/ip.h> /* struct iphdr */
28037 +#include <linux/skbuff.h>
28038 +#include <openswan.h>
28039 +#ifdef SPINLOCK
28040 +# ifdef SPINLOCK_23
28041 +# include <linux/spinlock.h> /* *lock* */
28042 +# else /* SPINLOCK_23 */
28043 +# include <asm/spinlock.h> /* *lock* */
28044 +# endif /* SPINLOCK_23 */
28045 +#endif /* SPINLOCK */
28046 +
28047 +#include <net/ip.h>
28048 +#include <net/protocol.h>
28049 +
28050 +#include "openswan/radij.h"
28051 +#include "openswan/ipsec_encap.h"
28052 +#include "openswan/ipsec_sa.h"
28053 +
28054 +#include "openswan/ipsec_radij.h"
28055 +#include "openswan/ipsec_xform.h"
28056 +#include "openswan/ipsec_tunnel.h"
28057 +#include "openswan/ipsec_rcv.h"
28058 +#include "openswan/ipsec_xmit.h"
28059 +
28060 +#include "openswan/ipsec_auth.h"
28061 +
28062 +#ifdef CONFIG_KLIPS_ESP
28063 +#include "openswan/ipsec_esp.h"
28064 +#endif /* CONFIG_KLIPS_ESP */
28065 +
28066 +#include "openswan/ipsec_proto.h"
28067 +#include "openswan/ipsec_alg.h"
28068 +
28069 +#ifdef CONFIG_KLIPS_DEBUG
28070 +#define ESP_DMP(_x,_y,_z) if(debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
28071 +#else
28072 +#define ESP_DMP(_x,_y,_z)
28073 +#endif
28074 +
28075 +#ifdef CONFIG_KLIPS_ESP
28076 +enum ipsec_rcv_value
28077 +ipsec_rcv_esp_checks(struct ipsec_rcv_state *irs,
28078 + struct sk_buff *skb)
28079 +{
28080 + __u8 proto;
28081 + int len; /* packet length */
28082 +
28083 + len = skb->len;
28084 + proto = irs->ipp->protocol;
28085 +
28086 + /* XXX this will need to be 8 for IPv6 */
28087 + if ((proto == IPPROTO_ESP) && ((len - irs->iphlen) % 4)) {
28088 + printk("klips_error:ipsec_rcv: "
28089 + "got packet with content length = %d from %s -- should be on 4 octet boundary, packet dropped\n",
28090 + len - irs->iphlen,
28091 + irs->ipsaddr_txt);
28092 + if(irs->stats) {
28093 + irs->stats->rx_errors++;
28094 + }
28095 + return IPSEC_RCV_BADLEN;
28096 + }
28097 +
28098 + if(skb->len < (irs->hard_header_len + sizeof(struct iphdr) + sizeof(struct esphdr))) {
28099 + KLIPS_PRINT(debug_rcv & DB_RX_INAU,
28100 + "klips_debug:ipsec_rcv: "
28101 + "runt esp packet of skb->len=%d received from %s, dropped.\n",
28102 + skb->len,
28103 + irs->ipsaddr_txt);
28104 + if(irs->stats) {
28105 + irs->stats->rx_errors++;
28106 + }
28107 + return IPSEC_RCV_BADLEN;
28108 + }
28109 +
28110 + irs->protostuff.espstuff.espp = (struct esphdr *)skb->h.raw;
28111 + irs->said.spi = irs->protostuff.espstuff.espp->esp_spi;
28112 +
28113 + return IPSEC_RCV_OK;
28114 +}
28115 +
28116 +enum ipsec_rcv_value
28117 +ipsec_rcv_esp_decrypt_setup(struct ipsec_rcv_state *irs,
28118 + struct sk_buff *skb,
28119 + __u32 *replay,
28120 + unsigned char **authenticator)
28121 +{
28122 + struct esphdr *espp = irs->protostuff.espstuff.espp;
28123 + //unsigned char *idat = (unsigned char *)espp;
28124 +
28125 + KLIPS_PRINT(debug_rcv,
28126 + "klips_debug:ipsec_rcv: "
28127 + "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n",
28128 + irs->ipsaddr_txt,
28129 + (__u32)ntohl(espp->esp_rpl),
28130 + (__u32)ntohl(*((__u32 *)(espp->esp_iv) )),
28131 + (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)),
28132 + irs->len,
28133 + irs->ilen,
28134 + irs->sa_len ? irs->sa : " (error)");
28135 +
28136 + *replay = ntohl(espp->esp_rpl);
28137 + *authenticator = &(skb->h.raw[irs->ilen]);
28138 +
28139 + return IPSEC_RCV_OK;
28140 +}
28141 +
28142 +enum ipsec_rcv_value
28143 +ipsec_rcv_esp_authcalc(struct ipsec_rcv_state *irs,
28144 + struct sk_buff *skb)
28145 +{
28146 + struct auth_alg *aa;
28147 + struct esphdr *espp = irs->protostuff.espstuff.espp;
28148 + union {
28149 + MD5_CTX md5;
28150 + SHA1_CTX sha1;
28151 + } tctx;
28152 +
28153 + if (irs->ipsp->ips_alg_auth) {
28154 + KLIPS_PRINT(debug_rcv,
28155 + "klips_debug:ipsec_rcv: "
28156 + "ipsec_alg hashing proto=%d... ",
28157 + irs->said.proto);
28158 + if(irs->said.proto == IPPROTO_ESP) {
28159 + ipsec_alg_sa_esp_hash(irs->ipsp,
28160 + (caddr_t)espp, irs->ilen,
28161 + irs->hash, AHHMAC_HASHLEN);
28162 + return IPSEC_RCV_OK;
28163 + }
28164 + return IPSEC_RCV_BADPROTO;
28165 + }
28166 + aa = irs->authfuncs;
28167 +
28168 + /* copy the initialized keying material */
28169 + memcpy(&tctx, irs->ictx, irs->ictx_len);
28170 +
28171 +#ifdef HASH_DEBUG
28172 + ESP_DMP("ictx", irs->ictx, irs->ictx_len);
28173 +
28174 + ESP_DMP("mac_esp", (caddr_t)espp, irs->ilen);
28175 +#endif
28176 + (*aa->update)((void *)&tctx, (caddr_t)espp, irs->ilen);
28177 +
28178 + (*aa->final)(irs->hash, (void *)&tctx);
28179 +
28180 +#ifdef HASH_DEBUG
28181 + ESP_DMP("hash1", irs->hash, aa->hashlen);
28182 +#endif
28183 +
28184 + memcpy(&tctx, irs->octx, irs->octx_len);
28185 +
28186 +#ifdef HASH_DEBUG
28187 + ESP_DMP("octx", irs->octx, irs->octx_len);
28188 +#endif
28189 +
28190 + (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
28191 + (*aa->final)(irs->hash, (void *)&tctx);
28192 +
28193 + return IPSEC_RCV_OK;
28194 +}
28195 +
28196 +
28197 +enum ipsec_rcv_value
28198 +ipsec_rcv_esp_decrypt(struct ipsec_rcv_state *irs)
28199 +{
28200 + struct ipsec_sa *ipsp = irs->ipsp;
28201 + struct esphdr *espp = irs->protostuff.espstuff.espp;
28202 + int i;
28203 + int pad = 0, padlen;
28204 + int badpad = 0;
28205 + int esphlen = 0;
28206 + __u8 *idat; /* pointer to content to be decrypted/authenticated */
28207 + int encaplen = 0;
28208 + struct sk_buff *skb;
28209 + struct ipsec_alg_enc *ixt_e=NULL;
28210 +
28211 + skb=irs->skb;
28212 +
28213 + idat = skb->h.raw;
28214 +
28215 + /* encaplen is the distance between the end of the IP
28216 + * header and the beginning of the ESP header.
28217 + * on ESP headers it is zero, but on UDP-encap ESP
28218 + * it includes the space for the UDP header.
28219 + *
28220 + * Note: UDP-encap code has already moved the
28221 + * skb->data forward to accomodate this.
28222 + */
28223 + encaplen = idat - (skb->nh.raw + irs->iphlen);
28224 +
28225 + ixt_e=ipsp->ips_alg_enc;
28226 + esphlen = ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
28227 + KLIPS_PRINT(debug_rcv,
28228 + "klips_debug:ipsec_rcv: "
28229 + "encalg=%d esphlen=%d\n",
28230 + ipsp->ips_encalg, esphlen);
28231 +
28232 + idat += esphlen;
28233 + irs->ilen -= esphlen;
28234 +
28235 + if (ipsec_alg_esp_encrypt(ipsp,
28236 + idat, irs->ilen, espp->esp_iv,
28237 + IPSEC_ALG_DECRYPT) <= 0) {
28238 + KLIPS_ERROR(debug_rcv, "klips_error:ipsec_rcv: "
28239 + "got packet with esplen = %d "
28240 + "from %s -- should be on "
28241 + "ENC(%d) octet boundary, "
28242 + "packet dropped\n",
28243 + irs->ilen,
28244 + irs->ipsaddr_txt,
28245 + ipsp->ips_encalg);
28246 + if(irs->stats) {
28247 + irs->stats->rx_errors++;
28248 + }
28249 + return IPSEC_RCV_BAD_DECRYPT;
28250 + }
28251 +
28252 + ESP_DMP("postdecrypt", idat, irs->ilen);
28253 +
28254 + irs->next_header = idat[irs->ilen - 1];
28255 + padlen = idat[irs->ilen - 2];
28256 + pad = padlen + 2 + irs->authlen;
28257 +
28258 + KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28259 + "klips_debug:ipsec_rcv: "
28260 + "padlen=%d, contents: 0x<offset>: 0x<value> 0x<value> ...\n",
28261 + padlen);
28262 +
28263 + for (i = 1; i <= padlen; i++) {
28264 + if((i % 16) == 1) {
28265 + KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28266 + "klips_debug: %02x:",
28267 + i - 1);
28268 + }
28269 + KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28270 + " %02x",
28271 + idat[irs->ilen - 2 - padlen + i - 1]);
28272 + if(i != idat[irs->ilen - 2 - padlen + i - 1]) {
28273 + badpad = 1;
28274 + }
28275 + if((i % 16) == 0) {
28276 + KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28277 + "\n");
28278 + }
28279 + }
28280 + if((i % 16) != 1) {
28281 + KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28282 + "\n");
28283 + }
28284 + if(badpad) {
28285 + KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28286 + "klips_debug:ipsec_rcv: "
28287 + "warning, decrypted packet from %s has bad padding\n",
28288 + irs->ipsaddr_txt);
28289 + KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28290 + "klips_debug:ipsec_rcv: "
28291 + "...may be bad decryption -- not dropped\n");
28292 + ipsp->ips_errs.ips_encpad_errs += 1;
28293 + }
28294 +
28295 + KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28296 + "klips_debug:ipsec_rcv: "
28297 + "packet decrypted from %s: next_header = %d, padding = %d\n",
28298 + irs->ipsaddr_txt,
28299 + irs->next_header,
28300 + pad - 2 - irs->authlen);
28301 +
28302 + irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - (esphlen + pad));
28303 +
28304 + /*
28305 + * move the IP header forward by the size of the ESP header, which
28306 + * will remove the the ESP header from the packet.
28307 + *
28308 + * XXX this is really unnecessary, since odds we are in tunnel
28309 + * mode, and we will be *removing* this IP header.
28310 + *
28311 + */
28312 + memmove((void *)(idat - irs->iphlen),
28313 + (void *)(skb->nh.raw), irs->iphlen);
28314 +
28315 + ESP_DMP("esp postmove", (idat - irs->iphlen),
28316 + irs->iphlen + irs->ilen);
28317 +
28318 + /* skb_pull below, will move up by esphlen */
28319 +
28320 + /* XXX not clear how this can happen, as the message indicates */
28321 + if(skb->len < esphlen) {
28322 + printk(KERN_WARNING
28323 + "klips_error:ipsec_rcv: "
28324 + "tried to skb_pull esphlen=%d, %d available. This should never happen, please report.\n",
28325 + esphlen, (int)(skb->len));
28326 + return IPSEC_RCV_ESP_DECAPFAIL;
28327 + }
28328 + skb_pull(skb, esphlen);
28329 + skb->nh.raw = idat - irs->iphlen;
28330 + irs->ipp = skb->nh.iph;
28331 +
28332 + ESP_DMP("esp postpull", skb->data, skb->len);
28333 +
28334 + /* now, trip off the padding from the end */
28335 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
28336 + "klips_debug:ipsec_rcv: "
28337 + "trimming to %d.\n",
28338 + irs->len - esphlen - pad);
28339 + if(pad + esphlen <= irs->len) {
28340 + skb_trim(skb, irs->len - esphlen - pad);
28341 + } else {
28342 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
28343 + "klips_debug:ipsec_rcv: "
28344 + "bogus packet, size is zero or negative, dropping.\n");
28345 + return IPSEC_RCV_DECAPFAIL;
28346 + }
28347 +
28348 + return IPSEC_RCV_OK;
28349 +}
28350 +
28351 +/*
28352 + *
28353 + */
28354 +enum ipsec_xmit_value
28355 +ipsec_xmit_esp_setup(struct ipsec_xmit_state *ixs)
28356 +{
28357 +#ifdef CONFIG_KLIPS_ENC_3DES
28358 + __u32 iv[2];
28359 +#endif
28360 + struct esphdr *espp;
28361 + int ilen = 0;
28362 + int padlen = 0, i;
28363 + unsigned char *dat;
28364 + unsigned char *idat, *pad;
28365 + __u8 hash[AH_AMAX];
28366 + union {
28367 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
28368 + MD5_CTX md5;
28369 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
28370 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
28371 + SHA1_CTX sha1;
28372 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
28373 + } tctx;
28374 +
28375 + dat = (unsigned char *)ixs->iph;
28376 +
28377 + espp = (struct esphdr *)(dat + ixs->iphlen);
28378 + espp->esp_spi = ixs->ipsp->ips_said.spi;
28379 + espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
28380 +
28381 + switch(ixs->ipsp->ips_encalg) {
28382 +#if defined(CONFIG_KLIPS_ENC_3DES)
28383 +#ifdef CONFIG_KLIPS_ENC_3DES
28384 + case ESP_3DES:
28385 +#endif /* CONFIG_KLIPS_ENC_3DES */
28386 + iv[0] = *((__u32*)&(espp->esp_iv) ) =
28387 + ((__u32*)(ixs->ipsp->ips_iv))[0];
28388 + iv[1] = *((__u32*)&(espp->esp_iv) + 1) =
28389 + ((__u32*)(ixs->ipsp->ips_iv))[1];
28390 + break;
28391 +#endif /* defined(CONFIG_KLIPS_ENC_3DES) */
28392 + default:
28393 + ixs->stats->tx_errors++;
28394 + return IPSEC_XMIT_ESP_BADALG;
28395 + }
28396 +
28397 + idat = dat + ixs->iphlen + sizeof(struct esphdr);
28398 + ilen = ixs->skb->len - (ixs->iphlen + sizeof(struct esphdr) + ixs->authlen);
28399 +
28400 + /* Self-describing padding */
28401 + pad = &dat[ixs->skb->len - ixs->tailroom];
28402 + padlen = ixs->tailroom - 2 - ixs->authlen;
28403 + for (i = 0; i < padlen; i++) {
28404 + pad[i] = i + 1;
28405 + }
28406 + dat[ixs->skb->len - ixs->authlen - 2] = padlen;
28407 +
28408 + dat[ixs->skb->len - ixs->authlen - 1] = ixs->iph->protocol;
28409 + ixs->iph->protocol = IPPROTO_ESP;
28410 +
28411 + switch(ixs->ipsp->ips_encalg) {
28412 +#ifdef CONFIG_KLIPS_ENC_3DES
28413 + case ESP_3DES:
28414 + des_ede3_cbc_encrypt((des_cblock *)idat,
28415 + (des_cblock *)idat,
28416 + ilen,
28417 + ((struct des_eks *)(ixs->ipsp->ips_key_e))[0].ks,
28418 + ((struct des_eks *)(ixs->ipsp->ips_key_e))[1].ks,
28419 + ((struct des_eks *)(ixs->ipsp->ips_key_e))[2].ks,
28420 + (des_cblock *)iv, 1);
28421 + break;
28422 +#endif /* CONFIG_KLIPS_ENC_3DES */
28423 + default:
28424 + ixs->stats->tx_errors++;
28425 + return IPSEC_XMIT_ESP_BADALG;
28426 + }
28427 +
28428 + switch(ixs->ipsp->ips_encalg) {
28429 +#if defined(CONFIG_KLIPS_ENC_3DES)
28430 +#ifdef CONFIG_KLIPS_ENC_3DES
28431 + case ESP_3DES:
28432 +#endif /* CONFIG_KLIPS_ENC_3DES */
28433 + /* XXX update IV with the last 8 octets of the encryption */
28434 +#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK
28435 + ((__u32*)(ixs->ipsp->ips_iv))[0] =
28436 + ((__u32 *)(idat))[(ilen >> 2) - 2];
28437 + ((__u32*)(ixs->ipsp->ips_iv))[1] =
28438 + ((__u32 *)(idat))[(ilen >> 2) - 1];
28439 +#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
28440 + prng_bytes(&ipsec_prng, (char *)ixs->ipsp->ips_iv, EMT_ESPDES_IV_SZ);
28441 +#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
28442 + break;
28443 +#endif /* defined(CONFIG_KLIPS_ENC_3DES) */
28444 + default:
28445 + ixs->stats->tx_errors++;
28446 + return IPSEC_XMIT_ESP_BADALG;
28447 + }
28448 +
28449 + switch(ixs->ipsp->ips_authalg) {
28450 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
28451 + case AH_MD5:
28452 + ipsec_xmit_dmp("espp", (char*)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
28453 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
28454 + ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
28455 + osMD5Update(&tctx.md5, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
28456 + ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
28457 + osMD5Final(hash, &tctx.md5);
28458 + ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
28459 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
28460 + ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
28461 + osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
28462 + ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
28463 + osMD5Final(hash, &tctx.md5);
28464 + ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
28465 + memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
28466 +
28467 + /* paranoid */
28468 + memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
28469 + memset((caddr_t)hash, 0, sizeof(*hash));
28470 + break;
28471 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
28472 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
28473 + case AH_SHA:
28474 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
28475 + SHA1Update(&tctx.sha1, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
28476 + SHA1Final(hash, &tctx.sha1);
28477 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
28478 + SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
28479 + SHA1Final(hash, &tctx.sha1);
28480 + memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
28481 +
28482 + /* paranoid */
28483 + memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
28484 + memset((caddr_t)hash, 0, sizeof(*hash));
28485 + break;
28486 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
28487 + case AH_NONE:
28488 + break;
28489 + default:
28490 + ixs->stats->tx_errors++;
28491 + return IPSEC_XMIT_AH_BADALG;
28492 + }
28493 +
28494 + ixs->skb->h.raw = (unsigned char*)espp;
28495 +
28496 + return IPSEC_XMIT_OK;
28497 +}
28498 +
28499 +
28500 +struct xform_functions esp_xform_funcs[]={
28501 + { rcv_checks: ipsec_rcv_esp_checks,
28502 + rcv_setup_auth: ipsec_rcv_esp_decrypt_setup,
28503 + rcv_calc_auth: ipsec_rcv_esp_authcalc,
28504 + rcv_decrypt: ipsec_rcv_esp_decrypt,
28505 +
28506 + xmit_setup: ipsec_xmit_esp_setup,
28507 + xmit_headroom: sizeof(struct esphdr),
28508 + xmit_needtailroom: 1,
28509 + },
28510 +};
28511 +
28512 +#ifndef CONFIG_XFRM_ALTERNATE_STACK
28513 +#ifdef NET_26
28514 +struct inet_protocol esp_protocol = {
28515 + .handler = ipsec_rcv,
28516 + .no_policy = 1,
28517 +};
28518 +#else
28519 +struct inet_protocol esp_protocol =
28520 +{
28521 + ipsec_rcv, /* ESP handler */
28522 + NULL, /* TUNNEL error control */
28523 +#ifdef NETDEV_25
28524 + 1, /* no policy */
28525 +#else
28526 + 0, /* next */
28527 + IPPROTO_ESP, /* protocol ID */
28528 + 0, /* copy */
28529 + NULL, /* data */
28530 + "ESP" /* name */
28531 +#endif
28532 +};
28533 +#endif /* NET_26 */
28534 +#endif /* CONFIG_XFRM_ALTERNATE_STACK */
28535 +
28536 +#endif /* !CONFIG_KLIPS_ESP */
28537 +
28538 +
28539 +/*
28540 + * $Log: ipsec_esp.c,v $
28541 + * Revision 1.13.2.4 2006/05/06 03:07:38 ken
28542 + * Pull in proper padsize->tailroom fix from #public
28543 + * Need to do correct math on padlen since padsize is not equal to tailroom
28544 + *
28545 + * Revision 1.13.2.3 2006/05/05 03:58:04 ken
28546 + * ixs->padsize becomes ixs->tailroom
28547 + *
28548 + * Revision 1.13.2.2 2006/05/01 14:36:03 mcr
28549 + * use KLIPS_ERROR for fatal things.
28550 + *
28551 + * Revision 1.13.2.1 2006/04/20 16:33:06 mcr
28552 + * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
28553 + * Fix in-kernel module compilation. Sub-makefiles do not work.
28554 + *
28555 + * Revision 1.13 2005/05/21 03:19:57 mcr
28556 + * hash ctx is not really that interesting most of the time.
28557 + *
28558 + * Revision 1.12 2005/05/11 01:28:49 mcr
28559 + * removed "poor-man"s OOP in favour of proper C structures.
28560 + *
28561 + * Revision 1.11 2005/04/29 05:10:22 mcr
28562 + * removed from extraenous includes to make unit testing easier.
28563 + *
28564 + * Revision 1.10 2005/04/17 04:36:14 mcr
28565 + * code now deals with ESP and UDP-ESP code.
28566 + *
28567 + * Revision 1.9 2005/04/15 19:52:30 mcr
28568 + * adjustments to use proper skb fields for data.
28569 + *
28570 + * Revision 1.8 2004/09/14 00:22:57 mcr
28571 + * adjustment of MD5* functions.
28572 + *
28573 + * Revision 1.7 2004/09/13 02:23:01 mcr
28574 + * #define inet_protocol if necessary.
28575 + *
28576 + * Revision 1.6 2004/09/06 18:35:49 mcr
28577 + * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
28578 + * so adjust for that.
28579 + *
28580 + * Revision 1.5 2004/08/17 03:27:23 mcr
28581 + * klips 2.6 edits.
28582 + *
28583 + * Revision 1.4 2004/08/04 15:57:07 mcr
28584 + * moved des .h files to include/des/ *
28585 + * included 2.6 protocol specific things
28586 + * started at NAT-T support, but it will require a kernel patch.
28587 + *
28588 + * Revision 1.3 2004/07/10 19:11:18 mcr
28589 + * CONFIG_IPSEC -> CONFIG_KLIPS.
28590 + *
28591 + * Revision 1.2 2004/04/06 02:49:25 mcr
28592 + * pullup of algo code from alg-branch.
28593 + *
28594 + *
28595 + *
28596 + */
28597 --- /dev/null Tue Mar 11 13:02:56 2003
28598 +++ linux/net/ipsec/ipsec_init.c Mon Feb 9 13:51:03 2004
28599 @@ -0,0 +1,683 @@
28600 +/*
28601 + * @(#) Initialization code.
28602 + * Copyright (C) 1996, 1997 John Ioannidis.
28603 + * Copyright (C) 1998 - 2002 Richard Guy Briggs <rgb@freeswan.org>
28604 + * 2001 - 2004 Michael Richardson <mcr@xelerance.com>
28605 + *
28606 + * This program is free software; you can redistribute it and/or modify it
28607 + * under the terms of the GNU General Public License as published by the
28608 + * Free Software Foundation; either version 2 of the License, or (at your
28609 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
28610 + *
28611 + * This program is distributed in the hope that it will be useful, but
28612 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28613 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28614 + * for more details.
28615 + *
28616 + * /proc system code was split out into ipsec_proc.c after rev. 1.70.
28617 + *
28618 + */
28619 +
28620 +char ipsec_init_c_version[] = "RCSID $Id: ipsec_init.c,v 1.104.2.2 2006/04/20 16:33:06 mcr Exp $";
28621 +
28622 +#ifndef AUTOCONF_INCLUDED
28623 +#include <linux/config.h>
28624 +#endif
28625 +#include <linux/version.h>
28626 +#include <linux/module.h>
28627 +#include <linux/kernel.h> /* printk() */
28628 +
28629 +#include "openswan/ipsec_param.h"
28630 +
28631 +#ifdef MALLOC_SLAB
28632 +# include <linux/slab.h> /* kmalloc() */
28633 +#else /* MALLOC_SLAB */
28634 +# include <linux/malloc.h> /* kmalloc() */
28635 +#endif /* MALLOC_SLAB */
28636 +#include <linux/errno.h> /* error codes */
28637 +#include <linux/types.h> /* size_t */
28638 +#include <linux/interrupt.h> /* mark_bh */
28639 +
28640 +#include <linux/netdevice.h> /* struct device, and other headers */
28641 +#include <linux/etherdevice.h> /* eth_type_trans */
28642 +#include <linux/ip.h> /* struct iphdr */
28643 +#include <linux/in.h> /* struct sockaddr_in */
28644 +#include <linux/skbuff.h>
28645 +#include <linux/random.h> /* get_random_bytes() */
28646 +#include <net/protocol.h>
28647 +
28648 +#include <openswan.h>
28649 +
28650 +#ifdef SPINLOCK
28651 +# ifdef SPINLOCK_23
28652 +# include <linux/spinlock.h> /* *lock* */
28653 +# else /* 23_SPINLOCK */
28654 +# include <asm/spinlock.h> /* *lock* */
28655 +# endif /* 23_SPINLOCK */
28656 +#endif /* SPINLOCK */
28657 +
28658 +#include <net/ip.h>
28659 +
28660 +#ifdef CONFIG_PROC_FS
28661 +# include <linux/proc_fs.h>
28662 +#endif /* CONFIG_PROC_FS */
28663 +
28664 +#ifdef NETLINK_SOCK
28665 +# include <linux/netlink.h>
28666 +#else
28667 +# include <net/netlink.h>
28668 +#endif
28669 +
28670 +#include "openswan/radij.h"
28671 +
28672 +#include "openswan/ipsec_life.h"
28673 +#include "openswan/ipsec_stats.h"
28674 +#include "openswan/ipsec_sa.h"
28675 +
28676 +#include "openswan/ipsec_encap.h"
28677 +#include "openswan/ipsec_radij.h"
28678 +#include "openswan/ipsec_xform.h"
28679 +#include "openswan/ipsec_tunnel.h"
28680 +
28681 +#include "openswan/ipsec_rcv.h"
28682 +#include "openswan/ipsec_ah.h"
28683 +#include "openswan/ipsec_esp.h"
28684 +
28685 +#ifdef CONFIG_KLIPS_IPCOMP
28686 +# include "openswan/ipcomp.h"
28687 +#endif /* CONFIG_KLIPS_IPCOMP */
28688 +
28689 +#include "openswan/ipsec_proto.h"
28690 +#include "openswan/ipsec_alg.h"
28691 +
28692 +#include <openswan/pfkeyv2.h>
28693 +#include <openswan/pfkey.h>
28694 +
28695 +#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
28696 +#include <net/xfrmudp.h>
28697 +#endif
28698 +
28699 +#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(HAVE_XFRM4_UDP_REGISTER)
28700 +#warning "You are trying to build KLIPS2.6 with NAT-T support, but you did not"
28701 +#error "properly apply the NAT-T patch to your 2.6 kernel source tree."
28702 +#endif
28703 +
28704 +#if !defined(CONFIG_KLIPS_ESP) && !defined(CONFIG_KLIPS_AH)
28705 +#error "kernel configuration must include ESP or AH"
28706 +#endif
28707 +
28708 +/*
28709 + * seems to be present in 2.4.10 (Linus), but also in some RH and other
28710 + * distro kernels of a lower number.
28711 + */
28712 +#ifdef MODULE_LICENSE
28713 +MODULE_LICENSE("GPL");
28714 +#endif
28715 +
28716 +#ifdef CONFIG_KLIPS_DEBUG
28717 +int debug_eroute = 0;
28718 +int debug_spi = 0;
28719 +int debug_netlink = 0;
28720 +#endif /* CONFIG_KLIPS_DEBUG */
28721 +
28722 +struct prng ipsec_prng;
28723 +
28724 +
28725 +#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
28726 +xfrm4_rcv_encap_t klips_old_encap = NULL;
28727 +#endif
28728 +
28729 +extern int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr);
28730 +/*
28731 + * the following structure is required so that we receive
28732 + * event notifications when network devices are enabled and
28733 + * disabled (ifconfig up and down).
28734 + */
28735 +static struct notifier_block ipsec_dev_notifier={
28736 + ipsec_device_event,
28737 + NULL,
28738 + 0
28739 +};
28740 +
28741 +#ifdef CONFIG_SYSCTL
28742 +extern int ipsec_sysctl_register(void);
28743 +extern void ipsec_sysctl_unregister(void);
28744 +#endif
28745 +
28746 +#ifdef NET_26
28747 +static inline int
28748 +openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol)
28749 +{
28750 + return inet_add_protocol(prot, protocol);
28751 +}
28752 +
28753 +static inline int
28754 +openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
28755 +{
28756 + return inet_del_protocol(prot, protocol);
28757 +}
28758 +
28759 +#else
28760 +static inline int
28761 +openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol)
28762 +{
28763 + inet_add_protocol(prot);
28764 + return 0;
28765 +}
28766 +
28767 +static inline int
28768 +openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
28769 +{
28770 + inet_del_protocol(prot);
28771 + return 0;
28772 +}
28773 +
28774 +#endif
28775 +
28776 +/* void */
28777 +int
28778 +ipsec_klips_init(void)
28779 +{
28780 + int error = 0;
28781 + unsigned char seed[256];
28782 +#ifdef CONFIG_KLIPS_ENC_3DES
28783 + extern int des_check_key;
28784 +
28785 + /* turn off checking of keys */
28786 + des_check_key=0;
28787 +#endif /* CONFIG_KLIPS_ENC_3DES */
28788 +
28789 + KLIPS_PRINT(1, "klips_info:ipsec_init: "
28790 + "KLIPS startup, Openswan KLIPS IPsec stack version: %s\n",
28791 + ipsec_version_code());
28792 +
28793 + error = ipsec_xmit_state_cache_init ();
28794 + if (error)
28795 + goto error_xmit_state_cache;
28796 +
28797 + error = ipsec_rcv_state_cache_init ();
28798 + if (error)
28799 + goto error_rcv_state_cache;
28800 +
28801 + error |= ipsec_proc_init();
28802 + if (error)
28803 + goto error_proc_init;
28804 +
28805 +#ifdef SPINLOCK
28806 + ipsec_sadb.sadb_lock = SPIN_LOCK_UNLOCKED;
28807 +#else /* SPINLOCK */
28808 + ipsec_sadb.sadb_lock = 0;
28809 +#endif /* SPINLOCK */
28810 +
28811 +#ifndef SPINLOCK
28812 + tdb_lock.lock = 0;
28813 + eroute_lock.lock = 0;
28814 +#endif /* !SPINLOCK */
28815 +
28816 + error |= ipsec_sadb_init();
28817 + if (error)
28818 + goto error_sadb_init;
28819 +
28820 + error |= ipsec_radijinit();
28821 + if (error)
28822 + goto error_radijinit;
28823 +
28824 + error |= pfkey_init();
28825 + if (error)
28826 + goto error_pfkey_init;
28827 +
28828 + error |= register_netdevice_notifier(&ipsec_dev_notifier);
28829 + if (error)
28830 + goto error_netdev_notifier;
28831 +
28832 +#ifdef CONFIG_XFRM_ALTERNATE_STACK
28833 + error = xfrm_register_alternate_rcv (ipsec_rcv);
28834 + if (error)
28835 + goto error_xfrm_register;
28836 +
28837 +#else // CONFIG_XFRM_ALTERNATE_STACK
28838 +
28839 +#ifdef CONFIG_KLIPS_ESP
28840 + openswan_inet_add_protocol(&esp_protocol, IPPROTO_ESP);
28841 +#endif /* CONFIG_KLIPS_ESP */
28842 +
28843 +#ifdef CONFIG_KLIPS_AH
28844 + openswan_inet_add_protocol(&ah_protocol, IPPROTO_AH);
28845 +#endif /* CONFIG_KLIPS_AH */
28846 +
28847 +/* we never actually link IPCOMP to the stack */
28848 +#ifdef IPCOMP_USED_ALONE
28849 +#ifdef CONFIG_KLIPS_IPCOMP
28850 + openswan_inet_add_protocol(&comp_protocol, IPPROTO_COMP);
28851 +#endif /* CONFIG_KLIPS_IPCOMP */
28852 +#endif
28853 +
28854 +#endif // CONFIG_XFRM_ALTERNATE_STACK
28855 +
28856 + error |= ipsec_tunnel_init_devices();
28857 + if (error)
28858 + goto error_tunnel_init_devices;
28859 +
28860 +#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
28861 + /* register our ESP-UDP handler */
28862 + if(udp4_register_esp_rcvencap(klips26_rcv_encap
28863 + , &klips_old_encap)!=0) {
28864 + printk(KERN_ERR "KLIPS: can not register klips_rcv_encap function\n");
28865 + }
28866 +#endif
28867 +
28868 +
28869 +#ifdef CONFIG_SYSCTL
28870 + error |= ipsec_sysctl_register();
28871 + if (error)
28872 + goto error_sysctl_register;
28873 +#endif
28874 +
28875 + ipsec_alg_init();
28876 +
28877 + get_random_bytes((void *)seed, sizeof(seed));
28878 + prng_init(&ipsec_prng, seed, sizeof(seed));
28879 +
28880 + return error;
28881 +
28882 + // undo ipsec_sysctl_register
28883 +error_sysctl_register:
28884 + ipsec_tunnel_cleanup_devices();
28885 +error_tunnel_init_devices:
28886 +#ifdef CONFIG_XFRM_ALTERNATE_STACK
28887 + xfrm_deregister_alternate_rcv(ipsec_rcv);
28888 +error_xfrm_register:
28889 +#endif // CONFIG_XFRM_ALTERNATE_STACK
28890 + unregister_netdevice_notifier(&ipsec_dev_notifier);
28891 +error_netdev_notifier:
28892 + pfkey_cleanup();
28893 +error_pfkey_init:
28894 + ipsec_radijcleanup();
28895 +error_radijinit:
28896 + ipsec_sadb_cleanup(0);
28897 + ipsec_sadb_free();
28898 +error_sadb_init:
28899 +error_proc_init:
28900 + // ipsec_proc_init() does not cleanup after itself, so we have to do it here
28901 + // TODO: ipsec_proc_init() should roll back what it chaned on failure
28902 + ipsec_proc_cleanup();
28903 + ipsec_rcv_state_cache_cleanup ();
28904 +error_rcv_state_cache:
28905 + ipsec_xmit_state_cache_cleanup ();
28906 +error_xmit_state_cache:
28907 + return error;
28908 +}
28909 +
28910 +
28911 +/* void */
28912 +int
28913 +ipsec_cleanup(void)
28914 +{
28915 + int error = 0;
28916 +
28917 +#ifdef CONFIG_SYSCTL
28918 + ipsec_sysctl_unregister();
28919 +#endif
28920 +#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
28921 + if(udp4_unregister_esp_rcvencap(klips_old_encap) < 0) {
28922 + printk(KERN_ERR "KLIPS: can not unregister klips_rcv_encap function\n");
28923 + }
28924 +#endif
28925 +
28926 + KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
28927 + "klips_debug:ipsec_cleanup: "
28928 + "calling ipsec_tunnel_cleanup_devices.\n");
28929 + error |= ipsec_tunnel_cleanup_devices();
28930 +
28931 + KLIPS_PRINT(debug_netlink, "called ipsec_tunnel_cleanup_devices");
28932 +
28933 +#ifdef CONFIG_XFRM_ALTERNATE_STACK
28934 +
28935 + xfrm_deregister_alternate_rcv(ipsec_rcv);
28936 +
28937 +#else // CONFIG_XFRM_ALTERNATE_STACK
28938 +
28939 +/* we never actually link IPCOMP to the stack */
28940 +#ifdef IPCOMP_USED_ALONE
28941 +#ifdef CONFIG_KLIPS_IPCOMP
28942 + if (openswan_inet_del_protocol(&comp_protocol, IPPROTO_COMP) < 0)
28943 + printk(KERN_INFO "klips_debug:ipsec_cleanup: "
28944 + "comp close: can't remove protocol\n");
28945 +#endif /* CONFIG_KLIPS_IPCOMP */
28946 +#endif /* IPCOMP_USED_ALONE */
28947 +
28948 +#ifdef CONFIG_KLIPS_AH
28949 + if (openswan_inet_del_protocol(&ah_protocol, IPPROTO_AH) < 0)
28950 + printk(KERN_INFO "klips_debug:ipsec_cleanup: "
28951 + "ah close: can't remove protocol\n");
28952 +#endif /* CONFIG_KLIPS_AH */
28953 +
28954 +#ifdef CONFIG_KLIPS_ESP
28955 + if (openswan_inet_del_protocol(&esp_protocol, IPPROTO_ESP) < 0)
28956 + printk(KERN_INFO "klips_debug:ipsec_cleanup: "
28957 + "esp close: can't remove protocol\n");
28958 +#endif /* CONFIG_KLIPS_ESP */
28959 +
28960 +#endif // CONFIG_XFRM_ALTERNATE_STACK
28961 +
28962 + error |= unregister_netdevice_notifier(&ipsec_dev_notifier);
28963 +
28964 + KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
28965 + "klips_debug:ipsec_cleanup: "
28966 + "calling ipsec_sadb_cleanup.\n");
28967 + error |= ipsec_sadb_cleanup(0);
28968 + error |= ipsec_sadb_free();
28969 +
28970 + KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
28971 + "klips_debug:ipsec_cleanup: "
28972 + "calling ipsec_radijcleanup.\n");
28973 + error |= ipsec_radijcleanup();
28974 +
28975 + KLIPS_PRINT(debug_pfkey, /* debug_tunnel & DB_TN_INIT, */
28976 + "klips_debug:ipsec_cleanup: "
28977 + "calling pfkey_cleanup.\n");
28978 + error |= pfkey_cleanup();
28979 +
28980 + ipsec_rcv_state_cache_cleanup ();
28981 + ipsec_xmit_state_cache_cleanup ();
28982 +
28983 + ipsec_rcv_state_cache_cleanup ();
28984 + ipsec_xmit_state_cache_cleanup ();
28985 +
28986 + ipsec_proc_cleanup();
28987 +
28988 + prng_final(&ipsec_prng);
28989 +
28990 + return error;
28991 +}
28992 +
28993 +#ifdef MODULE
28994 +int
28995 +init_module(void)
28996 +{
28997 + int error = 0;
28998 +
28999 + error |= ipsec_klips_init();
29000 +
29001 + return error;
29002 +}
29003 +
29004 +#ifndef NET_26
29005 +void
29006 +cleanup_module(void)
29007 +{
29008 + KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29009 + "klips_debug:cleanup_module: "
29010 + "calling ipsec_cleanup.\n");
29011 +
29012 + ipsec_cleanup();
29013 +
29014 + KLIPS_PRINT(1, "klips_info:cleanup_module: "
29015 + "ipsec module unloaded.\n");
29016 +}
29017 +#endif
29018 +#endif /* MODULE */
29019 +
29020 +/*
29021 + * $Log: ipsec_init.c,v $
29022 + * Revision 1.106 2005/09/14 14:22:55 mcr
29023 + * remove module unload on 2.6. --- it just won't work, so
29024 + * don't let people try.
29025 + * Revision 1.104.2.2 2006/04/20 16:33:06 mcr
29026 + * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
29027 + * Fix in-kernel module compilation. Sub-makefiles do not work.
29028 + *
29029 + * Revision 1.104.2.1 2005/08/12 01:18:20 ken
29030 + * Warn people who don't have NAT-T patch applied, but try and compile NAT-T code
29031 + *
29032 + * Revision 1.105 2005/08/12 00:56:33 mcr
29033 + * add warning for people who didn't apply nat-t patch.
29034 + *
29035 + * Revision 1.104 2005/07/08 15:51:41 mcr
29036 + * removed duplicate NAT-T code.
29037 + * if CONFIG_IPSEC_NAT_TRAVERSAL isn't defined, then there is no issue.
29038 + *
29039 + * Revision 1.103 2005/07/08 03:02:05 paul
29040 + * Fixed garbled define that accidentally got commited to the real tree.
29041 + *
29042 + * Revision 1.102 2005/07/08 02:56:37 paul
29043 + * gcc4 fixes that were not commited because vault was down
29044 + *
29045 + * Revision 1.101 2005/04/29 05:10:22 mcr
29046 + * removed from extraenous includes to make unit testing easier.
29047 + *
29048 + * Revision 1.100 2005/04/10 22:56:09 mcr
29049 + * change to udp.c registration API.
29050 + *
29051 + * Revision 1.99 2005/04/08 18:26:13 mcr
29052 + * register with udp.c, the klips26 encap receive function
29053 + *
29054 + * Revision 1.98 2004/09/13 02:23:18 mcr
29055 + * #define inet_protocol if necessary.
29056 + *
29057 + * Revision 1.97 2004/09/06 18:35:49 mcr
29058 + * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
29059 + * so adjust for that.
29060 + *
29061 + * Revision 1.96 2004/08/17 03:27:23 mcr
29062 + * klips 2.6 edits.
29063 + *
29064 + * Revision 1.95 2004/08/03 18:19:08 mcr
29065 + * in 2.6, use "net_device" instead of #define device->net_device.
29066 + * this probably breaks 2.0 compiles.
29067 + *
29068 + * Revision 1.94 2004/07/10 19:11:18 mcr
29069 + * CONFIG_IPSEC -> CONFIG_KLIPS.
29070 + *
29071 + * Revision 1.93 2004/04/06 02:49:26 mcr
29072 + * pullup of algo code from alg-branch.
29073 + *
29074 + * Revision 1.92 2004/03/30 15:30:39 ken
29075 + * Proper Capitalization
29076 + *
29077 + * Revision 1.91 2004/03/22 01:51:51 ken
29078 + * We are open
29079 + *
29080 + * Revision 1.90.4.2 2004/04/05 04:30:46 mcr
29081 + * patches for alg-branch to compile/work with 2.x openswan
29082 + *
29083 + * Revision 1.90.4.1 2003/12/22 15:25:52 jjo
29084 + * Merged algo-0.8.1-rc11-test1 into alg-branch
29085 + *
29086 + * Revision 1.90 2003/10/31 02:27:55 mcr
29087 + * pulled up port-selector patches and sa_id elimination.
29088 + *
29089 + * Revision 1.89.4.1 2003/10/29 01:30:41 mcr
29090 + * elimited "struct sa_id".
29091 + *
29092 + * Revision 1.89 2003/07/31 22:47:16 mcr
29093 + * preliminary (untested by FS-team) 2.5 patches.
29094 + *
29095 + * Revision 1.88 2003/06/22 20:05:36 mcr
29096 + * clarified why IPCOMP was not being registered, and put a new
29097 + * #ifdef in rather than #if 0.
29098 + *
29099 + * Revision 1.87 2002/09/20 15:40:51 rgb
29100 + * Added a lock to the global ipsec_sadb struct for future use.
29101 + * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
29102 + * of freeing newly created structures when clearing the reftable upon startup
29103 + * to start from a known state.
29104 + *
29105 + * Revision 1.86 2002/08/15 18:39:15 rgb
29106 + * Move ipsec_prng outside debug code.
29107 + *
29108 + * Revision 1.85 2002/05/14 02:35:29 rgb
29109 + * Change reference to tdb to ipsa.
29110 + *
29111 + * Revision 1.84 2002/04/24 07:55:32 mcr
29112 + * #include patches and Makefiles for post-reorg compilation.
29113 + *
29114 + * Revision 1.83 2002/04/24 07:36:28 mcr
29115 + * Moved from ./klips/net/ipsec/ipsec_init.c,v
29116 + *
29117 + * Revision 1.82 2002/04/20 00:12:25 rgb
29118 + * Added esp IV CBC attack fix, disabled.
29119 + *
29120 + * Revision 1.81 2002/04/09 16:13:32 mcr
29121 + * switch license to straight GPL.
29122 + *
29123 + * Revision 1.80 2002/03/24 07:34:08 rgb
29124 + * Sanity check for at least one of AH or ESP configured.
29125 + *
29126 + * Revision 1.79 2002/02/05 22:55:15 mcr
29127 + * added MODULE_LICENSE declaration.
29128 + * This macro does not appear in all kernel versions (see comment).
29129 + *
29130 + * Revision 1.78 2002/01/29 17:17:55 mcr
29131 + * moved include of ipsec_param.h to after include of linux/kernel.h
29132 + * otherwise, it seems that some option that is set in ipsec_param.h
29133 + * screws up something subtle in the include path to kernel.h, and
29134 + * it complains on the snprintf() prototype.
29135 + *
29136 + * Revision 1.77 2002/01/29 04:00:51 mcr
29137 + * more excise of kversions.h header.
29138 + *
29139 + * Revision 1.76 2002/01/29 02:13:17 mcr
29140 + * introduction of ipsec_kversion.h means that include of
29141 + * ipsec_param.h must preceed any decisions about what files to
29142 + * include to deal with differences in kernel source.
29143 + *
29144 + * Revision 1.75 2001/11/26 09:23:48 rgb
29145 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
29146 + *
29147 + * Revision 1.74 2001/11/22 05:44:11 henry
29148 + * new version stuff
29149 + *
29150 + * Revision 1.71.2.2 2001/10/22 20:51:00 mcr
29151 + * explicitely set des_check_key.
29152 + *
29153 + * Revision 1.71.2.1 2001/09/25 02:19:39 mcr
29154 + * /proc manipulation code moved to new ipsec_proc.c
29155 + *
29156 + * Revision 1.73 2001/11/06 19:47:17 rgb
29157 + * Changed lifetime_packets to uint32 from uint64.
29158 + *
29159 + * Revision 1.72 2001/10/18 04:45:19 rgb
29160 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
29161 + * lib/freeswan.h version macros moved to lib/kversions.h.
29162 + * Other compiler directive cleanups.
29163 + *
29164 + * Revision 1.71 2001/09/20 15:32:45 rgb
29165 + * Minor pfkey lifetime fixes.
29166 + *
29167 + * Revision 1.70 2001/07/06 19:51:21 rgb
29168 + * Added inbound policy checking code for IPIP SAs.
29169 + *
29170 + * Revision 1.69 2001/06/14 19:33:26 rgb
29171 + * Silence startup message for console, but allow it to be logged.
29172 + * Update copyright date.
29173 + *
29174 + * Revision 1.68 2001/05/29 05:14:36 rgb
29175 + * Added PMTU to /proc/net/ipsec_tncfg output. See 'man 5 ipsec_tncfg'.
29176 + *
29177 + * Revision 1.67 2001/05/04 16:34:52 rgb
29178 + * Rremove erroneous checking of return codes for proc_net_* in 2.4.
29179 + *
29180 + * Revision 1.66 2001/05/03 19:40:34 rgb
29181 + * Check error return codes in startup and shutdown.
29182 + *
29183 + * Revision 1.65 2001/02/28 05:03:27 rgb
29184 + * Clean up and rationalise startup messages.
29185 + *
29186 + * Revision 1.64 2001/02/27 22:24:53 rgb
29187 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
29188 + * Check for satoa() return codes.
29189 + *
29190 + * Revision 1.63 2000/11/29 20:14:06 rgb
29191 + * Add src= to the output of /proc/net/ipsec_spi and delete dst from IPIP.
29192 + *
29193 + * Revision 1.62 2000/11/06 04:31:24 rgb
29194 + * Ditched spin_lock_irqsave in favour of spin_lock_bh.
29195 + * Fixed longlong for pre-2.4 kernels (Svenning).
29196 + * Add Svenning's adaptive content compression.
29197 + * Disabled registration of ipcomp handler.
29198 + *
29199 + * Revision 1.61 2000/10/11 13:37:54 rgb
29200 + * #ifdef out debug print that causes proc/net/ipsec_version to oops.
29201 + *
29202 + * Revision 1.60 2000/09/20 03:59:01 rgb
29203 + * Change static info functions to DEBUG_NO_STATIC to reveal function names
29204 + * in oopsen.
29205 + *
29206 + * Revision 1.59 2000/09/16 01:06:26 rgb
29207 + * Added cast of var to silence compiler warning about long fed to int
29208 + * format.
29209 + *
29210 + * Revision 1.58 2000/09/15 11:37:01 rgb
29211 + * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
29212 + * IPCOMP zlib deflate code.
29213 + *
29214 + * Revision 1.57 2000/09/12 03:21:50 rgb
29215 + * Moved radij_c_version printing to ipsec_version_get_info().
29216 + * Reformatted ipsec_version_get_info().
29217 + * Added sysctl_{,un}register() calls.
29218 + *
29219 + * Revision 1.56 2000/09/08 19:16:50 rgb
29220 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
29221 + * Removed all references to CONFIG_IPSEC_PFKEYv2.
29222 + *
29223 + * Revision 1.55 2000/08/30 05:19:03 rgb
29224 + * Cleaned up no longer used spi_next, netlink register/unregister, other
29225 + * minor cleanup.
29226 + * Removed cruft replaced by TDB_XFORM_NAME.
29227 + * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
29228 + * Moved debug version strings to printk when /proc/net/ipsec_version is
29229 + * called.
29230 + *
29231 + * Revision 1.54 2000/08/20 18:31:05 rgb
29232 + * Changed cosmetic alignment in spi_info.
29233 + * Changed addtime and usetime to use actual value which is relative
29234 + * anyways, as intended. (Momchil)
29235 + *
29236 + * Revision 1.53 2000/08/18 17:37:03 rgb
29237 + * Added an (int) cast to shut up the compiler...
29238 + *
29239 + * Revision 1.52 2000/08/01 14:51:50 rgb
29240 + * Removed _all_ remaining traces of DES.
29241 + *
29242 + * Revision 1.51 2000/07/25 20:41:22 rgb
29243 + * Removed duplicate parameter in spi_getinfo.
29244 + *
29245 + * Revision 1.50 2000/07/17 03:21:45 rgb
29246 + * Removed /proc/net/ipsec_spinew.
29247 + *
29248 + * Revision 1.49 2000/06/28 05:46:51 rgb
29249 + * Renamed ivlen to iv_bits for consistency.
29250 + * Changed output of add and use times to be relative to now.
29251 + *
29252 + * Revision 1.48 2000/05/11 18:26:10 rgb
29253 + * Commented out calls to netlink_attach/detach to avoid activating netlink
29254 + * in the kenrel config.
29255 + *
29256 + * Revision 1.47 2000/05/10 22:35:26 rgb
29257 + * Comment out most of the startup version information.
29258 + *
29259 + * Revision 1.46 2000/03/22 16:15:36 rgb
29260 + * Fixed renaming of dev_get (MB).
29261 + *
29262 + * Revision 1.45 2000/03/16 06:40:48 rgb
29263 + * Hardcode PF_KEYv2 support.
29264 + *
29265 + * Revision 1.44 2000/01/22 23:19:20 rgb
29266 + * Simplified code to use existing macro TDB_XFORM_NAME().
29267 + *
29268 + * Revision 1.43 2000/01/21 06:14:04 rgb
29269 + * Print individual stats only if non-zero.
29270 + * Removed 'bits' from each keylength for brevity.
29271 + * Shortened lifetimes legend for brevity.
29272 + * Changed wording from 'last_used' to the clearer 'idle'.
29273 + *
29274 + * Revision 1.42 1999/12/31 14:57:19 rgb
29275 + * MB fix for new dummy-less proc_get_info in 2.3.35.
29276 + *
29277 + *
29278 + * Local variables:
29279 + * c-file-style: "linux"
29280 + * End:
29281 + *
29282 + */
29283 --- /dev/null Tue Mar 11 13:02:56 2003
29284 +++ linux/net/ipsec/ipsec_ipcomp.c Mon Feb 9 13:51:03 2004
29285 @@ -0,0 +1,258 @@
29286 +/*
29287 + * processing code for IPCOMP
29288 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
29289 + *
29290 + * This program is free software; you can redistribute it and/or modify it
29291 + * under the terms of the GNU General Public License as published by the
29292 + * Free Software Foundation; either version 2 of the License, or (at your
29293 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29294 + *
29295 + * This program is distributed in the hope that it will be useful, but
29296 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29297 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29298 + * for more details.
29299 + */
29300 +
29301 +char ipsec_ipcomp_c_version[] = "RCSID $Id: ipsec_ipcomp.c,v 1.5.2.1 2006/07/07 16:39:58 paul Exp $";
29302 +#ifndef AUTOCONF_INCLUDED
29303 +#include <linux/config.h>
29304 +#endif
29305 +#include <linux/version.h>
29306 +
29307 +#define __NO_VERSION__
29308 +#include <linux/module.h>
29309 +#include <linux/kernel.h> /* printk() */
29310 +
29311 +#include "openswan/ipsec_param.h"
29312 +
29313 +#ifdef MALLOC_SLAB
29314 +# include <linux/slab.h> /* kmalloc() */
29315 +#else /* MALLOC_SLAB */
29316 +# include <linux/malloc.h> /* kmalloc() */
29317 +#endif /* MALLOC_SLAB */
29318 +#include <linux/errno.h> /* error codes */
29319 +#include <linux/types.h> /* size_t */
29320 +#include <linux/interrupt.h> /* mark_bh */
29321 +
29322 +#include <linux/netdevice.h> /* struct device, and other headers */
29323 +#include <linux/etherdevice.h> /* eth_type_trans */
29324 +#include <linux/ip.h> /* struct iphdr */
29325 +#include <linux/skbuff.h>
29326 +#include <openswan.h>
29327 +#ifdef SPINLOCK
29328 +# ifdef SPINLOCK_23
29329 +# include <linux/spinlock.h> /* *lock* */
29330 +# else /* SPINLOCK_23 */
29331 +# include <asm/spinlock.h> /* *lock* */
29332 +# endif /* SPINLOCK_23 */
29333 +#endif /* SPINLOCK */
29334 +
29335 +#include <net/ip.h>
29336 +
29337 +#include "openswan/radij.h"
29338 +#include "openswan/ipsec_encap.h"
29339 +#include "openswan/ipsec_sa.h"
29340 +
29341 +#include "openswan/ipsec_radij.h"
29342 +#include "openswan/ipsec_xform.h"
29343 +#include "openswan/ipsec_tunnel.h"
29344 +#include "openswan/ipsec_rcv.h"
29345 +#include "openswan/ipsec_xmit.h"
29346 +
29347 +#include "openswan/ipsec_auth.h"
29348 +
29349 +#ifdef CONFIG_KLIPS_IPCOMP
29350 +#include "openswan/ipsec_ipcomp.h"
29351 +#endif /* CONFIG_KLIPS_IPCOMP */
29352 +
29353 +#include "openswan/ipsec_proto.h"
29354 +
29355 +#ifdef CONFIG_KLIPS_DEBUG
29356 +int debug_ipcomp = 0;
29357 +#endif /* CONFIG_KLIPS_DEBUG */
29358 +
29359 +
29360 +#ifdef CONFIG_KLIPS_IPCOMP
29361 +enum ipsec_rcv_value
29362 +ipsec_rcv_ipcomp_checks(struct ipsec_rcv_state *irs,
29363 + struct sk_buff *skb)
29364 +{
29365 + int ipcompminlen;
29366 +
29367 + ipcompminlen = sizeof(struct iphdr);
29368 +
29369 + if(skb->len < (ipcompminlen + sizeof(struct ipcomphdr))) {
29370 + KLIPS_PRINT(debug_rcv & DB_RX_INAU,
29371 + "klips_debug:ipsec_rcv: "
29372 + "runt comp packet of skb->len=%d received from %s, dropped.\n",
29373 + skb->len,
29374 + irs->ipsaddr_txt);
29375 + if(irs->stats) {
29376 + irs->stats->rx_errors++;
29377 + }
29378 + return IPSEC_RCV_BADLEN;
29379 + }
29380 +
29381 + irs->protostuff.ipcompstuff.compp = (struct ipcomphdr *)skb->h.raw;
29382 + irs->said.spi = htonl((__u32)ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi));
29383 + return IPSEC_RCV_OK;
29384 +}
29385 +
29386 +enum ipsec_rcv_value
29387 +ipsec_rcv_ipcomp_decomp(struct ipsec_rcv_state *irs)
29388 +{
29389 + unsigned int flags = 0;
29390 + struct ipsec_sa *ipsp = irs->ipsp;
29391 + struct sk_buff *skb;
29392 +
29393 + skb=irs->skb;
29394 +
29395 + ipsec_xmit_dmp("ipcomp", skb->h.raw, skb->len);
29396 +
29397 + if(ipsp == NULL) {
29398 + return IPSEC_RCV_SAIDNOTFOUND;
29399 + }
29400 +
29401 + if(sysctl_ipsec_inbound_policy_check &&
29402 + ((((ntohl(ipsp->ips_said.spi) & 0x0000ffff) != ntohl(irs->said.spi)) &&
29403 + (ipsp->ips_encalg != ntohl(irs->said.spi)) /* this is a workaround for peer non-compliance with rfc2393 */
29404 + ))) {
29405 + char sa2[SATOT_BUF];
29406 + size_t sa_len2 = 0;
29407 +
29408 + sa_len2 = satot(&ipsp->ips_said, 0, sa2, sizeof(sa2));
29409 +
29410 + KLIPS_PRINT(debug_rcv,
29411 + "klips_debug:ipsec_rcv: "
29412 + "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",
29413 + irs->sa_len ? irs->sa : " (error)",
29414 + ipsp != NULL ? (sa_len2 ? sa2 : " (error)") : "NULL",
29415 + ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi),
29416 + (__u32)ntohl(irs->said.spi),
29417 + ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
29418 + ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0);
29419 + if(irs->stats) {
29420 + irs->stats->rx_dropped++;
29421 + }
29422 + return IPSEC_RCV_SAIDNOTFOUND;
29423 + }
29424 +
29425 + ipsp->ips_comp_ratio_cbytes += ntohs(irs->ipp->tot_len);
29426 + irs->next_header = irs->protostuff.ipcompstuff.compp->ipcomp_nh;
29427 +
29428 + skb = skb_decompress(skb, ipsp, &flags);
29429 + if (!skb || flags) {
29430 + spin_unlock(&tdb_lock);
29431 + KLIPS_PRINT(debug_rcv,
29432 + "klips_debug:ipsec_rcv: "
29433 + "skb_decompress() returned error flags=%x, dropped.\n",
29434 + flags);
29435 + if (irs->stats) {
29436 + if (flags)
29437 + irs->stats->rx_errors++;
29438 + else
29439 + irs->stats->rx_dropped++;
29440 + }
29441 + return IPSEC_RCV_IPCOMPFAILED;
29442 + }
29443 +
29444 + /* make sure we update the pointer */
29445 + irs->skb = skb;
29446 +
29447 +#ifdef NET_21
29448 + irs->ipp = skb->nh.iph;
29449 +#else /* NET_21 */
29450 + irs->ipp = skb->ip_hdr;
29451 +#endif /* NET_21 */
29452 +
29453 + ipsp->ips_comp_ratio_dbytes += ntohs(irs->ipp->tot_len);
29454 +
29455 + KLIPS_PRINT(debug_rcv,
29456 + "klips_debug:ipsec_rcv: "
29457 + "packet decompressed SA(IPCA):%s cpi->spi=%08x spi=%08x, spi->cpi=%04x, nh=%d.\n",
29458 + irs->sa_len ? irs->sa : " (error)",
29459 + (__u32)ntohl(irs->said.spi),
29460 + ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
29461 + ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0,
29462 + irs->next_header);
29463 + KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, irs->ipp);
29464 +
29465 + return IPSEC_RCV_OK;
29466 +}
29467 +
29468 +enum ipsec_xmit_value
29469 +ipsec_xmit_ipcomp_setup(struct ipsec_xmit_state *ixs)
29470 +{
29471 + unsigned int flags = 0;
29472 +#ifdef CONFIG_KLIPS_DEBUG
29473 + unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
29474 +#endif /* CONFIG_KLIPS_DEBUG */
29475 +
29476 + ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
29477 +
29478 + ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
29479 +
29480 +#ifdef NET_21
29481 + ixs->iph = ixs->skb->nh.iph;
29482 +#else /* NET_21 */
29483 + ixs->iph = ixs->skb->ip_hdr;
29484 +#endif /* NET_21 */
29485 +
29486 + ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
29487 +
29488 +#ifdef CONFIG_KLIPS_DEBUG
29489 + if (debug_tunnel & DB_TN_CROUT)
29490 + {
29491 + if (old_tot_len > ntohs(ixs->iph->tot_len))
29492 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
29493 + "klips_debug:ipsec_xmit_encap_once: "
29494 + "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
29495 + old_tot_len, ntohs(ixs->iph->tot_len),
29496 + ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
29497 + ntohl(ixs->ipsp->ips_said.spi),
29498 + (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
29499 + else
29500 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
29501 + "klips_debug:ipsec_xmit_encap_once: "
29502 + "packet did not compress (flags = %d).\n",
29503 + flags);
29504 + }
29505 +#endif /* CONFIG_KLIPS_DEBUG */
29506 +
29507 + return IPSEC_XMIT_OK;
29508 +}
29509 +
29510 +struct xform_functions ipcomp_xform_funcs[]={
29511 + {rcv_checks: ipsec_rcv_ipcomp_checks,
29512 + rcv_decrypt: ipsec_rcv_ipcomp_decomp,
29513 + xmit_setup: ipsec_xmit_ipcomp_setup,
29514 + xmit_headroom: 0,
29515 + xmit_needtailroom: 0,
29516 + },
29517 +};
29518 +
29519 +#if 0
29520 +/* We probably don't want to install a pure IPCOMP protocol handler, but
29521 + only want to handle IPCOMP if it is encapsulated inside an ESP payload
29522 + (which is already handled) */
29523 +#ifndef CONFIG_XFRM_ALTERNATE_STACK
29524 +#ifdef CONFIG_KLIPS_IPCOMP
29525 +struct inet_protocol comp_protocol =
29526 +{
29527 + ipsec_rcv, /* COMP handler */
29528 + NULL, /* COMP error control */
29529 +#ifdef NETDEV_25
29530 + 1, /* no policy */
29531 +#else
29532 + 0, /* next */
29533 + IPPROTO_COMP, /* protocol ID */
29534 + 0, /* copy */
29535 + NULL, /* data */
29536 + "COMP" /* name */
29537 +#endif
29538 +};
29539 +#endif /* CONFIG_KLIPS_IPCOMP */
29540 +#endif /* CONFIG_XFRM_ALTERNATE_STACK */
29541 +#endif
29542 +
29543 +#endif /* CONFIG_KLIPS_IPCOMP */
29544 --- /dev/null Tue Mar 11 13:02:56 2003
29545 +++ linux/net/ipsec/ipsec_ipip.c Mon Feb 9 13:51:03 2004
29546 @@ -0,0 +1,122 @@
29547 +/*
29548 + * processing code for IPIP
29549 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
29550 + *
29551 + * This program is free software; you can redistribute it and/or modify it
29552 + * under the terms of the GNU General Public License as published by the
29553 + * Free Software Foundation; either version 2 of the License, or (at your
29554 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29555 + *
29556 + * This program is distributed in the hope that it will be useful, but
29557 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29558 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29559 + * for more details.
29560 + */
29561 +
29562 +char ipsec_ipip_c_version[] = "RCSID $Id: ipsec_ipip.c,v 1.5 2005/11/11 06:36:41 paul Exp $";
29563 +#ifndef AUTOCONF_INCLUDED
29564 +#include <linux/config.h>
29565 +#endif
29566 +#include <linux/version.h>
29567 +
29568 +#define __NO_VERSION__
29569 +#include <linux/module.h>
29570 +#include <linux/kernel.h> /* printk() */
29571 +
29572 +#include "openswan/ipsec_param.h"
29573 +
29574 +#ifdef MALLOC_SLAB
29575 +# include <linux/slab.h> /* kmalloc() */
29576 +#else /* MALLOC_SLAB */
29577 +# include <linux/malloc.h> /* kmalloc() */
29578 +#endif /* MALLOC_SLAB */
29579 +#include <linux/errno.h> /* error codes */
29580 +#include <linux/types.h> /* size_t */
29581 +#include <linux/interrupt.h> /* mark_bh */
29582 +
29583 +#include <linux/netdevice.h> /* struct device, and other headers */
29584 +#include <linux/etherdevice.h> /* eth_type_trans */
29585 +#include <linux/ip.h> /* struct iphdr */
29586 +#include <linux/skbuff.h>
29587 +#include <openswan.h>
29588 +#ifdef SPINLOCK
29589 +# ifdef SPINLOCK_23
29590 +# include <linux/spinlock.h> /* *lock* */
29591 +# else /* SPINLOCK_23 */
29592 +# include <asm/spinlock.h> /* *lock* */
29593 +# endif /* SPINLOCK_23 */
29594 +#endif /* SPINLOCK */
29595 +
29596 +#include <net/ip.h>
29597 +
29598 +#include "openswan/radij.h"
29599 +#include "openswan/ipsec_encap.h"
29600 +#include "openswan/ipsec_sa.h"
29601 +
29602 +#include "openswan/ipsec_radij.h"
29603 +#include "openswan/ipsec_xform.h"
29604 +#include "openswan/ipsec_tunnel.h"
29605 +#include "openswan/ipsec_rcv.h"
29606 +#include "openswan/ipsec_xmit.h"
29607 +
29608 +#include "openswan/ipsec_auth.h"
29609 +#include "openswan/ipsec_ipip.h"
29610 +#include "openswan/ipsec_param.h"
29611 +
29612 +#include "openswan/ipsec_proto.h"
29613 +
29614 +enum ipsec_xmit_value
29615 +ipsec_xmit_ipip_setup(struct ipsec_xmit_state *ixs)
29616 +{
29617 + ixs->iph->version = 4;
29618 +
29619 + switch(sysctl_ipsec_tos) {
29620 + case 0:
29621 +#ifdef NET_21
29622 + ixs->iph->tos = ixs->skb->nh.iph->tos;
29623 +#else /* NET_21 */
29624 + ixs->iph->tos = ixs->skb->ip_hdr->tos;
29625 +#endif /* NET_21 */
29626 + break;
29627 + case 1:
29628 + ixs->iph->tos = 0;
29629 + break;
29630 + default:
29631 + break;
29632 + }
29633 + ixs->iph->ttl = SYSCTL_IPSEC_DEFAULT_TTL;
29634 + ixs->iph->frag_off = 0;
29635 + ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
29636 + ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
29637 + ixs->iph->protocol = IPPROTO_IPIP;
29638 + ixs->iph->ihl = sizeof(struct iphdr) >> 2;
29639 +
29640 + KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
29641 +
29642 + ixs->newdst = (__u32)ixs->iph->daddr;
29643 + ixs->newsrc = (__u32)ixs->iph->saddr;
29644 +
29645 +#ifdef NET_21
29646 + ixs->skb->h.ipiph = ixs->skb->nh.iph;
29647 +#endif /* NET_21 */
29648 + return IPSEC_XMIT_OK;
29649 +}
29650 +
29651 +struct xform_functions ipip_xform_funcs[]={
29652 + { rcv_checks: NULL,
29653 + rcv_setup_auth: NULL,
29654 + rcv_calc_auth: NULL,
29655 + rcv_decrypt: NULL,
29656 +
29657 + xmit_setup: ipsec_xmit_ipip_setup,
29658 + xmit_headroom: sizeof(struct iphdr),
29659 + xmit_needtailroom: 0,
29660 + },
29661 +};
29662 +
29663 +
29664 +
29665 +
29666 +
29667 +
29668 +
29669 --- /dev/null Tue Mar 11 13:02:56 2003
29670 +++ linux/net/ipsec/ipsec_kern24.c Mon Feb 9 13:51:03 2004
29671 @@ -0,0 +1,74 @@
29672 +/*
29673 + * Copyright 2005 (C) Michael Richardson <mcr@xelerance.com>
29674 + *
29675 + * This is a file of functions which are present in 2.6 kernels,
29676 + * but are not available by default in the 2.4 series.
29677 + *
29678 + * As such this code is usually from the Linux kernel, and is covered by
29679 + * GPL.
29680 + *
29681 + * This program is free software; you can redistribute it and/or modify it
29682 + * under the terms of the GNU General Public License as published by the
29683 + * Free Software Foundation; either version 2 of the License, or (at your
29684 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29685 + *
29686 + * This program is distributed in the hope that it will be useful, but
29687 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29688 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29689 + * for more details.
29690 + *
29691 + * $Id: ipsec_kern24.c,v 1.2 2005/05/20 03:19:18 mcr Exp $
29692 + *
29693 + */
29694 +
29695 +#include <linux/kernel.h>
29696 +#include <linux/mm.h>
29697 +#include <linux/spinlock.h>
29698 +
29699 +/*
29700 + * printk rate limiting, lifted from the networking subsystem.
29701 + *
29702 + * This enforces a rate limit: not more than one kernel message
29703 + * every printk_ratelimit_jiffies to make a denial-of-service
29704 + * attack impossible.
29705 + */
29706 +static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
29707 +
29708 +int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
29709 +{
29710 + static unsigned long toks = 10*5*HZ;
29711 + static unsigned long last_msg;
29712 + static int missed;
29713 + unsigned long flags;
29714 + unsigned long now = jiffies;
29715 +
29716 + spin_lock_irqsave(&ratelimit_lock, flags);
29717 + toks += now - last_msg;
29718 + last_msg = now;
29719 + if (toks > (ratelimit_burst * ratelimit_jiffies))
29720 + toks = ratelimit_burst * ratelimit_jiffies;
29721 + if (toks >= ratelimit_jiffies) {
29722 + int lost = missed;
29723 + missed = 0;
29724 + toks -= ratelimit_jiffies;
29725 + spin_unlock_irqrestore(&ratelimit_lock, flags);
29726 + if (lost)
29727 + printk(KERN_WARNING "printk: %d messages suppressed.\n", lost);
29728 + return 1;
29729 + }
29730 + missed++;
29731 + spin_unlock_irqrestore(&ratelimit_lock, flags);
29732 + return 0;
29733 +}
29734 +
29735 +/* minimum time in jiffies between messages */
29736 +int printk_ratelimit_jiffies = 5*HZ;
29737 +
29738 +/* number of messages we send before ratelimiting */
29739 +int printk_ratelimit_burst = 10;
29740 +
29741 +int printk_ratelimit(void)
29742 +{
29743 + return __printk_ratelimit(printk_ratelimit_jiffies,
29744 + printk_ratelimit_burst);
29745 +}
29746 --- /dev/null Tue Mar 11 13:02:56 2003
29747 +++ linux/net/ipsec/ipsec_life.c Mon Feb 9 13:51:03 2004
29748 @@ -0,0 +1,268 @@
29749 +/*
29750 + * @(#) lifetime structure utilities
29751 + *
29752 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
29753 + * and Michael Richardson <mcr@freeswan.org>
29754 + *
29755 + * This program is free software; you can redistribute it and/or modify it
29756 + * under the terms of the GNU General Public License as published by the
29757 + * Free Software Foundation; either version 2 of the License, or (at your
29758 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29759 + *
29760 + * This program is distributed in the hope that it will be useful, but
29761 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29762 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29763 + * for more details.
29764 + *
29765 + * RCSID $Id: ipsec_life.c,v 1.13 2004/07/10 19:11:18 mcr Exp $
29766 + *
29767 + */
29768 +
29769 +/*
29770 + * This provides series of utility functions for dealing with lifetime
29771 + * structures.
29772 + *
29773 + * ipsec_check_lifetime - returns -1 hard lifetime exceeded
29774 + * 0 soft lifetime exceeded
29775 + * 1 everything is okay
29776 + * based upon whether or not the count exceeds hard/soft
29777 + *
29778 + */
29779 +
29780 +#define __NO_VERSION__
29781 +#include <linux/module.h>
29782 +#ifndef AUTOCONF_INCLUDED
29783 +#include <linux/config.h>
29784 +#endif /* for CONFIG_IP_FORWARD */
29785 +#include <linux/version.h>
29786 +#include <linux/kernel.h> /* printk() */
29787 +
29788 +#include "openswan/ipsec_param.h"
29789 +
29790 +#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
29791 +#include <linux/etherdevice.h> /* eth_type_trans */
29792 +#include <linux/skbuff.h>
29793 +#include <openswan.h>
29794 +
29795 +#include "openswan/radij.h"
29796 +#include "openswan/ipsec_life.h"
29797 +#include "openswan/ipsec_xform.h"
29798 +#include "openswan/ipsec_eroute.h"
29799 +#include "openswan/ipsec_encap.h"
29800 +#include "openswan/ipsec_radij.h"
29801 +
29802 +#include "openswan/ipsec_sa.h"
29803 +#include "openswan/ipsec_tunnel.h"
29804 +#include "openswan/ipsec_ipe4.h"
29805 +#include "openswan/ipsec_ah.h"
29806 +#include "openswan/ipsec_esp.h"
29807 +
29808 +#ifdef CONFIG_KLIPS_IPCOMP
29809 +#include "openswan/ipcomp.h"
29810 +#endif /* CONFIG_KLIPS_IPCOMP */
29811 +
29812 +#include <openswan/pfkeyv2.h>
29813 +#include <openswan/pfkey.h>
29814 +
29815 +#include "openswan/ipsec_proto.h"
29816 +
29817 +
29818 +enum ipsec_life_alive
29819 +ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
29820 + const char *lifename,
29821 + const char *saname,
29822 + enum ipsec_life_type ilt,
29823 + enum ipsec_direction idir,
29824 + struct ipsec_sa *ips)
29825 +{
29826 + __u64 count;
29827 + const char *dir;
29828 +
29829 + if(saname == NULL) {
29830 + saname = "unknown-SA";
29831 + }
29832 +
29833 + if(idir == ipsec_incoming) {
29834 + dir = "incoming";
29835 + } else {
29836 + dir = "outgoing";
29837 + }
29838 +
29839 +
29840 + if(ilt == ipsec_life_timebased) {
29841 + count = jiffies/HZ - il64->ipl_count;
29842 + } else {
29843 + count = il64->ipl_count;
29844 + }
29845 +
29846 + if(il64->ipl_hard &&
29847 + (count > il64->ipl_hard)) {
29848 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
29849 + "klips_debug:ipsec_lifetime_check: "
29850 + "hard %s lifetime of SA:<%s%s%s> %s has been reached, SA expired, "
29851 + "%s packet dropped.\n",
29852 + lifename,
29853 + IPS_XFORM_NAME(ips),
29854 + saname,
29855 + dir);
29856 +
29857 + pfkey_expire(ips, 1);
29858 + return ipsec_life_harddied;
29859 + }
29860 +
29861 + if(il64->ipl_soft &&
29862 + (count > il64->ipl_soft)) {
29863 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
29864 + "klips_debug:ipsec_lifetime_check: "
29865 + "soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, "
29866 + "soft expire message sent up, %s packet still processed.\n",
29867 + lifename,
29868 + IPS_XFORM_NAME(ips),
29869 + saname,
29870 + dir);
29871 +
29872 + if(ips->ips_state != K_SADB_SASTATE_DYING) {
29873 + pfkey_expire(ips, 0);
29874 + }
29875 + ips->ips_state = K_SADB_SASTATE_DYING;
29876 +
29877 + return ipsec_life_softdied;
29878 + }
29879 + return ipsec_life_okay;
29880 +}
29881 +
29882 +
29883 +/*
29884 + * This function takes a buffer (with length), a lifetime name and type,
29885 + * and formats a string to represent the current values of the lifetime.
29886 + *
29887 + * It returns the number of bytes that the format took (or would take,
29888 + * if the buffer were large enough: snprintf semantics).
29889 + * This is used in /proc routines and in debug output.
29890 + */
29891 +int
29892 +ipsec_lifetime_format(char *buffer,
29893 + int buflen,
29894 + char *lifename,
29895 + enum ipsec_life_type timebaselife,
29896 + struct ipsec_lifetime64 *lifetime)
29897 +{
29898 + int len = 0;
29899 + __u64 count;
29900 +
29901 + if(timebaselife == ipsec_life_timebased) {
29902 + count = jiffies/HZ - lifetime->ipl_count;
29903 + } else {
29904 + count = lifetime->ipl_count;
29905 + }
29906 +
29907 + if(lifetime->ipl_count > 1 ||
29908 + lifetime->ipl_soft ||
29909 + lifetime->ipl_hard) {
29910 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
29911 + len = ipsec_snprintf(buffer, buflen,
29912 + "%s(%Lu,%Lu,%Lu)",
29913 + lifename,
29914 + count,
29915 + lifetime->ipl_soft,
29916 + lifetime->ipl_hard);
29917 +#else /* XXX high 32 bits are not displayed */
29918 + len = ipsec_snprintf(buffer, buflen,
29919 + "%s(%lu,%lu,%lu)",
29920 + lifename,
29921 + (unsigned long)count,
29922 + (unsigned long)lifetime->ipl_soft,
29923 + (unsigned long)lifetime->ipl_hard);
29924 +#endif
29925 + }
29926 +
29927 + return len;
29928 +}
29929 +
29930 +void
29931 +ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
29932 + __u64 newvalue)
29933 +{
29934 + if(newvalue &&
29935 + (!lifetime->ipl_hard ||
29936 + (newvalue < lifetime->ipl_hard))) {
29937 + lifetime->ipl_hard = newvalue;
29938 +
29939 + if(!lifetime->ipl_soft &&
29940 + (lifetime->ipl_hard < lifetime->ipl_soft)) {
29941 + lifetime->ipl_soft = lifetime->ipl_hard;
29942 + }
29943 + }
29944 +}
29945 +
29946 +void
29947 +ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
29948 + __u64 newvalue)
29949 +{
29950 + if(newvalue &&
29951 + (!lifetime->ipl_soft ||
29952 + (newvalue < lifetime->ipl_soft))) {
29953 + lifetime->ipl_soft = newvalue;
29954 +
29955 + if(lifetime->ipl_hard &&
29956 + (lifetime->ipl_hard < lifetime->ipl_soft)) {
29957 + lifetime->ipl_soft = lifetime->ipl_hard;
29958 + }
29959 + }
29960 +}
29961 +
29962 +
29963 +/*
29964 + * $Log: ipsec_life.c,v $
29965 + * Revision 1.13 2004/07/10 19:11:18 mcr
29966 + * CONFIG_IPSEC -> CONFIG_KLIPS.
29967 + *
29968 + * Revision 1.12 2004/04/23 20:44:35 ken
29969 + * Update comments
29970 + *
29971 + * Revision 1.11 2004/04/06 02:49:26 mcr
29972 + * pullup of algo code from alg-branch.
29973 + *
29974 + * Revision 1.10 2004/03/30 11:03:10 paul
29975 + * two more occurances of snprintf, found by Sam from a users oops msg.
29976 + *
29977 + * Revision 1.9 2003/10/31 02:27:55 mcr
29978 + * pulled up port-selector patches and sa_id elimination.
29979 + *
29980 + * Revision 1.8.4.1 2003/10/29 01:30:41 mcr
29981 + * elimited "struct sa_id".
29982 + *
29983 + * Revision 1.8 2003/02/06 02:00:10 rgb
29984 + * Fixed incorrect debugging text label
29985 + *
29986 + * Revision 1.7 2002/05/23 07:16:26 rgb
29987 + * Fixed absolute/relative reference to lifetime count printout.
29988 + *
29989 + * Revision 1.6 2002/04/24 07:55:32 mcr
29990 + * #include patches and Makefiles for post-reorg compilation.
29991 + *
29992 + * Revision 1.5 2002/04/24 07:36:28 mcr
29993 + * Moved from ./klips/net/ipsec/ipsec_life.c,v
29994 + *
29995 + * Revision 1.4 2002/01/29 17:17:55 mcr
29996 + * moved include of ipsec_param.h to after include of linux/kernel.h
29997 + * otherwise, it seems that some option that is set in ipsec_param.h
29998 + * screws up something subtle in the include path to kernel.h, and
29999 + * it complains on the snprintf() prototype.
30000 + *
30001 + * Revision 1.3 2002/01/29 02:13:17 mcr
30002 + * introduction of ipsec_kversion.h means that include of
30003 + * ipsec_param.h must preceed any decisions about what files to
30004 + * include to deal with differences in kernel source.
30005 + *
30006 + * Revision 1.2 2001/11/26 09:16:14 rgb
30007 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
30008 + *
30009 + * Revision 1.1.2.1 2001/09/25 02:25:57 mcr
30010 + * lifetime structure created and common functions created.
30011 + *
30012 + * Local variables:
30013 + * c-file-style: "linux"
30014 + * End:
30015 + *
30016 + */
30017 --- /dev/null Tue Mar 11 13:02:56 2003
30018 +++ linux/net/ipsec/ipsec_mast.c Mon Feb 9 13:51:03 2004
30019 @@ -0,0 +1,1094 @@
30020 +/*
30021 + * IPSEC MAST code.
30022 + * Copyright (C) 1996, 1997 John Ioannidis.
30023 + * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
30024 + *
30025 + * This program is free software; you can redistribute it and/or modify it
30026 + * under the terms of the GNU General Public License as published by the
30027 + * Free Software Foundation; either version 2 of the License, or (at your
30028 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30029 + *
30030 + * This program is distributed in the hope that it will be useful, but
30031 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30032 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30033 + * for more details.
30034 + */
30035 +
30036 +char ipsec_mast_c_version[] = "RCSID $Id: ipsec_mast.c,v 1.7 2005/04/29 05:10:22 mcr Exp $";
30037 +
30038 +#define __NO_VERSION__
30039 +#include <linux/module.h>
30040 +#ifndef AUTOCONF_INCLUDED
30041 +#include <linux/config.h>
30042 +#endif /* for CONFIG_IP_FORWARD */
30043 +#include <linux/version.h>
30044 +#include <linux/kernel.h> /* printk() */
30045 +
30046 +#include "freeswan/ipsec_param.h"
30047 +
30048 +#ifdef MALLOC_SLAB
30049 +# include <linux/slab.h> /* kmalloc() */
30050 +#else /* MALLOC_SLAB */
30051 +# include <linux/malloc.h> /* kmalloc() */
30052 +#endif /* MALLOC_SLAB */
30053 +#include <linux/errno.h> /* error codes */
30054 +#include <linux/types.h> /* size_t */
30055 +#include <linux/interrupt.h> /* mark_bh */
30056 +
30057 +#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
30058 +#include <linux/etherdevice.h> /* eth_type_trans */
30059 +#include <linux/ip.h> /* struct iphdr */
30060 +#include <linux/tcp.h> /* struct tcphdr */
30061 +#include <linux/udp.h> /* struct udphdr */
30062 +#include <linux/skbuff.h>
30063 +#include <freeswan.h>
30064 +#include <linux/in6.h>
30065 +#include <net/dst.h>
30066 +#undef dev_kfree_skb
30067 +#define dev_kfree_skb(a,b) kfree_skb(a)
30068 +#define PHYSDEV_TYPE
30069 +#include <net/icmp.h> /* icmp_send() */
30070 +#include <net/ip.h>
30071 +#include <linux/netfilter_ipv4.h>
30072 +
30073 +#include <linux/if_arp.h>
30074 +
30075 +#include "freeswan/radij.h"
30076 +#include "freeswan/ipsec_life.h"
30077 +#include "freeswan/ipsec_xform.h"
30078 +#include "freeswan/ipsec_eroute.h"
30079 +#include "freeswan/ipsec_encap.h"
30080 +#include "freeswan/ipsec_radij.h"
30081 +#include "freeswan/ipsec_sa.h"
30082 +#include "freeswan/ipsec_tunnel.h"
30083 +#include "freeswan/ipsec_mast.h"
30084 +#include "freeswan/ipsec_ipe4.h"
30085 +#include "freeswan/ipsec_ah.h"
30086 +#include "freeswan/ipsec_esp.h"
30087 +
30088 +#include <openswan/pfkeyv2.h>
30089 +#include <openswan/pfkey.h>
30090 +
30091 +#include "freeswan/ipsec_proto.h"
30092 +
30093 +int ipsec_maxdevice_count = -1;
30094 +
30095 +DEBUG_NO_STATIC int
30096 +ipsec_mast_open(struct net_device *dev)
30097 +{
30098 + struct ipsecpriv *prv = dev->priv;
30099 +
30100 + /*
30101 + * Can't open until attached.
30102 + */
30103 +
30104 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30105 + "klips_debug:ipsec_mast_open: "
30106 + "dev = %s, prv->dev = %s\n",
30107 + dev->name, prv->dev?prv->dev->name:"NONE");
30108 +
30109 + if (prv->dev == NULL)
30110 + return -ENODEV;
30111 +
30112 + KLIPS_INC_USE;
30113 + return 0;
30114 +}
30115 +
30116 +DEBUG_NO_STATIC int
30117 +ipsec_mast_close(struct net_device *dev)
30118 +{
30119 + KLIPS_DEC_USE;
30120 + return 0;
30121 +}
30122 +
30123 +static inline int ipsec_mast_xmit2(struct sk_buff *skb)
30124 +{
30125 + return ip_send(skb);
30126 +}
30127 +
30128 +enum ipsec_xmit_value
30129 +ipsec_mast_send(struct ipsec_xmit_state*ixs)
30130 +{
30131 + /* new route/dst cache code from James Morris */
30132 + ixs->skb->dev = ixs->physdev;
30133 + /*skb_orphan(ixs->skb);*/
30134 + if((ixs->error = ip_route_output(&ixs->route,
30135 + ixs->skb->nh.iph->daddr,
30136 + ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
30137 + RT_TOS(ixs->skb->nh.iph->tos),
30138 + ixs->physdev->iflink /* rgb: should this be 0? */))) {
30139 + ixs->stats->tx_errors++;
30140 + KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30141 + "klips_debug:ipsec_xmit_send: "
30142 + "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
30143 + ixs->error,
30144 + ixs->route->u.dst.dev->name);
30145 + return IPSEC_XMIT_ROUTEERR;
30146 + }
30147 + if(ixs->dev == ixs->route->u.dst.dev) {
30148 + ip_rt_put(ixs->route);
30149 + /* This is recursion, drop it. */
30150 + ixs->stats->tx_errors++;
30151 + KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30152 + "klips_debug:ipsec_xmit_send: "
30153 + "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
30154 + ixs->dev->name);
30155 + return IPSEC_XMIT_RECURSDETECT;
30156 + }
30157 + dst_release(ixs->skb->dst);
30158 + ixs->skb->dst = &ixs->route->u.dst;
30159 + ixs->stats->tx_bytes += ixs->skb->len;
30160 + if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
30161 + ixs->stats->tx_errors++;
30162 + printk(KERN_WARNING
30163 + "klips_error:ipsec_xmit_send: "
30164 + "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
30165 + (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
30166 + ixs->skb->len);
30167 + return IPSEC_XMIT_PUSHPULLERR;
30168 + }
30169 + __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
30170 +#ifdef SKB_RESET_NFCT
30171 + nf_conntrack_put(ixs->skb->nfct);
30172 + ixs->skb->nfct = NULL;
30173 +#ifdef CONFIG_NETFILTER_DEBUG
30174 + ixs->skb->nf_debug = 0;
30175 +#endif /* CONFIG_NETFILTER_DEBUG */
30176 +#endif /* SKB_RESET_NFCT */
30177 + KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30178 + "klips_debug:ipsec_xmit_send: "
30179 + "...done, calling ip_send() on device:%s\n",
30180 + ixs->skb->dev ? ixs->skb->dev->name : "NULL");
30181 + KLIPS_IP_PRINT(debug_mast & DB_MAST_XMIT, ixs->skb->nh.iph);
30182 + {
30183 + int err;
30184 +
30185 + err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
30186 + ipsec_mast_xmit2);
30187 + if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
30188 + if(net_ratelimit())
30189 + printk(KERN_ERR
30190 + "klips_error:ipsec_xmit_send: "
30191 + "ip_send() failed, err=%d\n",
30192 + -err);
30193 + ixs->stats->tx_errors++;
30194 + ixs->stats->tx_aborted_errors++;
30195 + ixs->skb = NULL;
30196 + return IPSEC_XMIT_IPSENDFAILURE;
30197 + }
30198 + }
30199 + ixs->stats->tx_packets++;
30200 +
30201 + ixs->skb = NULL;
30202 +
30203 + return IPSEC_XMIT_OK;
30204 +}
30205 +
30206 +void
30207 +ipsec_mast_cleanup(struct ipsec_xmit_state*ixs)
30208 +{
30209 +#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
30210 + netif_wake_queue(ixs->dev);
30211 +#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
30212 + ixs->dev->tbusy = 0;
30213 +#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
30214 + if(ixs->saved_header) {
30215 + kfree(ixs->saved_header);
30216 + }
30217 + if(ixs->skb) {
30218 + dev_kfree_skb(ixs->skb, FREE_WRITE);
30219 + }
30220 + if(ixs->oskb) {
30221 + dev_kfree_skb(ixs->oskb, FREE_WRITE);
30222 + }
30223 + if (ixs->ips.ips_ident_s.data) {
30224 + kfree(ixs->ips.ips_ident_s.data);
30225 + }
30226 + if (ixs->ips.ips_ident_d.data) {
30227 + kfree(ixs->ips.ips_ident_d.data);
30228 + }
30229 +}
30230 +
30231 +#if 0
30232 +/*
30233 + * This function assumes it is being called from dev_queue_xmit()
30234 + * and that skb is filled properly by that function.
30235 + */
30236 +int
30237 +ipsec_mast_start_xmit(struct sk_buff *skb, struct net_device *dev, IPsecSAref_t SAref)
30238 +{
30239 + struct ipsec_xmit_state ixs_mem;
30240 + struct ipsec_xmit_state *ixs = &ixs_mem;
30241 + enum ipsec_xmit_value stat = IPSEC_XMIT_OK;
30242 +
30243 + /* dev could be a mast device, but should be optional, I think... */
30244 + /* SAref is also optional, but one of the two must be present. */
30245 + /* I wonder if it could accept no device or saref and guess? */
30246 +
30247 +/* ipsec_xmit_sanity_check_dev(ixs); */
30248 +
30249 + ipsec_xmit_sanity_check_skb(ixs);
30250 +
30251 + ipsec_xmit_adjust_hard_header(ixs);
30252 +
30253 + stat = ipsec_xmit_encap_bundle(ixs);
30254 + if(stat != IPSEC_XMIT_OK) {
30255 + /* SA processing failed */
30256 + }
30257 +
30258 + ipsec_xmit_hard_header_restore();
30259 +}
30260 +#endif
30261 +
30262 +DEBUG_NO_STATIC struct net_device_stats *
30263 +ipsec_mast_get_stats(struct net_device *dev)
30264 +{
30265 + return &(((struct ipsecpriv *)(dev->priv))->mystats);
30266 +}
30267 +
30268 +/*
30269 + * Revectored calls.
30270 + * For each of these calls, a field exists in our private structure.
30271 + */
30272 +
30273 +DEBUG_NO_STATIC int
30274 +ipsec_mast_hard_header(struct sk_buff *skb, struct net_device *dev,
30275 + unsigned short type, void *daddr, void *saddr, unsigned len)
30276 +{
30277 + struct ipsecpriv *prv = dev->priv;
30278 + struct net_device *tmp;
30279 + int ret;
30280 + struct net_device_stats *stats; /* This device's statistics */
30281 +
30282 + if(skb == NULL) {
30283 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30284 + "klips_debug:ipsec_mast_hard_header: "
30285 + "no skb...\n");
30286 + return -ENODATA;
30287 + }
30288 +
30289 + if(dev == NULL) {
30290 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30291 + "klips_debug:ipsec_mast_hard_header: "
30292 + "no device...\n");
30293 + return -ENODEV;
30294 + }
30295 +
30296 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30297 + "klips_debug:ipsec_mast_hard_header: "
30298 + "skb->dev=%s dev=%s.\n",
30299 + skb->dev ? skb->dev->name : "NULL",
30300 + dev->name);
30301 +
30302 + if(prv == NULL) {
30303 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30304 + "klips_debug:ipsec_mast_hard_header: "
30305 + "no private space associated with dev=%s\n",
30306 + dev->name ? dev->name : "NULL");
30307 + return -ENODEV;
30308 + }
30309 +
30310 + stats = (struct net_device_stats *) &(prv->mystats);
30311 +
30312 + if(prv->dev == NULL) {
30313 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30314 + "klips_debug:ipsec_mast_hard_header: "
30315 + "no physical device associated with dev=%s\n",
30316 + dev->name ? dev->name : "NULL");
30317 + stats->tx_dropped++;
30318 + return -ENODEV;
30319 + }
30320 +
30321 + /* check if we have to send a IPv6 packet. It might be a Router
30322 + Solicitation, where the building of the packet happens in
30323 + reverse order:
30324 + 1. ll hdr,
30325 + 2. IPv6 hdr,
30326 + 3. ICMPv6 hdr
30327 + -> skb->nh.raw is still uninitialized when this function is
30328 + called!! If this is no IPv6 packet, we can print debugging
30329 + messages, otherwise we skip all debugging messages and just
30330 + build the ll header */
30331 + if(type != ETH_P_IPV6) {
30332 + /* execute this only, if we don't have to build the
30333 + header for a IPv6 packet */
30334 + if(!prv->hard_header) {
30335 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30336 + "klips_debug:ipsec_mast_hard_header: "
30337 + "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
30338 + saddr,
30339 + daddr,
30340 + len,
30341 + type,
30342 + dev->name);
30343 + KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
30344 + "ip=%08x->%08x\n",
30345 + (__u32)ntohl(skb->nh.iph->saddr),
30346 + (__u32)ntohl(skb->nh.iph->daddr) );
30347 + stats->tx_dropped++;
30348 + return -ENODEV;
30349 + }
30350 +
30351 +#define da ((struct net_device *)(prv->dev))->dev_addr
30352 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30353 + "klips_debug:ipsec_mast_hard_header: "
30354 + "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
30355 + saddr,
30356 + daddr,
30357 + len,
30358 + type,
30359 + dev->name,
30360 + prv->dev->name,
30361 + da[0], da[1], da[2], da[3], da[4], da[5]);
30362 + KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
30363 + "ip=%08x->%08x\n",
30364 + (__u32)ntohl(skb->nh.iph->saddr),
30365 + (__u32)ntohl(skb->nh.iph->daddr) );
30366 + } else {
30367 + KLIPS_PRINT(debug_mast,
30368 + "klips_debug:ipsec_mast_hard_header: "
30369 + "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
30370 + }
30371 + tmp = skb->dev;
30372 + skb->dev = prv->dev;
30373 + ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
30374 + skb->dev = tmp;
30375 + return ret;
30376 +}
30377 +
30378 +DEBUG_NO_STATIC int
30379 +ipsec_mast_rebuild_header(struct sk_buff *skb)
30380 +{
30381 + struct ipsecpriv *prv = skb->dev->priv;
30382 + struct net_device *tmp;
30383 + int ret;
30384 + struct net_device_stats *stats; /* This device's statistics */
30385 +
30386 + if(skb->dev == NULL) {
30387 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30388 + "klips_debug:ipsec_mast_rebuild_header: "
30389 + "no device...");
30390 + return -ENODEV;
30391 + }
30392 +
30393 + if(prv == NULL) {
30394 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30395 + "klips_debug:ipsec_mast_rebuild_header: "
30396 + "no private space associated with dev=%s",
30397 + skb->dev->name ? skb->dev->name : "NULL");
30398 + return -ENODEV;
30399 + }
30400 +
30401 + stats = (struct net_device_stats *) &(prv->mystats);
30402 +
30403 + if(prv->dev == NULL) {
30404 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30405 + "klips_debug:ipsec_mast_rebuild_header: "
30406 + "no physical device associated with dev=%s",
30407 + skb->dev->name ? skb->dev->name : "NULL");
30408 + stats->tx_dropped++;
30409 + return -ENODEV;
30410 + }
30411 +
30412 + if(!prv->rebuild_header) {
30413 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30414 + "klips_debug:ipsec_mast_rebuild_header: "
30415 + "physical device has been detached, packet dropped skb->dev=%s->NULL ",
30416 + skb->dev->name);
30417 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30418 + "ip=%08x->%08x\n",
30419 + (__u32)ntohl(skb->nh.iph->saddr),
30420 + (__u32)ntohl(skb->nh.iph->daddr) );
30421 + stats->tx_dropped++;
30422 + return -ENODEV;
30423 + }
30424 +
30425 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30426 + "klips_debug:ipsec_mast: "
30427 + "Revectored rebuild_header dev=%s->%s ",
30428 + skb->dev->name, prv->dev->name);
30429 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30430 + "ip=%08x->%08x\n",
30431 + (__u32)ntohl(skb->nh.iph->saddr),
30432 + (__u32)ntohl(skb->nh.iph->daddr) );
30433 + tmp = skb->dev;
30434 + skb->dev = prv->dev;
30435 +
30436 + ret = prv->rebuild_header(skb);
30437 + skb->dev = tmp;
30438 + return ret;
30439 +}
30440 +
30441 +DEBUG_NO_STATIC int
30442 +ipsec_mast_set_mac_address(struct net_device *dev, void *addr)
30443 +{
30444 + struct ipsecpriv *prv = dev->priv;
30445 +
30446 + struct net_device_stats *stats; /* This device's statistics */
30447 +
30448 + if(dev == NULL) {
30449 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30450 + "klips_debug:ipsec_mast_set_mac_address: "
30451 + "no device...");
30452 + return -ENODEV;
30453 + }
30454 +
30455 + if(prv == NULL) {
30456 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30457 + "klips_debug:ipsec_mast_set_mac_address: "
30458 + "no private space associated with dev=%s",
30459 + dev->name ? dev->name : "NULL");
30460 + return -ENODEV;
30461 + }
30462 +
30463 + stats = (struct net_device_stats *) &(prv->mystats);
30464 +
30465 + if(prv->dev == NULL) {
30466 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30467 + "klips_debug:ipsec_mast_set_mac_address: "
30468 + "no physical device associated with dev=%s",
30469 + dev->name ? dev->name : "NULL");
30470 + stats->tx_dropped++;
30471 + return -ENODEV;
30472 + }
30473 +
30474 + if(!prv->set_mac_address) {
30475 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30476 + "klips_debug:ipsec_mast_set_mac_address: "
30477 + "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
30478 + dev->name);
30479 + return -ENODEV;
30480 + }
30481 +
30482 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30483 + "klips_debug:ipsec_mast_set_mac_address: "
30484 + "Revectored dev=%s->%s addr=0p%p\n",
30485 + dev->name, prv->dev->name, addr);
30486 + return prv->set_mac_address(prv->dev, addr);
30487 +
30488 +}
30489 +
30490 +DEBUG_NO_STATIC void
30491 +ipsec_mast_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
30492 +{
30493 + struct ipsecpriv *prv = dev->priv;
30494 +
30495 + struct net_device_stats *stats; /* This device's statistics */
30496 +
30497 + if(dev == NULL) {
30498 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30499 + "klips_debug:ipsec_mast_cache_update: "
30500 + "no device...");
30501 + return;
30502 + }
30503 +
30504 + if(prv == NULL) {
30505 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30506 + "klips_debug:ipsec_mast_cache_update: "
30507 + "no private space associated with dev=%s",
30508 + dev->name ? dev->name : "NULL");
30509 + return;
30510 + }
30511 +
30512 + stats = (struct net_device_stats *) &(prv->mystats);
30513 +
30514 + if(prv->dev == NULL) {
30515 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30516 + "klips_debug:ipsec_mast_cache_update: "
30517 + "no physical device associated with dev=%s",
30518 + dev->name ? dev->name : "NULL");
30519 + stats->tx_dropped++;
30520 + return;
30521 + }
30522 +
30523 + if(!prv->header_cache_update) {
30524 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30525 + "klips_debug:ipsec_mast_cache_update: "
30526 + "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
30527 + dev->name);
30528 + return;
30529 + }
30530 +
30531 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30532 + "klips_debug:ipsec_mast: "
30533 + "Revectored cache_update\n");
30534 + prv->header_cache_update(hh, prv->dev, haddr);
30535 + return;
30536 +}
30537 +
30538 +DEBUG_NO_STATIC int
30539 +ipsec_mast_neigh_setup(struct neighbour *n)
30540 +{
30541 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30542 + "klips_debug:ipsec_mast_neigh_setup:\n");
30543 +
30544 + if (n->nud_state == NUD_NONE) {
30545 + n->ops = &arp_broken_ops;
30546 + n->output = n->ops->output;
30547 + }
30548 + return 0;
30549 +}
30550 +
30551 +DEBUG_NO_STATIC int
30552 +ipsec_mast_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
30553 +{
30554 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30555 + "klips_debug:ipsec_mast_neigh_setup_dev: "
30556 + "setting up %s\n",
30557 + dev ? dev->name : "NULL");
30558 +
30559 + if (p->tbl->family == AF_INET) {
30560 + p->neigh_setup = ipsec_mast_neigh_setup;
30561 + p->ucast_probes = 0;
30562 + p->mcast_probes = 0;
30563 + }
30564 + return 0;
30565 +}
30566 +
30567 +/*
30568 + * We call the attach routine to attach another device.
30569 + */
30570 +
30571 +DEBUG_NO_STATIC int
30572 +ipsec_mast_attach(struct net_device *dev, struct net_device *physdev)
30573 +{
30574 + int i;
30575 + struct ipsecpriv *prv = dev->priv;
30576 +
30577 + if(dev == NULL) {
30578 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30579 + "klips_debug:ipsec_mast_attach: "
30580 + "no device...");
30581 + return -ENODEV;
30582 + }
30583 +
30584 + if(prv == NULL) {
30585 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30586 + "klips_debug:ipsec_mast_attach: "
30587 + "no private space associated with dev=%s",
30588 + dev->name ? dev->name : "NULL");
30589 + return -ENODATA;
30590 + }
30591 +
30592 + prv->dev = physdev;
30593 + prv->hard_start_xmit = physdev->hard_start_xmit;
30594 + prv->get_stats = physdev->get_stats;
30595 +
30596 + if (physdev->hard_header) {
30597 + prv->hard_header = physdev->hard_header;
30598 + dev->hard_header = ipsec_mast_hard_header;
30599 + } else
30600 + dev->hard_header = NULL;
30601 +
30602 + if (physdev->rebuild_header) {
30603 + prv->rebuild_header = physdev->rebuild_header;
30604 + dev->rebuild_header = ipsec_mast_rebuild_header;
30605 + } else
30606 + dev->rebuild_header = NULL;
30607 +
30608 + if (physdev->set_mac_address) {
30609 + prv->set_mac_address = physdev->set_mac_address;
30610 + dev->set_mac_address = ipsec_mast_set_mac_address;
30611 + } else
30612 + dev->set_mac_address = NULL;
30613 +
30614 + if (physdev->header_cache_update) {
30615 + prv->header_cache_update = physdev->header_cache_update;
30616 + dev->header_cache_update = ipsec_mast_cache_update;
30617 + } else
30618 + dev->header_cache_update = NULL;
30619 +
30620 + dev->hard_header_len = physdev->hard_header_len;
30621 +
30622 +/* prv->neigh_setup = physdev->neigh_setup; */
30623 + dev->neigh_setup = ipsec_mast_neigh_setup_dev;
30624 + dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
30625 + prv->mtu = physdev->mtu;
30626 +
30627 +#ifdef PHYSDEV_TYPE
30628 + dev->type = physdev->type; /* ARPHRD_MAST; */
30629 +#endif /* PHYSDEV_TYPE */
30630 +
30631 + dev->addr_len = physdev->addr_len;
30632 + for (i=0; i<dev->addr_len; i++) {
30633 + dev->dev_addr[i] = physdev->dev_addr[i];
30634 + }
30635 +#ifdef CONFIG_KLIPS_DEBUG
30636 + if(debug_mast & DB_MAST_INIT) {
30637 + printk(KERN_INFO "klips_debug:ipsec_mast_attach: "
30638 + "physical device %s being attached has HW address: %2x",
30639 + physdev->name, physdev->dev_addr[0]);
30640 + for (i=1; i < physdev->addr_len; i++) {
30641 + printk(":%02x", physdev->dev_addr[i]);
30642 + }
30643 + printk("\n");
30644 + }
30645 +#endif /* CONFIG_KLIPS_DEBUG */
30646 +
30647 + return 0;
30648 +}
30649 +
30650 +/*
30651 + * We call the detach routine to detach the ipsec mast from another device.
30652 + */
30653 +
30654 +DEBUG_NO_STATIC int
30655 +ipsec_mast_detach(struct net_device *dev)
30656 +{
30657 + int i;
30658 + struct ipsecpriv *prv = dev->priv;
30659 +
30660 + if(dev == NULL) {
30661 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30662 + "klips_debug:ipsec_mast_detach: "
30663 + "no device...");
30664 + return -ENODEV;
30665 + }
30666 +
30667 + if(prv == NULL) {
30668 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30669 + "klips_debug:ipsec_mast_detach: "
30670 + "no private space associated with dev=%s",
30671 + dev->name ? dev->name : "NULL");
30672 + return -ENODATA;
30673 + }
30674 +
30675 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30676 + "klips_debug:ipsec_mast_detach: "
30677 + "physical device %s being detached from virtual device %s\n",
30678 + prv->dev ? prv->dev->name : "NULL",
30679 + dev->name);
30680 +
30681 + prv->dev = NULL;
30682 + prv->hard_start_xmit = NULL;
30683 + prv->get_stats = NULL;
30684 +
30685 + prv->hard_header = NULL;
30686 +#ifdef DETACH_AND_DOWN
30687 + dev->hard_header = NULL;
30688 +#endif /* DETACH_AND_DOWN */
30689 +
30690 + prv->rebuild_header = NULL;
30691 +#ifdef DETACH_AND_DOWN
30692 + dev->rebuild_header = NULL;
30693 +#endif /* DETACH_AND_DOWN */
30694 +
30695 + prv->set_mac_address = NULL;
30696 +#ifdef DETACH_AND_DOWN
30697 + dev->set_mac_address = NULL;
30698 +#endif /* DETACH_AND_DOWN */
30699 +
30700 + prv->header_cache_update = NULL;
30701 +#ifdef DETACH_AND_DOWN
30702 + dev->header_cache_update = NULL;
30703 +#endif /* DETACH_AND_DOWN */
30704 +
30705 +#ifdef DETACH_AND_DOWN
30706 + dev->neigh_setup = NULL;
30707 +#endif /* DETACH_AND_DOWN */
30708 +
30709 + dev->hard_header_len = 0;
30710 +#ifdef DETACH_AND_DOWN
30711 + dev->mtu = 0;
30712 +#endif /* DETACH_AND_DOWN */
30713 + prv->mtu = 0;
30714 + for (i=0; i<MAX_ADDR_LEN; i++) {
30715 + dev->dev_addr[i] = 0;
30716 + }
30717 + dev->addr_len = 0;
30718 +#ifdef PHYSDEV_TYPE
30719 + dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */
30720 +#endif /* PHYSDEV_TYPE */
30721 +
30722 + return 0;
30723 +}
30724 +
30725 +/*
30726 + * We call the clear routine to detach all ipsec masts from other devices.
30727 + */
30728 +DEBUG_NO_STATIC int
30729 +ipsec_mast_clear(void)
30730 +{
30731 + int i;
30732 + struct net_device *ipsecdev = NULL, *prvdev;
30733 + struct ipsecpriv *prv;
30734 + char name[9];
30735 + int ret;
30736 +
30737 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30738 + "klips_debug:ipsec_mast_clear: .\n");
30739 +
30740 + for(i = 0; i < IPSEC_NUM_IF; i++) {
30741 + sprintf(name, IPSEC_DEV_FORMAT, i);
30742 + if((ipsecdev = ipsec_dev_get(name)) != NULL) {
30743 + if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
30744 + prvdev = (struct net_device *)(prv->dev);
30745 + if(prvdev) {
30746 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30747 + "klips_debug:ipsec_mast_clear: "
30748 + "physical device for device %s is %s\n",
30749 + name, prvdev->name);
30750 + if((ret = ipsec_mast_detach(ipsecdev))) {
30751 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30752 + "klips_debug:ipsec_mast_clear: "
30753 + "error %d detatching device %s from device %s.\n",
30754 + ret, name, prvdev->name);
30755 + return ret;
30756 + }
30757 + }
30758 + }
30759 + }
30760 + }
30761 + return 0;
30762 +}
30763 +
30764 +DEBUG_NO_STATIC int
30765 +ipsec_mast_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
30766 +{
30767 + struct ipsecmastconf *cf = (struct ipsecmastconf *)&ifr->ifr_data;
30768 + struct ipsecpriv *prv = dev->priv;
30769 + struct net_device *them; /* physical device */
30770 +#ifdef CONFIG_IP_ALIAS
30771 + char *colon;
30772 + char realphysname[IFNAMSIZ];
30773 +#endif /* CONFIG_IP_ALIAS */
30774 +
30775 + if(dev == NULL) {
30776 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30777 + "klips_debug:ipsec_mast_ioctl: "
30778 + "device not supplied.\n");
30779 + return -ENODEV;
30780 + }
30781 +
30782 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30783 + "klips_debug:ipsec_mast_ioctl: "
30784 + "tncfg service call #%d for dev=%s\n",
30785 + cmd,
30786 + dev->name ? dev->name : "NULL");
30787 + switch (cmd) {
30788 + /* attach a virtual ipsec? device to a physical device */
30789 + case IPSEC_SET_DEV:
30790 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30791 + "klips_debug:ipsec_mast_ioctl: "
30792 + "calling ipsec_mast_attatch...\n");
30793 +#ifdef CONFIG_IP_ALIAS
30794 + /* If this is an IP alias interface, get its real physical name */
30795 + strncpy(realphysname, cf->cf_name, IFNAMSIZ);
30796 + realphysname[IFNAMSIZ-1] = 0;
30797 + colon = strchr(realphysname, ':');
30798 + if (colon) *colon = 0;
30799 + them = ipsec_dev_get(realphysname);
30800 +#else /* CONFIG_IP_ALIAS */
30801 + them = ipsec_dev_get(cf->cf_name);
30802 +#endif /* CONFIG_IP_ALIAS */
30803 +
30804 + if (them == NULL) {
30805 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30806 + "klips_debug:ipsec_mast_ioctl: "
30807 + "physical device %s requested is null\n",
30808 + cf->cf_name);
30809 + return -ENXIO;
30810 + }
30811 +
30812 +#if 0
30813 + if (them->flags & IFF_UP) {
30814 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30815 + "klips_debug:ipsec_mast_ioctl: "
30816 + "physical device %s requested is not up.\n",
30817 + cf->cf_name);
30818 + return -ENXIO;
30819 + }
30820 +#endif
30821 +
30822 + if (prv && prv->dev) {
30823 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30824 + "klips_debug:ipsec_mast_ioctl: "
30825 + "virtual device is already connected to %s.\n",
30826 + prv->dev->name ? prv->dev->name : "NULL");
30827 + return -EBUSY;
30828 + }
30829 + return ipsec_mast_attach(dev, them);
30830 +
30831 + case IPSEC_DEL_DEV:
30832 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30833 + "klips_debug:ipsec_mast_ioctl: "
30834 + "calling ipsec_mast_detatch.\n");
30835 + if (! prv->dev) {
30836 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30837 + "klips_debug:ipsec_mast_ioctl: "
30838 + "physical device not connected.\n");
30839 + return -ENODEV;
30840 + }
30841 + return ipsec_mast_detach(dev);
30842 +
30843 + case IPSEC_CLR_DEV:
30844 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30845 + "klips_debug:ipsec_mast_ioctl: "
30846 + "calling ipsec_mast_clear.\n");
30847 + return ipsec_mast_clear();
30848 +
30849 + default:
30850 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30851 + "klips_debug:ipsec_mast_ioctl: "
30852 + "unknown command %d.\n",
30853 + cmd);
30854 + return -EOPNOTSUPP;
30855 + }
30856 +}
30857 +
30858 +int
30859 +ipsec_mast_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
30860 +{
30861 + struct net_device *dev = ptr;
30862 + struct net_device *ipsec_dev;
30863 + struct ipsecpriv *priv;
30864 + char name[9];
30865 + int i;
30866 +
30867 + if (dev == NULL) {
30868 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30869 + "klips_debug:ipsec_mast_device_event: "
30870 + "dev=NULL for event type %ld.\n",
30871 + event);
30872 + return(NOTIFY_DONE);
30873 + }
30874 +
30875 + /* check for loopback devices */
30876 + if (dev && (dev->flags & IFF_LOOPBACK)) {
30877 + return(NOTIFY_DONE);
30878 + }
30879 +
30880 + switch (event) {
30881 + case NETDEV_DOWN:
30882 + /* look very carefully at the scope of these compiler
30883 + directives before changing anything... -- RGB */
30884 +
30885 + case NETDEV_UNREGISTER:
30886 + switch (event) {
30887 + case NETDEV_DOWN:
30888 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30889 + "klips_debug:ipsec_mast_device_event: "
30890 + "NETDEV_DOWN dev=%s flags=%x\n",
30891 + dev->name,
30892 + dev->flags);
30893 + if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
30894 + printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
30895 + dev->name);
30896 + }
30897 + break;
30898 + case NETDEV_UNREGISTER:
30899 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30900 + "klips_debug:ipsec_mast_device_event: "
30901 + "NETDEV_UNREGISTER dev=%s flags=%x\n",
30902 + dev->name,
30903 + dev->flags);
30904 + break;
30905 + }
30906 +
30907 + /* find the attached physical device and detach it. */
30908 + for(i = 0; i < IPSEC_NUM_IF; i++) {
30909 + sprintf(name, IPSEC_DEV_FORMAT, i);
30910 + ipsec_dev = ipsec_dev_get(name);
30911 + if(ipsec_dev) {
30912 + priv = (struct ipsecpriv *)(ipsec_dev->priv);
30913 + if(priv) {
30914 + ;
30915 + if(((struct net_device *)(priv->dev)) == dev) {
30916 + /* dev_close(ipsec_dev); */
30917 + /* return */ ipsec_mast_detach(ipsec_dev);
30918 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30919 + "klips_debug:ipsec_mast_device_event: "
30920 + "device '%s' has been detached.\n",
30921 + ipsec_dev->name);
30922 + break;
30923 + }
30924 + } else {
30925 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30926 + "klips_debug:ipsec_mast_device_event: "
30927 + "device '%s' has no private data space!\n",
30928 + ipsec_dev->name);
30929 + }
30930 + }
30931 + }
30932 + break;
30933 + case NETDEV_UP:
30934 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30935 + "klips_debug:ipsec_mast_device_event: "
30936 + "NETDEV_UP dev=%s\n",
30937 + dev->name);
30938 + break;
30939 + case NETDEV_REBOOT:
30940 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30941 + "klips_debug:ipsec_mast_device_event: "
30942 + "NETDEV_REBOOT dev=%s\n",
30943 + dev->name);
30944 + break;
30945 + case NETDEV_CHANGE:
30946 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30947 + "klips_debug:ipsec_mast_device_event: "
30948 + "NETDEV_CHANGE dev=%s flags=%x\n",
30949 + dev->name,
30950 + dev->flags);
30951 + break;
30952 + case NETDEV_REGISTER:
30953 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30954 + "klips_debug:ipsec_mast_device_event: "
30955 + "NETDEV_REGISTER dev=%s\n",
30956 + dev->name);
30957 + break;
30958 + case NETDEV_CHANGEMTU:
30959 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30960 + "klips_debug:ipsec_mast_device_event: "
30961 + "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
30962 + dev->name,
30963 + dev->mtu);
30964 + break;
30965 + case NETDEV_CHANGEADDR:
30966 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30967 + "klips_debug:ipsec_mast_device_event: "
30968 + "NETDEV_CHANGEADDR dev=%s\n",
30969 + dev->name);
30970 + break;
30971 + case NETDEV_GOING_DOWN:
30972 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30973 + "klips_debug:ipsec_mast_device_event: "
30974 + "NETDEV_GOING_DOWN dev=%s\n",
30975 + dev->name);
30976 + break;
30977 + case NETDEV_CHANGENAME:
30978 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30979 + "klips_debug:ipsec_mast_device_event: "
30980 + "NETDEV_CHANGENAME dev=%s\n",
30981 + dev->name);
30982 + break;
30983 + default:
30984 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30985 + "klips_debug:ipsec_mast_device_event: "
30986 + "event type %ld unrecognised for dev=%s\n",
30987 + event,
30988 + dev->name);
30989 + break;
30990 + }
30991 + return NOTIFY_DONE;
30992 +}
30993 +
30994 +/*
30995 + * Called when an ipsec mast device is initialized.
30996 + * The ipsec mast device structure is passed to us.
30997 + */
30998 +
30999 +int
31000 +ipsec_mast_init(struct net_device *dev)
31001 +{
31002 + int i;
31003 +
31004 + KLIPS_PRINT(debug_mast,
31005 + "klips_debug:ipsec_mast_init: "
31006 + "allocating %lu bytes initialising device: %s\n",
31007 + (unsigned long) sizeof(struct ipsecpriv),
31008 + dev->name ? dev->name : "NULL");
31009 +
31010 + /* Add our mast functions to the device */
31011 + dev->open = ipsec_mast_open;
31012 + dev->stop = ipsec_mast_close;
31013 + dev->hard_start_xmit = ipsec_mast_start_xmit;
31014 + dev->get_stats = ipsec_mast_get_stats;
31015 +
31016 + dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
31017 + if (dev->priv == NULL)
31018 + return -ENOMEM;
31019 + memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
31020 +
31021 + for(i = 0; i < sizeof(zeroes); i++) {
31022 + ((__u8*)(zeroes))[i] = 0;
31023 + }
31024 +
31025 + dev->set_multicast_list = NULL;
31026 + dev->do_ioctl = ipsec_mast_ioctl;
31027 + dev->hard_header = NULL;
31028 + dev->rebuild_header = NULL;
31029 + dev->set_mac_address = NULL;
31030 + dev->header_cache_update= NULL;
31031 + dev->neigh_setup = ipsec_mast_neigh_setup_dev;
31032 + dev->hard_header_len = 0;
31033 + dev->mtu = 0;
31034 + dev->addr_len = 0;
31035 + dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */ /* ARPHRD_ETHER; */
31036 + dev->tx_queue_len = 10; /* Small queue */
31037 + memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
31038 +
31039 + /* New-style flags. */
31040 + dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
31041 + dev_init_buffers(dev);
31042 +
31043 + /* We're done. Have I forgotten anything? */
31044 + return 0;
31045 +}
31046 +
31047 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
31048 +/* Module specific interface (but it links with the rest of IPSEC) */
31049 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
31050 +
31051 +int
31052 +ipsec_mast_probe(struct net_device *dev)
31053 +{
31054 + ipsec_mast_init(dev);
31055 + return 0;
31056 +}
31057 +
31058 +int
31059 +ipsec_mast_init_devices(void)
31060 +{
31061 + return 0;
31062 +}
31063 +
31064 +/* void */
31065 +int
31066 +ipsec_mast_cleanup_devices(void)
31067 +{
31068 + int error = 0;
31069 + int i;
31070 + char name[10];
31071 + struct net_device *dev_mast;
31072 +
31073 + for(i = 0; i < ipsec_mastdevice_count; i++) {
31074 + sprintf(name, MAST_DEV_FORMAT, i);
31075 + if((dev_mast = ipsec_dev_get(name)) == NULL) {
31076 + break;
31077 + }
31078 + unregister_netdev(dev_mast);
31079 + kfree(dev_mast->priv);
31080 + dev_mast->priv=NULL;
31081 + }
31082 + return error;
31083 +}
31084 +
31085 +/*
31086 + * $Log: ipsec_mast.c,v $
31087 + * Revision 1.7 2005/04/29 05:10:22 mcr
31088 + * removed from extraenous includes to make unit testing easier.
31089 + *
31090 + * Revision 1.6 2004/12/03 21:25:57 mcr
31091 + * compile time fixes for running on 2.6.
31092 + * still experimental.
31093 + *
31094 + * Revision 1.5 2004/08/03 18:19:08 mcr
31095 + * in 2.6, use "net_device" instead of #define device->net_device.
31096 + * this probably breaks 2.0 compiles.
31097 + *
31098 + * Revision 1.4 2004/07/10 19:11:18 mcr
31099 + * CONFIG_IPSEC -> CONFIG_KLIPS.
31100 + *
31101 + * Revision 1.3 2003/10/31 02:27:55 mcr
31102 + * pulled up port-selector patches and sa_id elimination.
31103 + *
31104 + * Revision 1.2.4.1 2003/10/29 01:30:41 mcr
31105 + * elimited "struct sa_id".
31106 + *
31107 + * Revision 1.2 2003/06/22 20:06:17 mcr
31108 + * refactored mast code still had lots of ipsecX junk in it.
31109 + *
31110 + * Revision 1.1 2003/02/12 19:31:12 rgb
31111 + * Refactored from ipsec_tunnel.c
31112 + *
31113 + */
31114 --- /dev/null Tue Mar 11 13:02:56 2003
31115 +++ linux/net/ipsec/ipsec_md5c.c Mon Feb 9 13:51:03 2004
31116 @@ -0,0 +1,453 @@
31117 +/*
31118 + * RCSID $Id: ipsec_md5c.c,v 1.10 2005/04/15 01:25:57 mcr Exp $
31119 + */
31120 +
31121 +/*
31122 + * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic
31123 + * changes to accomodate it in the kernel by ji.
31124 + */
31125 +
31126 +#include <asm/byteorder.h>
31127 +#include <linux/string.h>
31128 +
31129 +#include "openswan/ipsec_md5h.h"
31130 +
31131 +/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
31132 + */
31133 +
31134 +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
31135 +rights reserved.
31136 +
31137 +License to copy and use this software is granted provided that it
31138 +is identified as the "RSA Data Security, Inc. MD5 Message-Digest
31139 +Algorithm" in all material mentioning or referencing this software
31140 +or this function.
31141 +
31142 +License is also granted to make and use derivative works provided
31143 +that such works are identified as "derived from the RSA Data
31144 +Security, Inc. MD5 Message-Digest Algorithm" in all material
31145 +mentioning or referencing the derived work.
31146 +
31147 +RSA Data Security, Inc. makes no representations concerning either
31148 +the merchantability of this software or the suitability of this
31149 +software for any particular purpose. It is provided "as is"
31150 +without express or implied warranty of any kind.
31151 +
31152 +These notices must be retained in any copies of any part of this
31153 +documentation and/or software.
31154 + */
31155 +
31156 +/*
31157 + * Additions by JI
31158 + *
31159 + * HAVEMEMCOPY is defined if mem* routines are available
31160 + *
31161 + * HAVEHTON is defined if htons() and htonl() can be used
31162 + * for big/little endian conversions
31163 + *
31164 + */
31165 +
31166 +#define HAVEMEMCOPY
31167 +#ifdef __LITTLE_ENDIAN
31168 +#define LITTLENDIAN
31169 +#endif
31170 +#ifdef __BIG_ENDIAN
31171 +#define BIGENDIAN
31172 +#endif
31173 +
31174 +/* Constants for MD5Transform routine.
31175 + */
31176 +
31177 +#define S11 7
31178 +#define S12 12
31179 +#define S13 17
31180 +#define S14 22
31181 +#define S21 5
31182 +#define S22 9
31183 +#define S23 14
31184 +#define S24 20
31185 +#define S31 4
31186 +#define S32 11
31187 +#define S33 16
31188 +#define S34 23
31189 +#define S41 6
31190 +#define S42 10
31191 +#define S43 15
31192 +#define S44 21
31193 +
31194 +static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
31195 +
31196 +#ifdef LITTLEENDIAN
31197 +#define Encode MD5_memcpy
31198 +#define Decode MD5_memcpy
31199 +#else
31200 +static void Encode PROTO_LIST
31201 + ((unsigned char *, UINT4 *, unsigned int));
31202 +static void Decode PROTO_LIST
31203 + ((UINT4 *, unsigned char *, unsigned int));
31204 +#endif
31205 +
31206 +#ifdef HAVEMEMCOPY
31207 +/* no need to include <memory.h> here; <linux/string.h> defines these */
31208 +#define MD5_memcpy memcpy
31209 +#define MD5_memset memset
31210 +#else
31211 +#ifdef HAVEBCOPY
31212 +#define MD5_memcpy(_a,_b,_c) bcopy((_b),(_a),(_c))
31213 +#define MD5_memset(_a,_b,_c) bzero((_a),(_c))
31214 +#else
31215 +static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
31216 +static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
31217 +#endif
31218 +#endif
31219 +static unsigned char PADDING[64] = {
31220 + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31221 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31222 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
31223 +};
31224 +
31225 +/* F, G, H and I are basic MD5 functions.
31226 + */
31227 +#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
31228 +#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
31229 +#define H(x, y, z) ((x) ^ (y) ^ (z))
31230 +#define I(x, y, z) ((y) ^ ((x) | (~z)))
31231 +
31232 +/* ROTATE_LEFT rotates x left n bits.
31233 + */
31234 +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
31235 +
31236 +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
31237 +Rotation is separate from addition to prevent recomputation.
31238 + */
31239 +#define FF(a, b, c, d, x, s, ac) { \
31240 + (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
31241 + (a) = ROTATE_LEFT ((a), (s)); \
31242 + (a) += (b); \
31243 + }
31244 +#define GG(a, b, c, d, x, s, ac) { \
31245 + (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
31246 + (a) = ROTATE_LEFT ((a), (s)); \
31247 + (a) += (b); \
31248 + }
31249 +#define HH(a, b, c, d, x, s, ac) { \
31250 + (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
31251 + (a) = ROTATE_LEFT ((a), (s)); \
31252 + (a) += (b); \
31253 + }
31254 +#define II(a, b, c, d, x, s, ac) { \
31255 + (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
31256 + (a) = ROTATE_LEFT ((a), (s)); \
31257 + (a) += (b); \
31258 + }
31259 +
31260 +/*
31261 + * MD5 initialization. Begins an MD5 operation, writing a new context.
31262 + */
31263 +void osMD5Init(void *vcontext)
31264 +{
31265 + MD5_CTX *context = vcontext;
31266 +
31267 + context->count[0] = context->count[1] = 0;
31268 + /* Load magic initialization constants.*/
31269 + context->state[0] = 0x67452301;
31270 + context->state[1] = 0xefcdab89;
31271 + context->state[2] = 0x98badcfe;
31272 + context->state[3] = 0x10325476;
31273 +}
31274 +
31275 +/* MD5 block update operation. Continues an MD5 message-digest
31276 + operation, processing another message block, and updating the
31277 + context.
31278 + */
31279 +void osMD5Update (vcontext, input, inputLen)
31280 + void *vcontext;
31281 + unsigned char *input; /* input block */
31282 + __u32 inputLen; /* length of input block */
31283 +{
31284 + MD5_CTX *context = vcontext;
31285 + __u32 i;
31286 + unsigned int index, partLen;
31287 +
31288 + /* Compute number of bytes mod 64 */
31289 + index = (unsigned int)((context->count[0] >> 3) & 0x3F);
31290 +
31291 + /* Update number of bits */
31292 + if ((context->count[0] += ((UINT4)inputLen << 3))
31293 + < ((UINT4)inputLen << 3))
31294 + context->count[1]++;
31295 + context->count[1] += ((UINT4)inputLen >> 29);
31296 +
31297 + partLen = 64 - index;
31298 +
31299 + /* Transform as many times as possible.
31300 +*/
31301 + if (inputLen >= partLen) {
31302 + MD5_memcpy
31303 + ((POINTER)&context->buffer[index], (POINTER)input, partLen);
31304 + MD5Transform (context->state, context->buffer);
31305 +
31306 + for (i = partLen; i + 63 < inputLen; i += 64)
31307 + MD5Transform (context->state, &input[i]);
31308 +
31309 + index = 0;
31310 + }
31311 + else
31312 + i = 0;
31313 +
31314 + /* Buffer remaining input */
31315 + MD5_memcpy
31316 + ((POINTER)&context->buffer[index], (POINTER)&input[i],
31317 + inputLen-i);
31318 +}
31319 +
31320 +/* MD5 finalization. Ends an MD5 message-digest operation, writing the
31321 + the message digest and zeroizing the context.
31322 + */
31323 +void osMD5Final (digest, vcontext)
31324 +unsigned char digest[16]; /* message digest */
31325 +void *vcontext; /* context */
31326 +{
31327 + MD5_CTX *context = vcontext;
31328 + unsigned char bits[8];
31329 + unsigned int index, padLen;
31330 +
31331 + /* Save number of bits */
31332 + Encode (bits, context->count, 8);
31333 +
31334 + /* Pad out to 56 mod 64.
31335 +*/
31336 + index = (unsigned int)((context->count[0] >> 3) & 0x3f);
31337 + padLen = (index < 56) ? (56 - index) : (120 - index);
31338 + osMD5Update (context, PADDING, padLen);
31339 +
31340 + /* Append length (before padding) */
31341 + osMD5Update (context, bits, 8);
31342 +
31343 + if (digest != NULL) /* Bill Simpson's padding */
31344 + {
31345 + /* store state in digest */
31346 + Encode (digest, context->state, 16);
31347 +
31348 + /* Zeroize sensitive information.
31349 + */
31350 + MD5_memset ((POINTER)context, 0, sizeof (*context));
31351 + }
31352 +}
31353 +
31354 +/* MD5 basic transformation. Transforms state based on block.
31355 + */
31356 +static void MD5Transform (state, block)
31357 +UINT4 state[4];
31358 +unsigned char block[64];
31359 +{
31360 + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
31361 +
31362 + Decode (x, block, 64);
31363 +
31364 + /* Round 1 */
31365 + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
31366 + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
31367 + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
31368 + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
31369 + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
31370 + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
31371 + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
31372 + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
31373 + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
31374 + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
31375 + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
31376 + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
31377 + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
31378 + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
31379 + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
31380 + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
31381 +
31382 + /* Round 2 */
31383 + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
31384 + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
31385 + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
31386 + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
31387 + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
31388 + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
31389 + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
31390 + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
31391 + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
31392 + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
31393 + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
31394 + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
31395 + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
31396 + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
31397 + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
31398 + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
31399 +
31400 + /* Round 3 */
31401 + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
31402 + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
31403 + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
31404 + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
31405 + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
31406 + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
31407 + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
31408 + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
31409 + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
31410 + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
31411 + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
31412 + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
31413 + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
31414 + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
31415 + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
31416 + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
31417 +
31418 + /* Round 4 */
31419 + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
31420 + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
31421 + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
31422 + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
31423 + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
31424 + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
31425 + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
31426 + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
31427 + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
31428 + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
31429 + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
31430 + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
31431 + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
31432 + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
31433 + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
31434 + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
31435 +
31436 + state[0] += a;
31437 + state[1] += b;
31438 + state[2] += c;
31439 + state[3] += d;
31440 +
31441 + /* Zeroize sensitive information.
31442 +*/
31443 + MD5_memset ((POINTER)x, 0, sizeof (x));
31444 +}
31445 +
31446 +#ifndef LITTLEENDIAN
31447 +
31448 +/* Encodes input (UINT4) into output (unsigned char). Assumes len is
31449 + a multiple of 4.
31450 + */
31451 +static void Encode (output, input, len)
31452 +unsigned char *output;
31453 +UINT4 *input;
31454 +unsigned int len;
31455 +{
31456 + unsigned int i, j;
31457 +
31458 + for (i = 0, j = 0; j < len; i++, j += 4) {
31459 + output[j] = (unsigned char)(input[i] & 0xff);
31460 + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
31461 + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
31462 + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
31463 + }
31464 +}
31465 +
31466 +/* Decodes input (unsigned char) into output (UINT4). Assumes len is
31467 + a multiple of 4.
31468 + */
31469 +static void Decode (output, input, len)
31470 +UINT4 *output;
31471 +unsigned char *input;
31472 +unsigned int len;
31473 +{
31474 + unsigned int i, j;
31475 +
31476 + for (i = 0, j = 0; j < len; i++, j += 4)
31477 + output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
31478 + (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
31479 +}
31480 +
31481 +#endif
31482 +
31483 +#ifndef HAVEMEMCOPY
31484 +#ifndef HAVEBCOPY
31485 +/* Note: Replace "for loop" with standard memcpy if possible.
31486 + */
31487 +
31488 +static void MD5_memcpy (output, input, len)
31489 +POINTER output;
31490 +POINTER input;
31491 +unsigned int len;
31492 +{
31493 + unsigned int i;
31494 +
31495 + for (i = 0; i < len; i++)
31496 +
31497 + output[i] = input[i];
31498 +}
31499 +
31500 +/* Note: Replace "for loop" with standard memset if possible.
31501 + */
31502 +
31503 +static void MD5_memset (output, value, len)
31504 +POINTER output;
31505 +int value;
31506 +unsigned int len;
31507 +{
31508 + unsigned int i;
31509 +
31510 + for (i = 0; i < len; i++)
31511 + ((char *)output)[i] = (char)value;
31512 +}
31513 +#endif
31514 +#endif
31515 +
31516 +/*
31517 + * $Log: ipsec_md5c.c,v $
31518 + * Revision 1.10 2005/04/15 01:25:57 mcr
31519 + * minor fix to comments.
31520 + *
31521 + * Revision 1.9 2004/09/08 17:21:36 ken
31522 + * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
31523 + *
31524 + * Revision 1.8 2004/04/06 02:49:26 mcr
31525 + * pullup of algo code from alg-branch.
31526 + *
31527 + * Revision 1.7 2002/09/10 01:45:14 mcr
31528 + * changed type of MD5_CTX and SHA1_CTX to void * so that
31529 + * the function prototypes would match, and could be placed
31530 + * into a pointer to a function.
31531 + *
31532 + * Revision 1.6 2002/04/24 07:55:32 mcr
31533 + * #include patches and Makefiles for post-reorg compilation.
31534 + *
31535 + * Revision 1.5 2002/04/24 07:36:28 mcr
31536 + * Moved from ./klips/net/ipsec/ipsec_md5c.c,v
31537 + *
31538 + * Revision 1.4 1999/12/13 13:59:12 rgb
31539 + * Quick fix to argument size to Update bugs.
31540 + *
31541 + * Revision 1.3 1999/05/21 18:09:28 henry
31542 + * unnecessary <memory.h> include causes trouble in 2.2
31543 + *
31544 + * Revision 1.2 1999/04/06 04:54:26 rgb
31545 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
31546 + * patch shell fixes.
31547 + *
31548 + * Revision 1.1 1998/06/18 21:27:48 henry
31549 + * move sources from klips/src to klips/net/ipsec, to keep stupid
31550 + * kernel-build scripts happier in the presence of symlinks
31551 + *
31552 + * Revision 1.2 1998/04/23 20:54:02 rgb
31553 + * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
31554 + * verified.
31555 + *
31556 + * Revision 1.1 1998/04/09 03:06:08 henry
31557 + * sources moved up from linux/net/ipsec
31558 + *
31559 + * Revision 1.1.1.1 1998/04/08 05:35:04 henry
31560 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
31561 + *
31562 + * Revision 0.3 1996/11/20 14:48:53 ji
31563 + * Release update only.
31564 + *
31565 + * Revision 0.2 1996/11/02 00:18:33 ji
31566 + * First limited release.
31567 + *
31568 + *
31569 + */
31570 --- /dev/null Tue Mar 11 13:02:56 2003
31571 +++ linux/net/ipsec/ipsec_proc.c Mon Feb 9 13:51:03 2004
31572 @@ -0,0 +1,1172 @@
31573 +/*
31574 + * @(#) /proc file system interface code.
31575 + *
31576 + * Copyright (C) 1996, 1997 John Ioannidis.
31577 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
31578 + * 2001 Michael Richardson <mcr@freeswan.org>
31579 + *
31580 + * This program is free software; you can redistribute it and/or modify it
31581 + * under the terms of the GNU General Public License as published by the
31582 + * Free Software Foundation; either version 2 of the License, or (at your
31583 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
31584 + *
31585 + * This program is distributed in the hope that it will be useful, but
31586 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
31587 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
31588 + * for more details.
31589 + *
31590 + * Split out from ipsec_init.c version 1.70.
31591 + */
31592 +
31593 +char ipsec_proc_c_version[] = "RCSID $Id: ipsec_proc.c,v 1.41 2005/11/11 04:04:03 paul Exp $";
31594 +
31595 +
31596 +#ifndef AUTOCONF_INCLUDED
31597 +#include <linux/config.h>
31598 +#endif
31599 +#include <linux/version.h>
31600 +#define __NO_VERSION__
31601 +#include <linux/module.h>
31602 +#include <linux/kernel.h> /* printk() */
31603 +
31604 +#include "openswan/ipsec_kversion.h"
31605 +#include "openswan/ipsec_param.h"
31606 +
31607 +#ifdef MALLOC_SLAB
31608 +# include <linux/slab.h> /* kmalloc() */
31609 +#else /* MALLOC_SLAB */
31610 +# include <linux/malloc.h> /* kmalloc() */
31611 +#endif /* MALLOC_SLAB */
31612 +#include <linux/errno.h> /* error codes */
31613 +#include <linux/types.h> /* size_t */
31614 +#include <linux/interrupt.h> /* mark_bh */
31615 +
31616 +#include <linux/netdevice.h> /* struct device, and other headers */
31617 +#include <linux/etherdevice.h> /* eth_type_trans */
31618 +#include <linux/ip.h> /* struct iphdr */
31619 +#include <linux/in.h> /* struct sockaddr_in */
31620 +#include <linux/skbuff.h>
31621 +#include <asm/uaccess.h> /* copy_from_user */
31622 +#include <openswan.h>
31623 +#ifdef SPINLOCK
31624 +#ifdef SPINLOCK_23
31625 +#include <linux/spinlock.h> /* *lock* */
31626 +#else /* SPINLOCK_23 */
31627 +#include <asm/spinlock.h> /* *lock* */
31628 +#endif /* SPINLOCK_23 */
31629 +#endif /* SPINLOCK */
31630 +
31631 +#include <net/ip.h>
31632 +#ifdef CONFIG_PROC_FS
31633 +#include <linux/proc_fs.h>
31634 +#endif /* CONFIG_PROC_FS */
31635 +#ifdef NETLINK_SOCK
31636 +#include <linux/netlink.h>
31637 +#else
31638 +#include <net/netlink.h>
31639 +#endif
31640 +
31641 +#include "openswan/radij.h"
31642 +
31643 +#include "openswan/ipsec_life.h"
31644 +#include "openswan/ipsec_stats.h"
31645 +#include "openswan/ipsec_sa.h"
31646 +
31647 +#include "openswan/ipsec_encap.h"
31648 +#include "openswan/ipsec_radij.h"
31649 +#include "openswan/ipsec_xform.h"
31650 +#include "openswan/ipsec_tunnel.h"
31651 +#include "openswan/ipsec_xmit.h"
31652 +
31653 +#include "openswan/ipsec_rcv.h"
31654 +#include "openswan/ipsec_ah.h"
31655 +#include "openswan/ipsec_esp.h"
31656 +#include "openswan/ipsec_kern24.h"
31657 +
31658 +#ifdef CONFIG_KLIPS_IPCOMP
31659 +#include "openswan/ipcomp.h"
31660 +#endif /* CONFIG_KLIPS_IPCOMP */
31661 +
31662 +#include "openswan/ipsec_proto.h"
31663 +
31664 +#include <openswan/pfkeyv2.h>
31665 +#include <openswan/pfkey.h>
31666 +
31667 +#ifdef CONFIG_PROC_FS
31668 +
31669 +#ifdef IPSEC_PROC_SUBDIRS
31670 +static struct proc_dir_entry *proc_net_ipsec_dir = NULL;
31671 +static struct proc_dir_entry *proc_eroute_dir = NULL;
31672 +static struct proc_dir_entry *proc_spi_dir = NULL;
31673 +static struct proc_dir_entry *proc_spigrp_dir = NULL;
31674 +static struct proc_dir_entry *proc_birth_dir = NULL;
31675 +static struct proc_dir_entry *proc_stats_dir = NULL;
31676 +#endif
31677 +
31678 +struct ipsec_birth_reply ipsec_ipv4_birth_packet;
31679 +struct ipsec_birth_reply ipsec_ipv6_birth_packet;
31680 +
31681 +#ifdef CONFIG_KLIPS_DEBUG
31682 +int debug_esp = 0;
31683 +int debug_ah = 0;
31684 +#endif /* CONFIG_KLIPS_DEBUG */
31685 +
31686 +#define DECREMENT_UNSIGNED(X, amount) ((amount < (X)) ? (X)-amount : 0)
31687 +
31688 +extern int ipsec_xform_get_info(char *buffer, char **start,
31689 + off_t offset, int length IPSEC_PROC_LAST_ARG);
31690 +
31691 +IPSEC_PROCFS_DEBUG_NO_STATIC
31692 +int
31693 +ipsec_eroute_get_info(char *buffer,
31694 + char **start,
31695 + off_t offset,
31696 + int length IPSEC_PROC_LAST_ARG)
31697 +{
31698 + struct wsbuf w = {buffer, length, offset, 0, 0};
31699 +
31700 +#ifdef CONFIG_KLIPS_DEBUG
31701 + if (debug_radij & DB_RJ_DUMPTREES)
31702 + rj_dumptrees(); /* XXXXXXXXX */
31703 +#endif /* CONFIG_KLIPS_DEBUG */
31704 +
31705 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
31706 + "klips_debug:ipsec_eroute_get_info: "
31707 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
31708 + buffer,
31709 + *start,
31710 + (int)offset,
31711 + length);
31712 +
31713 + spin_lock_bh(&eroute_lock);
31714 +
31715 + rj_walktree(rnh, ipsec_rj_walker_procprint, &w);
31716 +/* rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */
31717 +
31718 + spin_unlock_bh(&eroute_lock);
31719 +
31720 + *start = buffer + (offset - w.begin); /* Start of wanted data */
31721 + return w.len - (offset - w.begin);
31722 +}
31723 +
31724 +IPSEC_PROCFS_DEBUG_NO_STATIC
31725 +int
31726 +ipsec_spi_get_info(char *buffer,
31727 + char **start,
31728 + off_t offset,
31729 + int length IPSEC_PROC_LAST_ARG)
31730 +{
31731 + const int max_content = length > 0? length-1 : 0;
31732 + int len = 0;
31733 + off_t begin = 0;
31734 + int i;
31735 + struct ipsec_sa *sa_p;
31736 + char sa[SATOT_BUF];
31737 + char buf_s[SUBNETTOA_BUF];
31738 + char buf_d[SUBNETTOA_BUF];
31739 + size_t sa_len;
31740 +
31741 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
31742 + "klips_debug:ipsec_spi_get_info: "
31743 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
31744 + buffer,
31745 + *start,
31746 + (int)offset,
31747 + length);
31748 +
31749 + spin_lock_bh(&tdb_lock);
31750 +
31751 + for (i = 0; i < SADB_HASHMOD; i++) {
31752 + for (sa_p = ipsec_sadb_hash[i];
31753 + sa_p;
31754 + sa_p = sa_p->ips_hnext) {
31755 + atomic_inc(&sa_p->ips_refcount);
31756 + sa_len = satot(&sa_p->ips_said, 'x', sa, sizeof(sa));
31757 + len += ipsec_snprintf(buffer+len, length-len, "%s ",
31758 + sa_len ? sa : " (error)");
31759 +
31760 + len += ipsec_snprintf(buffer+len, length-len, "%s%s%s",
31761 + IPS_XFORM_NAME(sa_p));
31762 +
31763 + len += ipsec_snprintf(buffer+len, length-len, ": dir=%s",
31764 + (sa_p->ips_flags & EMT_INBOUND) ?
31765 + "in " : "out");
31766 +
31767 + if(sa_p->ips_addr_s) {
31768 + addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr,
31769 + 0, buf_s, sizeof(buf_s));
31770 + len += ipsec_snprintf(buffer+len, length-len, " src=%s",
31771 + buf_s);
31772 + }
31773 +
31774 + if((sa_p->ips_said.proto == IPPROTO_IPIP)
31775 + && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) {
31776 + subnettoa(sa_p->ips_flow_s.u.v4.sin_addr,
31777 + sa_p->ips_mask_s.u.v4.sin_addr,
31778 + 0,
31779 + buf_s,
31780 + sizeof(buf_s));
31781 +
31782 + subnettoa(sa_p->ips_flow_d.u.v4.sin_addr,
31783 + sa_p->ips_mask_d.u.v4.sin_addr,
31784 + 0,
31785 + buf_d,
31786 + sizeof(buf_d));
31787 +
31788 + len += ipsec_snprintf(buffer+len, length-len, " policy=%s->%s",
31789 + buf_s, buf_d);
31790 + }
31791 +
31792 + if(sa_p->ips_iv_bits) {
31793 + int j;
31794 + len += ipsec_snprintf(buffer+len, length-len, " iv_bits=%dbits iv=0x",
31795 + sa_p->ips_iv_bits);
31796 +
31797 + for(j = 0; j < sa_p->ips_iv_bits / 8; j++) {
31798 + len += ipsec_snprintf(buffer+len, length-len, "%02x",
31799 + (__u32)((__u8*)(sa_p->ips_iv))[j]);
31800 + }
31801 + }
31802 +
31803 + if(sa_p->ips_encalg || sa_p->ips_authalg) {
31804 + if(sa_p->ips_replaywin) {
31805 + len += ipsec_snprintf(buffer+len, length-len, " ooowin=%d",
31806 + sa_p->ips_replaywin);
31807 + }
31808 + if(sa_p->ips_errs.ips_replaywin_errs) {
31809 + len += ipsec_snprintf(buffer+len, length-len, " ooo_errs=%d",
31810 + sa_p->ips_errs.ips_replaywin_errs);
31811 + }
31812 + if(sa_p->ips_replaywin_lastseq) {
31813 + len += ipsec_snprintf(buffer+len, length-len, " seq=%d",
31814 + sa_p->ips_replaywin_lastseq);
31815 + }
31816 + if(sa_p->ips_replaywin_bitmap) {
31817 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
31818 + len += ipsec_snprintf(buffer+len, length-len, " bit=0x%Lx",
31819 + sa_p->ips_replaywin_bitmap);
31820 +#else
31821 + len += ipsec_snprintf(buffer+len, length-len, " bit=0x%x%08x",
31822 + (__u32)(sa_p->ips_replaywin_bitmap >> 32),
31823 + (__u32)sa_p->ips_replaywin_bitmap);
31824 +#endif
31825 + }
31826 + if(sa_p->ips_replaywin_maxdiff) {
31827 + len += ipsec_snprintf(buffer+len, length-len, " max_seq_diff=%d",
31828 + sa_p->ips_replaywin_maxdiff);
31829 + }
31830 + }
31831 + if(sa_p->ips_flags & ~EMT_INBOUND) {
31832 + len += ipsec_snprintf(buffer+len, length-len, " flags=0x%x",
31833 + sa_p->ips_flags & ~EMT_INBOUND);
31834 + len += ipsec_snprintf(buffer+len, length-len, "<");
31835 + /* flag printing goes here */
31836 + len += ipsec_snprintf(buffer+len, length-len, ">");
31837 + }
31838 + if(sa_p->ips_auth_bits) {
31839 + len += ipsec_snprintf(buffer+len, length-len, " alen=%d",
31840 + sa_p->ips_auth_bits);
31841 + }
31842 + if(sa_p->ips_key_bits_a) {
31843 + len += ipsec_snprintf(buffer+len, length-len, " aklen=%d",
31844 + sa_p->ips_key_bits_a);
31845 + }
31846 + if(sa_p->ips_errs.ips_auth_errs) {
31847 + len += ipsec_snprintf(buffer+len, length-len, " auth_errs=%d",
31848 + sa_p->ips_errs.ips_auth_errs);
31849 + }
31850 + if(sa_p->ips_key_bits_e) {
31851 + len += ipsec_snprintf(buffer+len, length-len, " eklen=%d",
31852 + sa_p->ips_key_bits_e);
31853 + }
31854 + if(sa_p->ips_errs.ips_encsize_errs) {
31855 + len += ipsec_snprintf(buffer+len, length-len, " encr_size_errs=%d",
31856 + sa_p->ips_errs.ips_encsize_errs);
31857 + }
31858 + if(sa_p->ips_errs.ips_encpad_errs) {
31859 + len += ipsec_snprintf(buffer+len, length-len, " encr_pad_errs=%d",
31860 + sa_p->ips_errs.ips_encpad_errs);
31861 + }
31862 +
31863 + len += ipsec_snprintf(buffer+len, length-len, " life(c,s,h)=");
31864 +
31865 + len += ipsec_lifetime_format(buffer + len,
31866 + length - len,
31867 + "alloc",
31868 + ipsec_life_countbased,
31869 + &sa_p->ips_life.ipl_allocations);
31870 +
31871 + len += ipsec_lifetime_format(buffer + len,
31872 + length - len,
31873 + "bytes",
31874 + ipsec_life_countbased,
31875 + &sa_p->ips_life.ipl_bytes);
31876 +
31877 + len += ipsec_lifetime_format(buffer + len,
31878 + length - len,
31879 + "addtime",
31880 + ipsec_life_timebased,
31881 + &sa_p->ips_life.ipl_addtime);
31882 +
31883 + len += ipsec_lifetime_format(buffer + len,
31884 + length - len,
31885 + "usetime",
31886 + ipsec_life_timebased,
31887 + &sa_p->ips_life.ipl_usetime);
31888 +
31889 + len += ipsec_lifetime_format(buffer + len,
31890 + length - len,
31891 + "packets",
31892 + ipsec_life_countbased,
31893 + &sa_p->ips_life.ipl_packets);
31894 +
31895 + if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */
31896 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
31897 + len += ipsec_snprintf(buffer+len, length-len, " idle=%Ld",
31898 + jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last);
31899 +#else
31900 + len += ipsec_snprintf(buffer+len, length-len, " idle=%lu",
31901 + jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last);
31902 +#endif
31903 + }
31904 +
31905 +#ifdef CONFIG_KLIPS_IPCOMP
31906 + if(sa_p->ips_said.proto == IPPROTO_COMP &&
31907 + (sa_p->ips_comp_ratio_dbytes ||
31908 + sa_p->ips_comp_ratio_cbytes)) {
31909 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
31910 + len += ipsec_snprintf(buffer+len, length-len, " ratio=%Ld:%Ld",
31911 + sa_p->ips_comp_ratio_dbytes,
31912 + sa_p->ips_comp_ratio_cbytes);
31913 +#else
31914 + len += ipsec_snprintf(buffer+len, length-len, " ratio=%lu:%lu",
31915 + (unsigned long)sa_p->ips_comp_ratio_dbytes,
31916 + (unsigned long)sa_p->ips_comp_ratio_cbytes);
31917 +#endif
31918 + }
31919 +#endif /* CONFIG_KLIPS_IPCOMP */
31920 +
31921 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
31922 + {
31923 + char *natttype_name;
31924 +
31925 + switch(sa_p->ips_natt_type)
31926 + {
31927 + case 0:
31928 + natttype_name="none";
31929 + break;
31930 + case ESPINUDP_WITH_NON_IKE:
31931 + natttype_name="nonike";
31932 + break;
31933 + case ESPINUDP_WITH_NON_ESP:
31934 + natttype_name="nonesp";
31935 + break;
31936 + default:
31937 + natttype_name = "unknown";
31938 + break;
31939 + }
31940 +
31941 + len += ipsec_snprintf(buffer + len, length-len, " natencap=%s",
31942 + natttype_name);
31943 +
31944 + len += ipsec_snprintf(buffer + len, length-len, " natsport=%d",
31945 + sa_p->ips_natt_sport);
31946 +
31947 + len += ipsec_snprintf(buffer + len,length-len, " natdport=%d",
31948 + sa_p->ips_natt_dport);
31949 + }
31950 +#else
31951 + len += ipsec_snprintf(buffer + len, length-len, " natencap=na");
31952 +#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
31953 +
31954 + len += ipsec_snprintf(buffer + len,length-len, " refcount=%d",
31955 + atomic_read(&sa_p->ips_refcount));
31956 +
31957 + len += ipsec_snprintf(buffer+len, length-len, " ref=%d",
31958 + sa_p->ips_ref);
31959 +#ifdef CONFIG_KLIPS_DEBUG
31960 + if(debug_xform) {
31961 + len += ipsec_snprintf(buffer+len, length-len, " reftable=%lu refentry=%lu",
31962 + (unsigned long)IPsecSAref2table(sa_p->ips_ref),
31963 + (unsigned long)IPsecSAref2entry(sa_p->ips_ref));
31964 + }
31965 +#endif /* CONFIG_KLIPS_DEBUG */
31966 +
31967 + len += ipsec_snprintf(buffer+len, length-len, "\n");
31968 +
31969 + atomic_dec(&sa_p->ips_refcount);
31970 +
31971 + if (len >= max_content) {
31972 + /* we've done all that can fit -- stop loops */
31973 + len = max_content; /* truncate crap */
31974 + goto done_spi_i;
31975 + } else {
31976 + const off_t pos = begin + len; /* file position of end of what we've generated */
31977 +
31978 + if (pos <= offset) {
31979 + /* all is before first interesting character:
31980 + * discard, but note where we are.
31981 + */
31982 + len = 0;
31983 + begin = pos;
31984 + }
31985 + }
31986 + }
31987 + }
31988 +
31989 +done_spi_i:
31990 + spin_unlock_bh(&tdb_lock);
31991 +
31992 + *start = buffer + (offset - begin); /* Start of wanted data */
31993 + return len - (offset - begin);
31994 +}
31995 +
31996 +IPSEC_PROCFS_DEBUG_NO_STATIC
31997 +int
31998 +ipsec_spigrp_get_info(char *buffer,
31999 + char **start,
32000 + off_t offset,
32001 + int length IPSEC_PROC_LAST_ARG)
32002 +{
32003 + /* Limit of useful snprintf output */
32004 + const int max_content = length > 0? length-1 : 0;
32005 +
32006 + int len = 0;
32007 + off_t begin = 0;
32008 + int i;
32009 + struct ipsec_sa *sa_p, *sa_p2;
32010 + char sa[SATOT_BUF];
32011 + size_t sa_len;
32012 +
32013 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32014 + "klips_debug:ipsec_spigrp_get_info: "
32015 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32016 + buffer,
32017 + *start,
32018 + (int)offset,
32019 + length);
32020 +
32021 + spin_lock_bh(&tdb_lock);
32022 +
32023 + for (i = 0; i < SADB_HASHMOD; i++) {
32024 + for (sa_p = ipsec_sadb_hash[i];
32025 + sa_p != NULL;
32026 + sa_p = sa_p->ips_hnext)
32027 + {
32028 + atomic_inc(&sa_p->ips_refcount);
32029 + if(sa_p->ips_inext == NULL) {
32030 + sa_p2 = sa_p;
32031 + while(sa_p2 != NULL) {
32032 + atomic_inc(&sa_p2->ips_refcount);
32033 + sa_len = satot(&sa_p2->ips_said,
32034 + 'x', sa, sizeof(sa));
32035 +
32036 + len += ipsec_snprintf(buffer+len, length-len, "%s ",
32037 + sa_len ? sa : " (error)");
32038 + atomic_dec(&sa_p2->ips_refcount);
32039 + sa_p2 = sa_p2->ips_onext;
32040 + }
32041 + len += ipsec_snprintf(buffer+len, length-len, "\n");
32042 + }
32043 +
32044 + atomic_dec(&sa_p->ips_refcount);
32045 +
32046 + if (len >= max_content) {
32047 + /* we've done all that can fit -- stop loops */
32048 + len = max_content; /* truncate crap */
32049 + goto done_spigrp_i;
32050 + } else {
32051 + const off_t pos = begin + len;
32052 +
32053 + if (pos <= offset) {
32054 + /* all is before first interesting character:
32055 + * discard, but note where we are.
32056 + */
32057 + len = 0;
32058 + begin = pos;
32059 + }
32060 + }
32061 + }
32062 + }
32063 +
32064 +done_spigrp_i:
32065 + spin_unlock_bh(&tdb_lock);
32066 +
32067 + *start = buffer + (offset - begin); /* Start of wanted data */
32068 + return len - (offset - begin);
32069 +}
32070 +
32071 +
32072 +IPSEC_PROCFS_DEBUG_NO_STATIC
32073 +int
32074 +ipsec_tncfg_get_info(char *buffer,
32075 + char **start,
32076 + off_t offset,
32077 + int length IPSEC_PROC_LAST_ARG)
32078 +{
32079 + /* limit of useful snprintf output */
32080 + const int max_content = length > 0? length-1 : 0;
32081 + int len = 0;
32082 + off_t begin = 0;
32083 + int i;
32084 + char name[9];
32085 + struct net_device *dev, *privdev;
32086 + struct ipsecpriv *priv;
32087 +
32088 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32089 + "klips_debug:ipsec_tncfg_get_info: "
32090 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32091 + buffer,
32092 + *start,
32093 + (int)offset,
32094 + length);
32095 +
32096 + for(i = 0; i < IPSEC_NUM_IF; i++) {
32097 + ipsec_snprintf(name, (ssize_t) sizeof(name), IPSEC_DEV_FORMAT, i);
32098 + dev = __ipsec_dev_get(name);
32099 + if(dev) {
32100 + priv = (struct ipsecpriv *)(dev->priv);
32101 + len += ipsec_snprintf(buffer+len, length-len, "%s",
32102 + dev->name);
32103 + if(priv) {
32104 + privdev = (struct net_device *)(priv->dev);
32105 + len += ipsec_snprintf(buffer+len, length-len, " -> %s",
32106 + privdev ? privdev->name : "NULL");
32107 + len += ipsec_snprintf(buffer+len, length-len, " mtu=%d(%d) -> %d",
32108 + dev->mtu,
32109 + priv->mtu,
32110 + privdev ? privdev->mtu : 0);
32111 + } else {
32112 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32113 + "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n",
32114 + dev->name);
32115 + }
32116 + len += ipsec_snprintf(buffer+len, length-len, "\n");
32117 +
32118 + if (len >= max_content) {
32119 + /* we've done all that can fit -- stop loop */
32120 + len = max_content; /* truncate crap */
32121 + break;
32122 + } else {
32123 + const off_t pos = begin + len;
32124 + if (pos <= offset) {
32125 + len = 0;
32126 + begin = pos;
32127 + }
32128 + }
32129 + }
32130 + }
32131 + *start = buffer + (offset - begin); /* Start of wanted data */
32132 + len -= (offset - begin); /* Start slop */
32133 + if (len > length)
32134 + len = length;
32135 + return len;
32136 +}
32137 +
32138 +IPSEC_PROCFS_DEBUG_NO_STATIC
32139 +int
32140 +ipsec_version_get_info(char *buffer,
32141 + char **start,
32142 + off_t offset,
32143 + int length IPSEC_PROC_LAST_ARG)
32144 +{
32145 + int len = 0;
32146 + off_t begin = 0;
32147 +
32148 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32149 + "klips_debug:ipsec_version_get_info: "
32150 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32151 + buffer,
32152 + *start,
32153 + (int)offset,
32154 + length);
32155 +
32156 + len += ipsec_snprintf(buffer + len,length-len, "Openswan version: %s\n",
32157 + ipsec_version_code());
32158 +#if 0
32159 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32160 + "klips_debug:ipsec_version_get_info: "
32161 + "ipsec_init version: %s\n",
32162 + ipsec_init_c_version);
32163 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32164 + "klips_debug:ipsec_version_get_info: "
32165 + "ipsec_tunnel version: %s\n",
32166 + ipsec_tunnel_c_version);
32167 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32168 + "klips_debug:ipsec_version_get_info: "
32169 + "ipsec_netlink version: %s\n",
32170 + ipsec_netlink_c_version);
32171 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32172 + "klips_debug:ipsec_version_get_info: "
32173 + "radij_c_version: %s\n",
32174 + radij_c_version);
32175 +#endif
32176 +
32177 +
32178 + *start = buffer + (offset - begin); /* Start of wanted data */
32179 + len -= (offset - begin); /* Start slop */
32180 + if (len > length)
32181 + len = length;
32182 + return len;
32183 +}
32184 +
32185 +IPSEC_PROCFS_DEBUG_NO_STATIC
32186 +int
32187 +ipsec_natt_get_info(char *buffer,
32188 + char **start,
32189 + off_t offset,
32190 + int length IPSEC_PROC_LAST_ARG)
32191 +{
32192 + int len = 0;
32193 + off_t begin = 0;
32194 +
32195 + len += ipsec_snprintf(buffer + len,
32196 + length-len, "%d\n",
32197 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
32198 + 1
32199 +#else
32200 + 0
32201 +#endif
32202 + );
32203 +
32204 + *start = buffer + (offset - begin); /* Start of wanted data */
32205 + len -= (offset - begin); /* Start slop */
32206 + if (len > length)
32207 + len = length;
32208 + return len;
32209 +}
32210 +
32211 +IPSEC_PROCFS_DEBUG_NO_STATIC
32212 +int
32213 +ipsec_birth_info(char *page,
32214 + char **start,
32215 + off_t offset,
32216 + int count,
32217 + int *eof,
32218 + void *data)
32219 +{
32220 + struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
32221 + int len;
32222 +
32223 + if(offset >= ibr->packet_template_len) {
32224 + if(eof) {
32225 + *eof=1;
32226 + }
32227 + return 0;
32228 + }
32229 +
32230 + len = ibr->packet_template_len;
32231 + len -= offset;
32232 + if (len > count)
32233 + len = count;
32234 +
32235 + memcpy(page + offset, ibr->packet_template+offset, len);
32236 +
32237 + return len;
32238 +}
32239 +
32240 +IPSEC_PROCFS_DEBUG_NO_STATIC
32241 +int
32242 +ipsec_birth_set(struct file *file, const char *buffer,
32243 + unsigned long count, void *data)
32244 +{
32245 + struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
32246 + int len;
32247 +
32248 + KLIPS_INC_USE;
32249 + if(count > IPSEC_BIRTH_TEMPLATE_MAXLEN) {
32250 + len = IPSEC_BIRTH_TEMPLATE_MAXLEN;
32251 + } else {
32252 + len = count;
32253 + }
32254 +
32255 + if(copy_from_user(ibr->packet_template, buffer, len)) {
32256 + KLIPS_DEC_USE;
32257 + return -EFAULT;
32258 + }
32259 + ibr->packet_template_len = len;
32260 +
32261 + KLIPS_DEC_USE;
32262 +
32263 + return len;
32264 +}
32265 +
32266 +
32267 +#ifdef CONFIG_KLIPS_DEBUG
32268 +IPSEC_PROCFS_DEBUG_NO_STATIC
32269 +int
32270 +ipsec_klipsdebug_get_info(char *buffer,
32271 + char **start,
32272 + off_t offset,
32273 + int length IPSEC_PROC_LAST_ARG)
32274 +{
32275 + int len = 0;
32276 + off_t begin = 0;
32277 +
32278 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32279 + "klips_debug:ipsec_klipsdebug_get_info: "
32280 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32281 + buffer,
32282 + *start,
32283 + (int)offset,
32284 + length);
32285 +
32286 + len += ipsec_snprintf(buffer+len, length-len, "debug_tunnel=%08x.\n", debug_tunnel);
32287 + len += ipsec_snprintf(buffer+len, length-len, "debug_xform=%08x.\n", debug_xform);
32288 + len += ipsec_snprintf(buffer+len, length-len, "debug_eroute=%08x.\n", debug_eroute);
32289 + len += ipsec_snprintf(buffer+len, length-len, "debug_spi=%08x.\n", debug_spi);
32290 + len += ipsec_snprintf(buffer+len, length-len, "debug_radij=%08x.\n", debug_radij);
32291 + len += ipsec_snprintf(buffer+len, length-len, "debug_esp=%08x.\n", debug_esp);
32292 + len += ipsec_snprintf(buffer+len, length-len, "debug_ah=%08x.\n", debug_ah);
32293 + len += ipsec_snprintf(buffer+len, length-len, "debug_rcv=%08x.\n", debug_rcv);
32294 + len += ipsec_snprintf(buffer+len, length-len, "debug_pfkey=%08x.\n", debug_pfkey);
32295 +
32296 + *start = buffer + (offset - begin); /* Start of wanted data */
32297 + len -= (offset - begin); /* Start slop */
32298 + if (len > length)
32299 + len = length;
32300 + return len;
32301 +}
32302 +#endif /* CONFIG_KLIPS_DEBUG */
32303 +
32304 +IPSEC_PROCFS_DEBUG_NO_STATIC
32305 +int
32306 +ipsec_stats_get_int_info(char *buffer,
32307 + char **start,
32308 + off_t offset,
32309 + int length,
32310 + int *eof,
32311 + void *data)
32312 +{
32313 +
32314 + const int max_content = length > 0? length-1 : 0;
32315 + int len = 0;
32316 + int *thing;
32317 +
32318 + thing = (int *)data;
32319 +
32320 + len = ipsec_snprintf(buffer+len, length-len, "%08x\n", *thing);
32321 +
32322 + if (len >= max_content)
32323 + len = max_content; /* truncate crap */
32324 +
32325 + *start = buffer + offset; /* Start of wanted data */
32326 + return len > offset? len - offset : 0;
32327 +
32328 +}
32329 +
32330 +#ifndef PROC_FS_2325
32331 +struct proc_dir_entry ipsec_eroute =
32332 +{
32333 + 0,
32334 + 12, "ipsec_eroute",
32335 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32336 + &proc_net_inode_operations,
32337 + ipsec_eroute_get_info,
32338 + NULL, NULL, NULL, NULL, NULL
32339 +};
32340 +
32341 +struct proc_dir_entry ipsec_spi =
32342 +{
32343 + 0,
32344 + 9, "ipsec_spi",
32345 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32346 + &proc_net_inode_operations,
32347 + ipsec_spi_get_info,
32348 + NULL, NULL, NULL, NULL, NULL
32349 +};
32350 +
32351 +struct proc_dir_entry ipsec_spigrp =
32352 +{
32353 + 0,
32354 + 12, "ipsec_spigrp",
32355 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32356 + &proc_net_inode_operations,
32357 + ipsec_spigrp_get_info,
32358 + NULL, NULL, NULL, NULL, NULL
32359 +};
32360 +
32361 +struct proc_dir_entry ipsec_tncfg =
32362 +{
32363 + 0,
32364 + 11, "ipsec_tncfg",
32365 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32366 + &proc_net_inode_operations,
32367 + ipsec_tncfg_get_info,
32368 + NULL, NULL, NULL, NULL, NULL
32369 +};
32370 +
32371 +struct proc_dir_entry ipsec_version =
32372 +{
32373 + 0,
32374 + 13, "ipsec_version",
32375 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32376 + &proc_net_inode_operations,
32377 + ipsec_version_get_info,
32378 + NULL, NULL, NULL, NULL, NULL
32379 +};
32380 +
32381 +#ifdef CONFIG_KLIPS_DEBUG
32382 +struct proc_dir_entry ipsec_klipsdebug =
32383 +{
32384 + 0,
32385 + 16, "ipsec_klipsdebug",
32386 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32387 + &proc_net_inode_operations,
32388 + ipsec_klipsdebug_get_info,
32389 + NULL, NULL, NULL, NULL, NULL
32390 +};
32391 +#endif /* CONFIG_KLIPS_DEBUG */
32392 +#endif /* !PROC_FS_2325 */
32393 +#endif /* CONFIG_PROC_FS */
32394 +
32395 +#if defined(PROC_FS_2325)
32396 +struct ipsec_proc_list {
32397 + char *name;
32398 + struct proc_dir_entry **parent;
32399 + struct proc_dir_entry **dir;
32400 + read_proc_t *readthing;
32401 + write_proc_t *writething;
32402 + void *data;
32403 +};
32404 +static struct ipsec_proc_list proc_items[]={
32405 +#ifdef CONFIG_KLIPS_DEBUG
32406 + {"klipsdebug", &proc_net_ipsec_dir, NULL, ipsec_klipsdebug_get_info, NULL, NULL},
32407 +#endif
32408 + {"eroute", &proc_net_ipsec_dir, &proc_eroute_dir, NULL, NULL, NULL},
32409 + {"all", &proc_eroute_dir, NULL, ipsec_eroute_get_info, NULL, NULL},
32410 + {"spi", &proc_net_ipsec_dir, &proc_spi_dir, NULL, NULL, NULL},
32411 + {"all", &proc_spi_dir, NULL, ipsec_spi_get_info, NULL, NULL},
32412 + {"spigrp", &proc_net_ipsec_dir, &proc_spigrp_dir, NULL, NULL, NULL},
32413 + {"all", &proc_spigrp_dir, NULL, ipsec_spigrp_get_info, NULL, NULL},
32414 + {"birth", &proc_net_ipsec_dir, &proc_birth_dir, NULL, NULL, NULL},
32415 + {"ipv4", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv4_birth_packet},
32416 + {"ipv6", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv6_birth_packet},
32417 + {"tncfg", &proc_net_ipsec_dir, NULL, ipsec_tncfg_get_info, NULL, NULL},
32418 + {"xforms", &proc_net_ipsec_dir, NULL, ipsec_xform_get_info, NULL, NULL},
32419 + {"stats", &proc_net_ipsec_dir, &proc_stats_dir, NULL, NULL, NULL},
32420 + {"trap_count", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_count},
32421 + {"trap_sendcount", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_sendcount},
32422 + {"natt", &proc_net_ipsec_dir, NULL, ipsec_natt_get_info, NULL, NULL},
32423 + {"version", &proc_net_ipsec_dir, NULL, ipsec_version_get_info, NULL, NULL},
32424 + {NULL, NULL, NULL, NULL, NULL, NULL}
32425 +};
32426 +#endif
32427 +
32428 +int
32429 +ipsec_proc_init()
32430 +{
32431 + int error = 0;
32432 +#ifdef IPSEC_PROC_SUBDIRS
32433 + struct proc_dir_entry *item;
32434 +#endif
32435 +
32436 + /*
32437 + * just complain because pluto won't run without /proc!
32438 + */
32439 +#ifndef CONFIG_PROC_FS
32440 +#error You must have PROC_FS built in to use KLIPS
32441 +#endif
32442 +
32443 + /* for 2.0 kernels */
32444 +#if !defined(PROC_FS_2325) && !defined(PROC_FS_21)
32445 + error |= proc_register_dynamic(&proc_net, &ipsec_eroute);
32446 + error |= proc_register_dynamic(&proc_net, &ipsec_spi);
32447 + error |= proc_register_dynamic(&proc_net, &ipsec_spigrp);
32448 + error |= proc_register_dynamic(&proc_net, &ipsec_tncfg);
32449 + error |= proc_register_dynamic(&proc_net, &ipsec_version);
32450 +#ifdef CONFIG_KLIPS_DEBUG
32451 + error |= proc_register_dynamic(&proc_net, &ipsec_klipsdebug);
32452 +#endif /* CONFIG_KLIPS_DEBUG */
32453 +#endif
32454 +
32455 + /* for 2.2 kernels */
32456 +#if !defined(PROC_FS_2325) && defined(PROC_FS_21)
32457 + error |= proc_register(proc_net, &ipsec_eroute);
32458 + error |= proc_register(proc_net, &ipsec_spi);
32459 + error |= proc_register(proc_net, &ipsec_spigrp);
32460 + error |= proc_register(proc_net, &ipsec_tncfg);
32461 + error |= proc_register(proc_net, &ipsec_version);
32462 +#ifdef CONFIG_KLIPS_DEBUG
32463 + error |= proc_register(proc_net, &ipsec_klipsdebug);
32464 +#endif /* CONFIG_KLIPS_DEBUG */
32465 +#endif
32466 +
32467 + /* for 2.4 kernels */
32468 +#if defined(PROC_FS_2325)
32469 + /* create /proc/net/ipsec */
32470 +
32471 + /* zero these out before we initialize /proc/net/ipsec/birth/stuff */
32472 + memset(&ipsec_ipv4_birth_packet, 0, sizeof(struct ipsec_birth_reply));
32473 + memset(&ipsec_ipv6_birth_packet, 0, sizeof(struct ipsec_birth_reply));
32474 +
32475 + proc_net_ipsec_dir = proc_mkdir("ipsec", proc_net);
32476 + if(proc_net_ipsec_dir == NULL) {
32477 + /* no point in continuing */
32478 + return 1;
32479 + }
32480 +
32481 + {
32482 + struct ipsec_proc_list *it;
32483 +
32484 + it=proc_items;
32485 + while(it->name!=NULL) {
32486 + if(it->dir) {
32487 + /* make a dir instead */
32488 + item = proc_mkdir(it->name, *it->parent);
32489 + *it->dir = item;
32490 + } else {
32491 + item = create_proc_entry(it->name, 0400, *it->parent);
32492 + }
32493 + if(item) {
32494 + item->read_proc = it->readthing;
32495 + item->write_proc = it->writething;
32496 + item->data = it->data;
32497 +#ifdef MODULE
32498 + item->owner = THIS_MODULE;
32499 +#endif
32500 + } else {
32501 + error |= 1;
32502 + }
32503 + it++;
32504 + }
32505 + }
32506 +
32507 + /* now create some symlinks to provide compatibility */
32508 + proc_symlink("ipsec_eroute", proc_net, "ipsec/eroute/all");
32509 + proc_symlink("ipsec_spi", proc_net, "ipsec/spi/all");
32510 + proc_symlink("ipsec_spigrp", proc_net, "ipsec/spigrp/all");
32511 + proc_symlink("ipsec_tncfg", proc_net, "ipsec/tncfg");
32512 + proc_symlink("ipsec_version",proc_net, "ipsec/version");
32513 + proc_symlink("ipsec_klipsdebug",proc_net,"ipsec/klipsdebug");
32514 +
32515 +#endif /* !PROC_FS_2325 */
32516 +
32517 + return error;
32518 +}
32519 +
32520 +void
32521 +ipsec_proc_cleanup()
32522 +{
32523 +
32524 + /* for 2.0 and 2.2 kernels */
32525 +#if !defined(PROC_FS_2325)
32526 +
32527 +#ifdef CONFIG_KLIPS_DEBUG
32528 + if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0)
32529 + printk("klips_debug:ipsec_cleanup: "
32530 + "cannot unregister /proc/net/ipsec_klipsdebug\n");
32531 +#endif /* CONFIG_KLIPS_DEBUG */
32532 +
32533 + if (proc_net_unregister(ipsec_version.low_ino) != 0)
32534 + printk("klips_debug:ipsec_cleanup: "
32535 + "cannot unregister /proc/net/ipsec_version\n");
32536 + if (proc_net_unregister(ipsec_eroute.low_ino) != 0)
32537 + printk("klips_debug:ipsec_cleanup: "
32538 + "cannot unregister /proc/net/ipsec_eroute\n");
32539 + if (proc_net_unregister(ipsec_spi.low_ino) != 0)
32540 + printk("klips_debug:ipsec_cleanup: "
32541 + "cannot unregister /proc/net/ipsec_spi\n");
32542 + if (proc_net_unregister(ipsec_spigrp.low_ino) != 0)
32543 + printk("klips_debug:ipsec_cleanup: "
32544 + "cannot unregister /proc/net/ipsec_spigrp\n");
32545 + if (proc_net_unregister(ipsec_tncfg.low_ino) != 0)
32546 + printk("klips_debug:ipsec_cleanup: "
32547 + "cannot unregister /proc/net/ipsec_tncfg\n");
32548 +#endif
32549 +
32550 + /* for 2.4 kernels */
32551 +#if defined(PROC_FS_2325)
32552 + {
32553 + struct ipsec_proc_list *it;
32554 +
32555 + /* find end of list */
32556 + it=proc_items;
32557 + while(it->name!=NULL) {
32558 + it++;
32559 + }
32560 + it--;
32561 +
32562 + do {
32563 + remove_proc_entry(it->name, *it->parent);
32564 + it--;
32565 + } while(it >= proc_items);
32566 + }
32567 +
32568 +
32569 +#ifdef CONFIG_KLIPS_DEBUG
32570 + remove_proc_entry("ipsec_klipsdebug", proc_net);
32571 +#endif /* CONFIG_KLIPS_DEBUG */
32572 + remove_proc_entry("ipsec_eroute", proc_net);
32573 + remove_proc_entry("ipsec_spi", proc_net);
32574 + remove_proc_entry("ipsec_spigrp", proc_net);
32575 + remove_proc_entry("ipsec_tncfg", proc_net);
32576 + remove_proc_entry("ipsec_version", proc_net);
32577 + remove_proc_entry("ipsec", proc_net);
32578 +#endif /* 2.4 kernel */
32579 +}
32580 +
32581 +/*
32582 + * $Log: ipsec_proc.c,v $
32583 + * Revision 1.41 2005/11/11 04:04:03 paul
32584 + * Fix for compiling without CONFIG_KLIPS_ALG by Toby
32585 + *
32586 + * Revision 1.40 2005/08/26 20:02:24 mcr
32587 + * added /proc/net/ipsec/natt file to indicate if NAT-T was compiled
32588 + * into KLIPS.
32589 + *
32590 + * Revision 1.39 2005/05/20 03:19:18 mcr
32591 + * modifications for use on 2.4.30 kernel, with backported
32592 + * printk_ratelimit(). all warnings removed.
32593 + *
32594 + * Revision 1.38 2005/04/29 05:10:22 mcr
32595 + * removed from extraenous includes to make unit testing easier.
32596 + *
32597 + * Revision 1.37 2005/04/13 22:49:49 mcr
32598 + * moved KLIPS specific snprintf() wrapper to seperate file.
32599 + *
32600 + * Revision 1.36 2005/04/06 17:44:36 mcr
32601 + * when NAT-T is compiled out, show encap as "NA"
32602 + *
32603 + * Revision 1.35 2005/01/26 00:50:35 mcr
32604 + * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
32605 + * and make sure that NAT_TRAVERSAL is set as well to match
32606 + * userspace compiles of code.
32607 + *
32608 + * Revision 1.34 2004/12/03 21:25:57 mcr
32609 + * compile time fixes for running on 2.6.
32610 + * still experimental.
32611 + *
32612 + * Revision 1.33 2004/08/17 03:27:23 mcr
32613 + * klips 2.6 edits.
32614 + *
32615 + * Revision 1.32 2004/08/03 18:19:08 mcr
32616 + * in 2.6, use "net_device" instead of #define device->net_device.
32617 + * this probably breaks 2.0 compiles.
32618 + *
32619 + * Revision 1.31 2004/07/10 19:11:18 mcr
32620 + * CONFIG_IPSEC -> CONFIG_KLIPS.
32621 + *
32622 + * Revision 1.30 2004/04/25 21:23:11 ken
32623 + * Pull in dhr's changes from FreeS/WAN 2.06
32624 + *
32625 + * Revision 1.29 2004/04/06 02:49:26 mcr
32626 + * pullup of algo code from alg-branch.
32627 + *
32628 + * Revision 1.28 2004/03/28 20:29:58 paul
32629 + * <hugh_> ssize_t, not ssized_t
32630 + *
32631 + * Revision 1.27 2004/03/28 20:27:20 paul
32632 + * Included tested and confirmed fixes mcr made and dhr verified for
32633 + * snprint statements. Changed one other snprintf to use ipsec_snprintf
32634 + * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
32635 + * dhr. (thanks dhr!)
32636 + *
32637 + * Revision 1.26 2004/02/09 22:07:06 mcr
32638 + * added information about nat-traversal setting to spi-output.
32639 + *
32640 + * Revision 1.25.4.1 2004/04/05 04:30:46 mcr
32641 + * patches for alg-branch to compile/work with 2.x openswan
32642 + *
32643 + * Revision 1.25 2003/10/31 02:27:55 mcr
32644 + * pulled up port-selector patches and sa_id elimination.
32645 + *
32646 + * Revision 1.24.4.1 2003/10/29 01:30:41 mcr
32647 + * elimited "struct sa_id".
32648 + *
32649 + * Revision 1.24 2003/06/20 01:42:21 mcr
32650 + * added counters to measure how many ACQUIREs we send to pluto,
32651 + * and how many are successfully sent.
32652 + *
32653 + * Revision 1.23 2003/04/03 17:38:09 rgb
32654 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
32655 + *
32656 + * Revision 1.22 2002/09/20 15:40:57 rgb
32657 + * Renamed saref macros for consistency and brevity.
32658 + *
32659 + * Revision 1.21 2002/09/20 05:01:35 rgb
32660 + * Print ref and reftable, refentry seperately.
32661 + *
32662 + * Revision 1.20 2002/09/19 02:35:39 mcr
32663 + * do not define structures needed by /proc/net/ipsec/ if we
32664 + * aren't going create that directory.
32665 + *
32666 + * Revision 1.19 2002/09/10 01:43:25 mcr
32667 + * fixed problem in /-* comment.
32668 + *
32669 + * Revision 1.18 2002/09/03 16:22:11 mcr
32670 + * fixed initialization of birth/stuff values - some simple
32671 + * screw ups in the code.
32672 + * removed debugging that was left in by mistake.
32673 + *
32674 + * Revision 1.17 2002/09/02 17:54:53 mcr
32675 + * changed how the table driven /proc entries are created so that
32676 + * making subdirs is now explicit rather than implicit.
32677 + *
32678 + * Revision 1.16 2002/08/30 01:23:37 mcr
32679 + * reorganized /proc creating code to clear up ifdefs,
32680 + * make the 2.4 code table driven, and put things into
32681 + * /proc/net/ipsec subdir. Symlinks are left for compatibility.
32682 + *
32683 + * Revision 1.15 2002/08/13 19:01:25 mcr
32684 + * patches from kenb to permit compilation of FreeSWAN on ia64.
32685 + * des library patched to use proper DES_LONG type for ia64.
32686 + *
32687 + * Revision 1.14 2002/07/26 08:48:31 rgb
32688 + * Added SA ref table code.
32689 + *
32690 + * Revision 1.13 2002/07/24 18:44:54 rgb
32691 + * Type fiddling to tame ia64 compiler.
32692 + *
32693 + * Revision 1.12 2002/05/27 18:56:07 rgb
32694 + * Convert to dynamic ipsec device allocation.
32695 + *
32696 + * Revision 1.11 2002/05/23 07:14:50 rgb
32697 + * Added refcount code.
32698 + * Cleaned up %p variants to 0p%p for test suite cleanup.
32699 + * Convert "usecount" to "refcount" to remove ambiguity.
32700 + *
32701 + * Revision 1.10 2002/04/24 07:55:32 mcr
32702 + * #include patches and Makefiles for post-reorg compilation.
32703 + *
32704 + * Revision 1.9 2002/04/24 07:36:28 mcr
32705 + * Moved from ./klips/net/ipsec/ipsec_proc.c,v
32706 + *
32707 + * Revision 1.8 2002/01/29 17:17:55 mcr
32708 + * moved include of ipsec_param.h to after include of linux/kernel.h
32709 + * otherwise, it seems that some option that is set in ipsec_param.h
32710 + * screws up something subtle in the include path to kernel.h, and
32711 + * it complains on the snprintf() prototype.
32712 + *
32713 + * Revision 1.7 2002/01/29 04:00:52 mcr
32714 + * more excise of kversions.h header.
32715 + *
32716 + * Revision 1.6 2002/01/29 02:13:17 mcr
32717 + * introduction of ipsec_kversion.h means that include of
32718 + * ipsec_param.h must preceed any decisions about what files to
32719 + * include to deal with differences in kernel source.
32720 + *
32721 + * Revision 1.5 2002/01/12 02:54:30 mcr
32722 + * beginnings of /proc/net/ipsec dir.
32723 + *
32724 + * Revision 1.4 2001/12/11 02:21:05 rgb
32725 + * Don't include module version here, fixing 2.2 compile bug.
32726 + *
32727 + * Revision 1.3 2001/12/05 07:19:44 rgb
32728 + * Fixed extraneous #include "version.c" bug causing modular KLIPS failure.
32729 + *
32730 + * Revision 1.2 2001/11/26 09:16:14 rgb
32731 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
32732 + *
32733 + * Revision 1.74 2001/11/22 05:44:11 henry
32734 + * new version stuff
32735 + *
32736 + * Revision 1.1.2.1 2001/09/25 02:19:40 mcr
32737 + * /proc manipulation code moved to new ipsec_proc.c
32738 + *
32739 + *
32740 + * Local variables:
32741 + * c-file-style: "linux"
32742 + * End:
32743 + *
32744 + */
32745 --- /dev/null Tue Mar 11 13:02:56 2003
32746 +++ linux/net/ipsec/ipsec_radij.c Mon Feb 9 13:51:03 2004
32747 @@ -0,0 +1,884 @@
32748 +/*
32749 + * Interface between the IPSEC code and the radix (radij) tree code
32750 + * Copyright (C) 1996, 1997 John Ioannidis.
32751 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
32752 + *
32753 + * This program is free software; you can redistribute it and/or modify it
32754 + * under the terms of the GNU General Public License as published by the
32755 + * Free Software Foundation; either version 2 of the License, or (at your
32756 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
32757 + *
32758 + * This program is distributed in the hope that it will be useful, but
32759 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
32760 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
32761 + * for more details.
32762 + *
32763 + * RCSID $Id: ipsec_radij.c,v 1.73 2005/04/29 05:10:22 mcr Exp $
32764 + */
32765 +
32766 +#ifndef AUTOCONF_INCLUDED
32767 +#include <linux/config.h>
32768 +#endif
32769 +#include <linux/version.h>
32770 +#include <linux/kernel.h> /* printk() */
32771 +
32772 +#include "openswan/ipsec_param.h"
32773 +
32774 +#ifdef MALLOC_SLAB
32775 +# include <linux/slab.h> /* kmalloc() */
32776 +#else /* MALLOC_SLAB */
32777 +# include <linux/malloc.h> /* kmalloc() */
32778 +#endif /* MALLOC_SLAB */
32779 +#include <linux/errno.h> /* error codes */
32780 +#include <linux/types.h> /* size_t */
32781 +#include <linux/interrupt.h> /* mark_bh */
32782 +
32783 +#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
32784 +#include <linux/etherdevice.h> /* eth_type_trans */
32785 +#include <linux/ip.h> /* struct iphdr */
32786 +#include <linux/skbuff.h>
32787 +#include <openswan.h>
32788 +#ifdef SPINLOCK
32789 +# ifdef SPINLOCK_23
32790 +# include <linux/spinlock.h> /* *lock* */
32791 +# else /* 23_SPINLOCK */
32792 +# include <asm/spinlock.h> /* *lock* */
32793 +# endif /* 23_SPINLOCK */
32794 +#endif /* SPINLOCK */
32795 +
32796 +#include <net/ip.h>
32797 +
32798 +#include "openswan/ipsec_eroute.h"
32799 +#include "openswan/ipsec_sa.h"
32800 +
32801 +#include "openswan/radij.h"
32802 +#include "openswan/ipsec_encap.h"
32803 +#include "openswan/radij.h"
32804 +#include "openswan/ipsec_encap.h"
32805 +#include "openswan/ipsec_radij.h"
32806 +#include "openswan/ipsec_tunnel.h" /* struct ipsecpriv */
32807 +#include "openswan/ipsec_xform.h"
32808 +
32809 +#include <openswan/pfkeyv2.h>
32810 +#include <openswan/pfkey.h>
32811 +
32812 +#include "openswan/ipsec_proto.h"
32813 +
32814 +#ifdef CONFIG_KLIPS_DEBUG
32815 +int debug_radij = 0;
32816 +#endif /* CONFIG_KLIPS_DEBUG */
32817 +
32818 +struct radij_node_head *rnh = NULL;
32819 +#ifdef SPINLOCK
32820 +spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED;
32821 +#else /* SPINLOCK */
32822 +spinlock_t eroute_lock;
32823 +#endif /* SPINLOCK */
32824 +
32825 +int
32826 +ipsec_radijinit(void)
32827 +{
32828 + maj_keylen = sizeof (struct sockaddr_encap);
32829 +
32830 + rj_init();
32831 +
32832 + if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */
32833 + return -1;
32834 + return 0;
32835 +}
32836 +
32837 +int
32838 +ipsec_radijcleanup(void)
32839 +{
32840 + int error = 0;
32841 +
32842 + spin_lock_bh(&eroute_lock);
32843 +
32844 + error = radijcleanup();
32845 +
32846 + spin_unlock_bh(&eroute_lock);
32847 +
32848 + return error;
32849 +}
32850 +
32851 +int
32852 +ipsec_cleareroutes(void)
32853 +{
32854 + int error;
32855 +
32856 + spin_lock_bh(&eroute_lock);
32857 +
32858 + error = radijcleartree();
32859 +
32860 + spin_unlock_bh(&eroute_lock);
32861 +
32862 + return error;
32863 +}
32864 +
32865 +int
32866 +ipsec_breakroute(struct sockaddr_encap *eaddr,
32867 + struct sockaddr_encap *emask,
32868 + struct sk_buff **first,
32869 + struct sk_buff **last)
32870 +{
32871 + struct eroute *ro;
32872 + struct radij_node *rn;
32873 + int error;
32874 +#ifdef CONFIG_KLIPS_DEBUG
32875 +
32876 + if (debug_eroute) {
32877 + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
32878 + subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
32879 + subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
32880 + KLIPS_PRINT(debug_eroute,
32881 + "klips_debug:ipsec_breakroute: "
32882 + "attempting to delete eroute for %s:%d->%s:%d %d\n",
32883 + buf1, ntohs(eaddr->sen_sport),
32884 + buf2, ntohs(eaddr->sen_dport), eaddr->sen_proto);
32885 + }
32886 +#endif /* CONFIG_KLIPS_DEBUG */
32887 +
32888 + spin_lock_bh(&eroute_lock);
32889 +
32890 + if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) {
32891 + spin_unlock_bh(&eroute_lock);
32892 + KLIPS_PRINT(debug_eroute,
32893 + "klips_debug:ipsec_breakroute: "
32894 + "node not found, eroute delete failed.\n");
32895 + return error;
32896 + }
32897 +
32898 + spin_unlock_bh(&eroute_lock);
32899 +
32900 + ro = (struct eroute *)rn;
32901 +
32902 + KLIPS_PRINT(debug_eroute,
32903 + "klips_debug:ipsec_breakroute: "
32904 + "deleted eroute=0p%p, ident=0p%p->0p%p, first=0p%p, last=0p%p\n",
32905 + ro,
32906 + ro->er_ident_s.data,
32907 + ro->er_ident_d.data,
32908 + ro->er_first,
32909 + ro->er_last);
32910 +
32911 + if (ro->er_ident_s.data != NULL) {
32912 + kfree(ro->er_ident_s.data);
32913 + }
32914 + if (ro->er_ident_d.data != NULL) {
32915 + kfree(ro->er_ident_d.data);
32916 + }
32917 + if (ro->er_first != NULL) {
32918 +#if 0
32919 + struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_first->dev->priv))->mystats);
32920 + stats->tx_dropped--;
32921 +#endif
32922 + *first = ro->er_first;
32923 + }
32924 + if (ro->er_last != NULL) {
32925 +#if 0
32926 + struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_last->dev->priv))->mystats);
32927 + stats->tx_dropped--;
32928 +#endif
32929 + *last = ro->er_last;
32930 + }
32931 +
32932 + if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT))
32933 + panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n");
32934 + memset((caddr_t)rn, 0, sizeof (struct eroute));
32935 + kfree(rn);
32936 +
32937 + return 0;
32938 +}
32939 +
32940 +int
32941 +ipsec_makeroute(struct sockaddr_encap *eaddr,
32942 + struct sockaddr_encap *emask,
32943 + ip_said said,
32944 + uint32_t pid,
32945 + struct sk_buff *skb,
32946 + struct ident *ident_s,
32947 + struct ident *ident_d)
32948 +{
32949 + struct eroute *retrt;
32950 + int error;
32951 + char sa[SATOT_BUF];
32952 + size_t sa_len;
32953 +
32954 +#ifdef CONFIG_KLIPS_DEBUG
32955 +
32956 + if (debug_eroute) {
32957 +
32958 + {
32959 + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
32960 +
32961 + subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
32962 + subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
32963 + sa_len = satot(&said, 0, sa, sizeof(sa));
32964 + KLIPS_PRINT(debug_eroute,
32965 + "klips_debug:ipsec_makeroute: "
32966 + "attempting to allocate %lu bytes to insert eroute for %s->%s, SA: %s, PID:%d, skb=0p%p, ident:%s->%s\n",
32967 + (unsigned long) sizeof(struct eroute),
32968 + buf1,
32969 + buf2,
32970 + sa_len ? sa : " (error)",
32971 + pid,
32972 + skb,
32973 + (ident_s ? (ident_s->data ? ident_s->data : "NULL") : "NULL"),
32974 + (ident_d ? (ident_d->data ? ident_d->data : "NULL") : "NULL"));
32975 + }
32976 + {
32977 + char buf1[sizeof(struct sockaddr_encap)*2 + 1],
32978 + buf2[sizeof(struct sockaddr_encap)*2 + 1];
32979 + int i;
32980 + unsigned char *b1 = buf1,
32981 + *b2 = buf2,
32982 + *ea = (unsigned char *)eaddr,
32983 + *em = (unsigned char *)emask;
32984 +
32985 +
32986 + for (i=0; i<sizeof(struct sockaddr_encap); i++) {
32987 + sprintf(b1, "%02x", ea[i]);
32988 + sprintf(b2, "%02x", em[i]);
32989 + b1+=2;
32990 + b2+=2;
32991 + }
32992 + KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_makeroute: %s / %s \n", buf1, buf2);
32993 + }
32994 +
32995 + }
32996 +#endif /* CONFIG_KLIPS_DEBUG */
32997 +
32998 + retrt = (struct eroute *)kmalloc(sizeof (struct eroute), GFP_ATOMIC);
32999 + if (retrt == NULL) {
33000 + printk("klips_error:ipsec_makeroute: "
33001 + "not able to allocate kernel memory");
33002 + return -ENOMEM;
33003 + }
33004 + memset((caddr_t)retrt, 0, sizeof (struct eroute));
33005 +
33006 + retrt->er_eaddr = *eaddr;
33007 + retrt->er_emask = *emask;
33008 + retrt->er_said = said;
33009 + retrt->er_pid = pid;
33010 + retrt->er_count = 0;
33011 + retrt->er_lasttime = jiffies/HZ;
33012 +
33013 + {
33014 + /* this is because gcc 3. doesn't like cast's as lvalues */
33015 + struct rjtentry *rje = (struct rjtentry *)&(retrt->er_rjt);
33016 + caddr_t er = (caddr_t)&(retrt->er_eaddr);
33017 +
33018 + rje->rd_nodes->rj_key= er;
33019 + }
33020 +
33021 + if (ident_s && ident_s->type != SADB_IDENTTYPE_RESERVED) {
33022 + int data_len = ident_s->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
33023 +
33024 + retrt->er_ident_s.type = ident_s->type;
33025 + retrt->er_ident_s.id = ident_s->id;
33026 + retrt->er_ident_s.len = ident_s->len;
33027 + if(data_len) {
33028 + KLIPS_PRINT(debug_eroute,
33029 + "klips_debug:ipsec_makeroute: "
33030 + "attempting to allocate %u bytes for ident_s.\n",
33031 + data_len);
33032 + if(!(retrt->er_ident_s.data = kmalloc(data_len, GFP_KERNEL))) {
33033 + kfree(retrt);
33034 + printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
33035 + return ENOMEM;
33036 + }
33037 + memcpy(retrt->er_ident_s.data, ident_s->data, data_len);
33038 + } else {
33039 + retrt->er_ident_s.data = NULL;
33040 + }
33041 + }
33042 +
33043 + if (ident_d && ident_d->type != SADB_IDENTTYPE_RESERVED) {
33044 + int data_len = ident_d->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
33045 +
33046 + retrt->er_ident_d.type = ident_d->type;
33047 + retrt->er_ident_d.id = ident_d->id;
33048 + retrt->er_ident_d.len = ident_d->len;
33049 + if(data_len) {
33050 + KLIPS_PRINT(debug_eroute,
33051 + "klips_debug:ipsec_makeroute: "
33052 + "attempting to allocate %u bytes for ident_d.\n",
33053 + data_len);
33054 + if(!(retrt->er_ident_d.data = kmalloc(data_len, GFP_KERNEL))) {
33055 + if (retrt->er_ident_s.data)
33056 + kfree(retrt->er_ident_s.data);
33057 + kfree(retrt);
33058 + printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
33059 + return ENOMEM;
33060 + }
33061 + memcpy(retrt->er_ident_d.data, ident_d->data, data_len);
33062 + } else {
33063 + retrt->er_ident_d.data = NULL;
33064 + }
33065 + }
33066 + retrt->er_first = skb;
33067 + retrt->er_last = NULL;
33068 +
33069 + KLIPS_PRINT(debug_eroute,
33070 + "klips_debug:ipsec_makeroute: "
33071 + "calling rj_addroute now\n");
33072 +
33073 + spin_lock_bh(&eroute_lock);
33074 +
33075 + error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask),
33076 + rnh, retrt->er_rjt.rd_nodes);
33077 +
33078 + spin_unlock_bh(&eroute_lock);
33079 +
33080 + if(error) {
33081 + sa_len = satot(&said, 0, sa, sizeof(sa));
33082 + KLIPS_PRINT(debug_eroute,
33083 + "klips_debug:ipsec_makeroute: "
33084 + "rj_addroute not able to insert eroute for SA:%s (error:%d)\n",
33085 + sa_len ? sa : " (error)", error);
33086 + if (retrt->er_ident_s.data)
33087 + kfree(retrt->er_ident_s.data);
33088 + if (retrt->er_ident_d.data)
33089 + kfree(retrt->er_ident_d.data);
33090 +
33091 + kfree(retrt);
33092 +
33093 + return error;
33094 + }
33095 +
33096 +#ifdef CONFIG_KLIPS_DEBUG
33097 + if (debug_eroute) {
33098 + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33099 +/*
33100 + subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
33101 + subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
33102 +*/
33103 + subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1));
33104 + subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2));
33105 + sa_len = satot(&retrt->er_said, 0, sa, sizeof(sa));
33106 +
33107 + KLIPS_PRINT(debug_eroute,
33108 + "klips_debug:ipsec_makeroute: "
33109 + "pid=%05d "
33110 + "count=%10d "
33111 + "lasttime=%6d "
33112 + "%-18s -> %-18s => %s\n",
33113 + retrt->er_pid,
33114 + retrt->er_count,
33115 + (int)(jiffies/HZ - retrt->er_lasttime),
33116 + buf1,
33117 + buf2,
33118 + sa_len ? sa : " (error)");
33119 + }
33120 +#endif /* CONFIG_KLIPS_DEBUG */
33121 + KLIPS_PRINT(debug_eroute,
33122 + "klips_debug:ipsec_makeroute: "
33123 + "succeeded.\n");
33124 + return 0;
33125 +}
33126 +
33127 +struct eroute *
33128 +ipsec_findroute(struct sockaddr_encap *eaddr)
33129 +{
33130 + struct radij_node *rn;
33131 +#ifdef CONFIG_KLIPS_DEBUG
33132 + char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF];
33133 +
33134 + if (debug_radij & DB_RJ_FINDROUTE) {
33135 + addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1));
33136 + addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2));
33137 + KLIPS_PRINT(debug_eroute,
33138 + "klips_debug:ipsec_findroute: "
33139 + "%s:%d->%s:%d %d\n",
33140 + buf1, ntohs(eaddr->sen_sport),
33141 + buf2, ntohs(eaddr->sen_dport),
33142 + eaddr->sen_proto);
33143 + }
33144 +#endif /* CONFIG_KLIPS_DEBUG */
33145 + rn = rj_match((caddr_t)eaddr, rnh);
33146 + if(rn) {
33147 + KLIPS_PRINT(debug_eroute && sysctl_ipsec_debug_verbose,
33148 + "klips_debug:ipsec_findroute: "
33149 + "found, points to proto=%d, spi=%x, dst=%x.\n",
33150 + ((struct eroute*)rn)->er_said.proto,
33151 + ntohl(((struct eroute*)rn)->er_said.spi),
33152 + ntohl(((struct eroute*)rn)->er_said.dst.u.v4.sin_addr.s_addr));
33153 + }
33154 + return (struct eroute *)rn;
33155 +}
33156 +
33157 +#ifdef CONFIG_PROC_FS
33158 +/** ipsec_rj_walker_procprint: print one line of eroute table output.
33159 + *
33160 + * Theoretical BUG: if w->length is less than the length
33161 + * of some line we should produce, that line will never
33162 + * be finished. In effect, the "file" will stop part way
33163 + * through that line.
33164 + */
33165 +int
33166 +ipsec_rj_walker_procprint(struct radij_node *rn, void *w0)
33167 +{
33168 + struct eroute *ro = (struct eroute *)rn;
33169 + struct rjtentry *rd = (struct rjtentry *)rn;
33170 + struct wsbuf *w = (struct wsbuf *)w0;
33171 + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33172 + char buf3[16];
33173 + char sa[SATOT_BUF];
33174 + size_t sa_len, buf_len;
33175 + struct sockaddr_encap *key, *mask;
33176 +
33177 + KLIPS_PRINT(debug_radij,
33178 + "klips_debug:ipsec_rj_walker_procprint: "
33179 + "rn=0p%p, w0=0p%p\n",
33180 + rn,
33181 + w0);
33182 + if (rn->rj_b >= 0) {
33183 + return 0;
33184 + }
33185 +
33186 + key = rd_key(rd);
33187 + mask = rd_mask(rd);
33188 +
33189 + if (key == NULL || mask == NULL) {
33190 + return 0;
33191 + }
33192 +
33193 + buf_len = subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
33194 + if(key->sen_sport != 0) {
33195 + sprintf(buf1+buf_len-1, ":%d", ntohs(key->sen_sport));
33196 + }
33197 +
33198 + buf_len = subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
33199 + if(key->sen_dport != 0) {
33200 + sprintf(buf2+buf_len-1, ":%d", ntohs(key->sen_dport));
33201 + }
33202 +
33203 + buf3[0]='\0';
33204 + if(key->sen_proto != 0) {
33205 + sprintf(buf3, ":%d", key->sen_proto);
33206 + }
33207 +
33208 + sa_len = satot(&ro->er_said, 'x', sa, sizeof(sa));
33209 + w->len += ipsec_snprintf(w->buffer + w->len,
33210 + w->length - w->len,
33211 + "%-10d "
33212 + "%-18s -> %-18s => %s%s\n",
33213 + ro->er_count,
33214 + buf1,
33215 + buf2,
33216 + sa_len ? sa : " (error)",
33217 + buf3);
33218 +
33219 + {
33220 + /* snprintf can only fill the last character with NUL
33221 + * so the maximum useful character is w->length-1.
33222 + * However, if w->length == 0, we cannot go back.
33223 + * (w->length surely cannot be negative.)
33224 + */
33225 + int max_content = w->length > 0? w->length-1 : 0;
33226 +
33227 + if (w->len >= max_content) {
33228 + /* we've done all that can fit -- stop treewalking */
33229 + w->len = max_content; /* truncate crap */
33230 + return -ENOBUFS;
33231 + } else {
33232 + const off_t pos = w->begin + w->len; /* file position of end of what we've generated */
33233 +
33234 + if (pos <= w->offset) {
33235 + /* all is before first interesting character:
33236 + * discard, but note where we are.
33237 + */
33238 + w->len = 0;
33239 + w->begin = pos;
33240 + }
33241 + return 0;
33242 + }
33243 + }
33244 +}
33245 +#endif /* CONFIG_PROC_FS */
33246 +
33247 +int
33248 +ipsec_rj_walker_delete(struct radij_node *rn, void *w0)
33249 +{
33250 + struct eroute *ro;
33251 + struct rjtentry *rd = (struct rjtentry *)rn;
33252 + struct radij_node *rn2;
33253 + int error;
33254 + struct sockaddr_encap *key, *mask;
33255 +
33256 + key = rd_key(rd);
33257 + mask = rd_mask(rd);
33258 +
33259 + if(!key || !mask) {
33260 + return -ENODATA;
33261 + }
33262 +#ifdef CONFIG_KLIPS_DEBUG
33263 + if(debug_radij) {
33264 + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33265 + subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
33266 + subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
33267 + KLIPS_PRINT(debug_radij,
33268 + "klips_debug:ipsec_rj_walker_delete: "
33269 + "deleting: %s -> %s\n",
33270 + buf1,
33271 + buf2);
33272 + }
33273 +#endif /* CONFIG_KLIPS_DEBUG */
33274 +
33275 + if((error = rj_delete(key, mask, rnh, &rn2))) {
33276 + KLIPS_PRINT(debug_radij,
33277 + "klips_debug:ipsec_rj_walker_delete: "
33278 + "rj_delete failed with error=%d.\n", error);
33279 + return error;
33280 + }
33281 +
33282 + if(rn2 != rn) {
33283 + printk("klips_debug:ipsec_rj_walker_delete: "
33284 + "tried to delete a different node?!? This should never happen!\n");
33285 + }
33286 +
33287 + ro = (struct eroute *)rn;
33288 +
33289 + if (ro->er_ident_s.data)
33290 + kfree(ro->er_ident_s.data);
33291 + if (ro->er_ident_d.data)
33292 + kfree(ro->er_ident_d.data);
33293 +
33294 + memset((caddr_t)rn, 0, sizeof (struct eroute));
33295 + kfree(rn);
33296 +
33297 + return 0;
33298 +}
33299 +
33300 +/*
33301 + * $Log: ipsec_radij.c,v $
33302 + * Revision 1.73 2005/04/29 05:10:22 mcr
33303 + * removed from extraenous includes to make unit testing easier.
33304 + *
33305 + * Revision 1.72 2004/12/03 21:25:57 mcr
33306 + * compile time fixes for running on 2.6.
33307 + * still experimental.
33308 + *
33309 + * Revision 1.71 2004/07/10 19:11:18 mcr
33310 + * CONFIG_IPSEC -> CONFIG_KLIPS.
33311 + *
33312 + * Revision 1.70 2004/04/25 21:10:52 ken
33313 + * Pull in dhr's changes from FreeS/WAN 2.06
33314 + *
33315 + * Revision 1.69 2004/04/06 02:49:26 mcr
33316 + * pullup of algo code from alg-branch.
33317 + *
33318 + * Revision 1.68 2004/03/28 20:27:20 paul
33319 + * Included tested and confirmed fixes mcr made and dhr verified for
33320 + * snprint statements. Changed one other snprintf to use ipsec_snprintf
33321 + * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
33322 + * dhr. (thanks dhr!)
33323 + *
33324 + * Revision 1.67.4.1 2004/04/05 04:30:46 mcr
33325 + * patches for alg-branch to compile/work with 2.x openswan
33326 + *
33327 + * Revision 1.67 2003/10/31 02:27:55 mcr
33328 + * pulled up port-selector patches and sa_id elimination.
33329 + *
33330 + * Revision 1.66.24.2 2003/10/29 01:30:41 mcr
33331 + * elimited "struct sa_id".
33332 + *
33333 + * Revision 1.66.24.1 2003/09/21 13:59:56 mcr
33334 + * pre-liminary X.509 patch - does not yet pass tests.
33335 + *
33336 + * Revision 1.66 2002/10/12 23:11:53 dhr
33337 + *
33338 + * [KenB + DHR] more 64-bit cleanup
33339 + *
33340 + * Revision 1.65 2002/09/20 05:01:40 rgb
33341 + * Added memory allocation debugging.
33342 + *
33343 + * Revision 1.64 2002/05/31 01:46:05 mcr
33344 + * added && sysctl_ipsec_debug_verbose verbose to ipsec_findroute
33345 + * as requested in PR#14.
33346 + *
33347 + * Revision 1.63 2002/05/23 07:14:11 rgb
33348 + * Cleaned up %p variants to 0p%p for test suite cleanup.
33349 + *
33350 + * Revision 1.62 2002/04/24 07:55:32 mcr
33351 + * #include patches and Makefiles for post-reorg compilation.
33352 + *
33353 + * Revision 1.61 2002/04/24 07:36:29 mcr
33354 + * Moved from ./klips/net/ipsec/ipsec_radij.c,v
33355 + *
33356 + * Revision 1.60 2002/02/19 23:59:45 rgb
33357 + * Removed redundant compiler directives.
33358 + *
33359 + * Revision 1.59 2002/02/06 04:13:47 mcr
33360 + * missing #ifdef CONFIG_IPSEC_DEBUG.
33361 + *
33362 + * Revision 1.58 2002/01/29 17:17:56 mcr
33363 + * moved include of ipsec_param.h to after include of linux/kernel.h
33364 + * otherwise, it seems that some option that is set in ipsec_param.h
33365 + * screws up something subtle in the include path to kernel.h, and
33366 + * it complains on the snprintf() prototype.
33367 + *
33368 + * Revision 1.57 2002/01/29 04:00:52 mcr
33369 + * more excise of kversions.h header.
33370 + *
33371 + * Revision 1.56 2002/01/29 02:13:17 mcr
33372 + * introduction of ipsec_kversion.h means that include of
33373 + * ipsec_param.h must preceed any decisions about what files to
33374 + * include to deal with differences in kernel source.
33375 + *
33376 + * Revision 1.55 2001/11/26 09:23:48 rgb
33377 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
33378 + *
33379 + * Revision 1.53.2.1 2001/09/25 02:26:32 mcr
33380 + * headers adjusted for new usage.
33381 + *
33382 + * Revision 1.54 2001/10/18 04:45:20 rgb
33383 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
33384 + * lib/freeswan.h version macros moved to lib/kversions.h.
33385 + * Other compiler directive cleanups.
33386 + *
33387 + * Revision 1.53 2001/09/19 17:19:40 rgb
33388 + * Debug output bugfix for NetCelo's PF_KEY ident patch.
33389 + *
33390 + * Revision 1.52 2001/09/19 16:33:37 rgb
33391 + * Temporarily disable ident fields to /proc/net/ipsec_eroute.
33392 + *
33393 + * Revision 1.51 2001/09/15 16:24:04 rgb
33394 + * Re-inject first and last HOLD packet when an eroute REPLACE is done.
33395 + *
33396 + * Revision 1.50 2001/09/14 16:58:36 rgb
33397 + * Added support for storing the first and last packets through a HOLD.
33398 + *
33399 + * Revision 1.49 2001/09/08 21:13:32 rgb
33400 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
33401 + *
33402 + * Revision 1.48 2001/06/15 04:12:56 rgb
33403 + * Fixed kernel memory allocation error return code polarity bug.
33404 + *
33405 + * Revision 1.47 2001/06/14 19:35:09 rgb
33406 + * Update copyright date.
33407 + *
33408 + * Revision 1.46 2001/06/08 08:47:18 rgb
33409 + * Fixed for debug disabled.
33410 + *
33411 + * Revision 1.45 2001/05/27 06:12:11 rgb
33412 + * Added structures for pid, packet count and last access time to eroute.
33413 + * Added packet count to beginning of /proc/net/ipsec_eroute.
33414 + *
33415 + * Revision 1.44 2001/05/03 19:41:01 rgb
33416 + * Initialise error return variable.
33417 + * Use more appropriate return value for ipsec_rj_walker_delete().
33418 + *
33419 + * Revision 1.43 2001/02/27 22:24:54 rgb
33420 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
33421 + * Check for satoa() return codes.
33422 + *
33423 + * Revision 1.42 2001/02/27 06:21:57 rgb
33424 + * Added findroute success instrumentation.
33425 + *
33426 + * Revision 1.41 2000/11/06 04:32:08 rgb
33427 + * Ditched spin_lock_irqsave in favour of spin_lock_bh.
33428 + *
33429 + * Revision 1.40 2000/09/08 19:12:56 rgb
33430 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
33431 + *
33432 + * Revision 1.39 2000/08/30 05:25:20 rgb
33433 + * Correct debug text in ipsec_breakroute() from incorrect
33434 + * "ipsec_callback".
33435 + *
33436 + * Revision 1.38 2000/07/28 14:58:31 rgb
33437 + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
33438 + *
33439 + * Revision 1.37 2000/03/16 14:02:50 rgb
33440 + * Fixed debug scope to enable compilation with debug off.
33441 + *
33442 + * Revision 1.36 2000/01/21 06:14:46 rgb
33443 + * Added debugging text to ipsec_rj_walker_delete().
33444 + * Set return code to negative for consistency.
33445 + *
33446 + * Revision 1.35 1999/11/23 23:05:24 rgb
33447 + * Use provided macro ADDRTOA_BUF instead of hardcoded value.
33448 + *
33449 + * Revision 1.34 1999/11/18 04:13:56 rgb
33450 + * Replaced all kernel version macros to shorter, readable form.
33451 + * Added CONFIG_PROC_FS compiler directives in case it is shut off.
33452 + *
33453 + * Revision 1.33 1999/11/17 15:53:39 rgb
33454 + * Changed all occurrences of #include "../../../lib/freeswan.h"
33455 + * to #include <freeswan.h> which works due to -Ilibfreeswan in the
33456 + * klips/net/ipsec/Makefile.
33457 + *
33458 + * Revision 1.32 1999/10/26 13:58:33 rgb
33459 + * Put spinlock flags variable declaration outside the debug compiler
33460 + * directive to enable compilation with debug shut off.
33461 + *
33462 + * Revision 1.31 1999/10/15 22:13:29 rgb
33463 + * Clean out cruft.
33464 + * Align /proc/net/ipsec_eroute output for easier readability.
33465 + * Fix double linefeed in radij debug output.
33466 + * Fix double locking bug that locks up 2.0.36 but not 2.0.38.
33467 + *
33468 + * Revision 1.30 1999/10/08 18:37:33 rgb
33469 + * Fix end-of-line spacing to sate whining PHMs.
33470 + *
33471 + * Revision 1.29 1999/10/03 18:52:45 rgb
33472 + * Spinlock support for 2.0.xx.
33473 + * Dumb return code spin_unlock fix.
33474 + *
33475 + * Revision 1.28 1999/10/01 16:22:24 rgb
33476 + * Switch from assignment init. to functional init. of spinlocks.
33477 + *
33478 + * Revision 1.27 1999/10/01 15:44:53 rgb
33479 + * Move spinlock header include to 2.1> scope.
33480 + *
33481 + * Revision 1.26 1999/10/01 00:01:23 rgb
33482 + * Added eroute structure locking.
33483 + *
33484 + * Revision 1.25 1999/06/10 16:07:30 rgb
33485 + * Silence delete eroute on no debug.
33486 + *
33487 + * Revision 1.24 1999/05/09 03:25:36 rgb
33488 + * Fix bug introduced by 2.2 quick-and-dirty patch.
33489 + *
33490 + * Revision 1.23 1999/05/05 22:02:31 rgb
33491 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
33492 + *
33493 + * Revision 1.22 1999/04/29 15:17:23 rgb
33494 + * Add return values to init and cleanup functions.
33495 + * Add sanity checking for null pointer arguments.
33496 + *
33497 + * Revision 1.21 1999/04/11 00:28:58 henry
33498 + * GPL boilerplate
33499 + *
33500 + * Revision 1.20 1999/04/06 04:54:26 rgb
33501 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
33502 + * patch shell fixes.
33503 + *
33504 + * Revision 1.19 1999/02/17 16:50:35 rgb
33505 + * Clean out unused cruft.
33506 + * Consolidate for space and speed efficiency.
33507 + * Convert DEBUG_IPSEC to KLIPS_PRINT
33508 + *
33509 + * Revision 1.18 1999/01/22 06:22:06 rgb
33510 + * Cruft clean-out.
33511 + * 64-bit clean-up.
33512 + *
33513 + * Revision 1.17 1998/12/02 03:09:39 rgb
33514 + * Clean up debug printing conditionals to compile with debugging off.
33515 + *
33516 + * Revision 1.16 1998/12/01 13:49:39 rgb
33517 + * Wrap version info printing in debug switches.
33518 + *
33519 + * Revision 1.15 1998/11/30 13:22:54 rgb
33520 + * Rationalised all the klips kernel file headers. They are much shorter
33521 + * now and won't conflict under RH5.2.
33522 + *
33523 + * Revision 1.14 1998/10/31 06:48:17 rgb
33524 + * Fixed up comments in #endif directives.
33525 + *
33526 + * Revision 1.13 1998/10/27 13:48:09 rgb
33527 + * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts.
33528 + * Fixed less(1) truncated output bug.
33529 + * Code clean-up.
33530 + *
33531 + * Revision 1.12 1998/10/25 02:41:36 rgb
33532 + * Change return type on ipsec_breakroute and ipsec_makeroute and add an
33533 + * argument to be able to transmit more infomation about errors.
33534 + * Fix cut-and-paste debug statement identifier.
33535 + *
33536 + * Revision 1.11 1998/10/22 06:45:39 rgb
33537 + * Cleaned up cruft.
33538 + * Convert to use satoa for printk.
33539 + *
33540 + * Revision 1.10 1998/10/19 14:44:28 rgb
33541 + * Added inclusion of freeswan.h.
33542 + * sa_id structure implemented and used: now includes protocol.
33543 + *
33544 + * Revision 1.9 1998/10/09 04:30:52 rgb
33545 + * Added 'klips_debug' prefix to all klips printk debug statements.
33546 + * Deleted old commented out cruft.
33547 + *
33548 + * Revision 1.8 1998/08/06 17:24:23 rgb
33549 + * Fix addrtoa return code bug from stale manpage advice preventing packets
33550 + * from being erouted.
33551 + *
33552 + * Revision 1.7 1998/08/06 07:44:59 rgb
33553 + * Fixed /proc/net/ipsec_eroute subnettoa and addrtoa return value bug that
33554 + * ended up in nothing being printed.
33555 + *
33556 + * Revision 1.6 1998/08/05 22:16:41 rgb
33557 + * Cleanup to prevent cosmetic errors (ie. debug output) from being fatal.
33558 + *
33559 + * Revision 1.5 1998/07/29 20:38:44 rgb
33560 + * Debug and fix subnettoa and addrtoa output.
33561 + *
33562 + * Revision 1.4 1998/07/28 00:02:39 rgb
33563 + * Converting to exclusive use of addrtoa.
33564 + * Fix eroute delete.
33565 + *
33566 + * Revision 1.3 1998/07/14 18:21:26 rgb
33567 + * Add function to clear the eroute table.
33568 + *
33569 + * Revision 1.2 1998/06/23 02:59:14 rgb
33570 + * Added debugging output to eroute add/delete routines.
33571 + *
33572 + * Revision 1.9 1998/06/18 21:29:06 henry
33573 + * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
33574 + * build scripts happier in presence of symbolic links
33575 + *
33576 + * Revision 1.8 1998/06/05 02:32:26 rgb
33577 + * Fix spi ntoh kernel debug output.
33578 + *
33579 + * Revision 1.7 1998/05/25 20:30:37 rgb
33580 + * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
33581 + *
33582 + * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
33583 + * add ipsec_rj_walker_delete.
33584 + *
33585 + * Revision 1.6 1998/05/21 13:08:57 rgb
33586 + * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of
33587 + * information is available for printout.
33588 + *
33589 + * Revision 1.5 1998/05/18 21:35:55 rgb
33590 + * Clean up output for numerical consistency and readability. Zero freed
33591 + * eroute memory.
33592 + *
33593 + * Revision 1.4 1998/04/21 21:28:58 rgb
33594 + * Rearrange debug switches to change on the fly debug output from user
33595 + * space. Only kernel changes checked in at this time. radij.c was also
33596 + * changed to temporarily remove buggy debugging code in rj_delete causing
33597 + * an OOPS and hence, netlink device open errors.
33598 + *
33599 + * Revision 1.3 1998/04/14 17:30:39 rgb
33600 + * Fix up compiling errors for radij tree memory reclamation.
33601 + *
33602 + * Revision 1.2 1998/04/12 22:03:23 rgb
33603 + * Updated ESP-3DES-HMAC-MD5-96,
33604 + * ESP-DES-HMAC-MD5-96,
33605 + * AH-HMAC-MD5-96,
33606 + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
33607 + * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
33608 + *
33609 + * Fixed eroute references in /proc/net/ipsec*.
33610 + *
33611 + * Started to patch module unloading memory leaks in ipsec_netlink and
33612 + * radij tree unloading.
33613 + *
33614 + * Revision 1.1 1998/04/09 03:06:10 henry
33615 + * sources moved up from linux/net/ipsec
33616 + *
33617 + * Revision 1.1.1.1 1998/04/08 05:35:03 henry
33618 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
33619 + *
33620 + * Revision 0.4 1997/01/15 01:28:15 ji
33621 + * No changes.
33622 + *
33623 + * Revision 0.3 1996/11/20 14:39:04 ji
33624 + * Minor cleanups.
33625 + * Rationalized debugging code.
33626 + *
33627 + * Revision 0.2 1996/11/02 00:18:33 ji
33628 + * First limited release.
33629 + *
33630 + *
33631 + */
33632 --- /dev/null Tue Mar 11 13:02:56 2003
33633 +++ linux/net/ipsec/ipsec_rcv.c Mon Feb 9 13:51:03 2004
33634 @@ -0,0 +1,2395 @@
33635 +/*
33636 + * receive code
33637 + * Copyright (C) 1996, 1997 John Ioannidis.
33638 + * Copyright (C) 1998-2003 Richard Guy Briggs.
33639 + * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
33640 + *
33641 + * This program is free software; you can redistribute it and/or modify it
33642 + * under the terms of the GNU General Public License as published by the
33643 + * Free Software Foundation; either version 2 of the License, or (at your
33644 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
33645 + *
33646 + * This program is distributed in the hope that it will be useful, but
33647 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
33648 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
33649 + * for more details.
33650 + */
33651 +
33652 +char ipsec_rcv_c_version[] = "RCSID $Id: ipsec_rcv.c,v 1.178 2005/10/21 02:19:34 mcr Exp $";
33653 +
33654 +#ifndef AUTOCONF_INCLUDED
33655 +#include <linux/config.h>
33656 +#endif
33657 +#include <linux/version.h>
33658 +
33659 +#define __NO_VERSION__
33660 +#include <linux/module.h>
33661 +#include <linux/kernel.h> /* printk() */
33662 +
33663 +#include "openswan/ipsec_param.h"
33664 +
33665 +#ifdef MALLOC_SLAB
33666 +# include <linux/slab.h> /* kmalloc() */
33667 +#else /* MALLOC_SLAB */
33668 +# include <linux/malloc.h> /* kmalloc() */
33669 +#endif /* MALLOC_SLAB */
33670 +#include <linux/errno.h> /* error codes */
33671 +#include <linux/types.h> /* size_t */
33672 +#include <linux/interrupt.h> /* mark_bh */
33673 +
33674 +#include <linux/netdevice.h> /* struct device, and other headers */
33675 +#include <linux/etherdevice.h> /* eth_type_trans */
33676 +#include <linux/ip.h> /* struct iphdr */
33677 +
33678 +#include <net/tcp.h>
33679 +#include <net/udp.h>
33680 +#include <linux/skbuff.h>
33681 +#include <openswan.h>
33682 +#ifdef SPINLOCK
33683 +# ifdef SPINLOCK_23
33684 +# include <linux/spinlock.h> /* *lock* */
33685 +# else /* SPINLOCK_23 */
33686 +# include <asm/spinlock.h> /* *lock* */
33687 +# endif /* SPINLOCK_23 */
33688 +#endif /* SPINLOCK */
33689 +
33690 +#include <net/ip.h>
33691 +
33692 +#include "openswan/ipsec_kern24.h"
33693 +#include "openswan/radij.h"
33694 +#include "openswan/ipsec_encap.h"
33695 +#include "openswan/ipsec_sa.h"
33696 +
33697 +#include "openswan/ipsec_radij.h"
33698 +#include "openswan/ipsec_xform.h"
33699 +#include "openswan/ipsec_tunnel.h"
33700 +#include "openswan/ipsec_rcv.h"
33701 +
33702 +#include "openswan/ipsec_auth.h"
33703 +
33704 +#include "openswan/ipsec_esp.h"
33705 +
33706 +#ifdef CONFIG_KLIPS_AH
33707 +#include "openswan/ipsec_ah.h"
33708 +#endif /* CONFIG_KLIPS_AH */
33709 +
33710 +#ifdef CONFIG_KLIPS_IPCOMP
33711 +#include "openswan/ipsec_ipcomp.h"
33712 +#endif /* CONFIG_KLIPS_COMP */
33713 +
33714 +#include <openswan/pfkeyv2.h>
33715 +#include <openswan/pfkey.h>
33716 +
33717 +#include "openswan/ipsec_proto.h"
33718 +#include "openswan/ipsec_alg.h"
33719 +#include "openswan/ipsec_kern24.h"
33720 +
33721 +#ifdef CONFIG_KLIPS_DEBUG
33722 +int debug_rcv = 0;
33723 +#endif /* CONFIG_KLIPS_DEBUG */
33724 +
33725 +int sysctl_ipsec_inbound_policy_check = 1;
33726 +
33727 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
33728 +#include <linux/udp.h>
33729 +#endif
33730 +
33731 +/* This is a private use protocol, and AT&T should be ashamed. They should have
33732 + * used protocol # 59, which is "no next header" instead of 0xFE.
33733 + */
33734 +#ifndef IPPROTO_ATT_HEARTBEAT
33735 +#define IPPROTO_ATT_HEARTBEAT 0xFE
33736 +#endif
33737 +
33738 +/*
33739 + * Check-replay-window routine, adapted from the original
33740 + * by J. Hughes, from draft-ietf-ipsec-esp-des-md5-03.txt
33741 + *
33742 + * This is a routine that implements a 64 packet window. This is intend-
33743 + * ed on being an implementation sample.
33744 + */
33745 +
33746 +DEBUG_NO_STATIC int
33747 +ipsec_checkreplaywindow(struct ipsec_sa*ipsp, __u32 seq)
33748 +{
33749 + __u32 diff;
33750 +
33751 + if (ipsp->ips_replaywin == 0) /* replay shut off */
33752 + return 1;
33753 + if (seq == 0)
33754 + return 0; /* first == 0 or wrapped */
33755 +
33756 + /* new larger sequence number */
33757 + if (seq > ipsp->ips_replaywin_lastseq) {
33758 + return 1; /* larger is good */
33759 + }
33760 + diff = ipsp->ips_replaywin_lastseq - seq;
33761 +
33762 + /* too old or wrapped */ /* if wrapped, kill off SA? */
33763 + if (diff >= ipsp->ips_replaywin) {
33764 + return 0;
33765 + }
33766 + /* this packet already seen */
33767 + if (ipsp->ips_replaywin_bitmap & (1 << diff))
33768 + return 0;
33769 + return 1; /* out of order but good */
33770 +}
33771 +
33772 +DEBUG_NO_STATIC int
33773 +ipsec_updatereplaywindow(struct ipsec_sa*ipsp, __u32 seq)
33774 +{
33775 + __u32 diff;
33776 +
33777 + if (ipsp->ips_replaywin == 0) /* replay shut off */
33778 + return 1;
33779 + if (seq == 0)
33780 + return 0; /* first == 0 or wrapped */
33781 +
33782 + /* new larger sequence number */
33783 + if (seq > ipsp->ips_replaywin_lastseq) {
33784 + diff = seq - ipsp->ips_replaywin_lastseq;
33785 +
33786 + /* In win, set bit for this pkt */
33787 + if (diff < ipsp->ips_replaywin)
33788 + ipsp->ips_replaywin_bitmap =
33789 + (ipsp->ips_replaywin_bitmap << diff) | 1;
33790 + else
33791 + /* This packet has way larger seq num */
33792 + ipsp->ips_replaywin_bitmap = 1;
33793 +
33794 + if(seq - ipsp->ips_replaywin_lastseq - 1 > ipsp->ips_replaywin_maxdiff) {
33795 + ipsp->ips_replaywin_maxdiff = seq - ipsp->ips_replaywin_lastseq - 1;
33796 + }
33797 + ipsp->ips_replaywin_lastseq = seq;
33798 + return 1; /* larger is good */
33799 + }
33800 + diff = ipsp->ips_replaywin_lastseq - seq;
33801 +
33802 + /* too old or wrapped */ /* if wrapped, kill off SA? */
33803 + if (diff >= ipsp->ips_replaywin) {
33804 +/*
33805 + if(seq < 0.25*max && ipsp->ips_replaywin_lastseq > 0.75*max) {
33806 + ipsec_sa_delchain(ipsp);
33807 + }
33808 +*/
33809 + return 0;
33810 + }
33811 + /* this packet already seen */
33812 + if (ipsp->ips_replaywin_bitmap & (1 << diff))
33813 + return 0;
33814 + ipsp->ips_replaywin_bitmap |= (1 << diff); /* mark as seen */
33815 + return 1; /* out of order but good */
33816 +}
33817 +
33818 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
33819 +struct auth_alg ipsec_rcv_md5[]={
33820 + {osMD5Init, osMD5Update, osMD5Final, AHMD596_ALEN}
33821 +};
33822 +
33823 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
33824 +
33825 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
33826 +struct auth_alg ipsec_rcv_sha1[]={
33827 + {SHA1Init, SHA1Update, SHA1Final, AHSHA196_ALEN}
33828 +};
33829 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
33830 +
33831 +/*
33832 + * decapsulate a single layer of the system
33833 + *
33834 + * the following things should be setup to enter this function.
33835 + *
33836 + * irs->stats == stats structure (or NULL)
33837 + * irs->ipp = IP header.
33838 + * irs->len = total length of packet
33839 + * skb->nh.iph = ipp;
33840 + * skb->h.raw = start of payload
33841 + * irs->ipsp = NULL.
33842 + * irs->iphlen = N/A = is recalculated.
33843 + * irs->ilen = 0;
33844 + * irs->authlen = 0;
33845 + * irs->authfuncs = NULL;
33846 + * irs->skb = the skb;
33847 + *
33848 + * proto_funcs should be from ipsec_esp.c, ipsec_ah.c or ipsec_ipcomp.c.
33849 + *
33850 + */
33851 +enum ipsec_rcv_value
33852 +ipsec_rcv_decap_once(struct ipsec_rcv_state *irs
33853 + , struct xform_functions *proto_funcs)
33854 +{
33855 + int iphlen;
33856 + __u8 proto;
33857 + struct in_addr ipsaddr;
33858 + struct in_addr ipdaddr;
33859 + int replay = 0; /* replay value in AH or ESP packet */
33860 + struct ipsec_sa* ipsnext = NULL; /* next SA towards inside of packet */
33861 + struct ipsec_sa *newipsp;
33862 + struct iphdr *ipp;
33863 + struct sk_buff *skb;
33864 + struct ipsec_alg_auth *ixt_a=NULL;
33865 +
33866 + skb = irs->skb;
33867 + irs->len = skb->len;
33868 + ipp = irs->ipp;
33869 + proto = ipp->protocol;
33870 + ipsaddr.s_addr = ipp->saddr;
33871 + addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
33872 + ipdaddr.s_addr = ipp->daddr;
33873 + addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
33874 +
33875 + iphlen = ipp->ihl << 2;
33876 + irs->iphlen=iphlen;
33877 + ipp->check = 0; /* we know the sum is good */
33878 +
33879 + KLIPS_PRINT(debug_rcv,
33880 + "klips_debug:ipsec_rcv_decap_once: "
33881 + "decap (%d) from %s -> %s\n",
33882 + proto, irs->ipsaddr_txt, irs->ipdaddr_txt);
33883 +
33884 + /*
33885 + * Find tunnel control block and (indirectly) call the
33886 + * appropriate tranform routine. The resulting sk_buf
33887 + * is a valid IP packet ready to go through input processing.
33888 + */
33889 +
33890 + irs->said.dst.u.v4.sin_addr.s_addr = ipp->daddr;
33891 + irs->said.dst.u.v4.sin_family = AF_INET;
33892 +
33893 + /* note: rcv_checks set up the said.spi value, if appropriate */
33894 + if(proto_funcs->rcv_checks) {
33895 + enum ipsec_rcv_value retval =
33896 + (*proto_funcs->rcv_checks)(irs, skb);
33897 +
33898 + if(retval < 0) {
33899 + return retval;
33900 + }
33901 + }
33902 +
33903 + irs->said.proto = proto;
33904 + irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa));
33905 + if(irs->sa_len == 0) {
33906 + strcpy(irs->sa, "(error)");
33907 + }
33908 +
33909 + newipsp = ipsec_sa_getbyid(&irs->said);
33910 + if (newipsp == NULL) {
33911 + KLIPS_PRINT(debug_rcv,
33912 + "klips_debug:ipsec_rcv: "
33913 + "no ipsec_sa for SA:%s: incoming packet with no SA dropped\n",
33914 + irs->sa_len ? irs->sa : " (error)");
33915 + if(irs->stats) {
33916 + irs->stats->rx_dropped++;
33917 + }
33918 + return IPSEC_RCV_SAIDNOTFOUND;
33919 + }
33920 +
33921 + /* MCR - XXX this is bizarre. ipsec_sa_getbyid returned it, having
33922 + * incremented the refcount, why in the world would we decrement it
33923 + * here? */
33924 + /* ipsec_sa_put(irs->ipsp);*/ /* incomplete */
33925 +
33926 + /* If it is in larval state, drop the packet, we cannot process yet. */
33927 + if(newipsp->ips_state == K_SADB_SASTATE_LARVAL) {
33928 + KLIPS_PRINT(debug_rcv,
33929 + "klips_debug:ipsec_rcv: "
33930 + "ipsec_sa in larval state, cannot be used yet, dropping packet.\n");
33931 + if(irs->stats) {
33932 + irs->stats->rx_dropped++;
33933 + }
33934 + ipsec_sa_put(newipsp);
33935 + return IPSEC_RCV_SAIDNOTLIVE;
33936 + }
33937 +
33938 + if(newipsp->ips_state == K_SADB_SASTATE_DEAD) {
33939 + KLIPS_PRINT(debug_rcv,
33940 + "klips_debug:ipsec_rcv: "
33941 + "ipsec_sa in dead state, cannot be used any more, dropping packet.\n");
33942 + if(irs->stats) {
33943 + irs->stats->rx_dropped++;
33944 + }
33945 + ipsec_sa_put(newipsp);
33946 + return IPSEC_RCV_SAIDNOTLIVE;
33947 + }
33948 +
33949 + if(sysctl_ipsec_inbound_policy_check) {
33950 + if(irs->ipp->saddr != ((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr) {
33951 + KLIPS_PRINT(debug_rcv,
33952 + "klips_debug:ipsec_rcv: "
33953 + "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n",
33954 + irs->sa_len ? irs->sa : " (error)",
33955 + irs->ipsaddr_txt);
33956 + if(irs->stats) {
33957 + irs->stats->rx_dropped++;
33958 + }
33959 + ipsec_sa_put(newipsp);
33960 + return IPSEC_RCV_FAILEDINBOUND;
33961 + }
33962 +
33963 + KLIPS_PRINT(debug_rcv,
33964 + "klips_debug:ipsec_rcv: "
33965 + "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n",
33966 + irs->sa_len ? irs->sa : " (error)",
33967 + irs->ipsaddr_txt);
33968 +
33969 + /*
33970 + * at this point, we have looked up a new SA, and we want to make sure that if this
33971 + * isn't the first SA in the list, that the previous SA actually points at this one.
33972 + */
33973 + if(irs->ipsp) {
33974 + if(irs->ipsp->ips_inext != newipsp) {
33975 + KLIPS_PRINT(debug_rcv,
33976 + "klips_debug:ipsec_rcv: "
33977 + "unexpected SA:%s: does not agree with ips->inext policy, dropped\n",
33978 + irs->sa_len ? irs->sa : " (error)");
33979 + if(irs->stats) {
33980 + irs->stats->rx_dropped++;
33981 + }
33982 + ipsec_sa_put(newipsp);
33983 + return IPSEC_RCV_FAILEDINBOUND;
33984 + }
33985 + KLIPS_PRINT(debug_rcv,
33986 + "klips_debug:ipsec_rcv: "
33987 + "SA:%s grouping from previous SA is OK.\n",
33988 + irs->sa_len ? irs->sa : " (error)");
33989 + } else {
33990 + KLIPS_PRINT(debug_rcv,
33991 + "klips_debug:ipsec_rcv: "
33992 + "SA:%s First SA in group.\n",
33993 + irs->sa_len ? irs->sa : " (error)");
33994 + }
33995 +
33996 +
33997 +
33998 +
33999 +
34000 +
34001 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34002 + if (proto == IPPROTO_ESP) {
34003 + KLIPS_PRINT(debug_rcv,
34004 + "klips_debug:ipsec_rcv: "
34005 + "natt_type=%u tdbp->ips_natt_type=%u : %s\n",
34006 + irs->natt_type, newipsp->ips_natt_type,
34007 + (irs->natt_type==newipsp->ips_natt_type)?"ok":"bad");
34008 + if (irs->natt_type != newipsp->ips_natt_type) {
34009 + KLIPS_PRINT(debug_rcv,
34010 + "klips_debug:ipsec_rcv: "
34011 + "SA:%s does not agree with expected NAT-T policy.\n",
34012 + irs->sa_len ? irs->sa : " (error)");
34013 + if(irs->stats) {
34014 + irs->stats->rx_dropped++;
34015 + }
34016 + ipsec_sa_put(newipsp);
34017 + return IPSEC_RCV_FAILEDINBOUND;
34018 + }
34019 + }
34020 +#endif
34021 + }
34022 +
34023 + /* okay, SA checks out, so free any previous SA, and record a new one*/
34024 +
34025 + if(irs->ipsp) {
34026 + ipsec_sa_put(irs->ipsp);
34027 + }
34028 + irs->ipsp=newipsp;
34029 +
34030 + /* note that the outer code will free the irs->ipsp
34031 + if there is an error */
34032 +
34033 +
34034 + /* now check the lifetimes */
34035 + if(ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_bytes, "bytes",
34036 + irs->sa, ipsec_life_countbased, ipsec_incoming,
34037 + irs->ipsp) == ipsec_life_harddied ||
34038 + ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "addtime",
34039 + irs->sa, ipsec_life_timebased, ipsec_incoming,
34040 + irs->ipsp) == ipsec_life_harddied ||
34041 + ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "usetime",
34042 + irs->sa, ipsec_life_timebased, ipsec_incoming,
34043 + irs->ipsp) == ipsec_life_harddied ||
34044 + ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_packets, "packets",
34045 + irs->sa, ipsec_life_countbased, ipsec_incoming,
34046 + irs->ipsp) == ipsec_life_harddied) {
34047 +
34048 + /*
34049 + * disconnect SA from the hash table, so it can not be
34050 + * found again.
34051 + */
34052 + ipsec_sa_rm(irs->ipsp);
34053 + if(irs->stats) {
34054 + irs->stats->rx_dropped++;
34055 + }
34056 +
34057 + KLIPS_PRINT(debug_rcv,
34058 + "klips_debug:ipsec_rcv_decap_once: "
34059 + "decap (%d) failed lifetime check\n",
34060 + proto);
34061 +
34062 + return IPSEC_RCV_LIFETIMEFAILED;
34063 + }
34064 +
34065 +#if 0
34066 + /*
34067 + * This is removed for some reasons:
34068 + * 1) it needs to happen *after* authentication.
34069 + * 2) do we really care, if it authenticates, if it came
34070 + * from the wrong location?
34071 + * 3) the NAT_KA messages in IKE will also get to pluto
34072 + * and it will figure out that stuff has moved.
34073 + * 4) the 2.6 udp-esp encap function does not pass us
34074 + * the originating port number, and I can't tell
34075 + * if skb->sk is guaranteed to be valid here.
34076 + * 2005-04-16: mcr@xelerance.com
34077 + */
34078 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34079 + /*
34080 + *
34081 + * XXX we should ONLY update pluto if the SA passes all checks,
34082 + * which we clearly do not now.
34083 + */
34084 + if ((irs->natt_type) &&
34085 + ( (irs->ipp->saddr != (((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr)) ||
34086 + (irs->natt_sport != newipsp->ips_natt_sport)
34087 + )) {
34088 + struct sockaddr sipaddr;
34089 + struct sockaddr_in *psin = (struct sockaddr_in*)(newipsp->ips_addr_s);
34090 +
34091 + /** Advertise NAT-T addr change to pluto **/
34092 + sipaddr.sa_family = AF_INET;
34093 + ((struct sockaddr_in*)&sipaddr)->sin_addr.s_addr = irs->ipp->saddr;
34094 + ((struct sockaddr_in*)&sipaddr)->sin_port = htons(irs->natt_sport);
34095 + pfkey_nat_t_new_mapping(newipsp, &sipaddr, irs->natt_sport);
34096 +
34097 + /**
34098 + * Then allow or block packet depending on
34099 + * sysctl_ipsec_inbound_policy_check.
34100 + *
34101 + * In all cases, pluto will update SA if new mapping is
34102 + * accepted.
34103 + */
34104 + if (sysctl_ipsec_inbound_policy_check) {
34105 + KLIPS_PRINT(debug_rcv,
34106 + "klips_debug:ipsec_rcv: "
34107 + "SA:%s, src=%s:%u of pkt does not agree with expected "
34108 + "SA source address [%08x:%u] (notifying pluto of change).\n",
34109 + irs->sa_len ? irs->sa : " (error)",
34110 + irs->ipsaddr_txt, irs->natt_sport,
34111 + psin->sin_addr.s_addr,
34112 + newipsp->ips_natt_sport);
34113 + if(irs->stats) {
34114 + irs->stats->rx_dropped++;
34115 + }
34116 + ipsec_sa_put(newipsp);
34117 + return IPSEC_RCV_FAILEDINBOUND;
34118 + }
34119 + }
34120 +#endif
34121 +#endif
34122 +
34123 + irs->authfuncs=NULL;
34124 +
34125 + /* authenticate, if required */
34126 + if ((ixt_a=irs->ipsp->ips_alg_auth)) {
34127 + irs->authlen = AHHMAC_HASHLEN;
34128 + irs->authfuncs = NULL;
34129 + irs->ictx = NULL;
34130 + irs->octx = NULL;
34131 + irs->ictx_len = 0;
34132 + irs->octx_len = 0;
34133 + KLIPS_PRINT(debug_rcv,
34134 + "klips_debug:ipsec_rcv: "
34135 + "authalg=%d authlen=%d\n",
34136 + irs->ipsp->ips_authalg,
34137 + irs->authlen);
34138 + } else
34139 + switch(irs->ipsp->ips_authalg) {
34140 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
34141 + case AH_MD5:
34142 + irs->authlen = AHHMAC_HASHLEN;
34143 + irs->authfuncs = ipsec_rcv_md5;
34144 + irs->ictx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx;
34145 + irs->octx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx;
34146 + irs->ictx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx);
34147 + irs->octx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx);
34148 + break;
34149 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
34150 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
34151 + case AH_SHA:
34152 + irs->authlen = AHHMAC_HASHLEN;
34153 + irs->authfuncs = ipsec_rcv_sha1;
34154 + irs->ictx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx;
34155 + irs->octx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx;
34156 + irs->ictx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx);
34157 + irs->octx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx);
34158 + break;
34159 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
34160 + case AH_NONE:
34161 + irs->authlen = 0;
34162 + irs->authfuncs = NULL;
34163 + irs->ictx = NULL;
34164 + irs->octx = NULL;
34165 + irs->ictx_len = 0;
34166 + irs->octx_len = 0;
34167 + break;
34168 + default:
34169 + irs->ipsp->ips_errs.ips_alg_errs += 1;
34170 + if(irs->stats) {
34171 + irs->stats->rx_errors++;
34172 + }
34173 + return IPSEC_RCV_BADAUTH;
34174 + }
34175 +
34176 + /* ilen counts number of bytes in ESP portion */
34177 + irs->ilen = ((skb->data + skb->len) - skb->h.raw) - irs->authlen;
34178 + if(irs->ilen <= 0) {
34179 + KLIPS_PRINT(debug_rcv,
34180 + "klips_debug:ipsec_rcv: "
34181 + "runt %s packet with no data, dropping.\n",
34182 + (proto == IPPROTO_ESP ? "esp" : "ah"));
34183 + if(irs->stats) {
34184 + irs->stats->rx_dropped++;
34185 + }
34186 + return IPSEC_RCV_BADLEN;
34187 + }
34188 +
34189 + if(irs->authfuncs || ixt_a) {
34190 + unsigned char *authenticator = NULL;
34191 +
34192 + if(proto_funcs->rcv_setup_auth) {
34193 + enum ipsec_rcv_value retval
34194 + = (*proto_funcs->rcv_setup_auth)(irs, skb,
34195 + &replay,
34196 + &authenticator);
34197 + if(retval < 0) {
34198 + return retval;
34199 + }
34200 + }
34201 +
34202 + if(!authenticator) {
34203 + irs->ipsp->ips_errs.ips_auth_errs += 1;
34204 + if(irs->stats) {
34205 + irs->stats->rx_dropped++;
34206 + }
34207 + return IPSEC_RCV_BADAUTH;
34208 + }
34209 +
34210 + if(!ipsec_checkreplaywindow(irs->ipsp, replay)) {
34211 + irs->ipsp->ips_errs.ips_replaywin_errs += 1;
34212 + KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
34213 + "klips_debug:ipsec_rcv: "
34214 + "duplicate frame from %s, packet dropped\n",
34215 + irs->ipsaddr_txt);
34216 + if(irs->stats) {
34217 + irs->stats->rx_dropped++;
34218 + }
34219 + return IPSEC_RCV_REPLAYFAILED;
34220 + }
34221 +
34222 + /*
34223 + * verify authenticator
34224 + */
34225 +
34226 + KLIPS_PRINT(debug_rcv,
34227 + "klips_debug:ipsec_rcv: "
34228 + "encalg = %d, authalg = %d.\n",
34229 + irs->ipsp->ips_encalg,
34230 + irs->ipsp->ips_authalg);
34231 +
34232 + /* calculate authenticator */
34233 + if(proto_funcs->rcv_calc_auth == NULL) {
34234 + return IPSEC_RCV_BADAUTH;
34235 + }
34236 + (*proto_funcs->rcv_calc_auth)(irs, skb);
34237 +
34238 + if (memcmp(irs->hash, authenticator, irs->authlen)) {
34239 + irs->ipsp->ips_errs.ips_auth_errs += 1;
34240 + KLIPS_PRINT(debug_rcv & DB_RX_INAU,
34241 + "klips_debug:ipsec_rcv: "
34242 + "auth failed on incoming packet from %s: hash=%08x%08x%08x auth=%08x%08x%08x, dropped\n",
34243 + irs->ipsaddr_txt,
34244 + ntohl(*(__u32*)&irs->hash[0]),
34245 + ntohl(*(__u32*)&irs->hash[4]),
34246 + ntohl(*(__u32*)&irs->hash[8]),
34247 + ntohl(*(__u32*)authenticator),
34248 + ntohl(*((__u32*)authenticator + 1)),
34249 + ntohl(*((__u32*)authenticator + 2)));
34250 + if(irs->stats) {
34251 + irs->stats->rx_dropped++;
34252 + }
34253 + return IPSEC_RCV_AUTHFAILED;
34254 + } else {
34255 + KLIPS_PRINT(debug_rcv,
34256 + "klips_debug:ipsec_rcv: "
34257 + "authentication successful.\n");
34258 + }
34259 +
34260 + /* Crypto hygiene: clear memory used to calculate autheticator.
34261 + * The length varies with the algorithm.
34262 + */
34263 + memset(irs->hash, 0, irs->authlen);
34264 +
34265 + /* If the sequence number == 0, expire SA, it had rolled */
34266 + if(irs->ipsp->ips_replaywin && !replay /* !irs->ipsp->ips_replaywin_lastseq */) {
34267 +
34268 + /* we need to remove it from the sadb hash, so that it can't be found again */
34269 + ipsec_sa_rm(irs->ipsp);
34270 +
34271 + KLIPS_PRINT(debug_rcv,
34272 + "klips_debug:ipsec_rcv: "
34273 + "replay window counter rolled, expiring SA.\n");
34274 + if(irs->stats) {
34275 + irs->stats->rx_dropped++;
34276 + }
34277 + return IPSEC_RCV_REPLAYROLLED;
34278 + }
34279 +
34280 + /* now update the replay counter */
34281 + if (!ipsec_updatereplaywindow(irs->ipsp, replay)) {
34282 + irs->ipsp->ips_errs.ips_replaywin_errs += 1;
34283 + KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
34284 + "klips_debug:ipsec_rcv: "
34285 + "duplicate frame from %s, packet dropped\n",
34286 + irs->ipsaddr_txt);
34287 + if(irs->stats) {
34288 + irs->stats->rx_dropped++;
34289 + }
34290 + return IPSEC_RCV_REPLAYROLLED;
34291 + }
34292 + }
34293 +
34294 + if(proto_funcs->rcv_decrypt) {
34295 + enum ipsec_rcv_value retval =
34296 + (*proto_funcs->rcv_decrypt)(irs);
34297 +
34298 + if(retval != IPSEC_RCV_OK) {
34299 + return retval;
34300 + }
34301 + }
34302 +
34303 + /*
34304 + * Adjust pointers
34305 + */
34306 + skb = irs->skb;
34307 + irs->len = skb->len;
34308 + ipp = irs->ipp = skb->nh.iph;
34309 + iphlen = ipp->ihl<<2;
34310 + skb->h.raw = skb->nh.raw + iphlen;
34311 +
34312 + /* zero any options that there might be */
34313 + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
34314 +
34315 + ipsaddr.s_addr = ipp->saddr;
34316 + addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
34317 + ipdaddr.s_addr = ipp->daddr;
34318 + addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
34319 +
34320 + /*
34321 + * Discard the original ESP/AH header
34322 + */
34323 + ipp->protocol = irs->next_header;
34324 +
34325 + ipp->check = 0; /* NOTE: this will be included in checksum */
34326 + ipp->check = ip_fast_csum((unsigned char *)skb->nh.iph, iphlen >> 2);
34327 +
34328 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
34329 + "klips_debug:ipsec_rcv: "
34330 + "after <%s%s%s>, SA:%s:\n",
34331 + IPS_XFORM_NAME(irs->ipsp),
34332 + irs->sa_len ? irs->sa : " (error)");
34333 + KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
34334 +
34335 + skb->protocol = htons(ETH_P_IP);
34336 + skb->ip_summed = 0;
34337 +
34338 + ipsnext = irs->ipsp->ips_inext;
34339 + if(sysctl_ipsec_inbound_policy_check) {
34340 + if(ipsnext) {
34341 + if(
34342 + ipp->protocol != IPPROTO_AH
34343 + && ipp->protocol != IPPROTO_ESP
34344 +#ifdef CONFIG_KLIPS_IPCOMP
34345 + && ipp->protocol != IPPROTO_COMP
34346 + && (ipsnext->ips_said.proto != IPPROTO_COMP
34347 + || ipsnext->ips_inext)
34348 +#endif /* CONFIG_KLIPS_IPCOMP */
34349 + && ipp->protocol != IPPROTO_IPIP
34350 + && ipp->protocol != IPPROTO_ATT_HEARTBEAT /* heartbeats to AT&T SIG/GIG */
34351 + ) {
34352 + KLIPS_PRINT(debug_rcv,
34353 + "klips_debug:ipsec_rcv: "
34354 + "packet with incomplete policy dropped, last successful SA:%s.\n",
34355 + irs->sa_len ? irs->sa : " (error)");
34356 + if(irs->stats) {
34357 + irs->stats->rx_dropped++;
34358 + }
34359 + return IPSEC_RCV_FAILEDINBOUND;
34360 + }
34361 + KLIPS_PRINT(debug_rcv,
34362 + "klips_debug:ipsec_rcv: "
34363 + "SA:%s, Another IPSEC header to process.\n",
34364 + irs->sa_len ? irs->sa : " (error)");
34365 + } else {
34366 + KLIPS_PRINT(debug_rcv,
34367 + "klips_debug:ipsec_rcv: "
34368 + "No ips_inext from this SA:%s.\n",
34369 + irs->sa_len ? irs->sa : " (error)");
34370 + }
34371 + }
34372 +
34373 +#ifdef CONFIG_KLIPS_IPCOMP
34374 + /* update ipcomp ratio counters, even if no ipcomp packet is present */
34375 + if (ipsnext
34376 + && ipsnext->ips_said.proto == IPPROTO_COMP
34377 + && ipp->protocol != IPPROTO_COMP) {
34378 + ipsnext->ips_comp_ratio_cbytes += ntohs(ipp->tot_len);
34379 + ipsnext->ips_comp_ratio_dbytes += ntohs(ipp->tot_len);
34380 + }
34381 +#endif /* CONFIG_KLIPS_IPCOMP */
34382 +
34383 + irs->ipsp->ips_life.ipl_bytes.ipl_count += irs->len;
34384 + irs->ipsp->ips_life.ipl_bytes.ipl_last = irs->len;
34385 +
34386 + if(!irs->ipsp->ips_life.ipl_usetime.ipl_count) {
34387 + irs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
34388 + }
34389 + irs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
34390 + irs->ipsp->ips_life.ipl_packets.ipl_count += 1;
34391 +
34392 +#ifdef CONFIG_NETFILTER
34393 + if(proto == IPPROTO_ESP || proto == IPPROTO_AH) {
34394 + skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_MASK))))
34395 + | IPsecSAref2NFmark(IPsecSA2SAref(irs->ipsp));
34396 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
34397 + "klips_debug:ipsec_rcv: "
34398 + "%s SA sets skb->nfmark=0x%x.\n",
34399 + proto == IPPROTO_ESP ? "ESP" : "AH",
34400 + (unsigned)skb->nfmark);
34401 + }
34402 +#endif /* CONFIG_NETFILTER */
34403 +
34404 + return IPSEC_RCV_OK;
34405 +}
34406 +
34407 +
34408 +/*
34409 + * core decapsulation loop for all protocols.
34410 + *
34411 + * the following things should be setup to enter this function.
34412 + *
34413 + * irs->stats == stats structure (or NULL)
34414 + * irs->ipp = IP header.
34415 + * irs->ipsp = NULL.
34416 + * irs->ilen = 0;
34417 + * irs->authlen = 0;
34418 + * irs->authfuncs = NULL;
34419 + * irs->skb = skb;
34420 + * skb->nh.iph = ipp;
34421 + * skb->h.raw = start of payload
34422 + *
34423 + */
34424 +int ipsec_rcv_decap(struct ipsec_rcv_state *irs)
34425 +{
34426 + struct ipsec_sa *ipsp = NULL;
34427 + struct ipsec_sa* ipsnext = NULL;
34428 + struct in_addr ipsaddr;
34429 + struct in_addr ipdaddr;
34430 + struct iphdr *ipp;
34431 + struct sk_buff *skb = NULL;
34432 +
34433 + /* begin decapsulating loop here */
34434 +
34435 + /*
34436 + The spinlock is to prevent any other process from
34437 + accessing or deleting the ipsec_sa hash table or any of the
34438 + ipsec_sa s while we are using and updating them.
34439 +
34440 + This is not optimal, but was relatively straightforward
34441 + at the time. A better way to do it has been planned for
34442 + more than a year, to lock the hash table and put reference
34443 + counts on each ipsec_sa instead. This is not likely to happen
34444 + in KLIPS1 unless a volunteer contributes it, but will be
34445 + designed into KLIPS2.
34446 + */
34447 + spin_lock(&tdb_lock);
34448 +
34449 + do {
34450 + int decap_stat;
34451 + struct xform_functions *proto_funcs;
34452 +
34453 + switch(irs->ipp->protocol) {
34454 + case IPPROTO_ESP:
34455 + proto_funcs = esp_xform_funcs;
34456 + break;
34457 +
34458 +#ifdef CONFIG_KLIPS_AH
34459 + case IPPROTO_AH:
34460 + proto_funcs = ah_xform_funcs;
34461 + break;
34462 +#endif /* !CONFIG_KLIPS_AH */
34463 +
34464 +#ifdef CONFIG_KLIPS_IPCOMP
34465 + case IPPROTO_COMP:
34466 + proto_funcs = ipcomp_xform_funcs;
34467 + break;
34468 +#endif /* !CONFIG_KLIPS_IPCOMP */
34469 + default:
34470 + if(irs->stats) {
34471 + irs->stats->rx_errors++;
34472 + }
34473 + decap_stat = IPSEC_RCV_BADPROTO;
34474 + goto rcvleave;
34475 + }
34476 +
34477 + decap_stat = ipsec_rcv_decap_once(irs, proto_funcs);
34478 +
34479 + if(decap_stat != IPSEC_RCV_OK) {
34480 + spin_unlock(&tdb_lock);
34481 + KLIPS_PRINT(debug_rcv,
34482 + "klips_debug:ipsec_rcv: decap_once failed: %d\n",
34483 + decap_stat);
34484 +
34485 + goto rcvleave;
34486 + }
34487 + /* end decapsulation loop here */
34488 + } while( (irs->ipp->protocol == IPPROTO_ESP )
34489 + || (irs->ipp->protocol == IPPROTO_AH )
34490 +#ifdef CONFIG_KLIPS_IPCOMP
34491 + || (irs->ipp->protocol == IPPROTO_COMP)
34492 +#endif /* CONFIG_KLIPS_IPCOMP */
34493 + );
34494 +
34495 + /* set up for decap loop */
34496 + ipp =irs->ipp;
34497 + ipsp =irs->ipsp;
34498 + ipsnext = ipsp->ips_inext;
34499 + skb = irs->skb;
34500 +
34501 + /* if there is an IPCOMP, but we don't have an IPPROTO_COMP,
34502 + * then we can just skip it
34503 + */
34504 +#ifdef CONFIG_KLIPS_IPCOMP
34505 + if(ipsnext && ipsnext->ips_said.proto == IPPROTO_COMP) {
34506 + ipsp = ipsnext;
34507 + ipsnext = ipsp->ips_inext;
34508 + }
34509 +#endif /* CONFIG_KLIPS_IPCOMP */
34510 +
34511 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34512 + if ((irs->natt_type) && (ipp->protocol != IPPROTO_IPIP)) {
34513 + /**
34514 + * NAT-Traversal and Transport Mode:
34515 + * we need to correct TCP/UDP checksum
34516 + *
34517 + * If we've got NAT-OA, we can fix checksum without recalculation.
34518 + */
34519 + __u32 natt_oa = ipsp->ips_natt_oa ?
34520 + ((struct sockaddr_in*)(ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
34521 + __u16 pkt_len = skb->tail - (unsigned char *)ipp;
34522 + __u16 data_len = pkt_len - (ipp->ihl << 2);
34523 +
34524 + switch (ipp->protocol) {
34525 + case IPPROTO_TCP:
34526 + if (data_len >= sizeof(struct tcphdr)) {
34527 + struct tcphdr *tcp = skb->h.th;
34528 + if (natt_oa) {
34529 + __u32 buff[2] = { ~natt_oa, ipp->saddr };
34530 + KLIPS_PRINT(debug_rcv,
34531 + "klips_debug:ipsec_rcv: "
34532 + "NAT-T & TRANSPORT: "
34533 + "fix TCP checksum using NAT-OA\n");
34534 + tcp->check = csum_fold(
34535 + csum_partial((unsigned char *)buff, sizeof(buff),
34536 + tcp->check^0xffff));
34537 + }
34538 + else {
34539 + KLIPS_PRINT(debug_rcv,
34540 + "klips_debug:ipsec_rcv: "
34541 + "NAT-T & TRANSPORT: recalc TCP checksum\n");
34542 + if (pkt_len > (ntohs(ipp->tot_len)))
34543 + data_len -= (pkt_len - ntohs(ipp->tot_len));
34544 + tcp->check = 0;
34545 + tcp->check = csum_tcpudp_magic(ipp->saddr, ipp->daddr,
34546 + data_len, IPPROTO_TCP,
34547 + csum_partial((unsigned char *)tcp, data_len, 0));
34548 + }
34549 + }
34550 + else {
34551 + KLIPS_PRINT(debug_rcv,
34552 + "klips_debug:ipsec_rcv: "
34553 + "NAT-T & TRANSPORT: can't fix TCP checksum\n");
34554 + }
34555 + break;
34556 + case IPPROTO_UDP:
34557 + if (data_len >= sizeof(struct udphdr)) {
34558 + struct udphdr *udp = skb->h.uh;
34559 + if (udp->check == 0) {
34560 + KLIPS_PRINT(debug_rcv,
34561 + "klips_debug:ipsec_rcv: "
34562 + "NAT-T & TRANSPORT: UDP checksum already 0\n");
34563 + }
34564 + else if (natt_oa) {
34565 + __u32 buff[2] = { ~natt_oa, ipp->saddr };
34566 + KLIPS_PRINT(debug_rcv,
34567 + "klips_debug:ipsec_rcv: "
34568 + "NAT-T & TRANSPORT: "
34569 + "fix UDP checksum using NAT-OA\n");
34570 + udp->check = csum_fold(
34571 + csum_partial((unsigned char *)buff, sizeof(buff),
34572 + udp->check^0xffff));
34573 + }
34574 + else {
34575 + KLIPS_PRINT(debug_rcv,
34576 + "klips_debug:ipsec_rcv: "
34577 + "NAT-T & TRANSPORT: zero UDP checksum\n");
34578 + udp->check = 0;
34579 + }
34580 + }
34581 + else {
34582 + KLIPS_PRINT(debug_rcv,
34583 + "klips_debug:ipsec_rcv: "
34584 + "NAT-T & TRANSPORT: can't fix UDP checksum\n");
34585 + }
34586 + break;
34587 + default:
34588 + KLIPS_PRINT(debug_rcv,
34589 + "klips_debug:ipsec_rcv: "
34590 + "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
34591 + break;
34592 + }
34593 + }
34594 +#endif
34595 +
34596 + /*
34597 + * XXX this needs to be locked from when it was first looked
34598 + * up in the decapsulation loop. Perhaps it is better to put
34599 + * the IPIP decap inside the loop.
34600 + */
34601 + if(ipsnext) {
34602 + ipsp = ipsnext;
34603 + irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa));
34604 + if((ipp->protocol != IPPROTO_IPIP) &&
34605 + (ipp->protocol != IPPROTO_ATT_HEARTBEAT)) { /* AT&T heartbeats to SIG/GIG */
34606 + spin_unlock(&tdb_lock);
34607 + KLIPS_PRINT(debug_rcv,
34608 + "klips_debug:ipsec_rcv: "
34609 + "SA:%s, Hey! How did this get through? Dropped.\n",
34610 + irs->sa_len ? irs->sa : " (error)");
34611 + if(irs->stats) {
34612 + irs->stats->rx_dropped++;
34613 + }
34614 + goto rcvleave;
34615 + }
34616 + if(sysctl_ipsec_inbound_policy_check) {
34617 + struct sockaddr_in *psin = (struct sockaddr_in*)(ipsp->ips_addr_s);
34618 + if((ipsnext = ipsp->ips_inext)) {
34619 + char sa2[SATOT_BUF];
34620 + size_t sa_len2;
34621 + sa_len2 = satot(&ipsnext->ips_said, 0, sa2, sizeof(sa2));
34622 + spin_unlock(&tdb_lock);
34623 + KLIPS_PRINT(debug_rcv,
34624 + "klips_debug:ipsec_rcv: "
34625 + "unexpected SA:%s after IPIP SA:%s\n",
34626 + sa_len2 ? sa2 : " (error)",
34627 + irs->sa_len ? irs->sa : " (error)");
34628 + if(irs->stats) {
34629 + irs->stats->rx_dropped++;
34630 + }
34631 + goto rcvleave;
34632 + }
34633 + if(ipp->saddr != psin->sin_addr.s_addr) {
34634 + spin_unlock(&tdb_lock);
34635 + KLIPS_PRINT(debug_rcv,
34636 + "klips_debug:ipsec_rcv: "
34637 + "SA:%s, src=%s(%08x) does match expected 0x%08x.\n",
34638 + irs->sa_len ? irs->sa : " (error)",
34639 + irs->ipsaddr_txt,
34640 + ipp->saddr, psin->sin_addr.s_addr);
34641 + if(irs->stats) {
34642 + irs->stats->rx_dropped++;
34643 + }
34644 + goto rcvleave;
34645 + }
34646 + }
34647 +
34648 + if(ipp->protocol == IPPROTO_IPIP) /* added to support AT&T heartbeats to SIG/GIG */
34649 + {
34650 + /*
34651 + * XXX this needs to be locked from when it was first looked
34652 + * up in the decapsulation loop. Perhaps it is better to put
34653 + * the IPIP decap inside the loop.
34654 + */
34655 + ipsp->ips_life.ipl_bytes.ipl_count += skb->len;
34656 + ipsp->ips_life.ipl_bytes.ipl_last = skb->len;
34657 +
34658 + if(!ipsp->ips_life.ipl_usetime.ipl_count) {
34659 + ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
34660 + }
34661 + ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
34662 + ipsp->ips_life.ipl_packets.ipl_count += 1;
34663 +
34664 + if(skb->len < irs->iphlen) {
34665 + spin_unlock(&tdb_lock);
34666 + printk(KERN_WARNING "klips_debug:ipsec_rcv: "
34667 + "tried to skb_pull iphlen=%d, %d available. This should never happen, please report.\n",
34668 + irs->iphlen,
34669 + (int)(skb->len));
34670 +
34671 + goto rcvleave;
34672 + }
34673 +
34674 + /*
34675 + * we need to pull up by size of IP header,
34676 + * options, but also by any UDP/ESP encap there might
34677 + * have been, and this deals with all cases.
34678 + */
34679 + skb_pull(skb, (skb->h.raw - skb->nh.raw));
34680 +
34681 + /* new L3 header is where L4 payload was */
34682 + skb->nh.raw = skb->h.raw;
34683 +
34684 + /* now setup new L4 payload location */
34685 + ipp = (struct iphdr *)skb->nh.raw;
34686 + skb->h.raw = skb->nh.raw + (ipp->ihl << 2);
34687 +
34688 +
34689 + /* remove any saved options that we might have,
34690 + * since we have a new IP header.
34691 + */
34692 + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
34693 +
34694 +#if 0
34695 + KLIPS_PRINT(debug_rcv, "csum: %d\n", ip_fast_csum((u8 *)ipp, ipp->ihl));
34696 +#endif
34697 +
34698 + /* re-do any strings for debugging */
34699 + ipsaddr.s_addr = ipp->saddr;
34700 + addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
34701 + ipdaddr.s_addr = ipp->daddr;
34702 + addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
34703 +
34704 + skb->protocol = htons(ETH_P_IP);
34705 + skb->ip_summed = 0;
34706 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
34707 + "klips_debug:ipsec_rcv: "
34708 + "IPIP tunnel stripped.\n");
34709 + KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
34710 + }
34711 +
34712 + if(sysctl_ipsec_inbound_policy_check
34713 + /*
34714 + Note: "xor" (^) logically replaces "not equal"
34715 + (!=) and "bitwise or" (|) logically replaces
34716 + "boolean or" (||). This is done to speed up
34717 + execution by doing only bitwise operations and
34718 + no branch operations
34719 + */
34720 + && (((ipp->saddr & ipsp->ips_mask_s.u.v4.sin_addr.s_addr)
34721 + ^ ipsp->ips_flow_s.u.v4.sin_addr.s_addr)
34722 + | ((ipp->daddr & ipsp->ips_mask_d.u.v4.sin_addr.s_addr)
34723 + ^ ipsp->ips_flow_d.u.v4.sin_addr.s_addr)) )
34724 + {
34725 + char sflow_txt[SUBNETTOA_BUF], dflow_txt[SUBNETTOA_BUF];
34726 +
34727 + subnettoa(ipsp->ips_flow_s.u.v4.sin_addr,
34728 + ipsp->ips_mask_s.u.v4.sin_addr,
34729 + 0, sflow_txt, sizeof(sflow_txt));
34730 + subnettoa(ipsp->ips_flow_d.u.v4.sin_addr,
34731 + ipsp->ips_mask_d.u.v4.sin_addr,
34732 + 0, dflow_txt, sizeof(dflow_txt));
34733 + spin_unlock(&tdb_lock);
34734 + KLIPS_PRINT(debug_rcv,
34735 + "klips_debug:ipsec_rcv: "
34736 + "SA:%s, inner tunnel policy [%s -> %s] does not agree with pkt contents [%s -> %s].\n",
34737 + irs->sa_len ? irs->sa : " (error)",
34738 + sflow_txt,
34739 + dflow_txt,
34740 + irs->ipsaddr_txt,
34741 + irs->ipdaddr_txt);
34742 + if(irs->stats) {
34743 + irs->stats->rx_dropped++;
34744 + }
34745 + goto rcvleave;
34746 + }
34747 +#ifdef CONFIG_NETFILTER
34748 + skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_TABLE_MASK))))
34749 + | IPsecSAref2NFmark(IPsecSA2SAref(ipsp));
34750 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
34751 + "klips_debug:ipsec_rcv: "
34752 + "IPIP SA sets skb->nfmark=0x%x.\n",
34753 + (unsigned)skb->nfmark);
34754 +#endif /* CONFIG_NETFILTER */
34755 + }
34756 +
34757 + spin_unlock(&tdb_lock);
34758 +
34759 + if(irs->stats) {
34760 + irs->stats->rx_bytes += skb->len;
34761 + }
34762 + if(skb->dst) {
34763 + dst_release(skb->dst);
34764 + skb->dst = NULL;
34765 + }
34766 + skb->pkt_type = PACKET_HOST;
34767 + if(irs->hard_header_len &&
34768 + (skb->mac.raw != (skb->nh.raw - irs->hard_header_len)) &&
34769 + (irs->hard_header_len <= skb_headroom(skb))) {
34770 + /* copy back original MAC header */
34771 + memmove(skb->nh.raw - irs->hard_header_len,
34772 + skb->mac.raw, irs->hard_header_len);
34773 + skb->mac.raw = skb->nh.raw - irs->hard_header_len;
34774 + }
34775 +
34776 +#ifdef CONFIG_KLIPS_IPCOMP
34777 + if(ipp->protocol == IPPROTO_COMP) {
34778 + unsigned int flags = 0;
34779 +
34780 + if(sysctl_ipsec_inbound_policy_check) {
34781 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
34782 + "klips_debug:ipsec_rcv: "
34783 + "inbound policy checking enabled, IPCOMP follows IPIP, dropped.\n");
34784 + if (irs->stats) {
34785 + irs->stats->rx_errors++;
34786 + }
34787 + goto rcvleave;
34788 + }
34789 + /*
34790 + XXX need a ipsec_sa for updating ratio counters but it is not
34791 + following policy anyways so it is not a priority
34792 + */
34793 + skb = skb_decompress(skb, NULL, &flags);
34794 + if (!skb || flags) {
34795 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
34796 + "klips_debug:ipsec_rcv: "
34797 + "skb_decompress() returned error flags: %d, dropped.\n",
34798 + flags);
34799 + if (irs->stats) {
34800 + irs->stats->rx_errors++;
34801 + }
34802 + goto rcvleave;
34803 + }
34804 + }
34805 +#endif /* CONFIG_KLIPS_IPCOMP */
34806 +
34807 + /*
34808 + * make sure that data now starts at IP header, since we are going
34809 + * to pass this back to ip_input (aka netif_rx). Rules for what the
34810 + * pointers wind up a different for 2.6 vs 2.4, so we just fudge it here.
34811 + */
34812 +#ifdef NET_26
34813 + skb->data = skb_push(skb, skb->h.raw - skb->nh.raw);
34814 +#else
34815 + skb->data = skb->nh.raw;
34816 + {
34817 + struct iphdr *iph = skb->nh.iph;
34818 + int len = ntohs(iph->tot_len);
34819 + skb->len = len;
34820 + }
34821 +#endif
34822 +
34823 +#ifdef SKB_RESET_NFCT
34824 + nf_conntrack_put(skb->nfct);
34825 + skb->nfct = NULL;
34826 +#if defined(CONFIG_NETFILTER_DEBUG) && defined(HAVE_SKB_NF_DEBUG)
34827 + skb->nf_debug = 0;
34828 +#endif /* CONFIG_NETFILTER_DEBUG */
34829 +#endif /* SKB_RESET_NFCT */
34830 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
34831 + "klips_debug:ipsec_rcv: "
34832 + "netif_rx() called.\n");
34833 + netif_rx(skb);
34834 + skb=NULL;
34835 +
34836 + rcvleave:
34837 + if(skb) {
34838 + ipsec_kfree_skb(skb);
34839 + }
34840 +
34841 + return(0);
34842 +}
34843 +
34844 +struct sk_buff *ipsec_rcv_unclone(struct sk_buff *skb,
34845 + struct ipsec_rcv_state *irs)
34846 +{
34847 + /* if skb was cloned (most likely due to a packet sniffer such as
34848 + tcpdump being momentarily attached to the interface), make
34849 + a copy of our own to modify */
34850 + if(skb_cloned(skb)) {
34851 + /* include any mac header while copying.. */
34852 + if(skb_headroom(skb) < irs->hard_header_len) {
34853 + printk(KERN_WARNING "klips_error:ipsec_rcv: "
34854 + "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
34855 + irs->hard_header_len,
34856 + skb_headroom(skb));
34857 + goto rcvleave;
34858 + }
34859 + skb_push(skb, irs->hard_header_len);
34860 + if
34861 +#ifdef SKB_COW_NEW
34862 + (skb_cow(skb, skb_headroom(skb)) != 0)
34863 +#else /* SKB_COW_NEW */
34864 + ((skb = skb_cow(skb, skb_headroom(skb))) == NULL)
34865 +#endif /* SKB_COW_NEW */
34866 + {
34867 + goto rcvleave;
34868 + }
34869 + if(skb->len < irs->hard_header_len) {
34870 + printk(KERN_WARNING "klips_error:ipsec_rcv: "
34871 + "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
34872 + irs->hard_header_len,
34873 + skb->len);
34874 + goto rcvleave;
34875 + }
34876 + skb_pull(skb, irs->hard_header_len);
34877 + }
34878 + return skb;
34879 +
34880 +rcvleave:
34881 + ipsec_kfree_skb(skb);
34882 + return NULL;
34883 +}
34884 +
34885 +
34886 +#if !defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
34887 +/*
34888 + * decapsulate a UDP encapsulated ESP packet
34889 + */
34890 +struct sk_buff *ipsec_rcv_natt_decap(struct sk_buff *skb
34891 + , struct ipsec_rcv_state *irs
34892 + , int *udp_decap_ret_p)
34893 +{
34894 + *udp_decap_ret_p = 0;
34895 + if (skb->sk && skb->nh.iph && skb->nh.iph->protocol==IPPROTO_UDP) {
34896 + /**
34897 + * Packet comes from udp_queue_rcv_skb so it is already defrag,
34898 + * checksum verified, ... (ie safe to use)
34899 + *
34900 + * If the packet is not for us, return -1 and udp_queue_rcv_skb
34901 + * will continue to handle it (do not kfree skb !!).
34902 + */
34903 +
34904 +#ifndef UDP_OPT_IN_SOCK
34905 + struct udp_opt {
34906 + __u32 esp_in_udp;
34907 + };
34908 + struct udp_opt *tp = (struct udp_opt *)&(skb->sk->tp_pinfo.af_tcp);
34909 +#else
34910 + struct udp_opt *tp = &(skb->sk->tp_pinfo.af_udp);
34911 +#endif
34912 +
34913 + struct iphdr *ip = (struct iphdr *)skb->nh.iph;
34914 + struct udphdr *udp = (struct udphdr *)((__u32 *)ip+ip->ihl);
34915 + __u8 *udpdata = (__u8 *)udp + sizeof(struct udphdr);
34916 + __u32 *udpdata32 = (__u32 *)udpdata;
34917 +
34918 + irs->natt_sport = ntohs(udp->source);
34919 + irs->natt_dport = ntohs(udp->dest);
34920 +
34921 + KLIPS_PRINT(debug_rcv,
34922 + "klips_debug:ipsec_rcv: "
34923 + "suspected ESPinUDP packet (NAT-Traversal) [%d].\n",
34924 + tp->esp_in_udp);
34925 + KLIPS_IP_PRINT(debug_rcv, ip);
34926 +
34927 + if (udpdata < skb->tail) {
34928 + unsigned int len = skb->tail - udpdata;
34929 + if ((len==1) && (udpdata[0]==0xff)) {
34930 + KLIPS_PRINT(debug_rcv,
34931 + "klips_debug:ipsec_rcv: "
34932 + /* not IPv6 compliant message */
34933 + "NAT-keepalive from %d.%d.%d.%d.\n", NIPQUAD(ip->saddr));
34934 + *udp_decap_ret_p = 0;
34935 + return NULL;
34936 + }
34937 + else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_IKE) &&
34938 + (len > (2*sizeof(__u32) + sizeof(struct esphdr))) &&
34939 + (udpdata32[0]==0) && (udpdata32[1]==0) ) {
34940 + /* ESP Packet with Non-IKE header */
34941 + KLIPS_PRINT(debug_rcv,
34942 + "klips_debug:ipsec_rcv: "
34943 + "ESPinUDP pkt with Non-IKE - spi=0x%x\n",
34944 + ntohl(udpdata32[2]));
34945 + irs->natt_type = ESPINUDP_WITH_NON_IKE;
34946 + irs->natt_len = sizeof(struct udphdr)+(2*sizeof(__u32));
34947 + }
34948 + else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_ESP) &&
34949 + (len > sizeof(struct esphdr)) &&
34950 + (udpdata32[0]!=0) ) {
34951 + /* ESP Packet without Non-ESP header */
34952 + irs->natt_type = ESPINUDP_WITH_NON_ESP;
34953 + irs->natt_len = sizeof(struct udphdr);
34954 + KLIPS_PRINT(debug_rcv,
34955 + "klips_debug:ipsec_rcv: "
34956 + "ESPinUDP pkt without Non-ESP - spi=0x%x\n",
34957 + ntohl(udpdata32[0]));
34958 + }
34959 + else {
34960 + KLIPS_PRINT(debug_rcv,
34961 + "klips_debug:ipsec_rcv: "
34962 + "IKE packet - not handled here\n");
34963 + *udp_decap_ret_p = -1;
34964 + return NULL;
34965 + }
34966 + }
34967 + else {
34968 + return NULL;
34969 + }
34970 + }
34971 + return skb;
34972 +}
34973 +#endif
34974 +
34975 +/* management of buffers */
34976 +static struct ipsec_rcv_state * ipsec_rcv_state_new (void);
34977 +static void ipsec_rcv_state_delete (struct ipsec_rcv_state *irs);
34978 +
34979 +int
34980 +ipsec_rcv(struct sk_buff *skb
34981 +#ifndef PROTO_HANDLER_SINGLE_PARM
34982 + unsigned short xlen
34983 +#endif /* PROTO_HANDLER_SINGLE_PARM */
34984 + )
34985 +{
34986 +#ifdef CONFIG_KLIPS_DEBUG
34987 + struct net_device *dev = skb->dev;
34988 +#endif /* CONFIG_KLIPS_DEBUG */
34989 + unsigned char protoc;
34990 + struct net_device_stats *stats = NULL; /* This device's statistics */
34991 + struct net_device *ipsecdev = NULL, *prvdev;
34992 + struct ipsecpriv *prv;
34993 + struct ipsec_rcv_state *irs = NULL;
34994 + struct iphdr *ipp;
34995 + char name[9];
34996 + int i;
34997 +
34998 + /* Don't unlink in the middle of a turnaround */
34999 + KLIPS_INC_USE;
35000 +
35001 + if (skb == NULL) {
35002 + KLIPS_PRINT(debug_rcv,
35003 + "klips_debug:ipsec_rcv: "
35004 + "NULL skb passed in.\n");
35005 + goto error_no_skb;
35006 + }
35007 +
35008 + if (skb->data == NULL) {
35009 + KLIPS_PRINT(debug_rcv,
35010 + "klips_debug:ipsec_rcv: "
35011 + "NULL skb->data passed in, packet is bogus, dropping.\n");
35012 + goto error_bad_skb;
35013 + }
35014 +
35015 + irs = ipsec_rcv_state_new ();
35016 + if (unlikely (! irs)) {
35017 + KLIPS_PRINT(debug_rcv,
35018 + "klips_debug:ipsec_rcv: "
35019 + "failled to allocate a rcv state object\n");
35020 + goto error_alloc;
35021 + }
35022 +
35023 +#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(NET_26)
35024 + {
35025 + /* NET_26 NAT-T is handled by seperate function */
35026 + struct sk_buff *nskb;
35027 + int udp_decap_ret = 0;
35028 +
35029 + nskb = ipsec_rcv_natt_decap(skb, irs, &udp_decap_ret);
35030 + if(nskb == NULL) {
35031 + /* return with non-zero, because UDP.c code
35032 + * need to send it upstream.
35033 + */
35034 + if(skb && udp_decap_ret == 0) {
35035 + ipsec_kfree_skb(skb);
35036 + }
35037 + KLIPS_DEC_USE;
35038 + return(udp_decap_ret);
35039 + }
35040 + skb = nskb;
35041 + }
35042 +#endif /* NAT_T */
35043 +
35044 + /* dev->hard_header_len is unreliable and should not be used */
35045 + irs->hard_header_len = skb->mac.raw ? (skb->nh.raw - skb->mac.raw) : 0;
35046 + if((irs->hard_header_len < 0) || (irs->hard_header_len > skb_headroom(skb)))
35047 + irs->hard_header_len = 0;
35048 +
35049 + skb = ipsec_rcv_unclone(skb, irs);
35050 + if(skb == NULL) {
35051 + goto rcvleave;
35052 + }
35053 +
35054 +#if IP_FRAGMENT_LINEARIZE
35055 + /* In Linux 2.4.4, we may have to reassemble fragments. They are
35056 + not assembled automatically to save TCP from having to copy
35057 + twice.
35058 + */
35059 + if (skb_is_nonlinear(skb)) {
35060 +#ifdef HAVE_NEW_SKB_LINEARIZE
35061 + if (skb_linearize_cow(skb) != 0)
35062 +#else
35063 + if (skb_linearize(skb, GFP_ATOMIC) != 0)
35064 +#endif
35065 + {
35066 + goto rcvleave;
35067 + }
35068 + }
35069 +#endif /* IP_FRAGMENT_LINEARIZE */
35070 +
35071 +#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(NET_26)
35072 + if (irs->natt_len) {
35073 + /**
35074 + * Now, we are sure packet is ESPinUDP, and we have a private
35075 + * copy that has been linearized, remove natt_len bytes
35076 + * from packet and modify protocol to ESP.
35077 + */
35078 + if (((unsigned char *)skb->data > (unsigned char *)skb->nh.iph)
35079 + && ((unsigned char *)skb->nh.iph > (unsigned char *)skb->head))
35080 + {
35081 + unsigned int _len = (unsigned char *)skb->data -
35082 + (unsigned char *)skb->nh.iph;
35083 + KLIPS_PRINT(debug_rcv,
35084 + "klips_debug:ipsec_rcv: adjusting skb: skb_push(%u)\n",
35085 + _len);
35086 + skb_push(skb, _len);
35087 + }
35088 + KLIPS_PRINT(debug_rcv,
35089 + "klips_debug:ipsec_rcv: "
35090 + "removing %d bytes from ESPinUDP packet\n", irs->natt_len);
35091 + ipp = skb->nh.iph;
35092 + irs->iphlen = ipp->ihl << 2;
35093 + ipp->tot_len = htons(ntohs(ipp->tot_len) - irs->natt_len);
35094 + if (skb->len < irs->iphlen + irs->natt_len) {
35095 + printk(KERN_WARNING
35096 + "klips_error:ipsec_rcv: "
35097 + "ESPinUDP packet is too small (%d < %d+%d). "
35098 + "This should never happen, please report.\n",
35099 + (int)(skb->len), irs->iphlen, irs->natt_len);
35100 + goto rcvleave;
35101 + }
35102 +
35103 + /* advance payload pointer to point past the UDP header */
35104 + skb->h.raw = skb->h.raw + irs->natt_len;
35105 +
35106 + /* modify protocol */
35107 + ipp->protocol = IPPROTO_ESP;
35108 +
35109 + skb->sk = NULL;
35110 +
35111 + KLIPS_IP_PRINT(debug_rcv, skb->nh.iph);
35112 + }
35113 +#endif
35114 +
35115 + ipp = skb->nh.iph;
35116 +
35117 + {
35118 + struct in_addr ipsaddr;
35119 + struct in_addr ipdaddr;
35120 +
35121 + ipsaddr.s_addr = ipp->saddr;
35122 + addrtoa(ipsaddr, 0, irs->ipsaddr_txt
35123 + , sizeof(irs->ipsaddr_txt));
35124 + ipdaddr.s_addr = ipp->daddr;
35125 + addrtoa(ipdaddr, 0, irs->ipdaddr_txt
35126 + , sizeof(irs->ipdaddr_txt));
35127 + }
35128 +
35129 + irs->iphlen = ipp->ihl << 2;
35130 +
35131 + KLIPS_PRINT(debug_rcv,
35132 + "klips_debug:ipsec_rcv: "
35133 + "<<< Info -- ");
35134 + KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ",
35135 + skb->dev->name ? skb->dev->name : "NULL");
35136 + KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ",
35137 + dev->name ? dev->name : "NULL");
35138 + KLIPS_PRINTMORE(debug_rcv, "\n");
35139 +
35140 + KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)),
35141 + "klips_debug:ipsec_rcv: "
35142 + "Informational -- **if this happens, find out why** skb->dev:%s is not equal to dev:%s\n",
35143 + skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL",
35144 + dev ? (dev->name ? dev->name : "NULL") : "NULL");
35145 +
35146 + protoc = ipp->protocol;
35147 +#ifndef NET_21
35148 + if((!protocol) || (protocol->protocol != protoc)) {
35149 + KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
35150 + "klips_debug:ipsec_rcv: "
35151 + "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n");
35152 + }
35153 +#endif /* !NET_21 */
35154 +
35155 + if( (protoc != IPPROTO_AH) &&
35156 +#ifdef CONFIG_KLIPS_IPCOMP_disabled_until_we_register_IPCOMP_HANDLER
35157 + (protoc != IPPROTO_COMP) &&
35158 +#endif /* CONFIG_KLIPS_IPCOMP */
35159 + (protoc != IPPROTO_ESP) ) {
35160 + KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
35161 + "klips_debug:ipsec_rcv: Why the hell is someone "
35162 + "passing me a non-ipsec protocol = %d packet? -- dropped.\n",
35163 + protoc);
35164 + goto rcvleave;
35165 + }
35166 +
35167 + if(skb->dev) {
35168 + for(i = 0; i < IPSEC_NUM_IF; i++) {
35169 + sprintf(name, IPSEC_DEV_FORMAT, i);
35170 + if(!strcmp(name, skb->dev->name)) {
35171 + prv = (struct ipsecpriv *)(skb->dev->priv);
35172 + if(prv) {
35173 + stats = (struct net_device_stats *) &(prv->mystats);
35174 + }
35175 + ipsecdev = skb->dev;
35176 + KLIPS_PRINT(debug_rcv,
35177 + "klips_debug:ipsec_rcv: "
35178 + "Info -- pkt already proc'ed a group of ipsec headers, processing next group of ipsec headers.\n");
35179 + break;
35180 + }
35181 + if((ipsecdev = __ipsec_dev_get(name)) == NULL) {
35182 + KLIPS_PRINT(debug_rcv,
35183 + "klips_error:ipsec_rcv: "
35184 + "device %s does not exist\n",
35185 + name);
35186 + }
35187 + prv = ipsecdev ? (struct ipsecpriv *)(ipsecdev->priv) : NULL;
35188 + prvdev = prv ? (struct net_device *)(prv->dev) : NULL;
35189 +
35190 +#if 0
35191 + KLIPS_PRINT(debug_rcv && prvdev,
35192 + "klips_debug:ipsec_rcv: "
35193 + "physical device for device %s is %s\n",
35194 + name,
35195 + prvdev->name);
35196 +#endif
35197 + if(prvdev && skb->dev &&
35198 + !strcmp(prvdev->name, skb->dev->name)) {
35199 + stats = prv ? ((struct net_device_stats *) &(prv->mystats)) : NULL;
35200 + skb->dev = ipsecdev;
35201 + KLIPS_PRINT(debug_rcv && prvdev,
35202 + "klips_debug:ipsec_rcv: "
35203 + "assigning packet ownership to virtual device %s from physical device %s.\n",
35204 + name, prvdev->name);
35205 + if(stats) {
35206 + stats->rx_packets++;
35207 + }
35208 + break;
35209 + }
35210 + }
35211 + } else {
35212 + KLIPS_PRINT(debug_rcv,
35213 + "klips_debug:ipsec_rcv: "
35214 + "device supplied with skb is NULL\n");
35215 + }
35216 +
35217 + if(stats == NULL) {
35218 + KLIPS_PRINT((debug_rcv),
35219 + "klips_error:ipsec_rcv: "
35220 + "packet received from physical I/F (%s) not connected to ipsec I/F. Cannot record stats. May not have SA for decoding. Is IPSEC traffic expected on this I/F? Check routing.\n",
35221 + skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL");
35222 + }
35223 +
35224 + KLIPS_IP_PRINT(debug_rcv, ipp);
35225 +
35226 + /* set up for decap loop */
35227 + irs->stats= stats;
35228 + irs->ipp = ipp;
35229 + irs->ipsp = NULL;
35230 + irs->ilen = 0;
35231 + irs->authlen=0;
35232 + irs->authfuncs=NULL;
35233 + irs->skb = skb;
35234 +
35235 + (void)ipsec_rcv_decap(irs);
35236 +
35237 + ipsec_rcv_state_delete (irs);
35238 + KLIPS_DEC_USE;
35239 + return(0);
35240 +
35241 +rcvleave:
35242 + ipsec_rcv_state_delete (irs);
35243 +
35244 +error_alloc:
35245 +error_bad_skb:
35246 + ipsec_kfree_skb(skb);
35247 +error_no_skb:
35248 +
35249 + KLIPS_DEC_USE;
35250 + return(0);
35251 +
35252 +}
35253 +
35254 +#ifdef NET_26
35255 +/*
35256 + * this entry point is not a protocol entry point, so the entry
35257 + * is a bit different.
35258 + *
35259 + * skb->iph->tot_len has been byte-swapped, and reduced by the size of
35260 + * the IP header (and options).
35261 + *
35262 + * skb->h.raw has been pulled up the ESP header.
35263 + *
35264 + * skb->iph->protocol = 50 IPPROTO_ESP;
35265 + *
35266 + */
35267 +int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type)
35268 +{
35269 + struct ipsec_rcv_state *irs = NULL;
35270 + struct iphdr *ipp;
35271 +
35272 + /* Don't unlink in the middle of a turnaround */
35273 + KLIPS_INC_USE;
35274 +
35275 + irs = ipsec_rcv_state_new ();
35276 + if (unlikely (! irs)) {
35277 + KLIPS_PRINT(debug_rcv,
35278 + "klips_debug:ipsec_rcv: "
35279 + "failled to allocate a rcv state object\n");
35280 + goto error_alloc;
35281 + }
35282 +
35283 + /* XXX fudge it so that all nat-t stuff comes from ipsec0 */
35284 + /* eventually, the SA itself will determine which device
35285 + * it comes from
35286 + */
35287 + {
35288 + skb->dev = ipsec_get_device(0);
35289 + }
35290 +
35291 + /* set up for decap loop */
35292 + irs->hard_header_len = skb->dev->hard_header_len;
35293 +
35294 + skb = ipsec_rcv_unclone(skb, irs);
35295 +
35296 +#if IP_FRAGMENT_LINEARIZE
35297 + /* In Linux 2.4.4, we may have to reassemble fragments. They are
35298 + not assembled automatically to save TCP from having to copy
35299 + twice.
35300 + */
35301 + if (skb_is_nonlinear(skb)) {
35302 +#ifdef HAVE_NEW_SKB_LINEARIZE
35303 + if (skb_linearize_cow(skb) != 0)
35304 +#else
35305 + if (skb_linearize(skb, GFP_ATOMIC) != 0)
35306 +#endif
35307 + {
35308 + goto rcvleave;
35309 + }
35310 + }
35311 +#endif /* IP_FRAGMENT_LINEARIZE */
35312 +
35313 + ipp = skb->nh.iph;
35314 +
35315 + {
35316 + struct in_addr ipsaddr;
35317 + struct in_addr ipdaddr;
35318 +
35319 + ipsaddr.s_addr = ipp->saddr;
35320 + addrtoa(ipsaddr, 0, irs->ipsaddr_txt
35321 + , sizeof(irs->ipsaddr_txt));
35322 + ipdaddr.s_addr = ipp->daddr;
35323 + addrtoa(ipdaddr, 0, irs->ipdaddr_txt
35324 + , sizeof(irs->ipdaddr_txt));
35325 + }
35326 +
35327 + irs->iphlen = ipp->ihl << 2;
35328 +
35329 + KLIPS_IP_PRINT(debug_rcv, ipp);
35330 +
35331 + irs->stats= NULL;
35332 + irs->ipp = ipp;
35333 + irs->ipsp = NULL;
35334 + irs->ilen = 0;
35335 + irs->authlen=0;
35336 + irs->authfuncs=NULL;
35337 + irs->skb = skb;
35338 +
35339 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
35340 + switch(encap_type) {
35341 + case UDP_ENCAP_ESPINUDP:
35342 + irs->natt_type = ESPINUDP_WITH_NON_ESP;
35343 + break;
35344 +
35345 + case UDP_ENCAP_ESPINUDP_NON_IKE:
35346 + irs->natt_type = ESPINUDP_WITH_NON_IKE;
35347 + break;
35348 +
35349 + default:
35350 + if(printk_ratelimit()) {
35351 + printk(KERN_INFO "KLIPS received unknown UDP-ESP encap type %u\n",
35352 + encap_type);
35353 + }
35354 + return -1;
35355 + }
35356 +
35357 +#endif
35358 + ipsec_rcv_decap(irs);
35359 +
35360 + KLIPS_DEC_USE;
35361 + ipsec_rcv_state_delete (irs);
35362 + return 0;
35363 +
35364 +rcvleave:
35365 + if(skb) {
35366 + ipsec_kfree_skb(skb);
35367 + }
35368 + ipsec_rcv_state_delete (irs);
35369 +error_alloc:
35370 + KLIPS_DEC_USE;
35371 + return 0;
35372 +}
35373 +#endif
35374 +
35375 +// ------------------------------------------------------------------------
35376 +// this handles creating and managing state for recv path
35377 +
35378 +static spinlock_t irs_cache_lock = SPIN_LOCK_UNLOCKED;
35379 +static kmem_cache_t *irs_cache_allocator = NULL;
35380 +static unsigned irs_cache_allocated_count = 0;
35381 +
35382 +int
35383 +ipsec_rcv_state_cache_init (void)
35384 +{
35385 + if (irs_cache_allocator)
35386 + return -EBUSY;
35387 +
35388 + spin_lock_init(&irs_cache_lock);
35389 +
35390 + irs_cache_allocator = kmem_cache_create ("ipsec_irs",
35391 + sizeof (struct ipsec_rcv_state), 0,
35392 + 0, NULL, NULL);
35393 + if (! irs_cache_allocator)
35394 + return -ENOMEM;
35395 +
35396 + return 0;
35397 +}
35398 +
35399 +void
35400 +ipsec_rcv_state_cache_cleanup (void)
35401 +{
35402 + if (unlikely (irs_cache_allocated_count))
35403 + printk ("ipsec: deleting ipsec_irs kmem_cache while in use\n");
35404 +
35405 + if (irs_cache_allocator) {
35406 + kmem_cache_destroy (irs_cache_allocator);
35407 + irs_cache_allocator = NULL;
35408 + }
35409 + irs_cache_allocated_count = 0;
35410 +}
35411 +
35412 +static struct ipsec_rcv_state *
35413 +ipsec_rcv_state_new (void)
35414 +{
35415 + struct ipsec_rcv_state *irs;
35416 +
35417 + spin_lock_bh (&irs_cache_lock);
35418 +
35419 + irs = kmem_cache_alloc (irs_cache_allocator, GFP_ATOMIC);
35420 +
35421 + if (likely (irs != NULL))
35422 + irs_cache_allocated_count++;
35423 +
35424 + spin_unlock_bh (&irs_cache_lock);
35425 +
35426 + if (unlikely (NULL == irs))
35427 + goto bail;
35428 +
35429 + // initialize the object
35430 + memset((caddr_t)irs, 0, sizeof(*irs));
35431 +
35432 +bail:
35433 + return irs;
35434 +}
35435 +
35436 +static void
35437 +ipsec_rcv_state_delete (struct ipsec_rcv_state *irs)
35438 +{
35439 + if (unlikely (! irs))
35440 + return;
35441 +
35442 + spin_lock_bh (&irs_cache_lock);
35443 +
35444 + irs_cache_allocated_count--;
35445 + kmem_cache_free (irs_cache_allocator, irs);
35446 +
35447 + spin_unlock_bh (&irs_cache_lock);
35448 +}
35449 +
35450 +/*
35451 + * $Log: ipsec_rcv.c,v $
35452 + * Revision 1.178 2005/10/21 02:19:34 mcr
35453 + * on 2.4 systems, we have to fix up the length as well.
35454 + *
35455 + * Revision 1.171.2.7 2006/04/20 16:33:07 mcr
35456 + * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
35457 + * Fix in-kernel module compilation. Sub-makefiles do not work.
35458 + *
35459 + * Revision 1.171.2.6 2005/12/07 06:07:04 paul
35460 + * comment out KLIPS_DEC_USE in ipsec_rcv_decap. Likely an artifact from
35461 + * refactoring. http://bugs.xelerance.com/view.php?id=454
35462 + *
35463 + * Revision 1.171.2.5 2005/10/21 02:22:29 mcr
35464 + * pull up of another try at 2.4.x kernel fix
35465 + *
35466 + * Revision 1.171.2.4 2005/10/21 01:39:56 mcr
35467 + * nat-t fix is 2.4/2.6 specific
35468 + *
35469 + * Revision 1.178 2005/10/21 02:19:34 mcr
35470 + * on 2.4 systems, we have to fix up the length as well.
35471 + *
35472 + * Revision 1.177 2005/10/21 00:18:31 mcr
35473 + * nat-t fix is 2.4 specific.
35474 + *
35475 + * Revision 1.176 2005/10/20 21:06:11 mcr
35476 + * possible fix for nat-t problem on 2.4 kernels.
35477 + *
35478 + * Revision 1.175 2005/10/13 02:49:24 mcr
35479 + * tested UDP-encapsulated ESP packets that were not actually ESP,
35480 + * (but IKE) were being eaten.
35481 + *
35482 + * Revision 1.174 2005/10/13 01:25:22 mcr
35483 + * UDP-encapsulated ESP packets that were not actually ESP,
35484 + * (but IKE) were being eaten.
35485 + *
35486 + * Revision 1.173 2005/08/31 23:26:11 mcr
35487 + * fixes for 2.6.13
35488 + *
35489 + * Revision 1.172 2005/08/05 08:44:54 mcr
35490 + * ipsec_kern24.h (compat code for 2.4) must be include
35491 + * explicitely now.
35492 + *
35493 + * Revision 1.171 2005/07/08 23:56:06 ken
35494 + * #ifdef
35495 + *
35496 + * Revision 1.170 2005/07/08 23:50:05 ken
35497 + * Don't attempt to decapsulate if NAT-T isn't available in the code
35498 + *
35499 + * Revision 1.169 2005/06/06 00:27:31 mcr
35500 + * fix for making tcpdump (packet capture) work correctly for
35501 + * nat-t received packets.
35502 + *
35503 + * Revision 1.168 2005/06/04 16:06:06 mcr
35504 + * better patch for nat-t rcv-device code.
35505 + *
35506 + * Revision 1.167 2005/06/03 17:04:46 mcr
35507 + * nat-t packets are forced to arrive from ipsec0.
35508 + *
35509 + * Revision 1.166 2005/04/29 05:10:22 mcr
35510 + * removed from extraenous includes to make unit testing easier.
35511 + *
35512 + * Revision 1.165 2005/04/20 17:11:32 mcr
35513 + * fixed to compile on 2.4.
35514 + *
35515 + * Revision 1.164 2005/04/18 03:09:50 ken
35516 + * Fix typo
35517 + *
35518 + * Revision 1.163 2005/04/17 05:32:58 mcr
35519 + * remove extraneous debugging
35520 + * make sure to return success from klips26_encap_rcv().
35521 + *
35522 + * Revision 1.162 2005/04/17 04:37:01 mcr
35523 + * make sure that irs->ipp is still set.
35524 + *
35525 + * Revision 1.161 2005/04/17 03:51:52 mcr
35526 + * removed old comment about removed code.
35527 + * added translation from udp.c/2.6 to KLIPS NAT-ESP naming.
35528 + * comment about check for origin address/port for incoming NAT-ESP packets.
35529 + *
35530 + * Revision 1.160 2005/04/15 19:55:58 mcr
35531 + * adjustments to use proper skb fields for data.
35532 + *
35533 + * Revision 1.159 2005/04/10 22:58:20 mcr
35534 + * refactoring of receive functions to make it easier to
35535 + * call the ESP decap.
35536 + *
35537 + * Revision 1.158 2005/04/08 18:27:53 mcr
35538 + * refactored ipsec_rcv() into ipsec_rcv() and ipsec_rcv_decap().
35539 + *
35540 + * Revision 1.157 2004/12/28 23:13:09 mcr
35541 + * use consistent CONFIG_IPSEC_NAT_TRAVERSAL.
35542 + *
35543 + * Revision 1.156 2004/12/03 21:34:51 mcr
35544 + * mistype of KLIPS_USE_COUNT -> KLIPS_INC_USE;
35545 + *
35546 + * Revision 1.155 2004/12/03 21:25:57 mcr
35547 + * compile time fixes for running on 2.6.
35548 + * still experimental.
35549 + *
35550 + * Revision 1.154 2004/09/08 17:21:36 ken
35551 + * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
35552 + *
35553 + * Revision 1.153 2004/08/22 20:10:00 mcr
35554 + * removed check for incorrect setting of NET_26.
35555 + *
35556 + * Revision 1.152 2004/08/21 15:22:39 mcr
35557 + * added #defines for ATT heartbeat.
35558 + *
35559 + * Revision 1.151 2004/08/21 02:16:32 ken
35560 + * Patch from Jochen Eisinger for AT&T MTS Heartbeat packet support
35561 + *
35562 + * Revision 1.150 2004/08/21 00:44:48 mcr
35563 + * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
35564 + *
35565 + * Revision 1.149 2004/08/20 21:45:45 mcr
35566 + * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
35567 + * be 26sec compatible. But, some defines where changed.
35568 + *
35569 + * Revision 1.148 2004/08/17 03:27:23 mcr
35570 + * klips 2.6 edits.
35571 + *
35572 + * Revision 1.147 2004/08/05 23:29:27 mcr
35573 + * fixed nesting of #ifdef vs {} in ipsec_rcv().
35574 + *
35575 + * Revision 1.146 2004/08/04 15:57:07 mcr
35576 + * moved des .h files to include/des/ *
35577 + * included 2.6 protocol specific things
35578 + * started at NAT-T support, but it will require a kernel patch.
35579 + *
35580 + * Revision 1.145 2004/08/03 18:19:08 mcr
35581 + * in 2.6, use "net_device" instead of #define device->net_device.
35582 + * this probably breaks 2.0 compiles.
35583 + *
35584 + * Revision 1.144 2004/07/10 19:11:18 mcr
35585 + * CONFIG_IPSEC -> CONFIG_KLIPS.
35586 + *
35587 + * Revision 1.143 2004/05/10 22:27:00 mcr
35588 + * fix for ESP-3DES-noauth test case.
35589 + *
35590 + * Revision 1.142 2004/05/10 22:25:57 mcr
35591 + * reformat of calls to ipsec_lifetime_check().
35592 + *
35593 + * Revision 1.141 2004/04/06 02:49:26 mcr
35594 + * pullup of algo code from alg-branch.
35595 + *
35596 + * Revision 1.140 2004/02/03 03:12:53 mcr
35597 + * removed erroneously, double patched code.
35598 + *
35599 + * Revision 1.139 2004/01/05 23:21:29 mcr
35600 + * initialize sin_family in ipsec_rcv.c
35601 + *
35602 + * Revision 1.138 2003/12/24 19:46:52 mcr
35603 + * if sock.h patch has not been applied, then define appropriate
35604 + * structure so we can use it. This is serious inferior, and
35605 + * depends upon the concept that the structure in question is
35606 + * smaller than the other members of that union.
35607 + * getting rid of differing methods is a better solution.
35608 + *
35609 + * Revision 1.137 2003/12/22 19:40:57 mcr
35610 + * NAT-T patches 0.6c.
35611 + *
35612 + * Revision 1.136 2003/12/15 18:13:12 mcr
35613 + * when compiling with NAT traversal, don't assume that the
35614 + * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
35615 + * is set.
35616 + *
35617 + * Revision 1.135 2003/12/13 19:10:21 mcr
35618 + * refactored rcv and xmit code - same as FS 2.05.
35619 + *
35620 + * Revision 1.134.2.1 2003/12/22 15:25:52 jjo
35621 + * Merged algo-0.8.1-rc11-test1 into alg-branch
35622 + *
35623 + * Revision 1.134 2003/12/10 01:14:27 mcr
35624 + * NAT-traversal patches to KLIPS.
35625 + *
35626 + * Revision 1.133 2003/10/31 02:27:55 mcr
35627 + * pulled up port-selector patches and sa_id elimination.
35628 + *
35629 + * Revision 1.132.2.1 2003/10/29 01:30:41 mcr
35630 + * elimited "struct sa_id".
35631 + *
35632 + * Revision 1.132 2003/09/02 19:51:48 mcr
35633 + * fixes for PR#252.
35634 + *
35635 + * Revision 1.131 2003/07/31 22:47:16 mcr
35636 + * preliminary (untested by FS-team) 2.5 patches.
35637 + *
35638 + * Revision 1.130 2003/04/03 17:38:25 rgb
35639 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
35640 + * Clarified logic for non-connected devices.
35641 + *
35642 + * Revision 1.129 2003/02/06 02:21:34 rgb
35643 + *
35644 + * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
35645 + * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
35646 + * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
35647 + *
35648 + * Revision 1.128 2002/12/13 20:58:03 rgb
35649 + * Relegated MCR's recent "_dmp" routine to debug_verbose.
35650 + * Cleaned up printing of source and destination addresses in debug output.
35651 + *
35652 + * Revision 1.127 2002/12/04 16:00:16 rgb
35653 + *
35654 + * Fixed AH decapsulation pointer update bug and added some comments and
35655 + * debugging.
35656 + * This bug was caught by west-ah-0[12].
35657 + *
35658 + * Revision 1.126 2002/11/04 05:03:43 mcr
35659 + * fixes for IPCOMP. There were two problems:
35660 + * 1) the irs->ipp pointer was not being updated properly after
35661 + * the ESP descryption. The meant nothing for IPIP, as the
35662 + * later IP header overwrote the earlier one.
35663 + * 2) the more serious problem was that skb_decompress will
35664 + * usually allocate a new SKB, so we have to make sure that
35665 + * it doesn't get lost.
35666 + * #2 meant removing the skb argument from the ->decrypt routine
35667 + * and moving it to the irs->skb, so it could be value/result.
35668 + *
35669 + * Revision 1.125 2002/11/01 01:53:35 dhr
35670 + *
35671 + * fix typo
35672 + *
35673 + * Revision 1.124 2002/10/31 22:49:01 dhr
35674 + *
35675 + * - eliminate unused variable "hash"
35676 + * - reduce scope of variable "authenticator"
35677 + * - add comment on a couple of tricky bits
35678 + *
35679 + * Revision 1.123 2002/10/31 22:39:56 dhr
35680 + *
35681 + * use correct type for result of function calls
35682 + *
35683 + * Revision 1.122 2002/10/31 22:36:25 dhr
35684 + *
35685 + * simplify complex test
35686 + *
35687 + * Revision 1.121 2002/10/31 22:34:04 dhr
35688 + *
35689 + * ipsprev is never used: ditch it
35690 + *
35691 + * Revision 1.120 2002/10/31 22:30:21 dhr
35692 + *
35693 + * eliminate redundant assignments
35694 + *
35695 + * Revision 1.119 2002/10/31 22:27:43 dhr
35696 + *
35697 + * make whitespace canonical
35698 + *
35699 + * Revision 1.118 2002/10/30 05:47:17 rgb
35700 + * Fixed cut-and-paste error mis-identifying comp runt as ah.
35701 + *
35702 + * Revision 1.117 2002/10/17 16:37:45 rgb
35703 + * Remove compp intermediate variable and in-line its contents
35704 + * where used
35705 + *
35706 + * Revision 1.116 2002/10/12 23:11:53 dhr
35707 + *
35708 + * [KenB + DHR] more 64-bit cleanup
35709 + *
35710 + * Revision 1.115 2002/10/07 19:06:58 rgb
35711 + * Minor fixups and activation to west-rcv-nfmark-set-01 test to check for SA reference properly set on incoming.
35712 + *
35713 + * Revision 1.114 2002/10/07 18:31:31 rgb
35714 + * Set saref on incoming packets.
35715 + *
35716 + * Revision 1.113 2002/09/16 21:28:12 mcr
35717 + * adjust hash length for HMAC calculation - must look at whether
35718 + * it is MD5 or SHA1.
35719 + *
35720 + * Revision 1.112 2002/09/16 21:19:15 mcr
35721 + * fixes for west-ah-icmp-01 - length of AH header must be
35722 + * calculated properly, and next_header field properly copied.
35723 + *
35724 + * Revision 1.111 2002/09/10 02:45:56 mcr
35725 + * re-factored the ipsec_rcv function into several functions,
35726 + * ipsec_rcv_decap_once, and a set of functions for AH, ESP and IPCOMP.
35727 + * In addition, the MD5 and SHA1 functions are replaced with pointers.
35728 + *
35729 + * Revision 1.110 2002/08/30 06:34:33 rgb
35730 + * Fix scope of shift in AH header length check.
35731 + *
35732 + * Revision 1.109 2002/08/27 16:49:20 rgb
35733 + * Fixed ESP short packet DOS (and AH and IPCOMP).
35734 + *
35735 + * Revision 1.108 2002/07/24 18:44:54 rgb
35736 + * Type fiddling to tame ia64 compiler.
35737 + *
35738 + * Revision 1.107 2002/05/27 18:58:18 rgb
35739 + * Convert to dynamic ipsec device allocation.
35740 + * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
35741 + *
35742 + * Revision 1.106 2002/05/23 07:15:21 rgb
35743 + * Pointer clean-up.
35744 + * Added refcount code.
35745 + *
35746 + * Revision 1.105 2002/05/14 02:35:06 rgb
35747 + * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
35748 + * ipsec_sa or ipsec_sa.
35749 + * Change references to _TDB to _IPSA.
35750 + *
35751 + * Revision 1.104 2002/04/24 07:55:32 mcr
35752 + * #include patches and Makefiles for post-reorg compilation.
35753 + *
35754 + * Revision 1.103 2002/04/24 07:36:30 mcr
35755 + * Moved from ./klips/net/ipsec/ipsec_rcv.c,v
35756 + *
35757 + * Revision 1.102 2002/01/29 17:17:56 mcr
35758 + * moved include of ipsec_param.h to after include of linux/kernel.h
35759 + * otherwise, it seems that some option that is set in ipsec_param.h
35760 + * screws up something subtle in the include path to kernel.h, and
35761 + * it complains on the snprintf() prototype.
35762 + *
35763 + * Revision 1.101 2002/01/29 04:00:52 mcr
35764 + * more excise of kversions.h header.
35765 + *
35766 + * Revision 1.100 2002/01/29 02:13:17 mcr
35767 + * introduction of ipsec_kversion.h means that include of
35768 + * ipsec_param.h must preceed any decisions about what files to
35769 + * include to deal with differences in kernel source.
35770 + *
35771 + * Revision 1.99 2002/01/28 21:40:59 mcr
35772 + * should use #if to test boolean option rather than #ifdef.
35773 + *
35774 + * Revision 1.98 2002/01/20 20:19:36 mcr
35775 + * renamed option to IP_FRAGMENT_LINEARIZE.
35776 + *
35777 + * Revision 1.97 2002/01/12 02:55:36 mcr
35778 + * fix for post-2.4.4 to linearize skb's when ESP packet
35779 + * was assembled from fragments.
35780 + *
35781 + * Revision 1.96 2001/11/26 09:23:49 rgb
35782 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
35783 + *
35784 + * Revision 1.93.2.2 2001/10/22 20:54:07 mcr
35785 + * include des.h, removed phony prototypes and fixed calling
35786 + * conventions to match real prototypes.
35787 + *
35788 + * Revision 1.93.2.1 2001/09/25 02:22:22 mcr
35789 + * struct tdb -> struct ipsec_sa.
35790 + * lifetime checks moved to ipsec_life.c
35791 + * some sa(tdb) manipulation functions renamed.
35792 + *
35793 + * Revision 1.95 2001/11/06 19:49:07 rgb
35794 + * Added variable descriptions.
35795 + * Removed unauthenticated sequence==0 check to prevent DoS.
35796 + *
35797 + * Revision 1.94 2001/10/18 04:45:20 rgb
35798 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
35799 + * lib/freeswan.h version macros moved to lib/kversions.h.
35800 + * Other compiler directive cleanups.
35801 + *
35802 + * Revision 1.93 2001/09/07 22:17:24 rgb
35803 + * Fix for removal of transport layer protocol handler arg in 2.4.4.
35804 + * Fix to accomodate peer non-conformance to IPCOMP rfc2393.
35805 + *
35806 + * Revision 1.92 2001/08/27 19:44:41 rgb
35807 + * Fix error in comment.
35808 + *
35809 + * Revision 1.91 2001/07/20 19:31:48 dhr
35810 + * [DHR] fix source and destination subnets of policy in diagnostic
35811 + *
35812 + * Revision 1.90 2001/07/06 19:51:09 rgb
35813 + * Added inbound policy checking code for IPIP SAs.
35814 + * Renamed unused function argument for ease and intuitive naming.
35815 + *
35816 + * Revision 1.89 2001/06/22 19:35:23 rgb
35817 + * Disable ipcomp processing if we are handed a ipcomp packet with no esp
35818 + * or ah header.
35819 + * Print protocol if we are handed a non-ipsec packet.
35820 + *
35821 + * Revision 1.88 2001/06/20 06:30:47 rgb
35822 + * Fixed transport mode IPCOMP policy check bug.
35823 + *
35824 + * Revision 1.87 2001/06/13 20:58:40 rgb
35825 + * Added parentheses around assignment used as truth value to silence
35826 + * compiler.
35827 + *
35828 + * Revision 1.86 2001/06/07 22:25:23 rgb
35829 + * Added a source address policy check for tunnel mode. It still does
35830 + * not check client addresses and masks.
35831 + * Only decapsulate IPIP if it is expected.
35832 + *
35833 + * Revision 1.85 2001/05/30 08:14:02 rgb
35834 + * Removed vestiges of esp-null transforms.
35835 + *
35836 + * Revision 1.84 2001/05/27 06:12:11 rgb
35837 + * Added structures for pid, packet count and last access time to eroute.
35838 + * Added packet count to beginning of /proc/net/ipsec_eroute.
35839 + *
35840 + * Revision 1.83 2001/05/04 16:45:47 rgb
35841 + * Remove unneeded code. ipp is not used after this point.
35842 + *
35843 + * Revision 1.82 2001/05/04 16:36:00 rgb
35844 + * Fix skb_cow() call for 2.4.4. (SS)
35845 + *
35846 + * Revision 1.81 2001/05/02 14:46:53 rgb
35847 + * Fix typo for compiler directive to pull IPH back.
35848 + *
35849 + * Revision 1.80 2001/04/30 19:46:34 rgb
35850 + * Update for 2.4.4. We now receive the skb with skb->data pointing to
35851 + * h.raw.
35852 + *
35853 + * Revision 1.79 2001/04/23 15:01:15 rgb
35854 + * Added spin_lock() check to prevent double-locking for multiple
35855 + * transforms and hence kernel lock-ups with SMP kernels.
35856 + * Minor spin_unlock() adjustments to unlock before non-dependant prints
35857 + * and IPSEC device stats updates.
35858 + *
35859 + * Revision 1.78 2001/04/21 23:04:24 rgb
35860 + * Check if soft expire has already been sent before sending another to
35861 + * prevent ACQUIRE flooding.
35862 + *
35863 + * Revision 1.77 2001/03/16 07:35:20 rgb
35864 + * Ditch extra #if 1 around now permanent policy checking code.
35865 + *
35866 + * Revision 1.76 2001/02/27 22:24:54 rgb
35867 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
35868 + * Check for satoa() return codes.
35869 + *
35870 + * Revision 1.75 2001/02/19 22:28:30 rgb
35871 + * Minor change to virtual device discovery code to assert which I/F has
35872 + * been found.
35873 + *
35874 + * Revision 1.74 2000/11/25 03:50:36 rgb
35875 + * Oops fix by minor re-arrangement of code to avoid accessing a freed tdb.
35876 + *
35877 + * Revision 1.73 2000/11/09 20:52:15 rgb
35878 + * More spinlock shuffling, locking earlier and unlocking later in rcv to
35879 + * include ipcomp and prevent races, renaming some tdb variables that got
35880 + * forgotten, moving some unlocks to include tdbs and adding a missing
35881 + * unlock. Thanks to Svenning for some of these.
35882 + *
35883 + * Revision 1.72 2000/11/09 20:11:22 rgb
35884 + * Minor shuffles to fix non-standard kernel config option selection.
35885 + *
35886 + * Revision 1.71 2000/11/06 04:36:18 rgb
35887 + * Ditched spin_lock_irqsave in favour of spin_lock.
35888 + * Minor initial protocol check rewrite.
35889 + * Clean up debug printing.
35890 + * Clean up tdb handling on ipcomp.
35891 + * Fixed transport mode null pointer de-reference without ipcomp.
35892 + * Add Svenning's adaptive content compression.
35893 + * Disabled registration of ipcomp handler.
35894 + *
35895 + * Revision 1.70 2000/10/30 23:41:43 henry
35896 + * Hans-Joerg Hoexer's null-pointer fix
35897 + *
35898 + * Revision 1.69 2000/10/10 18:54:16 rgb
35899 + * Added a fix for incoming policy check with ipcomp enabled but
35900 + * uncompressible.
35901 + *
35902 + * Revision 1.68 2000/09/22 17:53:12 rgb
35903 + * Fixed ipcomp tdb pointers update for policy checking.
35904 + *
35905 + * Revision 1.67 2000/09/21 03:40:58 rgb
35906 + * Added more debugging to try and track down the cpi outward copy problem.
35907 + *
35908 + * Revision 1.66 2000/09/20 04:00:10 rgb
35909 + * Changed static functions to DEBUG_NO_STATIC to reveal function names for
35910 + * debugging oopsen.
35911 + *
35912 + * Revision 1.65 2000/09/19 07:07:16 rgb
35913 + * Added debugging to inbound policy check for ipcomp.
35914 + * Added missing spin_unlocks (thanks Svenning!).
35915 + * Fixed misplaced tdbnext pointers causing mismatched ipip policy check.
35916 + * Protect ipcomp policy check following ipip decap with sysctl switch.
35917 + *
35918 + * Revision 1.64 2000/09/18 21:27:29 rgb
35919 + * 2.0 fixes.
35920 + *
35921 + * Revision 1.63 2000/09/18 02:35:50 rgb
35922 + * Added policy checking to ipcomp and re-enabled policy checking by
35923 + * default.
35924 + * Optimised satoa calls.
35925 + *
35926 + * Revision 1.62 2000/09/17 21:02:32 rgb
35927 + * Clean up debugging, removing slow timestamp debug code.
35928 + *
35929 + * Revision 1.61 2000/09/16 01:07:55 rgb
35930 + * Fixed erroneous ref from struct ipcomp to struct ipcomphdr.
35931 + *
35932 + * Revision 1.60 2000/09/15 11:37:01 rgb
35933 + * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
35934 + * IPCOMP zlib deflate code.
35935 + *
35936 + * Revision 1.59 2000/09/15 04:56:20 rgb
35937 + * Remove redundant satoa() call, reformat comment.
35938 + *
35939 + * Revision 1.58 2000/09/13 08:00:52 rgb
35940 + * Flick on inbound policy checking.
35941 + *
35942 + * Revision 1.57 2000/09/12 03:22:19 rgb
35943 + * Converted inbound_policy_check to sysctl.
35944 + * Re-enabled policy backcheck.
35945 + * Moved policy checks to top and within tdb lock.
35946 + *
35947 + * Revision 1.56 2000/09/08 19:12:56 rgb
35948 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
35949 + *
35950 + * Revision 1.55 2000/08/28 18:15:46 rgb
35951 + * Added MB's nf-debug reset patch.
35952 + *
35953 + * Revision 1.54 2000/08/27 01:41:26 rgb
35954 + * More minor tweaks to the bad padding debug code.
35955 + *
35956 + * Revision 1.53 2000/08/24 16:54:16 rgb
35957 + * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level
35958 + * info.
35959 + * Tidied up device reporting at the start of ipsec_rcv.
35960 + * Tidied up bad padding debugging and processing.
35961 + *
35962 + * Revision 1.52 2000/08/20 21:36:03 rgb
35963 + * Activated pfkey_expire() calls.
35964 + * Added a hard/soft expiry parameter to pfkey_expire().
35965 + * Added sanity checking to avoid propagating zero or smaller-length skbs
35966 + * from a bogus decryption.
35967 + * Re-arranged the order of soft and hard expiry to conform to RFC2367.
35968 + * Clean up references to CONFIG_IPSEC_PFKEYv2.
35969 + *
35970 + * Revision 1.51 2000/08/18 21:23:30 rgb
35971 + * Improve bad padding warning so that the printk buffer doesn't get
35972 + * trampled.
35973 + *
35974 + * Revision 1.50 2000/08/01 14:51:51 rgb
35975 + * Removed _all_ remaining traces of DES.
35976 + *
35977 + * Revision 1.49 2000/07/28 13:50:53 rgb
35978 + * Changed enet_statistics to net_device_stats and added back compatibility
35979 + * for pre-2.1.19.
35980 + *
35981 + * Revision 1.48 2000/05/10 19:14:40 rgb
35982 + * Only check usetime against soft and hard limits if the tdb has been
35983 + * used.
35984 + * Cast output of ntohl so that the broken prototype doesn't make our
35985 + * compile noisy.
35986 + *
35987 + * Revision 1.47 2000/05/09 17:45:43 rgb
35988 + * Fix replay bitmap corruption bug upon receipt of bogus packet
35989 + * with correct SPI. This was a DoS.
35990 + *
35991 + * Revision 1.46 2000/03/27 02:31:58 rgb
35992 + * Fixed authentication failure printout bug.
35993 + *
35994 + * Revision 1.45 2000/03/22 16:15:37 rgb
35995 + * Fixed renaming of dev_get (MB).
35996 + *
35997 + * Revision 1.44 2000/03/16 08:17:24 rgb
35998 + * Hardcode PF_KEYv2 support.
35999 + * Fixed minor bug checking AH header length.
36000 + *
36001 + * Revision 1.43 2000/03/14 12:26:59 rgb
36002 + * Added skb->nfct support for clearing netfilter conntrack bits (MB).
36003 + *
36004 + * Revision 1.42 2000/01/26 10:04:04 rgb
36005 + * Fixed inbound policy checking on transport mode bug.
36006 + * Fixed noisy 2.0 printk arguments.
36007 + *
36008 + * Revision 1.41 2000/01/24 20:58:02 rgb
36009 + * Improve debugging/reporting support for (disabled) inbound
36010 + * policy checking.
36011 + *
36012 + * Revision 1.40 2000/01/22 23:20:10 rgb
36013 + * Fixed up inboud policy checking code.
36014 + * Cleaned out unused crud.
36015 + *
36016 + * Revision 1.39 2000/01/21 06:15:29 rgb
36017 + * Added sanity checks on skb_push(), skb_pull() to prevent panics.
36018 + * Fixed cut-and-paste debug_tunnel to debug_rcv.
36019 + * Added inbound policy checking code, disabled.
36020 + * Simplified output code by updating ipp to post-IPIP decapsulation.
36021 + *
36022 + * elided pre-2000 comments. Use "cvs log"
36023 + *
36024 + *
36025 + * Local Variables:
36026 + * c-set-style: linux
36027 + * End:
36028 + *
36029 + */
36030 --- /dev/null Tue Mar 11 13:02:56 2003
36031 +++ linux/net/ipsec/ipsec_sa.c Mon Feb 9 13:51:03 2004
36032 @@ -0,0 +1,1501 @@
36033 +/*
36034 + * Common routines for IPsec SA maintenance routines.
36035 + *
36036 + * Copyright (C) 1996, 1997 John Ioannidis.
36037 + * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
36038 + *
36039 + * This program is free software; you can redistribute it and/or modify it
36040 + * under the terms of the GNU General Public License as published by the
36041 + * Free Software Foundation; either version 2 of the License, or (at your
36042 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
36043 + *
36044 + * This program is distributed in the hope that it will be useful, but
36045 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
36046 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36047 + * for more details.
36048 + *
36049 + * RCSID $Id: ipsec_sa.c,v 1.31 2005/11/11 04:38:56 paul Exp $
36050 + *
36051 + * This is the file formerly known as "ipsec_xform.h"
36052 + *
36053 + */
36054 +
36055 +#ifndef AUTOCONF_INCLUDED
36056 +#include <linux/config.h>
36057 +#endif
36058 +#include <linux/version.h>
36059 +#include <linux/kernel.h> /* printk() */
36060 +
36061 +#include "openswan/ipsec_param.h"
36062 +
36063 +#ifdef MALLOC_SLAB
36064 +# include <linux/slab.h> /* kmalloc() */
36065 +#else /* MALLOC_SLAB */
36066 +# include <linux/malloc.h> /* kmalloc() */
36067 +#endif /* MALLOC_SLAB */
36068 +#include <linux/vmalloc.h> /* vmalloc() */
36069 +#include <linux/errno.h> /* error codes */
36070 +#include <linux/types.h> /* size_t */
36071 +#include <linux/interrupt.h> /* mark_bh */
36072 +
36073 +#include <linux/netdevice.h> /* struct device, and other headers */
36074 +#include <linux/etherdevice.h> /* eth_type_trans */
36075 +#include <linux/ip.h> /* struct iphdr */
36076 +#include <linux/skbuff.h>
36077 +#include <openswan.h>
36078 +#ifdef SPINLOCK
36079 +#ifdef SPINLOCK_23
36080 +#include <linux/spinlock.h> /* *lock* */
36081 +#else /* SPINLOCK_23 */
36082 +#include <asm/spinlock.h> /* *lock* */
36083 +#endif /* SPINLOCK_23 */
36084 +#endif /* SPINLOCK */
36085 +
36086 +#include <net/ip.h>
36087 +
36088 +#include "openswan/radij.h"
36089 +
36090 +#include "openswan/ipsec_stats.h"
36091 +#include "openswan/ipsec_life.h"
36092 +#include "openswan/ipsec_sa.h"
36093 +#include "openswan/ipsec_xform.h"
36094 +
36095 +#include "openswan/ipsec_encap.h"
36096 +#include "openswan/ipsec_radij.h"
36097 +#include "openswan/ipsec_xform.h"
36098 +#include "openswan/ipsec_ipe4.h"
36099 +#include "openswan/ipsec_ah.h"
36100 +#include "openswan/ipsec_esp.h"
36101 +#include "openswan/ipsec_ipip.h"
36102 +#ifdef CONFIG_KLIPS_IPCOMP
36103 +#include "openswan/ipsec_ipcomp.h"
36104 +#endif /* CONFIG_KLIPS_COMP */
36105 +
36106 +#include <openswan/pfkeyv2.h>
36107 +#include <openswan/pfkey.h>
36108 +
36109 +#include "openswan/ipsec_proto.h"
36110 +#include "openswan/ipsec_alg.h"
36111 +
36112 +
36113 +#ifdef CONFIG_KLIPS_DEBUG
36114 +int debug_xform = 0;
36115 +#endif /* CONFIG_KLIPS_DEBUG */
36116 +
36117 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
36118 +
36119 +struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
36120 +#ifdef SPINLOCK
36121 +spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
36122 +#else /* SPINLOCK */
36123 +spinlock_t tdb_lock;
36124 +#endif /* SPINLOCK */
36125 +
36126 +struct ipsec_sadb ipsec_sadb;
36127 +
36128 +/* the sub table must be narrower (or equal) in bits than the variable type
36129 + in the main table to count the number of unused entries in it. */
36130 +typedef struct {
36131 + int testSizeOf_refSubTable :
36132 + ((sizeof(IPsecRefTableUnusedCount) * 8) < IPSEC_SA_REF_SUBTABLE_IDX_WIDTH ? -1 : 1);
36133 +} dummy;
36134 +
36135 +
36136 +/* The field where the saref will be hosted in the skb must be wide enough to
36137 + accomodate the information it needs to store. */
36138 +typedef struct {
36139 + int testSizeOf_refField :
36140 + (IPSEC_SA_REF_HOST_FIELD_WIDTH < IPSEC_SA_REF_TABLE_IDX_WIDTH ? -1 : 1 );
36141 +} dummy2;
36142 +
36143 +
36144 +#define IPS_HASH(said) (((said)->spi + (said)->dst.u.v4.sin_addr.s_addr + (said)->proto) % SADB_HASHMOD)
36145 +
36146 +// private functions for reference counting
36147 +static int ipsec_sa_wipe(struct ipsec_sa *ips);
36148 +
36149 +int
36150 +ipsec_SAref_recycle(void)
36151 +{
36152 + int table, i;
36153 + int error = 0;
36154 + int addone;
36155 +
36156 + ipsec_sadb.refFreeListHead = IPSEC_SAREF_NULL;
36157 + ipsec_sadb.refFreeListTail = IPSEC_SAREF_NULL;
36158 +
36159 + if(ipsec_sadb.refFreeListCont == IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) {
36160 + KLIPS_PRINT(debug_xform,
36161 + "klips_debug:ipsec_SAref_recycle: "
36162 + "end of table reached, continuing at start..\n");
36163 + ipsec_sadb.refFreeListCont = IPSEC_SAREF_FIRST;
36164 + }
36165 +
36166 + KLIPS_PRINT(debug_xform,
36167 + "klips_debug:ipsec_SAref_recycle: "
36168 + "recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n",
36169 + ipsec_sadb.refFreeListCont,
36170 + (ipsec_sadb.refTable[IPsecSAref2table(ipsec_sadb.refFreeListCont)] != NULL) ? IPsecSAref2SA(ipsec_sadb.refFreeListCont) : NULL,
36171 + IPsecSAref2table(ipsec_sadb.refFreeListCont),
36172 + IPsecSAref2entry(ipsec_sadb.refFreeListCont));
36173 +
36174 + /* add one additional table entry */
36175 + addone = 0;
36176 +
36177 + ipsec_sadb.refFreeListHead = IPSEC_SAREF_FIRST;
36178 + for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) {
36179 + table = IPsecSAref2table(ipsec_sadb.refFreeListCont);
36180 + if(addone == 0 && ipsec_sadb.refTable[table] == NULL) {
36181 + addone = 1;
36182 + error = ipsec_SArefSubTable_alloc(table);
36183 + if(error) {
36184 + return error;
36185 + }
36186 + }
36187 + if(ipsec_sadb.refTable[table] == NULL) {
36188 + /* we failed to add a second table, so just stop */
36189 + break;
36190 + }
36191 +
36192 + if(IPsecSAref2SA(ipsec_sadb.refFreeListCont) == NULL) {
36193 + ipsec_sadb.refFreeList[i] = ipsec_sadb.refFreeListCont;
36194 + }
36195 + ipsec_sadb.refFreeListCont++;
36196 + ipsec_sadb.refFreeListTail=i;
36197 + }
36198 +
36199 + if(ipsec_sadb.refFreeListTail == IPSEC_SAREF_NULL) {
36200 + KLIPS_PRINT(debug_xform,
36201 + "klips_debug:ipsec_SAref_recycle: "
36202 + "out of room in the SArefTable.\n");
36203 +
36204 + return(-ENOSPC);
36205 + }
36206 +
36207 + KLIPS_PRINT(debug_xform,
36208 + "klips_debug:ipsec_SAref_recycle: "
36209 + "SArefFreeList partly refilled to %d of %d.\n",
36210 + ipsec_sadb.refFreeListTail,
36211 + IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
36212 + return 0;
36213 +}
36214 +
36215 +int
36216 +ipsec_SArefSubTable_alloc(unsigned table)
36217 +{
36218 + unsigned entry;
36219 + struct IPsecSArefSubTable* SArefsub;
36220 +
36221 + KLIPS_PRINT(debug_xform,
36222 + "klips_debug:ipsec_SArefSubTable_alloc: "
36223 + "allocating %lu bytes for table %u of %u.\n",
36224 + (unsigned long) (IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)),
36225 + table,
36226 + IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
36227 +
36228 + /* allocate another sub-table */
36229 + SArefsub = vmalloc(IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *));
36230 + if(SArefsub == NULL) {
36231 + KLIPS_PRINT(debug_xform,
36232 + "klips_debug:ipsec_SArefSubTable_alloc: "
36233 + "error allocating memory for table %u of %u!\n",
36234 + table,
36235 + IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
36236 + return -ENOMEM;
36237 + }
36238 +
36239 + /* add this sub-table to the main table */
36240 + ipsec_sadb.refTable[table] = SArefsub;
36241 +
36242 + /* initialise each element to NULL */
36243 + KLIPS_PRINT(debug_xform,
36244 + "klips_debug:ipsec_SArefSubTable_alloc: "
36245 + "initialising %u elements (2 ^ %u) of table %u.\n",
36246 + IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
36247 + IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
36248 + table);
36249 + for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
36250 + SArefsub->entry[entry] = NULL;
36251 + }
36252 +
36253 + return 0;
36254 +}
36255 +
36256 +int
36257 +ipsec_saref_verify_slot(IPsecSAref_t ref)
36258 +{
36259 + int ref_table=IPsecSAref2table(ref);
36260 +
36261 + if(ipsec_sadb.refTable[ref_table] == NULL) {
36262 + int ret;
36263 + ret = ipsec_SArefSubTable_alloc(ref_table);
36264 + }
36265 +
36266 + return 0;
36267 +}
36268 +
36269 +int
36270 +ipsec_saref_freelist_init(void)
36271 +{
36272 + int i;
36273 +
36274 + KLIPS_PRINT(debug_xform,
36275 + "klips_debug:ipsec_saref_freelist_init: "
36276 + "initialising %u elements of FreeList.\n",
36277 + IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
36278 +
36279 + for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) {
36280 + ipsec_sadb.refFreeList[i] = IPSEC_SAREF_NULL;
36281 + }
36282 + ipsec_sadb.refFreeListHead = IPSEC_SAREF_NULL;
36283 + ipsec_sadb.refFreeListCont = IPSEC_SAREF_FIRST+1;
36284 + ipsec_sadb.refFreeListTail = IPSEC_SAREF_NULL;
36285 +
36286 + return 0;
36287 +}
36288 +
36289 +int
36290 +ipsec_sadb_init(void)
36291 +{
36292 + int error = 0;
36293 + unsigned i;
36294 +
36295 + for(i = 0; i < SADB_HASHMOD; i++) {
36296 + ipsec_sadb_hash[i] = NULL;
36297 + }
36298 + /* parts above are for the old style SADB hash table */
36299 +
36300 +
36301 + /* initialise SA reference table */
36302 +
36303 + /* initialise the main table */
36304 + KLIPS_PRINT(debug_xform,
36305 + "klips_debug:ipsec_sadb_init: "
36306 + "initialising main table of size %u (2 ^ %u).\n",
36307 + IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
36308 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH);
36309 + {
36310 + unsigned table;
36311 + for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
36312 + ipsec_sadb.refTable[table] = NULL;
36313 + }
36314 + }
36315 +
36316 + /* allocate the first sub-table */
36317 + error = ipsec_SArefSubTable_alloc(0);
36318 + if(error) {
36319 + return error;
36320 + }
36321 +
36322 + error = ipsec_saref_freelist_init();
36323 + return error;
36324 +}
36325 +
36326 +IPsecSAref_t
36327 +ipsec_SAref_alloc(int*error) /* pass in error var by pointer */
36328 +{
36329 + IPsecSAref_t SAref;
36330 +
36331 + KLIPS_PRINT(debug_xform,
36332 + "ipsec_SAref_alloc: "
36333 + "SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n",
36334 + ipsec_sadb.refFreeListHead,
36335 + ipsec_sadb.refFreeListCont,
36336 + ipsec_sadb.refFreeListTail,
36337 + IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
36338 +
36339 + if(ipsec_sadb.refFreeListHead == IPSEC_SAREF_NULL) {
36340 + KLIPS_PRINT(debug_xform,
36341 + "ipsec_SAref_alloc: "
36342 + "FreeList empty, recycling...\n");
36343 + *error = ipsec_SAref_recycle();
36344 + if(*error) {
36345 + return IPSEC_SAREF_NULL;
36346 + }
36347 + }
36348 +
36349 + SAref = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead];
36350 + if(SAref == IPSEC_SAREF_NULL) {
36351 + KLIPS_ERROR(debug_xform,
36352 + "ipsec_SAref_alloc: "
36353 + "unexpected error, refFreeListHead = %d points to invalid entry.\n",
36354 + ipsec_sadb.refFreeListHead);
36355 + *error = -ESPIPE;
36356 + return IPSEC_SAREF_NULL;
36357 + }
36358 +
36359 + KLIPS_PRINT(debug_xform,
36360 + "ipsec_SAref_alloc: "
36361 + "allocating SAref=%d, table=%u, entry=%u of %u.\n",
36362 + SAref,
36363 + IPsecSAref2table(SAref),
36364 + IPsecSAref2entry(SAref),
36365 + IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES);
36366 +
36367 + ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead] = IPSEC_SAREF_NULL;
36368 + ipsec_sadb.refFreeListHead++;
36369 + if(ipsec_sadb.refFreeListHead > ipsec_sadb.refFreeListTail) {
36370 + KLIPS_PRINT(debug_xform,
36371 + "ipsec_SAref_alloc: "
36372 + "last FreeList entry allocated, resetting list head to empty.\n");
36373 + ipsec_sadb.refFreeListHead = IPSEC_SAREF_NULL;
36374 + }
36375 +
36376 + return SAref;
36377 +}
36378 +
36379 +int
36380 +ipsec_sa_print(struct ipsec_sa *ips)
36381 +{
36382 + char sa[SATOT_BUF];
36383 + size_t sa_len;
36384 +
36385 + printk(KERN_INFO "klips_debug: SA:");
36386 + if(ips == NULL) {
36387 + printk("NULL\n");
36388 + return -ENOENT;
36389 + }
36390 + printk(" ref=%d", ips->ips_ref);
36391 + printk(" refcount=%d", atomic_read(&ips->ips_refcount));
36392 + if(ips->ips_hnext != NULL) {
36393 + printk(" hnext=0p%p", ips->ips_hnext);
36394 + }
36395 + if(ips->ips_next != NULL) {
36396 + printk(" next=0p%p", ips->ips_next);
36397 + }
36398 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
36399 + printk(" said=%s", sa_len ? sa : " (error)");
36400 + if(ips->ips_seq) {
36401 + printk(" seq=%u", ips->ips_seq);
36402 + }
36403 + if(ips->ips_pid) {
36404 + printk(" pid=%u", ips->ips_pid);
36405 + }
36406 + if(ips->ips_authalg) {
36407 + printk(" authalg=%u", ips->ips_authalg);
36408 + }
36409 + if(ips->ips_encalg) {
36410 + printk(" encalg=%u", ips->ips_encalg);
36411 + }
36412 + printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips));
36413 + if(ips->ips_replaywin) {
36414 + printk(" ooowin=%u", ips->ips_replaywin);
36415 + }
36416 + if(ips->ips_flags) {
36417 + printk(" flags=%u", ips->ips_flags);
36418 + }
36419 + if(ips->ips_addr_s) {
36420 + char buf[SUBNETTOA_BUF];
36421 + addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
36422 + 0, buf, sizeof(buf));
36423 + printk(" src=%s", buf);
36424 + }
36425 + if(ips->ips_addr_d) {
36426 + char buf[SUBNETTOA_BUF];
36427 + addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
36428 + 0, buf, sizeof(buf));
36429 + printk(" dst=%s", buf);
36430 + }
36431 + if(ips->ips_addr_p) {
36432 + char buf[SUBNETTOA_BUF];
36433 + addrtoa(((struct sockaddr_in*)(ips->ips_addr_p))->sin_addr,
36434 + 0, buf, sizeof(buf));
36435 + printk(" proxy=%s", buf);
36436 + }
36437 + if(ips->ips_key_bits_a) {
36438 + printk(" key_bits_a=%u", ips->ips_key_bits_a);
36439 + }
36440 + if(ips->ips_key_bits_e) {
36441 + printk(" key_bits_e=%u", ips->ips_key_bits_e);
36442 + }
36443 +
36444 + printk("\n");
36445 + return 0;
36446 +}
36447 +
36448 +struct ipsec_sa*
36449 +ipsec_sa_alloc(int*error) /* pass in error var by pointer */
36450 +{
36451 + struct ipsec_sa* ips;
36452 +
36453 + if((ips = kmalloc(sizeof(*ips), GFP_ATOMIC) ) == NULL) {
36454 + KLIPS_PRINT(debug_xform,
36455 + "ipsec_sa_alloc: "
36456 + "memory allocation error\n");
36457 + *error = -ENOMEM;
36458 + return NULL;
36459 + }
36460 + memset((caddr_t)ips, 0, sizeof(*ips));
36461 +
36462 + /* return with at least counter = 1 */
36463 + ipsec_sa_get(ips);
36464 +
36465 + *error = 0;
36466 + return(ips);
36467 +}
36468 +
36469 +void
36470 +ipsec_sa_untern(struct ipsec_sa *ips)
36471 +{
36472 + IPsecSAref_t ref = ips->ips_ref;
36473 + int error;
36474 +
36475 + /* verify that we are removing correct item! */
36476 + error = ipsec_saref_verify_slot(ref);
36477 + if(error) {
36478 + return;
36479 + }
36480 +
36481 + if(IPsecSAref2SA(ref) == ips) {
36482 + IPsecSAref2SA(ref) = NULL;
36483 + ipsec_sa_put(ips);
36484 + } else {
36485 + KLIPS_PRINT(debug_xform,
36486 + "ipsec_sa_untern: "
36487 + "ref=%u -> %p but untern'ing %p\n", ref,
36488 + IPsecSAref2SA(ref), ips);
36489 + }
36490 +
36491 +}
36492 +
36493 +int
36494 +ipsec_sa_intern(struct ipsec_sa *ips)
36495 +{
36496 + int error;
36497 + IPsecSAref_t ref = ips->ips_ref;
36498 +
36499 + if(ref == IPSEC_SAREF_NULL) {
36500 + ref = ipsec_SAref_alloc(&error); /* pass in error return by pointer */
36501 + KLIPS_PRINT(debug_xform,
36502 + "ipsec_sa_intern: "
36503 + "allocated ref=%u for sa %p\n", ref, ips);
36504 +
36505 + if(ref == IPSEC_SAREF_NULL) {
36506 + KLIPS_PRINT(debug_xform,
36507 + "ipsec_sa_intern: "
36508 + "SAref allocation error\n");
36509 + return error;
36510 + }
36511 +
36512 + ips->ips_ref = ref;
36513 + }
36514 +
36515 + error = ipsec_saref_verify_slot(ref);
36516 + if(error) {
36517 + return error;
36518 + }
36519 +
36520 + ipsec_sa_get(ips);
36521 + /*
36522 + * if there is an existing SA at this reference, then free it
36523 + * note, that nsa might == ips!. That's okay, we just incremented
36524 + * the reference count above.
36525 + */
36526 + {
36527 + struct ipsec_sa *nsa = IPsecSAref2SA(ref);
36528 + if(nsa) {
36529 + ipsec_sa_put(nsa);
36530 + }
36531 + }
36532 +
36533 + KLIPS_PRINT(debug_xform,
36534 + "ipsec_sa_alloc: "
36535 + "SAref[%d]=%p\n",
36536 + ips->ips_ref, ips);
36537 + IPsecSAref2SA(ips->ips_ref) = ips;
36538 +
36539 + /* return OK */
36540 + return 0;
36541 +}
36542 +
36543 +
36544 +struct ipsec_sa *
36545 +ipsec_sa_getbyid(ip_said *said)
36546 +{
36547 + int hashval;
36548 + struct ipsec_sa *ips;
36549 + char sa[SATOT_BUF];
36550 + size_t sa_len;
36551 +
36552 + if(said == NULL) {
36553 + KLIPS_PRINT(debug_xform,
36554 + "ipsec_sa_getbyid: "
36555 + "null pointer passed in!\n");
36556 + return NULL;
36557 + }
36558 +
36559 + sa_len = satot(said, 0, sa, sizeof(sa));
36560 +
36561 + hashval = IPS_HASH(said);
36562 +
36563 + KLIPS_PRINT(debug_xform,
36564 + "ipsec_sa_getbyid: "
36565 + "linked entry in ipsec_sa table for hash=%d of SA:%s requested.\n",
36566 + hashval,
36567 + sa_len ? sa : " (error)");
36568 +
36569 + if((ips = ipsec_sadb_hash[hashval]) == NULL) {
36570 + KLIPS_PRINT(debug_xform,
36571 + "ipsec_sa_getbyid: "
36572 + "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
36573 + hashval,
36574 + sa_len ? sa : " (error)");
36575 + return NULL;
36576 + }
36577 +
36578 + for (; ips; ips = ips->ips_hnext) {
36579 + if ((ips->ips_said.spi == said->spi) &&
36580 + (ips->ips_said.dst.u.v4.sin_addr.s_addr == said->dst.u.v4.sin_addr.s_addr) &&
36581 + (ips->ips_said.proto == said->proto)) {
36582 + ipsec_sa_get(ips);
36583 + return ips;
36584 + }
36585 + }
36586 +
36587 + KLIPS_PRINT(debug_xform,
36588 + "ipsec_sa_getbyid: "
36589 + "no entry in linked list for hash=%d of SA:%s.\n",
36590 + hashval,
36591 + sa_len ? sa : " (error)");
36592 + return NULL;
36593 +}
36594 +
36595 +struct ipsec_sa *
36596 +ipsec_sa_getbyref(IPsecSAref_t ref)
36597 +{
36598 + struct ipsec_sa *ips;
36599 + struct IPsecSArefSubTable *st = ipsec_sadb.refTable[IPsecSAref2table(ref)];
36600 +
36601 + if(st == NULL) {
36602 + return NULL;
36603 + }
36604 +
36605 + ips = st->entry[IPsecSAref2entry(ref)];
36606 + if(ips) {
36607 + ipsec_sa_get(ips);
36608 + }
36609 + return ips;
36610 +}
36611 +
36612 +
36613 +void
36614 +__ipsec_sa_put(struct ipsec_sa *ips, const char *func, int line)
36615 +{
36616 + char sa[SATOT_BUF];
36617 + size_t sa_len;
36618 +
36619 + if(ips == NULL) {
36620 + KLIPS_PRINT(debug_xform,
36621 + "ipsec_sa_put: "
36622 + "null pointer passed in!\n");
36623 + return;
36624 + }
36625 +
36626 + if(debug_xform) {
36627 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
36628 +
36629 + KLIPS_PRINT(debug_xform,
36630 + "ipsec_sa_put: "
36631 + "ipsec_sa %p SA:%s, ref:%d reference count (%d--) decremented by %s:%d.\n",
36632 + ips,
36633 + sa_len ? sa : " (error)",
36634 + ips->ips_ref,
36635 + atomic_read(&ips->ips_refcount),
36636 + func, line);
36637 + }
36638 +
36639 + if(atomic_dec_and_test(&ips->ips_refcount)) {
36640 + KLIPS_PRINT(debug_xform,
36641 + "ipsec_sa_put: freeing %p\n",
36642 + ips);
36643 + /* it was zero */
36644 + ipsec_sa_wipe(ips);
36645 + }
36646 +
36647 + return;
36648 +}
36649 +
36650 +struct ipsec_sa *
36651 +__ipsec_sa_get(struct ipsec_sa *ips, const char *func, int line)
36652 +{
36653 + char sa[SATOT_BUF];
36654 + size_t sa_len;
36655 +
36656 + if (ips == NULL)
36657 + return NULL;
36658 +
36659 + if(debug_xform) {
36660 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
36661 +
36662 + KLIPS_PRINT(debug_xform,
36663 + "ipsec_sa_get: "
36664 + "ipsec_sa %p SA:%s, ref:%d reference count (%d++) incremented by %s:%d.\n",
36665 + ips,
36666 + sa_len ? sa : " (error)",
36667 + ips->ips_ref,
36668 + atomic_read(&ips->ips_refcount),
36669 + func, line);
36670 + }
36671 +
36672 + atomic_inc(&ips->ips_refcount);
36673 +
36674 + // check to make sure we were not deleted
36675 + if (ips->ips_marked_deleted) {
36676 + // we cannot use this reference
36677 + ipsec_sa_put (ips);
36678 + ips = NULL;
36679 + }
36680 +
36681 + return ips;
36682 +}
36683 +
36684 +
36685 +/*
36686 + The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen
36687 +*/
36688 +int
36689 +ipsec_sa_add(struct ipsec_sa *ips)
36690 +{
36691 + int error = 0;
36692 + unsigned int hashval;
36693 +
36694 + ips = ipsec_sa_get(ips);
36695 +
36696 + if(ips == NULL) {
36697 + KLIPS_PRINT(debug_xform,
36698 + "klips_error:ipsec_sa_add: "
36699 + "null pointer passed in!\n");
36700 + return -ENODATA;
36701 + }
36702 + hashval = IPS_HASH(&ips->ips_said);
36703 +
36704 + spin_lock_bh(&tdb_lock);
36705 +
36706 + ips->ips_hnext = ipsec_sadb_hash[hashval];
36707 + ipsec_sadb_hash[hashval] = ips;
36708 +
36709 + spin_unlock_bh(&tdb_lock);
36710 +
36711 + return error;
36712 +}
36713 +
36714 +/*
36715 + * remove it from the hash chain, decrementing hash count
36716 + */
36717 +void ipsec_sa_rm(struct ipsec_sa *ips)
36718 +{
36719 + unsigned int hashval;
36720 + char sa[SATOT_BUF];
36721 + size_t sa_len;
36722 +
36723 +
36724 + if(ips == NULL) {
36725 + return;
36726 + }
36727 +
36728 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
36729 +
36730 + hashval = IPS_HASH(&ips->ips_said);
36731 +
36732 + KLIPS_PRINT(debug_xform,
36733 + "klips_debug:ipsec_sa_del: "
36734 + "unhashing SA:%s (ref=%u), hashval=%d.\n",
36735 + sa_len ? sa : " (error)",
36736 + ips->ips_ref,
36737 + hashval);
36738 +
36739 + if(ipsec_sadb_hash[hashval] == NULL) {
36740 + return;
36741 + }
36742 +
36743 + if (ips == ipsec_sadb_hash[hashval]) {
36744 + ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext;
36745 + ips->ips_hnext = NULL;
36746 + ipsec_sa_put(ips);
36747 + KLIPS_PRINT(debug_xform,
36748 + "klips_debug:ipsec_sa_del: "
36749 + "successfully unhashed first ipsec_sa in chain.\n");
36750 + return;
36751 + } else {
36752 + struct ipsec_sa *ipstp;
36753 +
36754 + for (ipstp = ipsec_sadb_hash[hashval];
36755 + ipstp;
36756 + ipstp = ipstp->ips_hnext) {
36757 + if (ipstp->ips_hnext == ips) {
36758 + ipstp->ips_hnext = ips->ips_hnext;
36759 + ips->ips_hnext = NULL;
36760 + ipsec_sa_put(ips);
36761 + KLIPS_PRINT(debug_xform,
36762 + "klips_debug:ipsec_sa_del: "
36763 + "successfully unhashed link in ipsec_sa chain.\n");
36764 + return;
36765 + }
36766 + }
36767 + }
36768 +}
36769 +
36770 +
36771 +#if 0
36772 +/*
36773 + * The ipsec_sa table better be locked before it is handed in,
36774 + * or races might happen.
36775 + *
36776 + * this routine assumes the SA has a refcount==0, and we free it.
36777 + * we also assume that the pointers are already cleaned up.
36778 + */
36779 +static int
36780 +ipsec_sa_del(struct ipsec_sa *ips)
36781 +{
36782 + unsigned int hashval;
36783 + struct ipsec_sa *ipstp;
36784 + char sa[SATOT_BUF];
36785 + size_t sa_len;
36786 +
36787 + if(ips == NULL) {
36788 + KLIPS_ERROR(debug_xform,
36789 + "klips_error:ipsec_sa_del: "
36790 + "null pointer passed in!\n");
36791 + return -ENODATA;
36792 + }
36793 +
36794 + if(ips->ips_next) {
36795 + struct ipsec_sa *in = ips->ips_next;
36796 +
36797 + ips->ips_next=NULL;
36798 + ipsec_sa_put(in);
36799 + }
36800 +
36801 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
36802 + hashval = IPS_HASH(&ips->ips_said);
36803 +
36804 + KLIPS_PRINT(debug_xform,
36805 + "klips_debug:ipsec_sa_del: "
36806 + "deleting SA:%s (ref=%u), hashval=%d.\n",
36807 + sa_len ? sa : " (error)",
36808 + ips->ips_ref,
36809 + hashval);
36810 +
36811 + if(ipsec_sadb_hash[hashval] == NULL) {
36812 + /* if this is NULL, then we can be sure that the SA was never
36813 + * added to the SADB, so we just free it.
36814 + */
36815 + KLIPS_PRINT(debug_xform,
36816 + "klips_debug:ipsec_sa_del: "
36817 + "no entries in ipsec_sa table for hash=%d (ref=%u) of SA:%s.\n",
36818 + hashval,
36819 + ips->ips_ref,
36820 + sa_len ? sa : " (error)");
36821 + return -ENOENT;
36822 + }
36823 +
36824 + if (ips == ipsec_sadb_hash[hashval]) {
36825 + ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext;
36826 + ips->ips_hnext = NULL;
36827 +
36828 + ipsec_sa_put(ips);
36829 + KLIPS_PRINT(debug_xform,
36830 + "klips_debug:ipsec_sa_del: "
36831 + "successfully deleted first ipsec_sa in chain.\n");
36832 + return 0;
36833 + } else {
36834 + for (ipstp = ipsec_sadb_hash[hashval];
36835 + ipstp;
36836 + ipstp = ipstp->ips_hnext) {
36837 + if (ipstp->ips_hnext == ips) {
36838 + ipstp->ips_hnext = ips->ips_hnext;
36839 + ips->ips_hnext = NULL;
36840 + ipsec_sa_put(ips);
36841 + KLIPS_PRINT(debug_xform,
36842 + "klips_debug:ipsec_sa_del: "
36843 + "successfully deleted link in ipsec_sa chain.\n");
36844 + return 0;
36845 + }
36846 + }
36847 + }
36848 +
36849 + KLIPS_PRINT(debug_xform,
36850 + "klips_debug:ipsec_sa_del: "
36851 + "no entries in linked list for hash=%d of SA:%s.\n",
36852 + hashval,
36853 + sa_len ? sa : " (error)");
36854 + return -ENOENT;
36855 +}
36856 +#endif
36857 +
36858 +int
36859 +ipsec_sadb_cleanup(__u8 proto)
36860 +{
36861 + unsigned i;
36862 + int error = 0;
36863 + struct ipsec_sa *ips;
36864 + //struct ipsec_sa *ipsnext, **ipsprev;
36865 + //char sa[SATOT_BUF];
36866 + //size_t sa_len;
36867 +
36868 + KLIPS_PRINT(debug_xform,
36869 + "klips_debug:ipsec_sadb_cleanup: "
36870 + "cleaning up proto=%d.\n",
36871 + proto);
36872 +
36873 + spin_lock_bh(&tdb_lock);
36874 +
36875 + for (i = 0; i < SADB_HASHMOD; i++) {
36876 + ips = ipsec_sadb_hash[i];
36877 +
36878 + while(ips) {
36879 + ipsec_sadb_hash[i]=ips->ips_hnext;
36880 + ips->ips_hnext=NULL;
36881 + ipsec_sa_put(ips);
36882 +
36883 + ips = ipsec_sadb_hash[i];
36884 + }
36885 + }
36886 +
36887 +//errlab:
36888 +
36889 + spin_unlock_bh(&tdb_lock);
36890 +
36891 +
36892 +#if IPSEC_SA_REF_CODE
36893 + /* clean up SA reference table */
36894 +
36895 + /* go through the ref table and clean out all the SAs */
36896 + KLIPS_PRINT(debug_xform,
36897 + "klips_debug:ipsec_sadb_cleanup: "
36898 + "removing SAref entries and tables.");
36899 + {
36900 + unsigned table, entry;
36901 + for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
36902 + KLIPS_PRINT(debug_xform,
36903 + "klips_debug:ipsec_sadb_cleanup: "
36904 + "cleaning SAref table=%u.\n",
36905 + table);
36906 + if(ipsec_sadb.refTable[table] == NULL) {
36907 + printk("\n");
36908 + KLIPS_PRINT(debug_xform,
36909 + "klips_debug:ipsec_sadb_cleanup: "
36910 + "cleaned %u used refTables.\n",
36911 + table);
36912 + break;
36913 + }
36914 + for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
36915 + if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
36916 + struct ipsec_sa *sa1 = ipsec_sadb.refTable[table]->entry[entry];
36917 + ipsec_sa_put(sa1);
36918 + ipsec_sadb.refTable[table]->entry[entry] = NULL;
36919 + }
36920 + }
36921 + }
36922 + }
36923 +#endif /* IPSEC_SA_REF_CODE */
36924 +
36925 + return(error);
36926 +}
36927 +
36928 +int
36929 +ipsec_sadb_free(void)
36930 +{
36931 + int error = 0;
36932 +
36933 + KLIPS_PRINT(debug_xform,
36934 + "klips_debug:ipsec_sadb_free: "
36935 + "freeing SArefTable memory.\n");
36936 +
36937 + /* clean up SA reference table */
36938 +
36939 + /* go through the ref table and clean out all the SAs if any are
36940 + left and free table memory */
36941 + KLIPS_PRINT(debug_xform,
36942 + "klips_debug:ipsec_sadb_free: "
36943 + "removing SAref entries and tables.\n");
36944 + {
36945 + unsigned table, entry;
36946 + for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
36947 + KLIPS_PRINT(debug_xform,
36948 + "klips_debug:ipsec_sadb_free: "
36949 + "removing SAref table=%u.\n",
36950 + table);
36951 + if(ipsec_sadb.refTable[table] == NULL) {
36952 + KLIPS_PRINT(debug_xform,
36953 + "klips_debug:ipsec_sadb_free: "
36954 + "removed %u used refTables.\n",
36955 + table);
36956 + break;
36957 + }
36958 + for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
36959 + if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
36960 + struct ipsec_sa *sa1 = ipsec_sadb.refTable[table]->entry[entry];
36961 +
36962 + BUG_ON(atomic_read(&sa1->ips_refcount) == 1);
36963 + ipsec_sa_put(sa1);
36964 + ipsec_sadb.refTable[table]->entry[entry] = NULL;
36965 + }
36966 + }
36967 + vfree(ipsec_sadb.refTable[table]);
36968 + ipsec_sadb.refTable[table] = NULL;
36969 + }
36970 + }
36971 +
36972 + return(error);
36973 +}
36974 +
36975 +static int
36976 +ipsec_sa_wipe(struct ipsec_sa *ips)
36977 +{
36978 + if(ips == NULL) {
36979 + return -ENODATA;
36980 + }
36981 +
36982 + /* paranoid clean up */
36983 + if(ips->ips_addr_s != NULL) {
36984 + memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size);
36985 + kfree(ips->ips_addr_s);
36986 + }
36987 + ips->ips_addr_s = NULL;
36988 +
36989 + if(ips->ips_addr_d != NULL) {
36990 + memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size);
36991 + kfree(ips->ips_addr_d);
36992 + }
36993 + ips->ips_addr_d = NULL;
36994 +
36995 + if(ips->ips_addr_p != NULL) {
36996 + memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size);
36997 + kfree(ips->ips_addr_p);
36998 + }
36999 + ips->ips_addr_p = NULL;
37000 +
37001 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
37002 + if(ips->ips_natt_oa) {
37003 + memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size);
37004 + kfree(ips->ips_natt_oa);
37005 + }
37006 + ips->ips_natt_oa = NULL;
37007 +#endif
37008 +
37009 + if(ips->ips_key_a != NULL) {
37010 + memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size);
37011 + kfree(ips->ips_key_a);
37012 + }
37013 + ips->ips_key_a = NULL;
37014 +
37015 + if(ips->ips_key_e != NULL) {
37016 + if (ips->ips_alg_enc &&
37017 + ips->ips_alg_enc->ixt_e_destroy_key)
37018 + {
37019 + ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc,
37020 + ips->ips_key_e);
37021 + } else
37022 + {
37023 + memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size);
37024 + kfree(ips->ips_key_e);
37025 + }
37026 + }
37027 + ips->ips_key_e = NULL;
37028 +
37029 + if(ips->ips_iv != NULL) {
37030 + memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
37031 + kfree(ips->ips_iv);
37032 + }
37033 + ips->ips_iv = NULL;
37034 +
37035 + if(ips->ips_ident_s.data != NULL) {
37036 + memset((caddr_t)(ips->ips_ident_s.data),
37037 + 0,
37038 + ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
37039 + kfree(ips->ips_ident_s.data);
37040 + }
37041 + ips->ips_ident_s.data = NULL;
37042 +
37043 + if(ips->ips_ident_d.data != NULL) {
37044 + memset((caddr_t)(ips->ips_ident_d.data),
37045 + 0,
37046 + ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
37047 + kfree(ips->ips_ident_d.data);
37048 + }
37049 + ips->ips_ident_d.data = NULL;
37050 +
37051 + if (ips->ips_alg_enc||ips->ips_alg_auth) {
37052 + ipsec_alg_sa_wipe(ips);
37053 + }
37054 +
37055 + BUG_ON(atomic_read(&ips->ips_refcount) != 0);
37056 +
37057 + memset((caddr_t)ips, 0, sizeof(*ips));
37058 + kfree(ips);
37059 + ips = NULL;
37060 +
37061 + return 0;
37062 +}
37063 +
37064 +extern int sysctl_ipsec_debug_verbose;
37065 +
37066 +int ipsec_sa_init(struct ipsec_sa *ipsp)
37067 +{
37068 + int i;
37069 + int error = 0;
37070 + char sa[SATOT_BUF];
37071 + size_t sa_len;
37072 + char ipaddr_txt[ADDRTOA_BUF];
37073 + char ipaddr2_txt[ADDRTOA_BUF];
37074 +#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || defined (CONFIG_KLIPS_AUTH_HMAC_SHA1)
37075 + unsigned char kb[AHMD596_BLKLEN];
37076 +#endif
37077 + struct ipsec_alg_enc *ixt_e = NULL;
37078 + struct ipsec_alg_auth *ixt_a = NULL;
37079 +
37080 + if(ipsp == NULL) {
37081 + KLIPS_PRINT(debug_pfkey,
37082 + "ipsec_sa_init: "
37083 + "ipsp is NULL, fatal\n");
37084 + SENDERR(EINVAL);
37085 + }
37086 +
37087 + sa_len = satot(&ipsp->ips_said, 0, sa, sizeof(sa));
37088 +
37089 + KLIPS_PRINT(debug_pfkey,
37090 + "ipsec_sa_init: "
37091 + "(pfkey defined) called for SA:%s\n",
37092 + sa_len ? sa : " (error)");
37093 +
37094 + KLIPS_PRINT(debug_pfkey,
37095 + "ipsec_sa_init: "
37096 + "calling init routine of %s%s%s\n",
37097 + IPS_XFORM_NAME(ipsp));
37098 +
37099 + switch(ipsp->ips_said.proto) {
37100 +#ifdef CONFIG_KLIPS_IPIP
37101 + case IPPROTO_IPIP: {
37102 + ipsp->ips_xformfuncs = ipip_xform_funcs;
37103 + addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr,
37104 + 0,
37105 + ipaddr_txt, sizeof(ipaddr_txt));
37106 + addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
37107 + 0,
37108 + ipaddr2_txt, sizeof(ipaddr_txt));
37109 + KLIPS_PRINT(debug_pfkey,
37110 + "ipsec_sa_init: "
37111 + "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n",
37112 + ipaddr_txt,
37113 + ipaddr2_txt);
37114 + }
37115 + break;
37116 +#endif /* !CONFIG_KLIPS_IPIP */
37117 +
37118 +#ifdef CONFIG_KLIPS_AH
37119 + case IPPROTO_AH:
37120 + ipsp->ips_xformfuncs = ah_xform_funcs;
37121 +
37122 + switch(ipsp->ips_authalg) {
37123 +# ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
37124 + case AH_MD5: {
37125 + unsigned char *akp;
37126 + unsigned int aks;
37127 + MD5_CTX *ictx;
37128 + MD5_CTX *octx;
37129 +
37130 + if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
37131 + KLIPS_PRINT(debug_pfkey,
37132 + "ipsec_sa_init: "
37133 + "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37134 + ipsp->ips_key_bits_a, AHMD596_KLEN * 8);
37135 + SENDERR(EINVAL);
37136 + }
37137 +
37138 +# if KLIPS_DIVULGE_HMAC_KEY
37139 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37140 + "ipsec_sa_init: "
37141 + "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
37142 + ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
37143 + ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
37144 + ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
37145 + ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
37146 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37147 +
37148 + ipsp->ips_auth_bits = AHMD596_ALEN * 8;
37149 +
37150 + /* save the pointer to the key material */
37151 + akp = ipsp->ips_key_a;
37152 + aks = ipsp->ips_key_a_size;
37153 +
37154 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37155 + "ipsec_sa_init: "
37156 + "allocating %lu bytes for md5_ctx.\n",
37157 + (unsigned long) sizeof(struct md5_ctx));
37158 + if((ipsp->ips_key_a = (caddr_t)
37159 + kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
37160 + ipsp->ips_key_a = akp;
37161 + SENDERR(ENOMEM);
37162 + }
37163 + ipsp->ips_key_a_size = sizeof(struct md5_ctx);
37164 +
37165 + for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37166 + kb[i] = akp[i] ^ HMAC_IPAD;
37167 + }
37168 + for (; i < AHMD596_BLKLEN; i++) {
37169 + kb[i] = HMAC_IPAD;
37170 + }
37171 +
37172 + ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
37173 + osMD5Init(ictx);
37174 + osMD5Update(ictx, kb, AHMD596_BLKLEN);
37175 +
37176 + for (i = 0; i < AHMD596_BLKLEN; i++) {
37177 + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37178 + }
37179 +
37180 + octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
37181 + osMD5Init(octx);
37182 + osMD5Update(octx, kb, AHMD596_BLKLEN);
37183 +
37184 +# if KLIPS_DIVULGE_HMAC_KEY
37185 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37186 + "ipsec_sa_init: "
37187 + "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37188 + ((__u32*)ictx)[0],
37189 + ((__u32*)ictx)[1],
37190 + ((__u32*)ictx)[2],
37191 + ((__u32*)ictx)[3],
37192 + ((__u32*)octx)[0],
37193 + ((__u32*)octx)[1],
37194 + ((__u32*)octx)[2],
37195 + ((__u32*)octx)[3] );
37196 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37197 +
37198 + /* zero key buffer -- paranoid */
37199 + memset(akp, 0, aks);
37200 + kfree(akp);
37201 + }
37202 + break;
37203 +# endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
37204 +# ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
37205 + case AH_SHA: {
37206 + unsigned char *akp;
37207 + unsigned int aks;
37208 + SHA1_CTX *ictx;
37209 + SHA1_CTX *octx;
37210 +
37211 + if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
37212 + KLIPS_PRINT(debug_pfkey,
37213 + "ipsec_sa_init: "
37214 + "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37215 + ipsp->ips_key_bits_a, AHSHA196_KLEN * 8);
37216 + SENDERR(EINVAL);
37217 + }
37218 +
37219 +# if KLIPS_DIVULGE_HMAC_KEY
37220 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37221 + "ipsec_sa_init: "
37222 + "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
37223 + ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
37224 + ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
37225 + ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
37226 + ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
37227 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37228 +
37229 + ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
37230 +
37231 + /* save the pointer to the key material */
37232 + akp = ipsp->ips_key_a;
37233 + aks = ipsp->ips_key_a_size;
37234 +
37235 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37236 + "ipsec_sa_init: "
37237 + "allocating %lu bytes for sha1_ctx.\n",
37238 + (unsigned long) sizeof(struct sha1_ctx));
37239 + if((ipsp->ips_key_a = (caddr_t)
37240 + kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
37241 + ipsp->ips_key_a = akp;
37242 + SENDERR(ENOMEM);
37243 + }
37244 + ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
37245 +
37246 + for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37247 + kb[i] = akp[i] ^ HMAC_IPAD;
37248 + }
37249 + for (; i < AHMD596_BLKLEN; i++) {
37250 + kb[i] = HMAC_IPAD;
37251 + }
37252 +
37253 + ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
37254 + SHA1Init(ictx);
37255 + SHA1Update(ictx, kb, AHSHA196_BLKLEN);
37256 +
37257 + for (i = 0; i < AHSHA196_BLKLEN; i++) {
37258 + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37259 + }
37260 +
37261 + octx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->octx);
37262 + SHA1Init(octx);
37263 + SHA1Update(octx, kb, AHSHA196_BLKLEN);
37264 +
37265 +# if KLIPS_DIVULGE_HMAC_KEY
37266 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37267 + "ipsec_sa_init: "
37268 + "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37269 + ((__u32*)ictx)[0],
37270 + ((__u32*)ictx)[1],
37271 + ((__u32*)ictx)[2],
37272 + ((__u32*)ictx)[3],
37273 + ((__u32*)octx)[0],
37274 + ((__u32*)octx)[1],
37275 + ((__u32*)octx)[2],
37276 + ((__u32*)octx)[3] );
37277 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37278 + /* zero key buffer -- paranoid */
37279 + memset(akp, 0, aks);
37280 + kfree(akp);
37281 + }
37282 + break;
37283 +# endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
37284 + default:
37285 + KLIPS_PRINT(debug_pfkey,
37286 + "ipsec_sa_init: "
37287 + "authalg=%d support not available in the kernel",
37288 + ipsp->ips_authalg);
37289 + SENDERR(EINVAL);
37290 + }
37291 + break;
37292 +#endif /* CONFIG_KLIPS_AH */
37293 +
37294 +#ifdef CONFIG_KLIPS_ESP
37295 + case IPPROTO_ESP:
37296 + ipsp->ips_xformfuncs = esp_xform_funcs;
37297 + {
37298 +#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || defined (CONFIG_KLIPS_AUTH_HMAC_SHA1)
37299 + unsigned char *akp;
37300 + unsigned int aks;
37301 +#endif
37302 +
37303 + ipsec_alg_sa_init(ipsp);
37304 + ixt_e=ipsp->ips_alg_enc;
37305 +
37306 + if (ixt_e == NULL) {
37307 + if(printk_ratelimit()) {
37308 + printk(KERN_ERR
37309 + "ipsec_sa_init: "
37310 + "encalg=%d support not available in the kernel",
37311 + ipsp->ips_encalg);
37312 + }
37313 + SENDERR(ENOENT);
37314 + }
37315 +
37316 + ipsp->ips_iv_size = ixt_e->ixt_common.ixt_support.ias_ivlen/8;
37317 +
37318 + /* Create IV */
37319 + if (ipsp->ips_iv_size) {
37320 + if((ipsp->ips_iv = (caddr_t)
37321 + kmalloc(ipsp->ips_iv_size, GFP_ATOMIC)) == NULL) {
37322 + SENDERR(ENOMEM);
37323 + }
37324 + prng_bytes(&ipsec_prng,
37325 + (char *)ipsp->ips_iv,
37326 + ipsp->ips_iv_size);
37327 + ipsp->ips_iv_bits = ipsp->ips_iv_size * 8;
37328 + }
37329 +
37330 + if ((error=ipsec_alg_enc_key_create(ipsp)) < 0)
37331 + SENDERR(-error);
37332 +
37333 + if ((ixt_a=ipsp->ips_alg_auth)) {
37334 + if ((error=ipsec_alg_auth_key_create(ipsp)) < 0)
37335 + SENDERR(-error);
37336 + } else
37337 +
37338 + switch(ipsp->ips_authalg) {
37339 +# ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
37340 + case AH_MD5: {
37341 + MD5_CTX *ictx;
37342 + MD5_CTX *octx;
37343 +
37344 + if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
37345 + KLIPS_PRINT(debug_pfkey,
37346 + "ipsec_sa_init: "
37347 + "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37348 + ipsp->ips_key_bits_a,
37349 + AHMD596_KLEN * 8);
37350 + SENDERR(EINVAL);
37351 + }
37352 +
37353 +# if KLIPS_DIVULGE_HMAC_KEY
37354 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37355 + "ipsec_sa_init: "
37356 + "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
37357 + ntohl(*(((__u32 *)(ipsp->ips_key_a))+0)),
37358 + ntohl(*(((__u32 *)(ipsp->ips_key_a))+1)),
37359 + ntohl(*(((__u32 *)(ipsp->ips_key_a))+2)),
37360 + ntohl(*(((__u32 *)(ipsp->ips_key_a))+3)));
37361 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37362 + ipsp->ips_auth_bits = AHMD596_ALEN * 8;
37363 +
37364 + /* save the pointer to the key material */
37365 + akp = ipsp->ips_key_a;
37366 + aks = ipsp->ips_key_a_size;
37367 +
37368 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37369 + "ipsec_sa_init: "
37370 + "allocating %lu bytes for md5_ctx.\n",
37371 + (unsigned long) sizeof(struct md5_ctx));
37372 + if((ipsp->ips_key_a = (caddr_t)
37373 + kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
37374 + ipsp->ips_key_a = akp;
37375 + SENDERR(ENOMEM);
37376 + }
37377 + ipsp->ips_key_a_size = sizeof(struct md5_ctx);
37378 +
37379 + for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37380 + kb[i] = akp[i] ^ HMAC_IPAD;
37381 + }
37382 + for (; i < AHMD596_BLKLEN; i++) {
37383 + kb[i] = HMAC_IPAD;
37384 + }
37385 +
37386 + ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
37387 + osMD5Init(ictx);
37388 + osMD5Update(ictx, kb, AHMD596_BLKLEN);
37389 +
37390 + for (i = 0; i < AHMD596_BLKLEN; i++) {
37391 + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37392 + }
37393 +
37394 + octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
37395 + osMD5Init(octx);
37396 + osMD5Update(octx, kb, AHMD596_BLKLEN);
37397 +
37398 +# if KLIPS_DIVULGE_HMAC_KEY
37399 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37400 + "ipsec_sa_init: "
37401 + "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37402 + ((__u32*)ictx)[0],
37403 + ((__u32*)ictx)[1],
37404 + ((__u32*)ictx)[2],
37405 + ((__u32*)ictx)[3],
37406 + ((__u32*)octx)[0],
37407 + ((__u32*)octx)[1],
37408 + ((__u32*)octx)[2],
37409 + ((__u32*)octx)[3] );
37410 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37411 + /* paranoid */
37412 + memset(akp, 0, aks);
37413 + kfree(akp);
37414 + break;
37415 + }
37416 +# endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
37417 +# ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
37418 + case AH_SHA: {
37419 + SHA1_CTX *ictx;
37420 + SHA1_CTX *octx;
37421 +
37422 + if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
37423 + KLIPS_PRINT(debug_pfkey,
37424 + "ipsec_sa_init: "
37425 + "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37426 + ipsp->ips_key_bits_a,
37427 + AHSHA196_KLEN * 8);
37428 + SENDERR(EINVAL);
37429 + }
37430 +
37431 +# if KLIPS_DIVULGE_HMAC_KEY
37432 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37433 + "ipsec_sa_init: "
37434 + "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
37435 + ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
37436 + ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
37437 + ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
37438 + ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
37439 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37440 + ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
37441 +
37442 + /* save the pointer to the key material */
37443 + akp = ipsp->ips_key_a;
37444 + aks = ipsp->ips_key_a_size;
37445 +
37446 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37447 + "ipsec_sa_init: "
37448 + "allocating %lu bytes for sha1_ctx.\n",
37449 + (unsigned long) sizeof(struct sha1_ctx));
37450 + if((ipsp->ips_key_a = (caddr_t)
37451 + kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
37452 + ipsp->ips_key_a = akp;
37453 + SENDERR(ENOMEM);
37454 + }
37455 + ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
37456 +
37457 + for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37458 + kb[i] = akp[i] ^ HMAC_IPAD;
37459 + }
37460 + for (; i < AHMD596_BLKLEN; i++) {
37461 + kb[i] = HMAC_IPAD;
37462 + }
37463 +
37464 + ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
37465 + SHA1Init(ictx);
37466 + SHA1Update(ictx, kb, AHSHA196_BLKLEN);
37467 +
37468 + for (i = 0; i < AHSHA196_BLKLEN; i++) {
37469 + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37470 + }
37471 +
37472 + octx = &((struct sha1_ctx*)(ipsp->ips_key_a))->octx;
37473 + SHA1Init(octx);
37474 + SHA1Update(octx, kb, AHSHA196_BLKLEN);
37475 +
37476 +# if KLIPS_DIVULGE_HMAC_KEY
37477 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37478 + "ipsec_sa_init: "
37479 + "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37480 + ((__u32*)ictx)[0],
37481 + ((__u32*)ictx)[1],
37482 + ((__u32*)ictx)[2],
37483 + ((__u32*)ictx)[3],
37484 + ((__u32*)octx)[0],
37485 + ((__u32*)octx)[1],
37486 + ((__u32*)octx)[2],
37487 + ((__u32*)octx)[3] );
37488 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37489 + memset(akp, 0, aks);
37490 + kfree(akp);
37491 + break;
37492 + }
37493 +# endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
37494 + case AH_NONE:
37495 + break;
37496 + default:
37497 + KLIPS_PRINT(debug_pfkey,
37498 + "ipsec_sa_init: "
37499 + "authalg=%d support not available in the kernel.\n",
37500 + ipsp->ips_authalg);
37501 + SENDERR(EINVAL);
37502 + }
37503 + }
37504 + break;
37505 +#endif /* !CONFIG_KLIPS_ESP */
37506 +#ifdef CONFIG_KLIPS_IPCOMP
37507 + case IPPROTO_COMP:
37508 + ipsp->ips_xformfuncs = ipcomp_xform_funcs;
37509 + ipsp->ips_comp_adapt_tries = 0;
37510 + ipsp->ips_comp_adapt_skip = 0;
37511 + ipsp->ips_comp_ratio_cbytes = 0;
37512 + ipsp->ips_comp_ratio_dbytes = 0;
37513 + break;
37514 +#endif /* CONFIG_KLIPS_IPCOMP */
37515 + default:
37516 + printk(KERN_ERR "KLIPS sa initialization: "
37517 + "proto=%d unknown.\n",
37518 + ipsp->ips_said.proto);
37519 + SENDERR(EINVAL);
37520 + }
37521 +
37522 + errlab:
37523 + return(error);
37524 +}
37525 +
37526 +/*
37527 + *
37528 + * Local Variables:
37529 + * c-file-style: "linux"
37530 + * End:
37531 + *
37532 + */
37533 +
37534 --- /dev/null Tue Mar 11 13:02:56 2003
37535 +++ linux/net/ipsec/ipsec_sha1.c Mon Feb 9 13:51:03 2004
37536 @@ -0,0 +1,219 @@
37537 +/*
37538 + * RCSID $Id: ipsec_sha1.c,v 1.9 2004/04/06 02:49:26 mcr Exp $
37539 + */
37540 +
37541 +/*
37542 + * The rest of the code is derived from sha1.c by Steve Reid, which is
37543 + * public domain.
37544 + * Minor cosmetic changes to accomodate it in the Linux kernel by ji.
37545 + */
37546 +
37547 +#include <asm/byteorder.h>
37548 +#include <linux/string.h>
37549 +
37550 +#include "openswan/ipsec_sha1.h"
37551 +
37552 +#if defined(rol)
37553 +#undef rol
37554 +#endif
37555 +
37556 +#define SHA1HANDSOFF
37557 +
37558 +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
37559 +
37560 +/* blk0() and blk() perform the initial expand. */
37561 +/* I got the idea of expanding during the round function from SSLeay */
37562 +#ifdef __LITTLE_ENDIAN
37563 +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
37564 + |(rol(block->l[i],8)&0x00FF00FF))
37565 +#else
37566 +#define blk0(i) block->l[i]
37567 +#endif
37568 +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
37569 + ^block->l[(i+2)&15]^block->l[i&15],1))
37570 +
37571 +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
37572 +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
37573 +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
37574 +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
37575 +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
37576 +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
37577 +
37578 +
37579 +/* Hash a single 512-bit block. This is the core of the algorithm. */
37580 +
37581 +void SHA1Transform(__u32 state[5], __u8 buffer[64])
37582 +{
37583 +__u32 a, b, c, d, e;
37584 +typedef union {
37585 + unsigned char c[64];
37586 + __u32 l[16];
37587 +} CHAR64LONG16;
37588 +CHAR64LONG16* block;
37589 +#ifdef SHA1HANDSOFF
37590 +static unsigned char workspace[64];
37591 + block = (CHAR64LONG16*)workspace;
37592 + memcpy(block, buffer, 64);
37593 +#else
37594 + block = (CHAR64LONG16*)buffer;
37595 +#endif
37596 + /* Copy context->state[] to working vars */
37597 + a = state[0];
37598 + b = state[1];
37599 + c = state[2];
37600 + d = state[3];
37601 + e = state[4];
37602 + /* 4 rounds of 20 operations each. Loop unrolled. */
37603 + 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);
37604 + 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);
37605 + 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);
37606 + 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);
37607 + 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);
37608 + 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);
37609 + 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);
37610 + 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);
37611 + 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);
37612 + 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);
37613 + 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);
37614 + 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);
37615 + 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);
37616 + 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);
37617 + 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);
37618 + 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);
37619 + 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);
37620 + 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);
37621 + 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);
37622 + 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);
37623 + /* Add the working vars back into context.state[] */
37624 + state[0] += a;
37625 + state[1] += b;
37626 + state[2] += c;
37627 + state[3] += d;
37628 + state[4] += e;
37629 + /* Wipe variables */
37630 + a = b = c = d = e = 0;
37631 +}
37632 +
37633 +
37634 +/* SHA1Init - Initialize new context */
37635 +
37636 +void SHA1Init(void *vcontext)
37637 +{
37638 + SHA1_CTX* context = vcontext;
37639 +
37640 + /* SHA1 initialization constants */
37641 + context->state[0] = 0x67452301;
37642 + context->state[1] = 0xEFCDAB89;
37643 + context->state[2] = 0x98BADCFE;
37644 + context->state[3] = 0x10325476;
37645 + context->state[4] = 0xC3D2E1F0;
37646 + context->count[0] = context->count[1] = 0;
37647 +}
37648 +
37649 +
37650 +/* Run your data through this. */
37651 +
37652 +void SHA1Update(void *vcontext, unsigned char* data, __u32 len)
37653 +{
37654 + SHA1_CTX* context = vcontext;
37655 + __u32 i, j;
37656 +
37657 + j = context->count[0];
37658 + if ((context->count[0] += len << 3) < j)
37659 + context->count[1]++;
37660 + context->count[1] += (len>>29);
37661 + j = (j >> 3) & 63;
37662 + if ((j + len) > 63) {
37663 + memcpy(&context->buffer[j], data, (i = 64-j));
37664 + SHA1Transform(context->state, context->buffer);
37665 + for ( ; i + 63 < len; i += 64) {
37666 + SHA1Transform(context->state, &data[i]);
37667 + }
37668 + j = 0;
37669 + }
37670 + else i = 0;
37671 + memcpy(&context->buffer[j], &data[i], len - i);
37672 +}
37673 +
37674 +
37675 +/* Add padding and return the message digest. */
37676 +
37677 +void SHA1Final(unsigned char digest[20], void *vcontext)
37678 +{
37679 + __u32 i, j;
37680 + unsigned char finalcount[8];
37681 + SHA1_CTX* context = vcontext;
37682 +
37683 + for (i = 0; i < 8; i++) {
37684 + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
37685 + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
37686 + }
37687 + SHA1Update(context, (unsigned char *)"\200", 1);
37688 + while ((context->count[0] & 504) != 448) {
37689 + SHA1Update(context, (unsigned char *)"\0", 1);
37690 + }
37691 + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
37692 + for (i = 0; i < 20; i++) {
37693 + digest[i] = (unsigned char)
37694 + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
37695 + }
37696 + /* Wipe variables */
37697 + i = j = 0;
37698 + memset(context->buffer, 0, 64);
37699 + memset(context->state, 0, 20);
37700 + memset(context->count, 0, 8);
37701 + memset(&finalcount, 0, 8);
37702 +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
37703 + SHA1Transform(context->state, context->buffer);
37704 +#endif
37705 +}
37706 +
37707 +
37708 +/*
37709 + * $Log: ipsec_sha1.c,v $
37710 + * Revision 1.9 2004/04/06 02:49:26 mcr
37711 + * pullup of algo code from alg-branch.
37712 + *
37713 + * Revision 1.8 2002/09/10 01:45:14 mcr
37714 + * changed type of MD5_CTX and SHA1_CTX to void * so that
37715 + * the function prototypes would match, and could be placed
37716 + * into a pointer to a function.
37717 + *
37718 + * Revision 1.7 2002/04/24 07:55:32 mcr
37719 + * #include patches and Makefiles for post-reorg compilation.
37720 + *
37721 + * Revision 1.6 2002/04/24 07:36:30 mcr
37722 + * Moved from ./klips/net/ipsec/ipsec_sha1.c,v
37723 + *
37724 + * Revision 1.5 1999/12/13 13:59:13 rgb
37725 + * Quick fix to argument size to Update bugs.
37726 + *
37727 + * Revision 1.4 1999/04/11 00:29:00 henry
37728 + * GPL boilerplate
37729 + *
37730 + * Revision 1.3 1999/04/06 04:54:27 rgb
37731 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
37732 + * patch shell fixes.
37733 + *
37734 + * Revision 1.2 1999/01/22 06:55:50 rgb
37735 + * 64-bit clean-up.
37736 + *
37737 + * Revision 1.1 1998/06/18 21:27:50 henry
37738 + * move sources from klips/src to klips/net/ipsec, to keep stupid
37739 + * kernel-build scripts happier in the presence of symlinks
37740 + *
37741 + * Revision 1.2 1998/04/23 20:54:04 rgb
37742 + * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
37743 + * verified.
37744 + *
37745 + * Revision 1.1 1998/04/09 03:06:11 henry
37746 + * sources moved up from linux/net/ipsec
37747 + *
37748 + * Revision 1.1.1.1 1998/04/08 05:35:05 henry
37749 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
37750 + *
37751 + * Revision 0.4 1997/01/15 01:28:15 ji
37752 + * New transform
37753 + *
37754 + *
37755 + */
37756 --- /dev/null Tue Mar 11 13:02:56 2003
37757 +++ linux/net/ipsec/ipsec_snprintf.c Mon Feb 9 13:51:03 2004
37758 @@ -0,0 +1,130 @@
37759 +/*
37760 + * @(#) ipsec_snprintf() function
37761 + *
37762 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
37763 + * 2001 Michael Richardson <mcr@freeswan.org>
37764 + * Copyright (C) 2005 Michael Richardson <mcr@xelerance.com>
37765 + *
37766 + * This program is free software; you can redistribute it and/or modify it
37767 + * under the terms of the GNU General Public License as published by the
37768 + * Free Software Foundation; either version 2 of the License, or (at your
37769 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
37770 + *
37771 + * This program is distributed in the hope that it will be useful, but
37772 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
37773 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37774 + * for more details.
37775 + *
37776 + * Split out from ipsec_proc.c.
37777 + */
37778 +
37779 +#ifndef AUTOCONF_INCLUDED
37780 +#include <linux/config.h>
37781 +#endif
37782 +#include <linux/version.h>
37783 +#define __NO_VERSION__
37784 +#include <linux/module.h>
37785 +#include <linux/kernel.h> /* printk() */
37786 +
37787 +#include "openswan/ipsec_kversion.h"
37788 +#include "openswan/ipsec_param.h"
37789 +
37790 +#include <net/ip.h>
37791 +
37792 +#include "openswan/radij.h"
37793 +
37794 +#include "openswan/ipsec_life.h"
37795 +#include "openswan/ipsec_stats.h"
37796 +#include "openswan/ipsec_sa.h"
37797 +
37798 +#include "openswan/ipsec_encap.h"
37799 +#include "openswan/ipsec_radij.h"
37800 +#include "openswan/ipsec_xform.h"
37801 +#include "openswan/ipsec_tunnel.h"
37802 +#include "openswan/ipsec_xmit.h"
37803 +
37804 +#include "openswan/ipsec_rcv.h"
37805 +#include "openswan/ipsec_ah.h"
37806 +#include "openswan/ipsec_esp.h"
37807 +#include "openswan/ipsec_kern24.h"
37808 +
37809 +#ifdef CONFIG_KLIPS_IPCOMP
37810 +#include "openswan/ipcomp.h"
37811 +#endif /* CONFIG_KLIPS_IPCOMP */
37812 +
37813 +#include "openswan/ipsec_proto.h"
37814 +
37815 +#include <openswan/pfkeyv2.h>
37816 +#include <openswan/pfkey.h>
37817 +
37818 +/* ipsec_snprintf: like snprintf except
37819 + * - size is signed and a negative value is treated as if it were 0
37820 + * - the returned result is never negative --
37821 + * an error generates a "?" or null output (depending on space).
37822 + * (Our callers are too lazy to check for an error return.)
37823 + *
37824 + * @param buf String buffer
37825 + * @param size Size of the string
37826 + * @param fmt printf string
37827 + * @param ... Variables to be displayed in fmt
37828 + * @return int Return code
37829 + */
37830 +int ipsec_snprintf(char *buf, ssize_t size, const char *fmt, ...)
37831 +{
37832 + va_list args;
37833 + int i;
37834 + size_t possize = size < 0? 0 : size;
37835 + va_start(args, fmt);
37836 + i = vsnprintf(buf,possize,fmt,args);
37837 + va_end(args);
37838 + if (i < 0) {
37839 + /* create empty output in place of error */
37840 + i = 0;
37841 + if (size > 0) {
37842 + *buf = '\0';
37843 + }
37844 + }
37845 + return i;
37846 +}
37847 +
37848 +
37849 +void ipsec_dmp_block(char *s, caddr_t bb, int len)
37850 +{
37851 + int i;
37852 + unsigned char *b = bb;
37853 +
37854 + printk(KERN_INFO "klips_dmp: "
37855 + "at %s, len=%d:\n", s, len);
37856 +
37857 + for(i = 0; i < len; i++ /*, c++*/) {
37858 + if(!(i % 16)) {
37859 + printk(KERN_INFO
37860 + "klips_debug: @%03x:",
37861 + i);
37862 + }
37863 + printk(" %02x", b[i]);
37864 + if(!((i + 1) % 16)) {
37865 + printk("\n");
37866 + }
37867 + }
37868 + if(i % 16) {
37869 + printk("\n");
37870 + }
37871 +}
37872 +
37873 +/*
37874 + *
37875 + * $Log: ipsec_snprintf.c,v $
37876 + * Revision 1.3 2005/04/29 05:10:22 mcr
37877 + * removed from extraenous includes to make unit testing easier.
37878 + *
37879 + * Revision 1.2 2005/04/15 00:32:01 mcr
37880 + * added ipsec_dmp_block routine.
37881 + *
37882 + *
37883 + * Local Variables:
37884 + * c-file-style: "linux"
37885 + * End:
37886 + *
37887 + */
37888 +
37889 --- /dev/null Tue Mar 11 13:02:56 2003
37890 +++ linux/net/ipsec/ipsec_tunnel.c Mon Feb 9 13:51:03 2004
37891 @@ -0,0 +1,2938 @@
37892 +/*
37893 + * IPSEC Tunneling code. Heavily based on drivers/net/new_tunnel.c
37894 + * Copyright (C) 1996, 1997 John Ioannidis.
37895 + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
37896 + *
37897 + * This program is free software; you can redistribute it and/or modify it
37898 + * under the terms of the GNU General Public License as published by the
37899 + * Free Software Foundation; either version 2 of the License, or (at your
37900 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
37901 + *
37902 + * This program is distributed in the hope that it will be useful, but
37903 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
37904 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37905 + * for more details.
37906 + */
37907 +
37908 +char ipsec_tunnel_c_version[] = "RCSID $Id: ipsec_tunnel.c,v 1.234 2005/11/11 04:46:38 paul Exp $";
37909 +
37910 +#define __NO_VERSION__
37911 +#include <linux/module.h>
37912 +#ifndef AUTOCONF_INCLUDED
37913 +#include <linux/config.h>
37914 +#endif /* for CONFIG_IP_FORWARD */
37915 +#include <linux/version.h>
37916 +#include <linux/kernel.h> /* printk() */
37917 +
37918 +#include "openswan/ipsec_param.h"
37919 +
37920 +#ifdef MALLOC_SLAB
37921 +# include <linux/slab.h> /* kmalloc() */
37922 +#else /* MALLOC_SLAB */
37923 +# include <linux/malloc.h> /* kmalloc() */
37924 +#endif /* MALLOC_SLAB */
37925 +#include <linux/errno.h> /* error codes */
37926 +#include <linux/types.h> /* size_t */
37927 +#include <linux/interrupt.h> /* mark_bh */
37928 +
37929 +#include <net/tcp.h>
37930 +#include <net/udp.h>
37931 +#include <linux/skbuff.h>
37932 +
37933 +#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
37934 +#include <linux/etherdevice.h> /* eth_type_trans */
37935 +#include <linux/ip.h> /* struct iphdr */
37936 +#include <linux/skbuff.h>
37937 +
37938 +#include <openswan.h>
37939 +
37940 +#ifdef NET_21
37941 +# include <linux/in6.h>
37942 +# define ip_chk_addr inet_addr_type
37943 +# define IS_MYADDR RTN_LOCAL
37944 +# include <net/dst.h>
37945 +# undef dev_kfree_skb
37946 +# define dev_kfree_skb(a,b) kfree_skb(a)
37947 +# define PHYSDEV_TYPE
37948 +#endif /* NET_21 */
37949 +
37950 +#include <net/icmp.h> /* icmp_send() */
37951 +#include <net/ip.h>
37952 +#ifdef NETDEV_23
37953 +# include <linux/netfilter_ipv4.h>
37954 +#endif /* NETDEV_23 */
37955 +
37956 +#include <linux/if_arp.h>
37957 +#include <net/arp.h>
37958 +
37959 +#include "openswan/ipsec_kversion.h"
37960 +#include "openswan/radij.h"
37961 +#include "openswan/ipsec_life.h"
37962 +#include "openswan/ipsec_xform.h"
37963 +#include "openswan/ipsec_eroute.h"
37964 +#include "openswan/ipsec_encap.h"
37965 +#include "openswan/ipsec_radij.h"
37966 +#include "openswan/ipsec_sa.h"
37967 +#include "openswan/ipsec_tunnel.h"
37968 +#include "openswan/ipsec_xmit.h"
37969 +#include "openswan/ipsec_ipe4.h"
37970 +#include "openswan/ipsec_ah.h"
37971 +#include "openswan/ipsec_esp.h"
37972 +#include "openswan/ipsec_kern24.h"
37973 +
37974 +#include <openswan/pfkeyv2.h>
37975 +#include <openswan/pfkey.h>
37976 +
37977 +#include "openswan/ipsec_proto.h"
37978 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
37979 +#include <linux/udp.h>
37980 +#endif
37981 +
37982 +static __u32 zeroes[64];
37983 +
37984 +#ifdef CONFIG_KLIPS_DEBUG
37985 +int debug_tunnel = 0;
37986 +#endif /* CONFIG_KLIPS_DEBUG */
37987 +
37988 +DEBUG_NO_STATIC int
37989 +ipsec_tunnel_open(struct net_device *dev)
37990 +{
37991 + struct ipsecpriv *prv = dev->priv;
37992 +
37993 + /*
37994 + * Can't open until attached.
37995 + */
37996 +
37997 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
37998 + "klips_debug:ipsec_tunnel_open: "
37999 + "dev = %s, prv->dev = %s\n",
38000 + dev->name, prv->dev?prv->dev->name:"NONE");
38001 +
38002 + if (prv->dev == NULL)
38003 + return -ENODEV;
38004 +
38005 + KLIPS_INC_USE;
38006 + return 0;
38007 +}
38008 +
38009 +DEBUG_NO_STATIC int
38010 +ipsec_tunnel_close(struct net_device *dev)
38011 +{
38012 + KLIPS_DEC_USE;
38013 + return 0;
38014 +}
38015 +
38016 +static inline int ipsec_tunnel_xmit2(struct sk_buff *skb)
38017 +{
38018 +
38019 +#ifdef NETDEV_25 /* 2.6 kernels */
38020 + return dst_output(skb);
38021 +#else
38022 + return ip_send(skb);
38023 +#endif
38024 +}
38025 +
38026 +enum ipsec_xmit_value
38027 +ipsec_tunnel_strip_hard_header(struct ipsec_xmit_state *ixs)
38028 +{
38029 + /* ixs->physdev->hard_header_len is unreliable and should not be used */
38030 + ixs->hard_header_len = (unsigned char *)(ixs->iph) - ixs->skb->data;
38031 +
38032 + if(ixs->hard_header_len < 0) {
38033 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38034 + "klips_error:ipsec_xmit_strip_hard_header: "
38035 + "Negative hard_header_len (%d)?!\n", ixs->hard_header_len);
38036 + ixs->stats->tx_dropped++;
38037 + return IPSEC_XMIT_BADHHLEN;
38038 + }
38039 +
38040 + /* while ixs->physdev->hard_header_len is unreliable and
38041 + * should not be trusted, it accurate and required for ATM, GRE and
38042 + * some other interfaces to work. Thanks to Willy Tarreau
38043 + * <willy@w.ods.org>.
38044 + */
38045 + if(ixs->hard_header_len == 0) { /* no hard header present */
38046 + ixs->hard_header_stripped = 1;
38047 + ixs->hard_header_len = ixs->physdev->hard_header_len;
38048 + }
38049 +
38050 +#ifdef CONFIG_KLIPS_DEBUG
38051 + if (debug_tunnel & DB_TN_XMIT) {
38052 + int i;
38053 + char c;
38054 +
38055 + printk(KERN_INFO "klips_debug:ipsec_xmit_strip_hard_header: "
38056 + ">>> skb->len=%ld hard_header_len:%d",
38057 + (unsigned long int)ixs->skb->len, ixs->hard_header_len);
38058 + c = ' ';
38059 + for (i=0; i < ixs->hard_header_len; i++) {
38060 + printk("%c%02x", c, ixs->skb->data[i]);
38061 + c = ':';
38062 + }
38063 + printk(" \n");
38064 + }
38065 +#endif /* CONFIG_KLIPS_DEBUG */
38066 +
38067 + KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
38068 +
38069 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
38070 + "klips_debug:ipsec_xmit_strip_hard_header: "
38071 + "Original head,tailroom: %d,%d\n",
38072 + skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
38073 +
38074 + return IPSEC_XMIT_OK;
38075 +}
38076 +
38077 +enum ipsec_xmit_value
38078 +ipsec_tunnel_SAlookup(struct ipsec_xmit_state *ixs)
38079 +{
38080 + unsigned int bypass;
38081 +
38082 + bypass = FALSE;
38083 +
38084 + /*
38085 + * First things first -- look us up in the erouting tables.
38086 + */
38087 + ixs->matcher.sen_len = sizeof (struct sockaddr_encap);
38088 + ixs->matcher.sen_family = AF_ENCAP;
38089 + ixs->matcher.sen_type = SENT_IP4;
38090 + ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
38091 + ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
38092 + ixs->matcher.sen_proto = ixs->iph->protocol;
38093 + ipsec_extract_ports(ixs->iph, &ixs->matcher);
38094 +
38095 + /*
38096 + * The spinlock is to prevent any other process from accessing or deleting
38097 + * the eroute while we are using and updating it.
38098 + */
38099 + spin_lock(&eroute_lock);
38100 +
38101 + ixs->eroute = ipsec_findroute(&ixs->matcher);
38102 +
38103 + if(ixs->iph->protocol == IPPROTO_UDP) {
38104 + struct udphdr *t = NULL;
38105 +
38106 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38107 + "klips_debug:udp port check: "
38108 + "fragoff: %d len: %d>%ld \n",
38109 + ntohs(ixs->iph->frag_off) & IP_OFFSET,
38110 + (ixs->skb->len - ixs->hard_header_len),
38111 + (unsigned long int) ((ixs->iph->ihl << 2) + sizeof(struct udphdr)));
38112 +
38113 + if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 &&
38114 + ((ixs->skb->len - ixs->hard_header_len) >=
38115 + ((ixs->iph->ihl << 2) + sizeof(struct udphdr))))
38116 + {
38117 + t =((struct udphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)));
38118 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38119 + "klips_debug:udp port in packet: "
38120 + "port %d -> %d\n",
38121 + ntohs(t->source), ntohs(t->dest));
38122 + }
38123 +
38124 + ixs->sport=0; ixs->dport=0;
38125 +
38126 + if(ixs->skb->sk) {
38127 +#ifdef NET_26
38128 +#ifdef HAVE_INET_SK_SPORT
38129 + ixs->sport = ntohs(inet_sk(ixs->skb->sk)->sport);
38130 + ixs->dport = ntohs(inet_sk(ixs->skb->sk)->dport);
38131 +#else
38132 + struct udp_sock *us;
38133 +
38134 + us = (struct udp_sock *)ixs->skb->sk;
38135 +
38136 + ixs->sport = ntohs(us->inet.sport);
38137 + ixs->dport = ntohs(us->inet.dport);
38138 +#endif
38139 +#else
38140 + ixs->sport = ntohs(ixs->skb->sk->sport);
38141 + ixs->dport = ntohs(ixs->skb->sk->dport);
38142 +#endif
38143 +
38144 + }
38145 +
38146 + if(t != NULL) {
38147 + if(ixs->sport == 0) {
38148 + ixs->sport = ntohs(t->source);
38149 + }
38150 + if(ixs->dport == 0) {
38151 + ixs->dport = ntohs(t->dest);
38152 + }
38153 + }
38154 + }
38155 +
38156 + /*
38157 + * practically identical to above, but let's be careful about
38158 + * tcp vs udp headers
38159 + */
38160 + if(ixs->iph->protocol == IPPROTO_TCP) {
38161 + struct tcphdr *t = NULL;
38162 +
38163 + if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 &&
38164 + ((ixs->skb->len - ixs->hard_header_len) >=
38165 + ((ixs->iph->ihl << 2) + sizeof(struct tcphdr)))) {
38166 + t =((struct tcphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)));
38167 + }
38168 +
38169 + ixs->sport=0; ixs->dport=0;
38170 +
38171 + if(ixs->skb->sk) {
38172 +#ifdef NET_26
38173 +#ifdef HAVE_INET_SK_SPORT
38174 + ixs->sport = ntohs(inet_sk(ixs->skb->sk)->sport);
38175 + ixs->dport = ntohs(inet_sk(ixs->skb->sk)->dport);
38176 +#else
38177 + struct tcp_tw_bucket *tw;
38178 +
38179 + tw = (struct tcp_tw_bucket *)ixs->skb->sk;
38180 + ixs->sport = ntohs(tw->tw_sport);
38181 + ixs->dport = ntohs(tw->tw_dport);
38182 +#endif
38183 +#else
38184 + ixs->sport = ntohs(ixs->skb->sk->sport);
38185 + ixs->dport = ntohs(ixs->skb->sk->dport);
38186 +#endif
38187 + }
38188 +
38189 + if(t != NULL) {
38190 + if(ixs->sport == 0) {
38191 + ixs->sport = ntohs(t->source);
38192 + }
38193 + if(ixs->dport == 0) {
38194 + ixs->dport = ntohs(t->dest);
38195 + }
38196 + }
38197 + }
38198 +
38199 + /* default to a %drop eroute */
38200 + ixs->outgoing_said.proto = IPPROTO_INT;
38201 + ixs->outgoing_said.spi = htonl(SPI_DROP);
38202 + ixs->outgoing_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
38203 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38204 + "klips_debug:ipsec_xmit_SAlookup: "
38205 + "checking for local udp/500 IKE packet "
38206 + "saddr=%x, er=0p%p, daddr=%x, er_dst=%x, proto=%d sport=%d dport=%d\n",
38207 + ntohl((unsigned int)ixs->iph->saddr),
38208 + ixs->eroute,
38209 + ntohl((unsigned int)ixs->iph->daddr),
38210 + ixs->eroute ? ntohl((unsigned int)ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr) : 0,
38211 + ixs->iph->protocol,
38212 + ixs->sport,
38213 + ixs->dport);
38214 +
38215 + /*
38216 + * cheat for now...are we udp/500? If so, let it through
38217 + * without interference since it is most likely an IKE packet.
38218 + */
38219 +
38220 + if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR
38221 + && (ixs->eroute==NULL
38222 + || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr
38223 + || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr)
38224 + && (ixs->iph->protocol == IPPROTO_UDP &&
38225 + (ixs->sport == 500 || ixs->sport == 4500))) {
38226 + /* Whatever the eroute, this is an IKE message
38227 + * from us (i.e. not being forwarded).
38228 + * Furthermore, if there is a tunnel eroute,
38229 + * the destination is the peer for this eroute.
38230 + * So %pass the packet: modify the default %drop.
38231 + */
38232 +
38233 + ixs->outgoing_said.spi = htonl(SPI_PASS);
38234 + if(!(ixs->skb->sk) && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0)) {
38235 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38236 + "klips_debug:ipsec_xmit_SAlookup: "
38237 + "local UDP/500 (probably IKE) passthrough: base fragment, rest of fragments will probably get filtered.\n");
38238 + }
38239 + bypass = TRUE;
38240 + }
38241 +
38242 +#ifdef KLIPS_EXCEPT_DNS53
38243 + /*
38244 + *
38245 + * if we are udp/53 or tcp/53, also let it through a %trap or %hold,
38246 + * since it is DNS, but *also* follow the %trap.
38247 + *
38248 + * we do not do this for tunnels, only %trap's and %hold's.
38249 + *
38250 + */
38251 +
38252 + if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR
38253 + && (ixs->eroute==NULL
38254 + || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr
38255 + || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr)
38256 + && ((ixs->iph->protocol == IPPROTO_UDP
38257 + || ixs->iph->protocol == IPPROTO_TCP)
38258 + && ixs->dport == 53)) {
38259 +
38260 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38261 + "klips_debug:ipsec_xmit_SAlookup: "
38262 + "possible DNS packet\n");
38263 +
38264 + if(ixs->eroute)
38265 + {
38266 + if(ixs->eroute->er_said.spi == htonl(SPI_TRAP)
38267 + || ixs->eroute->er_said.spi == htonl(SPI_HOLD))
38268 + {
38269 + ixs->outgoing_said.spi = htonl(SPI_PASSTRAP);
38270 + bypass = TRUE;
38271 + }
38272 + }
38273 + else
38274 + {
38275 + ixs->outgoing_said.spi = htonl(SPI_PASSTRAP);
38276 + bypass = TRUE;
38277 + }
38278 +
38279 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38280 + "klips_debug:ipsec_xmit_SAlookup: "
38281 + "bypass = %d\n", bypass);
38282 +
38283 + if(bypass
38284 + && !(ixs->skb->sk)
38285 + && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0))
38286 + {
38287 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38288 + "klips_debug:ipsec_xmit_SAlookup: "
38289 + "local port 53 (probably DNS) passthrough:"
38290 + "base fragment, rest of fragments will "
38291 + "probably get filtered.\n");
38292 + }
38293 + }
38294 +#endif
38295 +
38296 + if (bypass==FALSE && ixs->eroute) {
38297 + ixs->eroute->er_count++;
38298 + ixs->eroute->er_lasttime = jiffies/HZ;
38299 + if(ixs->eroute->er_said.proto==IPPROTO_INT
38300 + && ixs->eroute->er_said.spi==htonl(SPI_HOLD))
38301 + {
38302 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38303 + "klips_debug:ipsec_xmit_SAlookup: "
38304 + "shunt SA of HOLD: skb stored in HOLD.\n");
38305 + if(ixs->eroute->er_last != NULL) {
38306 + kfree_skb(ixs->eroute->er_last);
38307 + }
38308 + ixs->eroute->er_last = ixs->skb;
38309 + ixs->skb = NULL;
38310 + ixs->stats->tx_dropped++;
38311 + spin_unlock(&eroute_lock);
38312 + return IPSEC_XMIT_STOLEN;
38313 + }
38314 + ixs->outgoing_said = ixs->eroute->er_said;
38315 + ixs->eroute_pid = ixs->eroute->er_pid;
38316 +
38317 + /* Copy of the ident for the TRAP/TRAPSUBNET eroutes */
38318 + if(ixs->outgoing_said.proto==IPPROTO_INT
38319 + && (ixs->outgoing_said.spi==htonl(SPI_TRAP)
38320 + || (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)))) {
38321 + int len;
38322 +
38323 + ixs->ips.ips_ident_s.type = ixs->eroute->er_ident_s.type;
38324 + ixs->ips.ips_ident_s.id = ixs->eroute->er_ident_s.id;
38325 + ixs->ips.ips_ident_s.len = ixs->eroute->er_ident_s.len;
38326 + if (ixs->ips.ips_ident_s.len)
38327 + {
38328 + len = ixs->ips.ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
38329 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38330 + "klips_debug:ipsec_xmit_SAlookup: "
38331 + "allocating %d bytes for ident_s shunt SA of HOLD: skb stored in HOLD.\n",
38332 + len);
38333 + if ((ixs->ips.ips_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
38334 + printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
38335 + "Failed, tried to allocate %d bytes for source ident.\n",
38336 + len);
38337 + ixs->stats->tx_dropped++;
38338 + spin_unlock(&eroute_lock);
38339 + return IPSEC_XMIT_ERRMEMALLOC;
38340 + }
38341 + memcpy(ixs->ips.ips_ident_s.data, ixs->eroute->er_ident_s.data, len);
38342 + }
38343 + ixs->ips.ips_ident_d.type = ixs->eroute->er_ident_d.type;
38344 + ixs->ips.ips_ident_d.id = ixs->eroute->er_ident_d.id;
38345 + ixs->ips.ips_ident_d.len = ixs->eroute->er_ident_d.len;
38346 + if (ixs->ips.ips_ident_d.len)
38347 + {
38348 + len = ixs->ips.ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
38349 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38350 + "klips_debug:ipsec_xmit_SAlookup: "
38351 + "allocating %d bytes for ident_d shunt SA of HOLD: skb stored in HOLD.\n",
38352 + len);
38353 + if ((ixs->ips.ips_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
38354 + printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
38355 + "Failed, tried to allocate %d bytes for dest ident.\n",
38356 + len);
38357 + ixs->stats->tx_dropped++;
38358 + spin_unlock(&eroute_lock);
38359 + return IPSEC_XMIT_ERRMEMALLOC;
38360 + }
38361 + memcpy(ixs->ips.ips_ident_d.data, ixs->eroute->er_ident_d.data, len);
38362 + }
38363 + }
38364 + }
38365 +
38366 + spin_unlock(&eroute_lock);
38367 + return IPSEC_XMIT_OK;
38368 +}
38369 +
38370 +
38371 +enum ipsec_xmit_value
38372 +ipsec_tunnel_restore_hard_header(struct ipsec_xmit_state*ixs)
38373 +{
38374 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
38375 + "klips_debug:ipsec_xmit_restore_hard_header: "
38376 + "After recursive xforms -- head,tailroom: %d,%d\n",
38377 + skb_headroom(ixs->skb),
38378 + skb_tailroom(ixs->skb));
38379 +
38380 + if(ixs->saved_header) {
38381 + if(skb_headroom(ixs->skb) < ixs->hard_header_len) {
38382 + printk(KERN_WARNING
38383 + "klips_error:ipsec_xmit_restore_hard_header: "
38384 + "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
38385 + ixs->hard_header_len,
38386 + skb_headroom(ixs->skb));
38387 + ixs->stats->tx_errors++;
38388 + return IPSEC_XMIT_PUSHPULLERR;
38389 +
38390 + }
38391 + skb_push(ixs->skb, ixs->hard_header_len);
38392 + {
38393 + int i;
38394 + for (i = 0; i < ixs->hard_header_len; i++) {
38395 + ixs->skb->data[i] = ixs->saved_header[i];
38396 + }
38397 + }
38398 + }
38399 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
38400 + if (ixs->natt_type && ixs->natt_head) {
38401 + struct iphdr *ipp = ixs->skb->nh.iph;
38402 + struct udphdr *udp;
38403 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38404 + "klips_debug:ipsec_tunnel_start_xmit: "
38405 + "encapsuling packet into UDP (NAT-Traversal) (%d %d)\n",
38406 + ixs->natt_type, ixs->natt_head);
38407 +
38408 + ixs->iphlen = ipp->ihl << 2;
38409 + ipp->tot_len =
38410 + htons(ntohs(ipp->tot_len) + ixs->natt_head);
38411 + if(skb_tailroom(ixs->skb) < ixs->natt_head) {
38412 + printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
38413 + "tried to skb_put %d, %d available. "
38414 + "This should never happen, please report.\n",
38415 + ixs->natt_head,
38416 + skb_tailroom(ixs->skb));
38417 + ixs->stats->tx_errors++;
38418 + return IPSEC_XMIT_ESPUDP;
38419 + }
38420 + skb_put(ixs->skb, ixs->natt_head);
38421 +
38422 + udp = (struct udphdr *)((char *)ipp + ixs->iphlen);
38423 +
38424 + /* move ESP hdr after UDP hdr */
38425 + memmove((void *)((char *)udp + ixs->natt_head),
38426 + (void *)(udp),
38427 + ntohs(ipp->tot_len) - ixs->iphlen - ixs->natt_head);
38428 +
38429 + /* clear UDP & Non-IKE Markers (if any) */
38430 + memset(udp, 0, ixs->natt_head);
38431 +
38432 + /* fill UDP with usefull informations ;-) */
38433 + udp->source = htons(ixs->natt_sport);
38434 + udp->dest = htons(ixs->natt_dport);
38435 + udp->len = htons(ntohs(ipp->tot_len) - ixs->iphlen);
38436 +
38437 + /* set protocol */
38438 + ipp->protocol = IPPROTO_UDP;
38439 +
38440 + /* fix IP checksum */
38441 + ipp->check = 0;
38442 + ipp->check = ip_fast_csum((unsigned char *)ipp, ipp->ihl);
38443 + }
38444 +#endif
38445 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
38446 + "klips_debug:ipsec_xmit_restore_hard_header: "
38447 + "With hard_header, final head,tailroom: %d,%d\n",
38448 + skb_headroom(ixs->skb),
38449 + skb_tailroom(ixs->skb));
38450 +
38451 + return IPSEC_XMIT_OK;
38452 +}
38453 +
38454 +enum ipsec_xmit_value
38455 +ipsec_tunnel_send(struct ipsec_xmit_state*ixs)
38456 +{
38457 + int err;
38458 +#ifdef NETDEV_25
38459 + struct flowi fl;
38460 +#endif
38461 +
38462 + /* new route/dst cache code from James Morris */
38463 + ixs->skb->dev = ixs->physdev;
38464 +#ifdef NETDEV_25
38465 + fl.oif = ixs->physdev->iflink;
38466 + fl.nl_u.ip4_u.daddr = ixs->skb->nh.iph->daddr;
38467 + fl.nl_u.ip4_u.saddr = ixs->pass ? 0 : ixs->skb->nh.iph->saddr;
38468 + fl.nl_u.ip4_u.tos = RT_TOS(ixs->skb->nh.iph->tos);
38469 + fl.proto = ixs->skb->nh.iph->protocol;
38470 + if ((ixs->error = ip_route_output_key(&ixs->route, &fl))) {
38471 +#else
38472 + /*skb_orphan(ixs->skb);*/
38473 + if((ixs->error = ip_route_output(&ixs->route,
38474 + ixs->skb->nh.iph->daddr,
38475 + ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
38476 + RT_TOS(ixs->skb->nh.iph->tos),
38477 + /* mcr->rgb: should this be 0 instead? */
38478 + ixs->physdev->iflink))) {
38479 +#endif
38480 + ixs->stats->tx_errors++;
38481 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38482 + "klips_debug:ipsec_xmit_send: "
38483 + "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
38484 + ixs->error,
38485 + ixs->route->u.dst.dev->name);
38486 + return IPSEC_XMIT_ROUTEERR;
38487 + }
38488 +
38489 + if(ixs->dev == ixs->route->u.dst.dev) {
38490 + ip_rt_put(ixs->route);
38491 + /* This is recursion, drop it. */
38492 + ixs->stats->tx_errors++;
38493 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38494 + "klips_debug:ipsec_xmit_send: "
38495 + "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
38496 + ixs->dev->name);
38497 + return IPSEC_XMIT_RECURSDETECT;
38498 + }
38499 + dst_release(ixs->skb->dst);
38500 + ixs->skb->dst = &ixs->route->u.dst;
38501 +
38502 + ixs->stats->tx_bytes += ixs->skb->len;
38503 + if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
38504 + ixs->stats->tx_errors++;
38505 + printk(KERN_WARNING
38506 + "klips_error:ipsec_xmit_send: "
38507 + "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
38508 + (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
38509 + ixs->skb->len);
38510 + return IPSEC_XMIT_PUSHPULLERR;
38511 + }
38512 + __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
38513 +#ifdef SKB_RESET_NFCT
38514 + if(!ixs->pass) {
38515 + nf_conntrack_put(ixs->skb->nfct);
38516 + ixs->skb->nfct = NULL;
38517 + }
38518 +#if defined(CONFIG_NETFILTER_DEBUG) && defined(HAVE_SKB_NF_DEBUG)
38519 + ixs->skb->nf_debug = 0;
38520 +#endif /* CONFIG_NETFILTER_DEBUG */
38521 +#endif /* SKB_RESET_NFCT */
38522 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38523 + "klips_debug:ipsec_xmit_send: "
38524 + "...done, calling ip_send() on device:%s\n",
38525 + ixs->skb->dev ? ixs->skb->dev->name : "NULL");
38526 + KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->skb->nh.iph);
38527 +
38528 + if(ixs->pass) {
38529 + err = ipsec_tunnel_xmit2(ixs->skb);
38530 + } else {
38531 + err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT,
38532 + ixs->skb, NULL, ixs->route->u.dst.dev,
38533 + ipsec_tunnel_xmit2);
38534 + }
38535 + if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
38536 + if(net_ratelimit())
38537 + printk(KERN_ERR
38538 + "klips_error:ipsec_xmit_send: "
38539 + "ip_send() failed, err=%d\n",
38540 + -err);
38541 + ixs->stats->tx_errors++;
38542 + ixs->stats->tx_aborted_errors++;
38543 + ixs->skb = NULL;
38544 + return IPSEC_XMIT_IPSENDFAILURE;
38545 + }
38546 +
38547 + ixs->stats->tx_packets++;
38548 +
38549 + ixs->skb = NULL;
38550 +
38551 + return IPSEC_XMIT_OK;
38552 +}
38553 +
38554 +void
38555 +ipsec_tunnel_cleanup(struct ipsec_xmit_state*ixs)
38556 +{
38557 +#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
38558 + netif_wake_queue(ixs->dev);
38559 +#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
38560 + ixs->dev->tbusy = 0;
38561 +#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
38562 + if(ixs->saved_header) {
38563 + kfree(ixs->saved_header);
38564 + }
38565 + if(ixs->skb) {
38566 + dev_kfree_skb(ixs->skb, FREE_WRITE);
38567 + }
38568 + if(ixs->oskb) {
38569 + dev_kfree_skb(ixs->oskb, FREE_WRITE);
38570 + }
38571 + if (ixs->ips.ips_ident_s.data) {
38572 + kfree(ixs->ips.ips_ident_s.data);
38573 + }
38574 + if (ixs->ips.ips_ident_d.data) {
38575 + kfree(ixs->ips.ips_ident_d.data);
38576 + }
38577 +}
38578 +
38579 +/* management of buffers */
38580 +static struct ipsec_xmit_state * ipsec_xmit_state_new (void);
38581 +static void ipsec_xmit_state_delete (struct ipsec_xmit_state *ixs);
38582 +
38583 +
38584 +/*
38585 + * This function assumes it is being called from dev_queue_xmit()
38586 + * and that skb is filled properly by that function.
38587 + */
38588 +int
38589 +ipsec_tunnel_start_xmit(struct sk_buff *skb, struct net_device *dev)
38590 +{
38591 + struct ipsec_xmit_state *ixs = NULL;
38592 + enum ipsec_xmit_value stat;
38593 +
38594 + stat = IPSEC_XMIT_ERRMEMALLOC;
38595 + ixs = ipsec_xmit_state_new ();
38596 + if (! ixs) {
38597 + goto alloc_error;
38598 + }
38599 +
38600 + ixs->dev = dev;
38601 + ixs->skb = skb;
38602 +
38603 + stat = ipsec_xmit_sanity_check_dev(ixs);
38604 + if(stat != IPSEC_XMIT_OK) {
38605 + goto cleanup;
38606 + }
38607 +
38608 + stat = ipsec_xmit_sanity_check_skb(ixs);
38609 + if(stat != IPSEC_XMIT_OK) {
38610 + goto cleanup;
38611 + }
38612 +
38613 + stat = ipsec_tunnel_strip_hard_header(ixs);
38614 + if(stat != IPSEC_XMIT_OK) {
38615 + goto cleanup;
38616 + }
38617 +
38618 + stat = ipsec_tunnel_SAlookup(ixs);
38619 + if(stat != IPSEC_XMIT_OK) {
38620 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38621 + "klips_debug:ipsec_tunnel_start_xmit: SAlookup failed: %d\n",
38622 + stat);
38623 + goto cleanup;
38624 + }
38625 +
38626 + ixs->innersrc = ixs->iph->saddr;
38627 + /* start encapsulation loop here XXX */
38628 + do {
38629 + stat = ipsec_xmit_encap_bundle(ixs);
38630 + if(stat != IPSEC_XMIT_OK) {
38631 + if(stat == IPSEC_XMIT_PASS) {
38632 + goto bypass;
38633 + }
38634 +
38635 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38636 + "klips_debug:ipsec_tunnel_start_xmit: encap_bundle failed: %d\n",
38637 + stat);
38638 + goto cleanup;
38639 + }
38640 +
38641 + ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
38642 + ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
38643 + ixs->matcher.sen_proto = ixs->iph->protocol;
38644 + ipsec_extract_ports(ixs->iph, &ixs->matcher);
38645 +
38646 + spin_lock(&eroute_lock);
38647 + ixs->eroute = ipsec_findroute(&ixs->matcher);
38648 + if(ixs->eroute) {
38649 + ixs->outgoing_said = ixs->eroute->er_said;
38650 + ixs->eroute_pid = ixs->eroute->er_pid;
38651 + ixs->eroute->er_count++;
38652 + ixs->eroute->er_lasttime = jiffies/HZ;
38653 + }
38654 + spin_unlock(&eroute_lock);
38655 +
38656 + KLIPS_PRINT((debug_tunnel & DB_TN_XMIT) &&
38657 + /* ((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc)) */
38658 + (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
38659 + ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
38660 + ixs->eroute,
38661 + "klips_debug:ipsec_tunnel_start_xmit: "
38662 + "We are recursing here.\n");
38663 +
38664 + } while(/*((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc))*/
38665 + (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
38666 + ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
38667 + ixs->eroute);
38668 +
38669 + stat = ipsec_tunnel_restore_hard_header(ixs);
38670 + if(stat != IPSEC_XMIT_OK) {
38671 + goto cleanup;
38672 + }
38673 +
38674 + bypass:
38675 + stat = ipsec_tunnel_send(ixs);
38676 +
38677 + cleanup:
38678 + ipsec_tunnel_cleanup(ixs);
38679 +
38680 + ipsec_xmit_state_delete (ixs);
38681 +alloc_error:
38682 + return 0;
38683 +}
38684 +
38685 +DEBUG_NO_STATIC struct net_device_stats *
38686 +ipsec_tunnel_get_stats(struct net_device *dev)
38687 +{
38688 + return &(((struct ipsecpriv *)(dev->priv))->mystats);
38689 +}
38690 +
38691 +/*
38692 + * Revectored calls.
38693 + * For each of these calls, a field exists in our private structure.
38694 + */
38695 +
38696 +DEBUG_NO_STATIC int
38697 +ipsec_tunnel_hard_header(struct sk_buff *skb, struct net_device *dev,
38698 + unsigned short type, void *daddr, void *saddr, unsigned len)
38699 +{
38700 + struct ipsecpriv *prv = dev->priv;
38701 + struct net_device *tmp;
38702 + int ret;
38703 + struct net_device_stats *stats; /* This device's statistics */
38704 +
38705 + if(skb == NULL) {
38706 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38707 + "klips_debug:ipsec_tunnel_hard_header: "
38708 + "no skb...\n");
38709 + return -ENODATA;
38710 + }
38711 +
38712 + if(dev == NULL) {
38713 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38714 + "klips_debug:ipsec_tunnel_hard_header: "
38715 + "no device...\n");
38716 + return -ENODEV;
38717 + }
38718 +
38719 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38720 + "klips_debug:ipsec_tunnel_hard_header: "
38721 + "skb->dev=%s dev=%s.\n",
38722 + skb->dev ? skb->dev->name : "NULL",
38723 + dev->name);
38724 +
38725 + if(prv == NULL) {
38726 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38727 + "klips_debug:ipsec_tunnel_hard_header: "
38728 + "no private space associated with dev=%s\n",
38729 + dev->name ? dev->name : "NULL");
38730 + return -ENODEV;
38731 + }
38732 +
38733 + stats = (struct net_device_stats *) &(prv->mystats);
38734 +
38735 + if(prv->dev == NULL) {
38736 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38737 + "klips_debug:ipsec_tunnel_hard_header: "
38738 + "no physical device associated with dev=%s\n",
38739 + dev->name ? dev->name : "NULL");
38740 + stats->tx_dropped++;
38741 + return -ENODEV;
38742 + }
38743 +
38744 + /* check if we have to send a IPv6 packet. It might be a Router
38745 + Solicitation, where the building of the packet happens in
38746 + reverse order:
38747 + 1. ll hdr,
38748 + 2. IPv6 hdr,
38749 + 3. ICMPv6 hdr
38750 + -> skb->nh.raw is still uninitialized when this function is
38751 + called!! If this is no IPv6 packet, we can print debugging
38752 + messages, otherwise we skip all debugging messages and just
38753 + build the ll header */
38754 + if(type != ETH_P_IPV6) {
38755 + /* execute this only, if we don't have to build the
38756 + header for a IPv6 packet */
38757 + if(!prv->hard_header) {
38758 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38759 + "klips_debug:ipsec_tunnel_hard_header: "
38760 + "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
38761 + saddr,
38762 + daddr,
38763 + len,
38764 + type,
38765 + dev->name);
38766 +#ifdef NET_21
38767 + KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
38768 + "ip=%08x->%08x\n",
38769 + (__u32)ntohl(skb->nh.iph->saddr),
38770 + (__u32)ntohl(skb->nh.iph->daddr) );
38771 +#else /* NET_21 */
38772 + KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
38773 + "ip=%08x->%08x\n",
38774 + (__u32)ntohl(skb->ip_hdr->saddr),
38775 + (__u32)ntohl(skb->ip_hdr->daddr) );
38776 +#endif /* NET_21 */
38777 + stats->tx_dropped++;
38778 + return -ENODEV;
38779 + }
38780 +
38781 +#define da ((struct net_device *)(prv->dev))->dev_addr
38782 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38783 + "klips_debug:ipsec_tunnel_hard_header: "
38784 + "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
38785 + saddr,
38786 + daddr,
38787 + len,
38788 + type,
38789 + dev->name,
38790 + prv->dev->name,
38791 + da[0], da[1], da[2], da[3], da[4], da[5]);
38792 +#ifdef NET_21
38793 + KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
38794 + "ip=%08x->%08x\n",
38795 + (__u32)ntohl(skb->nh.iph->saddr),
38796 + (__u32)ntohl(skb->nh.iph->daddr) );
38797 +#else /* NET_21 */
38798 + KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
38799 + "ip=%08x->%08x\n",
38800 + (__u32)ntohl(skb->ip_hdr->saddr),
38801 + (__u32)ntohl(skb->ip_hdr->daddr) );
38802 +#endif /* NET_21 */
38803 + } else {
38804 + KLIPS_PRINT(debug_tunnel,
38805 + "klips_debug:ipsec_tunnel_hard_header: "
38806 + "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
38807 + }
38808 + tmp = skb->dev;
38809 + skb->dev = prv->dev;
38810 + ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
38811 + skb->dev = tmp;
38812 + return ret;
38813 +}
38814 +
38815 +DEBUG_NO_STATIC int
38816 +#ifdef NET_21
38817 +ipsec_tunnel_rebuild_header(struct sk_buff *skb)
38818 +#else /* NET_21 */
38819 +ipsec_tunnel_rebuild_header(void *buff, struct net_device *dev,
38820 + unsigned long raddr, struct sk_buff *skb)
38821 +#endif /* NET_21 */
38822 +{
38823 + struct ipsecpriv *prv = skb->dev->priv;
38824 + struct net_device *tmp;
38825 + int ret;
38826 + struct net_device_stats *stats; /* This device's statistics */
38827 +
38828 + if(skb->dev == NULL) {
38829 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38830 + "klips_debug:ipsec_tunnel_rebuild_header: "
38831 + "no device...");
38832 + return -ENODEV;
38833 + }
38834 +
38835 + if(prv == NULL) {
38836 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38837 + "klips_debug:ipsec_tunnel_rebuild_header: "
38838 + "no private space associated with dev=%s",
38839 + skb->dev->name ? skb->dev->name : "NULL");
38840 + return -ENODEV;
38841 + }
38842 +
38843 + stats = (struct net_device_stats *) &(prv->mystats);
38844 +
38845 + if(prv->dev == NULL) {
38846 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38847 + "klips_debug:ipsec_tunnel_rebuild_header: "
38848 + "no physical device associated with dev=%s",
38849 + skb->dev->name ? skb->dev->name : "NULL");
38850 + stats->tx_dropped++;
38851 + return -ENODEV;
38852 + }
38853 +
38854 + if(!prv->rebuild_header) {
38855 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38856 + "klips_debug:ipsec_tunnel_rebuild_header: "
38857 + "physical device has been detached, packet dropped skb->dev=%s->NULL ",
38858 + skb->dev->name);
38859 +#ifdef NET_21
38860 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38861 + "ip=%08x->%08x\n",
38862 + (__u32)ntohl(skb->nh.iph->saddr),
38863 + (__u32)ntohl(skb->nh.iph->daddr) );
38864 +#else /* NET_21 */
38865 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38866 + "ip=%08x->%08x\n",
38867 + (__u32)ntohl(skb->ip_hdr->saddr),
38868 + (__u32)ntohl(skb->ip_hdr->daddr) );
38869 +#endif /* NET_21 */
38870 + stats->tx_dropped++;
38871 + return -ENODEV;
38872 + }
38873 +
38874 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38875 + "klips_debug:ipsec_tunnel: "
38876 + "Revectored rebuild_header dev=%s->%s ",
38877 + skb->dev->name, prv->dev->name);
38878 +#ifdef NET_21
38879 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38880 + "ip=%08x->%08x\n",
38881 + (__u32)ntohl(skb->nh.iph->saddr),
38882 + (__u32)ntohl(skb->nh.iph->daddr) );
38883 +#else /* NET_21 */
38884 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38885 + "ip=%08x->%08x\n",
38886 + (__u32)ntohl(skb->ip_hdr->saddr),
38887 + (__u32)ntohl(skb->ip_hdr->daddr) );
38888 +#endif /* NET_21 */
38889 + tmp = skb->dev;
38890 + skb->dev = prv->dev;
38891 +
38892 +#ifdef NET_21
38893 + ret = prv->rebuild_header(skb);
38894 +#else /* NET_21 */
38895 + ret = prv->rebuild_header(buff, prv->dev, raddr, skb);
38896 +#endif /* NET_21 */
38897 + skb->dev = tmp;
38898 + return ret;
38899 +}
38900 +
38901 +DEBUG_NO_STATIC int
38902 +ipsec_tunnel_set_mac_address(struct net_device *dev, void *addr)
38903 +{
38904 + struct ipsecpriv *prv = dev->priv;
38905 +
38906 + struct net_device_stats *stats; /* This device's statistics */
38907 +
38908 + if(dev == NULL) {
38909 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38910 + "klips_debug:ipsec_tunnel_set_mac_address: "
38911 + "no device...");
38912 + return -ENODEV;
38913 + }
38914 +
38915 + if(prv == NULL) {
38916 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38917 + "klips_debug:ipsec_tunnel_set_mac_address: "
38918 + "no private space associated with dev=%s",
38919 + dev->name ? dev->name : "NULL");
38920 + return -ENODEV;
38921 + }
38922 +
38923 + stats = (struct net_device_stats *) &(prv->mystats);
38924 +
38925 + if(prv->dev == NULL) {
38926 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38927 + "klips_debug:ipsec_tunnel_set_mac_address: "
38928 + "no physical device associated with dev=%s",
38929 + dev->name ? dev->name : "NULL");
38930 + stats->tx_dropped++;
38931 + return -ENODEV;
38932 + }
38933 +
38934 + if(!prv->set_mac_address) {
38935 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38936 + "klips_debug:ipsec_tunnel_set_mac_address: "
38937 + "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
38938 + dev->name);
38939 + return -ENODEV;
38940 + }
38941 +
38942 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38943 + "klips_debug:ipsec_tunnel_set_mac_address: "
38944 + "Revectored dev=%s->%s addr=0p%p\n",
38945 + dev->name, prv->dev->name, addr);
38946 + return prv->set_mac_address(prv->dev, addr);
38947 +
38948 +}
38949 +
38950 +#ifndef NET_21
38951 +DEBUG_NO_STATIC void
38952 +ipsec_tunnel_cache_bind(struct hh_cache **hhp, struct net_device *dev,
38953 + unsigned short htype, __u32 daddr)
38954 +{
38955 + struct ipsecpriv *prv = dev->priv;
38956 +
38957 + struct net_device_stats *stats; /* This device's statistics */
38958 +
38959 + if(dev == NULL) {
38960 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38961 + "klips_debug:ipsec_tunnel_cache_bind: "
38962 + "no device...");
38963 + return;
38964 + }
38965 +
38966 + if(prv == NULL) {
38967 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38968 + "klips_debug:ipsec_tunnel_cache_bind: "
38969 + "no private space associated with dev=%s",
38970 + dev->name ? dev->name : "NULL");
38971 + return;
38972 + }
38973 +
38974 + stats = (struct net_device_stats *) &(prv->mystats);
38975 +
38976 + if(prv->dev == NULL) {
38977 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38978 + "klips_debug:ipsec_tunnel_cache_bind: "
38979 + "no physical device associated with dev=%s",
38980 + dev->name ? dev->name : "NULL");
38981 + stats->tx_dropped++;
38982 + return;
38983 + }
38984 +
38985 + if(!prv->header_cache_bind) {
38986 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38987 + "klips_debug:ipsec_tunnel_cache_bind: "
38988 + "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
38989 + dev->name);
38990 + stats->tx_dropped++;
38991 + return;
38992 + }
38993 +
38994 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
38995 + "klips_debug:ipsec_tunnel_cache_bind: "
38996 + "Revectored \n");
38997 + prv->header_cache_bind(hhp, prv->dev, htype, daddr);
38998 + return;
38999 +}
39000 +#endif /* !NET_21 */
39001 +
39002 +
39003 +DEBUG_NO_STATIC void
39004 +ipsec_tunnel_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
39005 +{
39006 + struct ipsecpriv *prv = dev->priv;
39007 +
39008 + struct net_device_stats *stats; /* This device's statistics */
39009 +
39010 + if(dev == NULL) {
39011 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39012 + "klips_debug:ipsec_tunnel_cache_update: "
39013 + "no device...");
39014 + return;
39015 + }
39016 +
39017 + if(prv == NULL) {
39018 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39019 + "klips_debug:ipsec_tunnel_cache_update: "
39020 + "no private space associated with dev=%s",
39021 + dev->name ? dev->name : "NULL");
39022 + return;
39023 + }
39024 +
39025 + stats = (struct net_device_stats *) &(prv->mystats);
39026 +
39027 + if(prv->dev == NULL) {
39028 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39029 + "klips_debug:ipsec_tunnel_cache_update: "
39030 + "no physical device associated with dev=%s",
39031 + dev->name ? dev->name : "NULL");
39032 + stats->tx_dropped++;
39033 + return;
39034 + }
39035 +
39036 + if(!prv->header_cache_update) {
39037 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39038 + "klips_debug:ipsec_tunnel_cache_update: "
39039 + "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
39040 + dev->name);
39041 + return;
39042 + }
39043 +
39044 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39045 + "klips_debug:ipsec_tunnel: "
39046 + "Revectored cache_update\n");
39047 + prv->header_cache_update(hh, prv->dev, haddr);
39048 + return;
39049 +}
39050 +
39051 +#ifdef NET_21
39052 +DEBUG_NO_STATIC int
39053 +ipsec_tunnel_neigh_setup(struct neighbour *n)
39054 +{
39055 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39056 + "klips_debug:ipsec_tunnel_neigh_setup:\n");
39057 +
39058 + if (n->nud_state == NUD_NONE) {
39059 + n->ops = &arp_broken_ops;
39060 + n->output = n->ops->output;
39061 + }
39062 + return 0;
39063 +}
39064 +
39065 +DEBUG_NO_STATIC int
39066 +ipsec_tunnel_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
39067 +{
39068 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39069 + "klips_debug:ipsec_tunnel_neigh_setup_dev: "
39070 + "setting up %s\n",
39071 + dev ? dev->name : "NULL");
39072 +
39073 + if (p->tbl->family == AF_INET) {
39074 + p->neigh_setup = ipsec_tunnel_neigh_setup;
39075 + p->ucast_probes = 0;
39076 + p->mcast_probes = 0;
39077 + }
39078 + return 0;
39079 +}
39080 +#endif /* NET_21 */
39081 +
39082 +/*
39083 + * We call the attach routine to attach another device.
39084 + */
39085 +
39086 +DEBUG_NO_STATIC int
39087 +ipsec_tunnel_attach(struct net_device *dev, struct net_device *physdev)
39088 +{
39089 + int i;
39090 + struct ipsecpriv *prv = dev->priv;
39091 +
39092 + if(dev == NULL) {
39093 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39094 + "klips_debug:ipsec_tunnel_attach: "
39095 + "no device...");
39096 + return -ENODEV;
39097 + }
39098 +
39099 + if(prv == NULL) {
39100 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39101 + "klips_debug:ipsec_tunnel_attach: "
39102 + "no private space associated with dev=%s",
39103 + dev->name ? dev->name : "NULL");
39104 + return -ENODATA;
39105 + }
39106 +
39107 + prv->dev = physdev;
39108 + prv->hard_start_xmit = physdev->hard_start_xmit;
39109 + prv->get_stats = physdev->get_stats;
39110 +
39111 + if (physdev->hard_header) {
39112 + prv->hard_header = physdev->hard_header;
39113 + dev->hard_header = ipsec_tunnel_hard_header;
39114 + } else
39115 + dev->hard_header = NULL;
39116 +
39117 + if (physdev->rebuild_header) {
39118 + prv->rebuild_header = physdev->rebuild_header;
39119 + dev->rebuild_header = ipsec_tunnel_rebuild_header;
39120 + } else
39121 + dev->rebuild_header = NULL;
39122 +
39123 + if (physdev->set_mac_address) {
39124 + prv->set_mac_address = physdev->set_mac_address;
39125 + dev->set_mac_address = ipsec_tunnel_set_mac_address;
39126 + } else
39127 + dev->set_mac_address = NULL;
39128 +
39129 +#ifndef NET_21
39130 + if (physdev->header_cache_bind) {
39131 + prv->header_cache_bind = physdev->header_cache_bind;
39132 + dev->header_cache_bind = ipsec_tunnel_cache_bind;
39133 + } else
39134 + dev->header_cache_bind = NULL;
39135 +#endif /* !NET_21 */
39136 +
39137 + if (physdev->header_cache_update) {
39138 + prv->header_cache_update = physdev->header_cache_update;
39139 + dev->header_cache_update = ipsec_tunnel_cache_update;
39140 + } else
39141 + dev->header_cache_update = NULL;
39142 +
39143 + dev->hard_header_len = physdev->hard_header_len;
39144 +
39145 +#ifdef NET_21
39146 +/* prv->neigh_setup = physdev->neigh_setup; */
39147 + dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
39148 +#endif /* NET_21 */
39149 + dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
39150 + prv->mtu = physdev->mtu;
39151 +
39152 +#ifdef PHYSDEV_TYPE
39153 + dev->type = physdev->type; /* ARPHRD_TUNNEL; */
39154 +#endif /* PHYSDEV_TYPE */
39155 +
39156 + dev->addr_len = physdev->addr_len;
39157 + for (i=0; i<dev->addr_len; i++) {
39158 + dev->dev_addr[i] = physdev->dev_addr[i];
39159 + }
39160 +#ifdef CONFIG_KLIPS_DEBUG
39161 + if(debug_tunnel & DB_TN_INIT) {
39162 + printk(KERN_INFO "klips_debug:ipsec_tunnel_attach: "
39163 + "physical device %s being attached has HW address: %2x",
39164 + physdev->name, physdev->dev_addr[0]);
39165 + for (i=1; i < physdev->addr_len; i++) {
39166 + printk(":%02x", physdev->dev_addr[i]);
39167 + }
39168 + printk("\n");
39169 + }
39170 +#endif /* CONFIG_KLIPS_DEBUG */
39171 +
39172 + return 0;
39173 +}
39174 +
39175 +/*
39176 + * We call the detach routine to detach the ipsec tunnel from another device.
39177 + */
39178 +
39179 +DEBUG_NO_STATIC int
39180 +ipsec_tunnel_detach(struct net_device *dev)
39181 +{
39182 + int i;
39183 + struct ipsecpriv *prv = dev->priv;
39184 +
39185 + if(dev == NULL) {
39186 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39187 + "klips_debug:ipsec_tunnel_detach: "
39188 + "no device...");
39189 + return -ENODEV;
39190 + }
39191 +
39192 + if(prv == NULL) {
39193 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39194 + "klips_debug:ipsec_tunnel_detach: "
39195 + "no private space associated with dev=%s",
39196 + dev->name ? dev->name : "NULL");
39197 + return -ENODATA;
39198 + }
39199 +
39200 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39201 + "klips_debug:ipsec_tunnel_detach: "
39202 + "physical device %s being detached from virtual device %s\n",
39203 + prv->dev ? prv->dev->name : "NULL",
39204 + dev->name);
39205 +
39206 + ipsec_dev_put(prv->dev);
39207 + prv->dev = NULL;
39208 + prv->hard_start_xmit = NULL;
39209 + prv->get_stats = NULL;
39210 +
39211 + prv->hard_header = NULL;
39212 +#ifdef DETACH_AND_DOWN
39213 + dev->hard_header = NULL;
39214 +#endif /* DETACH_AND_DOWN */
39215 +
39216 + prv->rebuild_header = NULL;
39217 +#ifdef DETACH_AND_DOWN
39218 + dev->rebuild_header = NULL;
39219 +#endif /* DETACH_AND_DOWN */
39220 +
39221 + prv->set_mac_address = NULL;
39222 +#ifdef DETACH_AND_DOWN
39223 + dev->set_mac_address = NULL;
39224 +#endif /* DETACH_AND_DOWN */
39225 +
39226 +#ifndef NET_21
39227 + prv->header_cache_bind = NULL;
39228 +#ifdef DETACH_AND_DOWN
39229 + dev->header_cache_bind = NULL;
39230 +#endif /* DETACH_AND_DOWN */
39231 +#endif /* !NET_21 */
39232 +
39233 + prv->header_cache_update = NULL;
39234 +#ifdef DETACH_AND_DOWN
39235 + dev->header_cache_update = NULL;
39236 +#endif /* DETACH_AND_DOWN */
39237 +
39238 +#ifdef NET_21
39239 +/* prv->neigh_setup = NULL; */
39240 +#ifdef DETACH_AND_DOWN
39241 + dev->neigh_setup = NULL;
39242 +#endif /* DETACH_AND_DOWN */
39243 +#endif /* NET_21 */
39244 + dev->hard_header_len = 0;
39245 +#ifdef DETACH_AND_DOWN
39246 + dev->mtu = 0;
39247 +#endif /* DETACH_AND_DOWN */
39248 + prv->mtu = 0;
39249 + for (i=0; i<MAX_ADDR_LEN; i++) {
39250 + dev->dev_addr[i] = 0;
39251 + }
39252 + dev->addr_len = 0;
39253 +#ifdef PHYSDEV_TYPE
39254 + dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */
39255 +#endif /* PHYSDEV_TYPE */
39256 +
39257 + return 0;
39258 +}
39259 +
39260 +/*
39261 + * We call the clear routine to detach all ipsec tunnels from other devices.
39262 + */
39263 +DEBUG_NO_STATIC int
39264 +ipsec_tunnel_clear(void)
39265 +{
39266 + int i;
39267 + struct net_device *ipsecdev = NULL, *prvdev;
39268 + struct ipsecpriv *prv;
39269 + int ret;
39270 +
39271 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39272 + "klips_debug:ipsec_tunnel_clear: .\n");
39273 +
39274 + for(i = 0; i < IPSEC_NUM_IF; i++) {
39275 + ipsecdev = ipsecdevices[i];
39276 + if(ipsecdev != NULL) {
39277 + if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
39278 + prvdev = (struct net_device *)(prv->dev);
39279 + if(prvdev) {
39280 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39281 + "klips_debug:ipsec_tunnel_clear: "
39282 + "physical device for device %s is %s\n",
39283 + ipsecdev->name, prvdev->name);
39284 + if((ret = ipsec_tunnel_detach(ipsecdev))) {
39285 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39286 + "klips_debug:ipsec_tunnel_clear: "
39287 + "error %d detatching device %s from device %s.\n",
39288 + ret, ipsecdev->name, prvdev->name);
39289 + return ret;
39290 + }
39291 + }
39292 + }
39293 + }
39294 + }
39295 + return 0;
39296 +}
39297 +
39298 +DEBUG_NO_STATIC int
39299 +ipsec_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
39300 +{
39301 + struct ipsectunnelconf *cf = (struct ipsectunnelconf *)&ifr->ifr_data;
39302 + struct ipsecpriv *prv = dev->priv;
39303 + struct net_device *them; /* physical device */
39304 +#ifdef CONFIG_IP_ALIAS
39305 + char *colon;
39306 + char realphysname[IFNAMSIZ];
39307 +#endif /* CONFIG_IP_ALIAS */
39308 +
39309 + if(dev == NULL) {
39310 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39311 + "klips_debug:ipsec_tunnel_ioctl: "
39312 + "device not supplied.\n");
39313 + return -ENODEV;
39314 + }
39315 +
39316 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39317 + "klips_debug:ipsec_tunnel_ioctl: "
39318 + "tncfg service call #%d for dev=%s\n",
39319 + cmd,
39320 + dev->name ? dev->name : "NULL");
39321 + switch (cmd) {
39322 + /* attach a virtual ipsec? device to a physical device */
39323 + case IPSEC_SET_DEV:
39324 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39325 + "klips_debug:ipsec_tunnel_ioctl: "
39326 + "calling ipsec_tunnel_attatch...\n");
39327 +#ifdef CONFIG_IP_ALIAS
39328 + /* If this is an IP alias interface, get its real physical name */
39329 + strncpy(realphysname, cf->cf_name, IFNAMSIZ);
39330 + realphysname[IFNAMSIZ-1] = 0;
39331 + colon = strchr(realphysname, ':');
39332 + if (colon) *colon = 0;
39333 + them = ipsec_dev_get(realphysname);
39334 +#else /* CONFIG_IP_ALIAS */
39335 + them = ipsec_dev_get(cf->cf_name);
39336 +#endif /* CONFIG_IP_ALIAS */
39337 +
39338 + if (them == NULL) {
39339 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39340 + "klips_debug:ipsec_tunnel_ioctl: "
39341 + "physical device %s requested is null\n",
39342 + cf->cf_name);
39343 + return -ENXIO;
39344 + }
39345 +
39346 +#if 0
39347 + if (them->flags & IFF_UP) {
39348 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39349 + "klips_debug:ipsec_tunnel_ioctl: "
39350 + "physical device %s requested is not up.\n",
39351 + cf->cf_name);
39352 + ipsec_dev_put(them);
39353 + return -ENXIO;
39354 + }
39355 +#endif
39356 +
39357 + if (prv && prv->dev) {
39358 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39359 + "klips_debug:ipsec_tunnel_ioctl: "
39360 + "virtual device is already connected to %s.\n",
39361 + prv->dev->name ? prv->dev->name : "NULL");
39362 + ipsec_dev_put(them);
39363 + return -EBUSY;
39364 + }
39365 + return ipsec_tunnel_attach(dev, them);
39366 +
39367 + case IPSEC_DEL_DEV:
39368 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39369 + "klips_debug:ipsec_tunnel_ioctl: "
39370 + "calling ipsec_tunnel_detatch.\n");
39371 + if (! prv->dev) {
39372 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39373 + "klips_debug:ipsec_tunnel_ioctl: "
39374 + "physical device not connected.\n");
39375 + return -ENODEV;
39376 + }
39377 + return ipsec_tunnel_detach(dev);
39378 +
39379 + case IPSEC_CLR_DEV:
39380 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39381 + "klips_debug:ipsec_tunnel_ioctl: "
39382 + "calling ipsec_tunnel_clear.\n");
39383 + return ipsec_tunnel_clear();
39384 +
39385 + default:
39386 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39387 + "klips_debug:ipsec_tunnel_ioctl: "
39388 + "unknown command %d.\n",
39389 + cmd);
39390 + return -EOPNOTSUPP;
39391 + }
39392 +}
39393 +
39394 +struct net_device *ipsec_get_device(int inst)
39395 +{
39396 + struct net_device *ipsec_dev;
39397 +
39398 + ipsec_dev = NULL;
39399 +
39400 + if(inst < IPSEC_NUM_IF) {
39401 + ipsec_dev = ipsecdevices[inst];
39402 + }
39403 +
39404 + return ipsec_dev;
39405 +}
39406 +
39407 +int
39408 +ipsec_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
39409 +{
39410 + struct net_device *dev = ptr;
39411 + struct net_device *ipsec_dev;
39412 + struct ipsecpriv *priv;
39413 + int i;
39414 +
39415 + if (dev == NULL) {
39416 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39417 + "klips_debug:ipsec_device_event: "
39418 + "dev=NULL for event type %ld.\n",
39419 + event);
39420 + return(NOTIFY_DONE);
39421 + }
39422 +
39423 + /* check for loopback devices */
39424 + if (dev && (dev->flags & IFF_LOOPBACK)) {
39425 + return(NOTIFY_DONE);
39426 + }
39427 +
39428 + switch (event) {
39429 + case NETDEV_DOWN:
39430 + /* look very carefully at the scope of these compiler
39431 + directives before changing anything... -- RGB */
39432 +#ifdef NET_21
39433 + case NETDEV_UNREGISTER:
39434 + switch (event) {
39435 + case NETDEV_DOWN:
39436 +#endif /* NET_21 */
39437 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39438 + "klips_debug:ipsec_device_event: "
39439 + "NETDEV_DOWN dev=%s flags=%x\n",
39440 + dev->name,
39441 + dev->flags);
39442 + if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
39443 + printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
39444 + dev->name);
39445 + }
39446 +#ifdef NET_21
39447 + break;
39448 + case NETDEV_UNREGISTER:
39449 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39450 + "klips_debug:ipsec_device_event: "
39451 + "NETDEV_UNREGISTER dev=%s flags=%x\n",
39452 + dev->name,
39453 + dev->flags);
39454 + break;
39455 + }
39456 +#endif /* NET_21 */
39457 +
39458 + /* find the attached physical device and detach it. */
39459 + for(i = 0; i < IPSEC_NUM_IF; i++) {
39460 + ipsec_dev = ipsecdevices[i];
39461 +
39462 + if(ipsec_dev) {
39463 + priv = (struct ipsecpriv *)(ipsec_dev->priv);
39464 + if(priv) {
39465 + ;
39466 + if(((struct net_device *)(priv->dev)) == dev) {
39467 + /* dev_close(ipsec_dev); */
39468 + /* return */ ipsec_tunnel_detach(ipsec_dev);
39469 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39470 + "klips_debug:ipsec_device_event: "
39471 + "device '%s' has been detached.\n",
39472 + ipsec_dev->name);
39473 + break;
39474 + }
39475 + } else {
39476 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39477 + "klips_debug:ipsec_device_event: "
39478 + "device '%s' has no private data space!\n",
39479 + ipsec_dev->name);
39480 + }
39481 + }
39482 + }
39483 + break;
39484 + case NETDEV_UP:
39485 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39486 + "klips_debug:ipsec_device_event: "
39487 + "NETDEV_UP dev=%s\n",
39488 + dev->name);
39489 + break;
39490 +#ifdef NET_21
39491 + case NETDEV_REBOOT:
39492 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39493 + "klips_debug:ipsec_device_event: "
39494 + "NETDEV_REBOOT dev=%s\n",
39495 + dev->name);
39496 + break;
39497 + case NETDEV_CHANGE:
39498 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39499 + "klips_debug:ipsec_device_event: "
39500 + "NETDEV_CHANGE dev=%s flags=%x\n",
39501 + dev->name,
39502 + dev->flags);
39503 + break;
39504 + case NETDEV_REGISTER:
39505 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39506 + "klips_debug:ipsec_device_event: "
39507 + "NETDEV_REGISTER dev=%s\n",
39508 + dev->name);
39509 + break;
39510 + case NETDEV_CHANGEMTU:
39511 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39512 + "klips_debug:ipsec_device_event: "
39513 + "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
39514 + dev->name,
39515 + dev->mtu);
39516 + break;
39517 + case NETDEV_CHANGEADDR:
39518 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39519 + "klips_debug:ipsec_device_event: "
39520 + "NETDEV_CHANGEADDR dev=%s\n",
39521 + dev->name);
39522 + break;
39523 + case NETDEV_GOING_DOWN:
39524 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39525 + "klips_debug:ipsec_device_event: "
39526 + "NETDEV_GOING_DOWN dev=%s\n",
39527 + dev->name);
39528 + break;
39529 + case NETDEV_CHANGENAME:
39530 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39531 + "klips_debug:ipsec_device_event: "
39532 + "NETDEV_CHANGENAME dev=%s\n",
39533 + dev->name);
39534 + break;
39535 +#endif /* NET_21 */
39536 + default:
39537 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39538 + "klips_debug:ipsec_device_event: "
39539 + "event type %ld unrecognised for dev=%s\n",
39540 + event,
39541 + dev->name);
39542 + break;
39543 + }
39544 + return NOTIFY_DONE;
39545 +}
39546 +
39547 +/*
39548 + * Called when an ipsec tunnel device is initialized.
39549 + * The ipsec tunnel device structure is passed to us.
39550 + */
39551 +
39552 +int
39553 +ipsec_tunnel_init(struct net_device *dev)
39554 +{
39555 + int i;
39556 +
39557 + KLIPS_PRINT(debug_tunnel,
39558 + "klips_debug:ipsec_tunnel_init: "
39559 + "allocating %lu bytes initialising device: %s\n",
39560 + (unsigned long) sizeof(struct ipsecpriv),
39561 + dev->name ? dev->name : "NULL");
39562 +
39563 + /* Add our tunnel functions to the device */
39564 + dev->open = ipsec_tunnel_open;
39565 + dev->stop = ipsec_tunnel_close;
39566 + dev->hard_start_xmit = ipsec_tunnel_start_xmit;
39567 + dev->get_stats = ipsec_tunnel_get_stats;
39568 +
39569 + dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
39570 + if (dev->priv == NULL)
39571 + return -ENOMEM;
39572 + memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
39573 +
39574 + for(i = 0; i < sizeof(zeroes); i++) {
39575 + ((__u8*)(zeroes))[i] = 0;
39576 + }
39577 +
39578 +#ifndef NET_21
39579 + /* Initialize the tunnel device structure */
39580 + for (i = 0; i < DEV_NUMBUFFS; i++)
39581 + skb_queue_head_init(&dev->buffs[i]);
39582 +#endif /* !NET_21 */
39583 +
39584 + dev->set_multicast_list = NULL;
39585 + dev->do_ioctl = ipsec_tunnel_ioctl;
39586 + dev->hard_header = NULL;
39587 + dev->rebuild_header = NULL;
39588 + dev->set_mac_address = NULL;
39589 +#ifndef NET_21
39590 + dev->header_cache_bind = NULL;
39591 +#endif /* !NET_21 */
39592 + dev->header_cache_update= NULL;
39593 +
39594 +#ifdef NET_21
39595 +/* prv->neigh_setup = NULL; */
39596 + dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
39597 +#endif /* NET_21 */
39598 + dev->hard_header_len = 0;
39599 + dev->mtu = 0;
39600 + dev->addr_len = 0;
39601 + dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */ /* ARPHRD_ETHER; */
39602 + dev->tx_queue_len = 10; /* Small queue */
39603 + memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
39604 +
39605 + /* New-style flags. */
39606 + dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
39607 +
39608 +#if 0
39609 +#ifdef NET_21
39610 + dev_init_buffers(dev);
39611 +#else /* NET_21 */
39612 + dev->family = AF_INET;
39613 + dev->pa_addr = 0;
39614 + dev->pa_brdaddr = 0;
39615 + dev->pa_mask = 0;
39616 + dev->pa_alen = 4;
39617 +#endif /* NET_21 */
39618 +#endif
39619 +
39620 + /* We're done. Have I forgotten anything? */
39621 + return 0;
39622 +}
39623 +
39624 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
39625 +/* Module specific interface (but it links with the rest of IPSEC) */
39626 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
39627 +
39628 +int
39629 +ipsec_tunnel_probe(struct net_device *dev)
39630 +{
39631 + ipsec_tunnel_init(dev);
39632 + return 0;
39633 +}
39634 +
39635 +struct net_device *ipsecdevices[IPSEC_NUM_IF];
39636 +
39637 +int
39638 +ipsec_tunnel_init_devices(void)
39639 +{
39640 + int i;
39641 + char name[IFNAMSIZ];
39642 + struct net_device *dev_ipsec;
39643 +
39644 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39645 + "klips_debug:ipsec_tunnel_init_devices: "
39646 + "creating and registering IPSEC_NUM_IF=%u devices, allocating %lu per device, IFNAMSIZ=%u.\n",
39647 + IPSEC_NUM_IF,
39648 + (unsigned long) (sizeof(struct net_device) + IFNAMSIZ),
39649 + IFNAMSIZ);
39650 +
39651 + for(i = 0; i < IPSEC_NUM_IF; i++) {
39652 + sprintf(name, IPSEC_DEV_FORMAT, i);
39653 + dev_ipsec = (struct net_device*)kmalloc(sizeof(struct net_device), GFP_KERNEL);
39654 + if (dev_ipsec == NULL) {
39655 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39656 + "klips_debug:ipsec_tunnel_init_devices: "
39657 + "failed to allocate memory for device %s, quitting device init.\n",
39658 + name);
39659 + return -ENOMEM;
39660 + }
39661 + memset((caddr_t)dev_ipsec, 0, sizeof(struct net_device));
39662 +#ifdef NETDEV_23
39663 + strncpy(dev_ipsec->name, name, sizeof(dev_ipsec->name));
39664 +#else /* NETDEV_23 */
39665 + dev_ipsec->name = (char*)kmalloc(IFNAMSIZ, GFP_KERNEL);
39666 + if (dev_ipsec->name == NULL) {
39667 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39668 + "klips_debug:ipsec_tunnel_init_devices: "
39669 + "failed to allocate memory for device %s name, quitting device init.\n",
39670 + name);
39671 + return -ENOMEM;
39672 + }
39673 + memset((caddr_t)dev_ipsec->name, 0, IFNAMSIZ);
39674 + strncpy(dev_ipsec->name, name, IFNAMSIZ);
39675 +#endif /* NETDEV_23 */
39676 + dev_ipsec->next = NULL;
39677 + dev_ipsec->init = &ipsec_tunnel_probe;
39678 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39679 + "klips_debug:ipsec_tunnel_init_devices: "
39680 + "registering device %s\n",
39681 + dev_ipsec->name);
39682 +
39683 + /* reference and hold the device reference */
39684 + dev_hold(dev_ipsec);
39685 + ipsecdevices[i]=dev_ipsec;
39686 +
39687 + if (register_netdev(dev_ipsec) != 0) {
39688 + KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT,
39689 + "klips_debug:ipsec_tunnel_init_devices: "
39690 + "registering device %s failed, quitting device init.\n",
39691 + dev_ipsec->name);
39692 + return -EIO;
39693 + } else {
39694 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39695 + "klips_debug:ipsec_tunnel_init_devices: "
39696 + "registering device %s succeeded, continuing...\n",
39697 + dev_ipsec->name);
39698 + }
39699 + }
39700 + return 0;
39701 +}
39702 +
39703 +/* void */
39704 +int
39705 +ipsec_tunnel_cleanup_devices(void)
39706 +{
39707 + int error = 0;
39708 + int i;
39709 + struct net_device *dev_ipsec;
39710 +
39711 + for(i = 0; i < IPSEC_NUM_IF; i++) {
39712 + dev_ipsec = ipsecdevices[i];
39713 + if(dev_ipsec == NULL) {
39714 + continue;
39715 + }
39716 +
39717 + /* release reference */
39718 + ipsecdevices[i]=NULL;
39719 + ipsec_dev_put(dev_ipsec);
39720 +
39721 + KLIPS_PRINT(debug_tunnel, "Unregistering %s (refcnt=%d)\n",
39722 + dev_ipsec->name,
39723 + atomic_read(&dev_ipsec->refcnt));
39724 + unregister_netdev(dev_ipsec);
39725 + KLIPS_PRINT(debug_tunnel, "Unregisted %s\n", dev_ipsec->name);
39726 +#ifndef NETDEV_23
39727 + kfree(dev_ipsec->name);
39728 + dev_ipsec->name=NULL;
39729 +#endif /* !NETDEV_23 */
39730 + kfree(dev_ipsec->priv);
39731 + dev_ipsec->priv=NULL;
39732 + }
39733 + return error;
39734 +}
39735 +
39736 +// ------------------------------------------------------------------------
39737 +// this handles creating and managing state for xmit path
39738 +
39739 +static spinlock_t ixs_cache_lock = SPIN_LOCK_UNLOCKED;
39740 +static kmem_cache_t *ixs_cache_allocator = NULL;
39741 +static unsigned ixs_cache_allocated_count = 0;
39742 +
39743 +int
39744 +ipsec_xmit_state_cache_init (void)
39745 +{
39746 + if (ixs_cache_allocator)
39747 + return -EBUSY;
39748 +
39749 + spin_lock_init(&ixs_cache_lock);
39750 +
39751 + ixs_cache_allocator = kmem_cache_create ("ipsec_ixs",
39752 + sizeof (struct ipsec_xmit_state), 0,
39753 + 0, NULL, NULL);
39754 + if (! ixs_cache_allocator)
39755 + return -ENOMEM;
39756 +
39757 + return 0;
39758 +}
39759 +
39760 +void
39761 +ipsec_xmit_state_cache_cleanup (void)
39762 +{
39763 + if (unlikely (ixs_cache_allocated_count))
39764 + printk ("ipsec: deleting ipsec_ixs kmem_cache while in use\n");
39765 +
39766 + if (ixs_cache_allocator) {
39767 + kmem_cache_destroy (ixs_cache_allocator);
39768 + ixs_cache_allocator = NULL;
39769 + }
39770 + ixs_cache_allocated_count = 0;
39771 +}
39772 +
39773 +static struct ipsec_xmit_state *
39774 +ipsec_xmit_state_new (void)
39775 +{
39776 + struct ipsec_xmit_state *ixs;
39777 +
39778 + spin_lock_bh (&ixs_cache_lock);
39779 +
39780 + ixs = kmem_cache_alloc (ixs_cache_allocator, GFP_ATOMIC);
39781 +
39782 + if (likely (ixs != NULL))
39783 + ixs_cache_allocated_count++;
39784 +
39785 + spin_unlock_bh (&ixs_cache_lock);
39786 +
39787 + if (unlikely (NULL == ixs))
39788 + goto bail;
39789 +
39790 + // initialize the object
39791 + memset((caddr_t)ixs, 0, sizeof(*ixs));
39792 +
39793 +bail:
39794 + return ixs;
39795 +}
39796 +
39797 +static void
39798 +ipsec_xmit_state_delete (struct ipsec_xmit_state *ixs)
39799 +{
39800 + if (unlikely (! ixs))
39801 + return;
39802 +
39803 + spin_lock_bh (&ixs_cache_lock);
39804 +
39805 + ixs_cache_allocated_count--;
39806 + kmem_cache_free (ixs_cache_allocator, ixs);
39807 +
39808 + spin_unlock_bh (&ixs_cache_lock);
39809 +}
39810 +
39811 +/*
39812 + * $Log: ipsec_tunnel.c,v $
39813 + * Revision 1.234 2005/11/11 04:46:38 paul
39814 + * Patch for 2.6.14 by David McCullough
39815 + *
39816 + * Revision 1.233 2005/08/31 23:26:11 mcr
39817 + * fixes for 2.6.13
39818 + *
39819 + * Revision 1.232.2.2 2005/11/22 04:11:52 ken
39820 + * Backport fixes for 2.6.14 kernels from HEAD
39821 + *
39822 + * Revision 1.232.2.1 2005/09/21 22:57:43 paul
39823 + * pulled up compile fix for 2.6.13
39824 + *
39825 + * Revision 1.232 2005/06/04 16:06:06 mcr
39826 + * better patch for nat-t rcv-device code.
39827 + *
39828 + * Revision 1.231 2005/05/21 03:28:51 mcr
39829 + * make sure that port-500 hole is used for port-4500 as well.
39830 + *
39831 + * Revision 1.230 2005/05/11 01:42:04 mcr
39832 + * removal of debugging showed useless/wrong variables used.
39833 + *
39834 + * Revision 1.229 2005/04/29 05:10:22 mcr
39835 + * removed from extraenous includes to make unit testing easier.
39836 + *
39837 + * Revision 1.228 2005/01/26 00:50:35 mcr
39838 + * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
39839 + * and make sure that NAT_TRAVERSAL is set as well to match
39840 + * userspace compiles of code.
39841 + *
39842 + * Revision 1.227 2004/12/10 21:16:08 ken
39843 + * 64bit fixes from Opteron port of KLIPS 2.6
39844 + *
39845 + * Revision 1.226 2004/12/04 07:11:23 mcr
39846 + * fix for snmp SIOCPRIVATE use of snmpd.
39847 + * http://bugs.xelerance.com/view.php?id=144
39848 + *
39849 + * Revision 1.225 2004/12/03 21:25:57 mcr
39850 + * compile time fixes for running on 2.6.
39851 + * still experimental.
39852 + *
39853 + * Revision 1.224 2004/08/14 03:28:24 mcr
39854 + * fixed log comment to remove warning about embedded comment.
39855 + *
39856 + * Revision 1.223 2004/08/04 15:57:07 mcr
39857 + * moved des .h files to include/des/ *
39858 + * included 2.6 protocol specific things
39859 + * started at NAT-T support, but it will require a kernel patch.
39860 + *
39861 + * Revision 1.222 2004/08/03 18:19:08 mcr
39862 + * in 2.6, use "net_device" instead of #define device->net_device.
39863 + * this probably breaks 2.0 compiles.
39864 + *
39865 + * Revision 1.221 2004/07/10 19:11:18 mcr
39866 + * CONFIG_IPSEC -> CONFIG_KLIPS.
39867 + *
39868 + * Revision 1.220 2004/04/06 02:49:26 mcr
39869 + * pullup of algo code from alg-branch.
39870 + *
39871 + * Revision 1.219 2004/02/03 03:13:17 mcr
39872 + * minor edits for readability, and error reporting.
39873 + *
39874 + * Revision 1.218 2004/01/27 20:29:20 mcr
39875 + * fix for unregister_netdev() problem for underlying eth0.
39876 + *
39877 + * Revision 1.217 2003/12/10 01:14:27 mcr
39878 + * NAT-traversal patches to KLIPS.
39879 + *
39880 + * Revision 1.216 2003/12/04 23:01:17 mcr
39881 + * removed ipsec_netlink.h
39882 + *
39883 + * Revision 1.215 2003/12/04 16:35:16 ken
39884 + * Fix for ATM devices where physdev->hard_header_len *is* correct
39885 + *
39886 + * Revision 1.214 2003/11/25 23:52:37 mcr
39887 + * fix typo in patch - ixs-> needed.
39888 + *
39889 + * Revision 1.213 2003/11/24 18:25:49 mcr
39890 + * patch from willy@w.ods.org to fix problems with ATM interfaces.
39891 + *
39892 + * Revision 1.212 2003/10/31 02:27:55 mcr
39893 + * pulled up port-selector patches and sa_id elimination.
39894 + *
39895 + * Revision 1.211.2.2 2003/10/29 01:30:41 mcr
39896 + * elimited "struct sa_id".
39897 + *
39898 + * Revision 1.211.2.1 2003/09/21 13:59:56 mcr
39899 + * pre-liminary X.509 patch - does not yet pass tests.
39900 + *
39901 + * Revision 1.211 2003/09/10 16:46:30 mcr
39902 + * patches for 2.4 backport/2.6 existence.
39903 + *
39904 + * Revision 1.210 2003/07/31 22:47:16 mcr
39905 + * preliminary (untested by FS-team) 2.5 patches.
39906 + *
39907 + * Revision 1.209 2003/06/22 21:28:43 mcr
39908 + * inability to unload module was caused by calls to dev_get
39909 + * (ipsec_dev_get), to gather a device from a name. There is
39910 + * simply no reason to look the devices up - they should be kept
39911 + * in a nice array, ready for use.
39912 + *
39913 + * Revision 1.208 2003/06/22 21:25:07 mcr
39914 + * all staticly counted ipsecXXX device support removed.
39915 + *
39916 + * Revision 1.207 2003/04/02 20:15:37 mcr
39917 + * fix for PR#204 - do not clear connection tracking info if we
39918 + * the packet is being sent in the clear.
39919 + *
39920 + * Revision 1.206 2003/02/12 19:32:51 rgb
39921 + * Refactored file to:
39922 + * ipsec_xmit.c
39923 + * ipsec_xmit.h
39924 + * ipsec_mast.c
39925 + *
39926 + * Revision 1.205 2003/02/06 17:47:00 rgb
39927 + *
39928 + * Remove unused ipsec_tunnel_lock() and ipsec_tunnel_unlock() code.
39929 + * Refactor ipsec_tunnel_start_xmit() further into:
39930 + * ipsec_xmit_sanity_check_dev()
39931 + * ipsec_xmit_sanity_check_skb()
39932 + * ipsec_xmit_strip_hard_header()
39933 + * ipsec_xmit_restore_hard_header()
39934 + * ipsec_xmit_send()
39935 + * ipsec_xmit_cleanup()
39936 + * and start a skeletal ipsec_mast_start_xmit() .
39937 + *
39938 + * Revision 1.204 2003/02/06 06:43:46 rgb
39939 + *
39940 + * Refactor ipsec_tunnel_start_xmit, bringing out:
39941 + * ipsec_xmit_SAlookup
39942 + * ipsec_xmit_encap_once
39943 + * ipsec_xmit_encap_bundle
39944 + *
39945 + * Revision 1.203 2003/02/06 02:21:34 rgb
39946 + *
39947 + * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
39948 + * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
39949 + * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
39950 + *
39951 + * Revision 1.202 2003/01/03 07:38:01 rgb
39952 + *
39953 + * Start to refactor ipsec_tunnel_start_xmit() by putting local variables
39954 + * into struct ipsec_xmit_state and renaming a few variables to give more
39955 + * unique or searchable names.
39956 + *
39957 + * Revision 1.201 2003/01/03 00:31:28 rgb
39958 + *
39959 + * Clean up memset usage, including fixing 2 places where keys were not
39960 + * properly wiped.
39961 + *
39962 + * Revision 1.200 2002/12/06 02:24:02 mcr
39963 + * patches for compiling against SUSE 8.1 kernels. Requires
39964 + * an additional -DSUSE_LINUX_2_4_19_IS_STUPID.
39965 + *
39966 + * Revision 1.199 2002/10/12 23:11:53 dhr
39967 + *
39968 + * [KenB + DHR] more 64-bit cleanup
39969 + *
39970 + * Revision 1.198 2002/10/05 05:02:58 dhr
39971 + *
39972 + * C labels go on statements
39973 + *
39974 + * Revision 1.197 2002/09/20 05:01:50 rgb
39975 + * Added compiler directive to switch on IP options and fix IP options bug.
39976 + * Make ip->ihl treatment consistent using shifts rather than multiplications.
39977 + * Check for large enough packet before accessing udp header for IKE bypass.
39978 + * Added memory allocation debugging.
39979 + * Fixed potential memory allocation failure-induced oops.
39980 + *
39981 + * Revision 1.196 2002/07/24 18:44:54 rgb
39982 + * Type fiddling to tame ia64 compiler.
39983 + *
39984 + * Revision 1.195 2002/07/23 03:36:07 rgb
39985 + * Fixed 2.2 device initialisation hang.
39986 + *
39987 + * Revision 1.194 2002/05/27 21:40:34 rgb
39988 + * Set unused ipsec devices to ARPHRD_VOID to avoid confusing iproute2.
39989 + * Cleaned up intermediate step to dynamic device allocation.
39990 + *
39991 + * Revision 1.193 2002/05/27 19:31:36 rgb
39992 + * Convert to dynamic ipsec device allocation.
39993 + * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
39994 + *
39995 + * Revision 1.192 2002/05/23 07:14:28 rgb
39996 + * Added refcount code.
39997 + * Cleaned up %p variants to 0p%p for test suite cleanup.
39998 + *
39999 + * Revision 1.191 2002/05/14 02:34:37 rgb
40000 + * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
40001 + * ipsec_sa or ipsec_sa.
40002 + *
40003 + * Revision 1.190 2002/04/24 07:55:32 mcr
40004 + * #include patches and Makefiles for post-reorg compilation.
40005 + *
40006 + * Revision 1.189 2002/04/24 07:36:32 mcr
40007 + * Moved from ./klips/net/ipsec/ipsec_tunnel.c,v
40008 + *
40009 + * Revision 1.188 2002/04/20 00:12:25 rgb
40010 + * Added esp IV CBC attack fix, disabled.
40011 + *
40012 + * Revision 1.187 2002/03/23 19:55:17 rgb
40013 + * Fix for 2.2 local IKE fragmentation blackhole. Still won't work if
40014 + * iptraf or another pcap app is running.
40015 + *
40016 + * Revision 1.186 2002/03/19 03:26:22 rgb
40017 + * Applied DHR's tunnel patch to streamline IKE/specialSA processing.
40018 + *
40019 + * Revision 1.185 2002/02/20 04:13:05 rgb
40020 + * Send back ICMP_PKT_FILTERED upon %reject.
40021 + *
40022 + * Revision 1.184 2002/01/29 17:17:56 mcr
40023 + * moved include of ipsec_param.h to after include of linux/kernel.h
40024 + * otherwise, it seems that some option that is set in ipsec_param.h
40025 + * screws up something subtle in the include path to kernel.h, and
40026 + * it complains on the snprintf() prototype.
40027 + *
40028 + * Revision 1.183 2002/01/29 04:00:53 mcr
40029 + * more excise of kversions.h header.
40030 + *
40031 + * Revision 1.182 2002/01/29 02:13:18 mcr
40032 + * introduction of ipsec_kversion.h means that include of
40033 + * ipsec_param.h must preceed any decisions about what files to
40034 + * include to deal with differences in kernel source.
40035 + *
40036 + * Revision 1.181 2002/01/07 20:00:33 rgb
40037 + * Added IKE destination port debugging.
40038 + *
40039 + * Revision 1.180 2001/12/21 21:49:54 rgb
40040 + * Fixed bug as a result of moving IKE bypass above %trap/%hold code.
40041 + *
40042 + * Revision 1.179 2001/12/19 21:08:14 rgb
40043 + * Added transport protocol ports to ipsec_print_ip().
40044 + * Update eroute info for non-SA targets.
40045 + * Added obey DF code disabled.
40046 + * Fixed formatting bugs in ipsec_tunnel_hard_header().
40047 + *
40048 + * Revision 1.178 2001/12/05 09:36:10 rgb
40049 + * Moved the UDP/500 IKE check just above the %hold/%trap checks to avoid
40050 + * IKE packets being stolen by the %hold (and returned to the sending KMd
40051 + * in an ACQUIRE, ironically ;-).
40052 + *
40053 + * Revision 1.177 2001/11/26 09:23:50 rgb
40054 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
40055 + *
40056 + * Revision 1.170.2.1 2001/09/25 02:28:27 mcr
40057 + * struct tdb -> struct ipsec_sa.
40058 + * lifetime checks moved to common routines.
40059 + * cleaned up includes.
40060 + *
40061 + * Revision 1.170.2.2 2001/10/22 21:08:01 mcr
40062 + * include des.h, removed phony prototypes and fixed calling
40063 + * conventions to match real prototypes.
40064 + *
40065 + * Revision 1.176 2001/11/09 18:32:31 rgb
40066 + * Added Hans Schultz' fragmented UDP/500 IKE socket port selector.
40067 + *
40068 + * Revision 1.175 2001/11/06 20:47:00 rgb
40069 + * Added Eric Espie's TRAPSUBNET fix, minus spin-lock-bh dabbling.
40070 + *
40071 + * Revision 1.174 2001/11/06 19:50:43 rgb
40072 + * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
40073 + * use also by pfkey_v2_parser.c
40074 + *
40075 + * Revision 1.173 2001/10/29 21:53:44 henry
40076 + * tone down the device-down message slightly, until we can make it smarter
40077 + *
40078 + * Revision 1.172 2001/10/26 04:59:37 rgb
40079 + * Added a critical level syslog message if an ipsec device goes down.
40080 + *
40081 + * Revision 1.171 2001/10/18 04:45:21 rgb
40082 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
40083 + * lib/freeswan.h version macros moved to lib/kversions.h.
40084 + * Other compiler directive cleanups.
40085 + *
40086 + * Revision 1.170 2001/09/25 00:09:50 rgb
40087 + * Added NetCelo's TRAPSUBNET code to convert a new type TRAPSUBNET into a
40088 + * HOLD.
40089 + *
40090 + * Revision 1.169 2001/09/15 16:24:05 rgb
40091 + * Re-inject first and last HOLD packet when an eroute REPLACE is done.
40092 + *
40093 + * Revision 1.168 2001/09/14 16:58:37 rgb
40094 + * Added support for storing the first and last packets through a HOLD.
40095 + *
40096 + * Revision 1.167 2001/09/08 21:13:33 rgb
40097 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
40098 + *
40099 + * Revision 1.166 2001/08/27 19:47:59 rgb
40100 + * Clear tdb before usage.
40101 + * Added comment: clear IF before calling routing?
40102 + *
40103 + * Revision 1.165 2001/07/03 01:23:53 rgb
40104 + * Send back ICMP iff DF set, !ICMP, offset==0, sysctl_icmp, iph->tot_len >
40105 + * emtu, and don't drop.
40106 + *
40107 + * Revision 1.164 2001/06/14 19:35:10 rgb
40108 + * Update copyright date.
40109 + *
40110 + * Revision 1.163 2001/06/06 20:28:51 rgb
40111 + * Added sanity checks for NULL skbs and devices.
40112 + * Added more debugging output to various functions.
40113 + * Removed redundant dev->priv argument to ipsec_tunnel_{at,de}tach().
40114 + * Renamed ipsec_tunnel_attach() virtual and physical device arguments.
40115 + * Corrected neigh_setup() device function assignment.
40116 + * Keep valid pointers to ipsec_tunnel_*() on detach.
40117 + * Set dev->type to the originally-initiallised value.
40118 + *
40119 + * Revision 1.162 2001/06/01 07:28:04 rgb
40120 + * Added sanity checks for detached devices. Don't down virtual devices
40121 + * to prevent packets going out in the clear if the detached device comes
40122 + * back up.
40123 + *
40124 + * Revision 1.161 2001/05/30 08:14:52 rgb
40125 + * Removed vestiges of esp-null transforms.
40126 + * NetDev Notifier instrumentation to track down disappearing devices.
40127 + *
40128 + * Revision 1.160 2001/05/29 05:15:12 rgb
40129 + * Added SS' PMTU patch which notifies sender if packet doesn't fit
40130 + * physical MTU (if it wasn't ICMP) and then drops it.
40131 + *
40132 + * Revision 1.159 2001/05/27 06:12:12 rgb
40133 + * Added structures for pid, packet count and last access time to eroute.
40134 + * Added packet count to beginning of /proc/net/ipsec_eroute.
40135 + *
40136 + * Revision 1.158 2001/05/24 05:39:33 rgb
40137 + * Applied source zeroing to 2.2 ip_route_output() call as well to enable
40138 + * PASS eroutes for opportunism.
40139 + *
40140 + * Revision 1.157 2001/05/23 22:35:28 rgb
40141 + * 2.4 source override simplification.
40142 + *
40143 + * Revision 1.156 2001/05/23 21:41:31 rgb
40144 + * Added error return code printing on ip_route_output().
40145 + *
40146 + * Revision 1.155 2001/05/23 05:09:13 rgb
40147 + * Fixed incorrect ip_route_output() failure message.
40148 + *
40149 + * Revision 1.154 2001/05/21 14:53:31 rgb
40150 + * Added debug statement for case when ip_route_output() fails, causing
40151 + * packet to be dropped, but log looked ok.
40152 + *
40153 + * Revision 1.153 2001/05/19 02:37:54 rgb
40154 + * Fixed missing comment termination.
40155 + *
40156 + * Revision 1.152 2001/05/19 02:35:50 rgb
40157 + * Debug code optimisation for non-debug speed.
40158 + * Kernel version compiler define comments.
40159 + * 2.2 and 2.4 kernel ip_send device and ip debug output added.
40160 + *
40161 + * Revision 1.151 2001/05/18 16:17:35 rgb
40162 + * Changed reference from "magic" to "shunt" SAs.
40163 + *
40164 + * Revision 1.150 2001/05/18 16:12:19 rgb
40165 + * Changed UDP/500 bypass test from 3 nested ifs to one anded if.
40166 + *
40167 + * Revision 1.149 2001/05/16 04:39:33 rgb
40168 + * Add default == eroute.dest to IKE bypass conditions for magic eroutes.
40169 + *
40170 + * Revision 1.148 2001/05/05 03:31:41 rgb
40171 + * IP frag debugging updates and enhancements.
40172 + *
40173 + * Revision 1.147 2001/05/03 19:41:40 rgb
40174 + * Added SS' skb_cow fix for 2.4.4.
40175 + *
40176 + * Revision 1.146 2001/04/30 19:28:16 rgb
40177 + * Update for 2.4.4. ip_select_ident() now has 3 args.
40178 + *
40179 + * Revision 1.145 2001/04/23 14:56:10 rgb
40180 + * Added spin_lock() check to prevent double-locking for multiple
40181 + * transforms and hence kernel lock-ups with SMP kernels.
40182 + *
40183 + * Revision 1.144 2001/04/21 23:04:45 rgb
40184 + * Define out skb->used for 2.4 kernels.
40185 + * Check if soft expire has already been sent before sending another to
40186 + * prevent ACQUIRE flooding.
40187 + *
40188 + * Revision 1.143 2001/03/16 07:37:21 rgb
40189 + * Added comments to all #endifs.
40190 + *
40191 + * Revision 1.142 2001/02/28 05:03:27 rgb
40192 + * Clean up and rationalise startup messages.
40193 + *
40194 + * Revision 1.141 2001/02/27 22:24:54 rgb
40195 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
40196 + * Check for satoa() return codes.
40197 + *
40198 + * Revision 1.140 2001/02/27 06:40:12 rgb
40199 + * Fixed TRAP->HOLD eroute byte order.
40200 + *
40201 + * Revision 1.139 2001/02/26 20:38:59 rgb
40202 + * Added compiler defines for 2.4.x-specific code.
40203 + *
40204 + * Revision 1.138 2001/02/26 19:57:27 rgb
40205 + * Implement magic SAs %drop, %reject, %trap, %hold, %pass as part
40206 + * of the new SPD and to support opportunistic.
40207 + * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
40208 + *
40209 + * Revision 1.137 2001/02/19 22:29:49 rgb
40210 + * Fixes for presence of active ipv6 segments which share ipsec physical
40211 + * device (gg).
40212 + *
40213 + * Revision 1.136 2001/01/29 22:30:38 rgb
40214 + * Fixed minor acquire debug printing bug.
40215 + *
40216 + * Revision 1.135 2001/01/29 22:19:45 rgb
40217 + * Zero source address for 2.4 bypass route lookup.
40218 + *
40219 + * Revision 1.134 2001/01/23 20:19:49 rgb
40220 + * 2.4 fix to remove removed is_clone member.
40221 + *
40222 + * Revision 1.133 2000/12/09 22:08:35 rgb
40223 + * Fix NET_23 bug, should be NETDEV_23.
40224 + *
40225 + * Revision 1.132 2000/12/01 06:54:50 rgb
40226 + * Fix for new 2.4 IP TTL default variable name.
40227 + *
40228 + * Revision 1.131 2000/11/09 20:52:15 rgb
40229 + * More spinlock shuffling, locking earlier and unlocking later in rcv to
40230 + * include ipcomp and prevent races, renaming some tdb variables that got
40231 + * forgotten, moving some unlocks to include tdbs and adding a missing
40232 + * unlock. Thanks to Svenning for some of these.
40233 + *
40234 + * Revision 1.130 2000/11/09 20:11:22 rgb
40235 + * Minor shuffles to fix non-standard kernel config option selection.
40236 + *
40237 + * Revision 1.129 2000/11/06 04:32:49 rgb
40238 + * Clean up debug printing.
40239 + * Copy skb->protocol for all kernel versions.
40240 + * Ditched spin_lock_irqsave in favour of spin_lock.
40241 + * Disabled TTL decrement, done in ip_forward.
40242 + * Added debug printing before pfkey_acquire().
40243 + * Fixed printk-deltdbchain-spin_lock races (Svenning).
40244 + * Use defaultTTL for 2.1+ kernels.
40245 + * Add Svenning's adaptive content compression.
40246 + * Fix up debug display arguments.
40247 + *
40248 + * Revision 1.128 2000/09/28 00:58:57 rgb
40249 + * Moved the IKE passthrough check after the eroute lookup so we can pass
40250 + * IKE through intermediate tunnels.
40251 + *
40252 + * Revision 1.127 2000/09/22 17:52:11 rgb
40253 + * Fixed misleading ipcomp debug output.
40254 + *
40255 + * Revision 1.126 2000/09/22 04:22:56 rgb
40256 + * Fixed dumb spi->cpi conversion error.
40257 + *
40258 + * Revision 1.125 2000/09/21 04:34:48 rgb
40259 + * A few debug-specific things should be hidden under
40260 + * CONFIG_IPSEC_DEBUG.(MB)
40261 + * Improved ip_send() error handling.(MB)
40262 + *
40263 + * Revision 1.124 2000/09/21 03:40:58 rgb
40264 + * Added more debugging to try and track down the cpi outward copy problem.
40265 + *
40266 + * Revision 1.123 2000/09/19 07:08:49 rgb
40267 + * Added debugging to outgoing compression report.
40268 + *
40269 + * Revision 1.122 2000/09/18 19:21:26 henry
40270 + * RGB-supplied fix for RH5.2 problem
40271 + *
40272 + * Revision 1.121 2000/09/17 21:05:09 rgb
40273 + * Added tdb to skb_compress call to write in cpi.
40274 + *
40275 + * Revision 1.120 2000/09/17 16:57:16 rgb
40276 + * Added Svenning's patch to remove restriction of ipcomp to innermost
40277 + * transform.
40278 + *
40279 + * Revision 1.119 2000/09/15 11:37:01 rgb
40280 + * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
40281 + * IPCOMP zlib deflate code.
40282 + *
40283 + * Revision 1.118 2000/09/15 04:57:16 rgb
40284 + * Moved debug output after sanity check.
40285 + * Added tos copy sysctl.
40286 + *
40287 + * Revision 1.117 2000/09/12 03:22:51 rgb
40288 + * Converted ipsec_icmp, no_eroute_pass, opportunistic and #if0 debugs to
40289 + * sysctl.
40290 + *
40291 + * Revision 1.116 2000/09/08 19:18:19 rgb
40292 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
40293 + * Added outgoing opportunistic hook, ifdef'ed out.
40294 + *
40295 + * Revision 1.115 2000/08/30 05:27:29 rgb
40296 + * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
40297 + * Kill remainder of tdb_xform, tdb_xdata, xformsw.
40298 + *
40299 + * Revision 1.114 2000/08/28 18:15:46 rgb
40300 + * Added MB's nf-debug reset patch.
40301 + *
40302 + * Revision 1.113 2000/08/27 02:26:40 rgb
40303 + * Send all no-eroute-bypass, pluto-bypass and passthrough packets through
40304 + * fragmentation machinery for 2.0, 2.2 and 2.4 kernels.
40305 + *
40306 + * Revision 1.112 2000/08/20 21:37:33 rgb
40307 + * Activated pfkey_expire() calls.
40308 + * Added a hard/soft expiry parameter to pfkey_expire(). (Momchil)
40309 + * Re-arranged the order of soft and hard expiry to conform to RFC2367.
40310 + * Clean up references to CONFIG_IPSEC_PFKEYv2.
40311 + *
40312 + * Revision 1.111 2000/08/01 14:51:51 rgb
40313 + * Removed _all_ remaining traces of DES.
40314 + *
40315 + * Revision 1.110 2000/07/28 14:58:31 rgb
40316 + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
40317 + *
40318 + * Revision 1.109 2000/07/28 13:50:54 rgb
40319 + * Changed enet_statistics to net_device_stats and added back compatibility
40320 + * for pre-2.1.19.
40321 + *
40322 + * Revision 1.108 2000/05/16 03:03:11 rgb
40323 + * Updates for 2.3.99pre8 from MB.
40324 + *
40325 + * Revision 1.107 2000/05/10 23:08:21 rgb
40326 + * Print a debug warning about bogus packets received by the outgoing
40327 + * processing machinery only when klipsdebug is not set to none.
40328 + * Comment out the device initialisation informational messages.
40329 + *
40330 + * Revision 1.106 2000/05/10 19:17:14 rgb
40331 + * Define an IP_SEND macro, intending to have all packet passthroughs
40332 + * use fragmentation. This didn't quite work, but is a step in the
40333 + * right direction.
40334 + * Added buffer allocation debugging statements.
40335 + * Added configure option to shut off no eroute passthrough.
40336 + * Only check usetime against soft and hard limits if the tdb has been
40337 + * used.
40338 + * Cast output of ntohl so that the broken prototype doesn't make our
40339 + * compile noisy.
40340 + *
40341 + * Revision 1.105 2000/03/22 16:15:37 rgb
40342 + * Fixed renaming of dev_get (MB).
40343 + *
40344 + * Revision 1.104 2000/03/16 14:04:15 rgb
40345 + * Indented headers for readability.
40346 + * Fixed debug scope to enable compilation with debug off.
40347 + * Added macros for ip_chk_addr and IS_MYADDR for identifying self.
40348 + *
40349 + * Revision 1.103 2000/03/16 07:11:07 rgb
40350 + * Hardcode PF_KEYv2 support.
40351 + * Fixed bug which allowed UDP/500 packet from another machine
40352 + * through in the clear.
40353 + * Added disabled skb->protocol fix for ISDN/ASYNC PPP from Matjaz Godec.
40354 + *
40355 + * Revision 1.102 2000/03/14 12:26:59 rgb
40356 + * Added skb->nfct support for clearing netfilter conntrack bits (MB).
40357 + *
40358 + * Revision 1.101 2000/02/14 21:05:22 rgb
40359 + * Added MB's netif_queue fix for kernels 2.3.43+.
40360 + *
40361 + * Revision 1.100 2000/01/26 10:04:57 rgb
40362 + * Fixed noisy 2.0 printk arguments.
40363 + *
40364 + * Revision 1.99 2000/01/21 06:16:25 rgb
40365 + * Added sanity checks on skb_push(), skb_pull() to prevent panics.
40366 + * Switched to AF_ENCAP macro.
40367 + * Shortened debug output per packet and re-arranging debug_tunnel
40368 + * bitmap flags, while retaining necessary information to avoid
40369 + * trampling the kernel print ring buffer.
40370 + * Reformatted recursion switch code.
40371 + * Changed all references to tdb_proto to tdb_said.proto for clarity.
40372 + *
40373 + * Revision 1.98 2000/01/13 08:09:31 rgb
40374 + * Shuffled debug_tunnel switches to focus output.
40375 + * Fixed outgoing recursion bug, limiting to recursing only if the remote
40376 + * SG changes and if it is valid, ie. not passthrough.
40377 + * Clarified a number of debug messages.
40378 + *
40379 + * Revision 1.97 2000/01/10 16:37:16 rgb
40380 + * MB support for new ip_select_ident() upon disappearance of
40381 + * ip_id_count in 2.3.36+.
40382 + *
40383 + * Revision 1.96 1999/12/31 14:59:08 rgb
40384 + * MB fix to use new skb_copy_expand in kernel 2.3.35.
40385 + *
40386 + * Revision 1.95 1999/12/29 21:15:44 rgb
40387 + * Fix tncfg to aliased device bug.
40388 + *
40389 + * Revision 1.94 1999/12/22 04:26:06 rgb
40390 + * Converted all 'static' functions to 'DEBUG_NO_STATIC' to enable
40391 + * debugging by providing external labels to all functions with debugging
40392 + * turned on.
40393 + *
40394 + * Revision 1.93 1999/12/13 13:30:14 rgb
40395 + * Changed MTU reports and HW address reporting back to debug only.
40396 + *
40397 + * Revision 1.92 1999/12/07 18:57:56 rgb
40398 + * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled.
40399 + *
40400 + * Revision 1.91 1999/12/01 22:15:36 rgb
40401 + * Add checks for LARVAL and DEAD SAs.
40402 + * Change state of SA from MATURE to DYING when a soft lifetime is
40403 + * reached and print debug warning.
40404 + *
40405 + * Revision 1.90 1999/11/23 23:04:04 rgb
40406 + * Use provided macro ADDRTOA_BUF instead of hardcoded value.
40407 + * Sort out pfkey and freeswan headers, putting them in a library path.
40408 + *
40409 + * Revision 1.89 1999/11/18 18:50:59 rgb
40410 + * Changed all device registrations for static linking to
40411 + * dynamic to reduce the number and size of patches.
40412 + *
40413 + * Revision 1.88 1999/11/18 04:09:19 rgb
40414 + * Replaced all kernel version macros to shorter, readable form.
40415 + *
40416 + * Revision 1.87 1999/11/17 15:53:40 rgb
40417 + * Changed all occurrences of #include "../../../lib/freeswan.h"
40418 + * to #include <freeswan.h> which works due to -Ilibfreeswan in the
40419 + * klips/net/ipsec/Makefile.
40420 + *
40421 + * Revision 1.86 1999/10/16 18:25:37 rgb
40422 + * Moved SA lifetime expiry checks before packet processing.
40423 + * Expire SA on replay counter rollover.
40424 + *
40425 + * Revision 1.85 1999/10/16 04:24:31 rgb
40426 + * Add stats for time since last packet.
40427 + *
40428 + * Revision 1.84 1999/10/16 00:30:47 rgb
40429 + * Added SA lifetime counting.
40430 + *
40431 + * Revision 1.83 1999/10/15 22:15:57 rgb
40432 + * Clean out cruft.
40433 + * Add debugging.
40434 + *
40435 + * Revision 1.82 1999/10/08 18:26:19 rgb
40436 + * Fix 2.0.3x outgoing fragmented packet memory leak.
40437 + *
40438 + * Revision 1.81 1999/10/05 02:38:54 rgb
40439 + * Lower the default mtu of virtual devices to 16260.
40440 + *
40441 + * Revision 1.80 1999/10/03 18:56:41 rgb
40442 + * Spinlock support for 2.3.xx.
40443 + * Don't forget to undo spinlocks on error!
40444 + * Check for valid eroute before copying the structure.
40445 + *
40446 + * Revision 1.79 1999/10/01 15:44:53 rgb
40447 + * Move spinlock header include to 2.1> scope.
40448 + *
40449 + * Revision 1.78 1999/10/01 00:02:43 rgb
40450 + * Added tdb structure locking.
40451 + * Added eroute structure locking.
40452 + *
40453 + * Revision 1.77 1999/09/30 02:52:29 rgb
40454 + * Add Marc Boucher's Copy-On-Write code (same as ipsec_rcv.c).
40455 + *
40456 + * Revision 1.76 1999/09/25 19:31:27 rgb
40457 + * Refine MSS hack to affect SYN, but not SYN+ACK packets.
40458 + *
40459 + * Revision 1.75 1999/09/24 22:52:38 rgb
40460 + * Fix two things broken in 2.0.38 by trying to fix network notifiers.
40461 + *
40462 + * Revision 1.74 1999/09/24 00:30:37 rgb
40463 + * Add test for changed source as well as destination to check for
40464 + * recursion.
40465 + *
40466 + * Revision 1.73 1999/09/23 20:52:24 rgb
40467 + * Add James Morris' MSS hack patch, disabled.
40468 + *
40469 + * Revision 1.72 1999/09/23 20:22:40 rgb
40470 + * Enable, tidy and fix network notifier code.
40471 + *
40472 + * Revision 1.71 1999/09/23 18:09:05 rgb
40473 + * Clean up 2.2.x fragmenting traces.
40474 + * Disable dev->type switching, forcing ARPHRD_TUNNEL.
40475 + *
40476 + * Revision 1.70 1999/09/22 14:14:24 rgb
40477 + * Add sanity checks for revectored calls to prevent calling a downed I/F.
40478 + *
40479 + * Revision 1.69 1999/09/21 15:00:57 rgb
40480 + * Add Marc Boucher's packet size check.
40481 + * Flesh out network device notifier code.
40482 + *
40483 + * Revision 1.68 1999/09/18 11:39:57 rgb
40484 + * Start to add (disabled) netdevice notifier code.
40485 + *
40486 + * Revision 1.67 1999/09/17 23:44:40 rgb
40487 + * Add a comment warning potential code hackers to stay away from mac.raw.
40488 + *
40489 + * Revision 1.66 1999/09/17 18:04:02 rgb
40490 + * Add fix for unpredictable hard_header_len for ISDN folks (thanks MB).
40491 + * Ditch TTL decrement in 2.2 (MB).
40492 + *
40493 + * Revision 1.65 1999/09/15 23:15:35 henry
40494 + * Marc Boucher's PPP fixes
40495 + *
40496 + * Revision 1.64 1999/09/07 13:40:53 rgb
40497 + * Ditch unreliable references to skb->mac.raw.
40498 + *
40499 + * Revision 1.63 1999/08/28 11:33:09 rgb
40500 + * Check for null skb->mac pointer.
40501 + *
40502 + * Revision 1.62 1999/08/28 02:02:30 rgb
40503 + * Add Marc Boucher's fix for properly dealing with skb->sk.
40504 + *
40505 + * Revision 1.61 1999/08/27 05:23:05 rgb
40506 + * Clean up skb->data/raw/nh/h manipulation.
40507 + * Add Marc Boucher's mods to aid tcpdump.
40508 + * Add sanity checks to skb->raw/nh/h pointer copies in skb_copy_expand.
40509 + * Re-order hard_header stripping -- might be able to remove it...
40510 + *
40511 + * Revision 1.60 1999/08/26 20:01:02 rgb
40512 + * Tidy up compiler directives and macros.
40513 + * Re-enable ICMP for tunnels where inner_dst != outer_dst.
40514 + * Remove unnecessary skb->dev = physdev assignment affecting 2.2.x.
40515 + *
40516 + * Revision 1.59 1999/08/25 15:44:41 rgb
40517 + * Clean up from 2.2.x instrumenting for compilation under 2.0.36.
40518 + *
40519 + * Revision 1.58 1999/08/25 15:00:54 rgb
40520 + * Add dst cache code for 2.2.xx.
40521 + * Add sanity check for skb packet header pointers.
40522 + * Add/modify debugging instrumentation to *_start_xmit, *_hard_header and
40523 + * *_rebuild_header.
40524 + * Add neigh_* cache code.
40525 + * Change dev->type back to ARPHRD_TUNNEL.
40526 + *
40527 + * Revision 1.57 1999/08/17 21:50:23 rgb
40528 + * Fixed minor debug output bugs.
40529 + * Regrouped error recovery exit code.
40530 + * Added compiler directives to remove unwanted code and symbols.
40531 + * Shut off ICMP messages: to be refined to only send ICMP to remote systems.
40532 + * Add debugging code for output function addresses.
40533 + * Fix minor bug in (possibly unused) header_cache_bind function.
40534 + * Add device neighbour caching code.
40535 + * Change dev->type from ARPHRD_TUNNEL to physdev->type.
40536 + *
40537 + * Revision 1.56 1999/08/03 17:22:56 rgb
40538 + * Debug output clarification using KERN_* macros. Other inactive changes
40539 + * added.
40540 + *
40541 + * Revision 1.55 1999/08/03 16:58:46 rgb
40542 + * Fix skb_copy_expand size bug. Was getting incorrect size.
40543 + *
40544 + * Revision 1.54 1999/07/14 19:32:38 rgb
40545 + * Fix oversize packet crash and ssh stalling in 2.2.x kernels.
40546 + *
40547 + * Revision 1.53 1999/06/10 15:44:02 rgb
40548 + * Minor reformatting and clean-up.
40549 + *
40550 + * Revision 1.52 1999/05/09 03:25:36 rgb
40551 + * Fix bug introduced by 2.2 quick-and-dirty patch.
40552 + *
40553 + * Revision 1.51 1999/05/08 21:24:59 rgb
40554 + * Add casting to silence the 2.2.x compile.
40555 + *
40556 + * Revision 1.50 1999/05/05 22:02:32 rgb
40557 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
40558 + *
40559 + * Revision 1.49 1999/04/29 15:18:52 rgb
40560 + * Change gettdb parameter to a pointer to reduce stack loading and
40561 + * facilitate parameter sanity checking.
40562 + * Fix undetected bug that might have tried to access a null pointer.
40563 + * Eliminate unnessessary usage of tdb_xform member to further switch
40564 + * away from the transform switch to the algorithm switch.
40565 + * Add return values to init and cleanup functions.
40566 + *
40567 + * Revision 1.48 1999/04/16 15:38:00 rgb
40568 + * Minor rearrangement of freeing code to avoid memory leaks with impossible or
40569 + * rare situations.
40570 + *
40571 + * Revision 1.47 1999/04/15 15:37:25 rgb
40572 + * Forward check changes from POST1_00 branch.
40573 + *
40574 + * Revision 1.32.2.4 1999/04/13 21:00:18 rgb
40575 + * Ditch 'things I wish I had known before...'.
40576 + *
40577 + * Revision 1.32.2.3 1999/04/13 20:34:38 rgb
40578 + * Free skb after fragmentation.
40579 + * Use stats more effectively.
40580 + * Add I/F to mtu notch-down reporting.
40581 + *
40582 + * Revision 1.32.2.2 1999/04/02 04:26:14 rgb
40583 + * Backcheck from HEAD, pre1.0.
40584 + *
40585 + * Revision 1.46 1999/04/11 00:29:00 henry
40586 + * GPL boilerplate
40587 + *
40588 + * Revision 1.45 1999/04/07 15:42:01 rgb
40589 + * Fix mtu/ping bug AGAIN!
40590 + *
40591 + * Revision 1.44 1999/04/06 04:54:27 rgb
40592 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
40593 + * patch shell fixes.
40594 + *
40595 + * Revision 1.43 1999/04/04 03:57:07 rgb
40596 + * ip_fragment() doesn't free the supplied skb. Freed.
40597 + *
40598 + * Revision 1.42 1999/04/01 23:27:15 rgb
40599 + * Preload size of virtual mtu.
40600 + *
40601 + * Revision 1.41 1999/04/01 09:31:23 rgb
40602 + * Invert meaning of ICMP PMTUD config option and clarify.
40603 + * Code clean-up.
40604 + *
40605 + * Revision 1.40 1999/04/01 04:37:17 rgb
40606 + * SSH stalling bug fix.
40607 + *
40608 + * Revision 1.39 1999/03/31 23:44:28 rgb
40609 + * Don't send ICMP on DF and frag_off.
40610 + *
40611 + * Revision 1.38 1999/03/31 15:20:10 rgb
40612 + * Quiet down debugging.
40613 + *
40614 + * Revision 1.37 1999/03/31 08:30:31 rgb
40615 + * Add switch to shut off ICMP PMTUD packets.
40616 + *
40617 + * Revision 1.36 1999/03/31 05:44:47 rgb
40618 + * Keep PMTU reduction private.
40619 + *
40620 + * Revision 1.35 1999/03/27 15:13:02 rgb
40621 + * PMTU/fragmentation bug fix.
40622 + *
40623 + * Revision 1.34 1999/03/17 21:19:26 rgb
40624 + * Fix kmalloc nonatomic bug.
40625 + *
40626 + * Revision 1.33 1999/03/17 15:38:42 rgb
40627 + * Code clean-up.
40628 + * ESP_NULL IV bug fix.
40629 + *
40630 + * Revision 1.32 1999/03/01 20:44:25 rgb
40631 + * Code clean-up.
40632 + * Memory leak bug fix.
40633 + *
40634 + * Revision 1.31 1999/02/27 00:02:09 rgb
40635 + * Tune to report the MTU reduction once, rather than after every recursion
40636 + * through the encapsulating code, preventing tcp stream stalling.
40637 + *
40638 + * Revision 1.30 1999/02/24 20:21:01 rgb
40639 + * Reformat debug printk's.
40640 + * Fix recursive encapsulation, dynamic MTU bugs and add debugging code.
40641 + * Clean-up.
40642 + *
40643 + * Revision 1.29 1999/02/22 17:08:14 rgb
40644 + * Fix recursive encapsulation code.
40645 + *
40646 + * Revision 1.28 1999/02/19 18:27:02 rgb
40647 + * Improve DF, fragmentation and PMTU behaviour and add dynamic MTU discovery.
40648 + *
40649 + * Revision 1.27 1999/02/17 16:51:37 rgb
40650 + * Clean out unused cruft.
40651 + * Temporarily tone down volume of debug output.
40652 + * Temporarily shut off fragment rejection.
40653 + * Disabled temporary failed recursive encapsulation loop.
40654 + *
40655 + * Revision 1.26 1999/02/12 21:21:26 rgb
40656 + * Move KLIPS_PRINT to ipsec_netlink.h for accessibility.
40657 + *
40658 + * Revision 1.25 1999/02/11 19:38:27 rgb
40659 + * More clean-up.
40660 + * Add sanity checking for skb_copy_expand() to prevent kernel panics on
40661 + * skb_put() values out of range.
40662 + * Fix head/tailroom calculation causing skb_put() out-of-range values.
40663 + * Fix return values to prevent 'nonatomic alloc_skb' warnings.
40664 + * Allocate new skb iff needed.
40665 + * Added more debug statements.
40666 + * Make headroom depend on structure, not hard-coded values.
40667 + *
40668 + * Revision 1.24 1999/02/10 23:20:33 rgb
40669 + * Shut up annoying 'statement has no effect' compiler warnings with
40670 + * debugging compiled out.
40671 + *
40672 + * Revision 1.23 1999/02/10 22:36:30 rgb
40673 + * Clean-up obsolete, unused and messy code.
40674 + * Converted most IPSEC_DEBUG statements to KLIPS_PRINT macros.
40675 + * Rename ipsec_tunnel_do_xmit to ipsec_tunnel_start_xmit and eliminated
40676 + * original ipsec_tunnel_start_xmit.
40677 + * Send all packet with different inner and outer destinations directly to
40678 + * the attached physical device, rather than back through ip_forward,
40679 + * preventing disappearing routes problems.
40680 + * Do sanity checking before investing too much CPU in allocating new
40681 + * structures.
40682 + * Fail on IP header options: We cannot process them yet.
40683 + * Add some helpful comments.
40684 + * Use virtual device for parameters instead of physical device.
40685 + *
40686 + * Revision 1.22 1999/02/10 03:03:02 rgb
40687 + * Duh. Fixed the TTL bug: forgot to update the checksum.
40688 + *
40689 + * Revision 1.21 1999/02/09 23:17:53 rgb
40690 + * Add structure members to ipsec_print_ip debug function.
40691 + * Temporarily fix TTL bug preventing tunnel mode from functioning.
40692 + *
40693 + * Revision 1.20 1999/02/09 00:14:25 rgb
40694 + * Add KLIPSPRINT macro. (Not used yet, though.)
40695 + * Delete old ip_tunnel code (BADCODE).
40696 + * Decrement TTL in outgoing packet.
40697 + * Set TTL on new IPIP_TUNNEL to default, not existing packet TTL.
40698 + * Delete ethernet only feature and fix hard-coded hard_header_len.
40699 + *
40700 + * Revision 1.19 1999/01/29 17:56:22 rgb
40701 + * 64-bit re-fix submitted by Peter Onion.
40702 + *
40703 + * Revision 1.18 1999/01/28 22:43:24 rgb
40704 + * Fixed bug in ipsec_print_ip that caused an OOPS, found by P.Onion.
40705 + *
40706 + * Revision 1.17 1999/01/26 02:08:16 rgb
40707 + * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
40708 + * Removed dead code.
40709 + *
40710 + * Revision 1.16 1999/01/22 06:25:26 rgb
40711 + * Cruft clean-out.
40712 + * Added algorithm switch code.
40713 + * 64-bit clean-up.
40714 + * Passthrough on IPIP protocol, spi 0x0 fix.
40715 + * Enhanced debugging.
40716 + *
40717 + * Revision 1.15 1998/12/01 13:22:04 rgb
40718 + * Added support for debug printing of version info.
40719 + *
40720 + * Revision 1.14 1998/11/30 13:22:55 rgb
40721 + * Rationalised all the klips kernel file headers. They are much shorter
40722 + * now and won't conflict under RH5.2.
40723 + *
40724 + * Revision 1.13 1998/11/17 21:13:52 rgb
40725 + * Put IKE port bypass debug output in user-switched debug statements.
40726 + *
40727 + * Revision 1.12 1998/11/13 13:20:25 rgb
40728 + * Fixed ntohs bug in udp/500 hole for IKE.
40729 + *
40730 + * Revision 1.11 1998/11/10 08:01:19 rgb
40731 + * Kill tcp/500 hole, keep udp/500 hole.
40732 + *
40733 + * Revision 1.10 1998/11/09 21:29:26 rgb
40734 + * If no eroute is found, discard packet and incr. tx_error.
40735 + *
40736 + * Revision 1.9 1998/10/31 06:50:00 rgb
40737 + * Add tcp/udp/500 bypass.
40738 + * Fixed up comments in #endif directives.
40739 + *
40740 + * Revision 1.8 1998/10/27 00:34:31 rgb
40741 + * Reformat debug output of IP headers.
40742 + * Newlines added before calls to ipsec_print_ip.
40743 + *
40744 + * Revision 1.7 1998/10/19 14:44:28 rgb
40745 + * Added inclusion of freeswan.h.
40746 + * sa_id structure implemented and used: now includes protocol.
40747 + *
40748 + * Revision 1.6 1998/10/09 04:31:35 rgb
40749 + * Added 'klips_debug' prefix to all klips printk debug statements.
40750 + *
40751 + * Revision 1.5 1998/08/28 03:09:51 rgb
40752 + * Prevent kernel log spam with default route through ipsec.
40753 + *
40754 + * Revision 1.4 1998/08/05 22:23:09 rgb
40755 + * Change setdev return code to ENXIO for a non-existant physical device.
40756 + *
40757 + * Revision 1.3 1998/07/29 20:41:11 rgb
40758 + * Add ipsec_tunnel_clear to clear all tunnel attachments.
40759 + *
40760 + * Revision 1.2 1998/06/25 20:00:33 rgb
40761 + * Clean up #endif comments.
40762 + * Rename dev_ipsec to dev_ipsec0 for consistency.
40763 + * Document ipsec device fields.
40764 + * Make ipsec_tunnel_probe visible from rest of kernel for static linking.
40765 + * Get debugging report for *every* ipsec device initialisation.
40766 + * Comment out redundant code.
40767 + *
40768 + * Revision 1.1 1998/06/18 21:27:50 henry
40769 + * move sources from klips/src to klips/net/ipsec, to keep stupid
40770 + * kernel-build scripts happier in the presence of symlinks
40771 + *
40772 + * Revision 1.8 1998/06/14 23:49:40 rgb
40773 + * Clarify version reporting on module loading.
40774 + *
40775 + * Revision 1.7 1998/05/27 23:19:20 rgb
40776 + * Added version reporting.
40777 + *
40778 + * Revision 1.6 1998/05/18 21:56:23 rgb
40779 + * Clean up for numerical consistency of output and cleaning up debug code.
40780 + *
40781 + * Revision 1.5 1998/05/12 02:44:23 rgb
40782 + * Clarifying 'no e-route to host' message.
40783 + *
40784 + * Revision 1.4 1998/04/30 15:34:35 rgb
40785 + * Enclosed most remaining debugging statements in #ifdef's to make it quieter.
40786 + *
40787 + * Revision 1.3 1998/04/21 21:28:54 rgb
40788 + * Rearrange debug switches to change on the fly debug output from user
40789 + * space. Only kernel changes checked in at this time. radij.c was also
40790 + * changed to temporarily remove buggy debugging code in rj_delete causing
40791 + * an OOPS and hence, netlink device open errors.
40792 + *
40793 + * Revision 1.2 1998/04/12 22:03:24 rgb
40794 + * Updated ESP-3DES-HMAC-MD5-96,
40795 + * ESP-DES-HMAC-MD5-96,
40796 + * AH-HMAC-MD5-96,
40797 + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
40798 + * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
40799 + *
40800 + * Fixed eroute references in /proc/net/ipsec*.
40801 + *
40802 + * Started to patch module unloading memory leaks in ipsec_netlink and
40803 + * radij tree unloading.
40804 + *
40805 + * Revision 1.1 1998/04/09 03:06:12 henry
40806 + * sources moved up from linux/net/ipsec
40807 + *
40808 + * Revision 1.1.1.1 1998/04/08 05:35:04 henry
40809 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
40810 + *
40811 + * Revision 0.5 1997/06/03 04:24:48 ji
40812 + * Added transport mode.
40813 + * Changed the way routing is done.
40814 + * Lots of bug fixes.
40815 + *
40816 + * Revision 0.4 1997/01/15 01:28:15 ji
40817 + * No changes.
40818 + *
40819 + * Revision 0.3 1996/11/20 14:39:04 ji
40820 + * Minor cleanups.
40821 + * Rationalized debugging code.
40822 + *
40823 + * Revision 0.2 1996/11/02 00:18:33 ji
40824 + * First limited release.
40825 + *
40826 + * Local Variables:
40827 + * c-style: linux
40828 + * End:
40829 + */
40830 --- /dev/null Tue Mar 11 13:02:56 2003
40831 +++ linux/net/ipsec/ipsec_xform.c Mon Feb 9 13:51:03 2004
40832 @@ -0,0 +1,355 @@
40833 +/*
40834 + * Common routines for IPSEC transformations.
40835 + * Copyright (C) 1996, 1997 John Ioannidis.
40836 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
40837 + *
40838 + * This program is free software; you can redistribute it and/or modify it
40839 + * under the terms of the GNU General Public License as published by the
40840 + * Free Software Foundation; either version 2 of the License, or (at your
40841 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
40842 + *
40843 + * This program is distributed in the hope that it will be useful, but
40844 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
40845 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
40846 + * for more details.
40847 + *
40848 + * RCSID $Id: ipsec_xform.c,v 1.65 2005/04/29 05:10:22 mcr Exp $
40849 + */
40850 +
40851 +#ifndef AUTOCONF_INCLUDED
40852 +#include <linux/config.h>
40853 +#endif
40854 +#include <linux/version.h>
40855 +#include <linux/kernel.h> /* printk() */
40856 +
40857 +#include "freeswan/ipsec_param.h"
40858 +
40859 +#ifdef MALLOC_SLAB
40860 +# include <linux/slab.h> /* kmalloc() */
40861 +#else /* MALLOC_SLAB */
40862 +# include <linux/malloc.h> /* kmalloc() */
40863 +#endif /* MALLOC_SLAB */
40864 +#include <linux/errno.h> /* error codes */
40865 +#include <linux/types.h> /* size_t */
40866 +#include <linux/interrupt.h> /* mark_bh */
40867 +
40868 +#include <linux/netdevice.h> /* struct device, and other headers */
40869 +#include <linux/etherdevice.h> /* eth_type_trans */
40870 +#include <linux/ip.h> /* struct iphdr */
40871 +#include <linux/skbuff.h>
40872 +#include <linux/random.h> /* get_random_bytes() */
40873 +#include <freeswan.h>
40874 +#ifdef SPINLOCK
40875 +# ifdef SPINLOCK_23
40876 +# include <linux/spinlock.h> /* *lock* */
40877 +# else /* SPINLOCK_23 */
40878 +# include <asm/spinlock.h> /* *lock* */
40879 +# endif /* SPINLOCK_23 */
40880 +#endif /* SPINLOCK */
40881 +
40882 +#include <net/ip.h>
40883 +
40884 +#include "freeswan/radij.h"
40885 +#include "freeswan/ipsec_encap.h"
40886 +#include "freeswan/ipsec_radij.h"
40887 +#include "freeswan/ipsec_xform.h"
40888 +#include "freeswan/ipsec_ipe4.h"
40889 +#include "freeswan/ipsec_ah.h"
40890 +#include "freeswan/ipsec_esp.h"
40891 +
40892 +#include <openswan/pfkeyv2.h>
40893 +#include <openswan/pfkey.h>
40894 +
40895 +#ifdef CONFIG_KLIPS_DEBUG
40896 +int debug_xform = 0;
40897 +#endif /* CONFIG_KLIPS_DEBUG */
40898 +
40899 +#ifdef SPINLOCK
40900 +spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
40901 +#else /* SPINLOCK */
40902 +spinlock_t tdb_lock;
40903 +#endif /* SPINLOCK */
40904 +
40905 +/*
40906 + * $Log: ipsec_xform.c,v $
40907 + * Revision 1.65 2005/04/29 05:10:22 mcr
40908 + * removed from extraenous includes to make unit testing easier.
40909 + *
40910 + * Revision 1.64 2004/07/10 19:11:18 mcr
40911 + * CONFIG_IPSEC -> CONFIG_KLIPS.
40912 + *
40913 + * Revision 1.63 2003/10/31 02:27:55 mcr
40914 + * pulled up port-selector patches and sa_id elimination.
40915 + *
40916 + * Revision 1.62.30.1 2003/10/29 01:30:41 mcr
40917 + * elimited "struct sa_id".
40918 + *
40919 + * Revision 1.62 2002/05/14 02:34:21 rgb
40920 + * Delete stale code.
40921 + *
40922 + * Revision 1.61 2002/04/24 07:55:32 mcr
40923 + * #include patches and Makefiles for post-reorg compilation.
40924 + *
40925 + * Revision 1.60 2002/04/24 07:36:33 mcr
40926 + * Moved from ./klips/net/ipsec/ipsec_xform.c,v
40927 + *
40928 + * Revision 1.59 2002/03/29 15:01:36 rgb
40929 + * Delete decommissioned code.
40930 + *
40931 + * Revision 1.58 2002/01/29 17:17:57 mcr
40932 + * moved include of ipsec_param.h to after include of linux/kernel.h
40933 + * otherwise, it seems that some option that is set in ipsec_param.h
40934 + * screws up something subtle in the include path to kernel.h, and
40935 + * it complains on the snprintf() prototype.
40936 + *
40937 + * Revision 1.57 2002/01/29 04:00:53 mcr
40938 + * more excise of kversions.h header.
40939 + *
40940 + * Revision 1.56 2001/11/27 05:17:22 mcr
40941 + * turn off the worst of the per-packet debugging.
40942 + *
40943 + * Revision 1.55 2001/11/26 09:23:50 rgb
40944 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
40945 + *
40946 + * Revision 1.54 2001/10/18 04:45:21 rgb
40947 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
40948 + * lib/freeswan.h version macros moved to lib/kversions.h.
40949 + * Other compiler directive cleanups.
40950 + *
40951 + * Revision 1.53 2001/09/08 21:13:34 rgb
40952 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
40953 + *
40954 + * Revision 1.52 2001/06/14 19:35:11 rgb
40955 + * Update copyright date.
40956 + *
40957 + * Revision 1.51 2001/05/30 08:14:03 rgb
40958 + * Removed vestiges of esp-null transforms.
40959 + *
40960 + * Revision 1.50 2001/05/03 19:43:18 rgb
40961 + * Initialise error return variable.
40962 + * Update SENDERR macro.
40963 + * Fix sign of error return code for ipsec_tdbcleanup().
40964 + * Use more appropriate return code for ipsec_tdbwipe().
40965 + *
40966 + * Revision 1.49 2001/04/19 18:56:17 rgb
40967 + * Fixed tdb table locking comments.
40968 + *
40969 + * Revision 1.48 2001/02/27 22:24:55 rgb
40970 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
40971 + * Check for satoa() return codes.
40972 + *
40973 + * Revision 1.47 2000/11/06 04:32:08 rgb
40974 + * Ditched spin_lock_irqsave in favour of spin_lock_bh.
40975 + *
40976 + * Revision 1.46 2000/09/20 16:21:57 rgb
40977 + * Cleaned up ident string alloc/free.
40978 + *
40979 + * Revision 1.45 2000/09/08 19:16:51 rgb
40980 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
40981 + * Removed all references to CONFIG_IPSEC_PFKEYv2.
40982 + *
40983 + * Revision 1.44 2000/08/30 05:29:04 rgb
40984 + * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
40985 + *
40986 + * Revision 1.43 2000/08/18 21:30:41 rgb
40987 + * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
40988 + *
40989 + * Revision 1.42 2000/08/01 14:51:51 rgb
40990 + * Removed _all_ remaining traces of DES.
40991 + *
40992 + * Revision 1.41 2000/07/28 14:58:31 rgb
40993 + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
40994 + *
40995 + * Revision 1.40 2000/06/28 05:50:11 rgb
40996 + * Actually set iv_bits.
40997 + *
40998 + * Revision 1.39 2000/05/10 23:11:09 rgb
40999 + * Added netlink debugging output.
41000 + * Added a cast to quiet down the ntohl bug.
41001 + *
41002 + * Revision 1.38 2000/05/10 19:18:42 rgb
41003 + * Cast output of ntohl so that the broken prototype doesn't make our
41004 + * compile noisy.
41005 + *
41006 + * Revision 1.37 2000/03/16 14:04:59 rgb
41007 + * Hardwired CONFIG_IPSEC_PFKEYv2 on.
41008 + *
41009 + * Revision 1.36 2000/01/26 10:11:28 rgb
41010 + * Fixed spacing in error text causing run-in words.
41011 + *
41012 + * Revision 1.35 2000/01/21 06:17:16 rgb
41013 + * Tidied up compiler directive indentation for readability.
41014 + * Added ictx,octx vars for simplification.(kravietz)
41015 + * Added macros for HMAC padding magic numbers.(kravietz)
41016 + * Fixed missing key length reporting bug.
41017 + * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
41018 + *
41019 + * Revision 1.34 1999/12/08 00:04:19 rgb
41020 + * Fixed SA direction overwriting bug for netlink users.
41021 + *
41022 + * Revision 1.33 1999/12/01 22:16:44 rgb
41023 + * Minor formatting changes in ESP MD5 initialisation.
41024 + *
41025 + * Revision 1.32 1999/11/25 09:06:36 rgb
41026 + * Fixed error return messages, should be returning negative numbers.
41027 + * Implemented SENDERR macro for propagating error codes.
41028 + * Added debug message and separate error code for algorithms not compiled
41029 + * in.
41030 + *
41031 + * Revision 1.31 1999/11/23 23:06:26 rgb
41032 + * Sort out pfkey and freeswan headers, putting them in a library path.
41033 + *
41034 + * Revision 1.30 1999/11/18 04:09:20 rgb
41035 + * Replaced all kernel version macros to shorter, readable form.
41036 + *
41037 + * Revision 1.29 1999/11/17 15:53:40 rgb
41038 + * Changed all occurrences of #include "../../../lib/freeswan.h"
41039 + * to #include <freeswan.h> which works due to -Ilibfreeswan in the
41040 + * klips/net/ipsec/Makefile.
41041 + *
41042 + * Revision 1.28 1999/10/18 20:04:01 rgb
41043 + * Clean-out unused cruft.
41044 + *
41045 + * Revision 1.27 1999/10/03 19:01:03 rgb
41046 + * Spinlock support for 2.3.xx and 2.0.xx kernels.
41047 + *
41048 + * Revision 1.26 1999/10/01 16:22:24 rgb
41049 + * Switch from assignment init. to functional init. of spinlocks.
41050 + *
41051 + * Revision 1.25 1999/10/01 15:44:54 rgb
41052 + * Move spinlock header include to 2.1> scope.
41053 + *
41054 + * Revision 1.24 1999/10/01 00:03:46 rgb
41055 + * Added tdb structure locking.
41056 + * Minor formatting changes.
41057 + * Add function to initialize tdb hash table.
41058 + *
41059 + * Revision 1.23 1999/05/25 22:42:12 rgb
41060 + * Add deltdbchain() debugging.
41061 + *
41062 + * Revision 1.22 1999/05/25 21:24:31 rgb
41063 + * Add debugging statements to deltdbchain().
41064 + *
41065 + * Revision 1.21 1999/05/25 03:51:48 rgb
41066 + * Refix error return code.
41067 + *
41068 + * Revision 1.20 1999/05/25 03:34:07 rgb
41069 + * Fix error return for flush.
41070 + *
41071 + * Revision 1.19 1999/05/09 03:25:37 rgb
41072 + * Fix bug introduced by 2.2 quick-and-dirty patch.
41073 + *
41074 + * Revision 1.18 1999/05/05 22:02:32 rgb
41075 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
41076 + *
41077 + * Revision 1.17 1999/04/29 15:20:16 rgb
41078 + * Change gettdb parameter to a pointer to reduce stack loading and
41079 + * facilitate parameter sanity checking.
41080 + * Add sanity checking for null pointer arguments.
41081 + * Add debugging instrumentation.
41082 + * Add function deltdbchain() which will take care of unlinking,
41083 + * zeroing and deleting a chain of tdbs.
41084 + * Add a parameter to tdbcleanup to be able to delete a class of SAs.
41085 + * tdbwipe now actually zeroes the tdb as well as any of its pointed
41086 + * structures.
41087 + *
41088 + * Revision 1.16 1999/04/16 15:36:29 rgb
41089 + * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
41090 + *
41091 + * Revision 1.15 1999/04/11 00:29:01 henry
41092 + * GPL boilerplate
41093 + *
41094 + * Revision 1.14 1999/04/06 04:54:28 rgb
41095 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
41096 + * patch shell fixes.
41097 + *
41098 + * Revision 1.13 1999/02/19 18:23:01 rgb
41099 + * Nix debug off compile warning.
41100 + *
41101 + * Revision 1.12 1999/02/17 16:52:16 rgb
41102 + * Consolidate satoa()s for space and speed efficiency.
41103 + * Convert DEBUG_IPSEC to KLIPS_PRINT
41104 + * Clean out unused cruft.
41105 + * Ditch NET_IPIP dependancy.
41106 + * Loop for 3des key setting.
41107 + *
41108 + * Revision 1.11 1999/01/26 02:09:05 rgb
41109 + * Remove ah/esp/IPIP switching on include files.
41110 + * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
41111 + * Removed dead code.
41112 + * Clean up debug code when switched off.
41113 + * Remove references to INET_GET_PROTOCOL.
41114 + * Added code exclusion macros to reduce code from unused algorithms.
41115 + *
41116 + * Revision 1.10 1999/01/22 06:28:55 rgb
41117 + * Cruft clean-out.
41118 + * Put random IV generation in kernel.
41119 + * Added algorithm switch code.
41120 + * Enhanced debugging.
41121 + * 64-bit clean-up.
41122 + *
41123 + * Revision 1.9 1998/11/30 13:22:55 rgb
41124 + * Rationalised all the klips kernel file headers. They are much shorter
41125 + * now and won't conflict under RH5.2.
41126 + *
41127 + * Revision 1.8 1998/11/25 04:59:06 rgb
41128 + * Add conditionals for no IPIP tunnel code.
41129 + * Delete commented out code.
41130 + *
41131 + * Revision 1.7 1998/10/31 06:50:41 rgb
41132 + * Convert xform ASCII names to no spaces.
41133 + * Fixed up comments in #endif directives.
41134 + *
41135 + * Revision 1.6 1998/10/19 14:44:28 rgb
41136 + * Added inclusion of freeswan.h.
41137 + * sa_id structure implemented and used: now includes protocol.
41138 + *
41139 + * Revision 1.5 1998/10/09 04:32:19 rgb
41140 + * Added 'klips_debug' prefix to all klips printk debug statements.
41141 + *
41142 + * Revision 1.4 1998/08/12 00:11:31 rgb
41143 + * Added new xform functions to the xform table.
41144 + * Fixed minor debug output spelling error.
41145 + *
41146 + * Revision 1.3 1998/07/09 17:45:31 rgb
41147 + * Clarify algorithm not available message.
41148 + *
41149 + * Revision 1.2 1998/06/23 03:00:51 rgb
41150 + * Check for presence of IPIP protocol if it is setup one way (we don't
41151 + * know what has been set up the other way and can only assume it will be
41152 + * symmetrical with the exception of keys).
41153 + *
41154 + * Revision 1.1 1998/06/18 21:27:51 henry
41155 + * move sources from klips/src to klips/net/ipsec, to keep stupid
41156 + * kernel-build scripts happier in the presence of symlinks
41157 + *
41158 + * Revision 1.3 1998/06/11 05:54:59 rgb
41159 + * Added transform version string pointer to xformsw initialisations.
41160 + *
41161 + * Revision 1.2 1998/04/21 21:28:57 rgb
41162 + * Rearrange debug switches to change on the fly debug output from user
41163 + * space. Only kernel changes checked in at this time. radij.c was also
41164 + * changed to temporarily remove buggy debugging code in rj_delete causing
41165 + * an OOPS and hence, netlink device open errors.
41166 + *
41167 + * Revision 1.1 1998/04/09 03:06:13 henry
41168 + * sources moved up from linux/net/ipsec
41169 + *
41170 + * Revision 1.1.1.1 1998/04/08 05:35:02 henry
41171 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
41172 + *
41173 + * Revision 0.5 1997/06/03 04:24:48 ji
41174 + * Added ESP-3DES-MD5-96
41175 + *
41176 + * Revision 0.4 1997/01/15 01:28:15 ji
41177 + * Added new transforms.
41178 + *
41179 + * Revision 0.3 1996/11/20 14:39:04 ji
41180 + * Minor cleanups.
41181 + * Rationalized debugging code.
41182 + *
41183 + * Revision 0.2 1996/11/02 00:18:33 ji
41184 + * First limited release.
41185 + *
41186 + *
41187 + */
41188 --- /dev/null Tue Mar 11 13:02:56 2003
41189 +++ linux/net/ipsec/ipsec_xmit.c Mon Feb 9 13:51:03 2004
41190 @@ -0,0 +1,1845 @@
41191 +/*
41192 + * IPSEC Transmit code.
41193 + * Copyright (C) 1996, 1997 John Ioannidis.
41194 + * Copyright (C) 1998-2003 Richard Guy Briggs.
41195 + * Copyright (C) 2004-2005 Michael Richardson <mcr@xelerance.com>
41196 + *
41197 + * This program is free software; you can redistribute it and/or modify it
41198 + * under the terms of the GNU General Public License as published by the
41199 + * Free Software Foundation; either version 2 of the License, or (at your
41200 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
41201 + *
41202 + * This program is distributed in the hope that it will be useful, but
41203 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
41204 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
41205 + * for more details.
41206 + */
41207 +
41208 +char ipsec_xmit_c_version[] = "RCSID $Id: ipsec_xmit.c,v 1.20.2.6 2006/07/07 22:09:49 paul Exp $";
41209 +
41210 +#define __NO_VERSION__
41211 +#include <linux/module.h>
41212 +#ifndef AUTOCONF_INCLUDED
41213 +#include <linux/config.h>
41214 +#endif /* for CONFIG_IP_FORWARD */
41215 +#include <linux/version.h>
41216 +#include <linux/kernel.h> /* printk() */
41217 +
41218 +#include "openswan/ipsec_param.h"
41219 +
41220 +#ifdef MALLOC_SLAB
41221 +# include <linux/slab.h> /* kmalloc() */
41222 +#else /* MALLOC_SLAB */
41223 +# include <linux/malloc.h> /* kmalloc() */
41224 +#endif /* MALLOC_SLAB */
41225 +#include <linux/errno.h> /* error codes */
41226 +#include <linux/types.h> /* size_t */
41227 +#include <linux/interrupt.h> /* mark_bh */
41228 +
41229 +#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
41230 +#include <linux/etherdevice.h> /* eth_type_trans */
41231 +#include <linux/ip.h> /* struct iphdr */
41232 +#include <linux/tcp.h> /* struct tcphdr */
41233 +#include <linux/udp.h> /* struct udphdr */
41234 +#include <linux/skbuff.h>
41235 +#include <asm/uaccess.h>
41236 +#include <asm/checksum.h>
41237 +#include <openswan.h>
41238 +#ifdef NET_21
41239 +# define MSS_HACK_ /* experimental */
41240 +# include <linux/in6.h>
41241 +# include <net/dst.h>
41242 +# define proto_priv cb
41243 +#endif /* NET_21 */
41244 +
41245 +#include <net/icmp.h> /* icmp_send() */
41246 +#include <net/ip.h>
41247 +#ifdef NETDEV_23
41248 +# include <linux/netfilter_ipv4.h>
41249 +#endif /* NETDEV_23 */
41250 +
41251 +#include <linux/if_arp.h>
41252 +#ifdef MSS_HACK
41253 +# include <net/tcp.h> /* TCP options */
41254 +#endif /* MSS_HACK */
41255 +
41256 +#include "openswan/ipsec_kern24.h"
41257 +#include "openswan/radij.h"
41258 +#include "openswan/ipsec_life.h"
41259 +#include "openswan/ipsec_xform.h"
41260 +#include "openswan/ipsec_eroute.h"
41261 +#include "openswan/ipsec_encap.h"
41262 +#include "openswan/ipsec_radij.h"
41263 +#include "openswan/ipsec_xmit.h"
41264 +#include "openswan/ipsec_sa.h"
41265 +#include "openswan/ipsec_tunnel.h"
41266 +#include "openswan/ipsec_ipe4.h"
41267 +#include "openswan/ipsec_ah.h"
41268 +#include "openswan/ipsec_esp.h"
41269 +
41270 +#ifdef CONFIG_KLIPS_IPCOMP
41271 +#include "openswan/ipcomp.h"
41272 +#endif /* CONFIG_KLIPS_IPCOMP */
41273 +
41274 +#include <openswan/pfkeyv2.h>
41275 +#include <openswan/pfkey.h>
41276 +
41277 +#include "openswan/ipsec_proto.h"
41278 +#include "openswan/ipsec_alg.h"
41279 +
41280 +
41281 +/*
41282 + * Stupid kernel API differences in APIs. Not only do some
41283 + * kernels not have ip_select_ident, but some have differing APIs,
41284 + * and SuSE has one with one parameter, but no way of checking to
41285 + * see what is really what.
41286 + */
41287 +
41288 +#ifdef SUSE_LINUX_2_4_19_IS_STUPID
41289 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
41290 +#else
41291 +
41292 +/* simplest case, nothing */
41293 +#if !defined(IP_SELECT_IDENT)
41294 +#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
41295 +#endif
41296 +
41297 +/* kernels > 2.3.37-ish */
41298 +#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
41299 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
41300 +#endif
41301 +
41302 +/* kernels > 2.4.2 */
41303 +#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
41304 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
41305 +#endif
41306 +
41307 +#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
41308 +
41309 +
41310 +
41311 +#if defined(CONFIG_KLIPS_AH)
41312 +static __u32 zeroes[64];
41313 +#endif
41314 +
41315 +#ifdef CONFIG_KLIPS_DEBUG
41316 +int sysctl_ipsec_debug_verbose = 0;
41317 +#endif /* CONFIG_KLIPS_DEBUG */
41318 +
41319 +int ipsec_xmit_trap_count = 0;
41320 +int ipsec_xmit_trap_sendcount = 0;
41321 +
41322 +int sysctl_ipsec_icmp = 0;
41323 +int sysctl_ipsec_tos = 0;
41324 +
41325 +#ifdef CONFIG_KLIPS_DEBUG
41326 +#define dmp(_x,_y,_z) if(debug_tunnel) ipsec_dmp_block(_x,_y,_z)
41327 +#else /* CONFIG_KLIPS_DEBUG */
41328 +#define dmp(_x, _y, _z)
41329 +#endif /* CONFIG_KLIPS_DEBUG */
41330 +
41331 +
41332 +#if !defined(SKB_COPY_EXPAND) || defined(KLIPS_UNIT_TESTS)
41333 +/*
41334 + * This is mostly skbuff.c:skb_copy().
41335 + */
41336 +struct sk_buff *
41337 +skb_copy_expand(const struct sk_buff *skb, int headroom,
41338 + int tailroom, int priority)
41339 +{
41340 + struct sk_buff *n;
41341 + unsigned long offset;
41342 +
41343 + /*
41344 + * Do sanity checking
41345 + */
41346 + if((headroom < 0) || (tailroom < 0) || ((headroom+tailroom) < 0)) {
41347 + printk(KERN_WARNING
41348 + "klips_error:skb_copy_expand: "
41349 + "Illegal negative head,tailroom %d,%d\n",
41350 + headroom,
41351 + tailroom);
41352 + return NULL;
41353 + }
41354 + /*
41355 + * Allocate the copy buffer
41356 + */
41357 +
41358 +#ifndef NET_21
41359 + IS_SKB(skb);
41360 +#endif /* !NET_21 */
41361 +
41362 +
41363 + n=alloc_skb(skb->end - skb->head + headroom + tailroom, priority);
41364 +
41365 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
41366 + "klips_debug:skb_copy_expand: "
41367 + "allocating %d bytes, head=0p%p data=0p%p tail=0p%p end=0p%p end-head=%d tail-data=%d\n",
41368 + skb->end - skb->head + headroom + tailroom,
41369 + skb->head,
41370 + skb->data,
41371 + skb->tail,
41372 + skb->end,
41373 + skb->end - skb->head,
41374 + skb->tail - skb->data);
41375 +
41376 + if(n==NULL)
41377 + return NULL;
41378 +
41379 + /*
41380 + * Shift between the two data areas in bytes
41381 + */
41382 +
41383 + /* Set the data pointer */
41384 + skb_reserve(n,skb->data-skb->head+headroom);
41385 + /* Set the tail pointer and length */
41386 + if(skb_tailroom(n) < skb->len) {
41387 + printk(KERN_WARNING "klips_error:skb_copy_expand: "
41388 + "tried to skb_put %ld, %d available. This should never happen, please report.\n",
41389 + (unsigned long int)skb->len,
41390 + skb_tailroom(n));
41391 + ipsec_kfree_skb(n);
41392 + return NULL;
41393 + }
41394 + skb_put(n,skb->len);
41395 +
41396 + offset=n->head + headroom - skb->head;
41397 +
41398 + /* Copy the bytes */
41399 + memcpy(n->head + headroom, skb->head,skb->end-skb->head);
41400 +#ifdef NET_21
41401 + n->csum=skb->csum;
41402 + n->priority=skb->priority;
41403 + n->dst=dst_clone(skb->dst);
41404 + if(skb->nh.raw)
41405 + n->nh.raw=skb->nh.raw+offset;
41406 +#ifndef NETDEV_23
41407 + n->is_clone=0;
41408 +#endif /* NETDEV_23 */
41409 + atomic_set(&n->users, 1);
41410 + n->destructor = NULL;
41411 +#ifdef HAVE_SOCK_SECURITY
41412 + n->security=skb->security;
41413 +#endif
41414 +#else /* NET_21 */
41415 + n->link3=NULL;
41416 + n->when=skb->when;
41417 + if(skb->ip_hdr)
41418 + n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
41419 + n->saddr=skb->saddr;
41420 + n->daddr=skb->daddr;
41421 + n->raddr=skb->raddr;
41422 + n->seq=skb->seq;
41423 + n->end_seq=skb->end_seq;
41424 + n->ack_seq=skb->ack_seq;
41425 + n->acked=skb->acked;
41426 + n->free=1;
41427 + n->arp=skb->arp;
41428 + n->tries=0;
41429 + n->lock=0;
41430 + n->users=0;
41431 +#endif /* NET_21 */
41432 + n->protocol=skb->protocol;
41433 + n->list=NULL;
41434 + n->sk=NULL;
41435 + n->dev=skb->dev;
41436 + if(skb->h.raw)
41437 + n->h.raw=skb->h.raw+offset;
41438 + if(skb->mac.raw)
41439 + n->mac.raw=skb->mac.raw+offset;
41440 + memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
41441 +#ifndef NETDEV_23
41442 + n->used=skb->used;
41443 +#endif /* !NETDEV_23 */
41444 + n->pkt_type=skb->pkt_type;
41445 + n->stamp=skb->stamp;
41446 +
41447 +#ifndef NET_21
41448 + IS_SKB(n);
41449 +#endif /* !NET_21 */
41450 + return n;
41451 +}
41452 +#endif /* !SKB_COPY_EXPAND */
41453 +
41454 +#ifdef CONFIG_KLIPS_DEBUG
41455 +void
41456 +ipsec_print_ip(struct iphdr *ip)
41457 +{
41458 + char buf[ADDRTOA_BUF];
41459 +
41460 + printk(KERN_INFO "klips_debug: IP:");
41461 + printk(" ihl:%d", ip->ihl << 2);
41462 + printk(" ver:%d", ip->version);
41463 + printk(" tos:%d", ip->tos);
41464 + printk(" tlen:%d", ntohs(ip->tot_len));
41465 + printk(" id:%d", ntohs(ip->id));
41466 + printk(" %s%s%sfrag_off:%d",
41467 + ip->frag_off & __constant_htons(IP_CE) ? "CE " : "",
41468 + ip->frag_off & __constant_htons(IP_DF) ? "DF " : "",
41469 + ip->frag_off & __constant_htons(IP_MF) ? "MF " : "",
41470 + (ntohs(ip->frag_off) & IP_OFFSET) << 3);
41471 + printk(" ttl:%d", ip->ttl);
41472 + printk(" proto:%d", ip->protocol);
41473 + if(ip->protocol == IPPROTO_UDP)
41474 + printk(" (UDP)");
41475 + if(ip->protocol == IPPROTO_TCP)
41476 + printk(" (TCP)");
41477 + if(ip->protocol == IPPROTO_ICMP)
41478 + printk(" (ICMP)");
41479 + if(ip->protocol == IPPROTO_ESP)
41480 + printk(" (ESP)");
41481 + if(ip->protocol == IPPROTO_AH)
41482 + printk(" (AH)");
41483 + if(ip->protocol == IPPROTO_COMP)
41484 + printk(" (COMP)");
41485 + printk(" chk:%d", ntohs(ip->check));
41486 + addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf));
41487 + printk(" saddr:%s", buf);
41488 + if(ip->protocol == IPPROTO_UDP)
41489 + printk(":%d",
41490 + ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
41491 + if(ip->protocol == IPPROTO_TCP)
41492 + printk(":%d",
41493 + ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
41494 + addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf));
41495 + printk(" daddr:%s", buf);
41496 + if(ip->protocol == IPPROTO_UDP)
41497 + printk(":%d",
41498 + ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
41499 + if(ip->protocol == IPPROTO_TCP)
41500 + printk(":%d",
41501 + ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
41502 + if(ip->protocol == IPPROTO_ICMP)
41503 + printk(" type:code=%d:%d",
41504 + ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type,
41505 + ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code);
41506 + printk("\n");
41507 +
41508 + if(sysctl_ipsec_debug_verbose) {
41509 + __u8 *c;
41510 + int len = ntohs(ip->tot_len) - ip->ihl*4;
41511 +
41512 + c = ((__u8*)ip) + ip->ihl*4;
41513 + ipsec_dmp_block("ip_print", c, len);
41514 + }
41515 +}
41516 +#endif /* CONFIG_KLIPS_DEBUG */
41517 +
41518 +#ifdef MSS_HACK
41519 +/*
41520 + * Issues:
41521 + * 1) Fragments arriving in the tunnel should probably be rejected.
41522 + * 2) How does this affect syncookies, mss_cache, dst cache ?
41523 + * 3) Path MTU discovery handling needs to be reviewed. For example,
41524 + * if we receive an ICMP 'packet too big' message from an intermediate
41525 + * router specifying it's next hop MTU, our stack may process this and
41526 + * adjust the MSS without taking our AH/ESP overheads into account.
41527 + */
41528 +
41529 +
41530 +/*
41531 + * Recaclulate checksum using differences between changed datum,
41532 + * borrowed from netfilter.
41533 + */
41534 +DEBUG_NO_STATIC u_int16_t
41535 +ipsec_fast_csum(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
41536 +{
41537 + u_int32_t diffs[] = { oldvalinv, newval };
41538 + return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
41539 + oldcheck^0xFFFF));
41540 +}
41541 +
41542 +/*
41543 + * Determine effective MSS.
41544 + *
41545 + * Note that we assume that there is always an MSS option for our own
41546 + * SYN segments, which is mentioned in tcp_syn_build_options(), kernel 2.2.x.
41547 + * This could change, and we should probably parse TCP options instead.
41548 + *
41549 + */
41550 +DEBUG_NO_STATIC u_int8_t
41551 +ipsec_adjust_mss(struct sk_buff *skb, struct tcphdr *tcph, u_int16_t mtu)
41552 +{
41553 + u_int16_t oldmss, newmss;
41554 + u_int32_t *mssp;
41555 + struct sock *sk = skb->sk;
41556 +
41557 + newmss = tcp_sync_mss(sk, mtu);
41558 + printk(KERN_INFO "klips: setting mss to %u\n", newmss);
41559 + mssp = (u_int32_t *)tcph + sizeof(struct tcphdr) / sizeof(u_int32_t);
41560 + oldmss = ntohl(*mssp) & 0x0000FFFF;
41561 + *mssp = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | newmss);
41562 + tcph->check = ipsec_fast_csum(htons(~oldmss),
41563 + htons(newmss), tcph->check);
41564 + return 1;
41565 +}
41566 +#endif /* MSS_HACK */
41567 +
41568 +/*
41569 + * Sanity checks
41570 + */
41571 +enum ipsec_xmit_value
41572 +ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs)
41573 +{
41574 +
41575 + if (ixs->dev == NULL) {
41576 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41577 + "klips_error:ipsec_xmit_sanity_check_dev: "
41578 + "No device associated with skb!\n" );
41579 + return IPSEC_XMIT_NODEV;
41580 + }
41581 +
41582 + ixs->prv = ixs->dev->priv;
41583 + if (ixs->prv == NULL) {
41584 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41585 + "klips_error:ipsec_xmit_sanity_check_dev: "
41586 + "Device has no private structure!\n" );
41587 + return IPSEC_XMIT_NOPRIVDEV;
41588 + }
41589 +
41590 + ixs->physdev = ixs->prv->dev;
41591 + if (ixs->physdev == NULL) {
41592 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41593 + "klips_error:ipsec_xmit_sanity_check_dev: "
41594 + "Device is not attached to physical device!\n" );
41595 + return IPSEC_XMIT_NOPHYSDEV;
41596 + }
41597 +
41598 + ixs->physmtu = ixs->physdev->mtu;
41599 + ixs->cur_mtu = ixs->physdev->mtu;
41600 + ixs->stats = (struct net_device_stats *) &(ixs->prv->mystats);
41601 +
41602 + return IPSEC_XMIT_OK;
41603 +}
41604 +
41605 +enum ipsec_xmit_value
41606 +ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs)
41607 +{
41608 + /*
41609 + * Return if there is nothing to do. (Does this ever happen?) XXX
41610 + */
41611 + if (ixs->skb == NULL) {
41612 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41613 + "klips_error:ipsec_xmit_sanity_check_skb: "
41614 + "Nothing to do!\n" );
41615 + return IPSEC_XMIT_NOSKB;
41616 + }
41617 +
41618 + /* if skb was cloned (most likely due to a packet sniffer such as
41619 + tcpdump being momentarily attached to the interface), make
41620 + a copy of our own to modify */
41621 + if(skb_cloned(ixs->skb)) {
41622 + if
41623 +#ifdef SKB_COW_NEW
41624 + (skb_cow(ixs->skb, skb_headroom(ixs->skb)) != 0)
41625 +#else /* SKB_COW_NEW */
41626 + ((ixs->skb = skb_cow(ixs->skb, skb_headroom(ixs->skb))) == NULL)
41627 +#endif /* SKB_COW_NEW */
41628 + {
41629 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
41630 + "klips_error:ipsec_xmit_sanity_check_skb: "
41631 + "skb_cow failed to allocate buffer, dropping.\n" );
41632 + ixs->stats->tx_dropped++;
41633 + return IPSEC_XMIT_ERRSKBALLOC;
41634 + }
41635 + }
41636 +
41637 + ixs->iph = ixs->skb->nh.iph;
41638 +
41639 + /* sanity check for IP version as we can't handle IPv6 right now */
41640 + if (ixs->iph->version != 4) {
41641 + KLIPS_PRINT(debug_tunnel,
41642 + "klips_debug:ipsec_xmit_sanity_check_skb: "
41643 + "found IP Version %d but cannot process other IP versions than v4.\n",
41644 + ixs->iph->version); /* XXX */
41645 + ixs->stats->tx_dropped++;
41646 + return IPSEC_XMIT_NOIPV6;
41647 + }
41648 +
41649 +#if IPSEC_DISALLOW_IPOPTIONS
41650 + if ((ixs->iph->ihl << 2) != sizeof (struct iphdr)) {
41651 + KLIPS_PRINT(debug_tunnel,
41652 + "klips_debug:ipsec_xmit_sanity_check_skb: "
41653 + "cannot process IP header options yet. May be mal-formed packet.\n"); /* XXX */
41654 + ixs->stats->tx_dropped++;
41655 + return IPSEC_XMIT_NOIPOPTIONS;
41656 + }
41657 +#endif /* IPSEC_DISALLOW_IPOPTIONS */
41658 +
41659 +#ifndef NET_21
41660 + if (ixs->iph->ttl <= 0) {
41661 + /* Tell the sender its packet died... */
41662 + ICMP_SEND(ixs->skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, ixs->physdev);
41663 +
41664 + KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_xmit_sanity_check_skb: "
41665 + "TTL=0, too many hops!\n");
41666 + ixs->stats->tx_dropped++;
41667 + return IPSEC_XMIT_TTLEXPIRED;
41668 + }
41669 +#endif /* !NET_21 */
41670 +
41671 + return IPSEC_XMIT_OK;
41672 +}
41673 +
41674 +enum ipsec_xmit_value
41675 +ipsec_xmit_encap_once(struct ipsec_xmit_state *ixs)
41676 +{
41677 +#ifdef CONFIG_KLIPS_ESP
41678 + struct esphdr *espp;
41679 + unsigned char *idat, *pad;
41680 + int authlen = 0, padlen = 0, i;
41681 +#endif /* !CONFIG_KLIPS_ESP */
41682 +#ifdef CONFIG_KLIPS_AH
41683 + struct iphdr ipo;
41684 + struct ahhdr *ahp;
41685 +#endif /* CONFIG_KLIPS_AH */
41686 +#if defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMAC_SHA1)
41687 + union {
41688 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
41689 + MD5_CTX md5;
41690 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
41691 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
41692 + SHA1_CTX sha1;
41693 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
41694 + } tctx;
41695 + __u8 hash[AH_AMAX];
41696 +#endif /* defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMACn_SHA1) */
41697 + int headroom = 0, tailroom = 0, ilen = 0, len = 0;
41698 + unsigned char *dat;
41699 + int blocksize = 8; /* XXX: should be inside ixs --jjo */
41700 + struct ipsec_alg_enc *ixt_e = NULL;
41701 + struct ipsec_alg_auth *ixt_a = NULL;
41702 +
41703 + ixs->iphlen = ixs->iph->ihl << 2;
41704 + ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
41705 + ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, SATOT_BUF);
41706 + KLIPS_PRINT(debug_tunnel & DB_TN_OXFS,
41707 + "klips_debug:ipsec_xmit_encap_once: "
41708 + "calling output for <%s%s%s>, SA:%s\n",
41709 + IPS_XFORM_NAME(ixs->ipsp),
41710 + ixs->sa_len ? ixs->sa_txt : " (error)");
41711 +
41712 + switch(ixs->ipsp->ips_said.proto) {
41713 +#ifdef CONFIG_KLIPS_AH
41714 + case IPPROTO_AH:
41715 + headroom += sizeof(struct ahhdr);
41716 + break;
41717 +#endif /* CONFIG_KLIPS_AH */
41718 +
41719 +#ifdef CONFIG_KLIPS_ESP
41720 + case IPPROTO_ESP:
41721 + ixt_e=ixs->ipsp->ips_alg_enc;
41722 + if (ixt_e) {
41723 + blocksize = ixt_e->ixt_common.ixt_blocksize;
41724 + headroom += ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
41725 + } else {
41726 + ixs->stats->tx_errors++;
41727 + return IPSEC_XMIT_ESP_BADALG;
41728 + }
41729 +
41730 + ixt_a=ixs->ipsp->ips_alg_auth;
41731 + if (ixt_a) {
41732 + tailroom += AHHMAC_HASHLEN;
41733 + } else
41734 + switch(ixs->ipsp->ips_authalg) {
41735 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
41736 + case AH_MD5:
41737 + authlen = AHHMAC_HASHLEN;
41738 + break;
41739 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
41740 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
41741 + case AH_SHA:
41742 + authlen = AHHMAC_HASHLEN;
41743 + break;
41744 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
41745 + case AH_NONE:
41746 + break;
41747 + default:
41748 + ixs->stats->tx_errors++;
41749 + return IPSEC_XMIT_ESP_BADALG;
41750 + }
41751 + tailroom += blocksize != 1 ?
41752 + ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 :
41753 + ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
41754 + tailroom += authlen;
41755 + break;
41756 +#endif /* CONFIG_KLIPS_ESP */
41757 +
41758 +#ifdef CONFIG_KLIPS_IPIP
41759 + case IPPROTO_IPIP:
41760 + headroom += sizeof(struct iphdr);
41761 + ixs->iphlen = sizeof(struct iphdr);
41762 + break;
41763 +#endif /* !CONFIG_KLIPS_IPIP */
41764 +
41765 +#ifdef CONFIG_KLIPS_IPCOMP
41766 + case IPPROTO_COMP:
41767 + break;
41768 +#endif /* CONFIG_KLIPS_IPCOMP */
41769 +
41770 + default:
41771 + ixs->stats->tx_errors++;
41772 + return IPSEC_XMIT_BADPROTO;
41773 + }
41774 +
41775 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
41776 + "klips_debug:ipsec_xmit_encap_once: "
41777 + "pushing %d bytes, putting %d, proto %d.\n",
41778 + headroom, tailroom, ixs->ipsp->ips_said.proto);
41779 + if(skb_headroom(ixs->skb) < headroom) {
41780 + printk(KERN_WARNING
41781 + "klips_error:ipsec_xmit_encap_once: "
41782 + "tried to skb_push headroom=%d, %d available. This should never happen, please report.\n",
41783 + headroom, skb_headroom(ixs->skb));
41784 + ixs->stats->tx_errors++;
41785 + return IPSEC_XMIT_ESP_PUSHPULLERR;
41786 + }
41787 +
41788 + dat = skb_push(ixs->skb, headroom);
41789 + ilen = ixs->skb->len - tailroom;
41790 + if(skb_tailroom(ixs->skb) < tailroom) {
41791 + printk(KERN_WARNING
41792 + "klips_error:ipsec_xmit_encap_once: "
41793 + "tried to skb_put %d, %d available. This should never happen, please report.\n",
41794 + tailroom, skb_tailroom(ixs->skb));
41795 + ixs->stats->tx_errors++;
41796 + return IPSEC_XMIT_ESP_PUSHPULLERR;
41797 + }
41798 + skb_put(ixs->skb, tailroom);
41799 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
41800 + "klips_debug:ipsec_xmit_encap_once: "
41801 + "head,tailroom: %d,%d before xform.\n",
41802 + skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
41803 + len = ixs->skb->len;
41804 + if(len > 0xfff0) {
41805 + printk(KERN_WARNING "klips_error:ipsec_xmit_encap_once: "
41806 + "tot_len (%d) > 65520. This should never happen, please report.\n",
41807 + len);
41808 + ixs->stats->tx_errors++;
41809 + return IPSEC_XMIT_BADLEN;
41810 + }
41811 + memmove((void *)dat, (void *)(dat + headroom), ixs->iphlen);
41812 + ixs->iph = (struct iphdr *)dat;
41813 + ixs->iph->tot_len = htons(ixs->skb->len);
41814 +
41815 + switch(ixs->ipsp->ips_said.proto) {
41816 +#ifdef CONFIG_KLIPS_ESP
41817 + case IPPROTO_ESP:
41818 + espp = (struct esphdr *)(dat + ixs->iphlen);
41819 + espp->esp_spi = ixs->ipsp->ips_said.spi;
41820 + espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
41821 +
41822 + if (!ixt_e) {
41823 + ixs->stats->tx_errors++;
41824 + return IPSEC_XMIT_ESP_BADALG;
41825 + }
41826 +
41827 + idat = dat + ixs->iphlen + headroom;
41828 + ilen = len - (ixs->iphlen + headroom + authlen);
41829 +
41830 + /* Self-describing padding */
41831 + pad = &dat[len - tailroom];
41832 + padlen = tailroom - 2 - authlen;
41833 + for (i = 0; i < padlen; i++) {
41834 + pad[i] = i + 1;
41835 + }
41836 + dat[len - authlen - 2] = padlen;
41837 +
41838 + dat[len - authlen - 1] = ixs->iph->protocol;
41839 + ixs->iph->protocol = IPPROTO_ESP;
41840 +
41841 + if(debug_tunnel & DB_TN_ENCAP) {
41842 + dmp("pre-encrypt", dat, len);
41843 + }
41844 +
41845 + /*
41846 + * Do all operations here:
41847 + * copy IV->ESP, encrypt, update ips IV
41848 + *
41849 + */
41850 + {
41851 + int ret;
41852 + memcpy(espp->esp_iv,
41853 + ixs->ipsp->ips_iv,
41854 + ixs->ipsp->ips_iv_size);
41855 + ret=ipsec_alg_esp_encrypt(ixs->ipsp,
41856 + idat, ilen, espp->esp_iv,
41857 + IPSEC_ALG_ENCRYPT);
41858 +
41859 + prng_bytes(&ipsec_prng,
41860 + (char *)ixs->ipsp->ips_iv,
41861 + ixs->ipsp->ips_iv_size);
41862 + }
41863 +
41864 + if (ixt_a) {
41865 + ipsec_alg_sa_esp_hash(ixs->ipsp,
41866 + (caddr_t)espp, len - ixs->iphlen - authlen,
41867 + &(dat[len - authlen]), authlen);
41868 +
41869 + } else
41870 + switch(ixs->ipsp->ips_authalg) {
41871 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
41872 + case AH_MD5:
41873 + dmp("espp", (char*)espp, len - ixs->iphlen - authlen);
41874 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
41875 + dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
41876 + osMD5Update(&tctx.md5, (caddr_t)espp, len - ixs->iphlen - authlen);
41877 + dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
41878 + osMD5Final(hash, &tctx.md5);
41879 + dmp("ictx hash", (char*)&hash, sizeof(hash));
41880 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
41881 + dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
41882 + osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
41883 + dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
41884 + osMD5Final(hash, &tctx.md5);
41885 + dmp("octx hash", (char*)&hash, sizeof(hash));
41886 + memcpy(&(dat[len - authlen]), hash, authlen);
41887 +
41888 + /* paranoid */
41889 + memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
41890 + memset((caddr_t)hash, 0, sizeof(*hash));
41891 + break;
41892 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
41893 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
41894 + case AH_SHA:
41895 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
41896 + SHA1Update(&tctx.sha1, (caddr_t)espp, len - ixs->iphlen - authlen);
41897 + SHA1Final(hash, &tctx.sha1);
41898 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
41899 + SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
41900 + SHA1Final(hash, &tctx.sha1);
41901 + memcpy(&(dat[len - authlen]), hash, authlen);
41902 +
41903 + /* paranoid */
41904 + memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
41905 + memset((caddr_t)hash, 0, sizeof(*hash));
41906 + break;
41907 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
41908 + case AH_NONE:
41909 + break;
41910 + default:
41911 + ixs->stats->tx_errors++;
41912 + return IPSEC_XMIT_AH_BADALG;
41913 + }
41914 +#ifdef NET_21
41915 + ixs->skb->h.raw = (unsigned char*)espp;
41916 +#endif /* NET_21 */
41917 + break;
41918 +#endif /* !CONFIG_KLIPS_ESP */
41919 +#ifdef CONFIG_KLIPS_AH
41920 + case IPPROTO_AH:
41921 + ahp = (struct ahhdr *)(dat + ixs->iphlen);
41922 + ahp->ah_spi = ixs->ipsp->ips_said.spi;
41923 + ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
41924 + ahp->ah_rv = 0;
41925 + ahp->ah_nh = ixs->iph->protocol;
41926 + ahp->ah_hl = (headroom >> 2) - sizeof(__u64)/sizeof(__u32);
41927 + ixs->iph->protocol = IPPROTO_AH;
41928 + dmp("ahp", (char*)ahp, sizeof(*ahp));
41929 +
41930 + ipo = *ixs->iph;
41931 + ipo.tos = 0;
41932 + ipo.frag_off = 0;
41933 + ipo.ttl = 0;
41934 + ipo.check = 0;
41935 + dmp("ipo", (char*)&ipo, sizeof(ipo));
41936 +
41937 + switch(ixs->ipsp->ips_authalg) {
41938 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
41939 + case AH_MD5:
41940 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
41941 + dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
41942 + osMD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
41943 + dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
41944 + osMD5Update(&tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
41945 + dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
41946 + osMD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
41947 + dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
41948 + osMD5Update(&tctx.md5, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom);
41949 + dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
41950 + osMD5Final(hash, &tctx.md5);
41951 + dmp("ictx hash", (char*)&hash, sizeof(hash));
41952 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
41953 + dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
41954 + osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
41955 + dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
41956 + osMD5Final(hash, &tctx.md5);
41957 + dmp("octx hash", (char*)&hash, sizeof(hash));
41958 +
41959 + memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
41960 +
41961 + /* paranoid */
41962 + memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
41963 + memset((caddr_t)hash, 0, sizeof(*hash));
41964 + break;
41965 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
41966 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
41967 + case AH_SHA:
41968 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
41969 + SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
41970 + SHA1Update(&tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
41971 + SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
41972 + SHA1Update(&tctx.sha1, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom);
41973 + SHA1Final(hash, &tctx.sha1);
41974 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
41975 + SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
41976 + SHA1Final(hash, &tctx.sha1);
41977 +
41978 + memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
41979 +
41980 + /* paranoid */
41981 + memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
41982 + memset((caddr_t)hash, 0, sizeof(*hash));
41983 + break;
41984 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
41985 + default:
41986 + ixs->stats->tx_errors++;
41987 + return IPSEC_XMIT_AH_BADALG;
41988 + }
41989 +#ifdef NET_21
41990 + ixs->skb->h.raw = (unsigned char*)ahp;
41991 +#endif /* NET_21 */
41992 + break;
41993 +#endif /* CONFIG_KLIPS_AH */
41994 +#ifdef CONFIG_KLIPS_IPIP
41995 + case IPPROTO_IPIP:
41996 + ixs->iph->version = 4;
41997 + switch(sysctl_ipsec_tos) {
41998 + case 0:
41999 +#ifdef NET_21
42000 + ixs->iph->tos = ixs->skb->nh.iph->tos;
42001 +#else /* NET_21 */
42002 + ixs->iph->tos = ixs->skb->ip_hdr->tos;
42003 +#endif /* NET_21 */
42004 + break;
42005 + case 1:
42006 + ixs->iph->tos = 0;
42007 + break;
42008 + default:
42009 + break;
42010 + }
42011 + ixs->iph->ttl = SYSCTL_IPSEC_DEFAULT_TTL;
42012 + ixs->iph->frag_off = 0;
42013 + ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
42014 + ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
42015 + ixs->iph->protocol = IPPROTO_IPIP;
42016 + ixs->iph->ihl = sizeof(struct iphdr) >> 2;
42017 +
42018 + KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
42019 +
42020 + ixs->newdst = (__u32)ixs->iph->daddr;
42021 + ixs->newsrc = (__u32)ixs->iph->saddr;
42022 +
42023 +#ifdef NET_21
42024 + ixs->skb->h.ipiph = ixs->skb->nh.iph;
42025 +#endif /* NET_21 */
42026 + break;
42027 +#endif /* !CONFIG_KLIPS_IPIP */
42028 +#ifdef CONFIG_KLIPS_IPCOMP
42029 + case IPPROTO_COMP:
42030 + {
42031 + unsigned int flags = 0;
42032 +#ifdef CONFIG_KLIPS_DEBUG
42033 + unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
42034 +#endif /* CONFIG_KLIPS_DEBUG */
42035 + ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
42036 +
42037 + ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
42038 +
42039 +#ifdef NET_21
42040 + ixs->iph = ixs->skb->nh.iph;
42041 +#else /* NET_21 */
42042 + ixs->iph = ixs->skb->ip_hdr;
42043 +#endif /* NET_21 */
42044 +
42045 + ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
42046 +
42047 +#ifdef CONFIG_KLIPS_DEBUG
42048 + if (debug_tunnel & DB_TN_CROUT)
42049 + {
42050 + if (old_tot_len > ntohs(ixs->iph->tot_len))
42051 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42052 + "klips_debug:ipsec_xmit_encap_once: "
42053 + "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
42054 + old_tot_len, ntohs(ixs->iph->tot_len),
42055 + ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
42056 + ntohl(ixs->ipsp->ips_said.spi),
42057 + (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
42058 + else
42059 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42060 + "klips_debug:ipsec_xmit_encap_once: "
42061 + "packet did not compress (flags = %d).\n",
42062 + flags);
42063 + }
42064 +#endif /* CONFIG_KLIPS_DEBUG */
42065 + }
42066 + break;
42067 +#endif /* CONFIG_KLIPS_IPCOMP */
42068 + default:
42069 + ixs->stats->tx_errors++;
42070 + return IPSEC_XMIT_BADPROTO;
42071 + }
42072 +
42073 +#ifdef NET_21
42074 + ixs->skb->nh.raw = ixs->skb->data;
42075 +#else /* NET_21 */
42076 + ixs->skb->ip_hdr = ixs->skb->h.iph = (struct iphdr *) ixs->skb->data;
42077 +#endif /* NET_21 */
42078 + ixs->iph->check = 0;
42079 + ixs->iph->check = ip_fast_csum((unsigned char *)ixs->iph, ixs->iph->ihl);
42080 +
42081 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42082 + "klips_debug:ipsec_xmit_encap_once: "
42083 + "after <%s%s%s>, SA:%s:\n",
42084 + IPS_XFORM_NAME(ixs->ipsp),
42085 + ixs->sa_len ? ixs->sa_txt : " (error)");
42086 + KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
42087 +
42088 + ixs->ipsp->ips_life.ipl_bytes.ipl_count += len;
42089 + ixs->ipsp->ips_life.ipl_bytes.ipl_last = len;
42090 +
42091 + if(!ixs->ipsp->ips_life.ipl_usetime.ipl_count) {
42092 + ixs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
42093 + }
42094 + ixs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
42095 + ixs->ipsp->ips_life.ipl_packets.ipl_count++;
42096 +
42097 + ixs->ipsp = ixs->ipsp->ips_onext;
42098 +
42099 + return IPSEC_XMIT_OK;
42100 +}
42101 +
42102 +/*
42103 + * If the IP packet (iph) is a carrying TCP/UDP, then set the encaps
42104 + * source and destination ports to those from the TCP/UDP header.
42105 + */
42106 +void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er)
42107 +{
42108 + struct udphdr *udp;
42109 +
42110 + switch (iph->protocol) {
42111 + case IPPROTO_UDP:
42112 + case IPPROTO_TCP:
42113 + /*
42114 + * The ports are at the same offsets in a TCP and UDP
42115 + * header so hack it ...
42116 + */
42117 + udp = (struct udphdr*)(((char*)iph)+(iph->ihl<<2));
42118 + er->sen_sport = udp->source;
42119 + er->sen_dport = udp->dest;
42120 + break;
42121 + default:
42122 + er->sen_sport = 0;
42123 + er->sen_dport = 0;
42124 + break;
42125 + }
42126 +}
42127 +
42128 +/*
42129 + * A TRAP eroute is installed and we want to replace it with a HOLD
42130 + * eroute.
42131 + */
42132 +static int create_hold_eroute(struct eroute *origtrap,
42133 + struct sk_buff * skb, struct iphdr * iph,
42134 + uint32_t eroute_pid)
42135 +{
42136 + struct eroute hold_eroute;
42137 + ip_said hold_said;
42138 + struct sk_buff *first, *last;
42139 + int error;
42140 +
42141 + first = last = NULL;
42142 + memset((caddr_t)&hold_eroute, 0, sizeof(hold_eroute));
42143 + memset((caddr_t)&hold_said, 0, sizeof(hold_said));
42144 +
42145 + hold_said.proto = IPPROTO_INT;
42146 + hold_said.spi = htonl(SPI_HOLD);
42147 + hold_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
42148 +
42149 + hold_eroute.er_eaddr.sen_len = sizeof(struct sockaddr_encap);
42150 + hold_eroute.er_emask.sen_len = sizeof(struct sockaddr_encap);
42151 + hold_eroute.er_eaddr.sen_family = AF_ENCAP;
42152 + hold_eroute.er_emask.sen_family = AF_ENCAP;
42153 + hold_eroute.er_eaddr.sen_type = SENT_IP4;
42154 + hold_eroute.er_emask.sen_type = 255;
42155 +
42156 + hold_eroute.er_eaddr.sen_ip_src.s_addr = iph->saddr;
42157 + hold_eroute.er_eaddr.sen_ip_dst.s_addr = iph->daddr;
42158 + hold_eroute.er_emask.sen_ip_src.s_addr = INADDR_BROADCAST;
42159 + hold_eroute.er_emask.sen_ip_dst.s_addr = INADDR_BROADCAST;
42160 + hold_eroute.er_emask.sen_sport = 0;
42161 + hold_eroute.er_emask.sen_dport = 0;
42162 + hold_eroute.er_pid = eroute_pid;
42163 + hold_eroute.er_count = 0;
42164 + hold_eroute.er_lasttime = jiffies/HZ;
42165 +
42166 + /*
42167 + * if it wasn't captured by a wildcard, then don't record it as
42168 + * a wildcard.
42169 + */
42170 + if(origtrap->er_eaddr.sen_proto != 0) {
42171 + hold_eroute.er_eaddr.sen_proto = iph->protocol;
42172 +
42173 + if((iph->protocol == IPPROTO_TCP ||
42174 + iph->protocol == IPPROTO_UDP) &&
42175 + (origtrap->er_eaddr.sen_sport != 0 ||
42176 + origtrap->er_eaddr.sen_dport != 0)) {
42177 +
42178 + if(origtrap->er_eaddr.sen_sport != 0)
42179 + hold_eroute.er_emask.sen_sport = ~0;
42180 +
42181 + if(origtrap->er_eaddr.sen_dport != 0)
42182 + hold_eroute.er_emask.sen_dport = ~0;
42183 +
42184 + ipsec_extract_ports(iph, &hold_eroute.er_eaddr);
42185 + }
42186 + }
42187 +
42188 +#ifdef CONFIG_KLIPS_DEBUG
42189 + if (debug_pfkey) {
42190 + char buf1[64], buf2[64];
42191 + subnettoa(hold_eroute.er_eaddr.sen_ip_src,
42192 + hold_eroute.er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
42193 + subnettoa(hold_eroute.er_eaddr.sen_ip_dst,
42194 + hold_eroute.er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
42195 + KLIPS_PRINT(debug_pfkey,
42196 + "klips_debug:ipsec_tunnel_start_xmit: "
42197 + "calling breakeroute and makeroute for %s:%d->%s:%d %d HOLD eroute.\n",
42198 + buf1, ntohs(hold_eroute.er_eaddr.sen_sport),
42199 + buf2, ntohs(hold_eroute.er_eaddr.sen_dport),
42200 + hold_eroute.er_eaddr.sen_proto);
42201 + }
42202 +#endif /* CONFIG_KLIPS_DEBUG */
42203 +
42204 + if (ipsec_breakroute(&(hold_eroute.er_eaddr), &(hold_eroute.er_emask),
42205 + &first, &last)) {
42206 + KLIPS_PRINT(debug_pfkey,
42207 + "klips_debug:ipsec_tunnel_start_xmit: "
42208 + "HOLD breakeroute found nothing.\n");
42209 + } else {
42210 + KLIPS_PRINT(debug_pfkey,
42211 + "klips_debug:ipsec_tunnel_start_xmit: "
42212 + "HOLD breakroute deleted %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u %u\n",
42213 + NIPQUAD(hold_eroute.er_eaddr.sen_ip_src),
42214 + ntohs(hold_eroute.er_eaddr.sen_sport),
42215 + NIPQUAD(hold_eroute.er_eaddr.sen_ip_dst),
42216 + ntohs(hold_eroute.er_eaddr.sen_dport),
42217 + hold_eroute.er_eaddr.sen_proto);
42218 + }
42219 + if (first != NULL)
42220 + kfree_skb(first);
42221 + if (last != NULL)
42222 + kfree_skb(last);
42223 +
42224 + error = ipsec_makeroute(&(hold_eroute.er_eaddr),
42225 + &(hold_eroute.er_emask),
42226 + hold_said, eroute_pid, skb, NULL, NULL);
42227 + if (error) {
42228 + KLIPS_PRINT(debug_pfkey,
42229 + "klips_debug:ipsec_tunnel_start_xmit: "
42230 + "HOLD makeroute returned %d, failed.\n", error);
42231 + } else {
42232 + KLIPS_PRINT(debug_pfkey,
42233 + "klips_debug:ipsec_tunnel_start_xmit: "
42234 + "HOLD makeroute call successful.\n");
42235 + }
42236 + return (error == 0);
42237 +}
42238 +
42239 +/*
42240 + * upon entry to this function, ixs->skb should be setup
42241 + * as follows:
42242 + *
42243 + * data = beginning of IP packet <- differs from ipsec_rcv().
42244 + * nh.raw = beginning of IP packet.
42245 + * h.raw = data after the IP packet.
42246 + *
42247 + */
42248 +enum ipsec_xmit_value
42249 +ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs)
42250 +{
42251 + struct ipsec_alg_enc *ixt_e = NULL;
42252 + struct ipsec_alg_auth *ixt_a = NULL;
42253 + int blocksize = 8;
42254 + enum ipsec_xmit_value bundle_stat = IPSEC_XMIT_OK;
42255 + struct ipsec_sa *saved_ipsp;
42256 +
42257 + ixs->newdst = ixs->orgdst = ixs->iph->daddr;
42258 + ixs->newsrc = ixs->orgsrc = ixs->iph->saddr;
42259 + ixs->orgedst = ixs->outgoing_said.dst.u.v4.sin_addr.s_addr;
42260 + ixs->iphlen = ixs->iph->ihl << 2;
42261 + ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
42262 + ixs->max_headroom = ixs->max_tailroom = 0;
42263 +
42264 + if (ixs->outgoing_said.proto == IPPROTO_INT) {
42265 + switch (ntohl(ixs->outgoing_said.spi)) {
42266 + case SPI_DROP:
42267 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42268 + "klips_debug:ipsec_xmit_encap_bundle: "
42269 + "shunt SA of DROP or no eroute: dropping.\n");
42270 + ixs->stats->tx_dropped++;
42271 + break;
42272 +
42273 + case SPI_REJECT:
42274 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42275 + "klips_debug:ipsec_xmit_encap_bundle: "
42276 + "shunt SA of REJECT: notifying and dropping.\n");
42277 + ICMP_SEND(ixs->skb,
42278 + ICMP_DEST_UNREACH,
42279 + ICMP_PKT_FILTERED,
42280 + 0,
42281 + ixs->physdev);
42282 + ixs->stats->tx_dropped++;
42283 + break;
42284 +
42285 + case SPI_PASS:
42286 +#ifdef NET_21
42287 + ixs->pass = 1;
42288 +#endif /* NET_21 */
42289 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42290 + "klips_debug:ipsec_xmit_encap_bundle: "
42291 + "PASS: calling dev_queue_xmit\n");
42292 + return IPSEC_XMIT_PASS;
42293 + goto cleanup;
42294 +
42295 + case SPI_HOLD:
42296 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42297 + "klips_debug:ipsec_xmit_encap_bundle: "
42298 + "shunt SA of HOLD: this does not make sense here, dropping.\n");
42299 + ixs->stats->tx_dropped++;
42300 + break;
42301 +
42302 + case SPI_TRAP:
42303 + case SPI_TRAPSUBNET:
42304 + {
42305 + struct sockaddr_in src, dst;
42306 +#ifdef CONFIG_KLIPS_DEBUG
42307 + char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF];
42308 +#endif /* CONFIG_KLIPS_DEBUG */
42309 +
42310 + /* Signal all listening KMds with a PF_KEY ACQUIRE */
42311 +
42312 + memset(&src, 0, sizeof(src));
42313 + memset(&dst, 0, sizeof(dst));
42314 + src.sin_family = AF_INET;
42315 + dst.sin_family = AF_INET;
42316 + src.sin_addr.s_addr = ixs->iph->saddr;
42317 + dst.sin_addr.s_addr = ixs->iph->daddr;
42318 +
42319 + ixs->ips.ips_transport_protocol = 0;
42320 + src.sin_port = 0;
42321 + dst.sin_port = 0;
42322 +
42323 + if(ixs->eroute->er_eaddr.sen_proto != 0) {
42324 + ixs->ips.ips_transport_protocol = ixs->iph->protocol;
42325 +
42326 + if(ixs->eroute->er_eaddr.sen_sport != 0) {
42327 + src.sin_port =
42328 + (ixs->iph->protocol == IPPROTO_UDP
42329 + ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->source
42330 + : (ixs->iph->protocol == IPPROTO_TCP
42331 + ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->source
42332 + : 0));
42333 + }
42334 + if(ixs->eroute->er_eaddr.sen_dport != 0) {
42335 + dst.sin_port =
42336 + (ixs->iph->protocol == IPPROTO_UDP
42337 + ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->dest
42338 + : (ixs->iph->protocol == IPPROTO_TCP
42339 + ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->dest
42340 + : 0));
42341 + }
42342 + }
42343 +
42344 + ixs->ips.ips_addr_s = (struct sockaddr*)(&src);
42345 + ixs->ips.ips_addr_d = (struct sockaddr*)(&dst);
42346 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42347 + "klips_debug:ipsec_xmit_encap_bundle: "
42348 + "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n",
42349 + addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_addr, 0, bufsrc, sizeof(bufsrc)) <= ADDRTOA_BUF ? bufsrc : "BAD_ADDR",
42350 + ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_port),
42351 + addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_addr, 0, bufdst, sizeof(bufdst)) <= ADDRTOA_BUF ? bufdst : "BAD_ADDR",
42352 + ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_port),
42353 + ixs->ips.ips_said.proto);
42354 +
42355 + /* increment count of total traps needed */
42356 + ipsec_xmit_trap_count++;
42357 +
42358 + if (pfkey_acquire(&ixs->ips) == 0) {
42359 +
42360 + /* note that we succeeded */
42361 + ipsec_xmit_trap_sendcount++;
42362 +
42363 + if (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)) {
42364 + /*
42365 + * The spinlock is to prevent any other
42366 + * process from accessing or deleting
42367 + * the eroute while we are using and
42368 + * updating it.
42369 + */
42370 + spin_lock(&eroute_lock);
42371 + ixs->eroute = ipsec_findroute(&ixs->matcher);
42372 + if(ixs->eroute) {
42373 + ixs->eroute->er_said.spi = htonl(SPI_HOLD);
42374 + ixs->eroute->er_first = ixs->skb;
42375 + ixs->skb = NULL;
42376 + }
42377 + spin_unlock(&eroute_lock);
42378 + } else if (create_hold_eroute(ixs->eroute,
42379 + ixs->skb,
42380 + ixs->iph,
42381 + ixs->eroute_pid)) {
42382 + ixs->skb = NULL;
42383 + }
42384 + /* whether or not the above succeeded, we continue */
42385 +
42386 + }
42387 + ixs->stats->tx_dropped++;
42388 + }
42389 + default:
42390 + /* XXX what do we do with an unknown shunt spi? */
42391 + break;
42392 + } /* switch (ntohl(ixs->outgoing_said.spi)) */
42393 + return IPSEC_XMIT_STOLEN;
42394 + } /* if (ixs->outgoing_said.proto == IPPROTO_INT) */
42395 +
42396 + /*
42397 + The spinlock is to prevent any other process from
42398 + accessing or deleting the ipsec_sa hash table or any of the
42399 + ipsec_sa s while we are using and updating them.
42400 +
42401 + This is not optimal, but was relatively straightforward
42402 + at the time. A better way to do it has been planned for
42403 + more than a year, to lock the hash table and put reference
42404 + counts on each ipsec_sa instead. This is not likely to happen
42405 + in KLIPS1 unless a volunteer contributes it, but will be
42406 + designed into KLIPS2.
42407 + */
42408 + spin_lock(&tdb_lock);
42409 +
42410 + ixs->ipsp = ipsec_sa_getbyid(&ixs->outgoing_said);
42411 + ixs->sa_len = satot(&ixs->outgoing_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
42412 +
42413 + if (ixs->ipsp == NULL) {
42414 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42415 + "klips_debug:ipsec_xmit_encap_bundle: "
42416 + "no ipsec_sa for SA%s: outgoing packet with no SA, dropped.\n",
42417 + ixs->sa_len ? ixs->sa_txt : " (error)");
42418 + if(ixs->stats) {
42419 + ixs->stats->tx_dropped++;
42420 + }
42421 + bundle_stat = IPSEC_XMIT_SAIDNOTFOUND;
42422 + goto cleanup;
42423 + }
42424 +
42425 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42426 + "klips_debug:ipsec_xmit_encap_bundle: "
42427 + "found ipsec_sa -- SA:<%s%s%s> %s\n",
42428 + IPS_XFORM_NAME(ixs->ipsp),
42429 + ixs->sa_len ? ixs->sa_txt : " (error)");
42430 +
42431 + /*
42432 + * How much headroom do we need to be able to apply
42433 + * all the grouped transforms?
42434 + */
42435 + saved_ipsp = ixs->ipsp; /* save the head of the ipsec_sa chain */
42436 + while (ixs->ipsp) {
42437 + ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
42438 + if(ixs->sa_len == 0) {
42439 + strcpy(ixs->sa_txt, "(error)");
42440 + }
42441 +
42442 + /* If it is in larval state, drop the packet, we cannot process yet. */
42443 + if(ixs->ipsp->ips_state == K_SADB_SASTATE_LARVAL) {
42444 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42445 + "klips_debug:ipsec_xmit_encap_bundle: "
42446 + "ipsec_sa in larval state for SA:<%s%s%s> %s, cannot be used yet, dropping packet.\n",
42447 + IPS_XFORM_NAME(ixs->ipsp),
42448 + ixs->sa_len ? ixs->sa_txt : " (error)");
42449 + if(ixs->stats) {
42450 + ixs->stats->tx_errors++;
42451 + }
42452 + bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
42453 + goto cleanup;
42454 + }
42455 +
42456 + if(ixs->ipsp->ips_state == K_SADB_SASTATE_DEAD) {
42457 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42458 + "klips_debug:ipsec_xmit_encap_bundle: "
42459 + "ipsec_sa in dead state for SA:<%s%s%s> %s, can no longer be used, dropping packet.\n",
42460 + IPS_XFORM_NAME(ixs->ipsp),
42461 + ixs->sa_len ? ixs->sa_txt : " (error)");
42462 + ixs->stats->tx_errors++;
42463 + bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
42464 + goto cleanup;
42465 + }
42466 +
42467 + /* If the replay window counter == -1, expire SA, it will roll */
42468 + if(ixs->ipsp->ips_replaywin && ixs->ipsp->ips_replaywin_lastseq == -1) {
42469 + pfkey_expire(ixs->ipsp, 1);
42470 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42471 + "klips_debug:ipsec_xmit_encap_bundle: "
42472 + "replay window counter rolled for SA:<%s%s%s> %s, packet dropped, expiring SA.\n",
42473 + IPS_XFORM_NAME(ixs->ipsp),
42474 + ixs->sa_len ? ixs->sa_txt : " (error)");
42475 + ipsec_sa_rm(ixs->ipsp);
42476 + ixs->stats->tx_errors++;
42477 + bundle_stat = IPSEC_XMIT_REPLAYROLLED;
42478 + goto cleanup;
42479 + }
42480 +
42481 + /*
42482 + * if this is the first time we are using this SA, mark start time,
42483 + * and offset hard/soft counters by "now" for later checking.
42484 + */
42485 +#if 0
42486 + if(ixs->ipsp->ips_life.ipl_usetime.count == 0) {
42487 + ixs->ipsp->ips_life.ipl_usetime.count = jiffies;
42488 + ixs->ipsp->ips_life.ipl_usetime.hard += jiffies;
42489 + ixs->ipsp->ips_life.ipl_usetime.soft += jiffies;
42490 + }
42491 +#endif
42492 +
42493 +
42494 + if(ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_bytes, "bytes", ixs->sa_txt,
42495 + ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
42496 + ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_addtime, "addtime",ixs->sa_txt,
42497 + ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
42498 + ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_usetime, "usetime",ixs->sa_txt,
42499 + ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
42500 + ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_packets, "packets",ixs->sa_txt,
42501 + ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied) {
42502 +
42503 + ipsec_sa_rm(ixs->ipsp);
42504 + ixs->stats->tx_errors++;
42505 + bundle_stat = IPSEC_XMIT_LIFETIMEFAILED;
42506 + goto cleanup;
42507 + }
42508 +
42509 +
42510 + ixs->headroom = ixs->tailroom = 0;
42511 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42512 + "klips_debug:ipsec_xmit_encap_bundle: "
42513 + "calling room for <%s%s%s>, SA:%s\n",
42514 + IPS_XFORM_NAME(ixs->ipsp),
42515 + ixs->sa_len ? ixs->sa_txt : " (error)");
42516 + switch(ixs->ipsp->ips_said.proto) {
42517 +#ifdef CONFIG_KLIPS_AH
42518 + case IPPROTO_AH:
42519 + ixs->headroom += sizeof(struct ahhdr);
42520 + break;
42521 +#endif /* CONFIG_KLIPS_AH */
42522 +#ifdef CONFIG_KLIPS_ESP
42523 + case IPPROTO_ESP:
42524 + ixt_e=ixs->ipsp->ips_alg_enc;
42525 + if (ixt_e) {
42526 + blocksize = ixt_e->ixt_common.ixt_blocksize;
42527 + ixs->headroom += ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
42528 + }
42529 + else {
42530 + ixs->stats->tx_errors++;
42531 + bundle_stat = IPSEC_XMIT_ESP_BADALG;
42532 + goto cleanup;
42533 + }
42534 +
42535 + if ((ixt_a=ixs->ipsp->ips_alg_auth)) {
42536 + ixs->tailroom += AHHMAC_HASHLEN;
42537 + } else
42538 + switch(ixs->ipsp->ips_authalg) {
42539 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42540 + case AH_MD5:
42541 + ixs->tailroom += AHHMAC_HASHLEN;
42542 + break;
42543 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42544 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42545 + case AH_SHA:
42546 + ixs->tailroom += AHHMAC_HASHLEN;
42547 + break;
42548 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
42549 + case AH_NONE:
42550 + break;
42551 + default:
42552 + ixs->stats->tx_errors++;
42553 + bundle_stat = IPSEC_XMIT_AH_BADALG;
42554 + goto cleanup;
42555 + }
42556 + ixs->tailroom += blocksize != 1 ?
42557 + ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 :
42558 + ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
42559 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
42560 + if ((ixs->ipsp->ips_natt_type) && (!ixs->natt_type)) {
42561 + ixs->natt_type = ixs->ipsp->ips_natt_type;
42562 + ixs->natt_sport = ixs->ipsp->ips_natt_sport;
42563 + ixs->natt_dport = ixs->ipsp->ips_natt_dport;
42564 + switch (ixs->natt_type) {
42565 + case ESPINUDP_WITH_NON_IKE:
42566 + ixs->natt_head = sizeof(struct udphdr)+(2*sizeof(__u32));
42567 + break;
42568 +
42569 + case ESPINUDP_WITH_NON_ESP:
42570 + ixs->natt_head = sizeof(struct udphdr);
42571 + break;
42572 +
42573 + default:
42574 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT
42575 + , "klips_xmit: invalid nat-t type %d"
42576 + , ixs->natt_type);
42577 + bundle_stat = IPSEC_XMIT_ESPUDP_BADTYPE;
42578 + goto cleanup;
42579 +
42580 + break;
42581 + }
42582 + ixs->tailroom += ixs->natt_head;
42583 + }
42584 +#endif
42585 + break;
42586 +#endif /* !CONFIG_KLIPS_ESP */
42587 +#ifdef CONFIG_KLIPS_IPIP
42588 + case IPPROTO_IPIP:
42589 + ixs->headroom += sizeof(struct iphdr);
42590 + break;
42591 +#endif /* !CONFIG_KLIPS_IPIP */
42592 + case IPPROTO_COMP:
42593 +#ifdef CONFIG_KLIPS_IPCOMP
42594 + /*
42595 + We can't predict how much the packet will
42596 + shrink without doing the actual compression.
42597 + We could do it here, if we were the first
42598 + encapsulation in the chain. That might save
42599 + us a skb_copy_expand, since we might fit
42600 + into the existing skb then. However, this
42601 + would be a bit unclean (and this hack has
42602 + bit us once), so we better not do it. After
42603 + all, the skb_copy_expand is cheap in
42604 + comparison to the actual compression.
42605 + At least we know the packet will not grow.
42606 + */
42607 + break;
42608 +#endif /* CONFIG_KLIPS_IPCOMP */
42609 + default:
42610 + ixs->stats->tx_errors++;
42611 + bundle_stat = IPSEC_XMIT_BADPROTO;
42612 + goto cleanup;
42613 + }
42614 + ixs->ipsp = ixs->ipsp->ips_onext;
42615 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42616 + "klips_debug:ipsec_xmit_encap_bundle: "
42617 + "Required head,tailroom: %d,%d\n",
42618 + ixs->headroom, ixs->tailroom);
42619 + ixs->max_headroom += ixs->headroom;
42620 + ixs->max_tailroom += ixs->tailroom;
42621 + ixs->pyldsz += (ixs->headroom + ixs->tailroom);
42622 + }
42623 + ixs->ipsp = saved_ipsp; /* restore the head of the ipsec_sa chain */
42624 +
42625 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42626 + "klips_debug:ipsec_xmit_encap_bundle: "
42627 + "existing head,tailroom: %d,%d before applying xforms with head,tailroom: %d,%d .\n",
42628 + skb_headroom(ixs->skb), skb_tailroom(ixs->skb),
42629 + ixs->max_headroom, ixs->max_tailroom);
42630 +
42631 + ixs->tot_headroom += ixs->max_headroom;
42632 + ixs->tot_tailroom += ixs->max_tailroom;
42633 +
42634 + ixs->mtudiff = ixs->cur_mtu + ixs->tot_headroom + ixs->tot_tailroom - ixs->physmtu;
42635 +
42636 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42637 + "klips_debug:ipsec_xmit_encap_bundle: "
42638 + "mtu:%d physmtu:%d tothr:%d tottr:%d mtudiff:%d ippkttotlen:%d\n",
42639 + ixs->cur_mtu, ixs->physmtu,
42640 + ixs->tot_headroom, ixs->tot_tailroom, ixs->mtudiff, ntohs(ixs->iph->tot_len));
42641 + if(ixs->mtudiff > 0) {
42642 + int newmtu = ixs->physmtu - (ixs->tot_headroom + ((ixs->tot_tailroom + 2) & ~7) + 5);
42643 +
42644 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42645 + "klips_info:ipsec_xmit_encap_bundle: "
42646 + "dev %s mtu of %d decreased by %d to %d\n",
42647 + ixs->dev ? ixs->dev->name : "ifX",
42648 + ixs->cur_mtu,
42649 + ixs->cur_mtu - newmtu,
42650 + newmtu);
42651 + ixs->cur_mtu = newmtu;
42652 +
42653 + /* this would seem to adjust the MTU of the route as well */
42654 +#if 0
42655 + ixs->skb->dst->pmtu = ixs->prv->mtu; /* RGB */
42656 +#endif /* 0 */
42657 + }
42658 +
42659 + /*
42660 + If the sender is doing PMTU discovery, and the
42661 + packet doesn't fit within ixs->prv->mtu, notify him
42662 + (unless it was an ICMP packet, or it was not the
42663 + zero-offset packet) and send it anyways.
42664 +
42665 + Note: buggy firewall configuration may prevent the
42666 + ICMP packet from getting back.
42667 + */
42668 + if(sysctl_ipsec_icmp
42669 + && ixs->cur_mtu < ntohs(ixs->iph->tot_len)
42670 + && (ixs->iph->frag_off & __constant_htons(IP_DF)) ) {
42671 + int notify = ixs->iph->protocol != IPPROTO_ICMP
42672 + && (ixs->iph->frag_off & __constant_htons(IP_OFFSET)) == 0;
42673 +
42674 +#ifdef IPSEC_obey_DF
42675 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42676 + "klips_debug:ipsec_xmit_encap_bundle: "
42677 + "fragmentation needed and DF set; %sdropping packet\n",
42678 + notify ? "sending ICMP and " : "");
42679 + if (notify)
42680 + ICMP_SEND(ixs->skb,
42681 + ICMP_DEST_UNREACH,
42682 + ICMP_FRAG_NEEDED,
42683 + ixs->cur_mtu,
42684 + ixs->physdev);
42685 + ixs->stats->tx_errors++;
42686 + bundle_stat = IPSEC_XMIT_CANNOTFRAG;
42687 + goto cleanup;
42688 +#else /* IPSEC_obey_DF */
42689 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42690 + "klips_debug:ipsec_xmit_encap_bundle: "
42691 + "fragmentation needed and DF set; %spassing packet\n",
42692 + notify ? "sending ICMP and " : "");
42693 + if (notify)
42694 + ICMP_SEND(ixs->skb,
42695 + ICMP_DEST_UNREACH,
42696 + ICMP_FRAG_NEEDED,
42697 + ixs->cur_mtu,
42698 + ixs->physdev);
42699 +#endif /* IPSEC_obey_DF */
42700 + }
42701 +
42702 +#ifdef MSS_HACK
42703 + /*
42704 + * If this is a transport mode TCP packet with
42705 + * SYN set, determine an effective MSS based on
42706 + * AH/ESP overheads determined above.
42707 + */
42708 + if (ixs->iph->protocol == IPPROTO_TCP
42709 + && ixs->outgoing_said.proto != IPPROTO_IPIP) {
42710 + struct tcphdr *tcph = ixs->skb->h.th;
42711 + if (tcph->syn && !tcph->ack) {
42712 + if(!ipsec_adjust_mss(ixs->skb, tcph, ixs->cur_mtu)) {
42713 + printk(KERN_WARNING
42714 + "klips_warning:ipsec_xmit_encap_bundle: "
42715 + "ipsec_adjust_mss() failed\n");
42716 + ixs->stats->tx_errors++;
42717 + bundle_stat = IPSEC_XMIT_MSSERR;
42718 + goto cleanup;
42719 + }
42720 + }
42721 + }
42722 +#endif /* MSS_HACK */
42723 +
42724 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
42725 + if ((ixs->natt_type) && (ixs->outgoing_said.proto != IPPROTO_IPIP)) {
42726 + /**
42727 + * NAT-Traversal and Transport Mode:
42728 + * we need to correct TCP/UDP checksum
42729 + *
42730 + * If we've got NAT-OA, we can fix checksum without recalculation.
42731 + * If we don't we can zero udp checksum.
42732 + */
42733 + __u32 natt_oa = ixs->ipsp->ips_natt_oa ?
42734 + ((struct sockaddr_in*)(ixs->ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
42735 + __u16 pkt_len = ixs->skb->tail - (unsigned char *)ixs->iph;
42736 + __u16 data_len = pkt_len - (ixs->iph->ihl << 2);
42737 + switch (ixs->iph->protocol) {
42738 + case IPPROTO_TCP:
42739 + if (data_len >= sizeof(struct tcphdr)) {
42740 + struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);
42741 + if (natt_oa) {
42742 + __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };
42743 + KLIPS_PRINT(debug_tunnel,
42744 + "klips_debug:ipsec_tunnel_start_xmit: "
42745 + "NAT-T & TRANSPORT: "
42746 + "fix TCP checksum using NAT-OA\n");
42747 + tcp->check = csum_fold(
42748 + csum_partial((unsigned char *)buff, sizeof(buff),
42749 + tcp->check^0xffff));
42750 + }
42751 + else {
42752 + KLIPS_PRINT(debug_tunnel,
42753 + "klips_debug:ipsec_tunnel_start_xmit: "
42754 + "NAT-T & TRANSPORT: do not recalc TCP checksum\n");
42755 + }
42756 + }
42757 + else {
42758 + KLIPS_PRINT(debug_tunnel,
42759 + "klips_debug:ipsec_tunnel_start_xmit: "
42760 + "NAT-T & TRANSPORT: can't fix TCP checksum\n");
42761 + }
42762 + break;
42763 + case IPPROTO_UDP:
42764 + if (data_len >= sizeof(struct udphdr)) {
42765 + struct udphdr *udp = (struct udphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);
42766 + if (udp->check == 0) {
42767 + KLIPS_PRINT(debug_tunnel,
42768 + "klips_debug:ipsec_tunnel_start_xmit: "
42769 + "NAT-T & TRANSPORT: UDP checksum already 0\n");
42770 + }
42771 + else if (natt_oa) {
42772 + __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };
42773 + KLIPS_PRINT(debug_tunnel,
42774 + "klips_debug:ipsec_tunnel_start_xmit: "
42775 + "NAT-T & TRANSPORT: "
42776 + "fix UDP checksum using NAT-OA\n");
42777 + udp->check = csum_fold(
42778 + csum_partial((unsigned char *)buff, sizeof(buff),
42779 + udp->check^0xffff));
42780 + }
42781 + else {
42782 + KLIPS_PRINT(debug_tunnel,
42783 + "klips_debug:ipsec_tunnel_start_xmit: "
42784 + "NAT-T & TRANSPORT: zero UDP checksum\n");
42785 + udp->check = 0;
42786 + }
42787 + }
42788 + else {
42789 + KLIPS_PRINT(debug_tunnel,
42790 + "klips_debug:ipsec_tunnel_start_xmit: "
42791 + "NAT-T & TRANSPORT: can't fix UDP checksum\n");
42792 + }
42793 + break;
42794 + default:
42795 + KLIPS_PRINT(debug_tunnel,
42796 + "klips_debug:ipsec_tunnel_start_xmit: "
42797 + "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
42798 + break;
42799 + }
42800 + }
42801 +#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
42802 +
42803 + if(!ixs->hard_header_stripped && ixs->hard_header_len>0) {
42804 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42805 + "klips_debug:ipsec_xmit_encap_bundle: "
42806 + "allocating %d bytes for hardheader.\n",
42807 + ixs->hard_header_len);
42808 + if((ixs->saved_header = kmalloc(ixs->hard_header_len, GFP_ATOMIC)) == NULL) {
42809 + printk(KERN_WARNING "klips_debug:ipsec_xmit_encap_bundle: "
42810 + "Failed, tried to allocate %d bytes for temp hard_header.\n",
42811 + ixs->hard_header_len);
42812 + ixs->stats->tx_errors++;
42813 + bundle_stat = IPSEC_XMIT_ERRMEMALLOC;
42814 + goto cleanup;
42815 + }
42816 + {
42817 + int i;
42818 + for (i = 0; i < ixs->hard_header_len; i++) {
42819 + ixs->saved_header[i] = ixs->skb->data[i];
42820 + }
42821 + }
42822 + if(ixs->skb->len < ixs->hard_header_len) {
42823 + printk(KERN_WARNING "klips_error:ipsec_xmit_encap_bundle: "
42824 + "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
42825 + ixs->hard_header_len, (int)(ixs->skb->len));
42826 + ixs->stats->tx_errors++;
42827 + bundle_stat = IPSEC_XMIT_ESP_PUSHPULLERR;
42828 + goto cleanup;
42829 + }
42830 + skb_pull(ixs->skb, ixs->hard_header_len);
42831 + ixs->hard_header_stripped = 1;
42832 +
42833 +/* ixs->iph = (struct iphdr *) (ixs->skb->data); */
42834 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42835 + "klips_debug:ipsec_xmit_encap_bundle: "
42836 + "head,tailroom: %d,%d after hard_header stripped.\n",
42837 + skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
42838 + KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, ixs->iph);
42839 + } else {
42840 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42841 + "klips_debug:ipsec_xmit_encap_bundle: "
42842 + "hard header already stripped.\n");
42843 + }
42844 +
42845 + ixs->ll_headroom = (ixs->hard_header_len + 15) & ~15;
42846 +
42847 + if ((skb_headroom(ixs->skb) >= ixs->max_headroom + 2 * ixs->ll_headroom) &&
42848 + (skb_tailroom(ixs->skb) >= ixs->max_tailroom)
42849 +#ifndef NET_21
42850 + && ixs->skb->free
42851 +#endif /* !NET_21 */
42852 + ) {
42853 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42854 + "klips_debug:ipsec_xmit_encap_bundle: "
42855 + "data fits in existing skb\n");
42856 + } else {
42857 + struct sk_buff* tskb;
42858 +
42859 + if(!ixs->oskb) {
42860 + ixs->oskb = ixs->skb;
42861 + }
42862 +
42863 + tskb = skb_copy_expand(ixs->skb,
42864 + /* The need for 2 * link layer length here remains unexplained...RGB */
42865 + ixs->max_headroom + 2 * ixs->ll_headroom,
42866 + ixs->max_tailroom,
42867 + GFP_ATOMIC);
42868 +
42869 + if(tskb && ixs->skb->sk) {
42870 + skb_set_owner_w(tskb, ixs->skb->sk);
42871 + }
42872 +
42873 + if(ixs->skb != ixs->oskb) {
42874 + ipsec_kfree_skb(ixs->skb);
42875 + }
42876 + ixs->skb = tskb;
42877 + if (!ixs->skb) {
42878 + printk(KERN_WARNING
42879 + "klips_debug:ipsec_xmit_encap_bundle: "
42880 + "Failed, tried to allocate %d head and %d tailroom\n",
42881 + ixs->max_headroom, ixs->max_tailroom);
42882 + ixs->stats->tx_errors++;
42883 + bundle_stat = IPSEC_XMIT_ERRSKBALLOC;
42884 + goto cleanup;
42885 + }
42886 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42887 + "klips_debug:ipsec_xmit_encap_bundle: "
42888 + "head,tailroom: %d,%d after allocation\n",
42889 + skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
42890 + }
42891 +
42892 +#ifdef CONFIG_KLIPS_DEBUG
42893 + if(debug_tunnel & DB_TN_ENCAP) {
42894 + ipsec_print_ip(ixs->iph);
42895 + }
42896 +#endif
42897 +
42898 + /*
42899 + * Apply grouped transforms to packet
42900 + */
42901 + while (ixs->ipsp) {
42902 + enum ipsec_xmit_value encap_stat = IPSEC_XMIT_OK;
42903 +
42904 + encap_stat = ipsec_xmit_encap_once(ixs);
42905 +
42906 +#ifdef CONFIG_KLIPS_DEBUG
42907 + if(debug_tunnel & DB_TN_ENCAP) {
42908 + ipsec_print_ip(ixs->iph);
42909 + }
42910 +#endif
42911 +
42912 + if(encap_stat != IPSEC_XMIT_OK) {
42913 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42914 + "klips_debug:ipsec_xmit_encap_bundle: encap_once failed: %d\n",
42915 + encap_stat);
42916 +
42917 + bundle_stat = IPSEC_XMIT_ENCAPFAIL;
42918 + goto cleanup;
42919 + }
42920 + }
42921 +
42922 + /* we are done with this SA */
42923 + ipsec_sa_put(ixs->ipsp);
42924 +
42925 + /* end encapsulation loop here XXX */
42926 + cleanup:
42927 + spin_unlock(&tdb_lock);
42928 + return bundle_stat;
42929 +}
42930 +
42931 +/*
42932 + * $Log: ipsec_xmit.c,v $
42933 + * Revision 1.20.2.6 2006/07/07 22:09:49 paul
42934 + * From: Bart Trojanowski <bart@xelerance.com>
42935 + * Removing a left over '#else' that split another '#if/#endif' block in two.
42936 + *
42937 + * Revision 1.20.2.5 2006/07/07 15:43:17 paul
42938 + * From: Bart Trojanowski <bart@xelerance.com>
42939 + * improved protocol detection in ipsec_print_ip() -- a debug aid.
42940 + *
42941 + * Revision 1.20.2.4 2006/04/20 16:33:07 mcr
42942 + * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
42943 + * Fix in-kernel module compilation. Sub-makefiles do not work.
42944 + *
42945 + * Revision 1.20.2.3 2005/11/29 21:52:57 ken
42946 + * Fix for #518 MTU issues
42947 + *
42948 + * Revision 1.20.2.2 2005/11/27 21:41:03 paul
42949 + * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"in for klips as module.
42950 + *
42951 + * Revision 1.20.2.1 2005/08/27 23:40:00 paul
42952 + * recommited HAVE_SOCK_SECURITY fixes for linux 2.6.13
42953 + *
42954 + * Revision 1.20 2005/07/12 15:39:27 paul
42955 + * include asm/uaccess.h for VERIFY_WRITE
42956 + *
42957 + * Revision 1.19 2005/05/24 01:02:35 mcr
42958 + * some refactoring/simplification of situation where alg
42959 + * is not found.
42960 + *
42961 + * Revision 1.18 2005/05/23 23:52:33 mcr
42962 + * adjust comments, add additional debugging.
42963 + *
42964 + * Revision 1.17 2005/05/23 22:57:23 mcr
42965 + * removed explicit 3DES support.
42966 + *
42967 + * Revision 1.16 2005/05/21 03:29:15 mcr
42968 + * fixed warning about unused zeroes if AH is off.
42969 + *
42970 + * Revision 1.15 2005/05/20 16:47:59 mcr
42971 + * include asm/checksum.h to get ip_fast_csum macro.
42972 + *
42973 + * Revision 1.14 2005/05/11 01:43:03 mcr
42974 + * removed "poor-man"s OOP in favour of proper C structures.
42975 + *
42976 + * Revision 1.13 2005/04/29 05:10:22 mcr
42977 + * removed from extraenous includes to make unit testing easier.
42978 + *
42979 + * Revision 1.12 2005/04/15 01:28:34 mcr
42980 + * use ipsec_dmp_block.
42981 + *
42982 + * Revision 1.11 2005/01/26 00:50:35 mcr
42983 + * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
42984 + * and make sure that NAT_TRAVERSAL is set as well to match
42985 + * userspace compiles of code.
42986 + *
42987 + * Revision 1.10 2004/09/13 17:55:21 ken
42988 + * MD5* -> osMD5*
42989 + *
42990 + * Revision 1.9 2004/07/10 19:11:18 mcr
42991 + * CONFIG_IPSEC -> CONFIG_KLIPS.
42992 + *
42993 + * Revision 1.8 2004/04/06 02:49:26 mcr
42994 + * pullup of algo code from alg-branch.
42995 + *
42996 + * Revision 1.7 2004/02/03 03:13:41 mcr
42997 + * mark invalid encapsulation states.
42998 + *
42999 + * Revision 1.6.2.1 2003/12/22 15:25:52 jjo
43000 + * Merged algo-0.8.1-rc11-test1 into alg-branch
43001 + *
43002 + * Revision 1.6 2003/12/10 01:14:27 mcr
43003 + * NAT-traversal patches to KLIPS.
43004 + *
43005 + * Revision 1.5 2003/10/31 02:27:55 mcr
43006 + * pulled up port-selector patches and sa_id elimination.
43007 + *
43008 + * Revision 1.4.4.2 2003/10/29 01:37:39 mcr
43009 + * when creating %hold from %trap, only make the %hold as
43010 + * specific as the %trap was - so if the protocol and ports
43011 + * were wildcards, then the %hold will be too.
43012 + *
43013 + * Revision 1.4.4.1 2003/09/21 13:59:56 mcr
43014 + * pre-liminary X.509 patch - does not yet pass tests.
43015 + *
43016 + * Revision 1.4 2003/06/20 02:28:10 mcr
43017 + * misstype of variable name, not detected by module build.
43018 + *
43019 + * Revision 1.3 2003/06/20 01:42:21 mcr
43020 + * added counters to measure how many ACQUIREs we send to pluto,
43021 + * and how many are successfully sent.
43022 + *
43023 + * Revision 1.2 2003/04/03 17:38:35 rgb
43024 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
43025 + * Normalised coding style.
43026 + * Simplified logic and reduced duplication of code.
43027 + *
43028 + * Revision 1.1 2003/02/12 19:31:23 rgb
43029 + * Refactored from ipsec_tunnel.c
43030 + *
43031 + * Local Variables:
43032 + * c-file-style: "linux"
43033 + * End:
43034 + *
43035 + */
43036 --- /dev/null Tue Mar 11 13:02:56 2003
43037 +++ linux/net/ipsec/match586.S Mon Feb 9 13:51:03 2004
43038 @@ -0,0 +1,357 @@
43039 +/* match.s -- Pentium-optimized version of longest_match()
43040 + * Written for zlib 1.1.2
43041 + * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
43042 + *
43043 + * This is free software; you can redistribute it and/or modify it
43044 + * under the terms of the GNU General Public License.
43045 + */
43046 +
43047 +#ifndef NO_UNDERLINE
43048 +#define match_init _ipcomp_match_init
43049 +#define longest_match _ipcomp_longest_match
43050 +#else
43051 +#define match_init ipcomp_match_init
43052 +#define longest_match ipcomp_longest_match
43053 +#endif
43054 +
43055 +#define MAX_MATCH (258)
43056 +#define MIN_MATCH (3)
43057 +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
43058 +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
43059 +
43060 +/* stack frame offsets */
43061 +
43062 +#define wmask 0 /* local copy of s->wmask */
43063 +#define window 4 /* local copy of s->window */
43064 +#define windowbestlen 8 /* s->window + bestlen */
43065 +#define chainlenscanend 12 /* high word: current chain len */
43066 + /* low word: last bytes sought */
43067 +#define scanstart 16 /* first two bytes of string */
43068 +#define scanalign 20 /* dword-misalignment of string */
43069 +#define nicematch 24 /* a good enough match size */
43070 +#define bestlen 28 /* size of best match so far */
43071 +#define scan 32 /* ptr to string wanting match */
43072 +
43073 +#define LocalVarsSize (36)
43074 +/* saved ebx 36 */
43075 +/* saved edi 40 */
43076 +/* saved esi 44 */
43077 +/* saved ebp 48 */
43078 +/* return address 52 */
43079 +#define deflatestate 56 /* the function arguments */
43080 +#define curmatch 60
43081 +
43082 +/* Offsets for fields in the deflate_state structure. These numbers
43083 + * are calculated from the definition of deflate_state, with the
43084 + * assumption that the compiler will dword-align the fields. (Thus,
43085 + * changing the definition of deflate_state could easily cause this
43086 + * program to crash horribly, without so much as a warning at
43087 + * compile time. Sigh.)
43088 + */
43089 +#define dsWSize 36
43090 +#define dsWMask 44
43091 +#define dsWindow 48
43092 +#define dsPrev 56
43093 +#define dsMatchLen 88
43094 +#define dsPrevMatch 92
43095 +#define dsStrStart 100
43096 +#define dsMatchStart 104
43097 +#define dsLookahead 108
43098 +#define dsPrevLen 112
43099 +#define dsMaxChainLen 116
43100 +#define dsGoodMatch 132
43101 +#define dsNiceMatch 136
43102 +
43103 +
43104 +.file "match.S"
43105 +
43106 +.globl match_init, longest_match
43107 +
43108 +.text
43109 +
43110 +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
43111 +
43112 +longest_match:
43113 +
43114 +/* Save registers that the compiler may be using, and adjust %esp to */
43115 +/* make room for our stack frame. */
43116 +
43117 + pushl %ebp
43118 + pushl %edi
43119 + pushl %esi
43120 + pushl %ebx
43121 + subl $LocalVarsSize, %esp
43122 +
43123 +/* Retrieve the function arguments. %ecx will hold cur_match */
43124 +/* throughout the entire function. %edx will hold the pointer to the */
43125 +/* deflate_state structure during the function's setup (before */
43126 +/* entering the main loop). */
43127 +
43128 + movl deflatestate(%esp), %edx
43129 + movl curmatch(%esp), %ecx
43130 +
43131 +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
43132 +
43133 + movl dsNiceMatch(%edx), %eax
43134 + movl dsLookahead(%edx), %ebx
43135 + cmpl %eax, %ebx
43136 + jl LookaheadLess
43137 + movl %eax, %ebx
43138 +LookaheadLess: movl %ebx, nicematch(%esp)
43139 +
43140 +/* register Bytef *scan = s->window + s->strstart; */
43141 +
43142 + movl dsWindow(%edx), %esi
43143 + movl %esi, window(%esp)
43144 + movl dsStrStart(%edx), %ebp
43145 + lea (%esi,%ebp), %edi
43146 + movl %edi, scan(%esp)
43147 +
43148 +/* Determine how many bytes the scan ptr is off from being */
43149 +/* dword-aligned. */
43150 +
43151 + movl %edi, %eax
43152 + negl %eax
43153 + andl $3, %eax
43154 + movl %eax, scanalign(%esp)
43155 +
43156 +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
43157 +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
43158 +
43159 + movl dsWSize(%edx), %eax
43160 + subl $MIN_LOOKAHEAD, %eax
43161 + subl %eax, %ebp
43162 + jg LimitPositive
43163 + xorl %ebp, %ebp
43164 +LimitPositive:
43165 +
43166 +/* unsigned chain_length = s->max_chain_length; */
43167 +/* if (s->prev_length >= s->good_match) { */
43168 +/* chain_length >>= 2; */
43169 +/* } */
43170 +
43171 + movl dsPrevLen(%edx), %eax
43172 + movl dsGoodMatch(%edx), %ebx
43173 + cmpl %ebx, %eax
43174 + movl dsMaxChainLen(%edx), %ebx
43175 + jl LastMatchGood
43176 + shrl $2, %ebx
43177 +LastMatchGood:
43178 +
43179 +/* chainlen is decremented once beforehand so that the function can */
43180 +/* use the sign flag instead of the zero flag for the exit test. */
43181 +/* It is then shifted into the high word, to make room for the scanend */
43182 +/* scanend value, which it will always accompany. */
43183 +
43184 + decl %ebx
43185 + shll $16, %ebx
43186 +
43187 +/* int best_len = s->prev_length; */
43188 +
43189 + movl dsPrevLen(%edx), %eax
43190 + movl %eax, bestlen(%esp)
43191 +
43192 +/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
43193 +
43194 + addl %eax, %esi
43195 + movl %esi, windowbestlen(%esp)
43196 +
43197 +/* register ush scan_start = *(ushf*)scan; */
43198 +/* register ush scan_end = *(ushf*)(scan+best_len-1); */
43199 +
43200 + movw (%edi), %bx
43201 + movw %bx, scanstart(%esp)
43202 + movw -1(%edi,%eax), %bx
43203 + movl %ebx, chainlenscanend(%esp)
43204 +
43205 +/* Posf *prev = s->prev; */
43206 +/* uInt wmask = s->w_mask; */
43207 +
43208 + movl dsPrev(%edx), %edi
43209 + movl dsWMask(%edx), %edx
43210 + mov %edx, wmask(%esp)
43211 +
43212 +/* Jump into the main loop. */
43213 +
43214 + jmp LoopEntry
43215 +
43216 +.balign 16
43217 +
43218 +/* do {
43219 + * match = s->window + cur_match;
43220 + * if (*(ushf*)(match+best_len-1) != scan_end ||
43221 + * *(ushf*)match != scan_start) continue;
43222 + * [...]
43223 + * } while ((cur_match = prev[cur_match & wmask]) > limit
43224 + * && --chain_length != 0);
43225 + *
43226 + * Here is the inner loop of the function. The function will spend the
43227 + * majority of its time in this loop, and majority of that time will
43228 + * be spent in the first ten instructions.
43229 + *
43230 + * Within this loop:
43231 + * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
43232 + * %ecx = curmatch
43233 + * %edx = curmatch & wmask
43234 + * %esi = windowbestlen - i.e., (window + bestlen)
43235 + * %edi = prev
43236 + * %ebp = limit
43237 + *
43238 + * Two optimization notes on the choice of instructions:
43239 + *
43240 + * The first instruction uses a 16-bit address, which costs an extra,
43241 + * unpairable cycle. This is cheaper than doing a 32-bit access and
43242 + * zeroing the high word, due to the 3-cycle misalignment penalty which
43243 + * would occur half the time. This also turns out to be cheaper than
43244 + * doing two separate 8-bit accesses, as the memory is so rarely in the
43245 + * L1 cache.
43246 + *
43247 + * The window buffer, however, apparently spends a lot of time in the
43248 + * cache, and so it is faster to retrieve the word at the end of the
43249 + * match string with two 8-bit loads. The instructions that test the
43250 + * word at the beginning of the match string, however, are executed
43251 + * much less frequently, and there it was cheaper to use 16-bit
43252 + * instructions, which avoided the necessity of saving off and
43253 + * subsequently reloading one of the other registers.
43254 + */
43255 +LookupLoop:
43256 + /* 1 U & V */
43257 + movw (%edi,%edx,2), %cx /* 2 U pipe */
43258 + movl wmask(%esp), %edx /* 2 V pipe */
43259 + cmpl %ebp, %ecx /* 3 U pipe */
43260 + jbe LeaveNow /* 3 V pipe */
43261 + subl $0x00010000, %ebx /* 4 U pipe */
43262 + js LeaveNow /* 4 V pipe */
43263 +LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */
43264 + andl %ecx, %edx /* 5 V pipe */
43265 + cmpb %bl, %al /* 6 U pipe */
43266 + jnz LookupLoop /* 6 V pipe */
43267 + movb (%esi,%ecx), %ah
43268 + cmpb %bh, %ah
43269 + jnz LookupLoop
43270 + movl window(%esp), %eax
43271 + movw (%eax,%ecx), %ax
43272 + cmpw scanstart(%esp), %ax
43273 + jnz LookupLoop
43274 +
43275 +/* Store the current value of chainlen. */
43276 +
43277 + movl %ebx, chainlenscanend(%esp)
43278 +
43279 +/* Point %edi to the string under scrutiny, and %esi to the string we */
43280 +/* are hoping to match it up with. In actuality, %esi and %edi are */
43281 +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
43282 +/* initialized to -(MAX_MATCH_8 - scanalign). */
43283 +
43284 + movl window(%esp), %esi
43285 + movl scan(%esp), %edi
43286 + addl %ecx, %esi
43287 + movl scanalign(%esp), %eax
43288 + movl $(-MAX_MATCH_8), %edx
43289 + lea MAX_MATCH_8(%edi,%eax), %edi
43290 + lea MAX_MATCH_8(%esi,%eax), %esi
43291 +
43292 +/* Test the strings for equality, 8 bytes at a time. At the end,
43293 + * adjust %edx so that it is offset to the exact byte that mismatched.
43294 + *
43295 + * We already know at this point that the first three bytes of the
43296 + * strings match each other, and they can be safely passed over before
43297 + * starting the compare loop. So what this code does is skip over 0-3
43298 + * bytes, as much as necessary in order to dword-align the %edi
43299 + * pointer. (%esi will still be misaligned three times out of four.)
43300 + *
43301 + * It should be confessed that this loop usually does not represent
43302 + * much of the total running time. Replacing it with a more
43303 + * straightforward "rep cmpsb" would not drastically degrade
43304 + * performance.
43305 + */
43306 +LoopCmps:
43307 + movl (%esi,%edx), %eax
43308 + movl (%edi,%edx), %ebx
43309 + xorl %ebx, %eax
43310 + jnz LeaveLoopCmps
43311 + movl 4(%esi,%edx), %eax
43312 + movl 4(%edi,%edx), %ebx
43313 + xorl %ebx, %eax
43314 + jnz LeaveLoopCmps4
43315 + addl $8, %edx
43316 + jnz LoopCmps
43317 + jmp LenMaximum
43318 +LeaveLoopCmps4: addl $4, %edx
43319 +LeaveLoopCmps: testl $0x0000FFFF, %eax
43320 + jnz LenLower
43321 + addl $2, %edx
43322 + shrl $16, %eax
43323 +LenLower: subb $1, %al
43324 + adcl $0, %edx
43325 +
43326 +/* Calculate the length of the match. If it is longer than MAX_MATCH, */
43327 +/* then automatically accept it as the best possible match and leave. */
43328 +
43329 + lea (%edi,%edx), %eax
43330 + movl scan(%esp), %edi
43331 + subl %edi, %eax
43332 + cmpl $MAX_MATCH, %eax
43333 + jge LenMaximum
43334 +
43335 +/* If the length of the match is not longer than the best match we */
43336 +/* have so far, then forget it and return to the lookup loop. */
43337 +
43338 + movl deflatestate(%esp), %edx
43339 + movl bestlen(%esp), %ebx
43340 + cmpl %ebx, %eax
43341 + jg LongerMatch
43342 + movl chainlenscanend(%esp), %ebx
43343 + movl windowbestlen(%esp), %esi
43344 + movl dsPrev(%edx), %edi
43345 + movl wmask(%esp), %edx
43346 + andl %ecx, %edx
43347 + jmp LookupLoop
43348 +
43349 +/* s->match_start = cur_match; */
43350 +/* best_len = len; */
43351 +/* if (len >= nice_match) break; */
43352 +/* scan_end = *(ushf*)(scan+best_len-1); */
43353 +
43354 +LongerMatch: movl nicematch(%esp), %ebx
43355 + movl %eax, bestlen(%esp)
43356 + movl %ecx, dsMatchStart(%edx)
43357 + cmpl %ebx, %eax
43358 + jge LeaveNow
43359 + movl window(%esp), %esi
43360 + addl %eax, %esi
43361 + movl %esi, windowbestlen(%esp)
43362 + movl chainlenscanend(%esp), %ebx
43363 + movw -1(%edi,%eax), %bx
43364 + movl dsPrev(%edx), %edi
43365 + movl %ebx, chainlenscanend(%esp)
43366 + movl wmask(%esp), %edx
43367 + andl %ecx, %edx
43368 + jmp LookupLoop
43369 +
43370 +/* Accept the current string, with the maximum possible length. */
43371 +
43372 +LenMaximum: movl deflatestate(%esp), %edx
43373 + movl $MAX_MATCH, bestlen(%esp)
43374 + movl %ecx, dsMatchStart(%edx)
43375 +
43376 +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
43377 +/* return s->lookahead; */
43378 +
43379 +LeaveNow:
43380 + movl deflatestate(%esp), %edx
43381 + movl bestlen(%esp), %ebx
43382 + movl dsLookahead(%edx), %eax
43383 + cmpl %eax, %ebx
43384 + jg LookaheadRet
43385 + movl %ebx, %eax
43386 +LookaheadRet:
43387 +
43388 +/* Restore the stack and return from whence we came. */
43389 +
43390 + addl $LocalVarsSize, %esp
43391 + popl %ebx
43392 + popl %esi
43393 + popl %edi
43394 + popl %ebp
43395 +match_init: ret
43396 --- /dev/null Tue Mar 11 13:02:56 2003
43397 +++ linux/net/ipsec/match686.S Mon Feb 9 13:51:03 2004
43398 @@ -0,0 +1,330 @@
43399 +/* match.s -- Pentium-Pro-optimized version of longest_match()
43400 + * Written for zlib 1.1.2
43401 + * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
43402 + *
43403 + * This is free software; you can redistribute it and/or modify it
43404 + * under the terms of the GNU General Public License.
43405 + */
43406 +
43407 +#ifndef NO_UNDERLINE
43408 +#define match_init _ipcomp_match_init
43409 +#define longest_match _ipcomp_longest_match
43410 +#else
43411 +#define match_init ipcomp_match_init
43412 +#define longest_match ipcomp_longest_match
43413 +#endif
43414 +
43415 +#define MAX_MATCH (258)
43416 +#define MIN_MATCH (3)
43417 +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
43418 +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
43419 +
43420 +/* stack frame offsets */
43421 +
43422 +#define chainlenwmask 0 /* high word: current chain len */
43423 + /* low word: s->wmask */
43424 +#define window 4 /* local copy of s->window */
43425 +#define windowbestlen 8 /* s->window + bestlen */
43426 +#define scanstart 16 /* first two bytes of string */
43427 +#define scanend 12 /* last two bytes of string */
43428 +#define scanalign 20 /* dword-misalignment of string */
43429 +#define nicematch 24 /* a good enough match size */
43430 +#define bestlen 28 /* size of best match so far */
43431 +#define scan 32 /* ptr to string wanting match */
43432 +
43433 +#define LocalVarsSize (36)
43434 +/* saved ebx 36 */
43435 +/* saved edi 40 */
43436 +/* saved esi 44 */
43437 +/* saved ebp 48 */
43438 +/* return address 52 */
43439 +#define deflatestate 56 /* the function arguments */
43440 +#define curmatch 60
43441 +
43442 +/* Offsets for fields in the deflate_state structure. These numbers
43443 + * are calculated from the definition of deflate_state, with the
43444 + * assumption that the compiler will dword-align the fields. (Thus,
43445 + * changing the definition of deflate_state could easily cause this
43446 + * program to crash horribly, without so much as a warning at
43447 + * compile time. Sigh.)
43448 + */
43449 +#define dsWSize 36
43450 +#define dsWMask 44
43451 +#define dsWindow 48
43452 +#define dsPrev 56
43453 +#define dsMatchLen 88
43454 +#define dsPrevMatch 92
43455 +#define dsStrStart 100
43456 +#define dsMatchStart 104
43457 +#define dsLookahead 108
43458 +#define dsPrevLen 112
43459 +#define dsMaxChainLen 116
43460 +#define dsGoodMatch 132
43461 +#define dsNiceMatch 136
43462 +
43463 +
43464 +.file "match.S"
43465 +
43466 +.globl match_init, longest_match
43467 +
43468 +.text
43469 +
43470 +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
43471 +
43472 +longest_match:
43473 +
43474 +/* Save registers that the compiler may be using, and adjust %esp to */
43475 +/* make room for our stack frame. */
43476 +
43477 + pushl %ebp
43478 + pushl %edi
43479 + pushl %esi
43480 + pushl %ebx
43481 + subl $LocalVarsSize, %esp
43482 +
43483 +/* Retrieve the function arguments. %ecx will hold cur_match */
43484 +/* throughout the entire function. %edx will hold the pointer to the */
43485 +/* deflate_state structure during the function's setup (before */
43486 +/* entering the main loop). */
43487 +
43488 + movl deflatestate(%esp), %edx
43489 + movl curmatch(%esp), %ecx
43490 +
43491 +/* uInt wmask = s->w_mask; */
43492 +/* unsigned chain_length = s->max_chain_length; */
43493 +/* if (s->prev_length >= s->good_match) { */
43494 +/* chain_length >>= 2; */
43495 +/* } */
43496 +
43497 + movl dsPrevLen(%edx), %eax
43498 + movl dsGoodMatch(%edx), %ebx
43499 + cmpl %ebx, %eax
43500 + movl dsWMask(%edx), %eax
43501 + movl dsMaxChainLen(%edx), %ebx
43502 + jl LastMatchGood
43503 + shrl $2, %ebx
43504 +LastMatchGood:
43505 +
43506 +/* chainlen is decremented once beforehand so that the function can */
43507 +/* use the sign flag instead of the zero flag for the exit test. */
43508 +/* It is then shifted into the high word, to make room for the wmask */
43509 +/* value, which it will always accompany. */
43510 +
43511 + decl %ebx
43512 + shll $16, %ebx
43513 + orl %eax, %ebx
43514 + movl %ebx, chainlenwmask(%esp)
43515 +
43516 +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
43517 +
43518 + movl dsNiceMatch(%edx), %eax
43519 + movl dsLookahead(%edx), %ebx
43520 + cmpl %eax, %ebx
43521 + jl LookaheadLess
43522 + movl %eax, %ebx
43523 +LookaheadLess: movl %ebx, nicematch(%esp)
43524 +
43525 +/* register Bytef *scan = s->window + s->strstart; */
43526 +
43527 + movl dsWindow(%edx), %esi
43528 + movl %esi, window(%esp)
43529 + movl dsStrStart(%edx), %ebp
43530 + lea (%esi,%ebp), %edi
43531 + movl %edi, scan(%esp)
43532 +
43533 +/* Determine how many bytes the scan ptr is off from being */
43534 +/* dword-aligned. */
43535 +
43536 + movl %edi, %eax
43537 + negl %eax
43538 + andl $3, %eax
43539 + movl %eax, scanalign(%esp)
43540 +
43541 +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
43542 +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
43543 +
43544 + movl dsWSize(%edx), %eax
43545 + subl $MIN_LOOKAHEAD, %eax
43546 + subl %eax, %ebp
43547 + jg LimitPositive
43548 + xorl %ebp, %ebp
43549 +LimitPositive:
43550 +
43551 +/* int best_len = s->prev_length; */
43552 +
43553 + movl dsPrevLen(%edx), %eax
43554 + movl %eax, bestlen(%esp)
43555 +
43556 +/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
43557 +
43558 + addl %eax, %esi
43559 + movl %esi, windowbestlen(%esp)
43560 +
43561 +/* register ush scan_start = *(ushf*)scan; */
43562 +/* register ush scan_end = *(ushf*)(scan+best_len-1); */
43563 +/* Posf *prev = s->prev; */
43564 +
43565 + movzwl (%edi), %ebx
43566 + movl %ebx, scanstart(%esp)
43567 + movzwl -1(%edi,%eax), %ebx
43568 + movl %ebx, scanend(%esp)
43569 + movl dsPrev(%edx), %edi
43570 +
43571 +/* Jump into the main loop. */
43572 +
43573 + movl chainlenwmask(%esp), %edx
43574 + jmp LoopEntry
43575 +
43576 +.balign 16
43577 +
43578 +/* do {
43579 + * match = s->window + cur_match;
43580 + * if (*(ushf*)(match+best_len-1) != scan_end ||
43581 + * *(ushf*)match != scan_start) continue;
43582 + * [...]
43583 + * } while ((cur_match = prev[cur_match & wmask]) > limit
43584 + * && --chain_length != 0);
43585 + *
43586 + * Here is the inner loop of the function. The function will spend the
43587 + * majority of its time in this loop, and majority of that time will
43588 + * be spent in the first ten instructions.
43589 + *
43590 + * Within this loop:
43591 + * %ebx = scanend
43592 + * %ecx = curmatch
43593 + * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
43594 + * %esi = windowbestlen - i.e., (window + bestlen)
43595 + * %edi = prev
43596 + * %ebp = limit
43597 + */
43598 +LookupLoop:
43599 + andl %edx, %ecx
43600 + movzwl (%edi,%ecx,2), %ecx
43601 + cmpl %ebp, %ecx
43602 + jbe LeaveNow
43603 + subl $0x00010000, %edx
43604 + js LeaveNow
43605 +LoopEntry: movzwl -1(%esi,%ecx), %eax
43606 + cmpl %ebx, %eax
43607 + jnz LookupLoop
43608 + movl window(%esp), %eax
43609 + movzwl (%eax,%ecx), %eax
43610 + cmpl scanstart(%esp), %eax
43611 + jnz LookupLoop
43612 +
43613 +/* Store the current value of chainlen. */
43614 +
43615 + movl %edx, chainlenwmask(%esp)
43616 +
43617 +/* Point %edi to the string under scrutiny, and %esi to the string we */
43618 +/* are hoping to match it up with. In actuality, %esi and %edi are */
43619 +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
43620 +/* initialized to -(MAX_MATCH_8 - scanalign). */
43621 +
43622 + movl window(%esp), %esi
43623 + movl scan(%esp), %edi
43624 + addl %ecx, %esi
43625 + movl scanalign(%esp), %eax
43626 + movl $(-MAX_MATCH_8), %edx
43627 + lea MAX_MATCH_8(%edi,%eax), %edi
43628 + lea MAX_MATCH_8(%esi,%eax), %esi
43629 +
43630 +/* Test the strings for equality, 8 bytes at a time. At the end,
43631 + * adjust %edx so that it is offset to the exact byte that mismatched.
43632 + *
43633 + * We already know at this point that the first three bytes of the
43634 + * strings match each other, and they can be safely passed over before
43635 + * starting the compare loop. So what this code does is skip over 0-3
43636 + * bytes, as much as necessary in order to dword-align the %edi
43637 + * pointer. (%esi will still be misaligned three times out of four.)
43638 + *
43639 + * It should be confessed that this loop usually does not represent
43640 + * much of the total running time. Replacing it with a more
43641 + * straightforward "rep cmpsb" would not drastically degrade
43642 + * performance.
43643 + */
43644 +LoopCmps:
43645 + movl (%esi,%edx), %eax
43646 + xorl (%edi,%edx), %eax
43647 + jnz LeaveLoopCmps
43648 + movl 4(%esi,%edx), %eax
43649 + xorl 4(%edi,%edx), %eax
43650 + jnz LeaveLoopCmps4
43651 + addl $8, %edx
43652 + jnz LoopCmps
43653 + jmp LenMaximum
43654 +LeaveLoopCmps4: addl $4, %edx
43655 +LeaveLoopCmps: testl $0x0000FFFF, %eax
43656 + jnz LenLower
43657 + addl $2, %edx
43658 + shrl $16, %eax
43659 +LenLower: subb $1, %al
43660 + adcl $0, %edx
43661 +
43662 +/* Calculate the length of the match. If it is longer than MAX_MATCH, */
43663 +/* then automatically accept it as the best possible match and leave. */
43664 +
43665 + lea (%edi,%edx), %eax
43666 + movl scan(%esp), %edi
43667 + subl %edi, %eax
43668 + cmpl $MAX_MATCH, %eax
43669 + jge LenMaximum
43670 +
43671 +/* If the length of the match is not longer than the best match we */
43672 +/* have so far, then forget it and return to the lookup loop. */
43673 +
43674 + movl deflatestate(%esp), %edx
43675 + movl bestlen(%esp), %ebx
43676 + cmpl %ebx, %eax
43677 + jg LongerMatch
43678 + movl windowbestlen(%esp), %esi
43679 + movl dsPrev(%edx), %edi
43680 + movl scanend(%esp), %ebx
43681 + movl chainlenwmask(%esp), %edx
43682 + jmp LookupLoop
43683 +
43684 +/* s->match_start = cur_match; */
43685 +/* best_len = len; */
43686 +/* if (len >= nice_match) break; */
43687 +/* scan_end = *(ushf*)(scan+best_len-1); */
43688 +
43689 +LongerMatch: movl nicematch(%esp), %ebx
43690 + movl %eax, bestlen(%esp)
43691 + movl %ecx, dsMatchStart(%edx)
43692 + cmpl %ebx, %eax
43693 + jge LeaveNow
43694 + movl window(%esp), %esi
43695 + addl %eax, %esi
43696 + movl %esi, windowbestlen(%esp)
43697 + movzwl -1(%edi,%eax), %ebx
43698 + movl dsPrev(%edx), %edi
43699 + movl %ebx, scanend(%esp)
43700 + movl chainlenwmask(%esp), %edx
43701 + jmp LookupLoop
43702 +
43703 +/* Accept the current string, with the maximum possible length. */
43704 +
43705 +LenMaximum: movl deflatestate(%esp), %edx
43706 + movl $MAX_MATCH, bestlen(%esp)
43707 + movl %ecx, dsMatchStart(%edx)
43708 +
43709 +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
43710 +/* return s->lookahead; */
43711 +
43712 +LeaveNow:
43713 + movl deflatestate(%esp), %edx
43714 + movl bestlen(%esp), %ebx
43715 + movl dsLookahead(%edx), %eax
43716 + cmpl %eax, %ebx
43717 + jg LookaheadRet
43718 + movl %ebx, %eax
43719 +LookaheadRet:
43720 +
43721 +/* Restore the stack and return from whence we came. */
43722 +
43723 + addl $LocalVarsSize, %esp
43724 + popl %ebx
43725 + popl %esi
43726 + popl %edi
43727 + popl %ebp
43728 +match_init: ret
43729 --- /dev/null Tue Mar 11 13:02:56 2003
43730 +++ linux/net/ipsec/pfkey_v2.c Mon Feb 9 13:51:03 2004
43731 @@ -0,0 +1,1996 @@
43732 +/*
43733 + * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F
43734 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
43735 + *
43736 + * This program is free software; you can redistribute it and/or modify it
43737 + * under the terms of the GNU General Public License as published by the
43738 + * Free Software Foundation; either version 2 of the License, or (at your
43739 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
43740 + *
43741 + * This program is distributed in the hope that it will be useful, but
43742 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
43743 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
43744 + * for more details.
43745 + *
43746 + * RCSID $Id: pfkey_v2.c,v 1.97.2.8 2006/07/10 15:56:11 paul Exp $
43747 + */
43748 +
43749 +/*
43750 + * Template from /usr/src/linux-2.0.36/net/unix/af_unix.c.
43751 + * Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c.
43752 + */
43753 +
43754 +#define __NO_VERSION__
43755 +#include <linux/module.h>
43756 +#include <linux/version.h>
43757 +#ifndef AUTOCONF_INCLUDED
43758 +#include <linux/config.h>
43759 +#endif
43760 +#include <linux/kernel.h>
43761 +
43762 +#include "openswan/ipsec_param.h"
43763 +
43764 +#include <linux/major.h>
43765 +#include <linux/signal.h>
43766 +#include <linux/sched.h>
43767 +#include <linux/errno.h>
43768 +#include <linux/string.h>
43769 +#include <linux/stat.h>
43770 +#include <linux/socket.h>
43771 +#include <linux/un.h>
43772 +#include <linux/fcntl.h>
43773 +#include <linux/termios.h>
43774 +#include <linux/socket.h>
43775 +#include <linux/sockios.h>
43776 +#include <linux/net.h> /* struct socket */
43777 +#include <linux/in.h>
43778 +#include <linux/fs.h>
43779 +#ifdef MALLOC_SLAB
43780 +# include <linux/slab.h> /* kmalloc() */
43781 +#else /* MALLOC_SLAB */
43782 +# include <linux/malloc.h> /* kmalloc() */
43783 +#endif /* MALLOC_SLAB */
43784 +#include <asm/segment.h>
43785 +#include <linux/skbuff.h>
43786 +#include <linux/netdevice.h>
43787 +#include <net/sock.h> /* struct sock */
43788 +#include <net/protocol.h>
43789 +/* #include <net/tcp.h> */
43790 +#include <net/af_unix.h>
43791 +#ifdef CONFIG_PROC_FS
43792 +# include <linux/proc_fs.h>
43793 +#endif /* CONFIG_PROC_FS */
43794 +
43795 +#include <linux/types.h>
43796 +
43797 +#include <openswan.h>
43798 +
43799 +#include "openswan/radij.h"
43800 +#include "openswan/ipsec_encap.h"
43801 +#include "openswan/ipsec_sa.h"
43802 +
43803 +#include <openswan/pfkeyv2.h>
43804 +#include <openswan/pfkey.h>
43805 +
43806 +#include "openswan/ipsec_proto.h"
43807 +#include "openswan/ipsec_kern24.h"
43808 +
43809 +#ifdef CONFIG_KLIPS_DEBUG
43810 +int debug_pfkey = 0;
43811 +extern int sysctl_ipsec_debug_verbose;
43812 +#endif /* CONFIG_KLIPS_DEBUG */
43813 +
43814 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
43815 +
43816 +#ifndef SOCKOPS_WRAPPED
43817 +#define SOCKOPS_WRAPPED(name) name
43818 +#endif /* SOCKOPS_WRAPPED */
43819 +
43820 +#ifdef NET_26
43821 +static rwlock_t pfkey_sock_lock = RW_LOCK_UNLOCKED;
43822 +HLIST_HEAD(pfkey_sock_list);
43823 +static DECLARE_WAIT_QUEUE_HEAD(pfkey_sock_wait);
43824 +static atomic_t pfkey_sock_users = ATOMIC_INIT(0);
43825 +#else
43826 +struct sock *pfkey_sock_list = NULL;
43827 +#endif
43828 +
43829 +struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
43830 +
43831 +struct socket_list *pfkey_open_sockets = NULL;
43832 +struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
43833 +
43834 +int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **);
43835 +
43836 +DEBUG_NO_STATIC int pfkey_create(struct socket *sock, int protocol);
43837 +DEBUG_NO_STATIC int pfkey_shutdown(struct socket *sock, int mode);
43838 +DEBUG_NO_STATIC int pfkey_release(struct socket *sock);
43839 +
43840 +#ifdef NET_26
43841 +DEBUG_NO_STATIC int pfkey_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len);
43842 +DEBUG_NO_STATIC int pfkey_recvmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg
43843 + , size_t size, int flags);
43844 +#else
43845 +DEBUG_NO_STATIC int pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm);
43846 +DEBUG_NO_STATIC int pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm);
43847 +#endif
43848 +
43849 +struct net_proto_family pfkey_family_ops = {
43850 + PF_KEY,
43851 + pfkey_create
43852 +};
43853 +
43854 +struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = {
43855 +#ifdef NETDEV_23
43856 + family: PF_KEY,
43857 + release: pfkey_release,
43858 + bind: sock_no_bind,
43859 + connect: sock_no_connect,
43860 + socketpair: sock_no_socketpair,
43861 + accept: sock_no_accept,
43862 + getname: sock_no_getname,
43863 + poll: datagram_poll,
43864 + ioctl: sock_no_ioctl,
43865 + listen: sock_no_listen,
43866 + shutdown: pfkey_shutdown,
43867 + setsockopt: sock_no_setsockopt,
43868 + getsockopt: sock_no_getsockopt,
43869 + sendmsg: pfkey_sendmsg,
43870 + recvmsg: pfkey_recvmsg,
43871 + mmap: sock_no_mmap,
43872 +#else /* NETDEV_23 */
43873 + PF_KEY,
43874 + sock_no_dup,
43875 + pfkey_release,
43876 + sock_no_bind,
43877 + sock_no_connect,
43878 + sock_no_socketpair,
43879 + sock_no_accept,
43880 + sock_no_getname,
43881 + datagram_poll,
43882 + sock_no_ioctl,
43883 + sock_no_listen,
43884 + pfkey_shutdown,
43885 + sock_no_setsockopt,
43886 + sock_no_getsockopt,
43887 + sock_no_fcntl,
43888 + pfkey_sendmsg,
43889 + pfkey_recvmsg
43890 +#endif /* NETDEV_23 */
43891 +};
43892 +
43893 +#ifdef NETDEV_23
43894 +#include <linux/smp_lock.h>
43895 +SOCKOPS_WRAP(pfkey, PF_KEY);
43896 +#endif /* NETDEV_23 */
43897 +
43898 +#ifdef NET_26
43899 +static void pfkey_sock_list_grab(void)
43900 +{
43901 + write_lock_bh(&pfkey_sock_lock);
43902 +
43903 + if (atomic_read(&pfkey_sock_users)) {
43904 + DECLARE_WAITQUEUE(wait, current);
43905 +
43906 + add_wait_queue_exclusive(&pfkey_sock_wait, &wait);
43907 + for(;;) {
43908 + set_current_state(TASK_UNINTERRUPTIBLE);
43909 + if (atomic_read(&pfkey_sock_users) == 0)
43910 + break;
43911 + write_unlock_bh(&pfkey_sock_lock);
43912 + schedule();
43913 + write_lock_bh(&pfkey_sock_lock);
43914 + }
43915 +
43916 + __set_current_state(TASK_RUNNING);
43917 + remove_wait_queue(&pfkey_sock_wait, &wait);
43918 + }
43919 +}
43920 +
43921 +static __inline__ void pfkey_sock_list_ungrab(void)
43922 +{
43923 + write_unlock_bh(&pfkey_sock_lock);
43924 + wake_up(&pfkey_sock_wait);
43925 +}
43926 +
43927 +static __inline__ void pfkey_lock_sock_list(void)
43928 +{
43929 + /* read_lock() synchronizes us to pfkey_table_grab */
43930 +
43931 + read_lock(&pfkey_sock_lock);
43932 + atomic_inc(&pfkey_sock_users);
43933 + read_unlock(&pfkey_sock_lock);
43934 +}
43935 +
43936 +static __inline__ void pfkey_unlock_sock_list(void)
43937 +{
43938 + if (atomic_dec_and_test(&pfkey_sock_users))
43939 + wake_up(&pfkey_sock_wait);
43940 +}
43941 +#endif
43942 +
43943 +int
43944 +pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets)
43945 +{
43946 + struct socket_list *socket_listp,*prev;
43947 +
43948 + if(!socketp) {
43949 + KLIPS_PRINT(debug_pfkey,
43950 + "klips_debug:pfkey_list_remove_socket: "
43951 + "NULL socketp handed in, failed.\n");
43952 + return -EINVAL;
43953 + }
43954 +
43955 + if(!sockets) {
43956 + KLIPS_PRINT(debug_pfkey,
43957 + "klips_debug:pfkey_list_remove_socket: "
43958 + "NULL sockets list handed in, failed.\n");
43959 + return -EINVAL;
43960 + }
43961 +
43962 + socket_listp = *sockets;
43963 + prev = NULL;
43964 +
43965 + KLIPS_PRINT(debug_pfkey,
43966 + "klips_debug:pfkey_list_remove_socket: "
43967 + "removing sock=0p%p\n",
43968 + socketp);
43969 +
43970 + while(socket_listp != NULL) {
43971 + if(socket_listp->socketp == socketp) {
43972 + if(prev != NULL) {
43973 + prev->next = socket_listp->next;
43974 + } else {
43975 + *sockets = socket_listp->next;
43976 + }
43977 +
43978 + kfree((void*)socket_listp);
43979 +
43980 + break;
43981 + }
43982 + prev = socket_listp;
43983 + socket_listp = socket_listp->next;
43984 + }
43985 +
43986 + return 0;
43987 +}
43988 +
43989 +int
43990 +pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets)
43991 +{
43992 + struct socket_list *socket_listp;
43993 +
43994 + if(!socketp) {
43995 + KLIPS_PRINT(debug_pfkey,
43996 + "klips_debug:pfkey_list_insert_socket: "
43997 + "NULL socketp handed in, failed.\n");
43998 + return -EINVAL;
43999 + }
44000 +
44001 + if(!sockets) {
44002 + KLIPS_PRINT(debug_pfkey,
44003 + "klips_debug:pfkey_list_insert_socket: "
44004 + "NULL sockets list handed in, failed.\n");
44005 + return -EINVAL;
44006 + }
44007 +
44008 + KLIPS_PRINT(debug_pfkey,
44009 + "klips_debug:pfkey_list_insert_socket: "
44010 + "allocating %lu bytes for socketp=0p%p\n",
44011 + (unsigned long) sizeof(struct socket_list),
44012 + socketp);
44013 +
44014 + if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) {
44015 + KLIPS_PRINT(debug_pfkey,
44016 + "klips_debug:pfkey_list_insert_socket: "
44017 + "memory allocation error.\n");
44018 + return -ENOMEM;
44019 + }
44020 +
44021 + socket_listp->socketp = socketp;
44022 + socket_listp->next = *sockets;
44023 + *sockets = socket_listp;
44024 +
44025 + return 0;
44026 +}
44027 +
44028 +int
44029 +pfkey_list_remove_supported(struct ipsec_alg_supported *supported, struct supported_list **supported_list)
44030 +{
44031 + struct supported_list *supported_listp = *supported_list, *prev = NULL;
44032 +
44033 + if(!supported) {
44034 + KLIPS_PRINT(debug_pfkey,
44035 + "klips_debug:pfkey_list_remove_supported: "
44036 + "NULL supported handed in, failed.\n");
44037 + return -EINVAL;
44038 + }
44039 +
44040 + if(!supported_list) {
44041 + KLIPS_PRINT(debug_pfkey,
44042 + "klips_debug:pfkey_list_remove_supported: "
44043 + "NULL supported_list handed in, failed.\n");
44044 + return -EINVAL;
44045 + }
44046 +
44047 + KLIPS_PRINT(debug_pfkey,
44048 + "klips_debug:pfkey_list_remove_supported: "
44049 + "removing supported=0p%p\n",
44050 + supported);
44051 +
44052 + while(supported_listp != NULL) {
44053 + if(supported_listp->supportedp == supported) {
44054 + if(prev != NULL) {
44055 + prev->next = supported_listp->next;
44056 + } else {
44057 + *supported_list = supported_listp->next;
44058 + }
44059 +
44060 + kfree((void*)supported_listp);
44061 +
44062 + break;
44063 + }
44064 + prev = supported_listp;
44065 + supported_listp = supported_listp->next;
44066 + }
44067 +
44068 + return 0;
44069 +}
44070 +
44071 +int
44072 +pfkey_list_insert_supported(struct ipsec_alg_supported *supported
44073 + , struct supported_list **supported_list)
44074 +{
44075 + struct supported_list *supported_listp;
44076 +
44077 + if(!supported) {
44078 + KLIPS_PRINT(debug_pfkey,
44079 + "klips_debug:pfkey_list_insert_supported: "
44080 + "NULL supported handed in, failed.\n");
44081 + return -EINVAL;
44082 + }
44083 +
44084 + if(!supported_list) {
44085 + KLIPS_PRINT(debug_pfkey,
44086 + "klips_debug:pfkey_list_insert_supported: "
44087 + "NULL supported_list handed in, failed.\n");
44088 + return -EINVAL;
44089 + }
44090 +
44091 + KLIPS_PRINT(debug_pfkey,
44092 + "klips_debug:pfkey_list_insert_supported: "
44093 + "allocating %lu bytes for incoming, supported=0p%p, supported_list=0p%p\n",
44094 + (unsigned long) sizeof(struct supported_list),
44095 + supported,
44096 + supported_list);
44097 +
44098 + supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL);
44099 +
44100 + if(supported_listp == NULL)
44101 + {
44102 + KLIPS_PRINT(debug_pfkey,
44103 + "klips_debug:pfkey_list_insert_supported: "
44104 + "memory allocation error.\n");
44105 + return -ENOMEM;
44106 + }
44107 +
44108 + supported_listp->supportedp = supported;
44109 + supported_listp->next = *supported_list;
44110 + *supported_list = supported_listp;
44111 + KLIPS_PRINT(debug_pfkey,
44112 + "klips_debug:pfkey_list_insert_supported: "
44113 + "outgoing, supported=0p%p, supported_list=0p%p\n",
44114 + supported,
44115 + supported_list);
44116 +
44117 + return 0;
44118 +}
44119 +
44120 +#ifdef NET_26
44121 +DEBUG_NO_STATIC void
44122 +pfkey_insert_socket(struct sock *sk)
44123 +{
44124 + KLIPS_PRINT(debug_pfkey,
44125 + "klips_debug:pfkey_insert_socket: "
44126 + "sk=0p%p\n",
44127 + sk);
44128 + pfkey_sock_list_grab();
44129 + sk_add_node(sk, &pfkey_sock_list);
44130 + pfkey_sock_list_ungrab();
44131 +}
44132 +
44133 +DEBUG_NO_STATIC void
44134 +pfkey_remove_socket(struct sock *sk)
44135 +{
44136 + KLIPS_PRINT(debug_pfkey,
44137 + "klips_debug:pfkey_remove_socket: 0p%p\n", sk);
44138 + pfkey_sock_list_grab();
44139 + sk_del_node_init(sk);
44140 + pfkey_sock_list_ungrab();
44141 + return;
44142 +}
44143 +#else
44144 +
44145 +DEBUG_NO_STATIC void
44146 +pfkey_insert_socket(struct sock *sk)
44147 +{
44148 + KLIPS_PRINT(debug_pfkey,
44149 + "klips_debug:pfkey_insert_socket: "
44150 + "sk=0p%p\n",
44151 + sk);
44152 + cli();
44153 + sk->next=pfkey_sock_list;
44154 + pfkey_sock_list=sk;
44155 + sti();
44156 +}
44157 +DEBUG_NO_STATIC void
44158 +pfkey_remove_socket(struct sock *sk)
44159 +{
44160 + struct sock **s;
44161 +
44162 + s = NULL;
44163 + KLIPS_PRINT(debug_pfkey,
44164 + "klips_debug:pfkey_remove_socket: .\n");
44165 +
44166 + cli();
44167 + s=&pfkey_sock_list;
44168 +
44169 + while(*s!=NULL) {
44170 + if(*s==sk) {
44171 + *s=sk->next;
44172 + sk->next=NULL;
44173 + sti();
44174 + KLIPS_PRINT(debug_pfkey,
44175 + "klips_debug:pfkey_remove_socket: "
44176 + "succeeded.\n");
44177 + return;
44178 + }
44179 + s=&((*s)->next);
44180 + }
44181 + sti();
44182 +
44183 + KLIPS_PRINT(debug_pfkey,
44184 + "klips_debug:pfkey_remove_socket: "
44185 + "not found.\n");
44186 + return;
44187 +}
44188 +#endif
44189 +
44190 +DEBUG_NO_STATIC void
44191 +pfkey_destroy_socket(struct sock *sk)
44192 +{
44193 + struct sk_buff *skb;
44194 +
44195 + KLIPS_PRINT(debug_pfkey,
44196 + "klips_debug:pfkey_destroy_socket: 0p%p\n",sk);
44197 + pfkey_remove_socket(sk);
44198 +
44199 + KLIPS_PRINT(debug_pfkey,
44200 + "klips_debug:pfkey_destroy_socket: "
44201 + "pfkey_remove_socket called, sk=0p%p\n",sk);
44202 +
44203 + KLIPS_PRINT(debug_pfkey,
44204 + "klips_debug:pfkey_destroy_socket: "
44205 + "sk(0p%p)->(&0p%p)receive_queue.{next=0p%p,prev=0p%p}.\n",
44206 + sk,
44207 + &(sk->sk_receive_queue),
44208 + sk->sk_receive_queue.next,
44209 + sk->sk_receive_queue.prev);
44210 +
44211 + while(sk && ((skb=skb_dequeue(&(sk->sk_receive_queue)))!=NULL)) {
44212 +#ifdef CONFIG_KLIPS_DEBUG
44213 + if(debug_pfkey && sysctl_ipsec_debug_verbose) {
44214 + KLIPS_PRINT(debug_pfkey,
44215 + "klips_debug:pfkey_destroy_socket: "
44216 + "skb=0p%p dequeued.\n", skb);
44217 + printk(KERN_INFO "klips_debug:pfkey_destroy_socket: "
44218 + "pfkey_skb contents:");
44219 + printk(" next:0p%p", skb->next);
44220 + printk(" prev:0p%p", skb->prev);
44221 + printk(" sk:0p%p", skb->sk);
44222 + printk(" dev:0p%p", skb->dev);
44223 + if(skb->dev) {
44224 + if(skb->dev->name) {
44225 + printk(" dev->name:%s", skb->dev->name);
44226 + } else {
44227 + printk(" dev->name:NULL?");
44228 + }
44229 + } else {
44230 + printk(" dev:NULL");
44231 + }
44232 + printk(" h:0p%p", skb->h.raw);
44233 + printk(" nh:0p%p", skb->nh.raw);
44234 + printk(" mac:0p%p", skb->mac.raw);
44235 + printk(" dst:0p%p", skb->dst);
44236 + if(sysctl_ipsec_debug_verbose) {
44237 + int i;
44238 +
44239 + printk(" cb");
44240 + for(i=0; i<48; i++) {
44241 + printk(":%2x", skb->cb[i]);
44242 + }
44243 + }
44244 + printk(" len:%d", skb->len);
44245 + printk(" csum:%d", skb->csum);
44246 +#ifndef NETDEV_23
44247 + printk(" used:%d", skb->used);
44248 + printk(" is_clone:%d", skb->is_clone);
44249 +#endif /* NETDEV_23 */
44250 + printk(" cloned:%d", skb->cloned);
44251 + printk(" pkt_type:%d", skb->pkt_type);
44252 + printk(" ip_summed:%d", skb->ip_summed);
44253 + printk(" priority:%d", skb->priority);
44254 + printk(" protocol:%d", skb->protocol);
44255 +#ifdef HAVE_SOCK_SECURITY
44256 + printk(" security:%d", skb->security);
44257 +#endif
44258 + printk(" truesize:%d", skb->truesize);
44259 + printk(" head:0p%p", skb->head);
44260 + printk(" data:0p%p", skb->data);
44261 + printk(" tail:0p%p", skb->tail);
44262 + printk(" end:0p%p", skb->end);
44263 + if(sysctl_ipsec_debug_verbose) {
44264 + unsigned char* i;
44265 + printk(" data");
44266 + for(i = skb->head; i < skb->end; i++) {
44267 + printk(":%2x", (unsigned char)(*(i)));
44268 + }
44269 + }
44270 + printk(" destructor:0p%p", skb->destructor);
44271 + printk("\n");
44272 + }
44273 +#endif /* CONFIG_KLIPS_DEBUG */
44274 + KLIPS_PRINT(debug_pfkey,
44275 + "klips_debug:pfkey_destroy_socket: "
44276 + "skb=0p%p freed.\n",
44277 + skb);
44278 + ipsec_kfree_skb(skb);
44279 + }
44280 +
44281 +#ifdef NET_26
44282 + sock_set_flag(sk, SOCK_DEAD);
44283 +#else
44284 + sk->dead = 1;
44285 +#endif
44286 + sk_free(sk);
44287 +
44288 + KLIPS_PRINT(debug_pfkey,
44289 + "klips_debug:pfkey_destroy_socket: destroyed.\n");
44290 +}
44291 +
44292 +int
44293 +pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg)
44294 +{
44295 + int error = 0;
44296 + struct sk_buff * skb = NULL;
44297 + struct sock *sk;
44298 +
44299 + if(sock == NULL) {
44300 + KLIPS_PRINT(debug_pfkey,
44301 + "klips_debug:pfkey_upmsg: "
44302 + "NULL socket passed in.\n");
44303 + return -EINVAL;
44304 + }
44305 +
44306 + if(pfkey_msg == NULL) {
44307 + KLIPS_PRINT(debug_pfkey,
44308 + "klips_debug:pfkey_upmsg: "
44309 + "NULL pfkey_msg passed in.\n");
44310 + return -EINVAL;
44311 + }
44312 +
44313 + sk = sock->sk;
44314 +
44315 + if(sk == NULL) {
44316 + KLIPS_PRINT(debug_pfkey,
44317 + "klips_debug:pfkey_upmsg: "
44318 + "NULL sock passed in.\n");
44319 + return -EINVAL;
44320 + }
44321 +
44322 + KLIPS_PRINT(debug_pfkey,
44323 + "klips_debug:pfkey_upmsg: "
44324 + "allocating %d bytes...\n",
44325 + (int)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN));
44326 + if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) {
44327 + KLIPS_PRINT(debug_pfkey,
44328 + "klips_debug:pfkey_upmsg: "
44329 + "no buffers left to send up a message.\n");
44330 + return -ENOBUFS;
44331 + }
44332 + KLIPS_PRINT(debug_pfkey,
44333 + "klips_debug:pfkey_upmsg: "
44334 + "...allocated at 0p%p.\n",
44335 + skb);
44336 +
44337 + skb->dev = NULL;
44338 +
44339 + if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
44340 + printk(KERN_WARNING "klips_error:pfkey_upmsg: "
44341 + "tried to skb_put %ld, %d available. This should never happen, please report.\n",
44342 + (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN,
44343 + skb_tailroom(skb));
44344 + ipsec_kfree_skb(skb);
44345 + return -ENOBUFS;
44346 + }
44347 + skb->h.raw = skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
44348 + memcpy(skb->h.raw, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
44349 +
44350 + if((error = sock_queue_rcv_skb(sk, skb)) < 0) {
44351 + skb->sk=NULL;
44352 + KLIPS_PRINT(debug_pfkey,
44353 + "klips_debug:pfkey_upmsg: "
44354 + "error=%d calling sock_queue_rcv_skb with skb=0p%p.\n",
44355 + error,
44356 + skb);
44357 + ipsec_kfree_skb(skb);
44358 + return error;
44359 + }
44360 + return error;
44361 +}
44362 +
44363 +#ifdef NET_26_12_SKALLOC
44364 +static struct proto key_proto = {
44365 + .name = "KEY",
44366 + .owner = THIS_MODULE,
44367 + .obj_size = sizeof(struct sock),
44368 +
44369 +};
44370 +#endif
44371 +
44372 +DEBUG_NO_STATIC int
44373 +pfkey_create(struct socket *sock, int protocol)
44374 +{
44375 + struct sock *sk;
44376 +
44377 + if(sock == NULL) {
44378 + KLIPS_PRINT(debug_pfkey,
44379 + "klips_debug:pfkey_create: "
44380 + "socket NULL.\n");
44381 + return -EINVAL;
44382 + }
44383 +
44384 + KLIPS_PRINT(debug_pfkey,
44385 + "klips_debug:pfkey_create: "
44386 + "sock=0p%p type:%d state:%d flags:%ld protocol:%d\n",
44387 + sock,
44388 + sock->type,
44389 + (unsigned int)(sock->state),
44390 + sock->flags, protocol);
44391 +
44392 + if(sock->type != SOCK_RAW) {
44393 + KLIPS_PRINT(debug_pfkey,
44394 + "klips_debug:pfkey_create: "
44395 + "only SOCK_RAW supported.\n");
44396 + return -ESOCKTNOSUPPORT;
44397 + }
44398 +
44399 + if(protocol != PF_KEY_V2) {
44400 + KLIPS_PRINT(debug_pfkey,
44401 + "klips_debug:pfkey_create: "
44402 + "protocol not PF_KEY_V2.\n");
44403 + return -EPROTONOSUPPORT;
44404 + }
44405 +
44406 + if((current->uid != 0)) {
44407 + KLIPS_PRINT(debug_pfkey,
44408 + "klips_debug:pfkey_create: "
44409 + "must be root to open pfkey sockets.\n");
44410 + return -EACCES;
44411 + }
44412 +
44413 + sock->state = SS_UNCONNECTED;
44414 +
44415 + KLIPS_INC_USE;
44416 +
44417 +#ifdef NET_26
44418 +#ifdef NET_26_12_SKALLOC
44419 + sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1);
44420 +#else
44421 + sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1, NULL);
44422 +#endif
44423 +#else
44424 + /* 2.4 interface */
44425 + sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1);
44426 +#endif
44427 +
44428 + if(sk == NULL)
44429 + {
44430 + KLIPS_PRINT(debug_pfkey,
44431 + "klips_debug:pfkey_create: "
44432 + "Out of memory trying to allocate.\n");
44433 + KLIPS_DEC_USE;
44434 + return -ENOMEM;
44435 + }
44436 +
44437 + sock_init_data(sock, sk);
44438 +
44439 + sk->sk_destruct = NULL;
44440 + sk->sk_reuse = 1;
44441 + sock->ops = &pfkey_ops;
44442 +
44443 + sk->sk_family = PF_KEY;
44444 +/* sk->num = protocol; */
44445 + sk->sk_protocol = protocol;
44446 + key_pid(sk) = current->pid;
44447 + KLIPS_PRINT(debug_pfkey,
44448 + "klips_debug:pfkey_create: "
44449 + "sock->fasync_list=0p%p sk->sleep=0p%p.\n",
44450 + sock->fasync_list,
44451 + sk->sk_sleep);
44452 +
44453 + pfkey_insert_socket(sk);
44454 + pfkey_list_insert_socket(sock, &pfkey_open_sockets);
44455 +
44456 + KLIPS_PRINT(debug_pfkey,
44457 + "klips_debug:pfkey_create: "
44458 + "Socket sock=0p%p sk=0p%p initialised.\n", sock, sk);
44459 + return 0;
44460 +}
44461 +
44462 +DEBUG_NO_STATIC int
44463 +#ifdef NETDEV_23
44464 +pfkey_release(struct socket *sock)
44465 +#else /* NETDEV_23 */
44466 +pfkey_release(struct socket *sock, struct socket *peersock)
44467 +#endif /* NETDEV_23 */
44468 +{
44469 + struct sock *sk;
44470 + int i;
44471 +
44472 + if(sock==NULL) {
44473 + KLIPS_PRINT(debug_pfkey,
44474 + "klips_debug:pfkey_release: "
44475 + "No socket attached.\n");
44476 + return 0; /* -EINVAL; */
44477 + }
44478 +
44479 + sk=sock->sk;
44480 +
44481 + /* May not have data attached */
44482 + if(sk==NULL) {
44483 + KLIPS_PRINT(debug_pfkey,
44484 + "klips_debug:pfkey_release: "
44485 + "No sk attached to sock=0p%p.\n", sock);
44486 + return 0; /* -EINVAL; */
44487 + }
44488 +
44489 + KLIPS_PRINT(debug_pfkey,
44490 + "klips_debug:pfkey_release: "
44491 + "sock=0p%p sk=0p%p\n", sock, sk);
44492 +
44493 + if(sock_flag(sk, SOCK_DEAD))
44494 + if(sk->sk_state_change) {
44495 + sk->sk_state_change(sk);
44496 + }
44497 +
44498 + sock->sk = NULL;
44499 +
44500 + /* Try to flush out this socket. Throw out buffers at least */
44501 + pfkey_destroy_socket(sk);
44502 + pfkey_list_remove_socket(sock, &pfkey_open_sockets);
44503 + for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
44504 + pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i]));
44505 + }
44506 +
44507 + KLIPS_DEC_USE;
44508 + KLIPS_PRINT(debug_pfkey,
44509 + "klips_debug:pfkey_release: "
44510 + "succeeded.\n");
44511 +
44512 + return 0;
44513 +}
44514 +
44515 +DEBUG_NO_STATIC int
44516 +pfkey_shutdown(struct socket *sock, int mode)
44517 +{
44518 + struct sock *sk;
44519 +
44520 + if(sock == NULL) {
44521 + KLIPS_PRINT(debug_pfkey,
44522 + "klips_debug:pfkey_shutdown: "
44523 + "NULL socket passed in.\n");
44524 + return -EINVAL;
44525 + }
44526 +
44527 + sk=sock->sk;
44528 +
44529 + if(sk == NULL) {
44530 + KLIPS_PRINT(debug_pfkey,
44531 + "klips_debug:pfkey_shutdown: "
44532 + "No sock attached to socket.\n");
44533 + return -EINVAL;
44534 + }
44535 +
44536 + KLIPS_PRINT(debug_pfkey,
44537 + "klips_debug:pfkey_shutdown: "
44538 + "mode=%x.\n", mode);
44539 + mode++;
44540 +
44541 + if(mode&SEND_SHUTDOWN) {
44542 + sk->sk_shutdown|=SEND_SHUTDOWN;
44543 + sk->sk_state_change(sk);
44544 + }
44545 +
44546 + if(mode&RCV_SHUTDOWN) {
44547 + sk->sk_shutdown|=RCV_SHUTDOWN;
44548 + sk->sk_state_change(sk);
44549 + }
44550 + return 0;
44551 +}
44552 +
44553 +/*
44554 + * Send PF_KEY data down.
44555 + */
44556 +
44557 +DEBUG_NO_STATIC int
44558 +#ifdef NET_26
44559 +pfkey_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
44560 +#else
44561 +pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
44562 +#endif
44563 +{
44564 + struct sock *sk;
44565 + int error = 0;
44566 + struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL;
44567 +
44568 + if(sock == NULL) {
44569 + KLIPS_PRINT(debug_pfkey,
44570 + "klips_debug:pfkey_sendmsg: "
44571 + "Null socket passed in.\n");
44572 + SENDERR(EINVAL);
44573 + }
44574 +
44575 + sk = sock->sk;
44576 +
44577 + if(sk == NULL) {
44578 + KLIPS_PRINT(debug_pfkey,
44579 + "klips_debug:pfkey_sendmsg: "
44580 + "Null sock passed in.\n");
44581 + SENDERR(EINVAL);
44582 + }
44583 +
44584 + if(msg == NULL) {
44585 + KLIPS_PRINT(debug_pfkey,
44586 + "klips_debug:pfkey_sendmsg: "
44587 + "Null msghdr passed in.\n");
44588 + SENDERR(EINVAL);
44589 + }
44590 +
44591 + KLIPS_PRINT(debug_pfkey,
44592 + "klips_debug:pfkey_sendmsg: .\n");
44593 + if(sk->sk_err) {
44594 + error = sock_error(sk);
44595 + KLIPS_PRINT(debug_pfkey,
44596 + "klips_debug:pfkey_sendmsg: "
44597 + "sk->err is non-zero, returns %d.\n",
44598 + error);
44599 + SENDERR(-error);
44600 + }
44601 +
44602 + if((current->uid != 0)) {
44603 + KLIPS_PRINT(debug_pfkey,
44604 + "klips_debug:pfkey_sendmsg: "
44605 + "must be root to send messages to pfkey sockets.\n");
44606 + SENDERR(EACCES);
44607 + }
44608 +
44609 + if(msg->msg_control)
44610 + {
44611 + KLIPS_PRINT(debug_pfkey,
44612 + "klips_debug:pfkey_sendmsg: "
44613 + "can't set flags or set msg_control.\n");
44614 + SENDERR(EINVAL);
44615 + }
44616 +
44617 + if(sk->sk_shutdown & SEND_SHUTDOWN) {
44618 + KLIPS_PRINT(debug_pfkey,
44619 + "klips_debug:pfkey_sendmsg: "
44620 + "shutdown.\n");
44621 + send_sig(SIGPIPE, current, 0);
44622 + SENDERR(EPIPE);
44623 + }
44624 +
44625 + if(len < sizeof(struct sadb_msg)) {
44626 + KLIPS_PRINT(debug_pfkey,
44627 + "klips_debug:pfkey_sendmsg: "
44628 + "bogus msg len of %d, too small.\n", (int)len);
44629 + SENDERR(EMSGSIZE);
44630 + }
44631 +
44632 + KLIPS_PRINT(debug_pfkey,
44633 + "klips_debug:pfkey_sendmsg: "
44634 + "allocating %d bytes for downward message.\n",
44635 + (int)len);
44636 + if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) {
44637 + KLIPS_PRINT(debug_pfkey,
44638 + "klips_debug:pfkey_sendmsg: "
44639 + "memory allocation error.\n");
44640 + SENDERR(ENOBUFS);
44641 + }
44642 +
44643 + memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len);
44644 +
44645 + if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
44646 + KLIPS_PRINT(1 || debug_pfkey,
44647 + "klips_debug:pfkey_sendmsg: "
44648 + "not PF_KEY_V2 msg, found %d, should be %d.\n",
44649 + pfkey_msg->sadb_msg_version,
44650 + PF_KEY_V2);
44651 + kfree((void*)pfkey_msg);
44652 + return -EINVAL;
44653 + }
44654 +
44655 + if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
44656 + KLIPS_PRINT(debug_pfkey,
44657 + "klips_debug:pfkey_sendmsg: "
44658 + "bogus msg len of %d, not %d byte aligned.\n",
44659 + (int)len, (int)IPSEC_PFKEYv2_ALIGN);
44660 + SENDERR(EMSGSIZE);
44661 + }
44662 +
44663 +#if 0
44664 + /* This check is questionable, since a downward message could be
44665 + the result of an ACQUIRE either from kernel (PID==0) or
44666 + userspace (some other PID). */
44667 + /* check PID */
44668 + if(pfkey_msg->sadb_msg_pid != current->pid) {
44669 + KLIPS_PRINT(debug_pfkey,
44670 + "klips_debug:pfkey_sendmsg: "
44671 + "pid (%d) does not equal sending process pid (%d).\n",
44672 + pfkey_msg->sadb_msg_pid, current->pid);
44673 + SENDERR(EINVAL);
44674 + }
44675 +#endif
44676 +
44677 + if(pfkey_msg->sadb_msg_reserved) {
44678 + KLIPS_PRINT(debug_pfkey,
44679 + "klips_debug:pfkey_sendmsg: "
44680 + "reserved field must be zero, set to %d.\n",
44681 + pfkey_msg->sadb_msg_reserved);
44682 + SENDERR(EINVAL);
44683 + }
44684 +
44685 + if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){
44686 + KLIPS_PRINT(debug_pfkey,
44687 + "klips_debug:pfkey_sendmsg: "
44688 + "msg type too large or small:%d.\n",
44689 + pfkey_msg->sadb_msg_type);
44690 + SENDERR(EINVAL);
44691 + }
44692 +
44693 + KLIPS_PRINT(debug_pfkey,
44694 + "klips_debug:pfkey_sendmsg: "
44695 + "msg sent for parsing.\n");
44696 +
44697 + if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) {
44698 + struct socket_list *pfkey_socketsp;
44699 +
44700 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
44701 + "pfkey_msg_parse returns %d.\n",
44702 + error);
44703 +
44704 + if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) {
44705 + KLIPS_PRINT(debug_pfkey,
44706 + "klips_debug:pfkey_sendmsg: "
44707 + "memory allocation error.\n");
44708 + SENDERR(ENOBUFS);
44709 + }
44710 + memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg));
44711 + pfkey_reply->sadb_msg_errno = -error;
44712 + pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
44713 +
44714 + for(pfkey_socketsp = pfkey_open_sockets;
44715 + pfkey_socketsp;
44716 + pfkey_socketsp = pfkey_socketsp->next) {
44717 + int error_upmsg = 0;
44718 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
44719 + "sending up error=%d message=0p%p to socket=0p%p.\n",
44720 + error,
44721 + pfkey_reply,
44722 + pfkey_socketsp->socketp);
44723 + if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
44724 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
44725 + "sending up error message to socket=0p%p failed with error=%d.\n",
44726 + pfkey_socketsp->socketp,
44727 + error_upmsg);
44728 + /* pfkey_msg_free(&pfkey_reply); */
44729 + /* SENDERR(-error); */
44730 + }
44731 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
44732 + "sending up error message to socket=0p%p succeeded.\n",
44733 + pfkey_socketsp->socketp);
44734 + }
44735 +
44736 + pfkey_msg_free(&pfkey_reply);
44737 +
44738 + SENDERR(-error);
44739 + }
44740 +
44741 + errlab:
44742 + if (pfkey_msg) {
44743 + kfree((void*)pfkey_msg);
44744 + }
44745 +
44746 + if(error) {
44747 + return error;
44748 + } else {
44749 + return len;
44750 + }
44751 +}
44752 +
44753 +/*
44754 + * Receive PF_KEY data up.
44755 + */
44756 +
44757 +DEBUG_NO_STATIC int
44758 +#ifdef NET_26
44759 +pfkey_recvmsg(struct kiocb *kiocb
44760 + , struct socket *sock
44761 + , struct msghdr *msg
44762 + , size_t size
44763 + , int flags)
44764 +#else
44765 +pfkey_recvmsg(struct socket *sock
44766 + , struct msghdr *msg
44767 + , int size, int flags
44768 + , struct scm_cookie *scm)
44769 +#endif
44770 +{
44771 + struct sock *sk;
44772 + int noblock = flags & MSG_DONTWAIT;
44773 + struct sk_buff *skb;
44774 + int error;
44775 +
44776 + if(sock == NULL) {
44777 + KLIPS_PRINT(debug_pfkey,
44778 + "klips_debug:pfkey_recvmsg: "
44779 + "Null socket passed in.\n");
44780 + return -EINVAL;
44781 + }
44782 +
44783 + sk = sock->sk;
44784 +
44785 + if(sk == NULL) {
44786 + KLIPS_PRINT(debug_pfkey,
44787 + "klips_debug:pfkey_recvmsg: "
44788 + "Null sock passed in for sock=0p%p.\n", sock);
44789 + return -EINVAL;
44790 + }
44791 +
44792 + if(msg == NULL) {
44793 + KLIPS_PRINT(debug_pfkey,
44794 + "klips_debug:pfkey_recvmsg: "
44795 + "Null msghdr passed in for sock=0p%p, sk=0p%p.\n",
44796 + sock, sk);
44797 + return -EINVAL;
44798 + }
44799 +
44800 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
44801 + "klips_debug:pfkey_recvmsg: sock=0p%p sk=0p%p msg=0p%p size=%d.\n",
44802 + sock, sk, msg, (int)size);
44803 + if(flags & ~MSG_PEEK) {
44804 + KLIPS_PRINT(debug_pfkey,
44805 + "klips_debug:pfkey_sendmsg: "
44806 + "flags (%d) other than MSG_PEEK not supported.\n",
44807 + flags);
44808 + return -EOPNOTSUPP;
44809 + }
44810 +
44811 + msg->msg_namelen = 0; /* sizeof(*ska); */
44812 +
44813 + if(sk->sk_err) {
44814 + KLIPS_PRINT(debug_pfkey,
44815 + "klips_debug:pfkey_sendmsg: "
44816 + "sk->sk_err=%d.\n", sk->sk_err);
44817 + return sock_error(sk);
44818 + }
44819 +
44820 + if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) {
44821 + return error;
44822 + }
44823 +
44824 + if(size > skb->len) {
44825 + size = skb->len;
44826 + }
44827 + else if(size <skb->len) {
44828 + msg->msg_flags |= MSG_TRUNC;
44829 + }
44830 +
44831 + skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
44832 +#ifdef HAVE_TSTAMP
44833 + sk->sk_stamp.tv_sec = skb->tstamp.off_sec;
44834 + sk->sk_stamp.tv_usec = skb->tstamp.off_usec;
44835 +#else
44836 + sk->sk_stamp=skb->stamp;
44837 +#endif
44838 +
44839 + skb_free_datagram(sk, skb);
44840 + return size;
44841 +}
44842 +
44843 +#ifdef CONFIG_PROC_FS
44844 +#ifndef PROC_FS_2325
44845 +DEBUG_NO_STATIC
44846 +#endif /* PROC_FS_2325 */
44847 +int
44848 +pfkey_get_info(char *buffer, char **start, off_t offset, int length
44849 +#ifndef PROC_NO_DUMMY
44850 +, int dummy
44851 +#endif /* !PROC_NO_DUMMY */
44852 +)
44853 +{
44854 + const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */
44855 +#ifdef NET_26
44856 + struct hlist_node *node;
44857 +#endif
44858 + off_t begin=0;
44859 + int len=0;
44860 + struct sock *sk;
44861 +
44862 +#ifdef CONFIG_KLIPS_DEBUG
44863 + if(!sysctl_ipsec_debug_verbose) {
44864 +#endif /* CONFIG_KLIPS_DEBUG */
44865 + len += ipsec_snprintf(buffer, length,
44866 + " sock pid socket next prev e n p sndbf Flags Type St\n");
44867 +#ifdef CONFIG_KLIPS_DEBUG
44868 + } else {
44869 + len += ipsec_snprintf(buffer, length,
44870 + " sock pid d sleep socket next prev e r z n p sndbf stamp Flags Type St\n");
44871 + }
44872 +#endif /* CONFIG_KLIPS_DEBUG */
44873 +
44874 + sk_for_each(sk, node, &pfkey_sock_list) {
44875 +
44876 +#ifdef CONFIG_KLIPS_DEBUG
44877 + if(!sysctl_ipsec_debug_verbose) {
44878 +#endif /* CONFIG_KLIPS_DEBUG */
44879 + len += ipsec_snprintf(buffer+len, length-len,
44880 + "%8p %5d %8p %d %d %5d %08lX %8X %2X\n",
44881 + sk,
44882 + key_pid(sk),
44883 + sk->sk_socket,
44884 + sk->sk_err,
44885 + sk->sk_protocol,
44886 + sk->sk_sndbuf,
44887 + sk->sk_socket->flags,
44888 + sk->sk_socket->type,
44889 + sk->sk_socket->state);
44890 +#ifdef CONFIG_KLIPS_DEBUG
44891 + } else {
44892 + len += ipsec_snprintf(buffer+len, length-len,
44893 + "%8p %5d %d %8p %8p %d %d %d %d %5d %d.%06d %08lX %8X %2X\n",
44894 + sk,
44895 + key_pid(sk),
44896 + sock_flag(sk, SOCK_DEAD),
44897 + sk->sk_sleep,
44898 + sk->sk_socket,
44899 + sk->sk_err,
44900 + sk->sk_reuse,
44901 +#ifdef HAVE_SOCK_ZAPPED
44902 + sock_flag(sk, SOCK_ZAPPED),
44903 +#else
44904 + sk->sk_zapped,
44905 +#endif
44906 + sk->sk_protocol,
44907 + sk->sk_sndbuf,
44908 + (unsigned int)sk->sk_stamp.tv_sec,
44909 + (unsigned int)sk->sk_stamp.tv_usec,
44910 + sk->sk_socket->flags,
44911 + sk->sk_socket->type,
44912 + sk->sk_socket->state);
44913 + }
44914 +#endif /* CONFIG_KLIPS_DEBUG */
44915 +
44916 + if (len >= max_content) {
44917 + /* we've done all that can fit -- stop loop */
44918 + len = max_content; /* truncate crap */
44919 + break;
44920 + } else {
44921 + const off_t pos = begin + len; /* file position of end of what we've generated */
44922 +
44923 + if (pos <= offset) {
44924 + /* all is before first interesting character:
44925 + * discard, but note where we are.
44926 + */
44927 + len = 0;
44928 + begin = pos;
44929 + }
44930 + }
44931 + }
44932 +
44933 + *start = buffer + (offset - begin); /* Start of wanted data */
44934 + return len - (offset - begin);
44935 +}
44936 +
44937 +#ifndef PROC_FS_2325
44938 +DEBUG_NO_STATIC
44939 +#endif /* PROC_FS_2325 */
44940 +int
44941 +pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length
44942 +#ifndef PROC_NO_DUMMY
44943 +, int dummy
44944 +#endif /* !PROC_NO_DUMMY */
44945 +)
44946 +{
44947 + /* limit of useful snprintf output */
44948 + const int max_content = length > 0? length-1 : 0;
44949 + off_t begin=0;
44950 + int len=0;
44951 + int satype;
44952 + struct supported_list *ps;
44953 +
44954 + len += ipsec_snprintf(buffer, length,
44955 + "satype exttype alg_id ivlen minbits maxbits name\n");
44956 +
44957 + for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
44958 + ps = pfkey_supported_list[satype];
44959 + while(ps) {
44960 + struct ipsec_alg_supported *alg = ps->supportedp;
44961 + unsigned char *n = alg->ias_name;
44962 + if(n == NULL) n = "unknown";
44963 +
44964 + len += ipsec_snprintf(buffer+len, length-len,
44965 + " %2d %2d %2d %3d %3d %3d %20s\n",
44966 + satype,
44967 + alg->ias_exttype,
44968 + alg->ias_id,
44969 + alg->ias_ivlen,
44970 + alg->ias_keyminbits,
44971 + alg->ias_keymaxbits,
44972 + n);
44973 +
44974 + if (len >= max_content) {
44975 + /* we've done all that can fit -- stop loop */
44976 + len = max_content; /* truncate crap */
44977 + break;
44978 + } else {
44979 + const off_t pos = begin + len; /* file position of end of what we've generated */
44980 +
44981 + if (pos <= offset) {
44982 + /* all is before first interesting character:
44983 + * discard, but note where we are.
44984 + */
44985 + len = 0;
44986 + begin = pos;
44987 + }
44988 + }
44989 +
44990 + ps = ps->next;
44991 + }
44992 + }
44993 + *start = buffer + (offset - begin); /* Start of wanted data */
44994 + return len - (offset - begin);
44995 +}
44996 +
44997 +#ifndef PROC_FS_2325
44998 +DEBUG_NO_STATIC
44999 +#endif /* PROC_FS_2325 */
45000 +int
45001 +pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length
45002 +#ifndef PROC_NO_DUMMY
45003 +, int dummy
45004 +#endif /* !PROC_NO_DUMMY */
45005 +)
45006 +{
45007 + const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */
45008 + off_t begin=0;
45009 + int len=0;
45010 + int satype;
45011 + struct socket_list *pfkey_sockets;
45012 +
45013 + len += ipsec_snprintf(buffer, length,
45014 + "satype socket pid sk\n");
45015 +
45016 + for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
45017 + pfkey_sockets = pfkey_registered_sockets[satype];
45018 + while(pfkey_sockets) {
45019 + len += ipsec_snprintf(buffer+len, length-len,
45020 + " %2d %8p %5d %8p\n",
45021 + satype,
45022 + pfkey_sockets->socketp,
45023 + key_pid(pfkey_sockets->socketp->sk),
45024 + pfkey_sockets->socketp->sk);
45025 +
45026 + if (len >= max_content) {
45027 + /* we've done all that can fit -- stop loop (could stop two) */
45028 + len = max_content; /* truncate crap */
45029 + break;
45030 + } else {
45031 + const off_t pos = begin + len; /* file position of end of what we've generated */
45032 +
45033 + if (pos <= offset) {
45034 + /* all is before first interesting character:
45035 + * discard, but note where we are.
45036 + */
45037 + len = 0;
45038 + begin = pos;
45039 + }
45040 + }
45041 +
45042 + pfkey_sockets = pfkey_sockets->next;
45043 + }
45044 + }
45045 + *start = buffer + (offset - begin); /* Start of wanted data */
45046 + return len - (offset - begin);
45047 +}
45048 +
45049 +#ifndef PROC_FS_2325
45050 +struct proc_dir_entry proc_net_pfkey =
45051 +{
45052 + 0,
45053 + 6, "pf_key",
45054 + S_IFREG | S_IRUGO, 1, 0, 0,
45055 + 0, &proc_net_inode_operations,
45056 + pfkey_get_info
45057 +};
45058 +struct proc_dir_entry proc_net_pfkey_supported =
45059 +{
45060 + 0,
45061 + 16, "pf_key_supported",
45062 + S_IFREG | S_IRUGO, 1, 0, 0,
45063 + 0, &proc_net_inode_operations,
45064 + pfkey_supported_get_info
45065 +};
45066 +struct proc_dir_entry proc_net_pfkey_registered =
45067 +{
45068 + 0,
45069 + 17, "pf_key_registered",
45070 + S_IFREG | S_IRUGO, 1, 0, 0,
45071 + 0, &proc_net_inode_operations,
45072 + pfkey_registered_get_info
45073 +};
45074 +#endif /* !PROC_FS_2325 */
45075 +#endif /* CONFIG_PROC_FS */
45076 +
45077 +DEBUG_NO_STATIC int
45078 +supported_add_all(int satype, struct ipsec_alg_supported supported[], int size)
45079 +{
45080 + int i;
45081 + int error = 0;
45082 +
45083 + KLIPS_PRINT(debug_pfkey,
45084 + "klips_debug:init_pfkey: "
45085 + "sizeof(supported_init_<satype=%d>)[%d]/sizeof(struct ipsec_alg_supported)[%d]=%d.\n",
45086 + satype,
45087 + size,
45088 + (int)sizeof(struct ipsec_alg_supported),
45089 + (int)(size/sizeof(struct ipsec_alg_supported)));
45090 +
45091 + for(i = 0; i < size / sizeof(struct ipsec_alg_supported); i++) {
45092 +
45093 + unsigned char *n = supported[i].ias_name;
45094 + if(n == NULL) n="unknown";
45095 +
45096 + KLIPS_PRINT(debug_pfkey,
45097 + "klips_debug:init_pfkey: "
45098 + "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d name=%s.\n",
45099 + i,
45100 + satype,
45101 + supported[i].ias_exttype,
45102 + supported[i].ias_id,
45103 + supported[i].ias_ivlen,
45104 + supported[i].ias_keyminbits,
45105 + supported[i].ias_keymaxbits,
45106 + n);
45107 +
45108 + error |= pfkey_list_insert_supported(&(supported[i]),
45109 + &(pfkey_supported_list[satype]));
45110 + }
45111 + return error;
45112 +}
45113 +
45114 +DEBUG_NO_STATIC int
45115 +supported_remove_all(int satype)
45116 +{
45117 + int error = 0;
45118 + struct ipsec_alg_supported*supportedp;
45119 +
45120 + while(pfkey_supported_list[satype]) {
45121 + unsigned char *n;
45122 + supportedp = pfkey_supported_list[satype]->supportedp;
45123 +
45124 + n = supportedp->ias_name;
45125 + if(n == NULL) n="unknown";
45126 +
45127 + KLIPS_PRINT(debug_pfkey,
45128 + "klips_debug:init_pfkey: "
45129 + "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d name=%s.\n",
45130 + satype,
45131 + supportedp->ias_exttype,
45132 + supportedp->ias_id,
45133 + supportedp->ias_ivlen,
45134 + supportedp->ias_keyminbits,
45135 + supportedp->ias_keymaxbits, n);
45136 +
45137 + error |= pfkey_list_remove_supported(supportedp,
45138 + &(pfkey_supported_list[satype]));
45139 + }
45140 + return error;
45141 +}
45142 +
45143 +int
45144 +pfkey_init(void)
45145 +{
45146 + int error = 0;
45147 + int i;
45148 +
45149 + static struct ipsec_alg_supported supported_init_ah[] = {
45150 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
45151 + {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
45152 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
45153 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
45154 + {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160}
45155 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
45156 + };
45157 + static struct ipsec_alg_supported supported_init_esp[] = {
45158 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
45159 + {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
45160 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
45161 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
45162 + {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160},
45163 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
45164 +#ifdef CONFIG_KLIPS_ENC_3DES
45165 + {SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_3DESCBC, 64, 168, 168},
45166 +#endif /* CONFIG_KLIPS_ENC_3DES */
45167 + };
45168 + static struct ipsec_alg_supported supported_init_ipip[] = {
45169 + {SADB_EXT_SUPPORTED_ENCRYPT, K_SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32}
45170 +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
45171 + , {SADB_EXT_SUPPORTED_ENCRYPT, K_SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32}
45172 + , {SADB_EXT_SUPPORTED_ENCRYPT, K_SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128}
45173 + , {SADB_EXT_SUPPORTED_ENCRYPT, K_SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128}
45174 +#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
45175 + };
45176 +#ifdef CONFIG_KLIPS_IPCOMP
45177 + static struct ipsec_alg_supported supported_init_ipcomp[] = {
45178 + {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1}
45179 + };
45180 +#endif /* CONFIG_KLIPS_IPCOMP */
45181 +
45182 +#if 0
45183 + printk(KERN_INFO
45184 + "klips_info:pfkey_init: "
45185 + "FreeS/WAN: initialising PF_KEYv2 domain sockets.\n");
45186 +#endif
45187 +
45188 + for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
45189 + pfkey_registered_sockets[i] = NULL;
45190 + pfkey_supported_list[i] = NULL;
45191 + }
45192 +
45193 + error |= supported_add_all(SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah));
45194 + error |= supported_add_all(SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp));
45195 +#ifdef CONFIG_KLIPS_IPCOMP
45196 + error |= supported_add_all(SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp));
45197 +#endif /* CONFIG_KLIPS_IPCOMP */
45198 + error |= supported_add_all(SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip));
45199 +
45200 + error |= sock_register(&pfkey_family_ops);
45201 +
45202 +#ifdef CONFIG_PROC_FS
45203 +# ifndef PROC_FS_2325
45204 +# ifdef PROC_FS_21
45205 + error |= proc_register(proc_net, &proc_net_pfkey);
45206 + error |= proc_register(proc_net, &proc_net_pfkey_supported);
45207 + error |= proc_register(proc_net, &proc_net_pfkey_registered);
45208 +# else /* PROC_FS_21 */
45209 + error |= proc_register_dynamic(&proc_net, &proc_net_pfkey);
45210 + error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_supported);
45211 + error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_registered);
45212 +# endif /* PROC_FS_21 */
45213 +# else /* !PROC_FS_2325 */
45214 + proc_net_create ("pf_key", 0, pfkey_get_info);
45215 + proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info);
45216 + proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info);
45217 +# endif /* !PROC_FS_2325 */
45218 +#endif /* CONFIG_PROC_FS */
45219 +
45220 + return error;
45221 +}
45222 +
45223 +int
45224 +pfkey_cleanup(void)
45225 +{
45226 + int error = 0;
45227 +
45228 + printk(KERN_INFO "klips_info:pfkey_cleanup: "
45229 + "shutting down PF_KEY domain sockets.\n");
45230 + sock_unregister(PF_KEY);
45231 +
45232 + error |= supported_remove_all(SADB_SATYPE_AH);
45233 + error |= supported_remove_all(SADB_SATYPE_ESP);
45234 +#ifdef CONFIG_KLIPS_IPCOMP
45235 + error |= supported_remove_all(SADB_X_SATYPE_COMP);
45236 +#endif /* CONFIG_KLIPS_IPCOMP */
45237 + error |= supported_remove_all(SADB_X_SATYPE_IPIP);
45238 +
45239 +#ifdef CONFIG_PROC_FS
45240 +# ifndef PROC_FS_2325
45241 + if (proc_net_unregister(proc_net_pfkey.low_ino) != 0)
45242 + printk("klips_debug:pfkey_cleanup: "
45243 + "cannot unregister /proc/net/pf_key\n");
45244 + if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0)
45245 + printk("klips_debug:pfkey_cleanup: "
45246 + "cannot unregister /proc/net/pf_key_supported\n");
45247 + if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0)
45248 + printk("klips_debug:pfkey_cleanup: "
45249 + "cannot unregister /proc/net/pf_key_registered\n");
45250 +# else /* !PROC_FS_2325 */
45251 + proc_net_remove ("pf_key");
45252 + proc_net_remove ("pf_key_supported");
45253 + proc_net_remove ("pf_key_registered");
45254 +# endif /* !PROC_FS_2325 */
45255 +#endif /* CONFIG_PROC_FS */
45256 +
45257 + /* other module unloading cleanup happens here */
45258 + return error;
45259 +}
45260 +
45261 +#ifdef MODULE
45262 +#if 0
45263 +int
45264 +init_module(void)
45265 +{
45266 + pfkey_init();
45267 + return 0;
45268 +}
45269 +
45270 +void
45271 +cleanup_module(void)
45272 +{
45273 + pfkey_cleanup();
45274 +}
45275 +#endif /* 0 */
45276 +#else /* MODULE */
45277 +struct net_protocol;
45278 +void pfkey_proto_init(struct net_protocol *pro)
45279 +{
45280 + pfkey_init();
45281 +}
45282 +#endif /* MODULE */
45283 +
45284 +/*
45285 + * $Log: pfkey_v2.c,v $
45286 + * Revision 1.97.2.8 2006/07/10 15:56:11 paul
45287 + * Fix for bug #642 by Bart.
45288 + *
45289 + * Revision 1.97.2.7 2006/04/04 11:34:19 ken
45290 + * Backport SMP fixes + #ifdef cleanup from #public
45291 + *
45292 + * Revision 1.97.2.6 2006/02/15 05:00:20 paul
45293 + * Fix for crasher on 2.6.12+ with klips (mostly seen on redhat kernels)
45294 + *
45295 + * Revision 1.97.2.5 2005/11/22 04:11:52 ken
45296 + * Backport fixes for 2.6.14 kernels from HEAD
45297 + *
45298 + * Revision 1.97.2.4 2005/09/14 16:40:45 mcr
45299 + * pull up of compilation on 2.4
45300 + *
45301 + * Revision 1.97.2.3 2005/09/06 02:10:03 mcr
45302 + * pulled up possible SMP-related compilation fix
45303 + *
45304 + * Revision 1.97.2.2 2005/08/28 01:21:12 paul
45305 + * Undid Ken's gcc4 fix in version 1.94 since it breaks linking KLIPS on
45306 + * SMP kernels.
45307 + *
45308 + * Revision 1.97.2.1 2005/08/27 23:40:00 paul
45309 + * recommited HAVE_SOCK_SECURITY fixes for linux 2.6.13
45310 + *
45311 + * Revision 1.102 2005/09/14 16:37:23 mcr
45312 + * fix to compile on 2.4.
45313 + *
45314 + * Revision 1.101 2005/09/06 01:42:25 mcr
45315 + * removed additional SOCKOPS_WRAPPED code
45316 + *
45317 + * Revision 1.100 2005/08/30 18:10:15 mcr
45318 + * remove SOCKOPS_WRAPPED() code, add proper locking to the
45319 + * pfkey code. (cross fingers)
45320 + *
45321 + * Revision 1.99 2005/08/28 01:53:37 paul
45322 + * Undid Ken's gcc4 fix in version 1.94 since it breaks linking KLIPS on SMP kernels.
45323 + *
45324 + * Revision 1.98 2005/08/27 23:07:21 paul
45325 + * Somewhere between 2.6.12 and 2.6.13rc7 the unused security memnber in sk_buff
45326 + * has been removed. This patch should fix compilation for both cases.
45327 + *
45328 + * Revision 1.97 2005/07/20 00:33:36 mcr
45329 + * fixed typo in #ifdef for SKALLOC.
45330 + *
45331 + * Revision 1.96 2005/07/19 20:02:15 mcr
45332 + * sk_alloc() interface change.
45333 + *
45334 + * Revision 1.95 2005/07/09 00:40:06 ken
45335 + * Fix for GCC4 - it doesn't like the potential for duplicate declaration
45336 + *
45337 + * Revision 1.94 2005/07/09 00:14:04 ken
45338 + * Casts for 64bit cleanliness
45339 + *
45340 + * Revision 1.93 2005/07/08 16:20:05 mcr
45341 + * fix for 2.6.12 disapperance of sk_zapped field -> sock_flags.
45342 + *
45343 + * Revision 1.92 2005/05/21 03:29:39 mcr
45344 + * fixed missing prototype definition.
45345 + *
45346 + * Revision 1.91 2005/05/11 01:43:45 mcr
45347 + * removed "poor-man"s OOP in favour of proper C structures.
45348 + *
45349 + * Revision 1.90 2005/05/02 18:42:47 mcr
45350 + * fix for cut&paste error with pfkey_v2.c "supported_name"
45351 + *
45352 + * Revision 1.89 2005/05/01 03:12:31 mcr
45353 + * print name if it is available.
45354 + *
45355 + * Revision 1.88 2005/04/29 05:10:22 mcr
45356 + * removed from extraenous includes to make unit testing easier.
45357 + *
45358 + * Revision 1.87 2005/04/15 19:57:10 mcr
45359 + * make sure that address has 0p so that it will
45360 + * sanitized.
45361 + *
45362 + * Revision 1.86 2005/04/08 18:28:36 mcr
45363 + * some minor #ifdef simplification in pursuit of a possible bug.
45364 + *
45365 + * Revision 1.85 2004/12/03 21:25:57 mcr
45366 + * compile time fixes for running on 2.6.
45367 + * still experimental.
45368 + *
45369 + * Revision 1.84 2004/08/17 03:27:23 mcr
45370 + * klips 2.6 edits.
45371 + *
45372 + * Revision 1.83 2004/08/04 15:57:07 mcr
45373 + * moved des .h files to include/des/ *
45374 + * included 2.6 protocol specific things
45375 + * started at NAT-T support, but it will require a kernel patch.
45376 + *
45377 + * Revision 1.82 2004/07/10 19:11:18 mcr
45378 + * CONFIG_IPSEC -> CONFIG_KLIPS.
45379 + *
45380 + * Revision 1.81 2004/04/25 21:23:11 ken
45381 + * Pull in dhr's changes from FreeS/WAN 2.06
45382 + *
45383 + * Revision 1.80 2004/04/06 02:49:26 mcr
45384 + * pullup of algo code from alg-branch.
45385 + *
45386 + * Revision 1.79.4.1 2003/12/22 15:25:52 jjo
45387 + * . Merged algo-0.8.1-rc11-test1 into alg-branch
45388 + *
45389 + * Revision 1.79 2003/10/31 02:27:55 mcr
45390 + * pulled up port-selector patches and sa_id elimination.
45391 + *
45392 + * Revision 1.78.4.1 2003/10/29 01:30:41 mcr
45393 + * elimited "struct sa_id".
45394 + *
45395 + * Revision 1.78 2003/04/03 17:38:09 rgb
45396 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
45397 + *
45398 + * Revision 1.77 2002/10/17 16:49:36 mcr
45399 + * sock->ops should reference the unwrapped options so that
45400 + * we get hacked in locking on SMP systems.
45401 + *
45402 + * Revision 1.76 2002/10/12 23:11:53 dhr
45403 + *
45404 + * [KenB + DHR] more 64-bit cleanup
45405 + *
45406 + * Revision 1.75 2002/09/20 05:01:57 rgb
45407 + * Added memory allocation debugging.
45408 + *
45409 + * Revision 1.74 2002/09/19 02:42:50 mcr
45410 + * do not define the pfkey_ops function for now.
45411 + *
45412 + * Revision 1.73 2002/09/17 17:29:23 mcr
45413 + * #if 0 out some dead code - pfkey_ops is never used as written.
45414 + *
45415 + * Revision 1.72 2002/07/24 18:44:54 rgb
45416 + * Type fiddling to tame ia64 compiler.
45417 + *
45418 + * Revision 1.71 2002/05/23 07:14:11 rgb
45419 + * Cleaned up %p variants to 0p%p for test suite cleanup.
45420 + *
45421 + * Revision 1.70 2002/04/24 07:55:32 mcr
45422 + * #include patches and Makefiles for post-reorg compilation.
45423 + *
45424 + * Revision 1.69 2002/04/24 07:36:33 mcr
45425 + * Moved from ./klips/net/ipsec/pfkey_v2.c,v
45426 + *
45427 + * Revision 1.68 2002/03/08 01:15:17 mcr
45428 + * put some internal structure only debug messages behind
45429 + * && sysctl_ipsec_debug_verbose.
45430 + *
45431 + * Revision 1.67 2002/01/29 17:17:57 mcr
45432 + * moved include of ipsec_param.h to after include of linux/kernel.h
45433 + * otherwise, it seems that some option that is set in ipsec_param.h
45434 + * screws up something subtle in the include path to kernel.h, and
45435 + * it complains on the snprintf() prototype.
45436 + *
45437 + * Revision 1.66 2002/01/29 04:00:54 mcr
45438 + * more excise of kversions.h header.
45439 + *
45440 + * Revision 1.65 2002/01/29 02:13:18 mcr
45441 + * introduction of ipsec_kversion.h means that include of
45442 + * ipsec_param.h must preceed any decisions about what files to
45443 + * include to deal with differences in kernel source.
45444 + *
45445 + * Revision 1.64 2001/11/26 09:23:51 rgb
45446 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
45447 + *
45448 + * Revision 1.61.2.1 2001/09/25 02:28:44 mcr
45449 + * cleaned up includes.
45450 + *
45451 + * Revision 1.63 2001/11/12 19:38:00 rgb
45452 + * Continue trying other sockets even if one fails and return only original
45453 + * error.
45454 + *
45455 + * Revision 1.62 2001/10/18 04:45:22 rgb
45456 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
45457 + * lib/freeswan.h version macros moved to lib/kversions.h.
45458 + * Other compiler directive cleanups.
45459 + *
45460 + * Revision 1.61 2001/09/20 15:32:59 rgb
45461 + * Min/max cleanup.
45462 + *
45463 + * Revision 1.60 2001/06/14 19:35:12 rgb
45464 + * Update copyright date.
45465 + *
45466 + * Revision 1.59 2001/06/13 15:35:48 rgb
45467 + * Fixed #endif comments.
45468 + *
45469 + * Revision 1.58 2001/05/04 16:37:24 rgb
45470 + * Remove erroneous checking of return codes for proc_net_* in 2.4.
45471 + *
45472 + * Revision 1.57 2001/05/03 19:43:36 rgb
45473 + * Initialise error return variable.
45474 + * Check error return codes in startup and shutdown.
45475 + * Standardise on SENDERR() macro.
45476 + *
45477 + * Revision 1.56 2001/04/21 23:05:07 rgb
45478 + * Define out skb->used for 2.4 kernels.
45479 + *
45480 + * Revision 1.55 2001/02/28 05:03:28 rgb
45481 + * Clean up and rationalise startup messages.
45482 + *
45483 + * Revision 1.54 2001/02/27 22:24:55 rgb
45484 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
45485 + * Check for satoa() return codes.
45486 + *
45487 + * Revision 1.53 2001/02/27 06:48:18 rgb
45488 + * Fixed pfkey socket unregister log message to reflect type and function.
45489 + *
45490 + * Revision 1.52 2001/02/26 22:34:38 rgb
45491 + * Fix error return code that was getting overwritten by the error return
45492 + * code of an upmsg.
45493 + *
45494 + * Revision 1.51 2001/01/30 23:42:47 rgb
45495 + * Allow pfkey msgs from pid other than user context required for ACQUIRE
45496 + * and subsequent ADD or UDATE.
45497 + *
45498 + * Revision 1.50 2001/01/23 20:22:59 rgb
45499 + * 2.4 fix to remove removed is_clone member.
45500 + *
45501 + * Revision 1.49 2000/11/06 04:33:47 rgb
45502 + * Changed non-exported functions to DEBUG_NO_STATIC.
45503 + *
45504 + * Revision 1.48 2000/09/29 19:47:41 rgb
45505 + * Update copyright.
45506 + *
45507 + * Revision 1.47 2000/09/22 04:23:04 rgb
45508 + * Added more debugging to pfkey_upmsg() call from pfkey_sendmsg() error.
45509 + *
45510 + * Revision 1.46 2000/09/21 04:20:44 rgb
45511 + * Fixed array size off-by-one error. (Thanks Svenning!)
45512 + *
45513 + * Revision 1.45 2000/09/20 04:01:26 rgb
45514 + * Changed static functions to DEBUG_NO_STATIC for revealing function names
45515 + * in oopsen.
45516 + *
45517 + * Revision 1.44 2000/09/19 00:33:17 rgb
45518 + * 2.0 fixes.
45519 + *
45520 + * Revision 1.43 2000/09/16 01:28:13 rgb
45521 + * Fixed use of 0 in p format warning.
45522 + *
45523 + * Revision 1.42 2000/09/16 01:09:41 rgb
45524 + * Fixed debug format warning for pointers that was expecting ints.
45525 + *
45526 + * Revision 1.41 2000/09/13 15:54:00 rgb
45527 + * Rewrote pfkey_get_info(), added pfkey_{supported,registered}_get_info().
45528 + * Moved supported algos add and remove to functions.
45529 + *
45530 + * Revision 1.40 2000/09/12 18:49:28 rgb
45531 + * Added IPIP tunnel and IPCOMP register support.
45532 + *
45533 + * Revision 1.39 2000/09/12 03:23:49 rgb
45534 + * Converted #if0 debugs to sysctl.
45535 + * Removed debug_pfkey initialisations that prevented no_debug loading or
45536 + * linking.
45537 + *
45538 + * Revision 1.38 2000/09/09 06:38:02 rgb
45539 + * Return positive errno in pfkey_reply error message.
45540 + *
45541 + * Revision 1.37 2000/09/08 19:19:09 rgb
45542 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
45543 + * Clean-up of long-unused crud...
45544 + * Create pfkey error message on on failure.
45545 + * Give pfkey_list_{insert,remove}_{socket,supported}() some error
45546 + * checking.
45547 + *
45548 + * Revision 1.36 2000/09/01 18:49:38 rgb
45549 + * Reap experimental NET_21_ bits.
45550 + * Turned registered sockets list into an array of one list per satype.
45551 + * Remove references to deprecated sklist_{insert,remove}_socket.
45552 + * Removed leaking socket debugging code.
45553 + * Removed duplicate pfkey_insert_socket in pfkey_create.
45554 + * Removed all references to pfkey msg->msg_name, since it is not used for
45555 + * pfkey.
45556 + * Added a supported algorithms array lists, one per satype and registered
45557 + * existing algorithms.
45558 + * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
45559 + * list.
45560 + * Only send pfkey_expire() messages to sockets registered for that satype.
45561 + *
45562 + * Revision 1.35 2000/08/24 17:03:00 rgb
45563 + * Corrected message size error return code for PF_KEYv2.
45564 + * Removed downward error prohibition.
45565 + *
45566 + * Revision 1.34 2000/08/21 16:32:26 rgb
45567 + * Re-formatted for cosmetic consistency and readability.
45568 + *
45569 + * Revision 1.33 2000/08/20 21:38:24 rgb
45570 + * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
45571 + * Extended the upward message initiation of pfkey_sendmsg(). (Momchil)
45572 + *
45573 + * Revision 1.32 2000/07/28 14:58:31 rgb
45574 + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
45575 + *
45576 + * Revision 1.31 2000/05/16 03:04:00 rgb
45577 + * Updates for 2.3.99pre8 from MB.
45578 + *
45579 + * Revision 1.30 2000/05/10 19:22:21 rgb
45580 + * Use sklist private functions for 2.3.xx compatibility.
45581 + *
45582 + * Revision 1.29 2000/03/22 16:17:03 rgb
45583 + * Fixed SOCKOPS_WRAPPED macro for SMP (MB).
45584 + *
45585 + * Revision 1.28 2000/02/21 19:30:45 rgb
45586 + * Removed references to pkt_bridged for 2.3.47 compatibility.
45587 + *
45588 + * Revision 1.27 2000/02/14 21:07:00 rgb
45589 + * Fixed /proc/net/pf-key legend spacing.
45590 + *
45591 + * Revision 1.26 2000/01/22 03:46:59 rgb
45592 + * Fixed pfkey error return mechanism so that we are able to free the
45593 + * local copy of the pfkey_msg, plugging a memory leak and silencing
45594 + * the bad object free complaints.
45595 + *
45596 + * Revision 1.25 2000/01/21 06:19:44 rgb
45597 + * Moved pfkey_list_remove_socket() calls to before MOD_USE_DEC_COUNT.
45598 + * Added debugging to pfkey_upmsg.
45599 + *
45600 + * Revision 1.24 2000/01/10 16:38:23 rgb
45601 + * MB fixups for 2.3.x.
45602 + *
45603 + * Revision 1.23 1999/12/09 23:22:16 rgb
45604 + * Added more instrumentation for debugging 2.0 socket
45605 + * selection/reading.
45606 + * Removed erroneous 2.0 wait==NULL check bug in select.
45607 + *
45608 + * Revision 1.22 1999/12/08 20:32:16 rgb
45609 + * Tidied up 2.0.xx support, after major pfkey work, eliminating
45610 + * msg->msg_name twiddling in the process, since it is not defined
45611 + * for PF_KEYv2.
45612 + *
45613 + * Revision 1.21 1999/12/01 22:17:19 rgb
45614 + * Set skb->dev to zero on new skb in case it is a reused skb.
45615 + * Added check for skb_put overflow and freeing to avoid upmsg on error.
45616 + * Added check for wrong pfkey version and freeing to avoid upmsg on
45617 + * error.
45618 + * Shut off content dumping in pfkey_destroy.
45619 + * Added debugging message for size of buffer allocated for upmsg.
45620 + *
45621 + * Revision 1.20 1999/11/27 12:11:00 rgb
45622 + * Minor clean-up, enabling quiet operation of pfkey if desired.
45623 + *
45624 + * Revision 1.19 1999/11/25 19:04:21 rgb
45625 + * Update proc_fs code for pfkey to use dynamic registration.
45626 + *
45627 + * Revision 1.18 1999/11/25 09:07:17 rgb
45628 + * Implemented SENDERR macro for propagating error codes.
45629 + * Fixed error return code bug.
45630 + *
45631 + * Revision 1.17 1999/11/23 23:07:20 rgb
45632 + * Change name of pfkey_msg_parser to pfkey_msg_interp since it no longer
45633 + * parses. (PJO)
45634 + * Sort out pfkey and freeswan headers, putting them in a library path.
45635 + *
45636 + * Revision 1.16 1999/11/20 22:00:22 rgb
45637 + * Moved socketlist type declarations and prototypes for shared use.
45638 + * Renamed reformatted and generically extended for use by other socket
45639 + * lists pfkey_{del,add}_open_socket to pfkey_list_{remove,insert}_socket.
45640 + *
45641 + * Revision 1.15 1999/11/18 04:15:09 rgb
45642 + * Make pfkey_data_ready temporarily available for 2.2.x testing.
45643 + * Clean up pfkey_destroy_socket() debugging statements.
45644 + * Add Peter Onion's code to send messages up to all listening sockets.
45645 + * Changed all occurrences of #include "../../../lib/freeswan.h"
45646 + * to #include <freeswan.h> which works due to -Ilibfreeswan in the
45647 + * klips/net/ipsec/Makefile.
45648 + * Replaced all kernel version macros to shorter, readable form.
45649 + * Added CONFIG_PROC_FS compiler directives in case it is shut off.
45650 + *
45651 + * Revision 1.14 1999/11/17 16:01:00 rgb
45652 + * Make pfkey_data_ready temporarily available for 2.2.x testing.
45653 + * Clean up pfkey_destroy_socket() debugging statements.
45654 + * Add Peter Onion's code to send messages up to all listening sockets.
45655 + * Changed #include "../../../lib/freeswan.h" to #include <freeswan.h>
45656 + * which works due to -Ilibfreeswan in the klips/net/ipsec/Makefile.
45657 + *
45658 + * Revision 1.13 1999/10/27 19:59:51 rgb
45659 + * Removed af_unix comments that are no longer relevant.
45660 + * Added debug prink statements.
45661 + * Added to the /proc output in pfkey_get_info.
45662 + * Made most functions non-static to enable oops tracing.
45663 + * Re-enable skb dequeueing and freeing.
45664 + * Fix skb_alloc() and skb_put() size bug in pfkey_upmsg().
45665 + *
45666 + * Revision 1.12 1999/10/26 17:05:42 rgb
45667 + * Complete re-ordering based on proto_ops structure order.
45668 + * Separated out proto_ops structures for 2.0.x and 2.2.x for clarity.
45669 + * Simplification to use built-in socket ops where possible for 2.2.x.
45670 + * Add shorter macros for compiler directives to visually clean-up.
45671 + * Add lots of sk skb dequeueing debugging statements.
45672 + * Added to the /proc output in pfkey_get_info.
45673 + *
45674 + * Revision 1.11 1999/09/30 02:55:10 rgb
45675 + * Bogus skb detection.
45676 + * Fix incorrect /proc/net/ipsec-eroute printk message.
45677 + *
45678 + * Revision 1.10 1999/09/21 15:22:13 rgb
45679 + * Temporary fix while I figure out the right way to destroy sockets.
45680 + *
45681 + * Revision 1.9 1999/07/08 19:19:44 rgb
45682 + * Fix pointer format warning.
45683 + * Fix missing member error under 2.0.xx kernels.
45684 + *
45685 + * Revision 1.8 1999/06/13 07:24:04 rgb
45686 + * Add more debugging.
45687 + *
45688 + * Revision 1.7 1999/06/10 05:24:17 rgb
45689 + * Clarified compiler directives.
45690 + * Renamed variables to reduce confusion.
45691 + * Used sklist_*_socket() kernel functions to simplify 2.2.x socket support.
45692 + * Added lots of sanity checking.
45693 + *
45694 + * Revision 1.6 1999/06/03 18:59:50 rgb
45695 + * More updates to 2.2.x socket support. Almost works, oops at end of call.
45696 + *
45697 + * Revision 1.5 1999/05/25 22:44:05 rgb
45698 + * Start fixing 2.2 sockets.
45699 + *
45700 + * Revision 1.4 1999/04/29 15:21:34 rgb
45701 + * Move log to the end of the file.
45702 + * Eliminate min/max redefinition in #include <net/tcp.h>.
45703 + * Correct path for pfkey #includes
45704 + * Standardise an error return method.
45705 + * Add debugging instrumentation.
45706 + * Move message type checking to pfkey_msg_parse().
45707 + * Add check for errno incorrectly set.
45708 + * Add check for valid PID.
45709 + * Add check for reserved illegally set.
45710 + * Add check for message out of bounds.
45711 + *
45712 + * Revision 1.3 1999/04/15 17:58:07 rgb
45713 + * Add RCSID labels.
45714 + *
45715 + * Revision 1.2 1999/04/15 15:37:26 rgb
45716 + * Forward check changes from POST1_00 branch.
45717 + *
45718 + * Revision 1.1.2.2 1999/04/13 20:37:12 rgb
45719 + * Header Title correction.
45720 + *
45721 + * Revision 1.1.2.1 1999/03/26 20:58:55 rgb
45722 + * Add pfkeyv2 support to KLIPS.
45723 + *
45724 + *
45725 + * RFC 2367
45726 + * PF_KEY_v2 Key Management API
45727 + */
45728 --- /dev/null Tue Mar 11 13:02:56 2003
45729 +++ linux/net/ipsec/pfkey_v2_build.c Mon Feb 9 13:51:03 2004
45730 @@ -0,0 +1,1642 @@
45731 +/*
45732 + * RFC2367 PF_KEYv2 Key management API message parser
45733 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
45734 + *
45735 + * This program is free software; you can redistribute it and/or modify it
45736 + * under the terms of the GNU General Public License as published by the
45737 + * Free Software Foundation; either version 2 of the License, or (at your
45738 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
45739 + *
45740 + * This program is distributed in the hope that it will be useful, but
45741 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
45742 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
45743 + * for more details.
45744 + *
45745 + * RCSID $Id: pfkey_v2_build.c,v 1.53 2005/11/09 00:30:37 mcr Exp $
45746 + */
45747 +
45748 +/*
45749 + * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
45750 + */
45751 +
45752 +char pfkey_v2_build_c_version[] = "$Id: pfkey_v2_build.c,v 1.53 2005/11/09 00:30:37 mcr Exp $";
45753 +
45754 +/*
45755 + * Some ugly stuff to allow consistent debugging code for use in the
45756 + * kernel and in user space
45757 +*/
45758 +
45759 +#if defined(__KERNEL__) && defined(linux)
45760 +
45761 +# include <linux/kernel.h> /* for printk */
45762 +
45763 +# include "openswan/ipsec_kversion.h" /* for malloc switch */
45764 +# ifdef MALLOC_SLAB
45765 +# include <linux/slab.h> /* kmalloc() */
45766 +# else /* MALLOC_SLAB */
45767 +# include <linux/malloc.h> /* kmalloc() */
45768 +# endif /* MALLOC_SLAB */
45769 +# include <linux/errno.h> /* error codes */
45770 +# include <linux/types.h> /* size_t */
45771 +# include <linux/interrupt.h> /* mark_bh */
45772 +
45773 +# include <linux/netdevice.h> /* struct device, and other headers */
45774 +# include <linux/etherdevice.h> /* eth_type_trans */
45775 +# include <linux/ip.h> /* struct iphdr */
45776 +# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
45777 +# include <linux/ipv6.h> /* struct ipv6hdr */
45778 +# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
45779 +
45780 +# define MALLOC(size) kmalloc(size, GFP_ATOMIC)
45781 +# define FREE(obj) kfree(obj)
45782 +# include <openswan.h>
45783 +#else /* __KERNEL__ */
45784 +
45785 +# include <sys/types.h>
45786 +# include <sys/errno.h>
45787 +# include <netinet/in.h>
45788 +# include <stdlib.h>
45789 +# include <stdio.h>
45790 +# include <string.h> /* memset */
45791 +
45792 +# include <openswan.h>
45793 +
45794 +#endif /* __KERNEL__ */
45795 +
45796 +#include <openswan/pfkeyv2.h>
45797 +#include <openswan/pfkey.h>
45798 +
45799 +#ifdef __KERNEL__
45800 +#include "openswan/radij.h" /* rd_nodes */
45801 +#include "openswan/ipsec_encap.h" /* sockaddr_encap */
45802 +#endif /* __KERNEL__ */
45803 +
45804 +
45805 +#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
45806 +#include "openswan/pfkey_debug.h"
45807 +
45808 +
45809 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
45810 +
45811 +void
45812 +pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
45813 +{
45814 + int i;
45815 +
45816 + for (i = 0; i != SADB_EXT_MAX + 1; i++) {
45817 + extensions[i] = NULL;
45818 + }
45819 +}
45820 +
45821 +void
45822 +pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
45823 +{
45824 + int i;
45825 +
45826 + if(!extensions) {
45827 + return;
45828 + }
45829 +
45830 + if(extensions[0]) {
45831 + memset(extensions[0], 0, sizeof(struct sadb_msg));
45832 + FREE(extensions[0]);
45833 + extensions[0] = NULL;
45834 + }
45835 +
45836 + for (i = 1; i != SADB_EXT_MAX + 1; i++) {
45837 + if(extensions[i]) {
45838 + memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
45839 + FREE(extensions[i]);
45840 + extensions[i] = NULL;
45841 + }
45842 + }
45843 +}
45844 +
45845 +void
45846 +pfkey_msg_free(struct sadb_msg **pfkey_msg)
45847 +{
45848 + if(*pfkey_msg) {
45849 + memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
45850 + FREE(*pfkey_msg);
45851 + *pfkey_msg = NULL;
45852 + }
45853 +}
45854 +
45855 +/* Default extension builders taken from the KLIPS code */
45856 +
45857 +int
45858 +pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
45859 + uint8_t msg_type,
45860 + uint8_t satype,
45861 + uint8_t msg_errno,
45862 + uint32_t seq,
45863 + uint32_t pid)
45864 +{
45865 + int error = 0;
45866 + struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext;
45867 +
45868 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45869 + "pfkey_msg_hdr_build:\n");
45870 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45871 + "pfkey_msg_hdr_build: "
45872 + "on_entry &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
45873 + &pfkey_ext,
45874 + pfkey_ext,
45875 + *pfkey_ext);
45876 + /* sanity checks... */
45877 + if(pfkey_msg) {
45878 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45879 + "pfkey_msg_hdr_build: "
45880 + "why is pfkey_msg already pointing to something?\n");
45881 + SENDERR(EINVAL);
45882 + }
45883 +
45884 + if(!msg_type) {
45885 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45886 + "pfkey_msg_hdr_build: "
45887 + "msg type not set, must be non-zero..\n");
45888 + SENDERR(EINVAL);
45889 + }
45890 +
45891 + if(msg_type > SADB_MAX) {
45892 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45893 + "pfkey_msg_hdr_build: "
45894 + "msg type too large:%d.\n",
45895 + msg_type);
45896 + SENDERR(EINVAL);
45897 + }
45898 +
45899 + if(satype > SADB_SATYPE_MAX) {
45900 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45901 + "pfkey_msg_hdr_build: "
45902 + "satype %d > max %d\n",
45903 + satype, SADB_SATYPE_MAX);
45904 + SENDERR(EINVAL);
45905 + }
45906 +
45907 + pfkey_msg = (struct sadb_msg*)MALLOC(sizeof(struct sadb_msg));
45908 + *pfkey_ext = (struct sadb_ext*)pfkey_msg;
45909 +
45910 + if(pfkey_msg == NULL) {
45911 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45912 + "pfkey_msg_hdr_build: "
45913 + "memory allocation failed\n");
45914 + SENDERR(ENOMEM);
45915 + }
45916 + memset(pfkey_msg, 0, sizeof(struct sadb_msg));
45917 +
45918 + pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
45919 +
45920 + pfkey_msg->sadb_msg_type = msg_type;
45921 + pfkey_msg->sadb_msg_satype = satype;
45922 +
45923 + pfkey_msg->sadb_msg_version = PF_KEY_V2;
45924 + pfkey_msg->sadb_msg_errno = msg_errno;
45925 + pfkey_msg->sadb_msg_reserved = 0;
45926 + pfkey_msg->sadb_msg_seq = seq;
45927 + pfkey_msg->sadb_msg_pid = pid;
45928 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45929 + "pfkey_msg_hdr_build: "
45930 + "on_exit &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
45931 + &pfkey_ext,
45932 + pfkey_ext,
45933 + *pfkey_ext);
45934 +errlab:
45935 + return error;
45936 +}
45937 +
45938 +int
45939 +pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
45940 + uint16_t exttype,
45941 + uint32_t spi,
45942 + uint8_t replay_window,
45943 + uint8_t sa_state,
45944 + uint8_t auth,
45945 + uint8_t encrypt,
45946 + uint32_t flags,
45947 + uint32_t/*IPsecSAref_t*/ ref)
45948 +{
45949 + int error = 0;
45950 + struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext;
45951 +
45952 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45953 + "pfkey_sa_build: "
45954 + "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n",
45955 + ntohl(spi), /* in network order */
45956 + replay_window,
45957 + sa_state,
45958 + auth,
45959 + encrypt,
45960 + flags);
45961 + /* sanity checks... */
45962 + if(pfkey_sa) {
45963 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45964 + "pfkey_sa_build: "
45965 + "why is pfkey_sa already pointing to something?\n");
45966 + SENDERR(EINVAL);
45967 + }
45968 +
45969 + if(exttype != SADB_EXT_SA &&
45970 + exttype != SADB_X_EXT_SA2) {
45971 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45972 + "pfkey_sa_build: "
45973 + "invalid exttype=%d.\n",
45974 + exttype);
45975 + SENDERR(EINVAL);
45976 + }
45977 +
45978 + if(replay_window > 64) {
45979 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45980 + "pfkey_sa_build: "
45981 + "replay window size: %d -- must be 0 <= size <= 64\n",
45982 + replay_window);
45983 + SENDERR(EINVAL);
45984 + }
45985 +
45986 + if(auth > SADB_AALG_MAX) {
45987 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45988 + "pfkey_sa_build: "
45989 + "auth=%d > SADB_AALG_MAX=%d.\n",
45990 + auth,
45991 + SADB_AALG_MAX);
45992 + SENDERR(EINVAL);
45993 + }
45994 +
45995 +#if SADB_EALG_MAX < 255
45996 + if(encrypt > SADB_EALG_MAX) {
45997 + DEBUGGING(PF_KEY_DEBUG_BUILD,
45998 + "pfkey_sa_build: "
45999 + "encrypt=%d > SADB_EALG_MAX=%d.\n",
46000 + encrypt,
46001 + SADB_EALG_MAX);
46002 + SENDERR(EINVAL);
46003 + }
46004 +#endif
46005 +
46006 + if(sa_state > K_SADB_SASTATE_MAX) {
46007 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46008 + "pfkey_sa_build: "
46009 + "sa_state=%d exceeds MAX=%d.\n",
46010 + sa_state,
46011 + K_SADB_SASTATE_MAX);
46012 + SENDERR(EINVAL);
46013 + }
46014 +
46015 + if(sa_state == K_SADB_SASTATE_DEAD) {
46016 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46017 + "pfkey_sa_build: "
46018 + "sa_state=%d is DEAD=%d is not allowed.\n",
46019 + sa_state,
46020 + K_SADB_SASTATE_DEAD);
46021 + SENDERR(EINVAL);
46022 + }
46023 +
46024 + if((IPSEC_SAREF_NULL != ref) && (ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
46025 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46026 + "pfkey_sa_build: "
46027 + "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
46028 + ref,
46029 + IPSEC_SAREF_NULL,
46030 + IPSEC_SA_REF_TABLE_NUM_ENTRIES);
46031 + SENDERR(EINVAL);
46032 + }
46033 +
46034 + pfkey_sa = (struct sadb_sa*)MALLOC(sizeof(struct sadb_sa));
46035 + *pfkey_ext = (struct sadb_ext*)pfkey_sa;
46036 +
46037 + if(pfkey_sa == NULL) {
46038 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46039 + "pfkey_sa_build: "
46040 + "memory allocation failed\n");
46041 + SENDERR(ENOMEM);
46042 + }
46043 + memset(pfkey_sa, 0, sizeof(struct sadb_sa));
46044 +
46045 + pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN;
46046 + pfkey_sa->sadb_sa_exttype = exttype;
46047 + pfkey_sa->sadb_sa_spi = spi;
46048 + pfkey_sa->sadb_sa_replay = replay_window;
46049 + pfkey_sa->sadb_sa_state = sa_state;
46050 + pfkey_sa->sadb_sa_auth = auth;
46051 + pfkey_sa->sadb_sa_encrypt = encrypt;
46052 + pfkey_sa->sadb_sa_flags = flags;
46053 + pfkey_sa->sadb_x_sa_ref = ref;
46054 +
46055 +errlab:
46056 + return error;
46057 +}
46058 +
46059 +int
46060 +pfkey_sa_build(struct sadb_ext ** pfkey_ext,
46061 + uint16_t exttype,
46062 + uint32_t spi,
46063 + uint8_t replay_window,
46064 + uint8_t sa_state,
46065 + uint8_t auth,
46066 + uint8_t encrypt,
46067 + uint32_t flags)
46068 +{
46069 + return pfkey_sa_ref_build(pfkey_ext,
46070 + exttype,
46071 + spi,
46072 + replay_window,
46073 + sa_state,
46074 + auth,
46075 + encrypt,
46076 + flags,
46077 + IPSEC_SAREF_NULL);
46078 +}
46079 +
46080 +int
46081 +pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
46082 + uint16_t exttype,
46083 + uint32_t allocations,
46084 + uint64_t bytes,
46085 + uint64_t addtime,
46086 + uint64_t usetime,
46087 + uint32_t packets)
46088 +{
46089 + int error = 0;
46090 + struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext;
46091 +
46092 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46093 + "pfkey_lifetime_build:\n");
46094 + /* sanity checks... */
46095 + if(pfkey_lifetime) {
46096 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46097 + "pfkey_lifetime_build: "
46098 + "why is pfkey_lifetime already pointing to something?\n");
46099 + SENDERR(EINVAL);
46100 + }
46101 +
46102 + if(exttype != SADB_EXT_LIFETIME_CURRENT &&
46103 + exttype != SADB_EXT_LIFETIME_HARD &&
46104 + exttype != SADB_EXT_LIFETIME_SOFT) {
46105 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46106 + "pfkey_lifetime_build: "
46107 + "invalid exttype=%d.\n",
46108 + exttype);
46109 + SENDERR(EINVAL);
46110 + }
46111 +
46112 + pfkey_lifetime = (struct sadb_lifetime*)MALLOC(sizeof(struct sadb_lifetime));
46113 + *pfkey_ext = (struct sadb_ext*) pfkey_lifetime;
46114 +
46115 + if(pfkey_lifetime == NULL) {
46116 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46117 + "pfkey_lifetime_build: "
46118 + "memory allocation failed\n");
46119 + SENDERR(ENOMEM);
46120 + }
46121 + memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime));
46122 +
46123 + pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN;
46124 + pfkey_lifetime->sadb_lifetime_exttype = exttype;
46125 + pfkey_lifetime->sadb_lifetime_allocations = allocations;
46126 + pfkey_lifetime->sadb_lifetime_bytes = bytes;
46127 + pfkey_lifetime->sadb_lifetime_addtime = addtime;
46128 + pfkey_lifetime->sadb_lifetime_usetime = usetime;
46129 + pfkey_lifetime->sadb_x_lifetime_packets = packets;
46130 +
46131 +errlab:
46132 + return error;
46133 +}
46134 +
46135 +int
46136 +pfkey_address_build(struct sadb_ext** pfkey_ext,
46137 + uint16_t exttype,
46138 + uint8_t proto,
46139 + uint8_t prefixlen,
46140 + struct sockaddr* address)
46141 +{
46142 + int error = 0;
46143 + int saddr_len = 0;
46144 + char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/];
46145 + struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext;
46146 +
46147 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46148 + "pfkey_address_build: "
46149 + "exttype=%d proto=%d prefixlen=%d\n",
46150 + exttype,
46151 + proto,
46152 + prefixlen);
46153 + /* sanity checks... */
46154 + if(pfkey_address) {
46155 + ERROR("pfkey_address_build: "
46156 + "why is pfkey_address already pointing to something?\n");
46157 + SENDERR(EINVAL);
46158 + }
46159 +
46160 + if (!address) {
46161 + ERROR("pfkey_address_build: " "address is NULL\n");
46162 + SENDERR(EINVAL);
46163 + }
46164 +
46165 + switch(exttype) {
46166 + case SADB_EXT_ADDRESS_SRC:
46167 + case SADB_EXT_ADDRESS_DST:
46168 + case SADB_EXT_ADDRESS_PROXY:
46169 + case SADB_X_EXT_ADDRESS_DST2:
46170 + case SADB_X_EXT_ADDRESS_SRC_FLOW:
46171 + case SADB_X_EXT_ADDRESS_DST_FLOW:
46172 + case SADB_X_EXT_ADDRESS_SRC_MASK:
46173 + case SADB_X_EXT_ADDRESS_DST_MASK:
46174 +#ifdef NAT_TRAVERSAL
46175 + case SADB_X_EXT_NAT_T_OA:
46176 +#endif
46177 + break;
46178 + default:
46179 + ERROR("pfkey_address_build: "
46180 + "unrecognised ext_type=%d.\n",
46181 + exttype);
46182 + SENDERR(EINVAL);
46183 + }
46184 +
46185 + switch(address->sa_family) {
46186 + case AF_INET:
46187 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46188 + "pfkey_address_build: "
46189 + "found address family AF_INET.\n");
46190 + saddr_len = sizeof(struct sockaddr_in);
46191 + sprintf(ipaddr_txt, "%d.%d.%d.%d:%d"
46192 + , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 0) & 0xFF
46193 + , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 8) & 0xFF
46194 + , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF
46195 + , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF
46196 + , ntohs(((struct sockaddr_in*)address)->sin_port));
46197 + break;
46198 + case AF_INET6:
46199 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46200 + "pfkey_address_build: "
46201 + "found address family AF_INET6.\n");
46202 + saddr_len = sizeof(struct sockaddr_in6);
46203 + sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x"
46204 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0])
46205 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1])
46206 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2])
46207 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3])
46208 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4])
46209 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5])
46210 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6])
46211 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7])
46212 + , ntohs(((struct sockaddr_in6*)address)->sin6_port));
46213 + break;
46214 + default:
46215 + ERROR("pfkey_address_build: "
46216 + "address->sa_family=%d not supported.\n",
46217 + address->sa_family);
46218 + SENDERR(EPFNOSUPPORT);
46219 + }
46220 +
46221 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46222 + "pfkey_address_build: "
46223 + "found address=%s.\n",
46224 + ipaddr_txt);
46225 + if(prefixlen != 0) {
46226 + ERROR("pfkey_address_build: "
46227 + "address prefixes not supported yet.\n");
46228 + SENDERR(EAFNOSUPPORT); /* not supported yet */
46229 + }
46230 +
46231 + /* allocate some memory for the extension */
46232 + pfkey_address = (struct sadb_address*)
46233 + MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN));
46234 + *pfkey_ext = (struct sadb_ext*)pfkey_address;
46235 +
46236 + if(pfkey_address == NULL ) {
46237 + ERROR("pfkey_lifetime_build: "
46238 + "memory allocation failed\n");
46239 + SENDERR(ENOMEM);
46240 + }
46241 + memset(pfkey_address,
46242 + 0,
46243 + ALIGN_N(sizeof(struct sadb_address) + saddr_len,
46244 + IPSEC_PFKEYv2_ALIGN));
46245 +
46246 + pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len,
46247 + IPSEC_PFKEYv2_ALIGN);
46248 +
46249 + pfkey_address->sadb_address_exttype = exttype;
46250 + pfkey_address->sadb_address_proto = proto;
46251 + pfkey_address->sadb_address_prefixlen = prefixlen;
46252 + pfkey_address->sadb_address_reserved = 0;
46253 +
46254 + memcpy((char*)pfkey_address + sizeof(struct sadb_address),
46255 + address,
46256 + saddr_len);
46257 +
46258 +#if 0
46259 + for(i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) {
46260 + pfkey_address_s_ska.sin_zero[i] = 0;
46261 + }
46262 +#endif
46263 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46264 + "pfkey_address_build: "
46265 + "successful created len: %d.\n", pfkey_address->sadb_address_len);
46266 +
46267 + errlab:
46268 + return error;
46269 +}
46270 +
46271 +int
46272 +pfkey_key_build(struct sadb_ext** pfkey_ext,
46273 + uint16_t exttype,
46274 + uint16_t key_bits,
46275 + unsigned char * key)
46276 +{
46277 + int error = 0;
46278 + struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext;
46279 +
46280 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46281 + "pfkey_key_build:\n");
46282 + /* sanity checks... */
46283 + if(pfkey_key) {
46284 + ERROR("pfkey_key_build: "
46285 + "why is pfkey_key already pointing to something?\n");
46286 + SENDERR(EINVAL);
46287 + }
46288 +
46289 + if(!key_bits) {
46290 + ERROR("pfkey_key_build: "
46291 + "key_bits is zero, it must be non-zero.\n");
46292 + SENDERR(EINVAL);
46293 + }
46294 +
46295 + if( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) {
46296 + ERROR("pfkey_key_build: "
46297 + "unsupported extension type=%d.\n",
46298 + exttype);
46299 + SENDERR(EINVAL);
46300 + }
46301 +
46302 + pfkey_key = (struct sadb_key*)
46303 + MALLOC(sizeof(struct sadb_key) +
46304 + DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
46305 +
46306 + *pfkey_ext = (struct sadb_ext*)pfkey_key;
46307 +
46308 + if(pfkey_key == NULL) {
46309 + ERROR("pfkey_key_build: "
46310 + "memory allocation failed\n");
46311 + SENDERR(ENOMEM);
46312 + }
46313 + memset(pfkey_key,
46314 + 0,
46315 + sizeof(struct sadb_key) +
46316 + DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
46317 +
46318 + pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits,
46319 + 64);
46320 + pfkey_key->sadb_key_exttype = exttype;
46321 + pfkey_key->sadb_key_bits = key_bits;
46322 + pfkey_key->sadb_key_reserved = 0;
46323 + memcpy((char*)pfkey_key + sizeof(struct sadb_key),
46324 + key,
46325 + DIVUP(key_bits, 8));
46326 +
46327 +errlab:
46328 + return error;
46329 +}
46330 +
46331 +int
46332 +pfkey_ident_build(struct sadb_ext** pfkey_ext,
46333 + uint16_t exttype,
46334 + uint16_t ident_type,
46335 + uint64_t ident_id,
46336 + uint8_t ident_len,
46337 + char* ident_string)
46338 +{
46339 + int error = 0;
46340 + struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext;
46341 + int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
46342 +
46343 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46344 + "pfkey_ident_build:\n");
46345 + /* sanity checks... */
46346 + if(pfkey_ident) {
46347 + ERROR("pfkey_ident_build: "
46348 + "why is pfkey_ident already pointing to something?\n");
46349 + SENDERR(EINVAL);
46350 + }
46351 +
46352 + if( ! ((exttype == SADB_EXT_IDENTITY_SRC) ||
46353 + (exttype == SADB_EXT_IDENTITY_DST))) {
46354 + ERROR("pfkey_ident_build: "
46355 + "unsupported extension type=%d.\n",
46356 + exttype);
46357 + SENDERR(EINVAL);
46358 + }
46359 +
46360 + if((ident_type == SADB_IDENTTYPE_RESERVED)) {
46361 + ERROR("pfkey_ident_build: "
46362 + "ident_type must be non-zero.\n");
46363 + SENDERR(EINVAL);
46364 + }
46365 +
46366 + if(ident_type > SADB_IDENTTYPE_MAX) {
46367 + ERROR("pfkey_ident_build: "
46368 + "identtype=%d out of range.\n",
46369 + ident_type);
46370 + SENDERR(EINVAL);
46371 + }
46372 +
46373 + if(((ident_type == SADB_IDENTTYPE_PREFIX) ||
46374 + (ident_type == SADB_IDENTTYPE_FQDN)) &&
46375 + !ident_string) {
46376 + ERROR("pfkey_ident_build: "
46377 + "string required to allocate size of extension.\n");
46378 + SENDERR(EINVAL);
46379 + }
46380 +
46381 +#if 0
46382 + if((ident_type == SADB_IDENTTYPE_USERFQDN) ) {
46383 + }
46384 +#endif
46385 +
46386 + pfkey_ident = (struct sadb_ident*)
46387 + MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN);
46388 +
46389 + *pfkey_ext = (struct sadb_ext*)pfkey_ident;
46390 +
46391 + if(pfkey_ident == NULL) {
46392 + ERROR("pfkey_ident_build: "
46393 + "memory allocation failed\n");
46394 + SENDERR(ENOMEM);
46395 + }
46396 + memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN);
46397 +
46398 + pfkey_ident->sadb_ident_len = ident_len;
46399 + pfkey_ident->sadb_ident_exttype = exttype;
46400 + pfkey_ident->sadb_ident_type = ident_type;
46401 + pfkey_ident->sadb_ident_reserved = 0;
46402 + pfkey_ident->sadb_ident_id = ident_id;
46403 + memcpy((char*)pfkey_ident + sizeof(struct sadb_ident),
46404 + ident_string,
46405 + data_len);
46406 +
46407 +errlab:
46408 + return error;
46409 +}
46410 +
46411 +int
46412 +pfkey_sens_build(struct sadb_ext** pfkey_ext,
46413 + uint32_t dpd,
46414 + uint8_t sens_level,
46415 + uint8_t sens_len,
46416 + uint64_t* sens_bitmap,
46417 + uint8_t integ_level,
46418 + uint8_t integ_len,
46419 + uint64_t* integ_bitmap)
46420 +{
46421 + int error = 0;
46422 + struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext;
46423 + int i;
46424 + uint64_t* bitmap;
46425 +
46426 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46427 + "pfkey_sens_build:\n");
46428 + /* sanity checks... */
46429 + if(pfkey_sens) {
46430 + ERROR("pfkey_sens_build: "
46431 + "why is pfkey_sens already pointing to something?\n");
46432 + SENDERR(EINVAL);
46433 + }
46434 +
46435 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46436 + "pfkey_sens_build: "
46437 + "Sorry, I can't build exttype=%d yet.\n",
46438 + (*pfkey_ext)->sadb_ext_type);
46439 + SENDERR(EINVAL); /* don't process these yet */
46440 +
46441 + pfkey_sens = (struct sadb_sens*)
46442 + MALLOC(sizeof(struct sadb_sens) +
46443 + (sens_len + integ_len) * sizeof(uint64_t));
46444 +
46445 + *pfkey_ext = (struct sadb_ext*)pfkey_sens;
46446 +
46447 + if(pfkey_sens == NULL) {
46448 + ERROR("pfkey_sens_build: "
46449 + "memory allocation failed\n");
46450 + SENDERR(ENOMEM);
46451 + }
46452 + memset(pfkey_sens,
46453 + 0,
46454 + sizeof(struct sadb_sens) +
46455 + (sens_len + integ_len) * sizeof(uint64_t));
46456 +
46457 + pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) +
46458 + (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN;
46459 + pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY;
46460 + pfkey_sens->sadb_sens_dpd = dpd;
46461 + pfkey_sens->sadb_sens_sens_level = sens_level;
46462 + pfkey_sens->sadb_sens_sens_len = sens_len;
46463 + pfkey_sens->sadb_sens_integ_level = integ_level;
46464 + pfkey_sens->sadb_sens_integ_len = integ_len;
46465 + pfkey_sens->sadb_sens_reserved = 0;
46466 +
46467 + bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens));
46468 + for(i = 0; i < sens_len; i++) {
46469 + *bitmap = sens_bitmap[i];
46470 + bitmap++;
46471 + }
46472 + for(i = 0; i < integ_len; i++) {
46473 + *bitmap = integ_bitmap[i];
46474 + bitmap++;
46475 + }
46476 +
46477 +errlab:
46478 + return error;
46479 +}
46480 +
46481 +int
46482 +pfkey_prop_build(struct sadb_ext** pfkey_ext,
46483 + uint8_t replay,
46484 + unsigned int comb_num,
46485 + struct sadb_comb* comb)
46486 +{
46487 + int error = 0;
46488 + int i;
46489 + struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext;
46490 + struct sadb_comb *combp;
46491 +
46492 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46493 + "pfkey_prop_build:\n");
46494 + /* sanity checks... */
46495 + if(pfkey_prop) {
46496 + ERROR("pfkey_prop_build: "
46497 + "why is pfkey_prop already pointing to something?\n");
46498 + SENDERR(EINVAL);
46499 + }
46500 +
46501 + pfkey_prop = (struct sadb_prop*)
46502 + MALLOC(sizeof(struct sadb_prop) +
46503 + comb_num * sizeof(struct sadb_comb));
46504 +
46505 + *pfkey_ext = (struct sadb_ext*)pfkey_prop;
46506 +
46507 + if(pfkey_prop == NULL) {
46508 + ERROR("pfkey_prop_build: "
46509 + "memory allocation failed\n");
46510 + SENDERR(ENOMEM);
46511 + }
46512 + memset(pfkey_prop,
46513 + 0,
46514 + sizeof(struct sadb_prop) +
46515 + comb_num * sizeof(struct sadb_comb));
46516 +
46517 + pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
46518 + comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN;
46519 +
46520 + pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
46521 + pfkey_prop->sadb_prop_replay = replay;
46522 +
46523 + for(i=0; i<3; i++) {
46524 + pfkey_prop->sadb_prop_reserved[i] = 0;
46525 + }
46526 +
46527 + combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop));
46528 + for(i = 0; i < comb_num; i++) {
46529 + memcpy (combp, &(comb[i]), sizeof(struct sadb_comb));
46530 + combp++;
46531 + }
46532 +
46533 +#if 0
46534 + uint8_t sadb_comb_auth;
46535 + uint8_t sadb_comb_encrypt;
46536 + uint16_t sadb_comb_flags;
46537 + uint16_t sadb_comb_auth_minbits;
46538 + uint16_t sadb_comb_auth_maxbits;
46539 + uint16_t sadb_comb_encrypt_minbits;
46540 + uint16_t sadb_comb_encrypt_maxbits;
46541 + uint32_t sadb_comb_reserved;
46542 + uint32_t sadb_comb_soft_allocations;
46543 + uint32_t sadb_comb_hard_allocations;
46544 + uint64_t sadb_comb_soft_bytes;
46545 + uint64_t sadb_comb_hard_bytes;
46546 + uint64_t sadb_comb_soft_addtime;
46547 + uint64_t sadb_comb_hard_addtime;
46548 + uint64_t sadb_comb_soft_usetime;
46549 + uint64_t sadb_comb_hard_usetime;
46550 + uint32_t sadb_comb_soft_packets;
46551 + uint32_t sadb_comb_hard_packets;
46552 +#endif
46553 +errlab:
46554 + return error;
46555 +}
46556 +
46557 +int
46558 +pfkey_supported_build(struct sadb_ext** pfkey_ext,
46559 + uint16_t exttype,
46560 + unsigned int alg_num,
46561 + struct sadb_alg* alg)
46562 +{
46563 + int error = 0;
46564 + unsigned int i;
46565 + struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext;
46566 + struct sadb_alg *pfkey_alg;
46567 +
46568 + /* sanity checks... */
46569 + if(pfkey_supported) {
46570 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46571 + "pfkey_supported_build: "
46572 + "why is pfkey_supported already pointing to something?\n");
46573 + SENDERR(EINVAL);
46574 + }
46575 +
46576 + if( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) {
46577 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46578 + "pfkey_supported_build: "
46579 + "unsupported extension type=%d.\n",
46580 + exttype);
46581 + SENDERR(EINVAL);
46582 + }
46583 +
46584 + pfkey_supported = (struct sadb_supported*)
46585 + MALLOC(sizeof(struct sadb_supported) +
46586 + alg_num *
46587 + sizeof(struct sadb_alg));
46588 +
46589 + *pfkey_ext = (struct sadb_ext*)pfkey_supported;
46590 +
46591 + if(pfkey_supported == NULL) {
46592 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46593 + "pfkey_supported_build: "
46594 + "memory allocation failed\n");
46595 + SENDERR(ENOMEM);
46596 + }
46597 + memset(pfkey_supported,
46598 + 0,
46599 + sizeof(struct sadb_supported) +
46600 + alg_num *
46601 + sizeof(struct sadb_alg));
46602 +
46603 + pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) +
46604 + alg_num *
46605 + sizeof(struct sadb_alg)) /
46606 + IPSEC_PFKEYv2_ALIGN;
46607 + pfkey_supported->sadb_supported_exttype = exttype;
46608 + pfkey_supported->sadb_supported_reserved = 0;
46609 +
46610 + pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported));
46611 + for(i = 0; i < alg_num; i++) {
46612 + memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg));
46613 + pfkey_alg->sadb_alg_reserved = 0;
46614 + pfkey_alg++;
46615 + }
46616 +
46617 +#if 0
46618 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46619 + "pfkey_supported_build: "
46620 + "Sorry, I can't build exttype=%d yet.\n",
46621 + (*pfkey_ext)->sadb_ext_type);
46622 + SENDERR(EINVAL); /* don't process these yet */
46623 +
46624 + uint8_t sadb_alg_id;
46625 + uint8_t sadb_alg_ivlen;
46626 + uint16_t sadb_alg_minbits;
46627 + uint16_t sadb_alg_maxbits;
46628 + uint16_t sadb_alg_reserved;
46629 +#endif
46630 +errlab:
46631 + return error;
46632 +}
46633 +
46634 +int
46635 +pfkey_spirange_build(struct sadb_ext** pfkey_ext,
46636 + uint16_t exttype,
46637 + uint32_t min, /* in network order */
46638 + uint32_t max) /* in network order */
46639 +{
46640 + int error = 0;
46641 + struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext;
46642 +
46643 + /* sanity checks... */
46644 + if(pfkey_spirange) {
46645 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46646 + "pfkey_spirange_build: "
46647 + "why is pfkey_spirange already pointing to something?\n");
46648 + SENDERR(EINVAL);
46649 + }
46650 +
46651 + if(ntohl(max) < ntohl(min)) {
46652 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46653 + "pfkey_spirange_build: "
46654 + "minspi=%08x must be < maxspi=%08x.\n",
46655 + ntohl(min),
46656 + ntohl(max));
46657 + SENDERR(EINVAL);
46658 + }
46659 +
46660 + if(ntohl(min) <= 255) {
46661 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46662 + "pfkey_spirange_build: "
46663 + "minspi=%08x must be > 255.\n",
46664 + ntohl(min));
46665 + SENDERR(EEXIST);
46666 + }
46667 +
46668 + pfkey_spirange = (struct sadb_spirange*)
46669 + MALLOC(sizeof(struct sadb_spirange));
46670 +
46671 + *pfkey_ext = (struct sadb_ext*)pfkey_spirange;
46672 +
46673 + if(pfkey_spirange == NULL) {
46674 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46675 + "pfkey_spirange_build: "
46676 + "memory allocation failed\n");
46677 + SENDERR(ENOMEM);
46678 + }
46679 + memset(pfkey_spirange,
46680 + 0,
46681 + sizeof(struct sadb_spirange));
46682 +
46683 + pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN;
46684 +
46685 + pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
46686 + pfkey_spirange->sadb_spirange_min = min;
46687 + pfkey_spirange->sadb_spirange_max = max;
46688 + pfkey_spirange->sadb_spirange_reserved = 0;
46689 + errlab:
46690 + return error;
46691 +}
46692 +
46693 +int
46694 +pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext)
46695 +{
46696 + int error = 0;
46697 + struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext;
46698 +
46699 + /* sanity checks... */
46700 + if(pfkey_x_kmprivate) {
46701 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46702 + "pfkey_x_kmprivate_build: "
46703 + "why is pfkey_x_kmprivate already pointing to something?\n");
46704 + SENDERR(EINVAL);
46705 + }
46706 +
46707 + pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
46708 +
46709 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46710 + "pfkey_x_kmprivate_build: "
46711 + "Sorry, I can't build exttype=%d yet.\n",
46712 + (*pfkey_ext)->sadb_ext_type);
46713 + SENDERR(EINVAL); /* don't process these yet */
46714 +
46715 + pfkey_x_kmprivate = (struct sadb_x_kmprivate*)
46716 + MALLOC(sizeof(struct sadb_x_kmprivate));
46717 +
46718 + *pfkey_ext = (struct sadb_ext*)pfkey_x_kmprivate;
46719 +
46720 + if(pfkey_x_kmprivate == NULL) {
46721 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46722 + "pfkey_x_kmprivate_build: "
46723 + "memory allocation failed\n");
46724 + SENDERR(ENOMEM);
46725 + }
46726 + memset(pfkey_x_kmprivate,
46727 + 0,
46728 + sizeof(struct sadb_x_kmprivate));
46729 +
46730 + pfkey_x_kmprivate->sadb_x_kmprivate_len =
46731 + sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN;
46732 +
46733 + pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE;
46734 + pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
46735 +errlab:
46736 + return error;
46737 +}
46738 +
46739 +int
46740 +pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
46741 + uint8_t satype)
46742 +{
46743 + int error = 0;
46744 + int i;
46745 + struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext;
46746 +
46747 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46748 + "pfkey_x_satype_build:\n");
46749 + /* sanity checks... */
46750 + if(pfkey_x_satype) {
46751 + ERROR("pfkey_x_satype_build: "
46752 + "why is pfkey_x_satype already pointing to something?\n");
46753 + SENDERR(EINVAL);
46754 + }
46755 +
46756 + if(!satype) {
46757 + ERROR("pfkey_x_satype_build: "
46758 + "SA type not set, must be non-zero.\n");
46759 + SENDERR(EINVAL);
46760 + }
46761 +
46762 + if(satype > SADB_SATYPE_MAX) {
46763 + ERROR("pfkey_x_satype_build: "
46764 + "satype %d > max %d\n",
46765 + satype, SADB_SATYPE_MAX);
46766 + SENDERR(EINVAL);
46767 + }
46768 +
46769 + pfkey_x_satype = (struct sadb_x_satype*)
46770 + MALLOC(sizeof(struct sadb_x_satype));
46771 +
46772 + *pfkey_ext = (struct sadb_ext*)pfkey_x_satype;
46773 + if(pfkey_x_satype == NULL) {
46774 + ERROR("pfkey_x_satype_build: "
46775 + "memory allocation failed\n");
46776 + SENDERR(ENOMEM);
46777 + }
46778 + memset(pfkey_x_satype,
46779 + 0,
46780 + sizeof(struct sadb_x_satype));
46781 +
46782 + pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN;
46783 +
46784 + pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2;
46785 + pfkey_x_satype->sadb_x_satype_satype = satype;
46786 + for(i=0; i<3; i++) {
46787 + pfkey_x_satype->sadb_x_satype_reserved[i] = 0;
46788 + }
46789 +
46790 +errlab:
46791 + return error;
46792 +}
46793 +
46794 +int
46795 +pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
46796 + uint32_t tunnel,
46797 + uint32_t netlink,
46798 + uint32_t xform,
46799 + uint32_t eroute,
46800 + uint32_t spi,
46801 + uint32_t radij,
46802 + uint32_t esp,
46803 + uint32_t ah,
46804 + uint32_t rcv,
46805 + uint32_t pfkey,
46806 + uint32_t ipcomp,
46807 + uint32_t verbose)
46808 +{
46809 + int error = 0;
46810 + int i;
46811 + struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext;
46812 +
46813 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46814 + "pfkey_x_debug_build:\n");
46815 + /* sanity checks... */
46816 + if(pfkey_x_debug) {
46817 + ERROR("pfkey_x_debug_build: "
46818 + "why is pfkey_x_debug already pointing to something?\n");
46819 + SENDERR(EINVAL);
46820 + }
46821 +
46822 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46823 + "pfkey_x_debug_build: "
46824 + "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",
46825 + tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose);
46826 +
46827 + pfkey_x_debug = (struct sadb_x_debug*)
46828 + MALLOC(sizeof(struct sadb_x_debug));
46829 +
46830 + *pfkey_ext = (struct sadb_ext*)pfkey_x_debug;
46831 +
46832 + if(pfkey_x_debug == NULL) {
46833 + ERROR("pfkey_x_debug_build: "
46834 + "memory allocation failed\n");
46835 + SENDERR(ENOMEM);
46836 + }
46837 +#if 0
46838 + memset(pfkey_x_debug,
46839 + 0,
46840 + sizeof(struct sadb_x_debug));
46841 +#endif
46842 +
46843 + pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN;
46844 + pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG;
46845 +
46846 + pfkey_x_debug->sadb_x_debug_tunnel = tunnel;
46847 + pfkey_x_debug->sadb_x_debug_netlink = netlink;
46848 + pfkey_x_debug->sadb_x_debug_xform = xform;
46849 + pfkey_x_debug->sadb_x_debug_eroute = eroute;
46850 + pfkey_x_debug->sadb_x_debug_spi = spi;
46851 + pfkey_x_debug->sadb_x_debug_radij = radij;
46852 + pfkey_x_debug->sadb_x_debug_esp = esp;
46853 + pfkey_x_debug->sadb_x_debug_ah = ah;
46854 + pfkey_x_debug->sadb_x_debug_rcv = rcv;
46855 + pfkey_x_debug->sadb_x_debug_pfkey = pfkey;
46856 + pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp;
46857 + pfkey_x_debug->sadb_x_debug_verbose = verbose;
46858 +
46859 + for(i=0; i<4; i++) {
46860 + pfkey_x_debug->sadb_x_debug_reserved[i] = 0;
46861 + }
46862 +
46863 +errlab:
46864 + return error;
46865 +}
46866 +
46867 +int
46868 +pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
46869 + uint8_t type)
46870 +{
46871 + int error = 0;
46872 + int i;
46873 + struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)*pfkey_ext;
46874 +
46875 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46876 + "pfkey_x_nat_t_type_build:\n");
46877 + /* sanity checks... */
46878 + if(pfkey_x_nat_t_type) {
46879 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46880 + "pfkey_x_nat_t_type_build: "
46881 + "why is pfkey_x_nat_t_type already pointing to something?\n");
46882 + SENDERR(EINVAL);
46883 + }
46884 +
46885 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46886 + "pfkey_x_nat_t_type_build: "
46887 + "type=%d\n", type);
46888 +
46889 + pfkey_x_nat_t_type = (struct sadb_x_nat_t_type*)
46890 + MALLOC(sizeof(struct sadb_x_nat_t_type));
46891 +
46892 + *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_type;
46893 +
46894 + if(pfkey_x_nat_t_type == NULL) {
46895 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46896 + "pfkey_x_nat_t_type_build: "
46897 + "memory allocation failed\n");
46898 + SENDERR(ENOMEM);
46899 + }
46900 +
46901 + pfkey_x_nat_t_type->sadb_x_nat_t_type_len = sizeof(struct sadb_x_nat_t_type) / IPSEC_PFKEYv2_ALIGN;
46902 + pfkey_x_nat_t_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
46903 + pfkey_x_nat_t_type->sadb_x_nat_t_type_type = type;
46904 + for(i=0; i<3; i++) {
46905 + pfkey_x_nat_t_type->sadb_x_nat_t_type_reserved[i] = 0;
46906 + }
46907 +
46908 +errlab:
46909 + return error;
46910 +}
46911 +int
46912 +pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
46913 + uint16_t exttype,
46914 + uint16_t port)
46915 +{
46916 + int error = 0;
46917 + struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)*pfkey_ext;
46918 +
46919 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46920 + "pfkey_x_nat_t_port_build:\n");
46921 + /* sanity checks... */
46922 + if(pfkey_x_nat_t_port) {
46923 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46924 + "pfkey_x_nat_t_port_build: "
46925 + "why is pfkey_x_nat_t_port already pointing to something?\n");
46926 + SENDERR(EINVAL);
46927 + }
46928 +
46929 + switch(exttype) {
46930 + case SADB_X_EXT_NAT_T_SPORT:
46931 + case SADB_X_EXT_NAT_T_DPORT:
46932 + break;
46933 + default:
46934 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46935 + "pfkey_nat_t_port_build: "
46936 + "unrecognised ext_type=%d.\n",
46937 + exttype);
46938 + SENDERR(EINVAL);
46939 + }
46940 +
46941 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46942 + "pfkey_x_nat_t_port_build: "
46943 + "ext=%d, port=%d\n", exttype, port);
46944 +
46945 + pfkey_x_nat_t_port = (struct sadb_x_nat_t_port*)
46946 + MALLOC(sizeof(struct sadb_x_nat_t_port));
46947 +
46948 + *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_port;
46949 +
46950 + if(pfkey_x_nat_t_port == NULL) {
46951 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46952 + "pfkey_x_nat_t_port_build: "
46953 + "memory allocation failed\n");
46954 + SENDERR(ENOMEM);
46955 + }
46956 +
46957 + pfkey_x_nat_t_port->sadb_x_nat_t_port_len = sizeof(struct sadb_x_nat_t_port) / IPSEC_PFKEYv2_ALIGN;
46958 + pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype = exttype;
46959 + pfkey_x_nat_t_port->sadb_x_nat_t_port_port = port;
46960 + pfkey_x_nat_t_port->sadb_x_nat_t_port_reserved = 0;
46961 +
46962 +errlab:
46963 + return error;
46964 +}
46965 +
46966 +int pfkey_x_protocol_build(struct sadb_ext **pfkey_ext,
46967 + uint8_t protocol)
46968 +{
46969 + int error = 0;
46970 + struct sadb_protocol * p = (struct sadb_protocol *)*pfkey_ext;
46971 + DEBUGGING(PF_KEY_DEBUG_BUILD,"pfkey_x_protocol_build: protocol=%u\n", protocol);
46972 + /* sanity checks... */
46973 + if (p != 0) {
46974 + ERROR("pfkey_x_protocol_build: bogus protocol pointer\n");
46975 + SENDERR(EINVAL);
46976 + }
46977 + if ((p = (struct sadb_protocol*)MALLOC(sizeof(*p))) == 0) {
46978 + ERROR("pfkey_build: memory allocation failed\n");
46979 + SENDERR(ENOMEM);
46980 + }
46981 + *pfkey_ext = (struct sadb_ext *)p;
46982 + p->sadb_protocol_len = sizeof(*p) / sizeof(uint64_t);
46983 + p->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
46984 + p->sadb_protocol_proto = protocol;
46985 + p->sadb_protocol_flags = 0;
46986 + p->sadb_protocol_reserved2 = 0;
46987 + errlab:
46988 + return error;
46989 +}
46990 +
46991 +int pfkey_outif_build(struct sadb_ext **pfkey_ext,
46992 + uint16_t outif)
46993 +{
46994 + int error = 0;
46995 + struct sadb_x_plumbif * p = (struct sadb_x_plumbif *)*pfkey_ext;
46996 +
46997 + if ((p = (struct sadb_x_plumbif*)MALLOC(sizeof(*p))) == 0) {
46998 + ERROR("pfkey_build: memory allocation failed\n");
46999 + SENDERR(ENOMEM);
47000 + }
47001 + *pfkey_ext = (struct sadb_ext *)p;
47002 +
47003 + p->sadb_x_outif_len = IPSEC_PFKEYv2_WORDS(sizeof(*p));
47004 + p->sadb_x_outif_exttype = K_SADB_X_EXT_PLUMBIF;
47005 + p->sadb_x_outif_ifnum = outif;
47006 +
47007 + errlab:
47008 + return error;
47009 +}
47010 +
47011 +
47012 +#if defined(I_DONT_THINK_THIS_WILL_BE_USEFUL) && I_DONT_THINK_THIS_WILL_BE_USEFUL
47013 +int (*ext_default_builders[SADB_EXT_MAX +1])(struct sadb_msg*, struct sadb_ext*)
47014 + =
47015 +{
47016 + NULL, /* pfkey_msg_build, */
47017 + pfkey_sa_build,
47018 + pfkey_lifetime_build,
47019 + pfkey_lifetime_build,
47020 + pfkey_lifetime_build,
47021 + pfkey_address_build,
47022 + pfkey_address_build,
47023 + pfkey_address_build,
47024 + pfkey_key_build,
47025 + pfkey_key_build,
47026 + pfkey_ident_build,
47027 + pfkey_ident_build,
47028 + pfkey_sens_build,
47029 + pfkey_prop_build,
47030 + pfkey_supported_build,
47031 + pfkey_supported_build,
47032 + pfkey_spirange_build,
47033 + pfkey_x_kmprivate_build,
47034 + pfkey_x_satype_build,
47035 + pfkey_sa_build,
47036 + pfkey_address_build,
47037 + pfkey_address_build,
47038 + pfkey_address_build,
47039 + pfkey_address_build,
47040 + pfkey_address_build,
47041 + pfkey_x_ext_debug_build
47042 +};
47043 +#endif
47044 +
47045 +int
47046 +pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir)
47047 +{
47048 + int error = 0;
47049 + unsigned ext;
47050 + unsigned total_size;
47051 + struct sadb_ext *pfkey_ext;
47052 + int extensions_seen = 0;
47053 +#ifndef __KERNEL__
47054 + struct sadb_ext *extensions_check[SADB_EXT_MAX + 1];
47055 +#endif
47056 +
47057 + if(!extensions[0]) {
47058 + ERROR("pfkey_msg_build: "
47059 + "extensions[0] must be specified (struct sadb_msg).\n");
47060 + SENDERR(EINVAL);
47061 + }
47062 +
47063 + /* figure out the total size for all the requested extensions */
47064 + total_size = IPSEC_PFKEYv2_WORDS(sizeof(struct sadb_msg));
47065 + for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
47066 + if(extensions[ext]) {
47067 + total_size += (extensions[ext])->sadb_ext_len;
47068 + }
47069 + }
47070 +
47071 + /* allocate that much space */
47072 + *pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN);
47073 + if(*pfkey_msg == NULL) {
47074 + ERROR("pfkey_msg_build: "
47075 + "memory allocation failed\n");
47076 + SENDERR(ENOMEM);
47077 + }
47078 +
47079 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47080 + "pfkey_msg_build: "
47081 + "pfkey_msg=0p%p allocated %lu bytes, &(extensions[0])=0p%p\n",
47082 + *pfkey_msg,
47083 + (unsigned long)(total_size * IPSEC_PFKEYv2_ALIGN),
47084 + &(extensions[0]));
47085 +
47086 + memcpy(*pfkey_msg,
47087 + extensions[0],
47088 + sizeof(struct sadb_msg));
47089 + (*pfkey_msg)->sadb_msg_len = total_size;
47090 + (*pfkey_msg)->sadb_msg_reserved = 0;
47091 + extensions_seen = 1 ;
47092 +
47093 + /*
47094 + * point pfkey_ext to immediately after the space for the header,
47095 + * i.e. at the first extension location.
47096 + */
47097 + pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg));
47098 +
47099 + for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
47100 + /* copy from extension[ext] to buffer */
47101 + if(extensions[ext]) {
47102 + /* Is this type of extension permitted for this type of message? */
47103 + if(!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] &
47104 + 1<<ext)) {
47105 + ERROR("pfkey_msg_build: "
47106 + "ext type %d not permitted for %d/%d/%d, exts_perm=%08x, 1<<type=%08x\n",
47107 + ext,
47108 + dir,EXT_BITS_PERM,(*pfkey_msg)->sadb_msg_type,
47109 + extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
47110 + 1<<ext);
47111 + SENDERR(EINVAL);
47112 + }
47113 +
47114 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47115 + "pfkey_msg_build: "
47116 + "copying %lu bytes from extensions[%u] (type=%d)\n",
47117 + (unsigned long)(extensions[ext]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN),
47118 + ext,
47119 + extensions[ext]->sadb_ext_type);
47120 +
47121 + memcpy(pfkey_ext,
47122 + extensions[ext],
47123 + (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
47124 + {
47125 + char *pfkey_ext_c = (char *)pfkey_ext;
47126 +
47127 + pfkey_ext_c += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN;
47128 + pfkey_ext = (struct sadb_ext *)pfkey_ext_c;
47129 + }
47130 +
47131 + /* Mark that we have seen this extension and remember the header location */
47132 + extensions_seen |= ( 1 << ext );
47133 + }
47134 + }
47135 +
47136 + /* check required extensions */
47137 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47138 + "pfkey_msg_build: "
47139 + "extensions permitted=%08x, seen=%08x, required=%08x.\n",
47140 + extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
47141 + extensions_seen,
47142 + extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]);
47143 +
47144 +#if 0
47145 + if((extensions_seen &
47146 + extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) !=
47147 + extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) {
47148 + ERROR(PF_KEY_DEBUG_BUILD,
47149 + "pfkey_msg_build: "
47150 + "required extensions missing:%08x.\n",
47151 + extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] -
47152 + (extensions_seen &
47153 + extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) );
47154 + SENDERR(EINVAL);
47155 + }
47156 +#endif
47157 +
47158 +#ifndef __KERNEL__
47159 +/*
47160 + * this is silly, there is no need to reparse the message that we just built.
47161 + *
47162 + */
47163 + if((error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir))) {
47164 + ERROR(
47165 + "pfkey_msg_build: "
47166 + "Trouble parsing newly built pfkey message, error=%d.\n",
47167 + error);
47168 + SENDERR(-error);
47169 + }
47170 +#endif
47171 +
47172 +errlab:
47173 +
47174 + return error;
47175 +}
47176 +
47177 +/*
47178 + * $Log: pfkey_v2_build.c,v $
47179 + * Revision 1.53 2005/11/09 00:30:37 mcr
47180 + * adjusted signed-ness and look.in
47181 + *
47182 + * Revision 1.52 2005/08/14 21:41:15 mcr
47183 + * augment error message when an extension is not permitted.
47184 + *
47185 + * Revision 1.51 2004/10/03 01:26:36 mcr
47186 + * fixes for gcc 3.4 compilation.
47187 + *
47188 + * Revision 1.50 2004/07/10 07:48:35 mcr
47189 + * Moved from linux/lib/libfreeswan/pfkey_v2_build.c,v
47190 + *
47191 + * Revision 1.49 2004/04/12 02:59:06 mcr
47192 + * erroneously moved pfkey_v2_build.c
47193 + *
47194 + * Revision 1.48 2004/04/09 18:00:40 mcr
47195 + * Moved from linux/lib/libfreeswan/pfkey_v2_build.c,v
47196 + *
47197 + * Revision 1.47 2004/03/08 01:59:08 ken
47198 + * freeswan.h -> openswan.h
47199 + *
47200 + * Revision 1.46 2003/12/10 01:20:19 mcr
47201 + * NAT-traversal patches to KLIPS.
47202 + *
47203 + * Revision 1.45 2003/12/04 23:01:12 mcr
47204 + * removed ipsec_netlink.h
47205 + *
47206 + * Revision 1.44 2003/10/31 02:27:12 mcr
47207 + * pulled up port-selector patches and sa_id elimination.
47208 + *
47209 + * Revision 1.43.4.2 2003/10/29 01:11:32 mcr
47210 + * added debugging for pfkey library.
47211 + *
47212 + * Revision 1.43.4.1 2003/09/21 13:59:44 mcr
47213 + * pre-liminary X.509 patch - does not yet pass tests.
47214 + *
47215 + * Revision 1.43 2003/05/07 17:29:17 mcr
47216 + * new function pfkey_debug_func added for us in debugging from
47217 + * pfkey library.
47218 + *
47219 + * Revision 1.42 2003/01/30 02:32:09 rgb
47220 + *
47221 + * Rename SAref table macro names for clarity.
47222 + * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
47223 + *
47224 + * Revision 1.41 2002/12/13 18:16:02 mcr
47225 + * restored sa_ref code
47226 + *
47227 + * Revision 1.40 2002/12/13 18:06:52 mcr
47228 + * temporarily removed sadb_x_sa_ref reference for 2.xx
47229 + *
47230 + * Revision 1.39 2002/12/13 17:43:28 mcr
47231 + * commented out access to sadb_x_sa_ref for 2.xx branch
47232 + *
47233 + * Revision 1.38 2002/10/09 03:12:05 dhr
47234 + *
47235 + * [kenb+dhr] 64-bit fixes
47236 + *
47237 + * Revision 1.37 2002/09/20 15:40:39 rgb
47238 + * Added new function pfkey_sa_ref_build() to accomodate saref parameter.
47239 + *
47240 + * Revision 1.36 2002/09/20 05:01:22 rgb
47241 + * Generalise for platform independance: fix (ia64) using unsigned for sizes.
47242 + *
47243 + * Revision 1.35 2002/07/24 18:44:54 rgb
47244 + * Type fiddling to tame ia64 compiler.
47245 + *
47246 + * Revision 1.34 2002/05/23 07:14:11 rgb
47247 + * Cleaned up %p variants to 0p%p for test suite cleanup.
47248 + *
47249 + * Revision 1.33 2002/04/24 07:55:32 mcr
47250 + * #include patches and Makefiles for post-reorg compilation.
47251 + *
47252 + * Revision 1.32 2002/04/24 07:36:40 mcr
47253 + * Moved from ./lib/pfkey_v2_build.c,v
47254 + *
47255 + * Revision 1.31 2002/01/29 22:25:35 rgb
47256 + * Re-add ipsec_kversion.h to keep MALLOC happy.
47257 + *
47258 + * Revision 1.30 2002/01/29 01:59:09 mcr
47259 + * removal of kversions.h - sources that needed it now use ipsec_param.h.
47260 + * updating of IPv6 structures to match latest in6.h version.
47261 + * removed dead code from openswan.h that also duplicated kversions.h
47262 + * code.
47263 + *
47264 + * Revision 1.29 2001/12/19 21:06:09 rgb
47265 + * Added port numbers to pfkey_address_build() debugging.
47266 + *
47267 + * Revision 1.28 2001/11/06 19:47:47 rgb
47268 + * Added packet parameter to lifetime and comb structures.
47269 + *
47270 + * Revision 1.27 2001/10/18 04:45:24 rgb
47271 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
47272 + * lib/openswan.h version macros moved to lib/kversions.h.
47273 + * Other compiler directive cleanups.
47274 + *
47275 + * Revision 1.26 2001/09/08 21:13:34 rgb
47276 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
47277 + *
47278 + * Revision 1.25 2001/06/14 19:35:16 rgb
47279 + * Update copyright date.
47280 + *
47281 + * Revision 1.24 2001/03/20 03:49:45 rgb
47282 + * Ditch superfluous debug_pfkey declaration.
47283 + * Move misplaced openswan.h inclusion for kernel case.
47284 + *
47285 + * Revision 1.23 2001/03/16 07:41:50 rgb
47286 + * Put openswan.h include before pluto includes.
47287 + *
47288 + * Revision 1.22 2001/02/27 22:24:56 rgb
47289 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
47290 + * Check for satoa() return codes.
47291 + *
47292 + * Revision 1.21 2000/11/17 18:10:30 rgb
47293 + * Fixed bugs mostly relating to spirange, to treat all spi variables as
47294 + * network byte order since this is the way PF_KEYv2 stored spis.
47295 + *
47296 + * Revision 1.20 2000/10/12 00:02:39 rgb
47297 + * Removed 'format, ##' nonsense from debug macros for RH7.0.
47298 + *
47299 + * Revision 1.19 2000/10/10 20:10:20 rgb
47300 + * Added support for debug_ipcomp and debug_verbose to klipsdebug.
47301 + *
47302 + * Revision 1.18 2000/09/12 18:59:54 rgb
47303 + * Added Gerhard's IPv6 support to pfkey parts of libopenswan.
47304 + *
47305 + * Revision 1.17 2000/09/12 03:27:00 rgb
47306 + * Moved DEBUGGING definition to compile kernel with debug off.
47307 + *
47308 + * Revision 1.16 2000/09/08 19:22:12 rgb
47309 + * Fixed pfkey_prop_build() parameter to be only single indirection.
47310 + * Fixed struct alg copy.
47311 + *
47312 + * Revision 1.15 2000/08/20 21:40:01 rgb
47313 + * Added an address parameter sanity check to pfkey_address_build().
47314 + *
47315 + * Revision 1.14 2000/08/15 17:29:23 rgb
47316 + * Fixes from SZI to untested pfkey_prop_build().
47317 + *
47318 + * Revision 1.13 2000/06/02 22:54:14 rgb
47319 + * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
47320 + *
47321 + * Revision 1.12 2000/05/10 19:24:01 rgb
47322 + * Fleshed out sensitivity, proposal and supported extensions.
47323 + *
47324 + * Revision 1.11 2000/03/16 14:07:23 rgb
47325 + * Renamed ALIGN macro to avoid fighting with others in kernel.
47326 + *
47327 + * Revision 1.10 2000/01/24 21:14:35 rgb
47328 + * Added disabled pluto pfkey lib debug flag.
47329 + *
47330 + * Revision 1.9 2000/01/21 06:27:32 rgb
47331 + * Added address cases for eroute flows.
47332 + * Removed unused code.
47333 + * Dropped unused argument to pfkey_x_satype_build().
47334 + * Indented compiler directives for readability.
47335 + * Added klipsdebug switching capability.
47336 + * Fixed SADB_EXT_MAX bug not permitting last extension access.
47337 + *
47338 + * Revision 1.8 1999/12/29 21:17:41 rgb
47339 + * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
47340 + * parameter for cleaner manipulation of extensions[] and to guard
47341 + * against potential memory leaks.
47342 + * Changed the I/F to pfkey_msg_free() for the same reason.
47343 + *
47344 + * Revision 1.7 1999/12/09 23:12:20 rgb
47345 + * Removed unused cruft.
47346 + * Added argument to pfkey_sa_build() to do eroutes.
47347 + * Fixed exttype check in as yet unused pfkey_lifetime_build().
47348 + *
47349 + * Revision 1.6 1999/12/07 19:54:29 rgb
47350 + * Removed static pluto debug flag.
47351 + * Added functions for pfkey message and extensions initialisation
47352 + * and cleanup.
47353 + *
47354 + * Revision 1.5 1999/12/01 22:20:06 rgb
47355 + * Changed pfkey_sa_build to accept an SPI in network byte order.
47356 + * Added <string.h> to quiet userspace compiler.
47357 + * Moved pfkey_lib_debug variable into the library.
47358 + * Removed SATYPE check from pfkey_msg_hdr_build so FLUSH will work.
47359 + * Added extension assembly debugging.
47360 + * Isolated assignment with brackets to be sure of scope.
47361 + *
47362 + * Revision 1.4 1999/11/27 11:57:35 rgb
47363 + * Added ipv6 headers.
47364 + * Remove over-zealous algorithm sanity checkers from pfkey_sa_build.
47365 + * Debugging error messages added.
47366 + * Fixed missing auth and encrypt assignment bug.
47367 + * Add argument to pfkey_msg_parse() for direction.
47368 + * Move parse-after-build check inside pfkey_msg_build().
47369 + * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
47370 + * Add CVS log entry to bottom of file.
47371 + *
47372 + */
47373 --- /dev/null Tue Mar 11 13:02:56 2003
47374 +++ linux/net/ipsec/pfkey_v2_debug.c Mon Feb 9 13:51:03 2004
47375 @@ -0,0 +1,185 @@
47376 +/*
47377 + * @(#) pfkey version 2 debugging messages
47378 + *
47379 + * Copyright (C) 2001 Richard Guy Briggs <rgb@openswan.org>
47380 + * and Michael Richardson <mcr@openswan.org>
47381 + *
47382 + * This program is free software; you can redistribute it and/or modify it
47383 + * under the terms of the GNU General Public License as published by the
47384 + * Free Software Foundation; either version 2 of the License, or (at your
47385 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
47386 + *
47387 + * This program is distributed in the hope that it will be useful, but
47388 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
47389 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
47390 + * for more details.
47391 + *
47392 + * RCSID $Id: pfkey_v2_debug.c,v 1.11 2005/04/06 17:45:16 mcr Exp $
47393 + *
47394 + */
47395 +
47396 +#ifdef __KERNEL__
47397 +
47398 +# include <linux/kernel.h> /* for printk */
47399 +
47400 +# include "openswan/ipsec_kversion.h" /* for malloc switch */
47401 +# ifdef MALLOC_SLAB
47402 +# include <linux/slab.h> /* kmalloc() */
47403 +# else /* MALLOC_SLAB */
47404 +# include <linux/malloc.h> /* kmalloc() */
47405 +# endif /* MALLOC_SLAB */
47406 +# include <linux/errno.h> /* error codes */
47407 +# include <linux/types.h> /* size_t */
47408 +# include <linux/interrupt.h> /* mark_bh */
47409 +
47410 +# include <linux/netdevice.h> /* struct device, and other headers */
47411 +# include <linux/etherdevice.h> /* eth_type_trans */
47412 +extern int debug_pfkey;
47413 +
47414 +#else /* __KERNEL__ */
47415 +
47416 +#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
47417 +# include <sys/types.h>
47418 +#else
47419 +# include <sys/types.h>
47420 +# include <linux/types.h>
47421 +# include <linux/errno.h>
47422 +#endif
47423 +
47424 +#endif /* __KERNEL__ */
47425 +
47426 +#include "openswan.h"
47427 +#include "openswan/pfkeyv2.h"
47428 +#include "openswan/pfkey.h"
47429 +
47430 +/*
47431 + * This file provides ASCII translations of PF_KEY magic numbers.
47432 + *
47433 + */
47434 +
47435 +static char *pfkey_sadb_ext_strings[]={
47436 + "reserved", /* SADB_EXT_RESERVED 0 */
47437 + "security-association", /* SADB_EXT_SA 1 */
47438 + "lifetime-current", /* SADB_EXT_LIFETIME_CURRENT 2 */
47439 + "lifetime-hard", /* SADB_EXT_LIFETIME_HARD 3 */
47440 + "lifetime-soft", /* SADB_EXT_LIFETIME_SOFT 4 */
47441 + "source-address", /* SADB_EXT_ADDRESS_SRC 5 */
47442 + "destination-address", /* SADB_EXT_ADDRESS_DST 6 */
47443 + "proxy-address", /* SADB_EXT_ADDRESS_PROXY 7 */
47444 + "authentication-key", /* SADB_EXT_KEY_AUTH 8 */
47445 + "cipher-key", /* SADB_EXT_KEY_ENCRYPT 9 */
47446 + "source-identity", /* SADB_EXT_IDENTITY_SRC 10 */
47447 + "destination-identity", /* SADB_EXT_IDENTITY_DST 11 */
47448 + "sensitivity-label", /* SADB_EXT_SENSITIVITY 12 */
47449 + "proposal", /* SADB_EXT_PROPOSAL 13 */
47450 + "supported-auth", /* SADB_EXT_SUPPORTED_AUTH 14 */
47451 + "supported-cipher", /* SADB_EXT_SUPPORTED_ENCRYPT 15 */
47452 + "spi-range", /* SADB_EXT_SPIRANGE 16 */
47453 + "X-kmpprivate", /* SADB_X_EXT_KMPRIVATE 17 */
47454 + "X-satype2", /* SADB_X_EXT_SATYPE2 18 */
47455 + "X-security-association", /* SADB_X_EXT_SA2 19 */
47456 + "X-destination-address2", /* SADB_X_EXT_ADDRESS_DST2 20 */
47457 + "X-source-flow-address", /* SADB_X_EXT_ADDRESS_SRC_FLOW 21 */
47458 + "X-dest-flow-address", /* SADB_X_EXT_ADDRESS_DST_FLOW 22 */
47459 + "X-source-mask", /* SADB_X_EXT_ADDRESS_SRC_MASK 23 */
47460 + "X-dest-mask", /* SADB_X_EXT_ADDRESS_DST_MASK 24 */
47461 + "X-set-debug", /* SADB_X_EXT_DEBUG 25 */
47462 + /* NAT_TRAVERSAL */
47463 + "X-NAT-T-type", /* SADB_X_EXT_NAT_T_TYPE 26 */
47464 + "X-NAT-T-sport", /* SADB_X_EXT_NAT_T_SPORT 27 */
47465 + "X-NAT-T-dport", /* SADB_X_EXT_NAT_T_DPORT 28 */
47466 + "X-NAT-T-OA", /* SADB_X_EXT_NAT_T_OA 29 */
47467 +};
47468 +
47469 +const char *
47470 +pfkey_v2_sadb_ext_string(int ext)
47471 +{
47472 + if(ext <= SADB_EXT_MAX) {
47473 + return pfkey_sadb_ext_strings[ext];
47474 + } else {
47475 + return "unknown-ext";
47476 + }
47477 +}
47478 +
47479 +
47480 +static char *pfkey_sadb_type_strings[]={
47481 + "reserved", /* SADB_RESERVED */
47482 + "getspi", /* SADB_GETSPI */
47483 + "update", /* SADB_UPDATE */
47484 + "add", /* SADB_ADD */
47485 + "delete", /* SADB_DELETE */
47486 + "get", /* SADB_GET */
47487 + "acquire", /* SADB_ACQUIRE */
47488 + "register", /* SADB_REGISTER */
47489 + "expire", /* SADB_EXPIRE */
47490 + "flush", /* SADB_FLUSH */
47491 + "dump", /* SADB_DUMP */
47492 + "x-promisc", /* SADB_X_PROMISC */
47493 + "x-pchange", /* SADB_X_PCHANGE */
47494 + "x-groupsa", /* SADB_X_GRPSA */
47495 + "x-addflow(eroute)", /* SADB_X_ADDFLOW */
47496 + "x-delflow(eroute)", /* SADB_X_DELFLOW */
47497 + "x-debug", /* SADB_X_DEBUG */
47498 +};
47499 +
47500 +const char *
47501 +pfkey_v2_sadb_type_string(int sadb_type)
47502 +{
47503 + if(sadb_type <= SADB_MAX) {
47504 + return pfkey_sadb_type_strings[sadb_type];
47505 + } else {
47506 + return "unknown-sadb-type";
47507 + }
47508 +}
47509 +
47510 +
47511 +
47512 +
47513 +/*
47514 + * $Log: pfkey_v2_debug.c,v $
47515 + * Revision 1.11 2005/04/06 17:45:16 mcr
47516 + * always include NAT-T names.
47517 + *
47518 + * Revision 1.10 2004/07/10 07:48:35 mcr
47519 + * Moved from linux/lib/libfreeswan/pfkey_v2_debug.c,v
47520 + *
47521 + * Revision 1.9 2004/03/08 01:59:08 ken
47522 + * freeswan.h -> openswan.h
47523 + *
47524 + * Revision 1.8 2003/12/10 01:20:19 mcr
47525 + * NAT-traversal patches to KLIPS.
47526 + *
47527 + * Revision 1.7 2002/09/20 05:01:26 rgb
47528 + * Fixed limit inclusion error in both type and ext string conversion.
47529 + *
47530 + * Revision 1.6 2002/04/24 07:55:32 mcr
47531 + * #include patches and Makefiles for post-reorg compilation.
47532 + *
47533 + * Revision 1.5 2002/04/24 07:36:40 mcr
47534 + * Moved from ./lib/pfkey_v2_debug.c,v
47535 + *
47536 + * Revision 1.4 2002/01/29 22:25:36 rgb
47537 + * Re-add ipsec_kversion.h to keep MALLOC happy.
47538 + *
47539 + * Revision 1.3 2002/01/29 01:59:09 mcr
47540 + * removal of kversions.h - sources that needed it now use ipsec_param.h.
47541 + * updating of IPv6 structures to match latest in6.h version.
47542 + * removed dead code from openswan.h that also duplicated kversions.h
47543 + * code.
47544 + *
47545 + * Revision 1.2 2002/01/20 20:34:50 mcr
47546 + * added pfkey_v2_sadb_type_string to decode sadb_type to string.
47547 + *
47548 + * Revision 1.1 2001/11/27 05:30:06 mcr
47549 + * initial set of debug strings for pfkey debugging.
47550 + * this will eventually only be included for debug builds.
47551 + *
47552 + * Revision 1.1 2001/09/21 04:12:03 mcr
47553 + * first compilable version.
47554 + *
47555 + *
47556 + * Local variables:
47557 + * c-file-style: "linux"
47558 + * End:
47559 + *
47560 + */
47561 --- /dev/null Tue Mar 11 13:02:56 2003
47562 +++ linux/net/ipsec/pfkey_v2_ext_bits.c Mon Feb 9 13:51:03 2004
47563 @@ -0,0 +1,814 @@
47564 +/*
47565 + * RFC2367 PF_KEYv2 Key management API message parser
47566 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
47567 + *
47568 + * This program is free software; you can redistribute it and/or modify it
47569 + * under the terms of the GNU General Public License as published by the
47570 + * Free Software Foundation; either version 2 of the License, or (at your
47571 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
47572 + *
47573 + * This program is distributed in the hope that it will be useful, but
47574 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
47575 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
47576 + * for more details.
47577 + *
47578 + * RCSID $Id: pfkey_v2_ext_bits.c,v 1.22 2005/05/11 01:45:31 mcr Exp $
47579 + */
47580 +
47581 +/*
47582 + * Template from klips/net/ipsec/ipsec/ipsec_parse.c.
47583 + */
47584 +
47585 +char pfkey_v2_ext_bits_c_version[] = "$Id: pfkey_v2_ext_bits.c,v 1.22 2005/05/11 01:45:31 mcr Exp $";
47586 +
47587 +/*
47588 + * Some ugly stuff to allow consistent debugging code for use in the
47589 + * kernel and in user space
47590 +*/
47591 +
47592 +#if defined(__KERNEL__) && defined(linux)
47593 +
47594 +# include <linux/kernel.h> /* for printk */
47595 +
47596 +# include "openswan/ipsec_kversion.h" /* for malloc switch */
47597 +# ifdef MALLOC_SLAB
47598 +# include <linux/slab.h> /* kmalloc() */
47599 +# else /* MALLOC_SLAB */
47600 +# include <linux/malloc.h> /* kmalloc() */
47601 +# endif /* MALLOC_SLAB */
47602 +# include <linux/errno.h> /* error codes */
47603 +# include <linux/types.h> /* size_t */
47604 +# include <linux/interrupt.h> /* mark_bh */
47605 +
47606 +# include <linux/netdevice.h> /* struct device, and other headers */
47607 +# include <linux/etherdevice.h> /* eth_type_trans */
47608 +# include <linux/ip.h> /* struct iphdr */
47609 +# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
47610 +# include <linux/ipv6.h>
47611 +# endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
47612 +
47613 +#else /* __KERNEL__ */
47614 +
47615 +# include <sys/types.h>
47616 +# include <sys/errno.h>
47617 +# include <stdio.h>
47618 +#endif
47619 +
47620 +#include <openswan.h>
47621 +#include <openswan/pfkeyv2.h>
47622 +#include <openswan/pfkey.h>
47623 +
47624 +unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_EXTENSIONS_MAX] = {
47625 +
47626 +/* INBOUND EXTENSIONS */
47627 +{
47628 +
47629 +/* PERMITTED IN */
47630 +{
47631 +/* SADB_RESERVED */
47632 +0
47633 +,
47634 +/* SADB_GETSPI */
47635 +1<<SADB_EXT_RESERVED
47636 +| 1<<SADB_EXT_ADDRESS_SRC
47637 +| 1<<SADB_EXT_ADDRESS_DST
47638 +| 1<<SADB_EXT_ADDRESS_PROXY
47639 +| 1<<SADB_EXT_SPIRANGE
47640 +,
47641 +/* SADB_UPDATE */
47642 +1<<SADB_EXT_RESERVED
47643 +| 1<<SADB_EXT_SA
47644 +| 1<<SADB_EXT_LIFETIME_CURRENT
47645 +| 1<<SADB_EXT_LIFETIME_HARD
47646 +| 1<<SADB_EXT_LIFETIME_SOFT
47647 +| 1<<SADB_EXT_ADDRESS_SRC
47648 +| 1<<SADB_EXT_ADDRESS_DST
47649 +| 1<<SADB_EXT_ADDRESS_PROXY
47650 +| 1<<SADB_EXT_KEY_AUTH
47651 +| 1<<SADB_EXT_KEY_ENCRYPT
47652 +| 1<<SADB_EXT_IDENTITY_SRC
47653 +| 1<<SADB_EXT_IDENTITY_DST
47654 +| 1<<SADB_EXT_SENSITIVITY
47655 +| 1<<SADB_X_EXT_NAT_T_SPORT
47656 +| 1<<SADB_X_EXT_NAT_T_DPORT
47657 +,
47658 +/* SADB_ADD */
47659 +1<<SADB_EXT_RESERVED
47660 +| 1<<SADB_EXT_SA
47661 +| 1<<SADB_EXT_LIFETIME_HARD
47662 +| 1<<SADB_EXT_LIFETIME_SOFT
47663 +| 1<<SADB_EXT_ADDRESS_SRC
47664 +| 1<<SADB_EXT_ADDRESS_DST
47665 +| 1<<SADB_EXT_ADDRESS_PROXY
47666 +| 1<<SADB_EXT_KEY_AUTH
47667 +| 1<<SADB_EXT_KEY_ENCRYPT
47668 +| 1<<SADB_EXT_IDENTITY_SRC
47669 +| 1<<SADB_EXT_IDENTITY_DST
47670 +| 1<<SADB_EXT_SENSITIVITY
47671 +| 1<<SADB_X_EXT_NAT_T_TYPE
47672 +| 1<<SADB_X_EXT_NAT_T_SPORT
47673 +| 1<<SADB_X_EXT_NAT_T_DPORT
47674 +| 1<<SADB_X_EXT_NAT_T_OA
47675 +,
47676 +/* SADB_DELETE */
47677 +1<<SADB_EXT_RESERVED
47678 +| 1<<SADB_EXT_SA
47679 +| 1<<SADB_EXT_ADDRESS_SRC
47680 +| 1<<SADB_EXT_ADDRESS_DST
47681 +,
47682 +/* SADB_GET */
47683 +1<<SADB_EXT_RESERVED
47684 +| 1<<SADB_EXT_SA
47685 +| 1<<SADB_EXT_ADDRESS_SRC
47686 +| 1<<SADB_EXT_ADDRESS_DST
47687 +,
47688 +/* SADB_ACQUIRE */
47689 +1<<SADB_EXT_RESERVED
47690 +| 1<<SADB_EXT_ADDRESS_SRC
47691 +| 1<<SADB_EXT_ADDRESS_DST
47692 +| 1<<SADB_EXT_ADDRESS_PROXY
47693 +| 1<<SADB_EXT_IDENTITY_SRC
47694 +| 1<<SADB_EXT_IDENTITY_DST
47695 +| 1<<SADB_EXT_SENSITIVITY
47696 +| 1<<SADB_EXT_PROPOSAL
47697 +,
47698 +/* SADB_REGISTER */
47699 +1<<SADB_EXT_RESERVED
47700 +,
47701 +/* SADB_EXPIRE */
47702 +0
47703 +,
47704 +/* SADB_FLUSH */
47705 +1<<SADB_EXT_RESERVED
47706 +,
47707 +/* SADB_DUMP */
47708 +1<<SADB_EXT_RESERVED
47709 +,
47710 +/* SADB_X_PROMISC */
47711 +1<<SADB_EXT_RESERVED
47712 +| 1<<SADB_EXT_SA
47713 +| 1<<SADB_EXT_LIFETIME_CURRENT
47714 +| 1<<SADB_EXT_LIFETIME_HARD
47715 +| 1<<SADB_EXT_LIFETIME_SOFT
47716 +| 1<<SADB_EXT_ADDRESS_SRC
47717 +| 1<<SADB_EXT_ADDRESS_DST
47718 +| 1<<SADB_EXT_ADDRESS_PROXY
47719 +| 1<<SADB_EXT_KEY_AUTH
47720 +| 1<<SADB_EXT_KEY_ENCRYPT
47721 +| 1<<SADB_EXT_IDENTITY_SRC
47722 +| 1<<SADB_EXT_IDENTITY_DST
47723 +| 1<<SADB_EXT_SENSITIVITY
47724 +| 1<<SADB_EXT_PROPOSAL
47725 +| 1<<SADB_EXT_SUPPORTED_AUTH
47726 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
47727 +| 1<<SADB_EXT_SPIRANGE
47728 +| 1<<SADB_X_EXT_KMPRIVATE
47729 +| 1<<SADB_X_EXT_SATYPE2
47730 +| 1<<SADB_X_EXT_SA2
47731 +| 1<<SADB_X_EXT_ADDRESS_DST2
47732 +,
47733 +/* SADB_X_PCHANGE */
47734 +1<<SADB_EXT_RESERVED
47735 +| 1<<SADB_EXT_SA
47736 +| 1<<SADB_EXT_LIFETIME_CURRENT
47737 +| 1<<SADB_EXT_LIFETIME_HARD
47738 +| 1<<SADB_EXT_LIFETIME_SOFT
47739 +| 1<<SADB_EXT_ADDRESS_SRC
47740 +| 1<<SADB_EXT_ADDRESS_DST
47741 +| 1<<SADB_EXT_ADDRESS_PROXY
47742 +| 1<<SADB_EXT_KEY_AUTH
47743 +| 1<<SADB_EXT_KEY_ENCRYPT
47744 +| 1<<SADB_EXT_IDENTITY_SRC
47745 +| 1<<SADB_EXT_IDENTITY_DST
47746 +| 1<<SADB_EXT_SENSITIVITY
47747 +| 1<<SADB_EXT_PROPOSAL
47748 +| 1<<SADB_EXT_SUPPORTED_AUTH
47749 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
47750 +| 1<<SADB_EXT_SPIRANGE
47751 +| 1<<SADB_X_EXT_KMPRIVATE
47752 +| 1<<SADB_X_EXT_SATYPE2
47753 +| 1<<SADB_X_EXT_SA2
47754 +| 1<<SADB_X_EXT_ADDRESS_DST2
47755 +,
47756 +/* SADB_X_GRPSA */
47757 +1<<SADB_EXT_RESERVED
47758 +| 1<<SADB_EXT_SA
47759 +| 1<<SADB_EXT_ADDRESS_DST
47760 +| 1<<SADB_X_EXT_SATYPE2
47761 +| 1<<SADB_X_EXT_SA2
47762 +| 1<<SADB_X_EXT_ADDRESS_DST2
47763 +,
47764 +/* SADB_X_ADDFLOW */
47765 +1<<SADB_EXT_RESERVED
47766 +| 1<<SADB_EXT_SA
47767 +| 1<<SADB_EXT_ADDRESS_SRC
47768 +| 1<<SADB_EXT_ADDRESS_DST
47769 +| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
47770 +| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
47771 +| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
47772 +| 1<<SADB_X_EXT_ADDRESS_DST_MASK
47773 +| 1<<SADB_EXT_IDENTITY_SRC
47774 +| 1<<SADB_EXT_IDENTITY_DST
47775 +| 1<<SADB_X_EXT_PROTOCOL
47776 +,
47777 +/* SADB_X_DELFLOW */
47778 +1<<SADB_EXT_RESERVED
47779 +| 1<<SADB_EXT_SA
47780 +| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
47781 +| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
47782 +| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
47783 +| 1<<SADB_X_EXT_ADDRESS_DST_MASK
47784 +| 1<<SADB_EXT_IDENTITY_SRC
47785 +| 1<<SADB_EXT_IDENTITY_DST
47786 +| 1<<SADB_X_EXT_PROTOCOL
47787 +,
47788 +/* SADB_X_DEBUG */
47789 +1<<SADB_EXT_RESERVED
47790 +| 1<<SADB_X_EXT_DEBUG
47791 +,
47792 +/* SADB_X_NAT_T_NEW_MAPPING */
47793 +1<<SADB_EXT_RESERVED
47794 +| 1<<SADB_EXT_SA
47795 +| 1<<SADB_EXT_ADDRESS_SRC
47796 +| 1<<SADB_EXT_ADDRESS_DST
47797 +| 1<<SADB_X_EXT_NAT_T_SPORT
47798 +| 1<<SADB_X_EXT_NAT_T_DPORT
47799 +},
47800 +
47801 +/* REQUIRED IN */
47802 +{
47803 +/* SADB_RESERVED */
47804 +0
47805 +,
47806 +/* SADB_GETSPI */
47807 +1<<SADB_EXT_RESERVED
47808 +| 1<<SADB_EXT_ADDRESS_SRC
47809 +| 1<<SADB_EXT_ADDRESS_DST
47810 +| 1<<SADB_EXT_SPIRANGE
47811 +,
47812 +/* SADB_UPDATE */
47813 +1<<SADB_EXT_RESERVED
47814 +| 1<<SADB_EXT_SA
47815 +| 1<<SADB_EXT_ADDRESS_SRC
47816 +| 1<<SADB_EXT_ADDRESS_DST
47817 +/*| 1<<SADB_EXT_KEY_AUTH*/
47818 +/*| 1<<SADB_EXT_KEY_ENCRYPT*/
47819 +,
47820 +/* SADB_ADD */
47821 +1<<SADB_EXT_RESERVED
47822 +| 1<<SADB_EXT_SA
47823 +| 1<<SADB_EXT_ADDRESS_SRC
47824 +| 1<<SADB_EXT_ADDRESS_DST
47825 +/*| 1<<SADB_EXT_KEY_AUTH*/
47826 +/*| 1<<SADB_EXT_KEY_ENCRYPT*/
47827 +,
47828 +/* SADB_DELETE */
47829 +1<<SADB_EXT_RESERVED
47830 +| 1<<SADB_EXT_SA
47831 +| 1<<SADB_EXT_ADDRESS_SRC
47832 +| 1<<SADB_EXT_ADDRESS_DST
47833 +,
47834 +/* SADB_GET */
47835 +1<<SADB_EXT_RESERVED
47836 +| 1<<SADB_EXT_SA
47837 +| 1<<SADB_EXT_ADDRESS_SRC
47838 +| 1<<SADB_EXT_ADDRESS_DST
47839 +,
47840 +/* SADB_ACQUIRE */
47841 +1<<SADB_EXT_RESERVED
47842 +| 1<<SADB_EXT_ADDRESS_SRC
47843 +| 1<<SADB_EXT_ADDRESS_DST
47844 +| 1<<SADB_EXT_PROPOSAL
47845 +,
47846 +/* SADB_REGISTER */
47847 +1<<SADB_EXT_RESERVED
47848 +,
47849 +/* SADB_EXPIRE */
47850 +0
47851 +,
47852 +/* SADB_FLUSH */
47853 +1<<SADB_EXT_RESERVED
47854 +,
47855 +/* SADB_DUMP */
47856 +1<<SADB_EXT_RESERVED
47857 +,
47858 +/* SADB_X_PROMISC */
47859 +1<<SADB_EXT_RESERVED
47860 +| 1<<SADB_EXT_SA
47861 +| 1<<SADB_EXT_LIFETIME_CURRENT
47862 +| 1<<SADB_EXT_LIFETIME_HARD
47863 +| 1<<SADB_EXT_LIFETIME_SOFT
47864 +| 1<<SADB_EXT_ADDRESS_SRC
47865 +| 1<<SADB_EXT_ADDRESS_DST
47866 +| 1<<SADB_EXT_ADDRESS_PROXY
47867 +| 1<<SADB_EXT_KEY_AUTH
47868 +| 1<<SADB_EXT_KEY_ENCRYPT
47869 +| 1<<SADB_EXT_IDENTITY_SRC
47870 +| 1<<SADB_EXT_IDENTITY_DST
47871 +| 1<<SADB_EXT_SENSITIVITY
47872 +| 1<<SADB_EXT_PROPOSAL
47873 +| 1<<SADB_EXT_SUPPORTED_AUTH
47874 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
47875 +| 1<<SADB_EXT_SPIRANGE
47876 +| 1<<SADB_X_EXT_KMPRIVATE
47877 +| 1<<SADB_X_EXT_SATYPE2
47878 +| 1<<SADB_X_EXT_SA2
47879 +| 1<<SADB_X_EXT_ADDRESS_DST2
47880 +,
47881 +/* SADB_X_PCHANGE */
47882 +1<<SADB_EXT_RESERVED
47883 +| 1<<SADB_EXT_SA
47884 +| 1<<SADB_EXT_LIFETIME_CURRENT
47885 +| 1<<SADB_EXT_LIFETIME_HARD
47886 +| 1<<SADB_EXT_LIFETIME_SOFT
47887 +| 1<<SADB_EXT_ADDRESS_SRC
47888 +| 1<<SADB_EXT_ADDRESS_DST
47889 +| 1<<SADB_EXT_ADDRESS_PROXY
47890 +| 1<<SADB_EXT_KEY_AUTH
47891 +| 1<<SADB_EXT_KEY_ENCRYPT
47892 +| 1<<SADB_EXT_IDENTITY_SRC
47893 +| 1<<SADB_EXT_IDENTITY_DST
47894 +| 1<<SADB_EXT_SENSITIVITY
47895 +| 1<<SADB_EXT_PROPOSAL
47896 +| 1<<SADB_EXT_SUPPORTED_AUTH
47897 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
47898 +| 1<<SADB_EXT_SPIRANGE
47899 +| 1<<SADB_X_EXT_KMPRIVATE
47900 +| 1<<SADB_X_EXT_SATYPE2
47901 +| 1<<SADB_X_EXT_SA2
47902 +| 1<<SADB_X_EXT_ADDRESS_DST2
47903 +,
47904 +/* SADB_X_GRPSA */
47905 +1<<SADB_EXT_RESERVED
47906 +| 1<<SADB_EXT_SA
47907 +| 1<<SADB_EXT_ADDRESS_DST
47908 +/*| 1<<SADB_X_EXT_SATYPE2*/
47909 +/*| 1<<SADB_X_EXT_SA2*/
47910 +/*| 1<<SADB_X_EXT_ADDRESS_DST2*/
47911 +,
47912 +/* SADB_X_ADDFLOW */
47913 +1<<SADB_EXT_RESERVED
47914 +| 1<<SADB_EXT_SA
47915 +| 1<<SADB_EXT_ADDRESS_DST
47916 +| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
47917 +| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
47918 +| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
47919 +| 1<<SADB_X_EXT_ADDRESS_DST_MASK
47920 +,
47921 +/* SADB_X_DELFLOW */
47922 +1<<SADB_EXT_RESERVED
47923 +/*| 1<<SADB_EXT_SA*/
47924 +#if 0 /* SADB_X_CLREROUTE doesn't need all these... */
47925 +| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
47926 +| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
47927 +| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
47928 +| 1<<SADB_X_EXT_ADDRESS_DST_MASK
47929 +#endif
47930 +,
47931 +/* SADB_X_DEBUG */
47932 +1<<SADB_EXT_RESERVED
47933 +| 1<<SADB_X_EXT_DEBUG
47934 +,
47935 +/* SADB_X_NAT_T_NEW_MAPPING */
47936 +1<<SADB_EXT_RESERVED
47937 +| 1<<SADB_EXT_SA
47938 +| 1<<SADB_EXT_ADDRESS_SRC
47939 +| 1<<SADB_EXT_ADDRESS_DST
47940 +| 1<<SADB_X_EXT_NAT_T_SPORT
47941 +| 1<<SADB_X_EXT_NAT_T_DPORT
47942 +}
47943 +
47944 +},
47945 +
47946 +/* OUTBOUND EXTENSIONS */
47947 +{
47948 +
47949 +/* PERMITTED OUT */
47950 +{
47951 +/* SADB_RESERVED */
47952 +0
47953 +,
47954 +/* SADB_GETSPI */
47955 +1<<SADB_EXT_RESERVED
47956 +| 1<<SADB_EXT_SA
47957 +| 1<<SADB_EXT_ADDRESS_SRC
47958 +| 1<<SADB_EXT_ADDRESS_DST
47959 +,
47960 +/* SADB_UPDATE */
47961 +1<<SADB_EXT_RESERVED
47962 +| 1<<SADB_EXT_SA
47963 +| 1<<SADB_EXT_LIFETIME_CURRENT
47964 +| 1<<SADB_EXT_LIFETIME_HARD
47965 +| 1<<SADB_EXT_LIFETIME_SOFT
47966 +| 1<<SADB_EXT_ADDRESS_SRC
47967 +| 1<<SADB_EXT_ADDRESS_DST
47968 +| 1<<SADB_EXT_ADDRESS_PROXY
47969 +| 1<<SADB_EXT_IDENTITY_SRC
47970 +| 1<<SADB_EXT_IDENTITY_DST
47971 +| 1<<SADB_EXT_SENSITIVITY
47972 +| 1<<SADB_X_EXT_NAT_T_SPORT
47973 +| 1<<SADB_X_EXT_NAT_T_DPORT
47974 +,
47975 +/* SADB_ADD */
47976 +1<<SADB_EXT_RESERVED
47977 +| 1<<SADB_EXT_SA
47978 +| 1<<SADB_EXT_LIFETIME_HARD
47979 +| 1<<SADB_EXT_LIFETIME_SOFT
47980 +| 1<<SADB_EXT_ADDRESS_SRC
47981 +| 1<<SADB_EXT_ADDRESS_DST
47982 +| 1<<SADB_EXT_IDENTITY_SRC
47983 +| 1<<SADB_EXT_IDENTITY_DST
47984 +| 1<<SADB_EXT_SENSITIVITY
47985 +| 1<<SADB_X_EXT_NAT_T_TYPE
47986 +| 1<<SADB_X_EXT_NAT_T_SPORT
47987 +| 1<<SADB_X_EXT_NAT_T_DPORT
47988 +| 1<<SADB_X_EXT_NAT_T_OA
47989 +,
47990 +/* SADB_DELETE */
47991 +1<<SADB_EXT_RESERVED
47992 +| 1<<SADB_EXT_SA
47993 +| 1<<SADB_EXT_ADDRESS_SRC
47994 +| 1<<SADB_EXT_ADDRESS_DST
47995 +,
47996 +/* SADB_GET */
47997 +1<<SADB_EXT_RESERVED
47998 +| 1<<SADB_EXT_SA
47999 +| 1<<SADB_EXT_LIFETIME_CURRENT
48000 +| 1<<SADB_EXT_LIFETIME_HARD
48001 +| 1<<SADB_EXT_LIFETIME_SOFT
48002 +| 1<<SADB_EXT_ADDRESS_SRC
48003 +| 1<<SADB_EXT_ADDRESS_DST
48004 +| 1<<SADB_EXT_ADDRESS_PROXY
48005 +| 1<<SADB_EXT_KEY_AUTH
48006 +| 1<<SADB_EXT_KEY_ENCRYPT
48007 +| 1<<SADB_EXT_IDENTITY_SRC
48008 +| 1<<SADB_EXT_IDENTITY_DST
48009 +| 1<<SADB_EXT_SENSITIVITY
48010 +| 1<<SADB_X_EXT_NAT_T_TYPE
48011 +| 1<<SADB_X_EXT_NAT_T_SPORT
48012 +| 1<<SADB_X_EXT_NAT_T_DPORT
48013 +| 1<<SADB_X_EXT_NAT_T_OA
48014 +,
48015 +/* SADB_ACQUIRE */
48016 +1<<SADB_EXT_RESERVED
48017 +| 1<<SADB_EXT_ADDRESS_SRC
48018 +| 1<<SADB_EXT_ADDRESS_DST
48019 +| 1<<SADB_EXT_ADDRESS_PROXY
48020 +| 1<<SADB_EXT_IDENTITY_SRC
48021 +| 1<<SADB_EXT_IDENTITY_DST
48022 +| 1<<SADB_EXT_SENSITIVITY
48023 +| 1<<SADB_EXT_PROPOSAL
48024 +,
48025 +/* SADB_REGISTER */
48026 +1<<SADB_EXT_RESERVED
48027 +| 1<<SADB_EXT_SUPPORTED_AUTH
48028 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48029 +,
48030 +/* SADB_EXPIRE */
48031 +1<<SADB_EXT_RESERVED
48032 +| 1<<SADB_EXT_SA
48033 +| 1<<SADB_EXT_LIFETIME_CURRENT
48034 +| 1<<SADB_EXT_LIFETIME_HARD
48035 +| 1<<SADB_EXT_LIFETIME_SOFT
48036 +| 1<<SADB_EXT_ADDRESS_SRC
48037 +| 1<<SADB_EXT_ADDRESS_DST
48038 +,
48039 +/* SADB_FLUSH */
48040 +1<<SADB_EXT_RESERVED
48041 +,
48042 +/* SADB_DUMP */
48043 +1<<SADB_EXT_RESERVED
48044 +| 1<<SADB_EXT_SA
48045 +| 1<<SADB_EXT_LIFETIME_CURRENT
48046 +| 1<<SADB_EXT_LIFETIME_HARD
48047 +| 1<<SADB_EXT_LIFETIME_SOFT
48048 +| 1<<SADB_EXT_ADDRESS_SRC
48049 +| 1<<SADB_EXT_ADDRESS_DST
48050 +| 1<<SADB_EXT_ADDRESS_PROXY
48051 +| 1<<SADB_EXT_KEY_AUTH
48052 +| 1<<SADB_EXT_KEY_ENCRYPT
48053 +| 1<<SADB_EXT_IDENTITY_SRC
48054 +| 1<<SADB_EXT_IDENTITY_DST
48055 +| 1<<SADB_EXT_SENSITIVITY
48056 +| 1<<SADB_X_EXT_NAT_T_TYPE
48057 +| 1<<SADB_X_EXT_NAT_T_SPORT
48058 +| 1<<SADB_X_EXT_NAT_T_DPORT
48059 +| 1<<SADB_X_EXT_NAT_T_OA
48060 +,
48061 +/* SADB_X_PROMISC */
48062 +1<<SADB_EXT_RESERVED
48063 +| 1<<SADB_EXT_SA
48064 +| 1<<SADB_EXT_LIFETIME_CURRENT
48065 +| 1<<SADB_EXT_LIFETIME_HARD
48066 +| 1<<SADB_EXT_LIFETIME_SOFT
48067 +| 1<<SADB_EXT_ADDRESS_SRC
48068 +| 1<<SADB_EXT_ADDRESS_DST
48069 +| 1<<SADB_EXT_ADDRESS_PROXY
48070 +| 1<<SADB_EXT_KEY_AUTH
48071 +| 1<<SADB_EXT_KEY_ENCRYPT
48072 +| 1<<SADB_EXT_IDENTITY_SRC
48073 +| 1<<SADB_EXT_IDENTITY_DST
48074 +| 1<<SADB_EXT_SENSITIVITY
48075 +| 1<<SADB_EXT_PROPOSAL
48076 +| 1<<SADB_EXT_SUPPORTED_AUTH
48077 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48078 +| 1<<SADB_EXT_SPIRANGE
48079 +| 1<<SADB_X_EXT_KMPRIVATE
48080 +| 1<<SADB_X_EXT_SATYPE2
48081 +| 1<<SADB_X_EXT_SA2
48082 +| 1<<SADB_X_EXT_ADDRESS_DST2
48083 +,
48084 +/* SADB_X_PCHANGE */
48085 +1<<SADB_EXT_RESERVED
48086 +| 1<<SADB_EXT_SA
48087 +| 1<<SADB_EXT_LIFETIME_CURRENT
48088 +| 1<<SADB_EXT_LIFETIME_HARD
48089 +| 1<<SADB_EXT_LIFETIME_SOFT
48090 +| 1<<SADB_EXT_ADDRESS_SRC
48091 +| 1<<SADB_EXT_ADDRESS_DST
48092 +| 1<<SADB_EXT_ADDRESS_PROXY
48093 +| 1<<SADB_EXT_KEY_AUTH
48094 +| 1<<SADB_EXT_KEY_ENCRYPT
48095 +| 1<<SADB_EXT_IDENTITY_SRC
48096 +| 1<<SADB_EXT_IDENTITY_DST
48097 +| 1<<SADB_EXT_SENSITIVITY
48098 +| 1<<SADB_EXT_PROPOSAL
48099 +| 1<<SADB_EXT_SUPPORTED_AUTH
48100 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48101 +| 1<<SADB_EXT_SPIRANGE
48102 +| 1<<SADB_X_EXT_KMPRIVATE
48103 +| 1<<SADB_X_EXT_SATYPE2
48104 +| 1<<SADB_X_EXT_SA2
48105 +| 1<<SADB_X_EXT_ADDRESS_DST2
48106 +,
48107 +/* SADB_X_GRPSA */
48108 +1<<SADB_EXT_RESERVED
48109 +| 1<<SADB_EXT_SA
48110 +| 1<<SADB_EXT_ADDRESS_DST
48111 +| 1<<SADB_X_EXT_SATYPE2
48112 +| 1<<SADB_X_EXT_SA2
48113 +| 1<<SADB_X_EXT_ADDRESS_DST2
48114 +,
48115 +/* SADB_X_ADDFLOW */
48116 +1<<SADB_EXT_RESERVED
48117 +| 1<<SADB_EXT_SA
48118 +| 1<<SADB_EXT_ADDRESS_SRC
48119 +| 1<<SADB_EXT_ADDRESS_DST
48120 +| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48121 +| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48122 +| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48123 +| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48124 +| 1<<SADB_X_EXT_PROTOCOL
48125 +,
48126 +/* SADB_X_DELFLOW */
48127 +1<<SADB_EXT_RESERVED
48128 +| 1<<SADB_EXT_SA
48129 +| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48130 +| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48131 +| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48132 +| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48133 +| 1<<SADB_X_EXT_PROTOCOL
48134 +,
48135 +/* SADB_X_DEBUG */
48136 +1<<SADB_EXT_RESERVED
48137 +| 1<<SADB_X_EXT_DEBUG
48138 +,
48139 +/* SADB_X_NAT_T_NEW_MAPPING */
48140 +1<<SADB_EXT_RESERVED
48141 +| 1<<SADB_EXT_SA
48142 +| 1<<SADB_EXT_ADDRESS_SRC
48143 +| 1<<SADB_EXT_ADDRESS_DST
48144 +| 1<<SADB_X_EXT_NAT_T_SPORT
48145 +| 1<<SADB_X_EXT_NAT_T_DPORT
48146 +},
48147 +
48148 +/* REQUIRED OUT */
48149 +{
48150 +/* SADB_RESERVED */
48151 +0
48152 +,
48153 +/* SADB_GETSPI */
48154 +1<<SADB_EXT_RESERVED
48155 +| 1<<SADB_EXT_SA
48156 +| 1<<SADB_EXT_ADDRESS_SRC
48157 +| 1<<SADB_EXT_ADDRESS_DST
48158 +,
48159 +/* SADB_UPDATE */
48160 +1<<SADB_EXT_RESERVED
48161 +| 1<<SADB_EXT_SA
48162 +| 1<<SADB_EXT_ADDRESS_SRC
48163 +| 1<<SADB_EXT_ADDRESS_DST
48164 +,
48165 +/* SADB_ADD */
48166 +1<<SADB_EXT_RESERVED
48167 +| 1<<SADB_EXT_SA
48168 +| 1<<SADB_EXT_ADDRESS_SRC
48169 +| 1<<SADB_EXT_ADDRESS_DST
48170 +,
48171 +/* SADB_DELETE */
48172 +1<<SADB_EXT_RESERVED
48173 +| 1<<SADB_EXT_SA
48174 +| 1<<SADB_EXT_ADDRESS_SRC
48175 +| 1<<SADB_EXT_ADDRESS_DST
48176 +,
48177 +/* SADB_GET */
48178 +1<<SADB_EXT_RESERVED
48179 +| 1<<SADB_EXT_SA
48180 +| 1<<SADB_EXT_ADDRESS_SRC
48181 +| 1<<SADB_EXT_ADDRESS_DST
48182 +/* | 1<<SADB_EXT_KEY_AUTH */
48183 +/* | 1<<SADB_EXT_KEY_ENCRYPT */
48184 +,
48185 +/* SADB_ACQUIRE */
48186 +1<<SADB_EXT_RESERVED
48187 +| 1<<SADB_EXT_ADDRESS_SRC
48188 +| 1<<SADB_EXT_ADDRESS_DST
48189 +| 1<<SADB_EXT_PROPOSAL
48190 +,
48191 +/* SADB_REGISTER */
48192 +1<<SADB_EXT_RESERVED
48193 +/* | 1<<SADB_EXT_SUPPORTED_AUTH
48194 + | 1<<SADB_EXT_SUPPORTED_ENCRYPT */
48195 +,
48196 +/* SADB_EXPIRE */
48197 +1<<SADB_EXT_RESERVED
48198 +| 1<<SADB_EXT_SA
48199 +| 1<<SADB_EXT_LIFETIME_CURRENT
48200 +/* | 1<<SADB_EXT_LIFETIME_HARD
48201 + | 1<<SADB_EXT_LIFETIME_SOFT */
48202 +| 1<<SADB_EXT_ADDRESS_SRC
48203 +| 1<<SADB_EXT_ADDRESS_DST
48204 +,
48205 +/* SADB_FLUSH */
48206 +1<<SADB_EXT_RESERVED
48207 +,
48208 +/* SADB_DUMP */
48209 +1<<SADB_EXT_RESERVED
48210 +| 1<<SADB_EXT_SA
48211 +| 1<<SADB_EXT_ADDRESS_SRC
48212 +| 1<<SADB_EXT_ADDRESS_DST
48213 +| 1<<SADB_EXT_KEY_AUTH
48214 +| 1<<SADB_EXT_KEY_ENCRYPT
48215 +,
48216 +/* SADB_X_PROMISC */
48217 +1<<SADB_EXT_RESERVED
48218 +| 1<<SADB_EXT_SA
48219 +| 1<<SADB_EXT_LIFETIME_CURRENT
48220 +| 1<<SADB_EXT_LIFETIME_HARD
48221 +| 1<<SADB_EXT_LIFETIME_SOFT
48222 +| 1<<SADB_EXT_ADDRESS_SRC
48223 +| 1<<SADB_EXT_ADDRESS_DST
48224 +| 1<<SADB_EXT_ADDRESS_PROXY
48225 +| 1<<SADB_EXT_KEY_AUTH
48226 +| 1<<SADB_EXT_KEY_ENCRYPT
48227 +| 1<<SADB_EXT_IDENTITY_SRC
48228 +| 1<<SADB_EXT_IDENTITY_DST
48229 +| 1<<SADB_EXT_SENSITIVITY
48230 +| 1<<SADB_EXT_PROPOSAL
48231 +| 1<<SADB_EXT_SUPPORTED_AUTH
48232 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48233 +| 1<<SADB_EXT_SPIRANGE
48234 +| 1<<SADB_X_EXT_KMPRIVATE
48235 +| 1<<SADB_X_EXT_SATYPE2
48236 +| 1<<SADB_X_EXT_SA2
48237 +| 1<<SADB_X_EXT_ADDRESS_DST2
48238 +,
48239 +/* SADB_X_PCHANGE */
48240 +1<<SADB_EXT_RESERVED
48241 +| 1<<SADB_EXT_SA
48242 +| 1<<SADB_EXT_LIFETIME_CURRENT
48243 +| 1<<SADB_EXT_LIFETIME_HARD
48244 +| 1<<SADB_EXT_LIFETIME_SOFT
48245 +| 1<<SADB_EXT_ADDRESS_SRC
48246 +| 1<<SADB_EXT_ADDRESS_DST
48247 +| 1<<SADB_EXT_ADDRESS_PROXY
48248 +| 1<<SADB_EXT_KEY_AUTH
48249 +| 1<<SADB_EXT_KEY_ENCRYPT
48250 +| 1<<SADB_EXT_IDENTITY_SRC
48251 +| 1<<SADB_EXT_IDENTITY_DST
48252 +| 1<<SADB_EXT_SENSITIVITY
48253 +| 1<<SADB_EXT_PROPOSAL
48254 +| 1<<SADB_EXT_SUPPORTED_AUTH
48255 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48256 +| 1<<SADB_EXT_SPIRANGE
48257 +| 1<<SADB_X_EXT_KMPRIVATE
48258 +| 1<<SADB_X_EXT_SATYPE2
48259 +| 1<<SADB_X_EXT_SA2
48260 +| 1<<SADB_X_EXT_ADDRESS_DST2
48261 +,
48262 +/* SADB_X_GRPSA */
48263 +1<<SADB_EXT_RESERVED
48264 +| 1<<SADB_EXT_SA
48265 +| 1<<SADB_EXT_ADDRESS_DST
48266 +,
48267 +/* SADB_X_ADDFLOW */
48268 +1<<SADB_EXT_RESERVED
48269 +| 1<<SADB_EXT_SA
48270 +| 1<<SADB_EXT_ADDRESS_DST
48271 +| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48272 +| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48273 +| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48274 +| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48275 +,
48276 +/* SADB_X_DELFLOW */
48277 +1<<SADB_EXT_RESERVED
48278 +/*| 1<<SADB_EXT_SA*/
48279 +| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48280 +| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48281 +| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48282 +| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48283 +,
48284 +/* SADB_X_DEBUG */
48285 +1<<SADB_EXT_RESERVED
48286 +| 1<<SADB_X_EXT_DEBUG
48287 +,
48288 +/* SADB_X_NAT_T_NEW_MAPPING */
48289 +1<<SADB_EXT_RESERVED
48290 +| 1<<SADB_EXT_SA
48291 +| 1<<SADB_EXT_ADDRESS_SRC
48292 +| 1<<SADB_EXT_ADDRESS_DST
48293 +| 1<<SADB_X_EXT_NAT_T_SPORT
48294 +| 1<<SADB_X_EXT_NAT_T_DPORT
48295 +}
48296 +}
48297 +};
48298 +
48299 +/*
48300 + * $Log: pfkey_v2_ext_bits.c,v $
48301 + * Revision 1.22 2005/05/11 01:45:31 mcr
48302 + * make pfkey.h standalone.
48303 + *
48304 + * Revision 1.21 2004/07/10 07:48:36 mcr
48305 + * Moved from linux/lib/libfreeswan/pfkey_v2_ext_bits.c,v
48306 + *
48307 + * Revision 1.20 2004/03/08 01:59:08 ken
48308 + * freeswan.h -> openswan.h
48309 + *
48310 + * Revision 1.19 2003/12/22 21:38:13 mcr
48311 + * removed extraenous #endif.
48312 + *
48313 + * Revision 1.18 2003/12/22 19:34:41 mcr
48314 + * added 0.6c NAT-T patch.
48315 + *
48316 + * Revision 1.17 2003/12/10 01:20:19 mcr
48317 + * NAT-traversal patches to KLIPS.
48318 + *
48319 + * Revision 1.16 2003/10/31 02:27:12 mcr
48320 + * pulled up port-selector patches and sa_id elimination.
48321 + *
48322 + * Revision 1.15.30.1 2003/09/21 13:59:44 mcr
48323 + * pre-liminary X.509 patch - does not yet pass tests.
48324 + *
48325 + * Revision 1.15 2002/04/24 07:55:32 mcr
48326 + * #include patches and Makefiles for post-reorg compilation.
48327 + *
48328 + * Revision 1.14 2002/04/24 07:36:40 mcr
48329 + * Moved from ./lib/pfkey_v2_ext_bits.c,v
48330 + *
48331 + * Revision 1.13 2002/01/29 22:25:36 rgb
48332 + * Re-add ipsec_kversion.h to keep MALLOC happy.
48333 + *
48334 + * Revision 1.12 2002/01/29 01:59:10 mcr
48335 + * removal of kversions.h - sources that needed it now use ipsec_param.h.
48336 + * updating of IPv6 structures to match latest in6.h version.
48337 + * removed dead code from openswan.h that also duplicated kversions.h
48338 + * code.
48339 + *
48340 + * Revision 1.11 2001/10/18 04:45:24 rgb
48341 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
48342 + * lib/openswan.h version macros moved to lib/kversions.h.
48343 + * Other compiler directive cleanups.
48344 + *
48345 + * Revision 1.10 2001/09/08 21:13:35 rgb
48346 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
48347 + *
48348 + * Revision 1.9 2001/06/14 19:35:16 rgb
48349 + * Update copyright date.
48350 + *
48351 + * Revision 1.8 2001/03/26 23:07:36 rgb
48352 + * Remove requirement for auth and enc key from UPDATE.
48353 + *
48354 + * Revision 1.7 2000/09/12 22:35:37 rgb
48355 + * Restructured to remove unused extensions from CLEARFLOW messages.
48356 + *
48357 + * Revision 1.6 2000/09/09 06:39:01 rgb
48358 + * Added comments for clarity.
48359 + *
48360 + * Revision 1.5 2000/06/02 22:54:14 rgb
48361 + * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
48362 + *
48363 + * Revision 1.4 2000/01/21 06:27:56 rgb
48364 + * Added address cases for eroute flows.
48365 + * Added comments for each message type.
48366 + * Added klipsdebug switching capability.
48367 + * Fixed GRPSA bitfields.
48368 + *
48369 + * Revision 1.3 1999/12/01 22:20:27 rgb
48370 + * Remove requirement for a proxy address in an incoming getspi message.
48371 + *
48372 + * Revision 1.2 1999/11/27 11:57:06 rgb
48373 + * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
48374 + * Add CVS log entry to bottom of file.
48375 + * Cleaned out unused bits.
48376 + *
48377 + */
48378 --- /dev/null Tue Mar 11 13:02:56 2003
48379 +++ linux/net/ipsec/pfkey_v2_ext_process.c Mon Feb 9 13:51:03 2004
48380 @@ -0,0 +1,865 @@
48381 +/*
48382 + * @(#) RFC2367 PF_KEYv2 Key management API message parser
48383 + * Copyright (C) 1998-2003 Richard Guy Briggs.
48384 + * Copyright (C) 2004-2006 Michael Richardson <mcr@xelerance.com>
48385 + *
48386 + * This program is free software; you can redistribute it and/or modify it
48387 + * under the terms of the GNU General Public License as published by the
48388 + * Free Software Foundation; either version 2 of the License, or (at your
48389 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
48390 + *
48391 + * This program is distributed in the hope that it will be useful, but
48392 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
48393 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
48394 + * for more details.
48395 + *
48396 + * RCSID $Id: pfkey_v2_ext_process.c,v 1.20 2005/04/29 05:10:22 mcr Exp $
48397 + */
48398 +
48399 +/*
48400 + * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
48401 + */
48402 +
48403 +char pfkey_v2_ext_process_c_version[] = "$Id: pfkey_v2_ext_process.c,v 1.20 2005/04/29 05:10:22 mcr Exp $";
48404 +
48405 +#ifndef AUTOCONF_INCLUDED
48406 +#include <linux/config.h>
48407 +#endif
48408 +#include <linux/version.h>
48409 +#include <linux/kernel.h> /* printk() */
48410 +
48411 +#include "openswan/ipsec_param.h"
48412 +
48413 +#ifdef MALLOC_SLAB
48414 +# include <linux/slab.h> /* kmalloc() */
48415 +#else /* MALLOC_SLAB */
48416 +# include <linux/malloc.h> /* kmalloc() */
48417 +#endif /* MALLOC_SLAB */
48418 +#include <linux/errno.h> /* error codes */
48419 +#include <linux/types.h> /* size_t */
48420 +#include <linux/interrupt.h> /* mark_bh */
48421 +
48422 +#include <linux/netdevice.h> /* struct device, and other headers */
48423 +#include <linux/etherdevice.h> /* eth_type_trans */
48424 +#include <linux/ip.h> /* struct iphdr */
48425 +#include <linux/skbuff.h>
48426 +
48427 +#include <openswan.h>
48428 +
48429 +#include <crypto/des.h>
48430 +
48431 +#ifdef SPINLOCK
48432 +# ifdef SPINLOCK_23
48433 +# include <linux/spinlock.h> /* *lock* */
48434 +# else /* SPINLOCK_23 */
48435 +# include <asm/spinlock.h> /* *lock* */
48436 +# endif /* SPINLOCK_23 */
48437 +#endif /* SPINLOCK */
48438 +#ifdef NET_21
48439 +# include <linux/in6.h>
48440 +# define ip_chk_addr inet_addr_type
48441 +# define IS_MYADDR RTN_LOCAL
48442 +#endif
48443 +
48444 +#include <net/ip.h>
48445 +#ifdef NETLINK_SOCK
48446 +# include <linux/netlink.h>
48447 +#else
48448 +# include <net/netlink.h>
48449 +#endif
48450 +
48451 +#include <linux/random.h> /* get_random_bytes() */
48452 +
48453 +#include "openswan/radij.h"
48454 +#include "openswan/ipsec_encap.h"
48455 +#include "openswan/ipsec_sa.h"
48456 +
48457 +#include "openswan/ipsec_radij.h"
48458 +#include "openswan/ipsec_xform.h"
48459 +#include "openswan/ipsec_ah.h"
48460 +#include "openswan/ipsec_esp.h"
48461 +#include "openswan/ipsec_tunnel.h"
48462 +#include "openswan/ipsec_rcv.h"
48463 +#include "openswan/ipcomp.h"
48464 +
48465 +#include <openswan/pfkeyv2.h>
48466 +#include <openswan/pfkey.h>
48467 +
48468 +#include "openswan/ipsec_proto.h"
48469 +#include "openswan/ipsec_alg.h"
48470 +
48471 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
48472 +
48473 +/* returns 0 on success */
48474 +int
48475 +pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
48476 +{
48477 + struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
48478 + int error = 0;
48479 + struct ipsec_sa* ipsp;
48480 +
48481 + KLIPS_PRINT(debug_pfkey,
48482 + "klips_debug:pfkey_sa_process: .\n");
48483 +
48484 + if(!extr || !extr->ips) {
48485 + KLIPS_PRINT(debug_pfkey,
48486 + "klips_debug:pfkey_sa_process: "
48487 + "extr or extr->ips is NULL, fatal\n");
48488 + SENDERR(EINVAL);
48489 + }
48490 +
48491 + switch(pfkey_ext->sadb_ext_type) {
48492 + case SADB_EXT_SA:
48493 + ipsp = extr->ips;
48494 + break;
48495 + case SADB_X_EXT_SA2:
48496 + if(extr->ips2 == NULL) {
48497 + extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
48498 + }
48499 + if(extr->ips2 == NULL) {
48500 + SENDERR(-error);
48501 + }
48502 + ipsp = extr->ips2;
48503 + break;
48504 + default:
48505 + KLIPS_PRINT(debug_pfkey,
48506 + "klips_debug:pfkey_sa_process: "
48507 + "invalid exttype=%d.\n",
48508 + pfkey_ext->sadb_ext_type);
48509 + SENDERR(EINVAL);
48510 + }
48511 +
48512 + ipsp->ips_said.spi = pfkey_sa->sadb_sa_spi;
48513 + ipsp->ips_replaywin = pfkey_sa->sadb_sa_replay;
48514 + ipsp->ips_state = pfkey_sa->sadb_sa_state;
48515 + ipsp->ips_flags = pfkey_sa->sadb_sa_flags;
48516 + ipsp->ips_replaywin_lastseq = ipsp->ips_replaywin_bitmap = 0;
48517 + ipsp->ips_ref = pfkey_sa->sadb_x_sa_ref;
48518 +
48519 + switch(ipsp->ips_said.proto) {
48520 + case IPPROTO_AH:
48521 + ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
48522 + ipsp->ips_encalg = SADB_EALG_NONE;
48523 + break;
48524 + case IPPROTO_ESP:
48525 + ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
48526 + ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
48527 + ipsec_alg_sa_init(ipsp);
48528 + break;
48529 + case IPPROTO_IPIP:
48530 + ipsp->ips_authalg = AH_NONE;
48531 + ipsp->ips_encalg = ESP_NONE;
48532 + break;
48533 +#ifdef CONFIG_KLIPS_IPCOMP
48534 + case IPPROTO_COMP:
48535 + ipsp->ips_authalg = AH_NONE;
48536 + ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
48537 + break;
48538 +#endif /* CONFIG_KLIPS_IPCOMP */
48539 + case IPPROTO_INT:
48540 + ipsp->ips_authalg = AH_NONE;
48541 + ipsp->ips_encalg = ESP_NONE;
48542 + break;
48543 + case 0:
48544 + break;
48545 + default:
48546 + KLIPS_PRINT(debug_pfkey,
48547 + "klips_debug:pfkey_sa_process: "
48548 + "unknown proto=%d.\n",
48549 + ipsp->ips_said.proto);
48550 + SENDERR(EINVAL);
48551 + }
48552 +
48553 +errlab:
48554 + return error;
48555 +}
48556 +
48557 +int
48558 +pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
48559 +{
48560 + int error = 0;
48561 + struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
48562 +
48563 + KLIPS_PRINT(debug_pfkey,
48564 + "klips_debug:pfkey_lifetime_process: .\n");
48565 +
48566 + if(!extr || !extr->ips) {
48567 + KLIPS_PRINT(debug_pfkey,
48568 + "klips_debug:pfkey_lifetime_process: "
48569 + "extr or extr->ips is NULL, fatal\n");
48570 + SENDERR(EINVAL);
48571 + }
48572 +
48573 + switch(pfkey_lifetime->sadb_lifetime_exttype) {
48574 + case SADB_EXT_LIFETIME_CURRENT:
48575 + KLIPS_PRINT(debug_pfkey,
48576 + "klips_debug:pfkey_lifetime_process: "
48577 + "lifetime_current not supported yet.\n");
48578 + SENDERR(EINVAL);
48579 + break;
48580 + case SADB_EXT_LIFETIME_HARD:
48581 + ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_allocations,
48582 + pfkey_lifetime->sadb_lifetime_allocations);
48583 +
48584 + ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_bytes,
48585 + pfkey_lifetime->sadb_lifetime_bytes);
48586 +
48587 + ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_addtime,
48588 + pfkey_lifetime->sadb_lifetime_addtime);
48589 +
48590 + ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_usetime,
48591 + pfkey_lifetime->sadb_lifetime_usetime);
48592 +
48593 + break;
48594 +
48595 + case SADB_EXT_LIFETIME_SOFT:
48596 + ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_allocations,
48597 + pfkey_lifetime->sadb_lifetime_allocations);
48598 +
48599 + ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_bytes,
48600 + pfkey_lifetime->sadb_lifetime_bytes);
48601 +
48602 + ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_addtime,
48603 + pfkey_lifetime->sadb_lifetime_addtime);
48604 +
48605 + ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_usetime,
48606 + pfkey_lifetime->sadb_lifetime_usetime);
48607 +
48608 + break;
48609 + default:
48610 + KLIPS_PRINT(debug_pfkey,
48611 + "klips_debug:pfkey_lifetime_process: "
48612 + "invalid exttype=%d.\n",
48613 + pfkey_ext->sadb_ext_type);
48614 + SENDERR(EINVAL);
48615 + }
48616 +
48617 +errlab:
48618 + return error;
48619 +}
48620 +
48621 +int
48622 +pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
48623 +{
48624 + int error = 0;
48625 + int saddr_len = 0;
48626 + char ipaddr_txt[ADDRTOA_BUF];
48627 + unsigned char **sap;
48628 + unsigned short * portp = 0;
48629 + struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
48630 + struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
48631 + struct ipsec_sa* ipsp;
48632 +
48633 + KLIPS_PRINT(debug_pfkey,
48634 + "klips_debug:pfkey_address_process:\n");
48635 +
48636 + if(!extr || !extr->ips) {
48637 + KLIPS_PRINT(debug_pfkey,
48638 + "klips_debug:pfkey_address_process: "
48639 + "extr or extr->ips is NULL, fatal\n");
48640 + SENDERR(EINVAL);
48641 + }
48642 +
48643 + switch(s->sa_family) {
48644 + case AF_INET:
48645 + saddr_len = sizeof(struct sockaddr_in);
48646 + addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt));
48647 + KLIPS_PRINT(debug_pfkey,
48648 + "klips_debug:pfkey_address_process: "
48649 + "found address family=%d, AF_INET, %s.\n",
48650 + s->sa_family,
48651 + ipaddr_txt);
48652 + break;
48653 +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
48654 + case AF_INET6:
48655 + saddr_len = sizeof(struct sockaddr_in6);
48656 + break;
48657 +#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
48658 + default:
48659 + KLIPS_PRINT(debug_pfkey,
48660 + "klips_debug:pfkey_address_process: "
48661 + "s->sa_family=%d not supported.\n",
48662 + s->sa_family);
48663 + SENDERR(EPFNOSUPPORT);
48664 + }
48665 +
48666 + switch(pfkey_address->sadb_address_exttype) {
48667 + case SADB_EXT_ADDRESS_SRC:
48668 + KLIPS_PRINT(debug_pfkey,
48669 + "klips_debug:pfkey_address_process: "
48670 + "found src address.\n");
48671 + sap = (unsigned char **)&(extr->ips->ips_addr_s);
48672 + extr->ips->ips_addr_s_size = saddr_len;
48673 + break;
48674 + case SADB_EXT_ADDRESS_DST:
48675 + KLIPS_PRINT(debug_pfkey,
48676 + "klips_debug:pfkey_address_process: "
48677 + "found dst address.\n");
48678 + sap = (unsigned char **)&(extr->ips->ips_addr_d);
48679 + extr->ips->ips_addr_d_size = saddr_len;
48680 + break;
48681 + case SADB_EXT_ADDRESS_PROXY:
48682 + KLIPS_PRINT(debug_pfkey,
48683 + "klips_debug:pfkey_address_process: "
48684 + "found proxy address.\n");
48685 + sap = (unsigned char **)&(extr->ips->ips_addr_p);
48686 + extr->ips->ips_addr_p_size = saddr_len;
48687 + break;
48688 + case SADB_X_EXT_ADDRESS_DST2:
48689 + KLIPS_PRINT(debug_pfkey,
48690 + "klips_debug:pfkey_address_process: "
48691 + "found 2nd dst address.\n");
48692 + if(extr->ips2 == NULL) {
48693 + extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
48694 + }
48695 + if(extr->ips2 == NULL) {
48696 + SENDERR(-error);
48697 + }
48698 + sap = (unsigned char **)&(extr->ips2->ips_addr_d);
48699 + extr->ips2->ips_addr_d_size = saddr_len;
48700 + break;
48701 + case SADB_X_EXT_ADDRESS_SRC_FLOW:
48702 + KLIPS_PRINT(debug_pfkey,
48703 + "klips_debug:pfkey_address_process: "
48704 + "found src flow address.\n");
48705 + if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
48706 + SENDERR(ENOMEM);
48707 + }
48708 + sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src);
48709 + portp = &(extr->eroute->er_eaddr.sen_sport);
48710 + break;
48711 + case SADB_X_EXT_ADDRESS_DST_FLOW:
48712 + KLIPS_PRINT(debug_pfkey,
48713 + "klips_debug:pfkey_address_process: "
48714 + "found dst flow address.\n");
48715 + if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
48716 + SENDERR(ENOMEM);
48717 + }
48718 + sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst);
48719 + portp = &(extr->eroute->er_eaddr.sen_dport);
48720 + break;
48721 + case SADB_X_EXT_ADDRESS_SRC_MASK:
48722 + KLIPS_PRINT(debug_pfkey,
48723 + "klips_debug:pfkey_address_process: "
48724 + "found src mask address.\n");
48725 + if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
48726 + SENDERR(ENOMEM);
48727 + }
48728 + sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src);
48729 + portp = &(extr->eroute->er_emask.sen_sport);
48730 + break;
48731 + case SADB_X_EXT_ADDRESS_DST_MASK:
48732 + KLIPS_PRINT(debug_pfkey,
48733 + "klips_debug:pfkey_address_process: "
48734 + "found dst mask address.\n");
48735 + if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
48736 + SENDERR(ENOMEM);
48737 + }
48738 + sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst);
48739 + portp = &(extr->eroute->er_emask.sen_dport);
48740 + break;
48741 +#ifdef NAT_TRAVERSAL
48742 + case SADB_X_EXT_NAT_T_OA:
48743 + KLIPS_PRINT(debug_pfkey,
48744 + "klips_debug:pfkey_address_process: "
48745 + "found NAT-OA address.\n");
48746 + sap = (unsigned char **)&(extr->ips->ips_natt_oa);
48747 + extr->ips->ips_natt_oa_size = saddr_len;
48748 + break;
48749 +#endif
48750 + default:
48751 + KLIPS_PRINT(debug_pfkey,
48752 + "klips_debug:pfkey_address_process: "
48753 + "unrecognised ext_type=%d.\n",
48754 + pfkey_address->sadb_address_exttype);
48755 + SENDERR(EINVAL);
48756 + }
48757 +
48758 + switch(pfkey_address->sadb_address_exttype) {
48759 + case SADB_EXT_ADDRESS_SRC:
48760 + case SADB_EXT_ADDRESS_DST:
48761 + case SADB_EXT_ADDRESS_PROXY:
48762 + case SADB_X_EXT_ADDRESS_DST2:
48763 +#ifdef NAT_TRAVERSAL
48764 + case SADB_X_EXT_NAT_T_OA:
48765 +#endif
48766 + KLIPS_PRINT(debug_pfkey,
48767 + "klips_debug:pfkey_address_process: "
48768 + "allocating %d bytes for saddr.\n",
48769 + saddr_len);
48770 + if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) {
48771 + SENDERR(ENOMEM);
48772 + }
48773 + memcpy(*sap, s, saddr_len);
48774 + break;
48775 + default:
48776 + if(s->sa_family != AF_INET) {
48777 + KLIPS_PRINT(debug_pfkey,
48778 + "klips_debug:pfkey_address_process: "
48779 + "s->sa_family=%d not supported.\n",
48780 + s->sa_family);
48781 + SENDERR(EPFNOSUPPORT);
48782 + }
48783 + {
48784 + unsigned long *ulsap = (unsigned long *)sap;
48785 + *ulsap = ((struct sockaddr_in*)s)->sin_addr.s_addr;
48786 + }
48787 +
48788 + if (portp != 0)
48789 + *portp = ((struct sockaddr_in*)s)->sin_port;
48790 +#ifdef CONFIG_KLIPS_DEBUG
48791 + if(extr->eroute) {
48792 + char buf1[64], buf2[64];
48793 + if (debug_pfkey) {
48794 + subnettoa(extr->eroute->er_eaddr.sen_ip_src,
48795 + extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
48796 + subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
48797 + extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
48798 + KLIPS_PRINT(debug_pfkey,
48799 + "klips_debug:pfkey_address_parse: "
48800 + "extr->eroute set to %s:%d->%s:%d\n",
48801 + buf1,
48802 + ntohs(extr->eroute->er_eaddr.sen_sport),
48803 + buf2,
48804 + ntohs(extr->eroute->er_eaddr.sen_dport));
48805 + }
48806 + }
48807 +#endif /* CONFIG_KLIPS_DEBUG */
48808 + }
48809 +
48810 + ipsp = extr->ips;
48811 + switch(pfkey_address->sadb_address_exttype) {
48812 + case SADB_X_EXT_ADDRESS_DST2:
48813 + ipsp = extr->ips2;
48814 + case SADB_EXT_ADDRESS_DST:
48815 + if(s->sa_family == AF_INET) {
48816 + ipsp->ips_said.dst.u.v4.sin_addr.s_addr = ((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr.s_addr;
48817 + ipsp->ips_said.dst.u.v4.sin_family = AF_INET;
48818 + addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
48819 + 0,
48820 + ipaddr_txt,
48821 + sizeof(ipaddr_txt));
48822 + KLIPS_PRINT(debug_pfkey,
48823 + "klips_debug:pfkey_address_process: "
48824 + "ips_said.dst set to %s.\n",
48825 + ipaddr_txt);
48826 + } else {
48827 + KLIPS_PRINT(debug_pfkey,
48828 + "klips_debug:pfkey_address_process: "
48829 + "uh, ips_said.dst doesn't do address family=%d yet, said will be invalid.\n",
48830 + s->sa_family);
48831 + }
48832 + default:
48833 + break;
48834 + }
48835 +
48836 + /* XXX check if port!=0 */
48837 +
48838 + KLIPS_PRINT(debug_pfkey,
48839 + "klips_debug:pfkey_address_process: successful.\n");
48840 + errlab:
48841 + return error;
48842 +}
48843 +
48844 +int
48845 +pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
48846 +{
48847 + int error = 0;
48848 + struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
48849 +
48850 + KLIPS_PRINT(debug_pfkey,
48851 + "klips_debug:pfkey_key_process: .\n");
48852 +
48853 + if(!extr || !extr->ips) {
48854 + KLIPS_PRINT(debug_pfkey,
48855 + "klips_debug:pfkey_key_process: "
48856 + "extr or extr->ips is NULL, fatal\n");
48857 + SENDERR(EINVAL);
48858 + }
48859 +
48860 + switch(pfkey_key->sadb_key_exttype) {
48861 + case SADB_EXT_KEY_AUTH:
48862 + KLIPS_PRINT(debug_pfkey,
48863 + "klips_debug:pfkey_key_process: "
48864 + "allocating %d bytes for authkey.\n",
48865 + DIVUP(pfkey_key->sadb_key_bits, 8));
48866 + if(!(extr->ips->ips_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
48867 + KLIPS_PRINT(debug_pfkey,
48868 + "klips_debug:pfkey_key_process: "
48869 + "memory allocation error.\n");
48870 + SENDERR(ENOMEM);
48871 + }
48872 + extr->ips->ips_key_bits_a = pfkey_key->sadb_key_bits;
48873 + extr->ips->ips_key_a_size = DIVUP(pfkey_key->sadb_key_bits, 8);
48874 + memcpy(extr->ips->ips_key_a,
48875 + (char*)pfkey_key + sizeof(struct sadb_key),
48876 + extr->ips->ips_key_a_size);
48877 + break;
48878 + case SADB_EXT_KEY_ENCRYPT: /* Key(s) */
48879 + KLIPS_PRINT(debug_pfkey,
48880 + "klips_debug:pfkey_key_process: "
48881 + "allocating %d bytes for enckey.\n",
48882 + DIVUP(pfkey_key->sadb_key_bits, 8));
48883 + if(!(extr->ips->ips_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
48884 + KLIPS_PRINT(debug_pfkey,
48885 + "klips_debug:pfkey_key_process: "
48886 + "memory allocation error.\n");
48887 + SENDERR(ENOMEM);
48888 + }
48889 + extr->ips->ips_key_bits_e = pfkey_key->sadb_key_bits;
48890 + extr->ips->ips_key_e_size = DIVUP(pfkey_key->sadb_key_bits, 8);
48891 + memcpy(extr->ips->ips_key_e,
48892 + (char*)pfkey_key + sizeof(struct sadb_key),
48893 + extr->ips->ips_key_e_size);
48894 + break;
48895 + default:
48896 + SENDERR(EINVAL);
48897 + }
48898 +
48899 + KLIPS_PRINT(debug_pfkey,
48900 + "klips_debug:pfkey_key_process: "
48901 + "success.\n");
48902 +errlab:
48903 + return error;
48904 +}
48905 +
48906 +int
48907 +pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
48908 +{
48909 + int error = 0;
48910 + struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
48911 + int data_len;
48912 +
48913 + KLIPS_PRINT(debug_pfkey,
48914 + "klips_debug:pfkey_ident_process: .\n");
48915 +
48916 + if(!extr || !extr->ips) {
48917 + KLIPS_PRINT(debug_pfkey,
48918 + "klips_debug:pfkey_ident_process: "
48919 + "extr or extr->ips is NULL, fatal\n");
48920 + SENDERR(EINVAL);
48921 + }
48922 +
48923 + switch(pfkey_ident->sadb_ident_exttype) {
48924 + case SADB_EXT_IDENTITY_SRC:
48925 + data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
48926 +
48927 + extr->ips->ips_ident_s.type = pfkey_ident->sadb_ident_type;
48928 + extr->ips->ips_ident_s.id = pfkey_ident->sadb_ident_id;
48929 + extr->ips->ips_ident_s.len = pfkey_ident->sadb_ident_len;
48930 + if(data_len) {
48931 + KLIPS_PRINT(debug_pfkey,
48932 + "klips_debug:pfkey_ident_process: "
48933 + "allocating %d bytes for ident_s.\n",
48934 + data_len);
48935 + if(!(extr->ips->ips_ident_s.data
48936 + = kmalloc(data_len, GFP_KERNEL))) {
48937 + SENDERR(ENOMEM);
48938 + }
48939 + memcpy(extr->ips->ips_ident_s.data,
48940 + (char*)pfkey_ident + sizeof(struct sadb_ident),
48941 + data_len);
48942 + } else {
48943 + extr->ips->ips_ident_s.data = NULL;
48944 + }
48945 + break;
48946 + case SADB_EXT_IDENTITY_DST: /* Identity(ies) */
48947 + data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
48948 +
48949 + extr->ips->ips_ident_d.type = pfkey_ident->sadb_ident_type;
48950 + extr->ips->ips_ident_d.id = pfkey_ident->sadb_ident_id;
48951 + extr->ips->ips_ident_d.len = pfkey_ident->sadb_ident_len;
48952 + if(data_len) {
48953 + KLIPS_PRINT(debug_pfkey,
48954 + "klips_debug:pfkey_ident_process: "
48955 + "allocating %d bytes for ident_d.\n",
48956 + data_len);
48957 + if(!(extr->ips->ips_ident_d.data
48958 + = kmalloc(data_len, GFP_KERNEL))) {
48959 + SENDERR(ENOMEM);
48960 + }
48961 + memcpy(extr->ips->ips_ident_d.data,
48962 + (char*)pfkey_ident + sizeof(struct sadb_ident),
48963 + data_len);
48964 + } else {
48965 + extr->ips->ips_ident_d.data = NULL;
48966 + }
48967 + break;
48968 + default:
48969 + SENDERR(EINVAL);
48970 + }
48971 +errlab:
48972 + return error;
48973 +}
48974 +
48975 +int
48976 +pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
48977 +{
48978 + int error = 0;
48979 +
48980 + KLIPS_PRINT(debug_pfkey,
48981 + "klips_debug:pfkey_sens_process: "
48982 + "Sorry, I can't process exttype=%d yet.\n",
48983 + pfkey_ext->sadb_ext_type);
48984 + SENDERR(EINVAL); /* don't process these yet */
48985 + errlab:
48986 + return error;
48987 +}
48988 +
48989 +int
48990 +pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
48991 +{
48992 + int error = 0;
48993 +
48994 + KLIPS_PRINT(debug_pfkey,
48995 + "klips_debug:pfkey_prop_process: "
48996 + "Sorry, I can't process exttype=%d yet.\n",
48997 + pfkey_ext->sadb_ext_type);
48998 + SENDERR(EINVAL); /* don't process these yet */
48999 +
49000 + errlab:
49001 + return error;
49002 +}
49003 +
49004 +int
49005 +pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49006 +{
49007 + int error = 0;
49008 +
49009 + KLIPS_PRINT(debug_pfkey,
49010 + "klips_debug:pfkey_supported_process: "
49011 + "Sorry, I can't process exttype=%d yet.\n",
49012 + pfkey_ext->sadb_ext_type);
49013 + SENDERR(EINVAL); /* don't process these yet */
49014 +
49015 +errlab:
49016 + return error;
49017 +}
49018 +
49019 +int
49020 +pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49021 +{
49022 + int error = 0;
49023 +
49024 + KLIPS_PRINT(debug_pfkey,
49025 + "klips_debug:pfkey_spirange_process: .\n");
49026 +/* errlab: */
49027 + return error;
49028 +}
49029 +
49030 +int
49031 +pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49032 +{
49033 + int error = 0;
49034 +
49035 + KLIPS_PRINT(debug_pfkey,
49036 + "klips_debug:pfkey_x_kmprivate_process: "
49037 + "Sorry, I can't process exttype=%d yet.\n",
49038 + pfkey_ext->sadb_ext_type);
49039 + SENDERR(EINVAL); /* don't process these yet */
49040 +
49041 +errlab:
49042 + return error;
49043 +}
49044 +
49045 +int
49046 +pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49047 +{
49048 + int error = 0;
49049 + struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
49050 +
49051 + KLIPS_PRINT(debug_pfkey,
49052 + "pfkey_x_satype_process: .\n");
49053 +
49054 + if(!extr || !extr->ips) {
49055 + KLIPS_PRINT(debug_pfkey,
49056 + "pfkey_x_satype_process: "
49057 + "extr or extr->ips is NULL, fatal\n");
49058 + SENDERR(EINVAL);
49059 + }
49060 +
49061 + if(extr->ips2 == NULL) {
49062 + extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
49063 + }
49064 + if(extr->ips2 == NULL) {
49065 + SENDERR(-error);
49066 + }
49067 + if(!(extr->ips2->ips_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
49068 + KLIPS_ERROR(debug_pfkey,
49069 + "pfkey_x_satype_process: "
49070 + "proto lookup from satype=%d failed.\n",
49071 + pfkey_x_satype->sadb_x_satype_satype);
49072 + SENDERR(EINVAL);
49073 + }
49074 + KLIPS_PRINT(debug_pfkey,
49075 + "pfkey_x_satype_process: "
49076 + "protocol==%d decoded from satype==%d(%s).\n",
49077 + extr->ips2->ips_said.proto,
49078 + pfkey_x_satype->sadb_x_satype_satype,
49079 + satype2name(pfkey_x_satype->sadb_x_satype_satype));
49080 +
49081 +errlab:
49082 + return error;
49083 +}
49084 +
49085 +
49086 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
49087 +int
49088 +pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49089 +{
49090 + int error = 0;
49091 + struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)pfkey_ext;
49092 +
49093 + if(!pfkey_x_nat_t_type) {
49094 + printk("klips_debug:pfkey_x_nat_t_type_process: "
49095 + "null pointer passed in\n");
49096 + SENDERR(EINVAL);
49097 + }
49098 +
49099 + KLIPS_PRINT(debug_pfkey,
49100 + "klips_debug:pfkey_x_nat_t_type_process: %d.\n",
49101 + pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
49102 +
49103 + if(!extr || !extr->ips) {
49104 + KLIPS_PRINT(debug_pfkey,
49105 + "klips_debug:pfkey_nat_t_type_process: "
49106 + "extr or extr->ips is NULL, fatal\n");
49107 + SENDERR(EINVAL);
49108 + }
49109 +
49110 + switch(pfkey_x_nat_t_type->sadb_x_nat_t_type_type) {
49111 + case ESPINUDP_WITH_NON_IKE: /* with Non-IKE (older version) */
49112 + case ESPINUDP_WITH_NON_ESP: /* with Non-ESP */
49113 +
49114 + extr->ips->ips_natt_type = pfkey_x_nat_t_type->sadb_x_nat_t_type_type;
49115 + break;
49116 + default:
49117 + KLIPS_PRINT(debug_pfkey,
49118 + "klips_debug:pfkey_x_nat_t_type_process: "
49119 + "unknown type %d.\n",
49120 + pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
49121 + SENDERR(EINVAL);
49122 + break;
49123 + }
49124 +
49125 +errlab:
49126 + return error;
49127 +}
49128 +
49129 +int
49130 +pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49131 +{
49132 + int error = 0;
49133 + struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)pfkey_ext;
49134 +
49135 + if(!pfkey_x_nat_t_port) {
49136 + printk("klips_debug:pfkey_x_nat_t_port_process: "
49137 + "null pointer passed in\n");
49138 + SENDERR(EINVAL);
49139 + }
49140 +
49141 + KLIPS_PRINT(debug_pfkey,
49142 + "klips_debug:pfkey_x_nat_t_port_process: %d/%d.\n",
49143 + pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype,
49144 + pfkey_x_nat_t_port->sadb_x_nat_t_port_port);
49145 +
49146 + if(!extr || !extr->ips) {
49147 + KLIPS_PRINT(debug_pfkey,
49148 + "klips_debug:pfkey_nat_t_type_process: "
49149 + "extr or extr->ips is NULL, fatal\n");
49150 + SENDERR(EINVAL);
49151 + }
49152 +
49153 + switch(pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype) {
49154 + case SADB_X_EXT_NAT_T_SPORT:
49155 + extr->ips->ips_natt_sport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
49156 + break;
49157 + case SADB_X_EXT_NAT_T_DPORT:
49158 + extr->ips->ips_natt_dport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
49159 + break;
49160 + default:
49161 + KLIPS_PRINT(debug_pfkey,
49162 + "klips_debug:pfkey_x_nat_t_port_process: "
49163 + "unknown exttype %d.\n",
49164 + pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype);
49165 + SENDERR(EINVAL);
49166 + break;
49167 + }
49168 +
49169 +errlab:
49170 + return error;
49171 +}
49172 +#endif
49173 +
49174 +int
49175 +pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49176 +{
49177 + int error = 0;
49178 + struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
49179 +
49180 + if(!pfkey_x_debug) {
49181 + printk("klips_debug:pfkey_x_debug_process: "
49182 + "null pointer passed in\n");
49183 + SENDERR(EINVAL);
49184 + }
49185 +
49186 + KLIPS_PRINT(debug_pfkey,
49187 + "klips_debug:pfkey_x_debug_process: .\n");
49188 +
49189 +#ifdef CONFIG_KLIPS_DEBUG
49190 + if(pfkey_x_debug->sadb_x_debug_netlink >>
49191 + (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) {
49192 + pfkey_x_debug->sadb_x_debug_netlink &=
49193 + ~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1));
49194 + debug_tunnel |= pfkey_x_debug->sadb_x_debug_tunnel;
49195 + debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink;
49196 + debug_xform |= pfkey_x_debug->sadb_x_debug_xform;
49197 + debug_eroute |= pfkey_x_debug->sadb_x_debug_eroute;
49198 + debug_spi |= pfkey_x_debug->sadb_x_debug_spi;
49199 + debug_radij |= pfkey_x_debug->sadb_x_debug_radij;
49200 + debug_esp |= pfkey_x_debug->sadb_x_debug_esp;
49201 + debug_ah |= pfkey_x_debug->sadb_x_debug_ah;
49202 + debug_rcv |= pfkey_x_debug->sadb_x_debug_rcv;
49203 + debug_pfkey |= pfkey_x_debug->sadb_x_debug_pfkey;
49204 +#ifdef CONFIG_KLIPS_IPCOMP
49205 + sysctl_ipsec_debug_ipcomp |= pfkey_x_debug->sadb_x_debug_ipcomp;
49206 +#endif /* CONFIG_KLIPS_IPCOMP */
49207 + sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose;
49208 + KLIPS_PRINT(debug_pfkey,
49209 + "klips_debug:pfkey_x_debug_process: "
49210 + "set\n");
49211 + } else {
49212 + KLIPS_PRINT(debug_pfkey,
49213 + "klips_debug:pfkey_x_debug_process: "
49214 + "unset\n");
49215 + debug_tunnel &= pfkey_x_debug->sadb_x_debug_tunnel;
49216 + debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink;
49217 + debug_xform &= pfkey_x_debug->sadb_x_debug_xform;
49218 + debug_eroute &= pfkey_x_debug->sadb_x_debug_eroute;
49219 + debug_spi &= pfkey_x_debug->sadb_x_debug_spi;
49220 + debug_radij &= pfkey_x_debug->sadb_x_debug_radij;
49221 + debug_esp &= pfkey_x_debug->sadb_x_debug_esp;
49222 + debug_ah &= pfkey_x_debug->sadb_x_debug_ah;
49223 + debug_rcv &= pfkey_x_debug->sadb_x_debug_rcv;
49224 + debug_pfkey &= pfkey_x_debug->sadb_x_debug_pfkey;
49225 +#ifdef CONFIG_KLIPS_IPCOMP
49226 + sysctl_ipsec_debug_ipcomp &= pfkey_x_debug->sadb_x_debug_ipcomp;
49227 +#endif /* CONFIG_KLIPS_IPCOMP */
49228 + sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose;
49229 + }
49230 +#else /* CONFIG_KLIPS_DEBUG */
49231 + printk("klips_debug:pfkey_x_debug_process: "
49232 + "debugging not enabled\n");
49233 + SENDERR(EINVAL);
49234 +#endif /* CONFIG_KLIPS_DEBUG */
49235 +
49236 +errlab:
49237 + return error;
49238 +}
49239 +
49240 +/*
49241 + * Local variables:
49242 + * c-file-style: "linux"
49243 + * End:
49244 + *
49245 + */
49246 --- /dev/null Tue Mar 11 13:02:56 2003
49247 +++ linux/net/ipsec/pfkey_v2_parse.c Mon Feb 9 13:51:03 2004
49248 @@ -0,0 +1,1564 @@
49249 +/*
49250 + * RFC2367 PF_KEYv2 Key management API message parser
49251 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
49252 + *
49253 + * This program is free software; you can redistribute it and/or modify it
49254 + * under the terms of the GNU General Public License as published by the
49255 + * Free Software Foundation; either version 2 of the License, or (at your
49256 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
49257 + *
49258 + * This program is distributed in the hope that it will be useful, but
49259 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
49260 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
49261 + * for more details.
49262 + *
49263 + * RCSID $Id: pfkey_v2_parse.c,v 1.65 2005/04/06 17:46:05 mcr Exp $
49264 + */
49265 +
49266 +/*
49267 + * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
49268 + */
49269 +
49270 +char pfkey_v2_parse_c_version[] = "$Id: pfkey_v2_parse.c,v 1.65 2005/04/06 17:46:05 mcr Exp $";
49271 +
49272 +/*
49273 + * Some ugly stuff to allow consistent debugging code for use in the
49274 + * kernel and in user space
49275 +*/
49276 +
49277 +#ifdef __KERNEL__
49278 +
49279 +# include <linux/kernel.h> /* for printk */
49280 +
49281 +#include "openswan/ipsec_kversion.h" /* for malloc switch */
49282 +
49283 +# ifdef MALLOC_SLAB
49284 +# include <linux/slab.h> /* kmalloc() */
49285 +# else /* MALLOC_SLAB */
49286 +# include <linux/malloc.h> /* kmalloc() */
49287 +# endif /* MALLOC_SLAB */
49288 +# include <linux/errno.h> /* error codes */
49289 +# include <linux/types.h> /* size_t */
49290 +# include <linux/interrupt.h> /* mark_bh */
49291 +
49292 +# include <linux/netdevice.h> /* struct device, and other headers */
49293 +# include <linux/etherdevice.h> /* eth_type_trans */
49294 +# include <linux/ip.h> /* struct iphdr */
49295 +# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
49296 +# include <linux/ipv6.h> /* struct ipv6hdr */
49297 +# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
49298 +extern int debug_pfkey;
49299 +
49300 +# include <openswan.h>
49301 +
49302 +#include "openswan/ipsec_encap.h"
49303 +
49304 +#else /* __KERNEL__ */
49305 +
49306 +# include <sys/types.h>
49307 +# include <sys/errno.h>
49308 +# include <stdio.h>
49309 +
49310 +# include <openswan.h>
49311 +# include "constants.h"
49312 +
49313 +#endif /* __KERNEL__ */
49314 +
49315 +
49316 +#include <openswan/pfkeyv2.h>
49317 +#include <openswan/pfkey.h>
49318 +
49319 +#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
49320 +
49321 +/*
49322 + * how to handle debugging for pfkey.
49323 + */
49324 +#include <openswan/pfkey_debug.h>
49325 +
49326 +unsigned int pfkey_lib_debug = PF_KEY_DEBUG_PARSE_NONE;
49327 +int (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
49328 +int (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
49329 +
49330 +
49331 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
49332 +
49333 +struct satype_tbl {
49334 + uint8_t proto;
49335 + uint8_t satype;
49336 + char* name;
49337 +} static satype_tbl[] = {
49338 +#ifdef __KERNEL__
49339 + { IPPROTO_ESP, SADB_SATYPE_ESP, "ESP" },
49340 + { IPPROTO_AH, SADB_SATYPE_AH, "AH" },
49341 + { IPPROTO_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
49342 +#ifdef CONFIG_KLIPS_IPCOMP
49343 + { IPPROTO_COMP, SADB_X_SATYPE_COMP, "COMP" },
49344 +#endif /* CONFIG_KLIPS_IPCOMP */
49345 + { IPPROTO_INT, SADB_X_SATYPE_INT, "INT" },
49346 +#else /* __KERNEL__ */
49347 + { SA_ESP, SADB_SATYPE_ESP, "ESP" },
49348 + { SA_AH, SADB_SATYPE_AH, "AH" },
49349 + { SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
49350 + { SA_COMP, SADB_X_SATYPE_COMP, "COMP" },
49351 + { SA_INT, SADB_X_SATYPE_INT, "INT" },
49352 +#endif /* __KERNEL__ */
49353 + { 0, 0, "UNKNOWN" }
49354 +};
49355 +
49356 +uint8_t
49357 +satype2proto(uint8_t satype)
49358 +{
49359 + int i =0;
49360 +
49361 + while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
49362 + i++;
49363 + }
49364 + return satype_tbl[i].proto;
49365 +}
49366 +
49367 +uint8_t
49368 +proto2satype(uint8_t proto)
49369 +{
49370 + int i = 0;
49371 +
49372 + while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
49373 + i++;
49374 + }
49375 + return satype_tbl[i].satype;
49376 +}
49377 +
49378 +char*
49379 +satype2name(uint8_t satype)
49380 +{
49381 + int i = 0;
49382 +
49383 + while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
49384 + i++;
49385 + }
49386 + return satype_tbl[i].name;
49387 +}
49388 +
49389 +char*
49390 +proto2name(uint8_t proto)
49391 +{
49392 + int i = 0;
49393 +
49394 + while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
49395 + i++;
49396 + }
49397 + return satype_tbl[i].name;
49398 +}
49399 +
49400 +/* Default extension parsers taken from the KLIPS code */
49401 +
49402 +DEBUG_NO_STATIC int
49403 +pfkey_sa_parse(struct sadb_ext *pfkey_ext)
49404 +{
49405 + int error = 0;
49406 + struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
49407 +#if 0
49408 + struct sadb_sa sav2;
49409 +#endif
49410 +
49411 + /* sanity checks... */
49412 + if(!pfkey_sa) {
49413 + ERROR("pfkey_sa_parse: "
49414 + "NULL pointer passed in.\n");
49415 + SENDERR(EINVAL);
49416 + }
49417 +
49418 +
49419 +
49420 + if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) {
49421 + ERROR(
49422 + "pfkey_sa_parse: "
49423 + "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n",
49424 + pfkey_sa->sadb_sa_len,
49425 + (int)sizeof(struct sadb_sa));
49426 + SENDERR(EINVAL);
49427 + }
49428 +
49429 +#if SADB_EALG_MAX < 255
49430 + if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) {
49431 + ERROR(
49432 + "pfkey_sa_parse: "
49433 + "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n",
49434 + pfkey_sa->sadb_sa_encrypt,
49435 + SADB_EALG_MAX);
49436 + SENDERR(EINVAL);
49437 + }
49438 +#endif
49439 +
49440 +#if SADB_AALG_MAX < 255
49441 + if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) {
49442 + ERROR(
49443 + "pfkey_sa_parse: "
49444 + "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n",
49445 + pfkey_sa->sadb_sa_auth,
49446 + SADB_AALG_MAX);
49447 + SENDERR(EINVAL);
49448 + }
49449 +#endif
49450 +
49451 +#if K_SADB_SASTATE_MAX < 255
49452 + if(pfkey_sa->sadb_sa_state > K_SADB_SASTATE_MAX) {
49453 + ERROR(
49454 + "pfkey_sa_parse: "
49455 + "state=%d exceeds MAX=%d.\n",
49456 + pfkey_sa->sadb_sa_state,
49457 + K_SADB_SASTATE_MAX);
49458 + SENDERR(EINVAL);
49459 + }
49460 +#endif
49461 +
49462 + if(pfkey_sa->sadb_sa_state == K_SADB_SASTATE_DEAD) {
49463 + ERROR(
49464 + "pfkey_sa_parse: "
49465 + "state=%d is DEAD=%d.\n",
49466 + pfkey_sa->sadb_sa_state,
49467 + K_SADB_SASTATE_DEAD);
49468 + SENDERR(EINVAL);
49469 + }
49470 +
49471 + if(pfkey_sa->sadb_sa_replay > 64) {
49472 + ERROR(
49473 + "pfkey_sa_parse: "
49474 + "replay window size: %d -- must be 0 <= size <= 64\n",
49475 + pfkey_sa->sadb_sa_replay);
49476 + SENDERR(EINVAL);
49477 + }
49478 +
49479 + if(! ((pfkey_sa->sadb_sa_exttype == SADB_EXT_SA) ||
49480 + (pfkey_sa->sadb_sa_exttype == SADB_X_EXT_SA2)))
49481 + {
49482 + ERROR(
49483 + "pfkey_sa_parse: "
49484 + "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n",
49485 + pfkey_sa->sadb_sa_exttype,
49486 + SADB_EXT_SA,
49487 + SADB_X_EXT_SA2);
49488 + SENDERR(EINVAL);
49489 + }
49490 +
49491 + if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref) && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
49492 + ERROR(
49493 + "pfkey_sa_parse: "
49494 + "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
49495 + pfkey_sa->sadb_x_sa_ref,
49496 + IPSEC_SAREF_NULL,
49497 + IPSEC_SA_REF_TABLE_NUM_ENTRIES);
49498 + SENDERR(EINVAL);
49499 + }
49500 +
49501 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
49502 + "pfkey_sa_parse: "
49503 + "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n",
49504 + pfkey_sa->sadb_sa_len,
49505 + pfkey_sa->sadb_sa_exttype,
49506 + pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype),
49507 + (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi),
49508 + pfkey_sa->sadb_sa_replay,
49509 + pfkey_sa->sadb_sa_state,
49510 + pfkey_sa->sadb_sa_auth,
49511 + pfkey_sa->sadb_sa_encrypt,
49512 + pfkey_sa->sadb_sa_flags,
49513 + pfkey_sa->sadb_x_sa_ref);
49514 +
49515 + errlab:
49516 + return error;
49517 +}
49518 +
49519 +DEBUG_NO_STATIC int
49520 +pfkey_lifetime_parse(struct sadb_ext *pfkey_ext)
49521 +{
49522 + int error = 0;
49523 + struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
49524 +
49525 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
49526 + "pfkey_lifetime_parse:enter\n");
49527 + /* sanity checks... */
49528 + if(!pfkey_lifetime) {
49529 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49530 + "pfkey_lifetime_parse: "
49531 + "NULL pointer passed in.\n");
49532 + SENDERR(EINVAL);
49533 + }
49534 +
49535 + if(pfkey_lifetime->sadb_lifetime_len !=
49536 + sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) {
49537 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49538 + "pfkey_lifetime_parse: "
49539 + "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n",
49540 + pfkey_lifetime->sadb_lifetime_len,
49541 + (int)sizeof(struct sadb_lifetime));
49542 + SENDERR(EINVAL);
49543 + }
49544 +
49545 + if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) &&
49546 + (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) &&
49547 + (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) {
49548 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49549 + "pfkey_lifetime_parse: "
49550 + "unexpected ext_type=%d.\n",
49551 + pfkey_lifetime->sadb_lifetime_exttype);
49552 + SENDERR(EINVAL);
49553 + }
49554 +
49555 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
49556 + "pfkey_lifetime_parse: "
49557 + "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u.\n",
49558 + pfkey_lifetime->sadb_lifetime_exttype,
49559 + pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype),
49560 + pfkey_lifetime->sadb_lifetime_allocations,
49561 + (unsigned)pfkey_lifetime->sadb_lifetime_bytes,
49562 + (unsigned)pfkey_lifetime->sadb_lifetime_addtime,
49563 + (unsigned)pfkey_lifetime->sadb_lifetime_usetime);
49564 +errlab:
49565 + return error;
49566 +}
49567 +
49568 +DEBUG_NO_STATIC int
49569 +pfkey_address_parse(struct sadb_ext *pfkey_ext)
49570 +{
49571 + int error = 0;
49572 + int saddr_len = 0;
49573 + struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
49574 + struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
49575 + char ipaddr_txt[ADDRTOT_BUF];
49576 +
49577 + /* sanity checks... */
49578 + if(!pfkey_address) {
49579 + ERROR(
49580 + "pfkey_address_parse: "
49581 + "NULL pointer passed in.\n");
49582 + SENDERR(EINVAL);
49583 + }
49584 +
49585 + if(pfkey_address->sadb_address_len <
49586 + (sizeof(struct sadb_address) + sizeof(struct sockaddr))/
49587 + IPSEC_PFKEYv2_ALIGN) {
49588 + ERROR("pfkey_address_parse: "
49589 + "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
49590 + pfkey_address->sadb_address_len,
49591 + (int)sizeof(struct sadb_address),
49592 + (int)sizeof(struct sockaddr));
49593 + SENDERR(EINVAL);
49594 + }
49595 +
49596 + if(pfkey_address->sadb_address_reserved) {
49597 + ERROR("pfkey_address_parse: "
49598 + "res=%d, must be zero.\n",
49599 + pfkey_address->sadb_address_reserved);
49600 + SENDERR(EINVAL);
49601 + }
49602 +
49603 + switch(pfkey_address->sadb_address_exttype) {
49604 + case SADB_EXT_ADDRESS_SRC:
49605 + case SADB_EXT_ADDRESS_DST:
49606 + case SADB_EXT_ADDRESS_PROXY:
49607 + case SADB_X_EXT_ADDRESS_DST2:
49608 + case SADB_X_EXT_ADDRESS_SRC_FLOW:
49609 + case SADB_X_EXT_ADDRESS_DST_FLOW:
49610 + case SADB_X_EXT_ADDRESS_SRC_MASK:
49611 + case SADB_X_EXT_ADDRESS_DST_MASK:
49612 +#ifdef NAT_TRAVERSAL
49613 + case SADB_X_EXT_NAT_T_OA:
49614 +#endif
49615 + break;
49616 + default:
49617 + ERROR(
49618 + "pfkey_address_parse: "
49619 + "unexpected ext_type=%d.\n",
49620 + pfkey_address->sadb_address_exttype);
49621 + SENDERR(ENODEV);
49622 + }
49623 +
49624 + switch(s->sa_family) {
49625 + case AF_INET:
49626 + saddr_len = sizeof(struct sockaddr_in);
49627 + sprintf(ipaddr_txt, "%d.%d.%d.%d"
49628 + , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 0) & 0xFF
49629 + , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 8) & 0xFF
49630 + , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF
49631 + , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF);
49632 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
49633 + "pfkey_address_parse: "
49634 + "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n",
49635 + pfkey_address->sadb_address_exttype,
49636 + pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
49637 + s->sa_family,
49638 + ipaddr_txt,
49639 + pfkey_address->sadb_address_proto,
49640 + ntohs(((struct sockaddr_in*)s)->sin_port));
49641 + break;
49642 + case AF_INET6:
49643 + saddr_len = sizeof(struct sockaddr_in6);
49644 + sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x"
49645 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0])
49646 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1])
49647 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2])
49648 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3])
49649 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4])
49650 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5])
49651 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6])
49652 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7]));
49653 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
49654 + "pfkey_address_parse: "
49655 + "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n",
49656 + pfkey_address->sadb_address_exttype,
49657 + pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
49658 + s->sa_family,
49659 + ipaddr_txt,
49660 + pfkey_address->sadb_address_proto,
49661 + ((struct sockaddr_in6*)s)->sin6_port);
49662 + break;
49663 + default:
49664 + ERROR(
49665 + "pfkey_address_parse: "
49666 + "s->sa_family=%d not supported.\n",
49667 + s->sa_family);
49668 + SENDERR(EPFNOSUPPORT);
49669 + }
49670 +
49671 + if(pfkey_address->sadb_address_len !=
49672 + DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) {
49673 + ERROR(
49674 + "pfkey_address_parse: "
49675 + "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
49676 + pfkey_address->sadb_address_len,
49677 + (int)sizeof(struct sadb_address),
49678 + saddr_len);
49679 + SENDERR(EINVAL);
49680 + }
49681 +
49682 + if(pfkey_address->sadb_address_prefixlen != 0) {
49683 + ERROR(
49684 + "pfkey_address_parse: "
49685 + "address prefixes not supported yet.\n");
49686 + SENDERR(EAFNOSUPPORT); /* not supported yet */
49687 + }
49688 +
49689 + /* XXX check if port!=0 */
49690 +
49691 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
49692 + "pfkey_address_parse: successful.\n");
49693 + errlab:
49694 + return error;
49695 +}
49696 +
49697 +DEBUG_NO_STATIC int
49698 +pfkey_key_parse(struct sadb_ext *pfkey_ext)
49699 +{
49700 + int error = 0;
49701 + struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
49702 +
49703 + /* sanity checks... */
49704 +
49705 + if(!pfkey_key) {
49706 + ERROR(
49707 + "pfkey_key_parse: "
49708 + "NULL pointer passed in.\n");
49709 + SENDERR(EINVAL);
49710 + }
49711 +
49712 + if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) {
49713 + ERROR(
49714 + "pfkey_key_parse: "
49715 + "size wrong ext_len=%d, key_ext_len=%d.\n",
49716 + pfkey_key->sadb_key_len,
49717 + (int)sizeof(struct sadb_key));
49718 + SENDERR(EINVAL);
49719 + }
49720 +
49721 + if(!pfkey_key->sadb_key_bits) {
49722 + ERROR(
49723 + "pfkey_key_parse: "
49724 + "key length set to zero, must be non-zero.\n");
49725 + SENDERR(EINVAL);
49726 + }
49727 +
49728 + if(pfkey_key->sadb_key_len !=
49729 + DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits,
49730 + PFKEYBITS)) {
49731 + ERROR(
49732 + "pfkey_key_parse: "
49733 + "key length=%d does not agree with extension length=%d.\n",
49734 + pfkey_key->sadb_key_bits,
49735 + pfkey_key->sadb_key_len);
49736 + SENDERR(EINVAL);
49737 + }
49738 +
49739 + if(pfkey_key->sadb_key_reserved) {
49740 + ERROR(
49741 + "pfkey_key_parse: "
49742 + "res=%d, must be zero.\n",
49743 + pfkey_key->sadb_key_reserved);
49744 + SENDERR(EINVAL);
49745 + }
49746 +
49747 + if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) ||
49748 + (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) {
49749 + ERROR(
49750 + "pfkey_key_parse: "
49751 + "expecting extension type AUTH or ENCRYPT, got %d.\n",
49752 + pfkey_key->sadb_key_exttype);
49753 + SENDERR(EINVAL);
49754 + }
49755 +
49756 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
49757 + "pfkey_key_parse: "
49758 + "success, found len=%d exttype=%d(%s) bits=%d reserved=%d.\n",
49759 + pfkey_key->sadb_key_len,
49760 + pfkey_key->sadb_key_exttype,
49761 + pfkey_v2_sadb_ext_string(pfkey_key->sadb_key_exttype),
49762 + pfkey_key->sadb_key_bits,
49763 + pfkey_key->sadb_key_reserved);
49764 +
49765 +errlab:
49766 + return error;
49767 +}
49768 +
49769 +DEBUG_NO_STATIC int
49770 +pfkey_ident_parse(struct sadb_ext *pfkey_ext)
49771 +{
49772 + int error = 0;
49773 + struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
49774 +
49775 + /* sanity checks... */
49776 + if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
49777 + ERROR(
49778 + "pfkey_ident_parse: "
49779 + "size wrong ext_len=%d, key_ext_len=%d.\n",
49780 + pfkey_ident->sadb_ident_len,
49781 + (int)sizeof(struct sadb_ident));
49782 + SENDERR(EINVAL);
49783 + }
49784 +
49785 + if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) {
49786 + ERROR(
49787 + "pfkey_ident_parse: "
49788 + "ident_type=%d out of range, must be less than %d.\n",
49789 + pfkey_ident->sadb_ident_type,
49790 + SADB_IDENTTYPE_MAX);
49791 + SENDERR(EINVAL);
49792 + }
49793 +
49794 + if(pfkey_ident->sadb_ident_reserved) {
49795 + ERROR(
49796 + "pfkey_ident_parse: "
49797 + "res=%d, must be zero.\n",
49798 + pfkey_ident->sadb_ident_reserved);
49799 + SENDERR(EINVAL);
49800 + }
49801 +
49802 + /* string terminator/padding must be zero */
49803 + if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
49804 + if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) {
49805 + ERROR(
49806 + "pfkey_ident_parse: "
49807 + "string padding must be zero, last is 0x%02x.\n",
49808 + *((char*)pfkey_ident +
49809 + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1));
49810 + SENDERR(EINVAL);
49811 + }
49812 + }
49813 +
49814 + if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) ||
49815 + (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) {
49816 + ERROR(
49817 + "pfkey_key_parse: "
49818 + "expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n",
49819 + pfkey_ident->sadb_ident_exttype);
49820 + SENDERR(EINVAL);
49821 + }
49822 +
49823 +errlab:
49824 + return error;
49825 +}
49826 +
49827 +DEBUG_NO_STATIC int
49828 +pfkey_sens_parse(struct sadb_ext *pfkey_ext)
49829 +{
49830 + int error = 0;
49831 + struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext;
49832 +
49833 + /* sanity checks... */
49834 + if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) {
49835 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49836 + "pfkey_sens_parse: "
49837 + "size wrong ext_len=%d, key_ext_len=%d.\n",
49838 + pfkey_sens->sadb_sens_len,
49839 + (int)sizeof(struct sadb_sens));
49840 + SENDERR(EINVAL);
49841 + }
49842 +
49843 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49844 + "pfkey_sens_parse: "
49845 + "Sorry, I can't parse exttype=%d yet.\n",
49846 + pfkey_ext->sadb_ext_type);
49847 +#if 0
49848 + SENDERR(EINVAL); /* don't process these yet */
49849 +#endif
49850 +
49851 +errlab:
49852 + return error;
49853 +}
49854 +
49855 +DEBUG_NO_STATIC int
49856 +pfkey_prop_parse(struct sadb_ext *pfkey_ext)
49857 +{
49858 + int error = 0;
49859 + int i, num_comb;
49860 + struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext;
49861 + struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop));
49862 +
49863 + /* sanity checks... */
49864 + if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) ||
49865 + (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) {
49866 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49867 + "pfkey_prop_parse: "
49868 + "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n",
49869 + pfkey_prop->sadb_prop_len,
49870 + (int)sizeof(struct sadb_prop),
49871 + (int)sizeof(struct sadb_comb));
49872 + SENDERR(EINVAL);
49873 + }
49874 +
49875 + if(pfkey_prop->sadb_prop_replay > 64) {
49876 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49877 + "pfkey_prop_parse: "
49878 + "replay window size: %d -- must be 0 <= size <= 64\n",
49879 + pfkey_prop->sadb_prop_replay);
49880 + SENDERR(EINVAL);
49881 + }
49882 +
49883 + for(i=0; i<3; i++) {
49884 + if(pfkey_prop->sadb_prop_reserved[i]) {
49885 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49886 + "pfkey_prop_parse: "
49887 + "res[%d]=%d, must be zero.\n",
49888 + i, pfkey_prop->sadb_prop_reserved[i]);
49889 + SENDERR(EINVAL);
49890 + }
49891 + }
49892 +
49893 + num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb);
49894 +
49895 + for(i = 0; i < num_comb; i++) {
49896 + if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) {
49897 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49898 + "pfkey_prop_parse: "
49899 + "pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n",
49900 + i,
49901 + pfkey_comb->sadb_comb_auth,
49902 + SADB_AALG_MAX);
49903 + SENDERR(EINVAL);
49904 + }
49905 +
49906 + if(pfkey_comb->sadb_comb_auth) {
49907 + if(!pfkey_comb->sadb_comb_auth_minbits) {
49908 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49909 + "pfkey_prop_parse: "
49910 + "pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n",
49911 + i);
49912 + SENDERR(EINVAL);
49913 + }
49914 + if(!pfkey_comb->sadb_comb_auth_maxbits) {
49915 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49916 + "pfkey_prop_parse: "
49917 + "pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n",
49918 + i);
49919 + SENDERR(EINVAL);
49920 + }
49921 + if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) {
49922 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49923 + "pfkey_prop_parse: "
49924 + "pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n",
49925 + i,
49926 + pfkey_comb->sadb_comb_auth_minbits,
49927 + pfkey_comb->sadb_comb_auth_maxbits);
49928 + SENDERR(EINVAL);
49929 + }
49930 + } else {
49931 + if(pfkey_comb->sadb_comb_auth_minbits) {
49932 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49933 + "pfkey_prop_parse: "
49934 + "pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n",
49935 + i,
49936 + pfkey_comb->sadb_comb_auth_minbits);
49937 + SENDERR(EINVAL);
49938 + }
49939 + if(pfkey_comb->sadb_comb_auth_maxbits) {
49940 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49941 + "pfkey_prop_parse: "
49942 + "pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n",
49943 + i,
49944 + pfkey_comb->sadb_comb_auth_maxbits);
49945 + SENDERR(EINVAL);
49946 + }
49947 + }
49948 +
49949 +#if SADB_EALG_MAX < 255
49950 + if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) {
49951 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49952 + "pfkey_comb_parse: "
49953 + "pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n",
49954 + i,
49955 + pfkey_comb->sadb_comb_encrypt,
49956 + SADB_EALG_MAX);
49957 + SENDERR(EINVAL);
49958 + }
49959 +#endif
49960 +
49961 + if(pfkey_comb->sadb_comb_encrypt) {
49962 + if(!pfkey_comb->sadb_comb_encrypt_minbits) {
49963 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49964 + "pfkey_prop_parse: "
49965 + "pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n",
49966 + i);
49967 + SENDERR(EINVAL);
49968 + }
49969 + if(!pfkey_comb->sadb_comb_encrypt_maxbits) {
49970 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49971 + "pfkey_prop_parse: "
49972 + "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n",
49973 + i);
49974 + SENDERR(EINVAL);
49975 + }
49976 + if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) {
49977 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49978 + "pfkey_prop_parse: "
49979 + "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n",
49980 + i,
49981 + pfkey_comb->sadb_comb_encrypt_minbits,
49982 + pfkey_comb->sadb_comb_encrypt_maxbits);
49983 + SENDERR(EINVAL);
49984 + }
49985 + } else {
49986 + if(pfkey_comb->sadb_comb_encrypt_minbits) {
49987 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49988 + "pfkey_prop_parse: "
49989 + "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n",
49990 + i,
49991 + pfkey_comb->sadb_comb_encrypt_minbits);
49992 + SENDERR(EINVAL);
49993 + }
49994 + if(pfkey_comb->sadb_comb_encrypt_maxbits) {
49995 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
49996 + "pfkey_prop_parse: "
49997 + "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n",
49998 + i,
49999 + pfkey_comb->sadb_comb_encrypt_maxbits);
50000 + SENDERR(EINVAL);
50001 + }
50002 + }
50003 +
50004 + /* XXX do sanity check on flags */
50005 +
50006 + if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) {
50007 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50008 + "pfkey_prop_parse: "
50009 + "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n",
50010 + i,
50011 + pfkey_comb->sadb_comb_soft_allocations,
50012 + pfkey_comb->sadb_comb_hard_allocations);
50013 + SENDERR(EINVAL);
50014 + }
50015 +
50016 + if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) {
50017 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50018 + "pfkey_prop_parse: "
50019 + "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n",
50020 + i,
50021 + (unsigned long long int)pfkey_comb->sadb_comb_soft_bytes,
50022 + (unsigned long long int)pfkey_comb->sadb_comb_hard_bytes);
50023 + SENDERR(EINVAL);
50024 + }
50025 +
50026 + if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) {
50027 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50028 + "pfkey_prop_parse: "
50029 + "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n",
50030 + i,
50031 + (unsigned long long int)pfkey_comb->sadb_comb_soft_addtime,
50032 + (unsigned long long int)pfkey_comb->sadb_comb_hard_addtime);
50033 + SENDERR(EINVAL);
50034 + }
50035 +
50036 + if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) {
50037 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50038 + "pfkey_prop_parse: "
50039 + "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n",
50040 + i,
50041 + (unsigned long long int)pfkey_comb->sadb_comb_soft_usetime,
50042 + (unsigned long long int)pfkey_comb->sadb_comb_hard_usetime);
50043 + SENDERR(EINVAL);
50044 + }
50045 +
50046 + if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) {
50047 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50048 + "pfkey_prop_parse: "
50049 + "pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n",
50050 + i,
50051 + pfkey_comb->sadb_x_comb_soft_packets,
50052 + pfkey_comb->sadb_x_comb_hard_packets);
50053 + SENDERR(EINVAL);
50054 + }
50055 +
50056 + pfkey_comb++;
50057 + }
50058 +
50059 +errlab:
50060 + return error;
50061 +}
50062 +
50063 +DEBUG_NO_STATIC int
50064 +pfkey_supported_parse(struct sadb_ext *pfkey_ext)
50065 +{
50066 + int error = 0;
50067 + unsigned int i, num_alg;
50068 + struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext;
50069 + struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported));
50070 +
50071 + /* sanity checks... */
50072 + if((pfkey_supported->sadb_supported_len <
50073 + sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) ||
50074 + (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) -
50075 + sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) {
50076 +
50077 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50078 + "pfkey_supported_parse: "
50079 + "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n",
50080 + pfkey_supported->sadb_supported_len,
50081 + (int)sizeof(struct sadb_supported),
50082 + (int)sizeof(struct sadb_alg));
50083 + SENDERR(EINVAL);
50084 + }
50085 +
50086 + if(pfkey_supported->sadb_supported_reserved) {
50087 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50088 + "pfkey_supported_parse: "
50089 + "res=%d, must be zero.\n",
50090 + pfkey_supported->sadb_supported_reserved);
50091 + SENDERR(EINVAL);
50092 + }
50093 +
50094 + num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg);
50095 +
50096 + for(i = 0; i < num_alg; i++) {
50097 + /* process algo description */
50098 + if(pfkey_alg->sadb_alg_reserved) {
50099 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50100 + "pfkey_supported_parse: "
50101 + "alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n",
50102 + i,
50103 + pfkey_alg->sadb_alg_id,
50104 + pfkey_alg->sadb_alg_ivlen,
50105 + pfkey_alg->sadb_alg_minbits,
50106 + pfkey_alg->sadb_alg_maxbits,
50107 + pfkey_alg->sadb_alg_reserved);
50108 + SENDERR(EINVAL);
50109 + }
50110 +
50111 + /* XXX can alg_id auth/enc be determined from info given?
50112 + Yes, but OpenBSD's method does not iteroperate with rfc2367.
50113 + rgb, 2000-04-06 */
50114 +
50115 + switch(pfkey_supported->sadb_supported_exttype) {
50116 + case SADB_EXT_SUPPORTED_AUTH:
50117 + if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) {
50118 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50119 + "pfkey_supported_parse: "
50120 + "alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n",
50121 + i,
50122 + pfkey_alg->sadb_alg_id,
50123 + SADB_AALG_MAX);
50124 + SENDERR(EINVAL);
50125 + }
50126 + break;
50127 + case SADB_EXT_SUPPORTED_ENCRYPT:
50128 +#if SADB_EALG_MAX < 255
50129 + if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) {
50130 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50131 + "pfkey_supported_parse: "
50132 + "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
50133 + i,
50134 + pfkey_alg->sadb_alg_id,
50135 + SADB_EALG_MAX);
50136 + SENDERR(EINVAL);
50137 + }
50138 +#endif
50139 + break;
50140 + default:
50141 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50142 + "pfkey_supported_parse: "
50143 + "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
50144 + i,
50145 + pfkey_alg->sadb_alg_id,
50146 + SADB_EALG_MAX);
50147 + SENDERR(EINVAL);
50148 + }
50149 + pfkey_alg++;
50150 + }
50151 +
50152 + errlab:
50153 + return error;
50154 +}
50155 +
50156 +DEBUG_NO_STATIC int
50157 +pfkey_spirange_parse(struct sadb_ext *pfkey_ext)
50158 +{
50159 + int error = 0;
50160 + struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext;
50161 +
50162 + /* sanity checks... */
50163 + if(pfkey_spirange->sadb_spirange_len !=
50164 + sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) {
50165 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50166 + "pfkey_spirange_parse: "
50167 + "size wrong ext_len=%d, key_ext_len=%d.\n",
50168 + pfkey_spirange->sadb_spirange_len,
50169 + (int)sizeof(struct sadb_spirange));
50170 + SENDERR(EINVAL);
50171 + }
50172 +
50173 + if(pfkey_spirange->sadb_spirange_reserved) {
50174 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50175 + "pfkey_spirange_parse: "
50176 + "reserved=%d must be set to zero.\n",
50177 + pfkey_spirange->sadb_spirange_reserved);
50178 + SENDERR(EINVAL);
50179 + }
50180 +
50181 + if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) {
50182 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50183 + "pfkey_spirange_parse: "
50184 + "minspi=%08x must be < maxspi=%08x.\n",
50185 + ntohl(pfkey_spirange->sadb_spirange_min),
50186 + ntohl(pfkey_spirange->sadb_spirange_max));
50187 + SENDERR(EINVAL);
50188 + }
50189 +
50190 + if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) {
50191 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50192 + "pfkey_spirange_parse: "
50193 + "minspi=%08x must be > 255.\n",
50194 + ntohl(pfkey_spirange->sadb_spirange_min));
50195 + SENDERR(EEXIST);
50196 + }
50197 +
50198 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50199 + "pfkey_spirange_parse: "
50200 + "ext_len=%u ext_type=%u(%s) min=%u max=%u res=%u.\n",
50201 + pfkey_spirange->sadb_spirange_len,
50202 + pfkey_spirange->sadb_spirange_exttype,
50203 + pfkey_v2_sadb_ext_string(pfkey_spirange->sadb_spirange_exttype),
50204 + pfkey_spirange->sadb_spirange_min,
50205 + pfkey_spirange->sadb_spirange_max,
50206 + pfkey_spirange->sadb_spirange_reserved);
50207 + errlab:
50208 + return error;
50209 +}
50210 +
50211 +DEBUG_NO_STATIC int
50212 +pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext)
50213 +{
50214 + int error = 0;
50215 + struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext;
50216 +
50217 + /* sanity checks... */
50218 + if(pfkey_x_kmprivate->sadb_x_kmprivate_len <
50219 + sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) {
50220 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50221 + "pfkey_x_kmprivate_parse: "
50222 + "size wrong ext_len=%d, key_ext_len=%d.\n",
50223 + pfkey_x_kmprivate->sadb_x_kmprivate_len,
50224 + (int)sizeof(struct sadb_x_kmprivate));
50225 + SENDERR(EINVAL);
50226 + }
50227 +
50228 + if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) {
50229 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50230 + "pfkey_x_kmprivate_parse: "
50231 + "reserved=%d must be set to zero.\n",
50232 + pfkey_x_kmprivate->sadb_x_kmprivate_reserved);
50233 + SENDERR(EINVAL);
50234 + }
50235 +
50236 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50237 + "pfkey_x_kmprivate_parse: "
50238 + "Sorry, I can't parse exttype=%d yet.\n",
50239 + pfkey_ext->sadb_ext_type);
50240 + SENDERR(EINVAL); /* don't process these yet */
50241 +
50242 +errlab:
50243 + return error;
50244 +}
50245 +
50246 +DEBUG_NO_STATIC int
50247 +pfkey_x_satype_parse(struct sadb_ext *pfkey_ext)
50248 +{
50249 + int error = 0;
50250 + int i;
50251 + struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
50252 +
50253 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
50254 + "pfkey_x_satype_parse: enter\n");
50255 + /* sanity checks... */
50256 + if(pfkey_x_satype->sadb_x_satype_len !=
50257 + sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) {
50258 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50259 + "pfkey_x_satype_parse: "
50260 + "size wrong ext_len=%d, key_ext_len=%d.\n",
50261 + pfkey_x_satype->sadb_x_satype_len,
50262 + (int)sizeof(struct sadb_x_satype));
50263 + SENDERR(EINVAL);
50264 + }
50265 +
50266 + if(!pfkey_x_satype->sadb_x_satype_satype) {
50267 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50268 + "pfkey_x_satype_parse: "
50269 + "satype is zero, must be non-zero.\n");
50270 + SENDERR(EINVAL);
50271 + }
50272 +
50273 + if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) {
50274 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50275 + "pfkey_x_satype_parse: "
50276 + "satype %d > max %d, invalid.\n",
50277 + pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX);
50278 + SENDERR(EINVAL);
50279 + }
50280 +
50281 + if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
50282 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50283 + "pfkey_x_satype_parse: "
50284 + "proto lookup from satype=%d failed.\n",
50285 + pfkey_x_satype->sadb_x_satype_satype);
50286 + SENDERR(EINVAL);
50287 + }
50288 +
50289 + for(i = 0; i < 3; i++) {
50290 + if(pfkey_x_satype->sadb_x_satype_reserved[i]) {
50291 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50292 + "pfkey_x_satype_parse: "
50293 + "reserved[%d]=%d must be set to zero.\n",
50294 + i, pfkey_x_satype->sadb_x_satype_reserved[i]);
50295 + SENDERR(EINVAL);
50296 + }
50297 + }
50298 +
50299 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50300 + "pfkey_x_satype_parse: "
50301 + "len=%u ext=%u(%s) satype=%u(%s) res=%u,%u,%u.\n",
50302 + pfkey_x_satype->sadb_x_satype_len,
50303 + pfkey_x_satype->sadb_x_satype_exttype,
50304 + pfkey_v2_sadb_ext_string(pfkey_x_satype->sadb_x_satype_exttype),
50305 + pfkey_x_satype->sadb_x_satype_satype,
50306 + satype2name(pfkey_x_satype->sadb_x_satype_satype),
50307 + pfkey_x_satype->sadb_x_satype_reserved[0],
50308 + pfkey_x_satype->sadb_x_satype_reserved[1],
50309 + pfkey_x_satype->sadb_x_satype_reserved[2]);
50310 +errlab:
50311 + return error;
50312 +}
50313 +
50314 +DEBUG_NO_STATIC int
50315 +pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext)
50316 +{
50317 + int error = 0;
50318 + int i;
50319 + struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
50320 +
50321 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
50322 + "pfkey_x_debug_parse: enter\n");
50323 + /* sanity checks... */
50324 + if(pfkey_x_debug->sadb_x_debug_len !=
50325 + sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) {
50326 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50327 + "pfkey_x_debug_parse: "
50328 + "size wrong ext_len=%d, key_ext_len=%d.\n",
50329 + pfkey_x_debug->sadb_x_debug_len,
50330 + (int)sizeof(struct sadb_x_debug));
50331 + SENDERR(EINVAL);
50332 + }
50333 +
50334 + for(i = 0; i < 4; i++) {
50335 + if(pfkey_x_debug->sadb_x_debug_reserved[i]) {
50336 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50337 + "pfkey_x_debug_parse: "
50338 + "reserved[%d]=%d must be set to zero.\n",
50339 + i, pfkey_x_debug->sadb_x_debug_reserved[i]);
50340 + SENDERR(EINVAL);
50341 + }
50342 + }
50343 +
50344 +errlab:
50345 + return error;
50346 +}
50347 +
50348 +DEBUG_NO_STATIC int
50349 +pfkey_x_ext_protocol_parse(struct sadb_ext *pfkey_ext)
50350 +{
50351 + int error = 0;
50352 + struct sadb_protocol *p = (struct sadb_protocol *)pfkey_ext;
50353 +
50354 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_protocol_parse:\n");
50355 + /* sanity checks... */
50356 +
50357 + if (p->sadb_protocol_len != sizeof(*p)/IPSEC_PFKEYv2_ALIGN) {
50358 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50359 + "pfkey_x_protocol_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
50360 + p->sadb_protocol_len, (int)sizeof(*p));
50361 + SENDERR(EINVAL);
50362 + }
50363 +
50364 + if (p->sadb_protocol_reserved2 != 0) {
50365 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50366 + "pfkey_protocol_parse: res=%d, must be zero.\n",
50367 + p->sadb_protocol_reserved2);
50368 + SENDERR(EINVAL);
50369 + }
50370 +
50371 + errlab:
50372 + return error;
50373 +}
50374 +
50375 +#ifdef NAT_TRAVERSAL
50376 +DEBUG_NO_STATIC int
50377 +pfkey_x_ext_nat_t_type_parse(struct sadb_ext *pfkey_ext)
50378 +{
50379 + return 0;
50380 +}
50381 +DEBUG_NO_STATIC int
50382 +pfkey_x_ext_nat_t_port_parse(struct sadb_ext *pfkey_ext)
50383 +{
50384 + return 0;
50385 +}
50386 +#endif
50387 +
50388 +#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME};
50389 +
50390 +DEFINEPARSER(pfkey_sa_parse);
50391 +DEFINEPARSER(pfkey_lifetime_parse);
50392 +DEFINEPARSER(pfkey_address_parse);
50393 +DEFINEPARSER(pfkey_key_parse);
50394 +DEFINEPARSER(pfkey_ident_parse);
50395 +DEFINEPARSER(pfkey_sens_parse);
50396 +DEFINEPARSER(pfkey_prop_parse);
50397 +DEFINEPARSER(pfkey_supported_parse);
50398 +DEFINEPARSER(pfkey_spirange_parse);
50399 +DEFINEPARSER(pfkey_x_kmprivate_parse);
50400 +DEFINEPARSER(pfkey_x_satype_parse);
50401 +DEFINEPARSER(pfkey_x_ext_debug_parse);
50402 +DEFINEPARSER(pfkey_x_ext_protocol_parse);
50403 +#ifdef NAT_TRAVERSAL
50404 +DEFINEPARSER(pfkey_x_ext_nat_t_type_parse);
50405 +DEFINEPARSER(pfkey_x_ext_nat_t_port_parse);
50406 +#endif
50407 +
50408 +struct pf_key_ext_parsers_def *ext_default_parsers[]=
50409 +{
50410 + NULL, /* pfkey_msg_parse, */
50411 + &pfkey_sa_parse_def,
50412 + &pfkey_lifetime_parse_def,
50413 + &pfkey_lifetime_parse_def,
50414 + &pfkey_lifetime_parse_def,
50415 + &pfkey_address_parse_def,
50416 + &pfkey_address_parse_def,
50417 + &pfkey_address_parse_def,
50418 + &pfkey_key_parse_def,
50419 + &pfkey_key_parse_def,
50420 + &pfkey_ident_parse_def,
50421 + &pfkey_ident_parse_def,
50422 + &pfkey_sens_parse_def,
50423 + &pfkey_prop_parse_def,
50424 + &pfkey_supported_parse_def,
50425 + &pfkey_supported_parse_def,
50426 + &pfkey_spirange_parse_def,
50427 + &pfkey_x_kmprivate_parse_def,
50428 + &pfkey_x_satype_parse_def,
50429 + &pfkey_sa_parse_def,
50430 + &pfkey_address_parse_def,
50431 + &pfkey_address_parse_def,
50432 + &pfkey_address_parse_def,
50433 + &pfkey_address_parse_def,
50434 + &pfkey_address_parse_def,
50435 + &pfkey_x_ext_debug_parse_def,
50436 + &pfkey_x_ext_protocol_parse_def,
50437 +#ifdef NAT_TRAVERSAL
50438 + &pfkey_x_ext_nat_t_type_parse_def,
50439 + &pfkey_x_ext_nat_t_port_parse_def,
50440 + &pfkey_x_ext_nat_t_port_parse_def,
50441 + &pfkey_address_parse_def,
50442 +#else
50443 + NULL,NULL,NULL,NULL,
50444 +#endif
50445 +};
50446 +
50447 +int
50448 +pfkey_msg_parse(struct sadb_msg *pfkey_msg,
50449 + struct pf_key_ext_parsers_def *ext_parsers[],
50450 + struct sadb_ext *extensions[],
50451 + int dir)
50452 +{
50453 + int error = 0;
50454 + int remain;
50455 + struct sadb_ext *pfkey_ext;
50456 + unsigned int extensions_seen = 0;
50457 +
50458 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50459 + "pfkey_msg_parse: "
50460 + "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
50461 + pfkey_msg->sadb_msg_version,
50462 + pfkey_msg->sadb_msg_type,
50463 + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
50464 + pfkey_msg->sadb_msg_errno,
50465 + pfkey_msg->sadb_msg_satype,
50466 + satype2name(pfkey_msg->sadb_msg_satype),
50467 + pfkey_msg->sadb_msg_len,
50468 + pfkey_msg->sadb_msg_reserved,
50469 + pfkey_msg->sadb_msg_seq,
50470 + pfkey_msg->sadb_msg_pid);
50471 +
50472 + if(ext_parsers == NULL) ext_parsers = ext_default_parsers;
50473 +
50474 + pfkey_extensions_init(extensions);
50475 +
50476 + remain = pfkey_msg->sadb_msg_len;
50477 + remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
50478 +
50479 + pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg +
50480 + sizeof(struct sadb_msg));
50481 +
50482 + extensions[0] = (struct sadb_ext *) pfkey_msg;
50483 +
50484 +
50485 + if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
50486 + ERROR("pfkey_msg_parse: "
50487 + "not PF_KEY_V2 msg, found %d, should be %d.\n",
50488 + pfkey_msg->sadb_msg_version,
50489 + PF_KEY_V2);
50490 + SENDERR(EINVAL);
50491 + }
50492 +
50493 + if(!pfkey_msg->sadb_msg_type) {
50494 + ERROR("pfkey_msg_parse: "
50495 + "msg type not set, must be non-zero..\n");
50496 + SENDERR(EINVAL);
50497 + }
50498 +
50499 + if(pfkey_msg->sadb_msg_type > SADB_MAX) {
50500 + ERROR("pfkey_msg_parse: "
50501 + "msg type=%d > max=%d.\n",
50502 + pfkey_msg->sadb_msg_type,
50503 + SADB_MAX);
50504 + SENDERR(EINVAL);
50505 + }
50506 +
50507 + switch(pfkey_msg->sadb_msg_type) {
50508 + case SADB_GETSPI:
50509 + case SADB_UPDATE:
50510 + case SADB_ADD:
50511 + case SADB_DELETE:
50512 + case SADB_GET:
50513 + case SADB_X_GRPSA:
50514 + case SADB_X_ADDFLOW:
50515 + if(!satype2proto(pfkey_msg->sadb_msg_satype)) {
50516 + ERROR("pfkey_msg_parse: "
50517 + "satype %d conversion to proto failed for msg_type %d (%s).\n",
50518 + pfkey_msg->sadb_msg_satype,
50519 + pfkey_msg->sadb_msg_type,
50520 + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
50521 + SENDERR(EINVAL);
50522 + } else {
50523 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50524 + "pfkey_msg_parse: "
50525 + "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n",
50526 + pfkey_msg->sadb_msg_satype,
50527 + satype2name(pfkey_msg->sadb_msg_satype),
50528 + satype2proto(pfkey_msg->sadb_msg_satype),
50529 + pfkey_msg->sadb_msg_type,
50530 + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
50531 + }
50532 + case SADB_ACQUIRE:
50533 + case SADB_REGISTER:
50534 + case SADB_EXPIRE:
50535 + if(!pfkey_msg->sadb_msg_satype) {
50536 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50537 + "pfkey_msg_parse: "
50538 + "satype is zero, must be non-zero for msg_type %d(%s).\n",
50539 + pfkey_msg->sadb_msg_type,
50540 + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
50541 + SENDERR(EINVAL);
50542 + }
50543 + default:
50544 + break;
50545 + }
50546 +
50547 + /* errno must not be set in downward messages */
50548 + /* this is not entirely true... a response to an ACQUIRE could return an error */
50549 + if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) {
50550 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50551 + "pfkey_msg_parse: "
50552 + "errno set to %d.\n",
50553 + pfkey_msg->sadb_msg_errno);
50554 + SENDERR(EINVAL);
50555 + }
50556 +
50557 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
50558 + "pfkey_msg_parse: "
50559 + "remain=%d\n",
50560 + remain
50561 + );
50562 +
50563 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
50564 + "pfkey_msg_parse: "
50565 + "extensions permitted=%08x, required=%08x.\n",
50566 + extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
50567 + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
50568 +
50569 + extensions_seen = 1;
50570 +
50571 + while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) {
50572 + /* Is there enough message left to support another extension header? */
50573 + if(remain < pfkey_ext->sadb_ext_len) {
50574 + ERROR("pfkey_msg_parse: "
50575 + "remain %d less than ext len %d.\n",
50576 + remain, pfkey_ext->sadb_ext_len);
50577 + SENDERR(EINVAL);
50578 + }
50579 +
50580 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
50581 + "pfkey_msg_parse: "
50582 + "parsing ext type=%d(%s) remain=%d.\n",
50583 + pfkey_ext->sadb_ext_type,
50584 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
50585 + remain);
50586 +
50587 + /* Is the extension header type valid? */
50588 + if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) {
50589 + ERROR("pfkey_msg_parse: "
50590 + "ext type %d(%s) invalid, SADB_EXT_MAX=%d.\n",
50591 + pfkey_ext->sadb_ext_type,
50592 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
50593 + SADB_EXT_MAX);
50594 + SENDERR(EINVAL);
50595 + }
50596 +
50597 + /* Have we already seen this type of extension? */
50598 + if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0)
50599 + {
50600 + ERROR("pfkey_msg_parse: "
50601 + "ext type %d(%s) already seen.\n",
50602 + pfkey_ext->sadb_ext_type,
50603 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
50604 + SENDERR(EINVAL);
50605 + }
50606 +
50607 + /* Do I even know about this type of extension? */
50608 + if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) {
50609 + ERROR("pfkey_msg_parse: "
50610 + "ext type %d(%s) unknown, ignoring.\n",
50611 + pfkey_ext->sadb_ext_type,
50612 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
50613 + goto next_ext;
50614 + }
50615 +
50616 + /* Is this type of extension permitted for this type of message? */
50617 + if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] &
50618 + 1<<pfkey_ext->sadb_ext_type)) {
50619 + ERROR("pfkey_msg_parse: "
50620 + "ext type %d(%s) not permitted, exts_perm_in=%08x, 1<<type=%08x\n",
50621 + pfkey_ext->sadb_ext_type,
50622 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
50623 + extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
50624 + 1<<pfkey_ext->sadb_ext_type);
50625 + SENDERR(EINVAL);
50626 + }
50627 +
50628 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50629 + "pfkey_msg_parse: "
50630 + "remain=%d ext_type=%d(%s) ext_len=%d parsing ext 0p%p with parser %s.\n",
50631 + remain,
50632 + pfkey_ext->sadb_ext_type,
50633 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
50634 + pfkey_ext->sadb_ext_len,
50635 + pfkey_ext,
50636 + ext_parsers[pfkey_ext->sadb_ext_type]->parser_name);
50637 +
50638 + /* Parse the extension */
50639 + if((error =
50640 + (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) {
50641 + ERROR("pfkey_msg_parse: "
50642 + "extension parsing for type %d(%s) failed with error %d.\n",
50643 + pfkey_ext->sadb_ext_type,
50644 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
50645 + error);
50646 + SENDERR(-error);
50647 + }
50648 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
50649 + "pfkey_msg_parse: "
50650 + "Extension %d(%s) parsed.\n",
50651 + pfkey_ext->sadb_ext_type,
50652 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
50653 +
50654 + /* Mark that we have seen this extension and remember the header location */
50655 + extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type );
50656 + extensions[pfkey_ext->sadb_ext_type] = pfkey_ext;
50657 +
50658 + next_ext:
50659 + /* Calculate how much message remains */
50660 + remain -= pfkey_ext->sadb_ext_len;
50661 +
50662 + if(!remain) {
50663 + break;
50664 + }
50665 + /* Find the next extension header */
50666 + pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext +
50667 + pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
50668 + }
50669 +
50670 + if(remain) {
50671 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50672 + "pfkey_msg_parse: "
50673 + "unexpected remainder of %d.\n",
50674 + remain);
50675 + /* why is there still something remaining? */
50676 + SENDERR(EINVAL);
50677 + }
50678 +
50679 + /* check required extensions */
50680 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50681 + "pfkey_msg_parse: "
50682 + "extensions permitted=%08x, seen=%08x, required=%08x.\n",
50683 + extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
50684 + extensions_seen,
50685 + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
50686 +
50687 + /* don't check further if it is an error return message since it
50688 + may not have a body */
50689 + if(pfkey_msg->sadb_msg_errno) {
50690 + SENDERR(-error);
50691 + }
50692 +
50693 + if((extensions_seen &
50694 + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) !=
50695 + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) {
50696 + ERROR("pfkey_msg_parse: "
50697 + "required extensions missing:%08x.\n",
50698 + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] -
50699 + (extensions_seen &
50700 + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]));
50701 + SENDERR(EINVAL);
50702 + }
50703 +
50704 + if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW)
50705 + && ((extensions_seen & K_SADB_X_EXT_ADDRESS_DELFLOW)
50706 + != K_SADB_X_EXT_ADDRESS_DELFLOW)
50707 + && (((extensions_seen & (1<<SADB_EXT_SA)) != (1<<SADB_EXT_SA))
50708 + || ((((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_flags
50709 + & SADB_X_SAFLAGS_CLEARFLOW)
50710 + != SADB_X_SAFLAGS_CLEARFLOW))) {
50711 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50712 + "pfkey_msg_parse: "
50713 + "required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n",
50714 + K_SADB_X_EXT_ADDRESS_DELFLOW
50715 + - (extensions_seen & K_SADB_X_EXT_ADDRESS_DELFLOW),
50716 + (1<<SADB_EXT_SA) - (extensions_seen & (1<<SADB_EXT_SA)));
50717 + SENDERR(EINVAL);
50718 + }
50719 +
50720 + switch(pfkey_msg->sadb_msg_type) {
50721 + case SADB_ADD:
50722 + case SADB_UPDATE:
50723 + /* check maturity */
50724 + if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state !=
50725 + K_SADB_SASTATE_MATURE) {
50726 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50727 + "pfkey_msg_parse: "
50728 + "state=%d for add or update should be MATURE=%d.\n",
50729 + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
50730 + K_SADB_SASTATE_MATURE);
50731 + SENDERR(EINVAL);
50732 + }
50733 +
50734 + /* check AH and ESP */
50735 + switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) {
50736 + case SADB_SATYPE_AH:
50737 + if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
50738 + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth !=
50739 + SADB_AALG_NONE)) {
50740 + ERROR("pfkey_msg_parse: "
50741 + "auth alg is zero, must be non-zero for AH SAs.\n");
50742 + SENDERR(EINVAL);
50743 + }
50744 + if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt !=
50745 + SADB_EALG_NONE) {
50746 + ERROR("pfkey_msg_parse: "
50747 + "AH handed encalg=%d, must be zero.\n",
50748 + ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt);
50749 + SENDERR(EINVAL);
50750 + }
50751 + break;
50752 + case SADB_SATYPE_ESP:
50753 + if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
50754 + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
50755 + SADB_EALG_NONE)) {
50756 + ERROR("pfkey_msg_parse: "
50757 + "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n",
50758 + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
50759 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
50760 + SENDERR(EINVAL);
50761 + }
50762 + if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt ==
50763 + SADB_EALG_NULL) &&
50764 + (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth ==
50765 + SADB_AALG_NONE) ) {
50766 + ERROR("pfkey_msg_parse: "
50767 + "ESP handed encNULL+authNONE, illegal combination.\n");
50768 + SENDERR(EINVAL);
50769 + }
50770 + break;
50771 + case SADB_X_SATYPE_COMP:
50772 + if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
50773 + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
50774 + SADB_EALG_NONE)) {
50775 + ERROR("pfkey_msg_parse: "
50776 + "encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n",
50777 + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
50778 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
50779 + SENDERR(EINVAL);
50780 + }
50781 + if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth !=
50782 + SADB_AALG_NONE) {
50783 + ERROR("pfkey_msg_parse: "
50784 + "COMP handed auth=%d, must be zero.\n",
50785 + ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth);
50786 + SENDERR(EINVAL);
50787 + }
50788 + break;
50789 + default:
50790 + break;
50791 + }
50792 +
50793 + if(ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) {
50794 + ERROR("pfkey_msg_parse: "
50795 + "spi=%08x must be > 255.\n",
50796 + ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi));
50797 + SENDERR(EINVAL);
50798 + }
50799 + default:
50800 + break;
50801 + }
50802 +
50803 +errlab:
50804 + return error;
50805 +}
50806 +
50807 +/*
50808 + * Local variables:
50809 + * c-file-style: "linux"
50810 + * End:
50811 + *
50812 + */
50813 --- /dev/null Tue Mar 11 13:02:56 2003
50814 +++ linux/net/ipsec/pfkey_v2_parser.c Mon Feb 9 13:51:03 2004
50815 @@ -0,0 +1,3543 @@
50816 +/*
50817 + * @(#) RFC2367 PF_KEYv2 Key management API message parser
50818 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
50819 + *
50820 + * This program is free software; you can redistribute it and/or modify it
50821 + * under the terms of the GNU General Public License as published by the
50822 + * Free Software Foundation; either version 2 of the License, or (at your
50823 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
50824 + *
50825 + * This program is distributed in the hope that it will be useful, but
50826 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
50827 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
50828 + * for more details.
50829 + *
50830 + * RCSID $Id: pfkey_v2_parser.c,v 1.134 2005/05/11 01:48:20 mcr Exp $
50831 + */
50832 +
50833 +/*
50834 + * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
50835 + */
50836 +
50837 +char pfkey_v2_parser_c_version[] = "$Id: pfkey_v2_parser.c,v 1.134 2005/05/11 01:48:20 mcr Exp $";
50838 +
50839 +#ifndef AUTOCONF_INCLUDED
50840 +#include <linux/config.h>
50841 +#endif
50842 +#include <linux/version.h>
50843 +#include <linux/kernel.h> /* printk() */
50844 +
50845 +#include "openswan/ipsec_param.h"
50846 +
50847 +#ifdef MALLOC_SLAB
50848 +# include <linux/slab.h> /* kmalloc() */
50849 +#else /* MALLOC_SLAB */
50850 +# include <linux/malloc.h> /* kmalloc() */
50851 +#endif /* MALLOC_SLAB */
50852 +#include <linux/errno.h> /* error codes */
50853 +#include <linux/types.h> /* size_t */
50854 +#include <linux/interrupt.h> /* mark_bh */
50855 +
50856 +#include <linux/netdevice.h> /* struct device, and other headers */
50857 +#include <linux/etherdevice.h> /* eth_type_trans */
50858 +#include <linux/ip.h> /* struct iphdr */
50859 +#include <linux/skbuff.h>
50860 +
50861 +#include <openswan.h>
50862 +
50863 +#include <crypto/des.h>
50864 +
50865 +#ifdef SPINLOCK
50866 +# ifdef SPINLOCK_23
50867 +# include <linux/spinlock.h> /* *lock* */
50868 +# else /* SPINLOCK_23 */
50869 +# include <asm/spinlock.h> /* *lock* */
50870 +# endif /* SPINLOCK_23 */
50871 +#endif /* SPINLOCK */
50872 +#ifdef NET_21
50873 +# include <net/route.h> /* inet_addr_type */
50874 +# include <linux/in6.h>
50875 +# define ip_chk_addr inet_addr_type
50876 +# define IS_MYADDR RTN_LOCAL
50877 +#endif
50878 +
50879 +#include <net/ip.h>
50880 +#ifdef NETLINK_SOCK
50881 +# include <linux/netlink.h>
50882 +#else
50883 +# include <net/netlink.h>
50884 +#endif
50885 +
50886 +#include <linux/random.h> /* get_random_bytes() */
50887 +
50888 +#include "openswan/radij.h"
50889 +#include "openswan/ipsec_encap.h"
50890 +#include "openswan/ipsec_sa.h"
50891 +
50892 +#include "openswan/ipsec_radij.h"
50893 +#include "openswan/ipsec_xform.h"
50894 +#include "openswan/ipsec_ah.h"
50895 +#include "openswan/ipsec_esp.h"
50896 +#include "openswan/ipsec_tunnel.h"
50897 +#include "openswan/ipsec_rcv.h"
50898 +#include "openswan/ipcomp.h"
50899 +
50900 +#include <openswan/pfkeyv2.h>
50901 +#include <openswan/pfkey.h>
50902 +
50903 +#include "openswan/ipsec_proto.h"
50904 +#include "openswan/ipsec_alg.h"
50905 +
50906 +#include "openswan/ipsec_kern24.h"
50907 +
50908 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
50909 +
50910 +struct sklist_t {
50911 + struct socket *sk;
50912 + struct sklist_t* next;
50913 +} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev;
50914 +
50915 +__u32 pfkey_msg_seq = 0;
50916 +
50917 +
50918 +#if 0
50919 +#define DUMP_SAID dump_said(&extr->ips->ips_said, __LINE__)
50920 +#define DUMP_SAID2 dump_said(&extr.ips->ips_said, __LINE__)
50921 +static void dump_said(ip_said *s, int line)
50922 +{
50923 + char msa[SATOT_BUF];
50924 + size_t msa_len;
50925 +
50926 + msa_len = satot(s, 0, msa, sizeof(msa));
50927 +
50928 + printk("line: %d msa: %s\n", line, msa);
50929 +}
50930 +#endif
50931 +
50932 +
50933 +int
50934 +pfkey_alloc_eroute(struct eroute** eroute)
50935 +{
50936 + int error = 0;
50937 + if(*eroute) {
50938 + KLIPS_PRINT(debug_pfkey,
50939 + "klips_debug:pfkey_alloc_eroute: "
50940 + "eroute struct already allocated\n");
50941 + SENDERR(EEXIST);
50942 + }
50943 +
50944 + if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) {
50945 + KLIPS_PRINT(debug_pfkey,
50946 + "klips_debug:pfkey_alloc_eroute: "
50947 + "memory allocation error\n");
50948 + SENDERR(ENOMEM);
50949 + }
50950 +
50951 + KLIPS_PRINT(debug_pfkey,
50952 + "klips_debug:pfkey_alloc_eroute: "
50953 + "allocating %lu bytes for an eroute at 0p%p\n",
50954 + (unsigned long) sizeof(**eroute), *eroute);
50955 +
50956 + memset((caddr_t)*eroute, 0, sizeof(**eroute));
50957 + (*eroute)->er_eaddr.sen_len =
50958 + (*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap);
50959 + (*eroute)->er_eaddr.sen_family =
50960 + (*eroute)->er_emask.sen_family = AF_ENCAP;
50961 + (*eroute)->er_eaddr.sen_type = SENT_IP4;
50962 + (*eroute)->er_emask.sen_type = 255;
50963 + (*eroute)->er_pid = 0;
50964 + (*eroute)->er_count = 0;
50965 + (*eroute)->er_lasttime = jiffies/HZ;
50966 +
50967 + errlab:
50968 + return(error);
50969 +}
50970 +
50971 +DEBUG_NO_STATIC int
50972 +pfkey_x_protocol_process(struct sadb_ext *pfkey_ext,
50973 + struct pfkey_extracted_data *extr)
50974 +{
50975 + int error = 0;
50976 + struct sadb_protocol * p = (struct sadb_protocol *)pfkey_ext;
50977 +
50978 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_protocol_process: %p\n", extr);
50979 +
50980 + if (extr == 0) {
50981 + KLIPS_PRINT(debug_pfkey,
50982 + "klips_debug:pfkey_x_protocol_process:"
50983 + "extr is NULL, fatal\n");
50984 + SENDERR(EINVAL);
50985 + }
50986 + if (extr->eroute == 0) {
50987 + KLIPS_PRINT(debug_pfkey,
50988 + "klips_debug:pfkey_x_protocol_process:"
50989 + "extr->eroute is NULL, fatal\n");
50990 + SENDERR(EINVAL);
50991 + }
50992 +
50993 + extr->eroute->er_eaddr.sen_proto = p->sadb_protocol_proto;
50994 + extr->eroute->er_emask.sen_proto = p->sadb_protocol_proto ? ~0:0;
50995 + KLIPS_PRINT(debug_pfkey,
50996 + "klips_debug:pfkey_x_protocol_process: protocol = %d.\n",
50997 + p->sadb_protocol_proto);
50998 + errlab:
50999 + return error;
51000 +}
51001 +
51002 +DEBUG_NO_STATIC int
51003 +pfkey_ipsec_sa_init(struct ipsec_sa *ipsp)
51004 +{
51005 + int rc;
51006 + KLIPS_PRINT(debug_pfkey, "Calling SA_INIT\n");
51007 + rc = ipsec_sa_init(ipsp);
51008 + return rc;
51009 +}
51010 +
51011 +int
51012 +pfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1])
51013 +{
51014 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: "
51015 + "error=%d\n",
51016 + error);
51017 + if (!error) {
51018 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
51019 + "success.\n");
51020 + return 1;
51021 + } else {
51022 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
51023 + "caught error %d\n",
51024 + error);
51025 + pfkey_extensions_free(extensions);
51026 + return 0;
51027 + }
51028 +}
51029 +
51030 +
51031 +DEBUG_NO_STATIC int
51032 +pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
51033 +{
51034 + int error = 0;
51035 + ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L);
51036 + int found_avail = 0;
51037 + struct ipsec_sa *ipsq;
51038 + char sa[SATOT_BUF];
51039 + size_t sa_len;
51040 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
51041 + struct sadb_msg *pfkey_reply = NULL;
51042 + struct socket_list *pfkey_socketsp;
51043 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
51044 +
51045 + KLIPS_PRINT(debug_pfkey,
51046 + "klips_debug:pfkey_getspi_parse: .\n");
51047 +
51048 + pfkey_extensions_init(extensions_reply);
51049 +
51050 + if(extr == NULL || extr->ips == NULL) {
51051 + KLIPS_PRINT(debug_pfkey,
51052 + "klips_debug:pfkey_getspi_parse: "
51053 + "error, extr or extr->ipsec_sa pointer NULL\n");
51054 + SENDERR(EINVAL);
51055 + }
51056 +
51057 + if(extensions[SADB_EXT_SPIRANGE]) {
51058 + minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min;
51059 + maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max;
51060 + }
51061 +
51062 + if(maxspi == minspi) {
51063 + extr->ips->ips_said.spi = maxspi;
51064 + ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
51065 + if(ipsq != NULL) {
51066 + sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
51067 + ipsec_sa_put(ipsq);
51068 + KLIPS_PRINT(debug_pfkey,
51069 + "klips_debug:pfkey_getspi_parse: "
51070 + "EMT_GETSPI found an old ipsec_sa for SA: %s, delete it first.\n",
51071 + sa_len ? sa : " (error)");
51072 + SENDERR(EEXIST);
51073 + } else {
51074 + found_avail = 1;
51075 + }
51076 + } else {
51077 + int i = 0;
51078 + __u32 rand_val;
51079 + __u32 spi_diff;
51080 + while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) {
51081 + prng_bytes(&ipsec_prng, (char *) &(rand_val),
51082 + ( (spi_diff < (2^8)) ? 1 :
51083 + ( (spi_diff < (2^16)) ? 2 :
51084 + ( (spi_diff < (2^24)) ? 3 :
51085 + 4 ) ) ) );
51086 + extr->ips->ips_said.spi = htonl(ntohl(minspi) +
51087 + (rand_val %
51088 + (spi_diff + 1)));
51089 + i++;
51090 + ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
51091 + if(ipsq == NULL) {
51092 + found_avail = 1;
51093 + } else {
51094 + ipsec_sa_put(ipsq);
51095 + }
51096 + }
51097 + }
51098 +
51099 + sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
51100 +
51101 + if (!found_avail) {
51102 + KLIPS_PRINT(debug_pfkey,
51103 + "klips_debug:pfkey_getspi_parse: "
51104 + "found an old ipsec_sa for SA: %s, delete it first.\n",
51105 + sa_len ? sa : " (error)");
51106 + SENDERR(EEXIST);
51107 + }
51108 +
51109 + if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) {
51110 + extr->ips->ips_flags |= EMT_INBOUND;
51111 + }
51112 +
51113 + KLIPS_PRINT(debug_pfkey,
51114 + "klips_debug:pfkey_getspi_parse: "
51115 + "existing ipsec_sa not found (this is good) for SA: %s, %s-bound, allocating.\n",
51116 + sa_len ? sa : " (error)",
51117 + extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
51118 +
51119 + /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
51120 + extr->ips->ips_rcvif = NULL;
51121 + extr->ips->ips_life.ipl_addtime.ipl_count = jiffies/HZ;
51122 +
51123 + extr->ips->ips_state = K_SADB_SASTATE_LARVAL;
51124 +
51125 + if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
51126 + extr->ips->ips_life.ipl_allocations.ipl_count += 1;
51127 + }
51128 +
51129 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
51130 + SADB_GETSPI,
51131 + satype,
51132 + 0,
51133 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
51134 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
51135 + extensions_reply)
51136 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
51137 + SADB_EXT_SA,
51138 + extr->ips->ips_said.spi,
51139 + 0,
51140 + K_SADB_SASTATE_LARVAL,
51141 + 0,
51142 + 0,
51143 + 0,
51144 + extr->ips->ips_ref),
51145 + extensions_reply)
51146 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
51147 + SADB_EXT_ADDRESS_SRC,
51148 + 0, /*extr->ips->ips_said.proto,*/
51149 + 0,
51150 + extr->ips->ips_addr_s),
51151 + extensions_reply)
51152 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
51153 + SADB_EXT_ADDRESS_DST,
51154 + 0, /*extr->ips->ips_said.proto,*/
51155 + 0,
51156 + extr->ips->ips_addr_d),
51157 + extensions_reply) )) {
51158 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
51159 + "failed to build the getspi reply message extensions\n");
51160 + goto errlab;
51161 + }
51162 +
51163 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
51164 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
51165 + "failed to build the getspi reply message\n");
51166 + SENDERR(-error);
51167 + }
51168 + for(pfkey_socketsp = pfkey_open_sockets;
51169 + pfkey_socketsp;
51170 + pfkey_socketsp = pfkey_socketsp->next) {
51171 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
51172 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
51173 + "sending up getspi reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
51174 + satype,
51175 + satype2name(satype),
51176 + pfkey_socketsp->socketp,
51177 + error);
51178 + SENDERR(-error);
51179 + }
51180 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
51181 + "sending up getspi reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
51182 + satype,
51183 + satype2name(satype),
51184 + pfkey_socketsp->socketp);
51185 + }
51186 +
51187 + if((error = ipsec_sa_add(extr->ips))) {
51188 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
51189 + "failed to add the larval SA=%s with error=%d.\n",
51190 + sa_len ? sa : " (error)",
51191 + error);
51192 + SENDERR(-error);
51193 + }
51194 + extr->ips = NULL;
51195 +
51196 + KLIPS_PRINT(debug_pfkey,
51197 + "klips_debug:pfkey_getspi_parse: "
51198 + "successful for SA: %s\n",
51199 + sa_len ? sa : " (error)");
51200 +
51201 + errlab:
51202 + if (pfkey_reply) {
51203 + pfkey_msg_free(&pfkey_reply);
51204 + }
51205 + pfkey_extensions_free(extensions_reply);
51206 + return error;
51207 +}
51208 +
51209 +DEBUG_NO_STATIC int
51210 +pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
51211 +{
51212 + int error = 0;
51213 + struct ipsec_sa* ipsq;
51214 + char sa[SATOT_BUF];
51215 + size_t sa_len;
51216 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
51217 + struct sadb_msg *pfkey_reply = NULL;
51218 + struct socket_list *pfkey_socketsp;
51219 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
51220 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
51221 + struct ipsec_sa *nat_t_ips_saved = NULL;
51222 +#endif
51223 + KLIPS_PRINT(debug_pfkey,
51224 + "klips_debug:pfkey_update_parse: .\n");
51225 +
51226 + pfkey_extensions_init(extensions_reply);
51227 +
51228 + if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != K_SADB_SASTATE_MATURE) {
51229 + KLIPS_PRINT(debug_pfkey,
51230 + "klips_debug:pfkey_update_parse: "
51231 + "error, sa_state=%d must be MATURE=%d\n",
51232 + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
51233 + K_SADB_SASTATE_MATURE);
51234 + SENDERR(EINVAL);
51235 + }
51236 +
51237 + if(extr == NULL || extr->ips == NULL) {
51238 + KLIPS_PRINT(debug_pfkey,
51239 + "klips_debug:pfkey_update_parse: "
51240 + "error, extr or extr->ips pointer NULL\n");
51241 + SENDERR(EINVAL);
51242 + }
51243 +
51244 + sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
51245 +
51246 + spin_lock_bh(&tdb_lock);
51247 +
51248 + ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
51249 + if (ipsq == NULL) {
51250 + spin_unlock_bh(&tdb_lock);
51251 + KLIPS_PRINT(debug_pfkey,
51252 + "klips_debug:pfkey_update_parse: "
51253 + "reserved ipsec_sa for SA: %s not found. Call SADB_GETSPI first or call SADB_ADD instead.\n",
51254 + sa_len ? sa : " (error)");
51255 + SENDERR(ENOENT);
51256 + }
51257 +
51258 + if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) {
51259 + extr->ips->ips_flags |= EMT_INBOUND;
51260 + }
51261 +
51262 + KLIPS_PRINT(debug_pfkey,
51263 + "klips_debug:pfkey_update_parse: "
51264 + "existing ipsec_sa found (this is good) for SA: %s, %s-bound, updating.\n",
51265 + sa_len ? sa : " (error)",
51266 + extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
51267 +
51268 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
51269 + if (extr->ips->ips_natt_sport || extr->ips->ips_natt_dport) {
51270 + KLIPS_PRINT(debug_pfkey,
51271 + "klips_debug:pfkey_update_parse: only updating NAT-T ports "
51272 + "(%u:%u -> %u:%u)\n",
51273 + ipsq->ips_natt_sport, ipsq->ips_natt_dport,
51274 + extr->ips->ips_natt_sport, extr->ips->ips_natt_dport);
51275 +
51276 + if (extr->ips->ips_natt_sport) {
51277 + ipsq->ips_natt_sport = extr->ips->ips_natt_sport;
51278 + if (ipsq->ips_addr_s->sa_family == AF_INET) {
51279 + ((struct sockaddr_in *)(ipsq->ips_addr_s))->sin_port = htons(extr->ips->ips_natt_sport);
51280 + }
51281 + }
51282 +
51283 + if (extr->ips->ips_natt_dport) {
51284 + ipsq->ips_natt_dport = extr->ips->ips_natt_dport;
51285 + if (ipsq->ips_addr_d->sa_family == AF_INET) {
51286 + ((struct sockaddr_in *)(ipsq->ips_addr_d))->sin_port = htons(extr->ips->ips_natt_dport);
51287 + }
51288 + }
51289 +
51290 + nat_t_ips_saved = extr->ips;
51291 + extr->ips = ipsq;
51292 + }
51293 + else
51294 +#endif
51295 + {
51296 +
51297 + /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
51298 + extr->ips->ips_rcvif = NULL;
51299 + if ((error = pfkey_ipsec_sa_init(extr->ips))) {
51300 + ipsec_sa_put(ipsq);
51301 + spin_unlock_bh(&tdb_lock);
51302 + KLIPS_PRINT(debug_pfkey,
51303 + "klips_debug:pfkey_update_parse: "
51304 + "not successful for SA: %s, deleting.\n",
51305 + sa_len ? sa : " (error)");
51306 + SENDERR(-error);
51307 + }
51308 +
51309 + extr->ips->ips_life.ipl_addtime.ipl_count = ipsq->ips_life.ipl_addtime.ipl_count;
51310 +
51311 + /* this will call delchain-equivalent if refcount=>0 */
51312 + ipsec_sa_put(ipsq);
51313 + }
51314 +
51315 + spin_unlock_bh(&tdb_lock);
51316 +
51317 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
51318 + SADB_UPDATE,
51319 + satype,
51320 + 0,
51321 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
51322 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
51323 + extensions_reply)
51324 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
51325 + SADB_EXT_SA,
51326 + extr->ips->ips_said.spi,
51327 + extr->ips->ips_replaywin,
51328 + extr->ips->ips_state,
51329 + extr->ips->ips_authalg,
51330 + extr->ips->ips_encalg,
51331 + extr->ips->ips_flags,
51332 + extr->ips->ips_ref),
51333 + extensions_reply)
51334 + /* The 3 lifetime extentions should only be sent if non-zero. */
51335 + && (extensions[SADB_EXT_LIFETIME_HARD]
51336 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
51337 + SADB_EXT_LIFETIME_HARD,
51338 + extr->ips->ips_life.ipl_allocations.ipl_hard,
51339 + extr->ips->ips_life.ipl_bytes.ipl_hard,
51340 + extr->ips->ips_life.ipl_addtime.ipl_hard,
51341 + extr->ips->ips_life.ipl_usetime.ipl_hard,
51342 + extr->ips->ips_life.ipl_packets.ipl_hard),
51343 + extensions_reply) : 1)
51344 + && (extensions[SADB_EXT_LIFETIME_SOFT]
51345 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
51346 + SADB_EXT_LIFETIME_SOFT,
51347 + extr->ips->ips_life.ipl_allocations.ipl_count,
51348 + extr->ips->ips_life.ipl_bytes.ipl_count,
51349 + extr->ips->ips_life.ipl_addtime.ipl_count,
51350 + extr->ips->ips_life.ipl_usetime.ipl_count,
51351 + extr->ips->ips_life.ipl_packets.ipl_count),
51352 + extensions_reply) : 1)
51353 + && (extr->ips->ips_life.ipl_allocations.ipl_count
51354 + || extr->ips->ips_life.ipl_bytes.ipl_count
51355 + || extr->ips->ips_life.ipl_addtime.ipl_count
51356 + || extr->ips->ips_life.ipl_usetime.ipl_count
51357 + || extr->ips->ips_life.ipl_packets.ipl_count
51358 +
51359 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
51360 + SADB_EXT_LIFETIME_CURRENT,
51361 + extr->ips->ips_life.ipl_allocations.ipl_count,
51362 + extr->ips->ips_life.ipl_bytes.ipl_count,
51363 + extr->ips->ips_life.ipl_addtime.ipl_count,
51364 + extr->ips->ips_life.ipl_usetime.ipl_count,
51365 + extr->ips->ips_life.ipl_packets.ipl_count),
51366 + extensions_reply) : 1)
51367 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
51368 + SADB_EXT_ADDRESS_SRC,
51369 + 0, /*extr->ips->ips_said.proto,*/
51370 + 0,
51371 + extr->ips->ips_addr_s),
51372 + extensions_reply)
51373 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
51374 + SADB_EXT_ADDRESS_DST,
51375 + 0, /*extr->ips->ips_said.proto,*/
51376 + 0,
51377 + extr->ips->ips_addr_d),
51378 + extensions_reply)
51379 + && (extr->ips->ips_ident_s.data
51380 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
51381 + SADB_EXT_IDENTITY_SRC,
51382 + extr->ips->ips_ident_s.type,
51383 + extr->ips->ips_ident_s.id,
51384 + extr->ips->ips_ident_s.len,
51385 + extr->ips->ips_ident_s.data),
51386 + extensions_reply) : 1)
51387 + && (extr->ips->ips_ident_d.data
51388 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
51389 + SADB_EXT_IDENTITY_DST,
51390 + extr->ips->ips_ident_d.type,
51391 + extr->ips->ips_ident_d.id,
51392 + extr->ips->ips_ident_d.len,
51393 + extr->ips->ips_ident_d.data),
51394 + extensions_reply) : 1)
51395 +#if 0
51396 + /* FIXME: This won't work yet because I have not finished
51397 + it. */
51398 + && (extr->ips->ips_sens_
51399 + ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
51400 + extr->ips->ips_sens_dpd,
51401 + extr->ips->ips_sens_sens_level,
51402 + extr->ips->ips_sens_sens_len,
51403 + extr->ips->ips_sens_sens_bitmap,
51404 + extr->ips->ips_sens_integ_level,
51405 + extr->ips->ips_sens_integ_len,
51406 + extr->ips->ips_sens_integ_bitmap),
51407 + extensions_reply) : 1)
51408 +#endif
51409 + )) {
51410 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
51411 + "failed to build the update reply message extensions\n");
51412 + SENDERR(-error);
51413 + }
51414 +
51415 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
51416 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
51417 + "failed to build the update reply message\n");
51418 + SENDERR(-error);
51419 + }
51420 + for(pfkey_socketsp = pfkey_open_sockets;
51421 + pfkey_socketsp;
51422 + pfkey_socketsp = pfkey_socketsp->next) {
51423 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
51424 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
51425 + "sending up update reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
51426 + satype,
51427 + satype2name(satype),
51428 + pfkey_socketsp->socketp,
51429 + error);
51430 + SENDERR(-error);
51431 + }
51432 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
51433 + "sending up update reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
51434 + satype,
51435 + satype2name(satype),
51436 + pfkey_socketsp->socketp);
51437 + }
51438 +
51439 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
51440 + if (nat_t_ips_saved) {
51441 + /**
51442 + * As we _really_ update existing SA, we keep tdbq and need to delete
51443 + * parsed ips (nat_t_ips_saved, was extr->ips).
51444 + *
51445 + * goto errlab with extr->ips = nat_t_ips_saved will free it.
51446 + */
51447 +
51448 + extr->ips = nat_t_ips_saved;
51449 +
51450 + error = 0;
51451 + KLIPS_PRINT(debug_pfkey,
51452 + "klips_debug:pfkey_update_parse (NAT-T ports): "
51453 + "successful for SA: %s\n",
51454 + sa_len ? sa : " (error)");
51455 +
51456 + goto errlab;
51457 + }
51458 +#endif
51459 +
51460 + if((error = ipsec_sa_add(extr->ips))) {
51461 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
51462 + "failed to update the mature SA=%s with error=%d.\n",
51463 + sa_len ? sa : " (error)",
51464 + error);
51465 + SENDERR(-error);
51466 + }
51467 + extr->ips = NULL;
51468 +
51469 + KLIPS_PRINT(debug_pfkey,
51470 + "klips_debug:pfkey_update_parse: "
51471 + "successful for SA: %s\n",
51472 + sa_len ? sa : " (error)");
51473 +
51474 + errlab:
51475 + if (pfkey_reply) {
51476 + pfkey_msg_free(&pfkey_reply);
51477 + }
51478 + pfkey_extensions_free(extensions_reply);
51479 + return error;
51480 +}
51481 +
51482 +DEBUG_NO_STATIC int
51483 +pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
51484 +{
51485 + int error = 0;
51486 + struct ipsec_sa* ipsq;
51487 + char sa[SATOT_BUF];
51488 + size_t sa_len;
51489 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
51490 + struct sadb_msg *pfkey_reply = NULL;
51491 + struct socket_list *pfkey_socketsp;
51492 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
51493 +
51494 + KLIPS_PRINT(debug_pfkey,
51495 + "klips_debug:pfkey_add_parse: .\n");
51496 +
51497 + pfkey_extensions_init(extensions_reply);
51498 +
51499 + if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != K_SADB_SASTATE_MATURE) {
51500 + KLIPS_PRINT(debug_pfkey,
51501 + "klips_debug:pfkey_add_parse: "
51502 + "error, sa_state=%d must be MATURE=%d\n",
51503 + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
51504 + K_SADB_SASTATE_MATURE);
51505 + SENDERR(EINVAL);
51506 + }
51507 +
51508 + if(!extr || !extr->ips) {
51509 + KLIPS_PRINT(debug_pfkey,
51510 + "klips_debug:pfkey_add_parse: "
51511 + "extr or extr->ips pointer NULL\n");
51512 + SENDERR(EINVAL);
51513 + }
51514 +
51515 + sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
51516 +
51517 + ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
51518 + if(ipsq != NULL) {
51519 + ipsec_sa_put(ipsq);
51520 + KLIPS_PRINT(debug_pfkey,
51521 + "klips_debug:pfkey_add_parse: "
51522 + "found an old ipsec_sa for SA%s, delete it first.\n",
51523 + sa_len ? sa : " (error)");
51524 + SENDERR(EEXIST);
51525 + }
51526 +
51527 + if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) {
51528 + extr->ips->ips_flags |= EMT_INBOUND;
51529 + }
51530 +
51531 + KLIPS_PRINT(debug_pfkey,
51532 + "klips_debug:pfkey_add_parse: "
51533 + "existing ipsec_sa not found (this is good) for SA%s, %s-bound, allocating.\n",
51534 + sa_len ? sa : " (error)",
51535 + extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
51536 +
51537 + /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
51538 + extr->ips->ips_rcvif = NULL;
51539 +
51540 + if ((error = pfkey_ipsec_sa_init(extr->ips))) {
51541 + KLIPS_PRINT(debug_pfkey,
51542 + "klips_debug:pfkey_add_parse: "
51543 + "not successful for SA: %s, deleting.\n",
51544 + sa_len ? sa : " (error)");
51545 + SENDERR(-error);
51546 + }
51547 +
51548 +#if 0
51549 + /* extensions would provide this information, but not in this branch */
51550 + if(extr->sarefme!=IPSEC_SAREF_NULL
51551 + && extr->ips->ips_ref==IPSEC_SAREF_NULL) {
51552 + extr->ips->ips_ref=extr->sarefme;
51553 + }
51554 +
51555 + if(extr->sarefhim!=IPSEC_SAREF_NULL
51556 + && extr->ips->ips_refhim==IPSEC_SAREF_NULL) {
51557 + extr->ips->ips_refhim=extr->sarefhim;
51558 + }
51559 +#endif
51560 +
51561 + /* attach it to the SAref table */
51562 + if((error = ipsec_sa_intern(extr->ips)) != 0) {
51563 + KLIPS_ERROR(debug_pfkey,
51564 + "pfkey_add_parse: "
51565 + "failed to intern SA as SAref#%lu\n"
51566 + , (unsigned long)extr->ips->ips_ref);
51567 + SENDERR(-error);
51568 + }
51569 +
51570 + extr->ips->ips_life.ipl_addtime.ipl_count = jiffies / HZ;
51571 + if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
51572 + extr->ips->ips_life.ipl_allocations.ipl_count += 1;
51573 + }
51574 +
51575 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
51576 + SADB_ADD,
51577 + satype,
51578 + 0,
51579 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
51580 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
51581 + extensions_reply)
51582 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
51583 + SADB_EXT_SA,
51584 + extr->ips->ips_said.spi,
51585 + extr->ips->ips_replaywin,
51586 + extr->ips->ips_state,
51587 + extr->ips->ips_authalg,
51588 + extr->ips->ips_encalg,
51589 + extr->ips->ips_flags,
51590 + extr->ips->ips_ref),
51591 + extensions_reply)
51592 + /* The 3 lifetime extentions should only be sent if non-zero. */
51593 + && (extensions[SADB_EXT_LIFETIME_HARD]
51594 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
51595 + SADB_EXT_LIFETIME_HARD,
51596 + extr->ips->ips_life.ipl_allocations.ipl_hard,
51597 + extr->ips->ips_life.ipl_bytes.ipl_hard,
51598 + extr->ips->ips_life.ipl_addtime.ipl_hard,
51599 + extr->ips->ips_life.ipl_usetime.ipl_hard,
51600 + extr->ips->ips_life.ipl_packets.ipl_hard),
51601 + extensions_reply) : 1)
51602 + && (extensions[SADB_EXT_LIFETIME_SOFT]
51603 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
51604 + SADB_EXT_LIFETIME_SOFT,
51605 + extr->ips->ips_life.ipl_allocations.ipl_soft,
51606 + extr->ips->ips_life.ipl_bytes.ipl_soft,
51607 + extr->ips->ips_life.ipl_addtime.ipl_soft,
51608 + extr->ips->ips_life.ipl_usetime.ipl_soft,
51609 + extr->ips->ips_life.ipl_packets.ipl_soft),
51610 + extensions_reply) : 1)
51611 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
51612 + SADB_EXT_ADDRESS_SRC,
51613 + 0, /*extr->ips->ips_said.proto,*/
51614 + 0,
51615 + extr->ips->ips_addr_s),
51616 + extensions_reply)
51617 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
51618 + SADB_EXT_ADDRESS_DST,
51619 + 0, /*extr->ips->ips_said.proto,*/
51620 + 0,
51621 + extr->ips->ips_addr_d),
51622 + extensions_reply)
51623 + && (extr->ips->ips_ident_s.data
51624 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
51625 + SADB_EXT_IDENTITY_SRC,
51626 + extr->ips->ips_ident_s.type,
51627 + extr->ips->ips_ident_s.id,
51628 + extr->ips->ips_ident_s.len,
51629 + extr->ips->ips_ident_s.data),
51630 + extensions_reply) : 1)
51631 + && (extr->ips->ips_ident_d.data
51632 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
51633 + SADB_EXT_IDENTITY_DST,
51634 + extr->ips->ips_ident_d.type,
51635 + extr->ips->ips_ident_d.id,
51636 + extr->ips->ips_ident_d.len,
51637 + extr->ips->ips_ident_d.data),
51638 + extensions_reply) : 1)
51639 +#if 0
51640 + /* FIXME: This won't work yet because I have not finished
51641 + it. */
51642 + && (extr->ips->ips_sens_
51643 + ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
51644 + extr->ips->ips_sens_dpd,
51645 + extr->ips->ips_sens_sens_level,
51646 + extr->ips->ips_sens_sens_len,
51647 + extr->ips->ips_sens_sens_bitmap,
51648 + extr->ips->ips_sens_integ_level,
51649 + extr->ips->ips_sens_integ_len,
51650 + extr->ips->ips_sens_integ_bitmap),
51651 + extensions_reply) : 1)
51652 +#endif
51653 + )) {
51654 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
51655 + "failed to build the add reply message extensions\n");
51656 + SENDERR(-error);
51657 + }
51658 +
51659 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
51660 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
51661 + "failed to build the add reply message\n");
51662 + SENDERR(-error);
51663 + }
51664 + for(pfkey_socketsp = pfkey_open_sockets;
51665 + pfkey_socketsp;
51666 + pfkey_socketsp = pfkey_socketsp->next) {
51667 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
51668 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
51669 + "sending up add reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
51670 + satype,
51671 + satype2name(satype),
51672 + pfkey_socketsp->socketp,
51673 + error);
51674 + SENDERR(-error);
51675 + }
51676 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
51677 + "sending up add reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
51678 + satype,
51679 + satype2name(satype),
51680 + pfkey_socketsp->socketp);
51681 + }
51682 +
51683 + if((error = ipsec_sa_add(extr->ips))) {
51684 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
51685 + "failed to add the mature SA=%s with error=%d.\n",
51686 + sa_len ? sa : " (error)",
51687 + error);
51688 + SENDERR(-error);
51689 + }
51690 + ipsec_sa_put(extr->ips);
51691 + extr->ips = NULL;
51692 +
51693 + KLIPS_PRINT(debug_pfkey,
51694 + "klips_debug:pfkey_add_parse: "
51695 + "successful for SA: %s\n",
51696 + sa_len ? sa : " (error)");
51697 +
51698 + errlab:
51699 + if (pfkey_reply) {
51700 + pfkey_msg_free(&pfkey_reply);
51701 + }
51702 + pfkey_extensions_free(extensions_reply);
51703 + return error;
51704 +}
51705 +
51706 +DEBUG_NO_STATIC int
51707 +pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
51708 +{
51709 + struct ipsec_sa *ipsp;
51710 + char sa[SATOT_BUF];
51711 + size_t sa_len;
51712 + int error = 0;
51713 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
51714 + struct sadb_msg *pfkey_reply = NULL;
51715 + struct socket_list *pfkey_socketsp;
51716 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
51717 + IPsecSAref_t ref;
51718 +
51719 + KLIPS_PRINT(debug_pfkey,
51720 + "klips_debug:pfkey_delete_parse: .\n");
51721 +
51722 + pfkey_extensions_init(extensions_reply);
51723 +
51724 + if(!extr || !extr->ips) {
51725 + KLIPS_PRINT(debug_pfkey,
51726 + "klips_debug:pfkey_delete_parse: "
51727 + "extr or extr->ips pointer NULL, fatal\n");
51728 + SENDERR(EINVAL);
51729 + }
51730 +
51731 + sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
51732 +
51733 + spin_lock_bh(&tdb_lock);
51734 +
51735 + ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
51736 + if (ipsp == NULL) {
51737 + spin_unlock_bh(&tdb_lock);
51738 + KLIPS_PRINT(debug_pfkey,
51739 + "klips_debug:pfkey_delete_parse: "
51740 + "ipsec_sa not found for SA:%s, could not delete.\n",
51741 + sa_len ? sa : " (error)");
51742 + SENDERR(ESRCH);
51743 + }
51744 +
51745 + /* remove it from SAref tables */
51746 + ref = ipsp->ips_ref;
51747 + ipsec_sa_untern(ipsp);
51748 + ipsec_sa_rm(ipsp);
51749 +
51750 + /* this will call delchain-equivalent if refcount -> 0
51751 + * noting that get() above, added to ref count */
51752 + ipsec_sa_put(ipsp);
51753 + spin_unlock_bh(&tdb_lock);
51754 +
51755 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
51756 + SADB_DELETE,
51757 + satype,
51758 + 0,
51759 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
51760 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
51761 + extensions_reply)
51762 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
51763 + SADB_EXT_SA,
51764 + extr->ips->ips_said.spi,
51765 + 0,
51766 + 0,
51767 + 0,
51768 + 0,
51769 + 0,
51770 + ref),
51771 + extensions_reply)
51772 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
51773 + SADB_EXT_ADDRESS_SRC,
51774 + 0, /*extr->ips->ips_said.proto,*/
51775 + 0,
51776 + extr->ips->ips_addr_s),
51777 + extensions_reply)
51778 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
51779 + SADB_EXT_ADDRESS_DST,
51780 + 0, /*extr->ips->ips_said.proto,*/
51781 + 0,
51782 + extr->ips->ips_addr_d),
51783 + extensions_reply)
51784 + )) {
51785 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
51786 + "failed to build the delete reply message extensions\n");
51787 + SENDERR(-error);
51788 + }
51789 +
51790 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
51791 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
51792 + "failed to build the delete reply message\n");
51793 + SENDERR(-error);
51794 + }
51795 + for(pfkey_socketsp = pfkey_open_sockets;
51796 + pfkey_socketsp;
51797 + pfkey_socketsp = pfkey_socketsp->next) {
51798 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
51799 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
51800 + "sending up delete reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
51801 + satype,
51802 + satype2name(satype),
51803 + pfkey_socketsp->socketp,
51804 + error);
51805 + SENDERR(-error);
51806 + }
51807 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
51808 + "sending up delete reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
51809 + satype,
51810 + satype2name(satype),
51811 + pfkey_socketsp->socketp);
51812 + }
51813 +
51814 + errlab:
51815 + if (pfkey_reply) {
51816 + pfkey_msg_free(&pfkey_reply);
51817 + }
51818 + pfkey_extensions_free(extensions_reply);
51819 + return error;
51820 +}
51821 +
51822 +DEBUG_NO_STATIC int
51823 +pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
51824 +{
51825 + int error = 0;
51826 + struct ipsec_sa *ipsp;
51827 + char sa[SATOT_BUF];
51828 + size_t sa_len;
51829 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
51830 + struct sadb_msg *pfkey_reply = NULL;
51831 +
51832 + KLIPS_PRINT(debug_pfkey,
51833 + "klips_debug:pfkey_get_parse: .\n");
51834 +
51835 + pfkey_extensions_init(extensions_reply);
51836 +
51837 + if(!extr || !extr->ips) {
51838 + KLIPS_PRINT(debug_pfkey,
51839 + "klips_debug:pfkey_get_parse: "
51840 + "extr or extr->ips pointer NULL, fatal\n");
51841 + SENDERR(EINVAL);
51842 + }
51843 +
51844 + sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
51845 +
51846 + spin_lock_bh(&tdb_lock);
51847 +
51848 + ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
51849 + if (ipsp == NULL) {
51850 + spin_unlock_bh(&tdb_lock);
51851 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
51852 + "ipsec_sa not found for SA=%s, could not get.\n",
51853 + sa_len ? sa : " (error)");
51854 + SENDERR(ESRCH);
51855 + }
51856 +
51857 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
51858 + SADB_GET,
51859 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype,
51860 + 0,
51861 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
51862 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
51863 + extensions_reply)
51864 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
51865 + SADB_EXT_SA,
51866 + extr->ips->ips_said.spi,
51867 + extr->ips->ips_replaywin,
51868 + extr->ips->ips_state,
51869 + extr->ips->ips_authalg,
51870 + extr->ips->ips_encalg,
51871 + extr->ips->ips_flags,
51872 + extr->ips->ips_ref),
51873 + extensions_reply)
51874 + /* The 3 lifetime extentions should only be sent if non-zero. */
51875 + && (ipsp->ips_life.ipl_allocations.ipl_count
51876 + || ipsp->ips_life.ipl_bytes.ipl_count
51877 + || ipsp->ips_life.ipl_addtime.ipl_count
51878 + || ipsp->ips_life.ipl_usetime.ipl_count
51879 + || ipsp->ips_life.ipl_packets.ipl_count
51880 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
51881 + SADB_EXT_LIFETIME_CURRENT,
51882 + ipsp->ips_life.ipl_allocations.ipl_count,
51883 + ipsp->ips_life.ipl_bytes.ipl_count,
51884 + ipsp->ips_life.ipl_addtime.ipl_count,
51885 + ipsp->ips_life.ipl_usetime.ipl_count,
51886 + ipsp->ips_life.ipl_packets.ipl_count),
51887 + extensions_reply) : 1)
51888 + && (ipsp->ips_life.ipl_allocations.ipl_hard
51889 + || ipsp->ips_life.ipl_bytes.ipl_hard
51890 + || ipsp->ips_life.ipl_addtime.ipl_hard
51891 + || ipsp->ips_life.ipl_usetime.ipl_hard
51892 + || ipsp->ips_life.ipl_packets.ipl_hard
51893 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
51894 + SADB_EXT_LIFETIME_HARD,
51895 + ipsp->ips_life.ipl_allocations.ipl_hard,
51896 + ipsp->ips_life.ipl_bytes.ipl_hard,
51897 + ipsp->ips_life.ipl_addtime.ipl_hard,
51898 + ipsp->ips_life.ipl_usetime.ipl_hard,
51899 + ipsp->ips_life.ipl_packets.ipl_hard),
51900 + extensions_reply) : 1)
51901 + && (ipsp->ips_life.ipl_allocations.ipl_soft
51902 + || ipsp->ips_life.ipl_bytes.ipl_soft
51903 + || ipsp->ips_life.ipl_addtime.ipl_soft
51904 + || ipsp->ips_life.ipl_usetime.ipl_soft
51905 + || ipsp->ips_life.ipl_packets.ipl_soft
51906 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
51907 + SADB_EXT_LIFETIME_SOFT,
51908 + ipsp->ips_life.ipl_allocations.ipl_soft,
51909 + ipsp->ips_life.ipl_bytes.ipl_soft,
51910 + ipsp->ips_life.ipl_addtime.ipl_soft,
51911 + ipsp->ips_life.ipl_usetime.ipl_soft,
51912 + ipsp->ips_life.ipl_packets.ipl_soft),
51913 + extensions_reply) : 1)
51914 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
51915 + SADB_EXT_ADDRESS_SRC,
51916 + 0, /*extr->ips->ips_said.proto,*/
51917 + 0,
51918 + extr->ips->ips_addr_s),
51919 + extensions_reply)
51920 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
51921 + SADB_EXT_ADDRESS_DST,
51922 + 0, /*extr->ips->ips_said.proto,*/
51923 + 0,
51924 + extr->ips->ips_addr_d),
51925 + extensions_reply)
51926 + && (extr->ips->ips_addr_p
51927 + ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_PROXY],
51928 + SADB_EXT_ADDRESS_PROXY,
51929 + 0, /*extr->ips->ips_said.proto,*/
51930 + 0,
51931 + extr->ips->ips_addr_p),
51932 + extensions_reply) : 1)
51933 +#if 0
51934 + /* FIXME: This won't work yet because the keys are not
51935 + stored directly in the ipsec_sa. They are stored as
51936 + contexts. */
51937 + && (extr->ips->ips_key_a_size
51938 + ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_AUTH],
51939 + SADB_EXT_KEY_AUTH,
51940 + extr->ips->ips_key_a_size * 8,
51941 + extr->ips->ips_key_a),
51942 + extensions_reply) : 1)
51943 + /* FIXME: This won't work yet because the keys are not
51944 + stored directly in the ipsec_sa. They are stored as
51945 + key schedules. */
51946 + && (extr->ips->ips_key_e_size
51947 + ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_ENCRYPT],
51948 + SADB_EXT_KEY_ENCRYPT,
51949 + extr->ips->ips_key_e_size * 8,
51950 + extr->ips->ips_key_e),
51951 + extensions_reply) : 1)
51952 +#endif
51953 + && (extr->ips->ips_ident_s.data
51954 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
51955 + SADB_EXT_IDENTITY_SRC,
51956 + extr->ips->ips_ident_s.type,
51957 + extr->ips->ips_ident_s.id,
51958 + extr->ips->ips_ident_s.len,
51959 + extr->ips->ips_ident_s.data),
51960 + extensions_reply) : 1)
51961 + && (extr->ips->ips_ident_d.data
51962 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
51963 + SADB_EXT_IDENTITY_DST,
51964 + extr->ips->ips_ident_d.type,
51965 + extr->ips->ips_ident_d.id,
51966 + extr->ips->ips_ident_d.len,
51967 + extr->ips->ips_ident_d.data),
51968 + extensions_reply) : 1)
51969 +#if 0
51970 + /* FIXME: This won't work yet because I have not finished
51971 + it. */
51972 + && (extr->ips->ips_sens_
51973 + ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
51974 + extr->ips->ips_sens_dpd,
51975 + extr->ips->ips_sens_sens_level,
51976 + extr->ips->ips_sens_sens_len,
51977 + extr->ips->ips_sens_sens_bitmap,
51978 + extr->ips->ips_sens_integ_level,
51979 + extr->ips->ips_sens_integ_len,
51980 + extr->ips->ips_sens_integ_bitmap),
51981 + extensions_reply) : 1)
51982 +#endif
51983 + )) {
51984 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
51985 + "failed to build the get reply message extensions\n");
51986 + ipsec_sa_put(ipsp);
51987 + spin_unlock_bh(&tdb_lock);
51988 + SENDERR(-error);
51989 + }
51990 +
51991 + ipsec_sa_put(ipsp);
51992 + spin_unlock_bh(&tdb_lock);
51993 +
51994 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
51995 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
51996 + "failed to build the get reply message\n");
51997 + SENDERR(-error);
51998 + }
51999 +
52000 + if((error = pfkey_upmsg(sk->sk_socket, pfkey_reply))) {
52001 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
52002 + "failed to send the get reply message\n");
52003 + SENDERR(-error);
52004 + }
52005 +
52006 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
52007 + "succeeded in sending get reply message.\n");
52008 +
52009 + errlab:
52010 + if (pfkey_reply) {
52011 + pfkey_msg_free(&pfkey_reply);
52012 + }
52013 + pfkey_extensions_free(extensions_reply);
52014 + return error;
52015 +}
52016 +
52017 +DEBUG_NO_STATIC int
52018 +pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52019 +{
52020 + int error = 0;
52021 + struct socket_list *pfkey_socketsp;
52022 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52023 +
52024 + KLIPS_PRINT(debug_pfkey,
52025 + "klips_debug:pfkey_acquire_parse: .\n");
52026 +
52027 + /* XXX I don't know if we want an upper bound, since userspace may
52028 + want to register itself for an satype > SADB_SATYPE_MAX. */
52029 + if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
52030 + KLIPS_PRINT(debug_pfkey,
52031 + "klips_debug:pfkey_acquire_parse: "
52032 + "SATYPE=%d invalid.\n",
52033 + satype);
52034 + SENDERR(EINVAL);
52035 + }
52036 +
52037 + if(!(pfkey_registered_sockets[satype])) {
52038 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
52039 + "no sockets registered for SAtype=%d(%s).\n",
52040 + satype,
52041 + satype2name(satype));
52042 + SENDERR(EPROTONOSUPPORT);
52043 + }
52044 +
52045 + for(pfkey_socketsp = pfkey_registered_sockets[satype];
52046 + pfkey_socketsp;
52047 + pfkey_socketsp = pfkey_socketsp->next) {
52048 + if((error = pfkey_upmsg(pfkey_socketsp->socketp,
52049 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
52050 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
52051 + "sending up acquire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
52052 + satype,
52053 + satype2name(satype),
52054 + pfkey_socketsp->socketp,
52055 + error);
52056 + SENDERR(-error);
52057 + }
52058 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
52059 + "sending up acquire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
52060 + satype,
52061 + satype2name(satype),
52062 + pfkey_socketsp->socketp);
52063 + }
52064 +
52065 + errlab:
52066 + return error;
52067 +}
52068 +
52069 +DEBUG_NO_STATIC int
52070 +pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52071 +{
52072 + int error = 0;
52073 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52074 +
52075 + KLIPS_PRINT(debug_pfkey,
52076 + "klips_debug:pfkey_register_parse: .\n");
52077 +
52078 + /* XXX I don't know if we want an upper bound, since userspace may
52079 + want to register itself for an satype > SADB_SATYPE_MAX. */
52080 + if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
52081 + KLIPS_PRINT(debug_pfkey,
52082 + "klips_debug:pfkey_register_parse: "
52083 + "SATYPE=%d invalid.\n",
52084 + satype);
52085 + SENDERR(EINVAL);
52086 + }
52087 +
52088 + if(!pfkey_list_insert_socket(sk->sk_socket,
52089 + &(pfkey_registered_sockets[satype]))) {
52090 + KLIPS_PRINT(debug_pfkey,
52091 + "klips_debug:pfkey_register_parse: "
52092 + "SATYPE=%02d(%s) successfully registered by KMd (pid=%d).\n",
52093 + satype,
52094 + satype2name(satype),
52095 + key_pid(sk));
52096 + };
52097 +
52098 + /* send up register msg with supported SATYPE algos */
52099 +
52100 + error=pfkey_register_reply(satype, (struct sadb_msg*)extensions[SADB_EXT_RESERVED]);
52101 + errlab:
52102 + return error;
52103 +}
52104 +
52105 +int
52106 +pfkey_register_reply(int satype, struct sadb_msg *sadb_msg)
52107 +{
52108 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52109 + struct sadb_msg *pfkey_reply = NULL;
52110 + struct socket_list *pfkey_socketsp;
52111 + struct supported_list *pfkey_supported_listp;
52112 + unsigned int alg_num_a = 0, alg_num_e = 0;
52113 + struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL;
52114 + int error = 0;
52115 +
52116 + pfkey_extensions_init(extensions_reply);
52117 +
52118 + if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
52119 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
52120 + "SAtype=%d unspecified or unknown.\n",
52121 + satype);
52122 + SENDERR(EINVAL);
52123 + }
52124 + if(!(pfkey_registered_sockets[satype])) {
52125 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
52126 + "no sockets registered for SAtype=%d(%s).\n",
52127 + satype,
52128 + satype2name(satype));
52129 + SENDERR(EPROTONOSUPPORT);
52130 + }
52131 + /* send up register msg with supported SATYPE algos */
52132 + pfkey_supported_listp = pfkey_supported_list[satype];
52133 + KLIPS_PRINT(debug_pfkey,
52134 + "klips_debug:pfkey_register_reply: "
52135 + "pfkey_supported_list[%d]=0p%p\n",
52136 + satype,
52137 + pfkey_supported_list[satype]);
52138 + while(pfkey_supported_listp) {
52139 + KLIPS_PRINT(debug_pfkey,
52140 + "klips_debug:pfkey_register_reply: "
52141 + "checking supported=0p%p\n",
52142 + pfkey_supported_listp);
52143 + if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_AUTH) {
52144 + KLIPS_PRINT(debug_pfkey,
52145 + "klips_debug:pfkey_register_reply: "
52146 + "adding auth alg.\n");
52147 + alg_num_a++;
52148 + }
52149 + if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
52150 + KLIPS_PRINT(debug_pfkey,
52151 + "klips_debug:pfkey_register_reply: "
52152 + "adding encrypt alg.\n");
52153 + alg_num_e++;
52154 + }
52155 + pfkey_supported_listp = pfkey_supported_listp->next;
52156 + }
52157 +
52158 + if(alg_num_a) {
52159 + KLIPS_PRINT(debug_pfkey,
52160 + "klips_debug:pfkey_register_reply: "
52161 + "allocating %lu bytes for auth algs.\n",
52162 + (unsigned long) (alg_num_a * sizeof(struct sadb_alg)));
52163 + if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
52164 + KLIPS_PRINT(debug_pfkey,
52165 + "klips_debug:pfkey_register_reply: "
52166 + "auth alg memory allocation error\n");
52167 + SENDERR(ENOMEM);
52168 + }
52169 + alg_ap = alg_a;
52170 + }
52171 +
52172 + if(alg_num_e) {
52173 + KLIPS_PRINT(debug_pfkey,
52174 + "klips_debug:pfkey_register_reply: "
52175 + "allocating %lu bytes for enc algs.\n",
52176 + (unsigned long) (alg_num_e * sizeof(struct sadb_alg)));
52177 + if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
52178 + KLIPS_PRINT(debug_pfkey,
52179 + "klips_debug:pfkey_register_reply: "
52180 + "enc alg memory allocation error\n");
52181 + SENDERR(ENOMEM);
52182 + }
52183 + alg_ep = alg_e;
52184 + }
52185 +
52186 + pfkey_supported_listp = pfkey_supported_list[satype];
52187 + while(pfkey_supported_listp) {
52188 + if(alg_num_a) {
52189 + if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_AUTH) {
52190 + alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->ias_id;
52191 + alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->ias_ivlen;
52192 + alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->ias_keyminbits;
52193 + alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->ias_keymaxbits;
52194 + alg_ap->sadb_alg_reserved = 0;
52195 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
52196 + "klips_debug:pfkey_register_reply: "
52197 + "adding auth=0p%p\n",
52198 + alg_ap);
52199 + alg_ap++;
52200 + }
52201 + }
52202 + if(alg_num_e) {
52203 + if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
52204 + alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->ias_id;
52205 + alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->ias_ivlen;
52206 + alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->ias_keyminbits;
52207 + alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->ias_keymaxbits;
52208 + alg_ep->sadb_alg_reserved = 0;
52209 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
52210 + "klips_debug:pfkey_register_reply: "
52211 + "adding encrypt=0p%p\n",
52212 + alg_ep);
52213 + alg_ep++;
52214 + }
52215 + }
52216 + KLIPS_PRINT(debug_pfkey,
52217 + "klips_debug:pfkey_register_reply: "
52218 + "found satype=%d(%s) exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
52219 + satype,
52220 + satype2name(satype),
52221 + pfkey_supported_listp->supportedp->ias_exttype,
52222 + pfkey_supported_listp->supportedp->ias_id,
52223 + pfkey_supported_listp->supportedp->ias_ivlen,
52224 + pfkey_supported_listp->supportedp->ias_keyminbits,
52225 + pfkey_supported_listp->supportedp->ias_keymaxbits);
52226 + pfkey_supported_listp = pfkey_supported_listp->next;
52227 + }
52228 +
52229 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
52230 + SADB_REGISTER,
52231 + satype,
52232 + 0,
52233 + sadb_msg? sadb_msg->sadb_msg_seq : ++pfkey_msg_seq,
52234 + sadb_msg? sadb_msg->sadb_msg_pid: current->pid),
52235 + extensions_reply) &&
52236 + (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_AUTH],
52237 + SADB_EXT_SUPPORTED_AUTH,
52238 + alg_num_a,
52239 + alg_a),
52240 + extensions_reply) : 1) &&
52241 + (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_ENCRYPT],
52242 + SADB_EXT_SUPPORTED_ENCRYPT,
52243 + alg_num_e,
52244 + alg_e),
52245 + extensions_reply) : 1))) {
52246 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
52247 + "failed to build the register message extensions_reply\n");
52248 + SENDERR(-error);
52249 + }
52250 +
52251 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
52252 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
52253 + "failed to build the register message\n");
52254 + SENDERR(-error);
52255 + }
52256 + /* this should go to all registered sockets for that satype only */
52257 + for(pfkey_socketsp = pfkey_registered_sockets[satype];
52258 + pfkey_socketsp;
52259 + pfkey_socketsp = pfkey_socketsp->next) {
52260 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
52261 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
52262 + "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
52263 + satype,
52264 + satype2name(satype),
52265 + pfkey_socketsp->socketp,
52266 + error);
52267 + SENDERR(-error);
52268 + }
52269 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
52270 + "sending up register message for satype=%d(%s) to socket=0p%p succeeded.\n",
52271 + satype,
52272 + satype2name(satype),
52273 + pfkey_socketsp->socketp);
52274 + }
52275 +
52276 + errlab:
52277 + if(alg_a) {
52278 + kfree(alg_a);
52279 + }
52280 + if(alg_e) {
52281 + kfree(alg_e);
52282 + }
52283 +
52284 + if (pfkey_reply) {
52285 + pfkey_msg_free(&pfkey_reply);
52286 + }
52287 + pfkey_extensions_free(extensions_reply);
52288 + return error;
52289 +}
52290 +
52291 +DEBUG_NO_STATIC int
52292 +pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52293 +{
52294 + int error = 0;
52295 + struct socket_list *pfkey_socketsp;
52296 +#ifdef CONFIG_KLIPS_DEBUG
52297 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52298 +#endif /* CONFIG_KLIPS_DEBUG */
52299 +
52300 + KLIPS_PRINT(debug_pfkey,
52301 + "klips_debug:pfkey_expire_parse: .\n");
52302 +
52303 + if(pfkey_open_sockets) {
52304 + for(pfkey_socketsp = pfkey_open_sockets;
52305 + pfkey_socketsp;
52306 + pfkey_socketsp = pfkey_socketsp->next) {
52307 + if((error = pfkey_upmsg(pfkey_socketsp->socketp,
52308 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
52309 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
52310 + "sending up expire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
52311 + satype,
52312 + satype2name(satype),
52313 + pfkey_socketsp->socketp,
52314 + error);
52315 + SENDERR(-error);
52316 + }
52317 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
52318 + "sending up expire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
52319 + satype,
52320 + satype2name(satype),
52321 + pfkey_socketsp->socketp);
52322 + }
52323 + }
52324 +
52325 + errlab:
52326 + return error;
52327 +}
52328 +
52329 +DEBUG_NO_STATIC int
52330 +pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52331 +{
52332 + int error = 0;
52333 + struct socket_list *pfkey_socketsp;
52334 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52335 + uint8_t proto = 0;
52336 +
52337 + KLIPS_PRINT(debug_pfkey,
52338 + "klips_debug:pfkey_flush_parse: "
52339 + "flushing type %d SAs\n",
52340 + satype);
52341 +
52342 + if(satype && !(proto = satype2proto(satype))) {
52343 + KLIPS_PRINT(debug_pfkey,
52344 + "klips_debug:pfkey_flush_parse: "
52345 + "satype %d lookup failed.\n",
52346 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
52347 + SENDERR(EINVAL);
52348 + }
52349 +
52350 + if ((error = ipsec_sadb_cleanup(proto))) {
52351 + SENDERR(-error);
52352 + }
52353 +
52354 + if(pfkey_open_sockets) {
52355 + for(pfkey_socketsp = pfkey_open_sockets;
52356 + pfkey_socketsp;
52357 + pfkey_socketsp = pfkey_socketsp->next) {
52358 + if((error = pfkey_upmsg(pfkey_socketsp->socketp,
52359 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
52360 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
52361 + "sending up flush reply message for satype=%d(%s) (proto=%d) to socket=0p%p failed with error=%d.\n",
52362 + satype,
52363 + satype2name(satype),
52364 + proto,
52365 + pfkey_socketsp->socketp,
52366 + error);
52367 + SENDERR(-error);
52368 + }
52369 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
52370 + "sending up flush reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
52371 + satype,
52372 + satype2name(satype),
52373 + pfkey_socketsp->socketp);
52374 + }
52375 + }
52376 +
52377 + errlab:
52378 + return error;
52379 +}
52380 +
52381 +DEBUG_NO_STATIC int
52382 +pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52383 +{
52384 + int error = 0;
52385 +
52386 + KLIPS_PRINT(debug_pfkey,
52387 + "klips_debug:pfkey_dump_parse: .\n");
52388 +
52389 + SENDERR(ENOSYS);
52390 + errlab:
52391 + return error;
52392 +}
52393 +
52394 +DEBUG_NO_STATIC int
52395 +pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52396 +{
52397 + int error = 0;
52398 +
52399 + KLIPS_PRINT(debug_pfkey,
52400 + "klips_debug:pfkey_promisc_parse: .\n");
52401 +
52402 + SENDERR(ENOSYS);
52403 + errlab:
52404 + return error;
52405 +}
52406 +
52407 +DEBUG_NO_STATIC int
52408 +pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52409 +{
52410 + int error = 0;
52411 +
52412 + KLIPS_PRINT(debug_pfkey,
52413 + "klips_debug:pfkey_x_pchange_parse: .\n");
52414 +
52415 + SENDERR(ENOSYS);
52416 + errlab:
52417 + return error;
52418 +}
52419 +
52420 +DEBUG_NO_STATIC int
52421 +pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52422 +{
52423 + struct ipsec_sa *ips1p, *ips2p, *ipsp;
52424 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52425 + struct sadb_msg *pfkey_reply = NULL;
52426 + struct socket_list *pfkey_socketsp;
52427 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52428 + char sa1[SATOT_BUF], sa2[SATOT_BUF];
52429 + size_t sa_len1, sa_len2 = 0;
52430 + int error = 0;
52431 +
52432 + KLIPS_PRINT(debug_pfkey,
52433 + "klips_debug:pfkey_x_grpsa_parse: .\n");
52434 +
52435 + pfkey_extensions_init(extensions_reply);
52436 +
52437 + if(extr == NULL || extr->ips == NULL) {
52438 + KLIPS_PRINT(debug_pfkey,
52439 + "klips_debug:pfkey_x_grpsa_parse: "
52440 + "extr or extr->ips is NULL, fatal.\n");
52441 + SENDERR(EINVAL);
52442 + }
52443 +
52444 + sa_len1 = satot(&extr->ips->ips_said, 0, sa1, sizeof(sa1));
52445 + if(extr->ips2 != NULL) {
52446 + sa_len2 = satot(&extr->ips2->ips_said, 0, sa2, sizeof(sa2));
52447 + }
52448 +
52449 + spin_lock_bh(&tdb_lock);
52450 +
52451 + ips1p = ipsec_sa_getbyid(&(extr->ips->ips_said));
52452 + if(ips1p == NULL) {
52453 + spin_unlock_bh(&tdb_lock);
52454 + KLIPS_PRINT(debug_pfkey,
52455 + "klips_debug:pfkey_x_grpsa_parse: "
52456 + "reserved ipsec_sa for SA1: %s not found. Call SADB_ADD/UPDATE first.\n",
52457 + sa_len1 ? sa1 : " (error)");
52458 + SENDERR(ENOENT);
52459 + }
52460 + if(extr->ips2) { /* GRPSA */
52461 + ips2p = ipsec_sa_getbyid(&(extr->ips2->ips_said));
52462 + if(ips2p == NULL) {
52463 + ipsec_sa_put(ips1p);
52464 + spin_unlock_bh(&tdb_lock);
52465 + KLIPS_PRINT(debug_pfkey,
52466 + "klips_debug:pfkey_x_grpsa_parse: "
52467 + "reserved ipsec_sa for SA2: %s not found. Call SADB_ADD/UPDATE first.\n",
52468 + sa_len2 ? sa2 : " (error)");
52469 + SENDERR(ENOENT);
52470 + }
52471 +
52472 + /* Is either one already linked? */
52473 + if(ips1p->ips_onext) {
52474 + ipsec_sa_put(ips1p);
52475 + ipsec_sa_put(ips2p);
52476 + spin_unlock_bh(&tdb_lock);
52477 + KLIPS_PRINT(debug_pfkey,
52478 + "klips_debug:pfkey_x_grpsa_parse: "
52479 + "ipsec_sa for SA: %s is already linked.\n",
52480 + sa_len1 ? sa1 : " (error)");
52481 + SENDERR(EEXIST);
52482 + }
52483 + if(ips2p->ips_inext) {
52484 + ipsec_sa_put(ips1p);
52485 + ipsec_sa_put(ips2p);
52486 + spin_unlock_bh(&tdb_lock);
52487 + KLIPS_PRINT(debug_pfkey,
52488 + "klips_debug:pfkey_x_grpsa_parse: "
52489 + "ipsec_sa for SA: %s is already linked.\n",
52490 + sa_len2 ? sa2 : " (error)");
52491 + SENDERR(EEXIST);
52492 + }
52493 +
52494 + /* Is extr->ips already linked to extr->ips2? */
52495 + ipsp = ips2p;
52496 + while(ipsp) {
52497 + if(ipsp == ips1p) {
52498 + ipsec_sa_put(ips1p);
52499 + ipsec_sa_put(ips2p);
52500 + spin_unlock_bh(&tdb_lock);
52501 + KLIPS_PRINT(debug_pfkey,
52502 + "klips_debug:pfkey_x_grpsa_parse: "
52503 + "ipsec_sa for SA: %s is already linked to %s.\n",
52504 + sa_len1 ? sa1 : " (error)",
52505 + sa_len2 ? sa2 : " (error)");
52506 + SENDERR(EEXIST);
52507 + }
52508 + ipsp = ipsp->ips_onext;
52509 + }
52510 +
52511 + /* link 'em */
52512 + KLIPS_PRINT(debug_pfkey,
52513 + "klips_debug:pfkey_x_grpsa_parse: "
52514 + "linking ipsec_sa SA: %s with %s.\n",
52515 + sa_len1 ? sa1 : " (error)",
52516 + sa_len2 ? sa2 : " (error)");
52517 + ips1p->ips_onext = ips2p;
52518 + ips2p->ips_inext = ips1p;
52519 + } else { /* UNGRPSA */
52520 + ipsec_sa_put(ips1p);
52521 + KLIPS_PRINT(debug_pfkey,
52522 + "klips_debug:pfkey_x_grpsa_parse: "
52523 + "unlinking ipsec_sa SA: %s.\n",
52524 + sa_len1 ? sa1 : " (error)");
52525 + while(ips1p->ips_onext) {
52526 + ips1p = ips1p->ips_onext;
52527 + }
52528 + while(ips1p->ips_inext) {
52529 + ipsp = ips1p;
52530 + ips1p = ips1p->ips_inext;
52531 + ipsec_sa_put(ips1p);
52532 + ipsp->ips_inext = NULL;
52533 + ipsec_sa_put(ipsp);
52534 + ips1p->ips_onext = NULL;
52535 + }
52536 + }
52537 +
52538 + spin_unlock_bh(&tdb_lock);
52539 +
52540 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
52541 + SADB_X_GRPSA,
52542 + satype,
52543 + 0,
52544 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
52545 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
52546 + extensions_reply)
52547 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
52548 + SADB_EXT_SA,
52549 + extr->ips->ips_said.spi,
52550 + extr->ips->ips_replaywin,
52551 + extr->ips->ips_state,
52552 + extr->ips->ips_authalg,
52553 + extr->ips->ips_encalg,
52554 + extr->ips->ips_flags,
52555 + extr->ips->ips_ref),
52556 + extensions_reply)
52557 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
52558 + SADB_EXT_ADDRESS_DST,
52559 + 0, /*extr->ips->ips_said.proto,*/
52560 + 0,
52561 + extr->ips->ips_addr_d),
52562 + extensions_reply)
52563 + && (extr->ips2
52564 + ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[SADB_X_EXT_SATYPE2],
52565 + ((struct sadb_x_satype*)extensions[SADB_X_EXT_SATYPE2])->sadb_x_satype_satype
52566 + /* proto2satype(extr->ips2->ips_said.proto) */),
52567 + extensions_reply)
52568 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_X_EXT_SA2],
52569 + SADB_X_EXT_SA2,
52570 + extr->ips2->ips_said.spi,
52571 + extr->ips2->ips_replaywin,
52572 + extr->ips2->ips_state,
52573 + extr->ips2->ips_authalg,
52574 + extr->ips2->ips_encalg,
52575 + extr->ips2->ips_flags,
52576 + extr->ips2->ips_ref),
52577 + extensions_reply)
52578 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST2],
52579 + SADB_X_EXT_ADDRESS_DST2,
52580 + 0, /*extr->ips->ips_said.proto,*/
52581 + 0,
52582 + extr->ips2->ips_addr_d),
52583 + extensions_reply) ) : 1 )
52584 + )) {
52585 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
52586 + "failed to build the x_grpsa reply message extensions\n");
52587 + SENDERR(-error);
52588 + }
52589 +
52590 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
52591 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
52592 + "failed to build the x_grpsa reply message\n");
52593 + SENDERR(-error);
52594 + }
52595 +
52596 + for(pfkey_socketsp = pfkey_open_sockets;
52597 + pfkey_socketsp;
52598 + pfkey_socketsp = pfkey_socketsp->next) {
52599 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
52600 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
52601 + "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
52602 + satype,
52603 + satype2name(satype),
52604 + pfkey_socketsp->socketp,
52605 + error);
52606 + SENDERR(-error);
52607 + }
52608 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
52609 + "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
52610 + satype,
52611 + satype2name(satype),
52612 + pfkey_socketsp->socketp);
52613 + }
52614 +
52615 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
52616 + "succeeded in sending x_grpsa reply message.\n");
52617 +
52618 + errlab:
52619 + if (pfkey_reply) {
52620 + pfkey_msg_free(&pfkey_reply);
52621 + }
52622 + pfkey_extensions_free(extensions_reply);
52623 + return error;
52624 +}
52625 +
52626 +DEBUG_NO_STATIC int
52627 +pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52628 +{
52629 + int error = 0;
52630 +#ifdef CONFIG_KLIPS_DEBUG
52631 + char buf1[64], buf2[64];
52632 +#endif /* CONFIG_KLIPS_DEBUG */
52633 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52634 + struct sadb_msg *pfkey_reply = NULL;
52635 + struct socket_list *pfkey_socketsp;
52636 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52637 + ip_address srcflow, dstflow, srcmask, dstmask;
52638 +
52639 + KLIPS_PRINT(debug_pfkey,
52640 + "klips_debug:pfkey_x_addflow_parse: .\n");
52641 +
52642 + pfkey_extensions_init(extensions_reply);
52643 +
52644 + memset((caddr_t)&srcflow, 0, sizeof(srcflow));
52645 + memset((caddr_t)&dstflow, 0, sizeof(dstflow));
52646 + memset((caddr_t)&srcmask, 0, sizeof(srcmask));
52647 + memset((caddr_t)&dstmask, 0, sizeof(dstmask));
52648 +
52649 + if(!extr || !(extr->ips) || !(extr->eroute)) {
52650 + KLIPS_PRINT(debug_pfkey,
52651 + "klips_debug:pfkey_x_addflow_parse: "
52652 + "missing extr, ipsec_sa or eroute data.\n");
52653 + SENDERR(EINVAL);
52654 + }
52655 +
52656 + srcflow.u.v4.sin_family = AF_INET;
52657 + dstflow.u.v4.sin_family = AF_INET;
52658 + srcmask.u.v4.sin_family = AF_INET;
52659 + dstmask.u.v4.sin_family = AF_INET;
52660 + srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
52661 + dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
52662 + srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
52663 + dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
52664 +
52665 +#ifdef CONFIG_KLIPS_DEBUG
52666 + if (debug_pfkey) {
52667 + subnettoa(extr->eroute->er_eaddr.sen_ip_src,
52668 + extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
52669 + subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
52670 + extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
52671 + KLIPS_PRINT(debug_pfkey,
52672 + "klips_debug:pfkey_x_addflow_parse: "
52673 + "calling breakeroute and/or makeroute for %s->%s\n",
52674 + buf1, buf2);
52675 + }
52676 +#endif /* CONFIG_KLIPS_DEBUG */
52677 + if(extr->ips->ips_flags & SADB_X_SAFLAGS_INFLOW) {
52678 +/* if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) */
52679 + struct ipsec_sa *ipsp, *ipsq;
52680 + char sa[SATOT_BUF];
52681 + size_t sa_len;
52682 +
52683 + ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
52684 + if(ipsq == NULL) {
52685 + KLIPS_PRINT(debug_pfkey,
52686 + "klips_debug:pfkey_x_addflow_parse: "
52687 + "ipsec_sa not found, cannot set incoming policy.\n");
52688 + SENDERR(ENOENT);
52689 + }
52690 +
52691 + ipsp = ipsq;
52692 + while(ipsp && ipsp->ips_said.proto != IPPROTO_IPIP) {
52693 + ipsp = ipsp->ips_inext;
52694 + }
52695 +
52696 + if(ipsp == NULL) {
52697 + ipsec_sa_put(ipsq);
52698 + KLIPS_PRINT(debug_pfkey,
52699 + "klips_debug:pfkey_x_addflow_parse: "
52700 + "SA chain does not have an IPIP SA, cannot set incoming policy.\n");
52701 + SENDERR(ENOENT);
52702 + }
52703 +
52704 + sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
52705 +
52706 + ipsp->ips_flags |= SADB_X_SAFLAGS_INFLOW;
52707 + ipsp->ips_flow_s = srcflow;
52708 + ipsp->ips_flow_d = dstflow;
52709 + ipsp->ips_mask_s = srcmask;
52710 + ipsp->ips_mask_d = dstmask;
52711 +
52712 + ipsec_sa_put(ipsq);
52713 +
52714 + KLIPS_PRINT(debug_pfkey,
52715 + "klips_debug:pfkey_x_addflow_parse: "
52716 + "inbound eroute, setting incoming policy information in IPIP ipsec_sa for SA: %s.\n",
52717 + sa_len ? sa : " (error)");
52718 + } else {
52719 + struct sk_buff *first = NULL, *last = NULL;
52720 +
52721 + if(extr->ips->ips_flags & SADB_X_SAFLAGS_REPLACEFLOW) {
52722 + KLIPS_PRINT(debug_pfkey,
52723 + "klips_debug:pfkey_x_addflow_parse: "
52724 + "REPLACEFLOW flag set, calling breakeroute.\n");
52725 + if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr),
52726 + &(extr->eroute->er_emask),
52727 + &first, &last))) {
52728 + KLIPS_PRINT(debug_pfkey,
52729 + "klips_debug:pfkey_x_addflow_parse: "
52730 + "breakeroute returned %d. first=0p%p, last=0p%p\n",
52731 + error,
52732 + first,
52733 + last);
52734 + if(first != NULL) {
52735 + ipsec_kfree_skb(first);
52736 + }
52737 + if(last != NULL) {
52738 + ipsec_kfree_skb(last);
52739 + }
52740 + SENDERR(-error);
52741 + }
52742 + }
52743 +
52744 + KLIPS_PRINT(debug_pfkey,
52745 + "klips_debug:pfkey_x_addflow_parse: "
52746 + "calling makeroute.\n");
52747 +
52748 + if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr),
52749 + &(extr->eroute->er_emask),
52750 + extr->ips->ips_said,
52751 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid,
52752 + NULL,
52753 + &(extr->ips->ips_ident_s),
52754 + &(extr->ips->ips_ident_d)))) {
52755 + KLIPS_PRINT(debug_pfkey,
52756 + "klips_debug:pfkey_x_addflow_parse: "
52757 + "makeroute returned %d.\n", error);
52758 + SENDERR(-error);
52759 + }
52760 + if(first != NULL) {
52761 + KLIPS_PRINT(debug_eroute,
52762 + "klips_debug:pfkey_x_addflow_parse: "
52763 + "first=0p%p HOLD packet re-injected.\n",
52764 + first);
52765 + dst_output(first);
52766 + }
52767 + if(last != NULL) {
52768 + KLIPS_PRINT(debug_eroute,
52769 + "klips_debug:pfkey_x_addflow_parse: "
52770 + "last=0p%p HOLD packet re-injected.\n",
52771 + last);
52772 + dst_output(last);
52773 + }
52774 + }
52775 +
52776 + KLIPS_PRINT(debug_pfkey,
52777 + "klips_debug:pfkey_x_addflow_parse: "
52778 + "makeroute call successful.\n");
52779 +
52780 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
52781 + SADB_X_ADDFLOW,
52782 + satype,
52783 + 0,
52784 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
52785 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
52786 + extensions_reply)
52787 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
52788 + SADB_EXT_SA,
52789 + extr->ips->ips_said.spi,
52790 + extr->ips->ips_replaywin,
52791 + extr->ips->ips_state,
52792 + extr->ips->ips_authalg,
52793 + extr->ips->ips_encalg,
52794 + extr->ips->ips_flags,
52795 + extr->ips->ips_ref),
52796 + extensions_reply)
52797 + && (extensions[SADB_EXT_ADDRESS_SRC]
52798 + ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
52799 + SADB_EXT_ADDRESS_SRC,
52800 + 0, /*extr->ips->ips_said.proto,*/
52801 + 0,
52802 + extr->ips->ips_addr_s),
52803 + extensions_reply) : 1)
52804 + && (extensions[SADB_EXT_ADDRESS_DST]
52805 + ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
52806 + SADB_EXT_ADDRESS_DST,
52807 + 0, /*extr->ips->ips_said.proto,*/
52808 + 0,
52809 + extr->ips->ips_addr_d),
52810 + extensions_reply) : 1)
52811 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
52812 + SADB_X_EXT_ADDRESS_SRC_FLOW,
52813 + 0, /*extr->ips->ips_said.proto,*/
52814 + 0,
52815 + (struct sockaddr*)&srcflow),
52816 + extensions_reply)
52817 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
52818 + SADB_X_EXT_ADDRESS_DST_FLOW,
52819 + 0, /*extr->ips->ips_said.proto,*/
52820 + 0,
52821 + (struct sockaddr*)&dstflow),
52822 + extensions_reply)
52823 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
52824 + SADB_X_EXT_ADDRESS_SRC_MASK,
52825 + 0, /*extr->ips->ips_said.proto,*/
52826 + 0,
52827 + (struct sockaddr*)&srcmask),
52828 + extensions_reply)
52829 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
52830 + SADB_X_EXT_ADDRESS_DST_MASK,
52831 + 0, /*extr->ips->ips_said.proto,*/
52832 + 0,
52833 + (struct sockaddr*)&dstmask),
52834 + extensions_reply)
52835 + )) {
52836 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
52837 + "failed to build the x_addflow reply message extensions\n");
52838 + SENDERR(-error);
52839 + }
52840 +
52841 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
52842 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
52843 + "failed to build the x_addflow reply message\n");
52844 + SENDERR(-error);
52845 + }
52846 +
52847 + for(pfkey_socketsp = pfkey_open_sockets;
52848 + pfkey_socketsp;
52849 + pfkey_socketsp = pfkey_socketsp->next) {
52850 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
52851 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
52852 + "sending up x_addflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
52853 + satype,
52854 + satype2name(satype),
52855 + pfkey_socketsp->socketp,
52856 + error);
52857 + SENDERR(-error);
52858 + }
52859 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
52860 + "sending up x_addflow reply message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
52861 + satype,
52862 + satype2name(satype),
52863 + extr->ips->ips_said.proto,
52864 + pfkey_socketsp->socketp);
52865 + }
52866 +
52867 + KLIPS_PRINT(debug_pfkey,
52868 + "klips_debug:pfkey_x_addflow_parse: "
52869 + "extr->ips cleaned up and freed.\n");
52870 +
52871 + errlab:
52872 + if (pfkey_reply) {
52873 + pfkey_msg_free(&pfkey_reply);
52874 + }
52875 + pfkey_extensions_free(extensions_reply);
52876 + return error;
52877 +}
52878 +
52879 +DEBUG_NO_STATIC int
52880 +pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52881 +{
52882 + int error = 0;
52883 +#ifdef CONFIG_KLIPS_DEBUG
52884 + char buf1[64], buf2[64];
52885 +#endif /* CONFIG_KLIPS_DEBUG */
52886 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52887 + struct sadb_msg *pfkey_reply = NULL;
52888 + struct socket_list *pfkey_socketsp;
52889 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52890 + ip_address srcflow, dstflow, srcmask, dstmask;
52891 +
52892 + KLIPS_PRINT(debug_pfkey,
52893 + "klips_debug:pfkey_x_delflow_parse: .\n");
52894 +
52895 + pfkey_extensions_init(extensions_reply);
52896 +
52897 + memset((caddr_t)&srcflow, 0, sizeof(srcflow));
52898 + memset((caddr_t)&dstflow, 0, sizeof(dstflow));
52899 + memset((caddr_t)&srcmask, 0, sizeof(srcmask));
52900 + memset((caddr_t)&dstmask, 0, sizeof(dstmask));
52901 +
52902 + if(!extr || !(extr->ips)) {
52903 + KLIPS_PRINT(debug_pfkey,
52904 + "klips_debug:pfkey_x_delflow_parse: "
52905 + "extr, or extr->ips is NULL, fatal\n");
52906 + SENDERR(EINVAL);
52907 + }
52908 +
52909 + if(extr->ips->ips_flags & SADB_X_SAFLAGS_CLEARFLOW) {
52910 + KLIPS_PRINT(debug_pfkey,
52911 + "klips_debug:pfkey_x_delflow_parse: "
52912 + "CLEARFLOW flag set, calling cleareroutes.\n");
52913 + if ((error = ipsec_cleareroutes())) {
52914 + KLIPS_PRINT(debug_pfkey,
52915 + "klips_debug:pfkey_x_delflow_parse: "
52916 + "cleareroutes returned %d.\n", error);
52917 + SENDERR(-error);
52918 + }
52919 + } else {
52920 + struct sk_buff *first = NULL, *last = NULL;
52921 +
52922 + if(!(extr->eroute)) {
52923 + KLIPS_PRINT(debug_pfkey,
52924 + "klips_debug:pfkey_x_delflow_parse: "
52925 + "extr->eroute is NULL, fatal.\n");
52926 + SENDERR(EINVAL);
52927 + }
52928 +
52929 + srcflow.u.v4.sin_family = AF_INET;
52930 + dstflow.u.v4.sin_family = AF_INET;
52931 + srcmask.u.v4.sin_family = AF_INET;
52932 + dstmask.u.v4.sin_family = AF_INET;
52933 + srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
52934 + dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
52935 + srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
52936 + dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
52937 +
52938 +#ifdef CONFIG_KLIPS_DEBUG
52939 + if (debug_pfkey) {
52940 + subnettoa(extr->eroute->er_eaddr.sen_ip_src,
52941 + extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
52942 + subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
52943 + extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
52944 + KLIPS_PRINT(debug_pfkey,
52945 + "klips_debug:pfkey_x_delflow_parse: "
52946 + "calling breakeroute for %s->%s\n",
52947 + buf1, buf2);
52948 + }
52949 +#endif /* CONFIG_KLIPS_DEBUG */
52950 + error = ipsec_breakroute(&(extr->eroute->er_eaddr),
52951 + &(extr->eroute->er_emask),
52952 + &first, &last);
52953 + if(error) {
52954 + KLIPS_PRINT(debug_pfkey,
52955 + "klips_debug:pfkey_x_delflow_parse: "
52956 + "breakeroute returned %d. first=0p%p, last=0p%p\n",
52957 + error,
52958 + first,
52959 + last);
52960 + }
52961 + if(first != NULL) {
52962 + ipsec_kfree_skb(first);
52963 + }
52964 + if(last != NULL) {
52965 + ipsec_kfree_skb(last);
52966 + }
52967 + if(error) {
52968 + SENDERR(-error);
52969 + }
52970 + }
52971 +
52972 + error = pfkey_msg_hdr_build(&extensions_reply[0],
52973 + SADB_X_DELFLOW,
52974 + satype, 0,
52975 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
52976 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid);
52977 +
52978 + if(pfkey_safe_build(error, extensions_reply)) {
52979 + error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
52980 + SADB_EXT_SA,
52981 + extr->ips->ips_said.spi,
52982 + extr->ips->ips_replaywin,
52983 + extr->ips->ips_state,
52984 + extr->ips->ips_authalg,
52985 + extr->ips->ips_encalg,
52986 + extr->ips->ips_flags,
52987 + extr->ips->ips_ref);
52988 + }
52989 +
52990 + if(!(extr->ips->ips_flags & SADB_X_SAFLAGS_CLEARFLOW)) {
52991 + if(pfkey_safe_build(error, extensions_reply)) {
52992 + error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
52993 + SADB_X_EXT_ADDRESS_SRC_FLOW,
52994 + 0, /*extr->ips->ips_said.proto,*/
52995 + 0,
52996 + (struct sockaddr*)&srcflow);
52997 + }
52998 +
52999 + if(pfkey_safe_build(error, extensions_reply)) {
53000 + error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
53001 + SADB_X_EXT_ADDRESS_DST_FLOW,
53002 + 0, /*extr->ips->ips_said.proto,*/
53003 + 0,
53004 + (struct sockaddr*)&dstflow);
53005 + }
53006 +
53007 + if(pfkey_safe_build(error, extensions_reply)) {
53008 + error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
53009 + SADB_X_EXT_ADDRESS_SRC_MASK,
53010 + 0, /*extr->ips->ips_said.proto,*/
53011 + 0,
53012 + (struct sockaddr*)&srcmask);
53013 + }
53014 +
53015 + if(pfkey_safe_build(error, extensions_reply)) {
53016 + error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
53017 + SADB_X_EXT_ADDRESS_DST_MASK,
53018 + 0, /*extr->ips->ips_said.proto,*/
53019 + 0,
53020 + (struct sockaddr*)&dstmask);
53021 + }
53022 + }
53023 +
53024 + if(!pfkey_safe_build(error, extensions_reply)) {
53025 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
53026 + "failed to build the x_delflow reply message extensions\n");
53027 + SENDERR(-error);
53028 + }
53029 +
53030 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
53031 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
53032 + "failed to build the x_delflow reply message\n");
53033 + SENDERR(-error);
53034 + }
53035 +
53036 + for(pfkey_socketsp = pfkey_open_sockets;
53037 + pfkey_socketsp;
53038 + pfkey_socketsp = pfkey_socketsp->next) {
53039 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
53040 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
53041 + "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53042 + satype,
53043 + satype2name(satype),
53044 + pfkey_socketsp->socketp,
53045 + error);
53046 + SENDERR(-error);
53047 + }
53048 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
53049 + "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53050 + satype,
53051 + satype2name(satype),
53052 + pfkey_socketsp->socketp);
53053 + }
53054 +
53055 + KLIPS_PRINT(debug_pfkey,
53056 + "klips_debug:pfkey_x_delflow_parse: "
53057 + "extr->ips cleaned up and freed.\n");
53058 +
53059 + errlab:
53060 + if (pfkey_reply) {
53061 + pfkey_msg_free(&pfkey_reply);
53062 + }
53063 + pfkey_extensions_free(extensions_reply);
53064 + return error;
53065 +}
53066 +
53067 +DEBUG_NO_STATIC int
53068 +pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53069 +{
53070 + int error = 0;
53071 +
53072 + KLIPS_PRINT(debug_pfkey,
53073 + "klips_debug:pfkey_x_msg_debug_parse: .\n");
53074 +
53075 +/* errlab:*/
53076 + return error;
53077 +}
53078 +
53079 +/* pfkey_expire expects the ipsec_sa table to be locked before being called. */
53080 +int
53081 +pfkey_expire(struct ipsec_sa *ipsp, int hard)
53082 +{
53083 + struct sadb_ext *extensions[SADB_EXT_MAX+1];
53084 + struct sadb_msg *pfkey_msg = NULL;
53085 + struct socket_list *pfkey_socketsp;
53086 + int error = 0;
53087 + uint8_t satype;
53088 +
53089 + pfkey_extensions_init(extensions);
53090 +
53091 + if(!(satype = proto2satype(ipsp->ips_said.proto))) {
53092 + KLIPS_PRINT(debug_pfkey,
53093 + "klips_debug:pfkey_expire: "
53094 + "satype lookup for protocol %d lookup failed.\n",
53095 + ipsp->ips_said.proto);
53096 + SENDERR(EINVAL);
53097 + }
53098 +
53099 + if(!pfkey_open_sockets) {
53100 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
53101 + "no sockets listening.\n");
53102 + SENDERR(EPROTONOSUPPORT);
53103 + }
53104 +
53105 + if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
53106 + SADB_EXPIRE,
53107 + satype,
53108 + 0,
53109 + ++pfkey_msg_seq,
53110 + 0),
53111 + extensions)
53112 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
53113 + SADB_EXT_SA,
53114 + ipsp->ips_said.spi,
53115 + ipsp->ips_replaywin,
53116 + ipsp->ips_state,
53117 + ipsp->ips_authalg,
53118 + ipsp->ips_encalg,
53119 + ipsp->ips_flags,
53120 + ipsp->ips_ref),
53121 + extensions)
53122 + && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT],
53123 + SADB_EXT_LIFETIME_CURRENT,
53124 + ipsp->ips_life.ipl_allocations.ipl_count,
53125 + ipsp->ips_life.ipl_bytes.ipl_count,
53126 + ipsp->ips_life.ipl_addtime.ipl_count,
53127 + ipsp->ips_life.ipl_usetime.ipl_count,
53128 + ipsp->ips_life.ipl_packets.ipl_count),
53129 + extensions)
53130 + && (hard ?
53131 + pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD],
53132 + SADB_EXT_LIFETIME_HARD,
53133 + ipsp->ips_life.ipl_allocations.ipl_hard,
53134 + ipsp->ips_life.ipl_bytes.ipl_hard,
53135 + ipsp->ips_life.ipl_addtime.ipl_hard,
53136 + ipsp->ips_life.ipl_usetime.ipl_hard,
53137 + ipsp->ips_life.ipl_packets.ipl_hard),
53138 + extensions)
53139 + : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT],
53140 + SADB_EXT_LIFETIME_SOFT,
53141 + ipsp->ips_life.ipl_allocations.ipl_soft,
53142 + ipsp->ips_life.ipl_bytes.ipl_soft,
53143 + ipsp->ips_life.ipl_addtime.ipl_soft,
53144 + ipsp->ips_life.ipl_usetime.ipl_soft,
53145 + ipsp->ips_life.ipl_packets.ipl_soft),
53146 + extensions))
53147 + && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
53148 + SADB_EXT_ADDRESS_SRC,
53149 + 0, /* ipsp->ips_said.proto, */
53150 + 0,
53151 + ipsp->ips_addr_s),
53152 + extensions)
53153 + && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
53154 + SADB_EXT_ADDRESS_DST,
53155 + 0, /* ipsp->ips_said.proto, */
53156 + 0,
53157 + ipsp->ips_addr_d),
53158 + extensions))) {
53159 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
53160 + "failed to build the expire message extensions\n");
53161 + spin_unlock(&tdb_lock);
53162 + goto errlab;
53163 + }
53164 +
53165 + if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
53166 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
53167 + "failed to build the expire message\n");
53168 + SENDERR(-error);
53169 + }
53170 +
53171 + for(pfkey_socketsp = pfkey_open_sockets;
53172 + pfkey_socketsp;
53173 + pfkey_socketsp = pfkey_socketsp->next) {
53174 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
53175 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
53176 + "sending up expire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53177 + satype,
53178 + satype2name(satype),
53179 + pfkey_socketsp->socketp,
53180 + error);
53181 + SENDERR(-error);
53182 + }
53183 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
53184 + "sending up expire message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
53185 + satype,
53186 + satype2name(satype),
53187 + ipsp->ips_said.proto,
53188 + pfkey_socketsp->socketp);
53189 + }
53190 +
53191 + errlab:
53192 + if (pfkey_msg) {
53193 + pfkey_msg_free(&pfkey_msg);
53194 + }
53195 + pfkey_extensions_free(extensions);
53196 + return error;
53197 +}
53198 +
53199 +int
53200 +pfkey_acquire(struct ipsec_sa *ipsp)
53201 +{
53202 + struct sadb_ext *extensions[SADB_EXT_MAX+1];
53203 + struct sadb_msg *pfkey_msg = NULL;
53204 + struct socket_list *pfkey_socketsp;
53205 + int error = 0;
53206 + struct sadb_comb comb[] = {
53207 + /* auth; encrypt; flags; */
53208 + /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */
53209 + /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */
53210 + /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */
53211 + /* soft_packets; hard_packets; */
53212 + { SADB_AALG_MD5HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
53213 + 128, 128, 168, 168,
53214 + 0, 0, 0, 0, 0,
53215 + 57600, 86400, 57600, 86400,
53216 + 0, 0 },
53217 + { SADB_AALG_SHA1HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
53218 + 160, 160, 168, 168,
53219 + 0, 0, 0, 0, 0,
53220 + 57600, 86400, 57600, 86400,
53221 + 0, 0 }
53222 + };
53223 +
53224 + /* XXX This should not be hard-coded. It should be taken from the spdb */
53225 + uint8_t satype = SADB_SATYPE_ESP;
53226 +
53227 + pfkey_extensions_init(extensions);
53228 +
53229 + if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
53230 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
53231 + "SAtype=%d unspecified or unknown.\n",
53232 + satype);
53233 + SENDERR(EINVAL);
53234 + }
53235 +
53236 + if(!(pfkey_registered_sockets[satype])) {
53237 + KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
53238 + "no sockets registered for SAtype=%d(%s).\n",
53239 + satype,
53240 + satype2name(satype));
53241 + SENDERR(EPROTONOSUPPORT);
53242 + }
53243 +
53244 + if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
53245 + SADB_ACQUIRE,
53246 + satype,
53247 + 0,
53248 + ++pfkey_msg_seq,
53249 + 0),
53250 + extensions)
53251 + && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
53252 + SADB_EXT_ADDRESS_SRC,
53253 + ipsp->ips_transport_protocol,
53254 + 0,
53255 + ipsp->ips_addr_s),
53256 + extensions)
53257 + && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
53258 + SADB_EXT_ADDRESS_DST,
53259 + ipsp->ips_transport_protocol,
53260 + 0,
53261 + ipsp->ips_addr_d),
53262 + extensions)
53263 +#if 0
53264 + && (ipsp->ips_addr_p
53265 + ? pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY],
53266 + SADB_EXT_ADDRESS_PROXY,
53267 + ipsp->ips_transport_protocol,
53268 + 0,
53269 + ipsp->ips_addr_p),
53270 + extensions) : 1)
53271 +#endif
53272 + && (ipsp->ips_ident_s.type != SADB_IDENTTYPE_RESERVED
53273 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC],
53274 + SADB_EXT_IDENTITY_SRC,
53275 + ipsp->ips_ident_s.type,
53276 + ipsp->ips_ident_s.id,
53277 + ipsp->ips_ident_s.len,
53278 + ipsp->ips_ident_s.data),
53279 + extensions) : 1)
53280 +
53281 + && (ipsp->ips_ident_d.type != SADB_IDENTTYPE_RESERVED
53282 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST],
53283 + SADB_EXT_IDENTITY_DST,
53284 + ipsp->ips_ident_d.type,
53285 + ipsp->ips_ident_d.id,
53286 + ipsp->ips_ident_d.len,
53287 + ipsp->ips_ident_d.data),
53288 + extensions) : 1)
53289 +#if 0
53290 + /* FIXME: This won't work yet because I have not finished
53291 + it. */
53292 + && (ipsp->ips_sens_
53293 + ? pfkey_safe_build(error = pfkey_sens_build(&extensions[SADB_EXT_SENSITIVITY],
53294 + ipsp->ips_sens_dpd,
53295 + ipsp->ips_sens_sens_level,
53296 + ipsp->ips_sens_sens_len,
53297 + ipsp->ips_sens_sens_bitmap,
53298 + ipsp->ips_sens_integ_level,
53299 + ipsp->ips_sens_integ_len,
53300 + ipsp->ips_sens_integ_bitmap),
53301 + extensions) : 1)
53302 +#endif
53303 + && pfkey_safe_build(error = pfkey_prop_build(&extensions[SADB_EXT_PROPOSAL],
53304 + 64, /* replay */
53305 + sizeof(comb)/sizeof(struct sadb_comb),
53306 + &(comb[0])),
53307 + extensions)
53308 + )) {
53309 + KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
53310 + "failed to build the acquire message extensions\n");
53311 + SENDERR(-error);
53312 + }
53313 +
53314 + if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
53315 + KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
53316 + "failed to build the acquire message\n");
53317 + SENDERR(-error);
53318 + }
53319 +
53320 +#if defined(KLIPS_PFKEY_ACQUIRE_LOSSAGE) && KLIPS_PFKEY_ACQUIRE_LOSSAGE > 0
53321 + if(sysctl_ipsec_regress_pfkey_lossage) {
53322 + return(0);
53323 + }
53324 +#endif
53325 +
53326 + /* this should go to all registered sockets for that satype only */
53327 + for(pfkey_socketsp = pfkey_registered_sockets[satype];
53328 + pfkey_socketsp;
53329 + pfkey_socketsp = pfkey_socketsp->next) {
53330 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
53331 + KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
53332 + "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53333 + satype,
53334 + satype2name(satype),
53335 + pfkey_socketsp->socketp,
53336 + error);
53337 + SENDERR(-error);
53338 + }
53339 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
53340 + "sending up acquire message for satype=%d(%s) to socket=0p%p succeeded.\n",
53341 + satype,
53342 + satype2name(satype),
53343 + pfkey_socketsp->socketp);
53344 + }
53345 +
53346 + errlab:
53347 + if (pfkey_msg) {
53348 + pfkey_msg_free(&pfkey_msg);
53349 + }
53350 + pfkey_extensions_free(extensions);
53351 + return error;
53352 +}
53353 +
53354 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
53355 +int
53356 +pfkey_nat_t_new_mapping(struct ipsec_sa *ipsp, struct sockaddr *ipaddr,
53357 + __u16 sport)
53358 +{
53359 + struct sadb_ext *extensions[SADB_EXT_MAX+1];
53360 + struct sadb_msg *pfkey_msg = NULL;
53361 + struct socket_list *pfkey_socketsp;
53362 + int error = 0;
53363 + uint8_t satype = (ipsp->ips_said.proto==IPPROTO_ESP) ? SADB_SATYPE_ESP : 0;
53364 +
53365 + /* Construct SADB_X_NAT_T_NEW_MAPPING message */
53366 +
53367 + pfkey_extensions_init(extensions);
53368 +
53369 + if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
53370 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
53371 + "SAtype=%d unspecified or unknown.\n",
53372 + satype);
53373 + SENDERR(EINVAL);
53374 + }
53375 +
53376 + if(!(pfkey_registered_sockets[satype])) {
53377 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
53378 + "no sockets registered for SAtype=%d(%s).\n",
53379 + satype,
53380 + satype2name(satype));
53381 + SENDERR(EPROTONOSUPPORT);
53382 + }
53383 +
53384 + if (!(pfkey_safe_build
53385 + (error = pfkey_msg_hdr_build(&extensions[0], SADB_X_NAT_T_NEW_MAPPING,
53386 + satype, 0, ++pfkey_msg_seq, 0), extensions)
53387 + /* SA */
53388 + && pfkey_safe_build
53389 + (error = pfkey_sa_build(&extensions[SADB_EXT_SA],
53390 + SADB_EXT_SA, ipsp->ips_said.spi, 0, 0, 0, 0, 0), extensions)
53391 + /* ADDRESS_SRC = old addr */
53392 + && pfkey_safe_build
53393 + (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
53394 + SADB_EXT_ADDRESS_SRC, ipsp->ips_said.proto, 0, ipsp->ips_addr_s),
53395 + extensions)
53396 + /* NAT_T_SPORT = old port */
53397 + && pfkey_safe_build
53398 + (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_SPORT],
53399 + SADB_X_EXT_NAT_T_SPORT, ipsp->ips_natt_sport), extensions)
53400 + /* ADDRESS_DST = new addr */
53401 + && pfkey_safe_build
53402 + (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
53403 + SADB_EXT_ADDRESS_DST, ipsp->ips_said.proto, 0, ipaddr), extensions)
53404 + /* NAT_T_DPORT = new port */
53405 + && pfkey_safe_build
53406 + (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_DPORT],
53407 + SADB_X_EXT_NAT_T_DPORT, sport), extensions)
53408 + )) {
53409 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
53410 + "failed to build the nat_t_new_mapping message extensions\n");
53411 + SENDERR(-error);
53412 + }
53413 +
53414 + if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
53415 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
53416 + "failed to build the nat_t_new_mapping message\n");
53417 + SENDERR(-error);
53418 + }
53419 +
53420 + /* this should go to all registered sockets for that satype only */
53421 + for(pfkey_socketsp = pfkey_registered_sockets[satype];
53422 + pfkey_socketsp;
53423 + pfkey_socketsp = pfkey_socketsp->next) {
53424 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
53425 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
53426 + "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p failed with error=%d.\n",
53427 + satype,
53428 + satype2name(satype),
53429 + pfkey_socketsp->socketp,
53430 + error);
53431 + SENDERR(-error);
53432 + }
53433 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
53434 + "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p succeeded.\n",
53435 + satype,
53436 + satype2name(satype),
53437 + pfkey_socketsp->socketp);
53438 + }
53439 +
53440 + errlab:
53441 + if (pfkey_msg) {
53442 + pfkey_msg_free(&pfkey_msg);
53443 + }
53444 + pfkey_extensions_free(extensions);
53445 + return error;
53446 +}
53447 +
53448 +DEBUG_NO_STATIC int
53449 +pfkey_x_nat_t_new_mapping_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53450 +{
53451 + /* SADB_X_NAT_T_NEW_MAPPING not used in kernel */
53452 + return -EINVAL;
53453 +}
53454 +#endif
53455 +
53456 +DEBUG_NO_STATIC int (*ext_processors[SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) =
53457 +{
53458 + NULL, /* pfkey_msg_process, */
53459 + pfkey_sa_process,
53460 + pfkey_lifetime_process,
53461 + pfkey_lifetime_process,
53462 + pfkey_lifetime_process,
53463 + pfkey_address_process,
53464 + pfkey_address_process,
53465 + pfkey_address_process,
53466 + pfkey_key_process,
53467 + pfkey_key_process,
53468 + pfkey_ident_process,
53469 + pfkey_ident_process,
53470 + pfkey_sens_process,
53471 + pfkey_prop_process,
53472 + pfkey_supported_process,
53473 + pfkey_supported_process,
53474 + pfkey_spirange_process,
53475 + pfkey_x_kmprivate_process,
53476 + pfkey_x_satype_process,
53477 + pfkey_sa_process,
53478 + pfkey_address_process,
53479 + pfkey_address_process,
53480 + pfkey_address_process,
53481 + pfkey_address_process,
53482 + pfkey_address_process,
53483 + pfkey_x_debug_process,
53484 + pfkey_x_protocol_process
53485 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
53486 + ,
53487 + pfkey_x_nat_t_type_process,
53488 + pfkey_x_nat_t_port_process,
53489 + pfkey_x_nat_t_port_process,
53490 + pfkey_address_process
53491 +#endif
53492 +};
53493 +
53494 +
53495 +DEBUG_NO_STATIC int (*msg_parsers[SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr)
53496 + =
53497 +{
53498 + NULL, /* RESERVED */
53499 + pfkey_getspi_parse,
53500 + pfkey_update_parse,
53501 + pfkey_add_parse,
53502 + pfkey_delete_parse,
53503 + pfkey_get_parse,
53504 + pfkey_acquire_parse,
53505 + pfkey_register_parse,
53506 + pfkey_expire_parse,
53507 + pfkey_flush_parse,
53508 + pfkey_dump_parse,
53509 + pfkey_x_promisc_parse,
53510 + pfkey_x_pchange_parse,
53511 + pfkey_x_grpsa_parse,
53512 + pfkey_x_addflow_parse,
53513 + pfkey_x_delflow_parse,
53514 + pfkey_x_msg_debug_parse
53515 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
53516 + , pfkey_x_nat_t_new_mapping_parse
53517 +#endif
53518 +};
53519 +
53520 +int
53521 +pfkey_build_reply(struct sadb_msg *pfkey_msg,
53522 + struct pfkey_extracted_data *extr,
53523 + struct sadb_msg **pfkey_reply)
53524 +{
53525 + struct sadb_ext *extensions[SADB_EXT_MAX+1];
53526 + int error = 0;
53527 + int msg_type = pfkey_msg->sadb_msg_type;
53528 + int seq = pfkey_msg->sadb_msg_seq;
53529 +
53530 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
53531 + "building reply with type: %d\n",
53532 + msg_type);
53533 + pfkey_extensions_init(extensions);
53534 + if (!extr || !extr->ips) {
53535 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
53536 + "bad ipsec_sa passed\n");
53537 + return EINVAL; // TODO: should this not be negative?
53538 + }
53539 + error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0],
53540 + msg_type,
53541 + proto2satype(extr->ips->ips_said.proto),
53542 + 0,
53543 + seq,
53544 + pfkey_msg->sadb_msg_pid),
53545 + extensions) &&
53546 + (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
53547 + 1 << SADB_EXT_SA)
53548 + || pfkey_safe_build(pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
53549 + SADB_EXT_SA,
53550 + extr->ips->ips_said.spi,
53551 + extr->ips->ips_replaywin,
53552 + extr->ips->ips_state,
53553 + extr->ips->ips_authalg,
53554 + extr->ips->ips_encalg,
53555 + extr->ips->ips_flags,
53556 + extr->ips->ips_ref),
53557 + extensions)) &&
53558 + (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
53559 + 1 << SADB_EXT_LIFETIME_CURRENT)
53560 + || pfkey_safe_build(pfkey_lifetime_build(&extensions
53561 + [SADB_EXT_LIFETIME_CURRENT],
53562 + SADB_EXT_LIFETIME_CURRENT,
53563 + extr->ips->ips_life.ipl_allocations.ipl_count,
53564 + extr->ips->ips_life.ipl_bytes.ipl_count,
53565 + extr->ips->ips_life.ipl_addtime.ipl_count,
53566 + extr->ips->ips_life.ipl_usetime.ipl_count,
53567 + extr->ips->ips_life.ipl_packets.ipl_count),
53568 + extensions)) &&
53569 + (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
53570 + 1 << SADB_EXT_ADDRESS_SRC)
53571 + || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
53572 + SADB_EXT_ADDRESS_SRC,
53573 + extr->ips->ips_said.proto,
53574 + 0,
53575 + extr->ips->ips_addr_s),
53576 + extensions)) &&
53577 + (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
53578 + 1 << SADB_EXT_ADDRESS_DST)
53579 + || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
53580 + SADB_EXT_ADDRESS_DST,
53581 + extr->ips->ips_said.proto,
53582 + 0,
53583 + extr->ips->ips_addr_d),
53584 + extensions));
53585 +
53586 + if (error == 0) {
53587 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
53588 + "building extensions failed\n");
53589 + return EINVAL;
53590 + }
53591 +
53592 + KLIPS_PRINT(debug_pfkey,
53593 + "klips_debug:pfkey_build_reply: "
53594 + "built extensions, proceed to build the message\n");
53595 + KLIPS_PRINT(debug_pfkey,
53596 + "klips_debug:pfkey_build_reply: "
53597 + "extensions[1]=0p%p\n",
53598 + extensions[1]);
53599 + error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT);
53600 + pfkey_extensions_free(extensions);
53601 +
53602 + return error;
53603 +}
53604 +
53605 +int
53606 +pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg,
53607 + struct sadb_msg **pfkey_reply)
53608 +{
53609 + int error = 0;
53610 + int i;
53611 + struct sadb_ext *extensions[SADB_EXT_MAX+1];
53612 + struct pfkey_extracted_data extr = {NULL, NULL, NULL};
53613 +
53614 + pfkey_extensions_init(extensions);
53615 + KLIPS_PRINT(debug_pfkey,
53616 + "klips_debug:pfkey_msg_interp: "
53617 + "parsing message ver=%d, type=%d, errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
53618 + pfkey_msg->sadb_msg_version,
53619 + pfkey_msg->sadb_msg_type,
53620 + pfkey_msg->sadb_msg_errno,
53621 + pfkey_msg->sadb_msg_satype,
53622 + satype2name(pfkey_msg->sadb_msg_satype),
53623 + pfkey_msg->sadb_msg_len,
53624 + pfkey_msg->sadb_msg_reserved,
53625 + pfkey_msg->sadb_msg_seq,
53626 + pfkey_msg->sadb_msg_pid);
53627 +
53628 + extr.ips = ipsec_sa_alloc(&error); /* pass in error var by pointer */
53629 + if(extr.ips == NULL) {
53630 + KLIPS_PRINT(debug_pfkey,
53631 + "klips_debug:pfkey_msg_interp: "
53632 + "memory allocation error.\n");
53633 + SENDERR(-error);
53634 + }
53635 +
53636 + KLIPS_PRINT(debug_pfkey,
53637 + "klips_debug:pfkey_msg_interp: "
53638 + "allocated extr->ips=0p%p.\n",
53639 + extr.ips);
53640 +
53641 + if(pfkey_msg->sadb_msg_satype > SADB_SATYPE_MAX) {
53642 + KLIPS_PRINT(debug_pfkey,
53643 + "klips_debug:pfkey_msg_interp: "
53644 + "satype %d > max %d\n",
53645 + pfkey_msg->sadb_msg_satype,
53646 + SADB_SATYPE_MAX);
53647 + SENDERR(EINVAL);
53648 + }
53649 +
53650 + switch(pfkey_msg->sadb_msg_type) {
53651 + case SADB_GETSPI:
53652 + case SADB_UPDATE:
53653 + case SADB_ADD:
53654 + case SADB_DELETE:
53655 + case SADB_X_GRPSA:
53656 + case SADB_X_ADDFLOW:
53657 + if(!(extr.ips->ips_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) {
53658 + KLIPS_PRINT(debug_pfkey,
53659 + "klips_debug:pfkey_msg_interp: "
53660 + "satype %d lookup failed.\n",
53661 + pfkey_msg->sadb_msg_satype);
53662 + SENDERR(EINVAL);
53663 + } else {
53664 + KLIPS_PRINT(debug_pfkey,
53665 + "klips_debug:pfkey_msg_interp: "
53666 + "satype %d lookups to proto=%d.\n",
53667 + pfkey_msg->sadb_msg_satype,
53668 + extr.ips->ips_said.proto);
53669 + }
53670 + break;
53671 + default:
53672 + break;
53673 + }
53674 +
53675 + /* The NULL below causes the default extension parsers to be used */
53676 + /* Parse the extensions */
53677 + if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN)))
53678 + {
53679 + KLIPS_PRINT(debug_pfkey,
53680 + "klips_debug:pfkey_msg_interp: "
53681 + "message parsing failed with error %d.\n",
53682 + error);
53683 + SENDERR(-error);
53684 + }
53685 +
53686 + /* Process the extensions */
53687 + for(i=1; i <= SADB_EXT_MAX;i++) {
53688 + if(extensions[i] != NULL && ext_processors[i]!=NULL) {
53689 + KLIPS_PRINT(debug_pfkey,
53690 + "klips_debug:pfkey_msg_interp: "
53691 + "processing ext %d 0p%p with processor 0p%p.\n",
53692 + i, extensions[i], ext_processors[i]);
53693 + if((error = ext_processors[i](extensions[i], &extr))) {
53694 + KLIPS_PRINT(debug_pfkey,
53695 + "klips_debug:pfkey_msg_interp: "
53696 + "extension processing for type %d failed with error %d.\n",
53697 + i,
53698 + error);
53699 + SENDERR(-error);
53700 + }
53701 +
53702 + }
53703 +
53704 + }
53705 +
53706 + /* Parse the message types */
53707 + KLIPS_PRINT(debug_pfkey,
53708 + "klips_debug:pfkey_msg_interp: "
53709 + "parsing message type %d(%s) with msg_parser 0p%p.\n",
53710 + pfkey_msg->sadb_msg_type,
53711 + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
53712 + msg_parsers[pfkey_msg->sadb_msg_type]);
53713 + if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) {
53714 + KLIPS_PRINT(debug_pfkey,
53715 + "klips_debug:pfkey_msg_interp: "
53716 + "message parsing failed with error %d.\n",
53717 + error);
53718 + SENDERR(-error);
53719 + }
53720 +
53721 +#if 0
53722 + error = pfkey_build_reply(pfkey_msg, &extr, pfkey_reply);
53723 + if (error) {
53724 + *pfkey_reply = NULL;
53725 + }
53726 +#endif
53727 + errlab:
53728 + if(extr.ips != NULL) {
53729 + ipsec_sa_put(extr.ips);
53730 + }
53731 + if(extr.ips2 != NULL) {
53732 + ipsec_sa_put(extr.ips2);
53733 + }
53734 + if (extr.eroute != NULL) {
53735 + kfree(extr.eroute);
53736 + }
53737 + return(error);
53738 +}
53739 +
53740 +/*
53741 + * $Log: pfkey_v2_parser.c,v $
53742 + * Revision 1.134 2005/05/11 01:48:20 mcr
53743 + * removed "poor-man"s OOP in favour of proper C structures.
53744 + *
53745 + * Revision 1.133 2005/04/29 05:10:22 mcr
53746 + * removed from extraenous includes to make unit testing easier.
53747 + *
53748 + * Revision 1.132 2005/04/14 20:56:24 mcr
53749 + * moved (pfkey_)ipsec_sa_init to ipsec_sa.c.
53750 + *
53751 + * Revision 1.131 2005/01/26 00:50:35 mcr
53752 + * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
53753 + * and make sure that NAT_TRAVERSAL is set as well to match
53754 + * userspace compiles of code.
53755 + *
53756 + * Revision 1.130 2004/09/08 17:21:36 ken
53757 + * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
53758 + *
53759 + * Revision 1.129 2004/09/06 18:36:30 mcr
53760 + * if a protocol can not be found, then log it. This is not
53761 + * debugging.
53762 + *
53763 + * Revision 1.128 2004/08/21 00:45:19 mcr
53764 + * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
53765 + *
53766 + * Revision 1.127 2004/08/20 21:45:45 mcr
53767 + * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
53768 + * be 26sec compatible. But, some defines where changed.
53769 + *
53770 + * Revision 1.126 2004/08/17 03:27:23 mcr
53771 + * klips 2.6 edits.
53772 + *
53773 + * Revision 1.125 2004/08/04 15:57:07 mcr
53774 + * moved des .h files to include/des/ *
53775 + * included 2.6 protocol specific things
53776 + * started at NAT-T support, but it will require a kernel patch.
53777 + *
53778 + * Revision 1.124 2004/07/10 19:11:18 mcr
53779 + * CONFIG_IPSEC -> CONFIG_KLIPS.
53780 + *
53781 + * Revision 1.123 2004/04/06 02:49:26 mcr
53782 + * pullup of algo code from alg-branch.
53783 + *
53784 + * Revision 1.122.2.2 2004/04/05 04:30:46 mcr
53785 + * patches for alg-branch to compile/work with 2.x openswan
53786 + *
53787 + * Revision 1.122.2.1 2003/12/22 15:25:52 jjo
53788 + * . Merged algo-0.8.1-rc11-test1 into alg-branch
53789 + *
53790 + * Revision 1.122 2003/12/10 01:14:27 mcr
53791 + * NAT-traversal patches to KLIPS.
53792 + *
53793 + * Revision 1.121 2003/10/31 02:27:55 mcr
53794 + * pulled up port-selector patches and sa_id elimination.
53795 + *
53796 + * Revision 1.120.4.2 2003/10/29 01:30:41 mcr
53797 + * elimited "struct sa_id".
53798 + *
53799 + * Revision 1.120.4.1 2003/09/21 13:59:56 mcr
53800 + * pre-liminary X.509 patch - does not yet pass tests.
53801 + *
53802 + * Revision 1.120 2003/04/03 17:38:09 rgb
53803 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
53804 + *
53805 + * Revision 1.119 2003/02/06 01:52:37 rgb
53806 + * Removed no longer relevant comment
53807 + *
53808 + * Revision 1.118 2003/01/30 02:32:44 rgb
53809 + *
53810 + * Transmit error code through to caller from callee for better diagnosis of problems.
53811 + *
53812 + * Revision 1.117 2003/01/16 18:48:13 rgb
53813 + *
53814 + * Fixed sign bug in error return from an sa allocation call in
53815 + * pfkey_msg_interp.
53816 + *
53817 + * Revision 1.116 2002/10/17 16:38:01 rgb
53818 + * Change pfkey_alloc_eroute() to never static since its consumers
53819 + * have been moved outside the file.
53820 + *
53821 + * Revision 1.115 2002/10/12 23:11:53 dhr
53822 + *
53823 + * [KenB + DHR] more 64-bit cleanup
53824 + *
53825 + * Revision 1.114 2002/10/05 05:02:58 dhr
53826 + *
53827 + * C labels go on statements
53828 + *
53829 + * Revision 1.113 2002/09/30 19:11:22 rgb
53830 + * Turn on debugging for upgoing acquire messages to test for reliability.
53831 + *
53832 + * Revision 1.112 2002/09/20 15:41:16 rgb
53833 + * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
53834 + * Added sadb_x_sa_ref to struct sadb_sa.
53835 + * Added ref parameter to pfkey_sa_build().
53836 + *
53837 + * Revision 1.111 2002/09/20 05:02:08 rgb
53838 + * Added memory allocation debugging.
53839 + * Convert to switch to divulge hmac keys for debugging.
53840 + * Added text labels to elucidate numeric values presented.
53841 + *
53842 + * Revision 1.110 2002/08/03 18:03:05 mcr
53843 + * loop that checks for SPI's to have been already linked
53844 + * fails to actually step to next pointer, but continuously
53845 + * resets to head of list. Wrong pointer used.
53846 + * test east-icmp-02 revealed this.
53847 + *
53848 + * Revision 1.109 2002/07/26 08:48:31 rgb
53849 + * Added SA ref table code.
53850 + *
53851 + * Revision 1.108 2002/05/27 18:55:03 rgb
53852 + * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
53853 + *
53854 + * Revision 1.107 2002/05/23 07:16:08 rgb
53855 + * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
53856 + * Pointer clean-up.
53857 + * Added refcount code.
53858 + *
53859 + * Revision 1.106 2002/05/14 02:34:13 rgb
53860 + * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
53861 + * with "put" usage in the kernel.
53862 + * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
53863 + * ipsec_sa or ipsec_sa.
53864 + * Moved all the extension parsing functions to pfkey_v2_ext_process.c.
53865 + *
53866 + * Revision 1.105 2002/04/24 07:55:32 mcr
53867 + * #include patches and Makefiles for post-reorg compilation.
53868 + *
53869 + * Revision 1.104 2002/04/24 07:36:34 mcr
53870 + * Moved from ./klips/net/ipsec/pfkey_v2_parser.c,v
53871 + *
53872 + * Revision 1.103 2002/04/20 00:12:25 rgb
53873 + * Added esp IV CBC attack fix, disabled.
53874 + *
53875 + * Revision 1.102 2002/03/08 01:15:17 mcr
53876 + * put some internal structure only debug messages behind
53877 + * && sysctl_ipsec_debug_verbose.
53878 + *
53879 + * Revision 1.101 2002/01/29 17:17:57 mcr
53880 + * moved include of ipsec_param.h to after include of linux/kernel.h
53881 + * otherwise, it seems that some option that is set in ipsec_param.h
53882 + * screws up something subtle in the include path to kernel.h, and
53883 + * it complains on the snprintf() prototype.
53884 + *
53885 + * Revision 1.100 2002/01/29 04:00:54 mcr
53886 + * more excise of kversions.h header.
53887 + *
53888 + * Revision 1.99 2002/01/29 02:13:19 mcr
53889 + * introduction of ipsec_kversion.h means that include of
53890 + * ipsec_param.h must preceed any decisions about what files to
53891 + * include to deal with differences in kernel source.
53892 + *
53893 + * Revision 1.98 2002/01/12 02:57:57 mcr
53894 + * first regression test causes acquire messages to be lost
53895 + * 100% of the time. This is to help testing of pluto.
53896 + *
53897 + * Revision 1.97 2001/11/26 09:23:52 rgb
53898 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
53899 + *
53900 + * Revision 1.93.2.4 2001/10/23 04:20:27 mcr
53901 + * parity was forced on wrong structure! prototypes help here.
53902 + *
53903 + * Revision 1.93.2.3 2001/10/22 21:14:59 mcr
53904 + * include des.h, removed phony prototypes and fixed calling
53905 + * conventions to match real prototypes.
53906 + *
53907 + * Revision 1.93.2.2 2001/10/15 05:39:03 mcr
53908 + * %08lx is not the right format for u32. Use %08x. 64-bit safe? ha.
53909 + *
53910 + * Revision 1.93.2.1 2001/09/25 02:30:14 mcr
53911 + * struct tdb -> struct ipsec_sa.
53912 + * use new lifetime structure. common format routines for debug.
53913 + *
53914 + * Revision 1.96 2001/11/06 20:47:54 rgb
53915 + * Fixed user context call to ipsec_dev_start_xmit() bug. Call
53916 + * dev_queue_xmit() instead.
53917 + *
53918 + * Revision 1.95 2001/11/06 19:47:46 rgb
53919 + * Added packet parameter to lifetime and comb structures.
53920 + *
53921 + * Revision 1.94 2001/10/18 04:45:23 rgb
53922 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
53923 + * lib/freeswan.h version macros moved to lib/kversions.h.
53924 + * Other compiler directive cleanups.
53925 + *
53926 + * Revision 1.93 2001/09/20 15:32:59 rgb
53927 + * Min/max cleanup.
53928 + *
53929 + * Revision 1.92 2001/09/19 16:35:48 rgb
53930 + * PF_KEY ident fix for getspi from NetCelo (puttdb duplication).
53931 + *
53932 + * Revision 1.91 2001/09/15 16:24:06 rgb
53933 + * Re-inject first and last HOLD packet when an eroute REPLACE is done.
53934 + *
53935 + * Revision 1.90 2001/09/14 16:58:38 rgb
53936 + * Added support for storing the first and last packets through a HOLD.
53937 + *
53938 + * Revision 1.89 2001/09/08 21:14:07 rgb
53939 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
53940 + * Better state coherency (error management) between pf_key and IKE daemon.
53941 + * (NetCelo)
53942 + *
53943 + * Revision 1.88 2001/08/27 19:42:44 rgb
53944 + * Fix memory leak of encrypt and auth structs in pfkey register.
53945 + *
53946 + * Revision 1.87 2001/07/06 19:50:46 rgb
53947 + * Removed unused debugging code.
53948 + * Added inbound policy checking code for IPIP SAs.
53949 + *
53950 + * Revision 1.86 2001/06/20 06:26:04 rgb
53951 + * Changed missing SA errors from EEXIST to ENOENT and added debug output
53952 + * for already linked SAs.
53953 + *
53954 + * Revision 1.85 2001/06/15 04:57:02 rgb
53955 + * Remove single error return condition check and check for all errors in
53956 + * the case of a replace eroute delete operation. This means that
53957 + * applications must expect to be deleting something before replacing it
53958 + * and if nothing is found, complain.
53959 + *
53960 + * Revision 1.84 2001/06/14 19:35:12 rgb
53961 + * Update copyright date.
53962 + *
53963 + * Revision 1.83 2001/06/12 00:03:19 rgb
53964 + * Silence debug set/unset under normal conditions.
53965 + *
53966 + * Revision 1.82 2001/05/30 08:14:04 rgb
53967 + * Removed vestiges of esp-null transforms.
53968 + *
53969 + * Revision 1.81 2001/05/27 06:12:12 rgb
53970 + * Added structures for pid, packet count and last access time to eroute.
53971 + * Added packet count to beginning of /proc/net/ipsec_eroute.
53972 + *
53973 + * Revision 1.80 2001/05/03 19:43:59 rgb
53974 + * Check error return codes for all build function calls.
53975 + * Standardise on SENDERR() macro.
53976 + *
53977 + * Revision 1.79 2001/04/20 21:09:16 rgb
53978 + * Cleaned up fixed tdbwipes.
53979 + * Free pfkey_reply and clean up extensions_reply for grpsa, addflow and
53980 + * delflow (Per Cederqvist) plugging memleaks.
53981 + *
53982 + * Revision 1.78 2001/04/19 19:02:39 rgb
53983 + * Fixed extr.tdb freeing, stealing it for getspi, update and add.
53984 + * Refined a couple of spinlocks, fixed the one in update.
53985 + *
53986 + * Revision 1.77 2001/04/18 20:26:16 rgb
53987 + * Wipe/free eroute and both tdbs from extr at end of pfkey_msg_interp()
53988 + * instead of inside each message type parser. This fixes two memleaks.
53989 + *
53990 + * Revision 1.76 2001/04/17 23:51:18 rgb
53991 + * Quiet down pfkey_x_debug_process().
53992 + *
53993 + * Revision 1.75 2001/03/29 01:55:05 rgb
53994 + * Fixed pfkey key init memleak.
53995 + * Fixed pfkey encryption key debug output.
53996 + *
53997 + * Revision 1.74 2001/03/27 05:29:14 rgb
53998 + * Debug output cleanup/silencing.
53999 + *
54000 + * Revision 1.73 2001/02/28 05:03:28 rgb
54001 + * Clean up and rationalise startup messages.
54002 + *
54003 + * Revision 1.72 2001/02/27 22:24:56 rgb
54004 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
54005 + * Check for satoa() return codes.
54006 + *
54007 + * Revision 1.71 2001/02/27 06:59:30 rgb
54008 + * Added satype2name() conversions most places satype is debug printed.
54009 + *
54010 + * Revision 1.70 2001/02/26 22:37:08 rgb
54011 + * Fixed 'unknown proto' INT bug in new code.
54012 + * Added satype to protocol debugging instrumentation.
54013 + *
54014 + * Revision 1.69 2001/02/26 19:57:51 rgb
54015 + * Re-formatted debug output (split lines, consistent spacing).
54016 + * Fixed as yet undetected FLUSH bug which called ipsec_tdbcleanup()
54017 + * with an satype instead of proto.
54018 + * Checked for satype consistency and fixed minor bugs.
54019 + * Fixed undetected ungrpspi bug that tried to upmsg a second tdb.
54020 + * Check for satype sanity in pfkey_expire().
54021 + * Added satype sanity check to addflow.
54022 + *
54023 + * Revision 1.68 2001/02/12 23:14:40 rgb
54024 + * Remove double spin lock in pfkey_expire().
54025 + *
54026 + * Revision 1.67 2001/01/31 19:23:40 rgb
54027 + * Fixed double-unlock bug introduced by grpsa upmsg (found by Lars Heete).
54028 + *
54029 + * Revision 1.66 2001/01/29 22:20:04 rgb
54030 + * Fix minor add upmsg lifetime bug.
54031 + *
54032 + * Revision 1.65 2001/01/24 06:12:33 rgb
54033 + * Fixed address extension compile bugs just introduced.
54034 + *
54035 + * Revision 1.64 2001/01/24 00:31:15 rgb
54036 + * Added upmsg for addflow/delflow.
54037 + *
54038 + * Revision 1.63 2001/01/23 22:02:55 rgb
54039 + * Added upmsg to x_grpsa.
54040 + * Fixed lifetimes extentions to add/update/get upmsg.
54041 + *
54042 + * Revision 1.62 2000/11/30 21:47:51 rgb
54043 + * Fix error return bug after returning from pfkey_tdb_init().
54044 + *
54045 + * Revision 1.61 2000/11/17 18:10:29 rgb
54046 + * Fixed bugs mostly relating to spirange, to treat all spi variables as
54047 + * network byte order since this is the way PF_KEYv2 stored spis.
54048 + *
54049 + * Revision 1.60 2000/11/06 04:34:53 rgb
54050 + * Changed non-exported functions to DEBUG_NO_STATIC.
54051 + * Add Svenning's adaptive content compression.
54052 + * Ditched spin_lock_irqsave in favour of spin_lock/_bh.
54053 + * Fixed double unlock bug (Svenning).
54054 + * Fixed pfkey_msg uninitialized bug in pfkey_{expire,acquire}().
54055 + * Fixed incorrect extension type (prop) in pfkey)acquire().
54056 + *
54057 + * Revision 1.59 2000/10/11 15:25:12 rgb
54058 + * Fixed IPCOMP disabled compile bug.
54059 + *
54060 + * Revision 1.58 2000/10/11 14:54:03 rgb
54061 + * Fixed pfkey_acquire() satype to SADB_SATYPE_ESP and removed pfkey
54062 + * protocol violations of setting pfkey_address_build() protocol parameter
54063 + * to non-zero except in the case of pfkey_acquire().
54064 + *
54065 + * Revision 1.57 2000/10/10 20:10:18 rgb
54066 + * Added support for debug_ipcomp and debug_verbose to klipsdebug.
54067 + *
54068 + * Revision 1.56 2000/10/06 20:24:36 rgb
54069 + * Fixes to pfkey_acquire to initialize extensions[] and use correct
54070 + * ipproto.
54071 + *
54072 + * Revision 1.55 2000/10/03 03:20:57 rgb
54073 + * Added brackets to get a?b:c scope right for pfkey_register reply.
54074 + *
54075 + * Revision 1.54 2000/09/29 19:49:30 rgb
54076 + * As-yet-unused-bits cleanup.
54077 + *
54078 + * Revision 1.53 2000/09/28 00:35:45 rgb
54079 + * Padded SATYPE printout in pfkey_register for vertical alignment.
54080 + *
54081 + * Revision 1.52 2000/09/20 16:21:58 rgb
54082 + * Cleaned up ident string alloc/free.
54083 + *
54084 + * Revision 1.51 2000/09/20 04:04:20 rgb
54085 + * Changed static functions to DEBUG_NO_STATIC to reveal function names in
54086 + * oopsen.
54087 + *
54088 + * Revision 1.50 2000/09/16 01:10:53 rgb
54089 + * Fixed unused var warning with debug off.
54090 + *
54091 + * Revision 1.49 2000/09/15 11:37:02 rgb
54092 + * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
54093 + * IPCOMP zlib deflate code.
54094 + *
54095 + * Revision 1.48 2000/09/15 04:57:57 rgb
54096 + * Cleaned up existing IPCOMP code before svenning addition.
54097 + * Initialize pfkey_reply and extensions_reply in case of early error in
54098 + * message parsing functions (thanks Kai!).
54099 + *
54100 + * Revision 1.47 2000/09/13 08:02:56 rgb
54101 + * Added KMd registration notification.
54102 + *
54103 + * Revision 1.46 2000/09/12 22:35:36 rgb
54104 + * Restructured to remove unused extensions from CLEARFLOW messages.
54105 + *
54106 + * Revision 1.45 2000/09/12 03:24:23 rgb
54107 + * Converted #if0 debugs to sysctl.
54108 + *
54109 + * Revision 1.44 2000/09/09 06:38:39 rgb
54110 + * Correct SADB message type for update, add and delete.
54111 + *
54112 + * Revision 1.43 2000/09/08 19:19:56 rgb
54113 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
54114 + * Removed all references to CONFIG_IPSEC_PFKEYv2.
54115 + * Put in sanity checks in most msg type parsers to catch invalid satypes
54116 + * and empty socket lists.
54117 + * Moved spin-locks in pfkey_get_parse() to simplify.
54118 + * Added pfkey_acquire().
54119 + * Added upwards messages to update, add, delete, acquire_parse,
54120 + * expire_parse and flush.
54121 + * Fix pfkey_prop_build() parameter to be only single indirection.
54122 + * Changed all replies to use pfkey_reply.
54123 + * Check return code on puttdb() and deltdbchain() in getspi, update,
54124 + * add, delete.
54125 + * Fixed up all pfkey replies to open and registered sockets.
54126 + *
54127 + * Revision 1.42 2000/09/01 18:50:26 rgb
54128 + * Added a supported algorithms array lists, one per satype and registered
54129 + * existing algorithms.
54130 + * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
54131 + * list.
54132 + * Only send pfkey_expire() messages to sockets registered for that satype.
54133 + * Added reply to pfkey_getspi_parse().
54134 + * Added reply to pfkey_get_parse().
54135 + * Fixed debug output label bug in pfkey_lifetime_process().
54136 + * Cleaned up pfkey_sa_process a little.
54137 + * Moved pfkey_safe_build() above message type parsers to make it available
54138 + * for creating replies.
54139 + * Added comments for future work in pfkey_acquire_parse().
54140 + * Fleshed out guts of pfkey_register_parse().
54141 + *
54142 + * Revision 1.41 2000/08/24 16:58:11 rgb
54143 + * Fixed key debugging variables.
54144 + * Fixed error return code for a failed search.
54145 + * Changed order of pfkey_get operations.
54146 + *
54147 + * Revision 1.40 2000/08/21 16:32:27 rgb
54148 + * Re-formatted for cosmetic consistency and readability.
54149 + *
54150 + * Revision 1.39 2000/08/20 21:38:57 rgb
54151 + * Bugfixes to as-yet-unused pfkey_update_parse() and
54152 + * pfkey_register_parse(). (Momchil)
54153 + * Added functions pfkey_safe_build(), pfkey_expire() and
54154 + * pfkey_build_reply(). (Momchil)
54155 + * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
54156 + *
54157 + * Revision 1.38 2000/08/18 21:30:41 rgb
54158 + * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
54159 + *
54160 + * Revision 1.37 2000/08/18 18:18:02 rgb
54161 + * Cosmetic and descriptive changes made to debug test.
54162 + * getspi and update fixes from Momchil.
54163 + *
54164 + * Revision 1.36 2000/08/15 15:41:55 rgb
54165 + * Fixed the (as yet unused and untested) pfkey_getspi() routine.
54166 + *
54167 + * Revision 1.35 2000/08/01 14:51:52 rgb
54168 + * Removed _all_ remaining traces of DES.
54169 + *
54170 + * Revision 1.34 2000/07/28 14:58:32 rgb
54171 + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
54172 + *
54173 + * Revision 1.33 2000/06/28 05:50:11 rgb
54174 + * Actually set iv_bits.
54175 + *
54176 + * Revision 1.32 2000/05/30 18:36:56 rgb
54177 + * Fix AH auth hash setup bug. This breaks interop with previous PF_KEY
54178 + * FreeS/WAN, but fixes interop with other implementations.
54179 + *
54180 + * Revision 1.31 2000/03/16 14:05:48 rgb
54181 + * Fixed brace scope preventing non-debug compile.
54182 + * Added null parameter check for pfkey_x_debug().
54183 + *
54184 + * Revision 1.30 2000/01/22 23:21:13 rgb
54185 + * Use new function satype2proto().
54186 + *
54187 + * Revision 1.29 2000/01/22 08:40:21 rgb
54188 + * Invert condition to known value to avoid AF_INET6 in 2.0.36.
54189 + *
54190 + * Revision 1.28 2000/01/22 07:58:57 rgb
54191 + * Fixed REPLACEFLOW bug, missing braces around KLIPS_PRINT *and* SENDERR.
54192 + *
54193 + * Revision 1.27 2000/01/22 03:48:01 rgb
54194 + * Added extr pointer component debugging.
54195 + *
54196 + * Revision 1.26 2000/01/21 09:41:25 rgb
54197 + * Changed a (void*) to (char*) cast to do proper pointer math.
54198 + * Don't call tdbwipe if tdb2 is NULL.
54199 + *
54200 + * Revision 1.25 2000/01/21 06:21:01 rgb
54201 + * Added address cases for eroute flows.
54202 + * Tidied up compiler directive indentation for readability.
54203 + * Added ictx,octx vars for simplification.
54204 + * Added macros for HMAC padding magic numbers.
54205 + * Converted from double tdb arguments to one structure (extr)
54206 + * containing pointers to all temporary information structures
54207 + * and checking for valid arguments to all ext processors and
54208 + * msg type parsers.
54209 + * Added spiungrp'ing.
54210 + * Added klipsdebug switching capability.
54211 + * Removed sa_process() check for zero protocol.
54212 + * Added address case for DST2 for grouping.
54213 + * Added/changed minor debugging instrumentation.
54214 + * Fixed spigrp for single said, ungrouping case.
54215 + * Added code to parse addflow and delflow messages.
54216 + * Removed redundant statements duplicating tdbwipe() functionality
54217 + * and causing double kfrees.
54218 + * Permit addflow to have a protocol of 0.
54219 + *
54220 + * Revision 1.24 1999/12/09 23:23:00 rgb
54221 + * Added check to pfkey_sa_process() to do eroutes.
54222 + * Converted to DIVUP() macro.
54223 + * Converted if() to switch() in pfkey_register_parse().
54224 + * Use new pfkey_extensions_init() instead of memset().
54225 + *
54226 + * Revision 1.23 1999/12/01 22:18:13 rgb
54227 + * Preset minspi and maxspi values in case and spirange extension is not
54228 + * included and check for the presence of an spirange extension before
54229 + * using it. Initialise tdb_sastate to LARVAL.
54230 + * Fixed debugging output typo.
54231 + * Fixed authentication context initialisation bugs (4 places).
54232 + *
54233 + * Revision 1.22 1999/11/27 11:53:08 rgb
54234 + * Moved pfkey_msg_parse prototype to pfkey.h
54235 + * Moved exts_permitted/required prototype to pfkey.h.
54236 + * Moved sadb_satype2proto protocol lookup table to lib/pfkey_v2_parse.c.
54237 + * Deleted SADB_X_EXT_SA2 code from pfkey_sa_process() since it will never
54238 + * be called.
54239 + * Moved protocol/algorithm checks to lib/pfkey_v2_parse.c
54240 + * Debugging error messages added.
54241 + * Enable lifetime_current checking.
54242 + * Remove illegal requirement for SA extension to be present in an
54243 + * originating GETSPI call.
54244 + * Re-instate requirement for UPDATE or ADD message to be MATURE.
54245 + * Add argument to pfkey_msg_parse() for direction.
54246 + * Fixed IPIP dst address bug and purged redundant, leaky code.
54247 + *
54248 + * Revision 1.21 1999/11/24 05:24:20 rgb
54249 + * hanged 'void*extensions' to 'struct sadb_ext*extensions'.
54250 + * Fixed indention.
54251 + * Ditched redundant replay check.
54252 + * Fixed debug message text from 'parse' to 'process'.
54253 + * Added more debug output.
54254 + * Forgot to zero extensions array causing bug, fixed.
54255 + *
54256 + * Revision 1.20 1999/11/23 23:08:13 rgb
54257 + * Move all common parsing code to lib/pfkey_v2_parse.c and rename
54258 + * remaining bits to *_process. (PJO)
54259 + * Add macros for dealing with alignment and rounding up more opaquely.
54260 + * Use provided macro ADDRTOA_BUF instead of hardcoded value.
54261 + * Sort out pfkey and freeswan headers, putting them in a library path.
54262 + * Corrected a couple of bugs in as-yet-inactive code.
54263 + *
54264 + * Revision 1.19 1999/11/20 22:01:10 rgb
54265 + * Add more descriptive error messages for non-zero reserved fields.
54266 + * Add more descriptive error message for spirange parsing.
54267 + * Start on supported extension parsing.
54268 + * Start on register and get message parsing.
54269 + *
54270 + * Revision 1.18 1999/11/18 04:09:20 rgb
54271 + * Replaced all kernel version macros to shorter, readable form.
54272 + *
54273 + * Revision 1.17 1999/11/17 15:53:41 rgb
54274 + * Changed all occurrences of #include "../../../lib/freeswan.h"
54275 + * to #include <freeswan.h> which works due to -Ilibfreeswan in the
54276 + * klips/net/ipsec/Makefile.
54277 + *
54278 + * Revision 1.16 1999/10/26 16:57:43 rgb
54279 + * Add shorter macros for compiler directives to visually clean-up.
54280 + * Give ipv6 code meaningful compiler directive.
54281 + * Add comments to other #if 0 debug code.
54282 + * Remove unused *_bh_atomic() calls.
54283 + * Fix mis-placed spinlock.
54284 + *
54285 + * Revision 1.15 1999/10/16 18:27:10 rgb
54286 + * Clean-up unused cruft.
54287 + * Fix-up lifetime_allocations_c and lifetime_addtime_c initialisations.
54288 + *
54289 + * Revision 1.14 1999/10/08 18:37:34 rgb
54290 + * Fix end-of-line spacing to sate whining PHMs.
54291 + *
54292 + * Revision 1.13 1999/10/03 18:49:12 rgb
54293 + * Spinlock fixes for 2.0.xx and 2.3.xx.
54294 + *
54295 + * Revision 1.12 1999/10/01 15:44:54 rgb
54296 + * Move spinlock header include to 2.1> scope.
54297 + *
54298 + * Revision 1.11 1999/10/01 00:05:45 rgb
54299 + * Added tdb structure locking.
54300 + * Use 'jiffies' instead of do_get_timeofday().
54301 + * Fix lifetime assignments.
54302 + *
54303 + * Revision 1.10 1999/09/21 15:24:45 rgb
54304 + * Rework spirange code to save entropy and prevent endless loops.
54305 + *
54306 + * Revision 1.9 1999/09/16 12:10:21 rgb
54307 + * Minor fixes to random spi selection for correctness and entropy conservation.
54308 + *
54309 + * Revision 1.8 1999/05/25 22:54:46 rgb
54310 + * Fix comparison that should be an assignment in an if.
54311 + *
54312 + * Revision 1.7 1999/05/09 03:25:37 rgb
54313 + * Fix bug introduced by 2.2 quick-and-dirty patch.
54314 + *
54315 + * Revision 1.6 1999/05/08 21:32:30 rgb
54316 + * Fix error return reporting.
54317 + *
54318 + * Revision 1.5 1999/05/05 22:02:33 rgb
54319 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
54320 + *
54321 + * Revision 1.4 1999/04/29 15:22:40 rgb
54322 + * Standardise an error return method.
54323 + * Add debugging instrumentation.
54324 + * Add check for existence of macros min/max.
54325 + * Add extensions permitted/required in/out filters.
54326 + * Add satype-to-protocol table.
54327 + * Add a second tdb pointer to each parser to accomodate GRPSA.
54328 + * Move AH & no_algo_set to GETSPI, UPDATE and ADD.
54329 + * Add OOO window check.
54330 + * Add support for IPPROTO_IPIP and hooks for IPPROTO_COMP.
54331 + * Add timestamp to lifetime parse.
54332 + * Fix address structure length checking bug.
54333 + * Fix address structure allocation bug (forgot to kmalloc!).
54334 + * Add checks for extension lengths.
54335 + * Add checks for extension reserved illegal values.
54336 + * Add check for spirange legal values.
54337 + * Add an extension type for parsing a second satype, SA and
54338 + * DST_ADDRESS.
54339 + * Make changes to tdb_init() template to get pfkey_tdb_init(),
54340 + * eliminating any mention of xformsw.
54341 + * Implement getspi, update and grpsa (not tested).
54342 + * Add stubs for as yet unimplemented message types.
54343 + * Add table of message parsers to substitute for msg_parse switch.
54344 + *
54345 + * Revision 1.3 1999/04/15 17:58:07 rgb
54346 + * Add RCSID labels.
54347 + *
54348 + * Revision 1.2 1999/04/15 15:37:26 rgb
54349 + * Forward check changes from POST1_00 branch.
54350 + *
54351 + * Revision 1.1.2.1 1999/03/26 20:58:56 rgb
54352 + * Add pfkeyv2 support to KLIPS.
54353 + *
54354 + * Local variables:
54355 + * c-file-style: "linux"
54356 + * End:
54357 + *
54358 + */
54359 --- /dev/null Tue Mar 11 13:02:56 2003
54360 +++ linux/net/ipsec/prng.c Mon Feb 9 13:51:03 2004
54361 @@ -0,0 +1,202 @@
54362 +/*
54363 + * crypto-class pseudorandom number generator
54364 + * currently uses same algorithm as RC4(TM), from Schneier 2nd ed p397
54365 + * Copyright (C) 2002 Henry Spencer.
54366 + *
54367 + * This library is free software; you can redistribute it and/or modify it
54368 + * under the terms of the GNU Library General Public License as published by
54369 + * the Free Software Foundation; either version 2 of the License, or (at your
54370 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
54371 + *
54372 + * This library is distributed in the hope that it will be useful, but
54373 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
54374 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
54375 + * License for more details.
54376 + *
54377 + * RCSID $Id: prng.c,v 1.8 2005/08/25 01:20:21 paul Exp $
54378 + */
54379 +#include "openswan.h"
54380 +
54381 +/*
54382 + - prng_init - initialize PRNG from a key
54383 + */
54384 +void
54385 +prng_init(prng, key, keylen)
54386 +struct prng *prng;
54387 +const unsigned char *key;
54388 +size_t keylen;
54389 +{
54390 + unsigned char k[256];
54391 + int i, j;
54392 + unsigned const char *p;
54393 + unsigned const char *keyend = key + keylen;
54394 + unsigned char t;
54395 +
54396 + for (i = 0; i <= 255; i++)
54397 + prng->sbox[i] = i;
54398 + p = key;
54399 + for (i = 0; i <= 255; i++) {
54400 + k[i] = *p++;
54401 + if (p >= keyend)
54402 + p = key;
54403 + }
54404 + j = 0;
54405 + for (i = 0; i <= 255; i++) {
54406 + j = (j + prng->sbox[i] + k[i]) & 0xff;
54407 + t = prng->sbox[i];
54408 + prng->sbox[i] = prng->sbox[j];
54409 + prng->sbox[j] = t;
54410 + k[i] = 0; /* clear out key memory */
54411 + }
54412 + prng->i = 0;
54413 + prng->j = 0;
54414 + prng->count = 0;
54415 +}
54416 +
54417 +/*
54418 + - prng_bytes - get some pseudorandom bytes from PRNG
54419 + */
54420 +void
54421 +prng_bytes(prng, dst, dstlen)
54422 +struct prng *prng;
54423 +unsigned char *dst;
54424 +size_t dstlen;
54425 +{
54426 + int i, j, t;
54427 + unsigned char *p = dst;
54428 + size_t remain = dstlen;
54429 +# define MAXCOUNT 4000000000ul
54430 +
54431 + while (remain > 0) {
54432 + i = (prng->i + 1) & 0xff;
54433 + prng->i = i;
54434 + j = (prng->j + prng->sbox[i]) & 0xff;
54435 + prng->j = j;
54436 + t = prng->sbox[i];
54437 + prng->sbox[i] = prng->sbox[j];
54438 + prng->sbox[j] = t;
54439 + t = (t + prng->sbox[i]) & 0xff;
54440 + *p++ = prng->sbox[t];
54441 + remain--;
54442 + }
54443 + if (prng->count < MAXCOUNT - dstlen)
54444 + prng->count += dstlen;
54445 + else
54446 + prng->count = MAXCOUNT;
54447 +}
54448 +
54449 +/*
54450 + - prnt_count - how many bytes have been extracted from PRNG so far?
54451 + */
54452 +unsigned long
54453 +prng_count(prng)
54454 +struct prng *prng;
54455 +{
54456 + return prng->count;
54457 +}
54458 +
54459 +/*
54460 + - prng_final - clear out PRNG to ensure nothing left in memory
54461 + */
54462 +void
54463 +prng_final(prng)
54464 +struct prng *prng;
54465 +{
54466 + int i;
54467 +
54468 + for (i = 0; i <= 255; i++)
54469 + prng->sbox[i] = 0;
54470 + prng->i = 0;
54471 + prng->j = 0;
54472 + prng->count = 0; /* just for good measure */
54473 +}
54474 +
54475 +
54476 +
54477 +#ifdef PRNG_MAIN
54478 +
54479 +#include <stdio.h>
54480 +#include <stdlib.h>
54481 +
54482 +void regress();
54483 +
54484 +int
54485 +main(argc, argv)
54486 +int argc;
54487 +char *argv[];
54488 +{
54489 + struct prng pr;
54490 + unsigned char buf[100];
54491 + unsigned char *p;
54492 + size_t n;
54493 +
54494 + if (argc < 2) {
54495 + fprintf(stderr, "Usage: %s {key|-r}\n", argv[0]);
54496 + exit(2);
54497 + }
54498 +
54499 + if (strcmp(argv[1], "-r") == 0) {
54500 + regress();
54501 + fprintf(stderr, "regress() returned?!?\n");
54502 + exit(1);
54503 + }
54504 +
54505 + prng_init(&pr, argv[1], strlen(argv[1]));
54506 + prng_bytes(&pr, buf, 32);
54507 + printf("0x");
54508 + for (p = buf, n = 32; n > 0; p++, n--)
54509 + printf("%02x", *p);
54510 + printf("\n%lu bytes\n", prng_count(&pr));
54511 + prng_final(&pr);
54512 + exit(0);
54513 +}
54514 +
54515 +void
54516 +regress()
54517 +{
54518 + struct prng pr;
54519 + unsigned char buf[100];
54520 + unsigned char *p;
54521 + size_t n;
54522 + /* somewhat non-random sample key */
54523 + unsigned char key[] = "here we go gathering nuts in May";
54524 + /* first thirty bytes of output from that key */
54525 + unsigned char good[] = "\x3f\x02\x8e\x4a\x2a\xea\x23\x18\x92\x7c"
54526 + "\x09\x52\x83\x61\xaa\x26\xce\xbb\x9d\x71"
54527 + "\x71\xe5\x10\x22\xaf\x60\x54\x8d\x5b\x28";
54528 + int nzero, none;
54529 + int show = 0;
54530 +
54531 + prng_init(&pr, key, strlen(key));
54532 + prng_bytes(&pr, buf, sizeof(buf));
54533 + for (p = buf, n = sizeof(buf); n > 0; p++, n--) {
54534 + if (*p == 0)
54535 + nzero++;
54536 + if (*p == 255)
54537 + none++;
54538 + }
54539 + if (nzero > 3 || none > 3) {
54540 + fprintf(stderr, "suspiciously non-random output!\n");
54541 + show = 1;
54542 + }
54543 + if (memcmp(buf, good, strlen(good)) != 0) {
54544 + fprintf(stderr, "incorrect output!\n");
54545 + show = 1;
54546 + }
54547 + if (show) {
54548 + fprintf(stderr, "0x");
54549 + for (p = buf, n = sizeof(buf); n > 0; p++, n--)
54550 + fprintf(stderr, "%02x", *p);
54551 + fprintf(stderr, "\n");
54552 + exit(1);
54553 + }
54554 + if (prng_count(&pr) != sizeof(buf)) {
54555 + fprintf(stderr, "got %u bytes, but count is %lu\n",
54556 + sizeof(buf), prng_count(&pr));
54557 + exit(1);
54558 + }
54559 + prng_final(&pr);
54560 + exit(0);
54561 +}
54562 +
54563 +#endif /* PRNG_MAIN */
54564 --- /dev/null Tue Mar 11 13:02:56 2003
54565 +++ linux/net/ipsec/radij.c Mon Feb 9 13:51:03 2004
54566 @@ -0,0 +1,1232 @@
54567 +char radij_c_version[] = "RCSID $Id: radij.c,v 1.48 2005/04/29 05:10:22 mcr Exp $";
54568 +
54569 +/*
54570 + * This file is defived from ${SRC}/sys/net/radix.c of BSD 4.4lite
54571 + *
54572 + * Variable and procedure names have been modified so that they don't
54573 + * conflict with the original BSD code, as a small number of modifications
54574 + * have been introduced and we may want to reuse this code in BSD.
54575 + *
54576 + * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
54577 + * chi or a German ch sound (as `doch', not as in `milch'), or even a
54578 + * spanish j as in Juan. It is not as far back in the throat like
54579 + * the corresponding Hebrew sound, nor is it a soft breath like the English h.
54580 + * It has nothing to do with the Dutch ij sound.
54581 + *
54582 + * Here is the appropriate copyright notice:
54583 + */
54584 +
54585 +/*
54586 + * Copyright (c) 1988, 1989, 1993
54587 + * The Regents of the University of California. All rights reserved.
54588 + *
54589 + * Redistribution and use in source and binary forms, with or without
54590 + * modification, are permitted provided that the following conditions
54591 + * are met:
54592 + * 1. Redistributions of source code must retain the above copyright
54593 + * notice, this list of conditions and the following disclaimer.
54594 + * 2. Redistributions in binary form must reproduce the above copyright
54595 + * notice, this list of conditions and the following disclaimer in the
54596 + * documentation and/or other materials provided with the distribution.
54597 + * 3. All advertising materials mentioning features or use of this software
54598 + * must display the following acknowledgement:
54599 + * This product includes software developed by the University of
54600 + * California, Berkeley and its contributors.
54601 + * 4. Neither the name of the University nor the names of its contributors
54602 + * may be used to endorse or promote products derived from this software
54603 + * without specific prior written permission.
54604 + *
54605 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54606 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54607 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54608 + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
54609 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54610 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54611 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54612 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54613 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54614 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54615 + * SUCH DAMAGE.
54616 + *
54617 + * @(#)radix.c 8.2 (Berkeley) 1/4/94
54618 + */
54619 +
54620 +/*
54621 + * Routines to build and maintain radix trees for routing lookups.
54622 + */
54623 +
54624 +#ifndef AUTOCONF_INCLUDED
54625 +#include <linux/config.h>
54626 +#endif
54627 +#include <linux/version.h>
54628 +#include <linux/kernel.h> /* printk() */
54629 +
54630 +#include "openswan/ipsec_param.h"
54631 +
54632 +#ifdef MALLOC_SLAB
54633 +# include <linux/slab.h> /* kmalloc() */
54634 +#else /* MALLOC_SLAB */
54635 +# include <linux/malloc.h> /* kmalloc() */
54636 +#endif /* MALLOC_SLAB */
54637 +#include <linux/errno.h> /* error codes */
54638 +#include <linux/types.h> /* size_t */
54639 +#include <linux/interrupt.h> /* mark_bh */
54640 +
54641 +#include <linux/netdevice.h> /* struct device, and other headers */
54642 +#include <linux/etherdevice.h> /* eth_type_trans */
54643 +#include <linux/ip.h> /* struct iphdr */
54644 +#include <linux/skbuff.h>
54645 +#ifdef NET_21
54646 +# include <linux/in6.h>
54647 +#endif /* NET_21 */
54648 +
54649 +#include <net/ip.h>
54650 +
54651 +#include <openswan.h>
54652 +
54653 +#include "openswan/radij.h"
54654 +#include "openswan/ipsec_encap.h"
54655 +#include "openswan/ipsec_radij.h"
54656 +
54657 +int maj_keylen;
54658 +struct radij_mask *rj_mkfreelist;
54659 +struct radij_node_head *mask_rjhead;
54660 +static int gotOddMasks;
54661 +static char *maskedKey;
54662 +static char *rj_zeroes, *rj_ones;
54663 +
54664 +#define rj_masktop (mask_rjhead->rnh_treetop)
54665 +#ifdef Bcmp
54666 +# undef Bcmp
54667 +#endif /* Bcmp */
54668 +#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l))
54669 +/*
54670 + * The data structure for the keys is a radix tree with one way
54671 + * branching removed. The index rj_b at an internal node n represents a bit
54672 + * position to be tested. The tree is arranged so that all descendants
54673 + * of a node n have keys whose bits all agree up to position rj_b - 1.
54674 + * (We say the index of n is rj_b.)
54675 + *
54676 + * There is at least one descendant which has a one bit at position rj_b,
54677 + * and at least one with a zero there.
54678 + *
54679 + * A route is determined by a pair of key and mask. We require that the
54680 + * bit-wise logical and of the key and mask to be the key.
54681 + * We define the index of a route to associated with the mask to be
54682 + * the first bit number in the mask where 0 occurs (with bit number 0
54683 + * representing the highest order bit).
54684 + *
54685 + * We say a mask is normal if every bit is 0, past the index of the mask.
54686 + * If a node n has a descendant (k, m) with index(m) == index(n) == rj_b,
54687 + * and m is a normal mask, then the route applies to every descendant of n.
54688 + * If the index(m) < rj_b, this implies the trailing last few bits of k
54689 + * before bit b are all 0, (and hence consequently true of every descendant
54690 + * of n), so the route applies to all descendants of the node as well.
54691 + *
54692 + * The present version of the code makes no use of normal routes,
54693 + * but similar logic shows that a non-normal mask m such that
54694 + * index(m) <= index(n) could potentially apply to many children of n.
54695 + * Thus, for each non-host route, we attach its mask to a list at an internal
54696 + * node as high in the tree as we can go.
54697 + */
54698 +
54699 +struct radij_node *
54700 +rj_search(v_arg, head)
54701 + void *v_arg;
54702 + struct radij_node *head;
54703 +{
54704 + register struct radij_node *x;
54705 + register caddr_t v;
54706 +
54707 + for (x = head, v = v_arg; x->rj_b >= 0;) {
54708 + if (x->rj_bmask & v[x->rj_off])
54709 + x = x->rj_r;
54710 + else
54711 + x = x->rj_l;
54712 + }
54713 + return (x);
54714 +};
54715 +
54716 +struct radij_node *
54717 +rj_search_m(v_arg, head, m_arg)
54718 + struct radij_node *head;
54719 + void *v_arg, *m_arg;
54720 +{
54721 + register struct radij_node *x;
54722 + register caddr_t v = v_arg, m = m_arg;
54723 +
54724 + for (x = head; x->rj_b >= 0;) {
54725 + if ((x->rj_bmask & m[x->rj_off]) &&
54726 + (x->rj_bmask & v[x->rj_off]))
54727 + x = x->rj_r;
54728 + else
54729 + x = x->rj_l;
54730 + }
54731 + return x;
54732 +};
54733 +
54734 +int
54735 +rj_refines(m_arg, n_arg)
54736 + void *m_arg, *n_arg;
54737 +{
54738 + register caddr_t m = m_arg, n = n_arg;
54739 + register caddr_t lim, lim2 = lim = n + *(u_char *)n;
54740 + int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);
54741 + int masks_are_equal = 1;
54742 +
54743 + if (longer > 0)
54744 + lim -= longer;
54745 + while (n < lim) {
54746 + if (*n & ~(*m))
54747 + return 0;
54748 + if (*n++ != *m++)
54749 + masks_are_equal = 0;
54750 +
54751 + }
54752 + while (n < lim2)
54753 + if (*n++)
54754 + return 0;
54755 + if (masks_are_equal && (longer < 0))
54756 + for (lim2 = m - longer; m < lim2; )
54757 + if (*m++)
54758 + return 1;
54759 + return (!masks_are_equal);
54760 +}
54761 +
54762 +
54763 +struct radij_node *
54764 +rj_match(v_arg, head)
54765 + void *v_arg;
54766 + struct radij_node_head *head;
54767 +{
54768 + caddr_t v = v_arg;
54769 + register struct radij_node *t = head->rnh_treetop, *x;
54770 + register caddr_t cp = v, cp2, cp3;
54771 + caddr_t cplim, mstart;
54772 + struct radij_node *saved_t, *top = t;
54773 + int off = t->rj_off, vlen = *(u_char *)cp, matched_off;
54774 +
54775 + /*
54776 + * Open code rj_search(v, top) to avoid overhead of extra
54777 + * subroutine call.
54778 + */
54779 + for (; t->rj_b >= 0; ) {
54780 + if (t->rj_bmask & cp[t->rj_off])
54781 + t = t->rj_r;
54782 + else
54783 + t = t->rj_l;
54784 + }
54785 + /*
54786 + * See if we match exactly as a host destination
54787 + */
54788 + KLIPS_PRINT(debug_radij,
54789 + "klips_debug:rj_match: "
54790 + "* See if we match exactly as a host destination\n");
54791 +
54792 + cp += off; cp2 = t->rj_key + off; cplim = v + vlen;
54793 + for (; cp < cplim; cp++, cp2++)
54794 + if (*cp != *cp2)
54795 + goto on1;
54796 + /*
54797 + * This extra grot is in case we are explicitly asked
54798 + * to look up the default. Ugh!
54799 + */
54800 + if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey)
54801 + t = t->rj_dupedkey;
54802 + return t;
54803 +on1:
54804 + matched_off = cp - v;
54805 + saved_t = t;
54806 + KLIPS_PRINT(debug_radij,
54807 + "klips_debug:rj_match: "
54808 + "** try to match a leaf, t=0p%p\n", t);
54809 + do {
54810 + if (t->rj_mask) {
54811 + /*
54812 + * Even if we don't match exactly as a hosts;
54813 + * we may match if the leaf we wound up at is
54814 + * a route to a net.
54815 + */
54816 + cp3 = matched_off + t->rj_mask;
54817 + cp2 = matched_off + t->rj_key;
54818 + for (; cp < cplim; cp++)
54819 + if ((*cp2++ ^ *cp) & *cp3++)
54820 + break;
54821 + if (cp == cplim)
54822 + return t;
54823 + cp = matched_off + v;
54824 + }
54825 + } while ((t = t->rj_dupedkey));
54826 + t = saved_t;
54827 + /* start searching up the tree */
54828 + KLIPS_PRINT(debug_radij,
54829 + "klips_debug:rj_match: "
54830 + "*** start searching up the tree, t=0p%p\n",
54831 + t);
54832 + do {
54833 + register struct radij_mask *m;
54834 +
54835 + t = t->rj_p;
54836 + KLIPS_PRINT(debug_radij,
54837 + "klips_debug:rj_match: "
54838 + "**** t=0p%p\n",
54839 + t);
54840 + if ((m = t->rj_mklist)) {
54841 + /*
54842 + * After doing measurements here, it may
54843 + * turn out to be faster to open code
54844 + * rj_search_m here instead of always
54845 + * copying and masking.
54846 + */
54847 + /* off = min(t->rj_off, matched_off); */
54848 + off = t->rj_off;
54849 + if (matched_off < off)
54850 + off = matched_off;
54851 + mstart = maskedKey + off;
54852 + do {
54853 + cp2 = mstart;
54854 + cp3 = m->rm_mask + off;
54855 + KLIPS_PRINT(debug_radij,
54856 + "klips_debug:rj_match: "
54857 + "***** cp2=0p%p cp3=0p%p\n",
54858 + cp2, cp3);
54859 + for (cp = v + off; cp < cplim;)
54860 + *cp2++ = *cp++ & *cp3++;
54861 + x = rj_search(maskedKey, t);
54862 + while (x && x->rj_mask != m->rm_mask)
54863 + x = x->rj_dupedkey;
54864 + if (x &&
54865 + (Bcmp(mstart, x->rj_key + off,
54866 + vlen - off) == 0))
54867 + return x;
54868 + } while ((m = m->rm_mklist));
54869 + }
54870 + } while (t != top);
54871 + KLIPS_PRINT(debug_radij,
54872 + "klips_debug:rj_match: "
54873 + "***** not found.\n");
54874 + return 0;
54875 +};
54876 +
54877 +#ifdef RJ_DEBUG
54878 +int rj_nodenum;
54879 +struct radij_node *rj_clist;
54880 +int rj_saveinfo;
54881 +DEBUG_NO_STATIC void traverse(struct radij_node *);
54882 +#ifdef RJ_DEBUG2
54883 +int rj_debug = 1;
54884 +#else
54885 +int rj_debug = 0;
54886 +#endif /* RJ_DEBUG2 */
54887 +#endif /* RJ_DEBUG */
54888 +
54889 +struct radij_node *
54890 +rj_newpair(v, b, nodes)
54891 + void *v;
54892 + int b;
54893 + struct radij_node nodes[2];
54894 +{
54895 + register struct radij_node *tt = nodes, *t = tt + 1;
54896 + t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7);
54897 + t->rj_l = tt; t->rj_off = b >> 3;
54898 + tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t;
54899 + tt->rj_flags = t->rj_flags = RJF_ACTIVE;
54900 +#ifdef RJ_DEBUG
54901 + tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
54902 + tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
54903 +#endif /* RJ_DEBUG */
54904 + return t;
54905 +}
54906 +
54907 +struct radij_node *
54908 +rj_insert(v_arg, head, dupentry, nodes)
54909 + void *v_arg;
54910 + struct radij_node_head *head;
54911 + int *dupentry;
54912 + struct radij_node nodes[2];
54913 +{
54914 + caddr_t v = v_arg;
54915 + struct radij_node *top = head->rnh_treetop;
54916 + int head_off = top->rj_off, vlen = (int)*((u_char *)v);
54917 + register struct radij_node *t = rj_search(v_arg, top);
54918 + register caddr_t cp = v + head_off;
54919 + register int b;
54920 + struct radij_node *tt;
54921 + /*
54922 + *find first bit at which v and t->rj_key differ
54923 + */
54924 + {
54925 + register caddr_t cp2 = t->rj_key + head_off;
54926 + register int cmp_res;
54927 + caddr_t cplim = v + vlen;
54928 +
54929 + while (cp < cplim)
54930 + if (*cp2++ != *cp++)
54931 + goto on1;
54932 + *dupentry = 1;
54933 + return t;
54934 +on1:
54935 + *dupentry = 0;
54936 + cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
54937 + for (b = (cp - v) << 3; cmp_res; b--)
54938 + cmp_res >>= 1;
54939 + }
54940 + {
54941 + register struct radij_node *p, *x = top;
54942 + cp = v;
54943 + do {
54944 + p = x;
54945 + if (cp[x->rj_off] & x->rj_bmask)
54946 + x = x->rj_r;
54947 + else x = x->rj_l;
54948 + } while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */
54949 +#ifdef RJ_DEBUG
54950 + if (rj_debug)
54951 + printk("klips_debug:rj_insert: Going In:\n"), traverse(p);
54952 +#endif /* RJ_DEBUG */
54953 + t = rj_newpair(v_arg, b, nodes); tt = t->rj_l;
54954 + if ((cp[p->rj_off] & p->rj_bmask) == 0)
54955 + p->rj_l = t;
54956 + else
54957 + p->rj_r = t;
54958 + x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */
54959 + if ((cp[t->rj_off] & t->rj_bmask) == 0) {
54960 + t->rj_r = x;
54961 + } else {
54962 + t->rj_r = tt; t->rj_l = x;
54963 + }
54964 +#ifdef RJ_DEBUG
54965 + if (rj_debug)
54966 + printk("klips_debug:rj_insert: Coming out:\n"), traverse(p);
54967 +#endif /* RJ_DEBUG */
54968 + }
54969 + return (tt);
54970 +}
54971 +
54972 +struct radij_node *
54973 +rj_addmask(n_arg, search, skip)
54974 + int search, skip;
54975 + void *n_arg;
54976 +{
54977 + caddr_t netmask = (caddr_t)n_arg;
54978 + register struct radij_node *x;
54979 + register caddr_t cp, cplim;
54980 + register int b, mlen, j;
54981 + int maskduplicated;
54982 +
54983 + mlen = *(u_char *)netmask;
54984 + if (search) {
54985 + x = rj_search(netmask, rj_masktop);
54986 + mlen = *(u_char *)netmask;
54987 + if (Bcmp(netmask, x->rj_key, mlen) == 0)
54988 + return (x);
54989 + }
54990 + R_Malloc(x, struct radij_node *, maj_keylen + 2 * sizeof (*x));
54991 + if (x == 0)
54992 + return (0);
54993 + Bzero(x, maj_keylen + 2 * sizeof (*x));
54994 + cp = (caddr_t)(x + 2);
54995 + Bcopy(netmask, cp, mlen);
54996 + netmask = cp;
54997 + x = rj_insert(netmask, mask_rjhead, &maskduplicated, x);
54998 + /*
54999 + * Calculate index of mask.
55000 + */
55001 + cplim = netmask + mlen;
55002 + for (cp = netmask + skip; cp < cplim; cp++)
55003 + if (*(u_char *)cp != 0xff)
55004 + break;
55005 + b = (cp - netmask) << 3;
55006 + if (cp != cplim) {
55007 + if (*cp != 0) {
55008 + gotOddMasks = 1;
55009 + for (j = 0x80; j; b++, j >>= 1)
55010 + if ((j & *cp) == 0)
55011 + break;
55012 + }
55013 + }
55014 + x->rj_b = -1 - b;
55015 + return (x);
55016 +}
55017 +
55018 +#if 0
55019 +struct radij_node *
55020 +#endif
55021 +int
55022 +rj_addroute(v_arg, n_arg, head, treenodes)
55023 + void *v_arg, *n_arg;
55024 + struct radij_node_head *head;
55025 + struct radij_node treenodes[2];
55026 +{
55027 + caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
55028 + register struct radij_node *t, *x=NULL, *tt;
55029 + struct radij_node *saved_tt, *top = head->rnh_treetop;
55030 + short b = 0, b_leaf;
55031 + int mlen, keyduplicated;
55032 + caddr_t cplim;
55033 + struct radij_mask *m, **mp;
55034 +
55035 + /*
55036 + * In dealing with non-contiguous masks, there may be
55037 + * many different routes which have the same mask.
55038 + * We will find it useful to have a unique pointer to
55039 + * the mask to speed avoiding duplicate references at
55040 + * nodes and possibly save time in calculating indices.
55041 + */
55042 + if (netmask) {
55043 + x = rj_search(netmask, rj_masktop);
55044 + mlen = *(u_char *)netmask;
55045 + if (Bcmp(netmask, x->rj_key, mlen) != 0) {
55046 + x = rj_addmask(netmask, 0, top->rj_off);
55047 + if (x == 0)
55048 + return -ENOMEM; /* (0) rgb */
55049 + }
55050 + netmask = x->rj_key;
55051 + b = -1 - x->rj_b;
55052 + }
55053 + /*
55054 + * Deal with duplicated keys: attach node to previous instance
55055 + */
55056 + saved_tt = tt = rj_insert(v, head, &keyduplicated, treenodes);
55057 +#ifdef RJ_DEBUG
55058 + printk("addkey: duplicated: %d\n", keyduplicated);
55059 +#endif
55060 + if (keyduplicated) {
55061 + do {
55062 + if (tt->rj_mask == netmask)
55063 + return -EEXIST; /* -ENXIO; (0) rgb */
55064 + t = tt;
55065 + if (netmask == 0 ||
55066 + (tt->rj_mask && rj_refines(netmask, tt->rj_mask)))
55067 + break;
55068 + } while ((tt = tt->rj_dupedkey));
55069 + /*
55070 + * If the mask is not duplicated, we wouldn't
55071 + * find it among possible duplicate key entries
55072 + * anyway, so the above test doesn't hurt.
55073 + *
55074 + * We sort the masks for a duplicated key the same way as
55075 + * in a masklist -- most specific to least specific.
55076 + * This may require the unfortunate nuisance of relocating
55077 + * the head of the list.
55078 + */
55079 + if (tt && t == saved_tt) {
55080 + struct radij_node *xx = x;
55081 + /* link in at head of list */
55082 + (tt = treenodes)->rj_dupedkey = t;
55083 + tt->rj_flags = t->rj_flags;
55084 + tt->rj_p = x = t->rj_p;
55085 + if (x->rj_l == t) x->rj_l = tt; else x->rj_r = tt;
55086 + saved_tt = tt; x = xx;
55087 + } else {
55088 + (tt = treenodes)->rj_dupedkey = t->rj_dupedkey;
55089 + t->rj_dupedkey = tt;
55090 + }
55091 +#ifdef RJ_DEBUG
55092 + t=tt+1; tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
55093 + tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
55094 +#endif /* RJ_DEBUG */
55095 + t = saved_tt;
55096 + tt->rj_key = (caddr_t) v;
55097 + tt->rj_b = -1;
55098 + tt->rj_flags = t->rj_flags & ~RJF_ROOT;
55099 + }
55100 + /*
55101 + * Put mask in tree.
55102 + */
55103 + if (netmask) {
55104 + tt->rj_mask = netmask;
55105 + tt->rj_b = x->rj_b;
55106 + }
55107 + t = saved_tt->rj_p;
55108 + b_leaf = -1 - t->rj_b;
55109 + if (t->rj_r == saved_tt) x = t->rj_l; else x = t->rj_r;
55110 + /* Promote general routes from below */
55111 + if (x->rj_b < 0) {
55112 + if (x->rj_mask && (x->rj_b >= b_leaf) && x->rj_mklist == 0) {
55113 + MKGet(m);
55114 + if (m) {
55115 + Bzero(m, sizeof *m);
55116 + m->rm_b = x->rj_b;
55117 + m->rm_mask = x->rj_mask;
55118 + x->rj_mklist = t->rj_mklist = m;
55119 + }
55120 + }
55121 + } else if (x->rj_mklist) {
55122 + /*
55123 + * Skip over masks whose index is > that of new node
55124 + */
55125 + for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
55126 + if (m->rm_b >= b_leaf)
55127 + break;
55128 + t->rj_mklist = m; *mp = 0;
55129 + }
55130 + /* Add new route to highest possible ancestor's list */
55131 + if ((netmask == 0) || (b > t->rj_b )) {
55132 +#ifdef RJ_DEBUG
55133 + printk("klips:radij.c: netmask = %p or b(%d)>t->rjb(%d)\n", netmask, b, t->rj_b);
55134 +#endif
55135 + return 0; /* tt rgb */ /* can't lift at all */
55136 + }
55137 + b_leaf = tt->rj_b;
55138 + do {
55139 + x = t;
55140 + t = t->rj_p;
55141 + } while (b <= t->rj_b && x != top);
55142 + /*
55143 + * Search through routes associated with node to
55144 + * insert new route according to index.
55145 + * For nodes of equal index, place more specific
55146 + * masks first.
55147 + */
55148 + cplim = netmask + mlen;
55149 + for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) {
55150 + if (m->rm_b < b_leaf)
55151 + continue;
55152 + if (m->rm_b > b_leaf)
55153 + break;
55154 + if (m->rm_mask == netmask) {
55155 + m->rm_refs++;
55156 + tt->rj_mklist = m;
55157 +#ifdef RJ_DEBUG
55158 + printk("klips:radij.c: m->rm_mask %p == netmask\n", netmask);
55159 +#endif
55160 + return 0; /* tt rgb */
55161 + }
55162 + if (rj_refines(netmask, m->rm_mask))
55163 + break;
55164 + }
55165 + MKGet(m);
55166 + if (m == 0) {
55167 + printk("klips_debug:rj_addroute: "
55168 + "Mask for route not entered\n");
55169 + return 0; /* (tt) rgb */
55170 + }
55171 + Bzero(m, sizeof *m);
55172 + m->rm_b = b_leaf;
55173 + m->rm_mask = netmask;
55174 + m->rm_mklist = *mp;
55175 + *mp = m;
55176 + tt->rj_mklist = m;
55177 +#ifdef RJ_DEBUG
55178 + printk("klips:radij.c: addroute done\n");
55179 +#endif
55180 + return 0; /* tt rgb */
55181 +}
55182 +
55183 +int
55184 +rj_delete(v_arg, netmask_arg, head, node)
55185 + void *v_arg, *netmask_arg;
55186 + struct radij_node_head *head;
55187 + struct radij_node **node;
55188 +{
55189 + register struct radij_node *t, *p, *x, *tt;
55190 + struct radij_mask *m, *saved_m, **mp;
55191 + struct radij_node *dupedkey, *saved_tt, *top;
55192 + caddr_t v, netmask;
55193 + int b, head_off, vlen;
55194 +
55195 + v = v_arg;
55196 + netmask = netmask_arg;
55197 + x = head->rnh_treetop;
55198 + tt = rj_search(v, x);
55199 + head_off = x->rj_off;
55200 + vlen = *(u_char *)v;
55201 + saved_tt = tt;
55202 + top = x;
55203 + if (tt == 0 ||
55204 + Bcmp(v + head_off, tt->rj_key + head_off, vlen - head_off))
55205 + return -EFAULT; /* (0) rgb */
55206 + /*
55207 + * Delete our route from mask lists.
55208 + */
55209 + if ((dupedkey = tt->rj_dupedkey)) {
55210 + if (netmask)
55211 + netmask = rj_search(netmask, rj_masktop)->rj_key;
55212 + while (tt->rj_mask != netmask)
55213 + if ((tt = tt->rj_dupedkey) == 0)
55214 + return -ENOENT; /* -ENXIO; (0) rgb */
55215 + }
55216 + if (tt->rj_mask == 0 || (saved_m = m = tt->rj_mklist) == 0)
55217 + goto on1;
55218 + if (m->rm_mask != tt->rj_mask) {
55219 + printk("klips_debug:rj_delete: "
55220 + "inconsistent annotation\n");
55221 + goto on1;
55222 + }
55223 + if (--m->rm_refs >= 0)
55224 + goto on1;
55225 + b = -1 - tt->rj_b;
55226 + t = saved_tt->rj_p;
55227 + if (b > t->rj_b)
55228 + goto on1; /* Wasn't lifted at all */
55229 + do {
55230 + x = t;
55231 + t = t->rj_p;
55232 + } while (b <= t->rj_b && x != top);
55233 + for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
55234 + if (m == saved_m) {
55235 + *mp = m->rm_mklist;
55236 + MKFree(m);
55237 + break;
55238 + }
55239 + if (m == 0)
55240 + printk("klips_debug:rj_delete: "
55241 + "couldn't find our annotation\n");
55242 +on1:
55243 + /*
55244 + * Eliminate us from tree
55245 + */
55246 + if (tt->rj_flags & RJF_ROOT)
55247 + return -EFAULT; /* (0) rgb */
55248 +#ifdef RJ_DEBUG
55249 + /* Get us out of the creation list */
55250 + for (t = rj_clist; t && t->rj_ybro != tt; t = t->rj_ybro) {}
55251 + if (t) t->rj_ybro = tt->rj_ybro;
55252 +#endif /* RJ_DEBUG */
55253 + t = tt->rj_p;
55254 + if (dupedkey) {
55255 + if (tt == saved_tt) {
55256 + x = dupedkey; x->rj_p = t;
55257 + if (t->rj_l == tt) t->rj_l = x; else t->rj_r = x;
55258 + } else {
55259 + for (x = p = saved_tt; p && p->rj_dupedkey != tt;)
55260 + p = p->rj_dupedkey;
55261 + if (p) p->rj_dupedkey = tt->rj_dupedkey;
55262 + else printk("klips_debug:rj_delete: "
55263 + "couldn't find node that we started with\n");
55264 + }
55265 + t = tt + 1;
55266 + if (t->rj_flags & RJF_ACTIVE) {
55267 +#ifndef RJ_DEBUG
55268 + *++x = *t; p = t->rj_p;
55269 +#else
55270 + b = t->rj_info; *++x = *t; t->rj_info = b; p = t->rj_p;
55271 +#endif /* RJ_DEBUG */
55272 + if (p->rj_l == t) p->rj_l = x; else p->rj_r = x;
55273 + x->rj_l->rj_p = x; x->rj_r->rj_p = x;
55274 + }
55275 + goto out;
55276 + }
55277 + if (t->rj_l == tt) x = t->rj_r; else x = t->rj_l;
55278 + p = t->rj_p;
55279 + if (p->rj_r == t) p->rj_r = x; else p->rj_l = x;
55280 + x->rj_p = p;
55281 + /*
55282 + * Demote routes attached to us.
55283 + */
55284 + if (t->rj_mklist) {
55285 + if (x->rj_b >= 0) {
55286 + for (mp = &x->rj_mklist; (m = *mp);)
55287 + mp = &m->rm_mklist;
55288 + *mp = t->rj_mklist;
55289 + } else {
55290 + for (m = t->rj_mklist; m;) {
55291 + struct radij_mask *mm = m->rm_mklist;
55292 + if (m == x->rj_mklist && (--(m->rm_refs) < 0)) {
55293 + x->rj_mklist = 0;
55294 + MKFree(m);
55295 + } else
55296 + printk("klips_debug:rj_delete: "
55297 + "Orphaned Mask 0p%p at 0p%p\n", m, x);
55298 + m = mm;
55299 + }
55300 + }
55301 + }
55302 + /*
55303 + * We may be holding an active internal node in the tree.
55304 + */
55305 + x = tt + 1;
55306 + if (t != x) {
55307 +#ifndef RJ_DEBUG
55308 + *t = *x;
55309 +#else
55310 + b = t->rj_info; *t = *x; t->rj_info = b;
55311 +#endif /* RJ_DEBUG */
55312 + t->rj_l->rj_p = t; t->rj_r->rj_p = t;
55313 + p = x->rj_p;
55314 + if (p->rj_l == x) p->rj_l = t; else p->rj_r = t;
55315 + }
55316 +out:
55317 + tt->rj_flags &= ~RJF_ACTIVE;
55318 + tt[1].rj_flags &= ~RJF_ACTIVE;
55319 + *node = tt;
55320 + return 0; /* (tt) rgb */
55321 +}
55322 +
55323 +int
55324 +rj_walktree(h, f, w)
55325 + struct radij_node_head *h;
55326 + register int (*f)(struct radij_node *,void *);
55327 + void *w;
55328 +{
55329 + int error;
55330 + struct radij_node *base, *next;
55331 + register struct radij_node *rn;
55332 +
55333 + if(!h || !f /* || !w */) {
55334 + return -ENODATA;
55335 + }
55336 +
55337 + rn = h->rnh_treetop;
55338 + /*
55339 + * This gets complicated because we may delete the node
55340 + * while applying the function f to it, so we need to calculate
55341 + * the successor node in advance.
55342 + */
55343 + /* First time through node, go left */
55344 + while (rn->rj_b >= 0)
55345 + rn = rn->rj_l;
55346 + for (;;) {
55347 +#ifdef CONFIG_KLIPS_DEBUG
55348 + if(debug_radij) {
55349 + printk("klips_debug:rj_walktree: "
55350 + "for: rn=0p%p rj_b=%d rj_flags=%x",
55351 + rn,
55352 + rn->rj_b,
55353 + rn->rj_flags);
55354 + rn->rj_b >= 0 ?
55355 + printk(" node off=%x\n",
55356 + rn->rj_off) :
55357 + printk(" leaf key = %08x->%08x\n",
55358 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
55359 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
55360 + ;
55361 + }
55362 +#endif /* CONFIG_KLIPS_DEBUG */
55363 + base = rn;
55364 + /* If at right child go back up, otherwise, go right */
55365 + while (rn->rj_p->rj_r == rn && (rn->rj_flags & RJF_ROOT) == 0)
55366 + rn = rn->rj_p;
55367 + /* Find the next *leaf* since next node might vanish, too */
55368 + for (rn = rn->rj_p->rj_r; rn->rj_b >= 0;)
55369 + rn = rn->rj_l;
55370 + next = rn;
55371 +#ifdef CONFIG_KLIPS_DEBUG
55372 + if(debug_radij) {
55373 + printk("klips_debug:rj_walktree: "
55374 + "processing leaves, rn=0p%p rj_b=%d rj_flags=%x",
55375 + rn,
55376 + rn->rj_b,
55377 + rn->rj_flags);
55378 + rn->rj_b >= 0 ?
55379 + printk(" node off=%x\n",
55380 + rn->rj_off) :
55381 + printk(" leaf key = %08x->%08x\n",
55382 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
55383 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
55384 + ;
55385 + }
55386 +#endif /* CONFIG_KLIPS_DEBUG */
55387 + /* Process leaves */
55388 + while ((rn = base)) {
55389 + base = rn->rj_dupedkey;
55390 +#ifdef CONFIG_KLIPS_DEBUG
55391 + if(debug_radij) {
55392 + printk("klips_debug:rj_walktree: "
55393 + "while: base=0p%p rn=0p%p rj_b=%d rj_flags=%x",
55394 + base,
55395 + rn,
55396 + rn->rj_b,
55397 + rn->rj_flags);
55398 + rn->rj_b >= 0 ?
55399 + printk(" node off=%x\n",
55400 + rn->rj_off) :
55401 + printk(" leaf key = %08x->%08x\n",
55402 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
55403 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
55404 + ;
55405 + }
55406 +#endif /* CONFIG_KLIPS_DEBUG */
55407 + if (!(rn->rj_flags & RJF_ROOT) && (error = (*f)(rn, w)))
55408 + return (-error);
55409 + }
55410 + rn = next;
55411 + if (rn->rj_flags & RJF_ROOT)
55412 + return (0);
55413 + }
55414 + /* NOTREACHED */
55415 +}
55416 +
55417 +int
55418 +rj_inithead(head, off)
55419 + void **head;
55420 + int off;
55421 +{
55422 + register struct radij_node_head *rnh;
55423 + register struct radij_node *t, *tt, *ttt;
55424 + if (*head)
55425 + return (1);
55426 + R_Malloc(rnh, struct radij_node_head *, sizeof (*rnh));
55427 + if (rnh == NULL)
55428 + return (0);
55429 + Bzero(rnh, sizeof (*rnh));
55430 + *head = rnh;
55431 + t = rj_newpair(rj_zeroes, off, rnh->rnh_nodes);
55432 + ttt = rnh->rnh_nodes + 2;
55433 + t->rj_r = ttt;
55434 + t->rj_p = t;
55435 + tt = t->rj_l;
55436 + tt->rj_flags = t->rj_flags = RJF_ROOT | RJF_ACTIVE;
55437 + tt->rj_b = -1 - off;
55438 + *ttt = *tt;
55439 + ttt->rj_key = rj_ones;
55440 + rnh->rnh_addaddr = rj_addroute;
55441 + rnh->rnh_deladdr = rj_delete;
55442 + rnh->rnh_matchaddr = rj_match;
55443 + rnh->rnh_walktree = rj_walktree;
55444 + rnh->rnh_treetop = t;
55445 + return (1);
55446 +}
55447 +
55448 +void
55449 +rj_init()
55450 +{
55451 + char *cp, *cplim;
55452 +
55453 + if (maj_keylen == 0) {
55454 + printk("klips_debug:rj_init: "
55455 + "radij functions require maj_keylen be set\n");
55456 + return;
55457 + }
55458 + R_Malloc(rj_zeroes, char *, 3 * maj_keylen);
55459 + if (rj_zeroes == NULL)
55460 + panic("rj_init");
55461 + Bzero(rj_zeroes, 3 * maj_keylen);
55462 + rj_ones = cp = rj_zeroes + maj_keylen;
55463 + maskedKey = cplim = rj_ones + maj_keylen;
55464 + while (cp < cplim)
55465 + *cp++ = -1;
55466 + if (rj_inithead((void **)&mask_rjhead, 0) == 0)
55467 + panic("rj_init 2");
55468 +}
55469 +
55470 +void
55471 +rj_preorder(struct radij_node *rn, int l)
55472 +{
55473 + int i;
55474 +
55475 + if (rn == NULL){
55476 + printk("klips_debug:rj_preorder: "
55477 + "NULL pointer\n");
55478 + return;
55479 + }
55480 +
55481 + if (rn->rj_b >= 0){
55482 + rj_preorder(rn->rj_l, l+1);
55483 + rj_preorder(rn->rj_r, l+1);
55484 + printk("klips_debug:");
55485 + for (i=0; i<l; i++)
55486 + printk("*");
55487 + printk(" off = %d\n",
55488 + rn->rj_off);
55489 + } else {
55490 + printk("klips_debug:");
55491 + for (i=0; i<l; i++)
55492 + printk("@");
55493 + printk(" flags = %x",
55494 + (u_int)rn->rj_flags);
55495 + if (rn->rj_flags & RJF_ACTIVE) {
55496 + printk(" @key=0p%p",
55497 + rn->rj_key);
55498 + printk(" key = %08x->%08x",
55499 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
55500 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr));
55501 + printk(" @mask=0p%p",
55502 + rn->rj_mask);
55503 + if (rn->rj_mask)
55504 + printk(" mask = %08x->%08x",
55505 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_src.s_addr),
55506 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_dst.s_addr));
55507 + if (rn->rj_dupedkey)
55508 + printk(" dupedkey = 0p%p",
55509 + rn->rj_dupedkey);
55510 + }
55511 + printk("\n");
55512 + }
55513 +}
55514 +
55515 +#ifdef RJ_DEBUG
55516 +DEBUG_NO_STATIC void traverse(struct radij_node *p)
55517 +{
55518 + rj_preorder(p, 0);
55519 +}
55520 +#endif /* RJ_DEBUG */
55521 +
55522 +void
55523 +rj_dumptrees(void)
55524 +{
55525 + rj_preorder(rnh->rnh_treetop, 0);
55526 +}
55527 +
55528 +void
55529 +rj_free_mkfreelist(void)
55530 +{
55531 + struct radij_mask *mknp, *mknp2;
55532 +
55533 + mknp = rj_mkfreelist;
55534 + while(mknp)
55535 + {
55536 + mknp2 = mknp;
55537 + mknp = mknp->rm_mklist;
55538 + kfree(mknp2);
55539 + }
55540 +}
55541 +
55542 +int
55543 +radijcleartree(void)
55544 +{
55545 + return rj_walktree(rnh, ipsec_rj_walker_delete, NULL);
55546 +}
55547 +
55548 +int
55549 +radijcleanup(void)
55550 +{
55551 + int error = 0;
55552 +
55553 + error = radijcleartree();
55554 +
55555 + rj_free_mkfreelist();
55556 +
55557 +/* rj_walktree(mask_rjhead, ipsec_rj_walker_delete, NULL); */
55558 + if(mask_rjhead) {
55559 + kfree(mask_rjhead);
55560 + }
55561 +
55562 + if(rj_zeroes) {
55563 + kfree(rj_zeroes);
55564 + }
55565 +
55566 + if(rnh) {
55567 + kfree(rnh);
55568 + }
55569 +
55570 + return error;
55571 +}
55572 +
55573 +/*
55574 + * $Log: radij.c,v $
55575 + * Revision 1.48 2005/04/29 05:10:22 mcr
55576 + * removed from extraenous includes to make unit testing easier.
55577 + *
55578 + * Revision 1.47 2004/07/10 19:11:18 mcr
55579 + * CONFIG_IPSEC -> CONFIG_KLIPS.
55580 + *
55581 + * Revision 1.46 2004/04/06 02:49:26 mcr
55582 + * pullup of algo code from alg-branch.
55583 + *
55584 + * Revision 1.45 2003/10/31 02:27:55 mcr
55585 + * pulled up port-selector patches and sa_id elimination.
55586 + *
55587 + * Revision 1.44.30.1 2003/10/29 01:30:41 mcr
55588 + * elimited "struct sa_id".
55589 + *
55590 + * Revision 1.44 2002/07/24 18:44:54 rgb
55591 + * Type fiddling to tame ia64 compiler.
55592 + *
55593 + * Revision 1.43 2002/05/23 07:14:11 rgb
55594 + * Cleaned up %p variants to 0p%p for test suite cleanup.
55595 + *
55596 + * Revision 1.42 2002/04/24 07:55:32 mcr
55597 + * #include patches and Makefiles for post-reorg compilation.
55598 + *
55599 + * Revision 1.41 2002/04/24 07:36:35 mcr
55600 + * Moved from ./klips/net/ipsec/radij.c,v
55601 + *
55602 + * Revision 1.40 2002/01/29 17:17:58 mcr
55603 + * moved include of ipsec_param.h to after include of linux/kernel.h
55604 + * otherwise, it seems that some option that is set in ipsec_param.h
55605 + * screws up something subtle in the include path to kernel.h, and
55606 + * it complains on the snprintf() prototype.
55607 + *
55608 + * Revision 1.39 2002/01/29 04:00:55 mcr
55609 + * more excise of kversions.h header.
55610 + *
55611 + * Revision 1.38 2002/01/29 02:13:19 mcr
55612 + * introduction of ipsec_kversion.h means that include of
55613 + * ipsec_param.h must preceed any decisions about what files to
55614 + * include to deal with differences in kernel source.
55615 + *
55616 + * Revision 1.37 2001/10/18 04:45:23 rgb
55617 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
55618 + * lib/freeswan.h version macros moved to lib/kversions.h.
55619 + * Other compiler directive cleanups.
55620 + *
55621 + * Revision 1.36 2001/08/22 13:43:51 henry
55622 + * eliminate the single use of min() to avoid problems with Linus changing it
55623 + *
55624 + * Revision 1.35 2001/06/15 04:57:29 rgb
55625 + * Clarified error return codes.
55626 + * Changed mask add already exists to EEXIST.
55627 + * Changed mask delete did not exist to ENOENT.
55628 + *
55629 + * Revision 1.34 2001/05/03 19:44:26 rgb
55630 + * Fix sign of error return codes for rj_addroute().
55631 + *
55632 + * Revision 1.33 2001/02/27 22:24:56 rgb
55633 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
55634 + * Check for satoa() return codes.
55635 + *
55636 + * Revision 1.32 2001/02/27 06:23:15 rgb
55637 + * Debug line splitting.
55638 + *
55639 + * Revision 1.31 2000/11/06 04:35:21 rgb
55640 + * Clear table *before* releasing other items in radijcleanup.
55641 + *
55642 + * Revision 1.30 2000/09/20 04:07:40 rgb
55643 + * Changed static functions to DEBUG_NO_STATIC to reveal function names in
55644 + * oopsen.
55645 + *
55646 + * Revision 1.29 2000/09/12 03:25:02 rgb
55647 + * Moved radij_c_version printing to ipsec_version_get_info().
55648 + *
55649 + * Revision 1.28 2000/09/08 19:12:56 rgb
55650 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
55651 + *
55652 + * Revision 1.27 2000/07/28 14:58:32 rgb
55653 + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
55654 + *
55655 + * Revision 1.26 2000/05/10 23:11:37 rgb
55656 + * Comment out most of the startup version information.
55657 + *
55658 + * Revision 1.25 2000/01/21 06:21:47 rgb
55659 + * Change return codes to negative on error.
55660 + *
55661 + * Revision 1.24 1999/11/18 04:09:20 rgb
55662 + * Replaced all kernel version macros to shorter, readable form.
55663 + *
55664 + * Revision 1.23 1999/11/17 15:53:41 rgb
55665 + * Changed all occurrences of #include "../../../lib/freeswan.h"
55666 + * to #include <freeswan.h> which works due to -Ilibfreeswan in the
55667 + * klips/net/ipsec/Makefile.
55668 + *
55669 + * Revision 1.22 1999/10/15 22:17:28 rgb
55670 + * Modify radijcleanup() to call radijcleartree().
55671 + *
55672 + * Revision 1.21 1999/10/08 18:37:34 rgb
55673 + * Fix end-of-line spacing to sate whining PHMs.
55674 + *
55675 + * Revision 1.20 1999/10/01 15:44:54 rgb
55676 + * Move spinlock header include to 2.1> scope.
55677 + *
55678 + * Revision 1.19 1999/10/01 08:35:52 rgb
55679 + * Add spinlock include to shut up compiler for 2.0.38.
55680 + *
55681 + * Revision 1.18 1999/09/23 18:02:52 rgb
55682 + * De-alarm the search failure message so it doesn't sound so grave.
55683 + *
55684 + * Revision 1.17 1999/05/25 21:26:01 rgb
55685 + * Fix rj_walktree() sanity checking bug.
55686 + *
55687 + * Revision 1.16 1999/05/09 03:25:38 rgb
55688 + * Fix bug introduced by 2.2 quick-and-dirty patch.
55689 + *
55690 + * Revision 1.15 1999/05/05 22:02:33 rgb
55691 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
55692 + *
55693 + * Revision 1.14 1999/04/29 15:24:15 rgb
55694 + * Add sanity checking for null pointer arguments.
55695 + * Standardise an error return method.
55696 + *
55697 + * Revision 1.13 1999/04/11 00:29:02 henry
55698 + * GPL boilerplate
55699 + *
55700 + * Revision 1.12 1999/04/06 04:54:28 rgb
55701 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
55702 + * patch shell fixes.
55703 + *
55704 + * Revision 1.11 1999/02/17 16:52:53 rgb
55705 + * Convert DEBUG_IPSEC to KLIPS_PRINT
55706 + * Clean out unused cruft.
55707 + *
55708 + * Revision 1.10 1999/01/22 06:30:05 rgb
55709 + * Cruft clean-out.
55710 + * 64-bit clean-up.
55711 + *
55712 + * Revision 1.9 1998/12/01 13:22:04 rgb
55713 + * Added support for debug printing of version info.
55714 + *
55715 + * Revision 1.8 1998/11/30 13:22:55 rgb
55716 + * Rationalised all the klips kernel file headers. They are much shorter
55717 + * now and won't conflict under RH5.2.
55718 + *
55719 + * Revision 1.7 1998/10/25 02:43:26 rgb
55720 + * Change return type on rj_addroute and rj_delete and add and argument
55721 + * to the latter to be able to transmit more infomation about errors.
55722 + *
55723 + * Revision 1.6 1998/10/19 14:30:06 rgb
55724 + * Added inclusion of freeswan.h.
55725 + *
55726 + * Revision 1.5 1998/10/09 04:33:27 rgb
55727 + * Added 'klips_debug' prefix to all klips printk debug statements.
55728 + * Fixed output formatting slightly.
55729 + *
55730 + * Revision 1.4 1998/07/28 00:06:59 rgb
55731 + * Add debug detail to tree traversing.
55732 + *
55733 + * Revision 1.3 1998/07/14 18:07:58 rgb
55734 + * Add a routine to clear the eroute tree.
55735 + *
55736 + * Revision 1.2 1998/06/25 20:03:22 rgb
55737 + * Cleanup #endif comments. Debug output for rj_init.
55738 + *
55739 + * Revision 1.1 1998/06/18 21:30:22 henry
55740 + * move sources from klips/src to klips/net/ipsec to keep stupid kernel
55741 + * build scripts happier about symlinks
55742 + *
55743 + * Revision 1.8 1998/05/25 20:34:15 rgb
55744 + * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
55745 + *
55746 + * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
55747 + * add ipsec_rj_walker_delete.
55748 + *
55749 + * Recover memory for eroute table on unload of module.
55750 + *
55751 + * Revision 1.7 1998/05/21 12:58:58 rgb
55752 + * Moved 'extern' definitions to ipsec_radij.h to support /proc 3k limit fix.
55753 + *
55754 + * Revision 1.6 1998/04/23 20:57:29 rgb
55755 + * Cleaned up compiler warnings for unused debugging functions.
55756 + *
55757 + * Revision 1.5 1998/04/22 16:51:38 rgb
55758 + * Tidy up radij debug code from recent rash of modifications to debug code.
55759 + *
55760 + * Revision 1.4 1998/04/21 21:28:56 rgb
55761 + * Rearrange debug switches to change on the fly debug output from user
55762 + * space. Only kernel changes checked in at this time. radij.c was also
55763 + * changed to temporarily remove buggy debugging code in rj_delete causing
55764 + * an OOPS and hence, netlink device open errors.
55765 + *
55766 + * Revision 1.3 1998/04/14 17:30:37 rgb
55767 + * Fix up compiling errors for radij tree memory reclamation.
55768 + *
55769 + * Revision 1.2 1998/04/12 22:03:25 rgb
55770 + * Updated ESP-3DES-HMAC-MD5-96,
55771 + * ESP-DES-HMAC-MD5-96,
55772 + * AH-HMAC-MD5-96,
55773 + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
55774 + * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
55775 + *
55776 + * Fixed eroute references in /proc/net/ipsec*.
55777 + *
55778 + * Started to patch module unloading memory leaks in ipsec_netlink and
55779 + * radij tree unloading.
55780 + *
55781 + * Revision 1.1 1998/04/09 03:06:15 henry
55782 + * sources moved up from linux/net/ipsec
55783 + *
55784 + * Revision 1.1.1.1 1998/04/08 05:35:03 henry
55785 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
55786 + *
55787 + * Revision 0.4 1997/01/15 01:28:15 ji
55788 + * No changes.
55789 + *
55790 + * Revision 0.3 1996/11/20 14:39:04 ji
55791 + * Minor cleanups.
55792 + * Rationalized debugging code.
55793 + *
55794 + * Revision 0.2 1996/11/02 00:18:33 ji
55795 + * First limited release.
55796 + *
55797 + *
55798 + */
55799 --- /dev/null Tue Mar 11 13:02:56 2003
55800 +++ linux/net/ipsec/rangetoa.c Mon Feb 9 13:51:03 2004
55801 @@ -0,0 +1,60 @@
55802 +/*
55803 + * convert binary form of address range to ASCII
55804 + * Copyright (C) 1998, 1999 Henry Spencer.
55805 + *
55806 + * This library is free software; you can redistribute it and/or modify it
55807 + * under the terms of the GNU Library General Public License as published by
55808 + * the Free Software Foundation; either version 2 of the License, or (at your
55809 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
55810 + *
55811 + * This library is distributed in the hope that it will be useful, but
55812 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
55813 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
55814 + * License for more details.
55815 + *
55816 + * RCSID $Id: rangetoa.c,v 1.9 2004/07/10 07:48:37 mcr Exp $
55817 + */
55818 +#include "openswan.h"
55819 +
55820 +/*
55821 + - rangetoa - convert address range to ASCII
55822 + */
55823 +size_t /* space needed for full conversion */
55824 +rangetoa(addrs, format, dst, dstlen)
55825 +struct in_addr addrs[2];
55826 +int format; /* character */
55827 +char *dst; /* need not be valid if dstlen is 0 */
55828 +size_t dstlen;
55829 +{
55830 + size_t len;
55831 + size_t rest;
55832 + int n;
55833 + char *p;
55834 +
55835 + switch (format) {
55836 + case 0:
55837 + break;
55838 + default:
55839 + return 0;
55840 + break;
55841 + }
55842 +
55843 + len = addrtoa(addrs[0], 0, dst, dstlen);
55844 + if (len < dstlen)
55845 + for (p = dst + len - 1, n = 3; len < dstlen && n > 0;
55846 + p++, len++, n--)
55847 + *p = '.';
55848 + else
55849 + p = NULL;
55850 + if (len < dstlen)
55851 + rest = dstlen - len;
55852 + else {
55853 + if (dstlen > 0)
55854 + *(dst + dstlen - 1) = '\0';
55855 + rest = 0;
55856 + }
55857 +
55858 + len += addrtoa(addrs[1], 0, p, rest);
55859 +
55860 + return len;
55861 +}
55862 --- /dev/null Tue Mar 11 13:02:56 2003
55863 +++ linux/net/ipsec/satot.c Mon Feb 9 13:51:03 2004
55864 @@ -0,0 +1,134 @@
55865 +/*
55866 + * convert from binary form of SA ID to text
55867 + * Copyright (C) 2000, 2001 Henry Spencer.
55868 + *
55869 + * This library is free software; you can redistribute it and/or modify it
55870 + * under the terms of the GNU Library General Public License as published by
55871 + * the Free Software Foundation; either version 2 of the License, or (at your
55872 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
55873 + *
55874 + * This library is distributed in the hope that it will be useful, but
55875 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
55876 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
55877 + * License for more details.
55878 + *
55879 + * RCSID $Id: satot.c,v 1.13 2004/07/10 07:48:37 mcr Exp $
55880 + */
55881 +#include "openswan.h"
55882 +
55883 +static struct typename {
55884 + char type;
55885 + char *name;
55886 +} typenames[] = {
55887 + { SA_AH, "ah" },
55888 + { SA_ESP, "esp" },
55889 + { SA_IPIP, "tun" },
55890 + { SA_COMP, "comp" },
55891 + { SA_INT, "int" },
55892 + { 0, NULL }
55893 +};
55894 +
55895 +/*
55896 + - satot - convert SA to text "ah507@1.2.3.4"
55897 + */
55898 +size_t /* space needed for full conversion */
55899 +satot(sa, format, dst, dstlen)
55900 +const ip_said *sa;
55901 +int format; /* character */
55902 +char *dst; /* need not be valid if dstlen is 0 */
55903 +size_t dstlen;
55904 +{
55905 + size_t len = 0; /* 0 means "not recognized yet" */
55906 + int base;
55907 + int showversion; /* use delimiter to show IP version? */
55908 + struct typename *tn;
55909 + char *p;
55910 + char *pre;
55911 + char buf[10+1+ULTOT_BUF+ADDRTOT_BUF];
55912 + char unk[10];
55913 +
55914 + switch (format) {
55915 + case 0:
55916 + base = 16;
55917 + showversion = 1;
55918 + break;
55919 + case 'f':
55920 + base = 17;
55921 + showversion = 1;
55922 + break;
55923 + case 'x':
55924 + base = 'x';
55925 + showversion = 0;
55926 + break;
55927 + case 'd':
55928 + base = 10;
55929 + showversion = 0;
55930 + break;
55931 + default:
55932 + return 0;
55933 + break;
55934 + }
55935 +
55936 + memset(buf, 0, sizeof(buf));
55937 +
55938 + pre = NULL;
55939 + for (tn = typenames; tn->name != NULL; tn++)
55940 + if (sa->proto == tn->type) {
55941 + pre = tn->name;
55942 + break; /* NOTE BREAK OUT */
55943 + }
55944 + if (pre == NULL) { /* unknown protocol */
55945 + strcpy(unk, "unk");
55946 + (void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk),
55947 + sizeof(unk)-strlen(unk));
55948 + pre = unk;
55949 + }
55950 +
55951 + if (strcmp(pre, PASSTHROUGHTYPE) == 0 &&
55952 + sa->spi == PASSTHROUGHSPI &&
55953 + isunspecaddr(&sa->dst)) {
55954 + strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ?
55955 + PASSTHROUGH4NAME :
55956 + PASSTHROUGH6NAME);
55957 + len = strlen(buf);
55958 + }
55959 +
55960 + if (sa->proto == SA_INT) {
55961 + char intunk[10];
55962 + switch (ntohl(sa->spi)) {
55963 + case SPI_PASS: p = "%pass"; break;
55964 + case SPI_DROP: p = "%drop"; break;
55965 + case SPI_REJECT: p = "%reject"; break;
55966 + case SPI_HOLD: p = "%hold"; break;
55967 + case SPI_TRAP: p = "%trap"; break;
55968 + case SPI_TRAPSUBNET: p = "%trapsubnet"; break;
55969 + default: snprintf(intunk, 10, "%%unk-%d", ntohl(sa->spi)); p = intunk; break;
55970 + }
55971 + if (p != NULL) {
55972 + strcpy(buf, p);
55973 + len = strlen(buf);
55974 + }
55975 + }
55976 +
55977 + if (len == 0) { /* general case needed */
55978 + strcpy(buf, pre);
55979 + len = strlen(buf);
55980 + if (showversion) {
55981 + *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' :
55982 + ':';
55983 + len++;
55984 + *(buf+len) = '\0';
55985 + }
55986 + len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len);
55987 + *(buf+len-1) = '@';
55988 + len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len);
55989 + *(buf+len) = '\0';
55990 + }
55991 +
55992 + if (dst != NULL) {
55993 + if (len > dstlen)
55994 + *(buf+dstlen-1) = '\0';
55995 + strcpy(dst, buf);
55996 + }
55997 + return len;
55998 +}
55999 --- /dev/null Tue Mar 11 13:02:56 2003
56000 +++ linux/net/ipsec/subnetof.c Mon Feb 9 13:51:03 2004
56001 @@ -0,0 +1,59 @@
56002 +/*
56003 + * minor network-address manipulation utilities
56004 + * Copyright (C) 1998, 1999 Henry Spencer.
56005 + *
56006 + * This library is free software; you can redistribute it and/or modify it
56007 + * under the terms of the GNU Library General Public License as published by
56008 + * the Free Software Foundation; either version 2 of the License, or (at your
56009 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
56010 + *
56011 + * This library is distributed in the hope that it will be useful, but
56012 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
56013 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
56014 + * License for more details.
56015 + *
56016 + * RCSID $Id: subnetof.c,v 1.8 2004/07/10 07:48:37 mcr Exp $
56017 + */
56018 +#include "openswan.h"
56019 +
56020 +/*
56021 + - subnetof - given address and mask, return subnet part
56022 + */
56023 +struct in_addr
56024 +subnetof(addr, mask)
56025 +struct in_addr addr;
56026 +struct in_addr mask;
56027 +{
56028 + struct in_addr result;
56029 +
56030 + result.s_addr = addr.s_addr & mask.s_addr;
56031 + return result;
56032 +}
56033 +
56034 +/*
56035 + - hostof - given address and mask, return host part
56036 + */
56037 +struct in_addr
56038 +hostof(addr, mask)
56039 +struct in_addr addr;
56040 +struct in_addr mask;
56041 +{
56042 + struct in_addr result;
56043 +
56044 + result.s_addr = addr.s_addr & ~mask.s_addr;
56045 + return result;
56046 +}
56047 +
56048 +/*
56049 + - broadcastof - given (network) address and mask, return broadcast address
56050 + */
56051 +struct in_addr
56052 +broadcastof(addr, mask)
56053 +struct in_addr addr;
56054 +struct in_addr mask;
56055 +{
56056 + struct in_addr result;
56057 +
56058 + result.s_addr = addr.s_addr | ~mask.s_addr;
56059 + return result;
56060 +}
56061 --- /dev/null Tue Mar 11 13:02:56 2003
56062 +++ linux/net/ipsec/subnettoa.c Mon Feb 9 13:51:03 2004
56063 @@ -0,0 +1,61 @@
56064 +/*
56065 + * convert binary form of subnet description to ASCII
56066 + * Copyright (C) 1998, 1999 Henry Spencer.
56067 + *
56068 + * This library is free software; you can redistribute it and/or modify it
56069 + * under the terms of the GNU Library General Public License as published by
56070 + * the Free Software Foundation; either version 2 of the License, or (at your
56071 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
56072 + *
56073 + * This library is distributed in the hope that it will be useful, but
56074 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
56075 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
56076 + * License for more details.
56077 + *
56078 + * RCSID $Id: subnettoa.c,v 1.11 2004/07/10 07:48:37 mcr Exp $
56079 + */
56080 +#include "openswan.h"
56081 +
56082 +/*
56083 + - subnettoa - convert address and mask to ASCII "addr/mask"
56084 + * Output expresses the mask as a bit count if possible, else dotted decimal.
56085 + */
56086 +size_t /* space needed for full conversion */
56087 +subnettoa(addr, mask, format, dst, dstlen)
56088 +struct in_addr addr;
56089 +struct in_addr mask;
56090 +int format; /* character */
56091 +char *dst; /* need not be valid if dstlen is 0 */
56092 +size_t dstlen;
56093 +{
56094 + size_t len;
56095 + size_t rest;
56096 + int n;
56097 + char *p;
56098 +
56099 + switch (format) {
56100 + case 0:
56101 + break;
56102 + default:
56103 + return 0;
56104 + break;
56105 + }
56106 +
56107 + len = addrtoa(addr, 0, dst, dstlen);
56108 + if (len < dstlen) {
56109 + dst[len - 1] = '/';
56110 + p = dst + len;
56111 + rest = dstlen - len;
56112 + } else {
56113 + p = NULL;
56114 + rest = 0;
56115 + }
56116 +
56117 + n = masktobits(mask);
56118 + if (n >= 0)
56119 + len += ultoa((unsigned long)n, 10, p, rest);
56120 + else
56121 + len += addrtoa(mask, 0, p, rest);
56122 +
56123 + return len;
56124 +}
56125 --- /dev/null Tue Mar 11 13:02:56 2003
56126 +++ linux/net/ipsec/sysctl_net_ipsec.c Mon Feb 9 13:51:03 2004
56127 @@ -0,0 +1,199 @@
56128 +/*
56129 + * sysctl interface to net IPSEC subsystem.
56130 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
56131 + *
56132 + * This program is free software; you can redistribute it and/or modify it
56133 + * under the terms of the GNU General Public License as published by the
56134 + * Free Software Foundation; either version 2 of the License, or (at your
56135 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
56136 + *
56137 + * This program is distributed in the hope that it will be useful, but
56138 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
56139 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
56140 + * for more details.
56141 + *
56142 + * RCSID $Id: sysctl_net_ipsec.c,v 1.17 2004/07/10 19:11:18 mcr Exp $
56143 + */
56144 +
56145 +/* -*- linux-c -*-
56146 + *
56147 + * Initiated April 3, 1998, Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
56148 + */
56149 +
56150 +#include <linux/mm.h>
56151 +#include <linux/sysctl.h>
56152 +
56153 +#include "openswan/ipsec_param.h"
56154 +
56155 +#ifdef CONFIG_SYSCTL
56156 +
56157 +#define NET_IPSEC 2112 /* Random number */
56158 +#ifdef CONFIG_KLIPS_DEBUG
56159 +extern int debug_ah;
56160 +extern int debug_esp;
56161 +extern int debug_tunnel;
56162 +extern int debug_eroute;
56163 +extern int debug_spi;
56164 +extern int debug_radij;
56165 +extern int debug_netlink;
56166 +extern int debug_xform;
56167 +extern int debug_rcv;
56168 +extern int debug_pfkey;
56169 +extern int sysctl_ipsec_debug_verbose;
56170 +#ifdef CONFIG_KLIPS_IPCOMP
56171 +extern int sysctl_ipsec_debug_ipcomp;
56172 +#endif /* CONFIG_KLIPS_IPCOMP */
56173 +#endif /* CONFIG_KLIPS_DEBUG */
56174 +
56175 +extern int sysctl_ipsec_icmp;
56176 +extern int sysctl_ipsec_inbound_policy_check;
56177 +extern int sysctl_ipsec_tos;
56178 +int sysctl_ipsec_regress_pfkey_lossage;
56179 +
56180 +enum {
56181 +#ifdef CONFIG_KLIPS_DEBUG
56182 + NET_IPSEC_DEBUG_AH=1,
56183 + NET_IPSEC_DEBUG_ESP=2,
56184 + NET_IPSEC_DEBUG_TUNNEL=3,
56185 + NET_IPSEC_DEBUG_EROUTE=4,
56186 + NET_IPSEC_DEBUG_SPI=5,
56187 + NET_IPSEC_DEBUG_RADIJ=6,
56188 + NET_IPSEC_DEBUG_NETLINK=7,
56189 + NET_IPSEC_DEBUG_XFORM=8,
56190 + NET_IPSEC_DEBUG_RCV=9,
56191 + NET_IPSEC_DEBUG_PFKEY=10,
56192 + NET_IPSEC_DEBUG_VERBOSE=11,
56193 + NET_IPSEC_DEBUG_IPCOMP=12,
56194 +#endif /* CONFIG_KLIPS_DEBUG */
56195 + NET_IPSEC_ICMP=13,
56196 + NET_IPSEC_INBOUND_POLICY_CHECK=14,
56197 + NET_IPSEC_TOS=15,
56198 + NET_IPSEC_REGRESS_PFKEY_LOSSAGE=16,
56199 +};
56200 +
56201 +static ctl_table ipsec_table[] = {
56202 +#ifdef CONFIG_KLIPS_DEBUG
56203 + { NET_IPSEC_DEBUG_AH, "debug_ah", &debug_ah,
56204 + sizeof(int), 0644, NULL, &proc_dointvec},
56205 + { NET_IPSEC_DEBUG_ESP, "debug_esp", &debug_esp,
56206 + sizeof(int), 0644, NULL, &proc_dointvec},
56207 + { NET_IPSEC_DEBUG_TUNNEL, "debug_tunnel", &debug_tunnel,
56208 + sizeof(int), 0644, NULL, &proc_dointvec},
56209 + { NET_IPSEC_DEBUG_EROUTE, "debug_eroute", &debug_eroute,
56210 + sizeof(int), 0644, NULL, &proc_dointvec},
56211 + { NET_IPSEC_DEBUG_SPI, "debug_spi", &debug_spi,
56212 + sizeof(int), 0644, NULL, &proc_dointvec},
56213 + { NET_IPSEC_DEBUG_RADIJ, "debug_radij", &debug_radij,
56214 + sizeof(int), 0644, NULL, &proc_dointvec},
56215 + { NET_IPSEC_DEBUG_NETLINK, "debug_netlink", &debug_netlink,
56216 + sizeof(int), 0644, NULL, &proc_dointvec},
56217 + { NET_IPSEC_DEBUG_XFORM, "debug_xform", &debug_xform,
56218 + sizeof(int), 0644, NULL, &proc_dointvec},
56219 + { NET_IPSEC_DEBUG_RCV, "debug_rcv", &debug_rcv,
56220 + sizeof(int), 0644, NULL, &proc_dointvec},
56221 + { NET_IPSEC_DEBUG_PFKEY, "debug_pfkey", &debug_pfkey,
56222 + sizeof(int), 0644, NULL, &proc_dointvec},
56223 + { NET_IPSEC_DEBUG_VERBOSE, "debug_verbose",&sysctl_ipsec_debug_verbose,
56224 + sizeof(int), 0644, NULL, &proc_dointvec},
56225 +#ifdef CONFIG_KLIPS_IPCOMP
56226 + { NET_IPSEC_DEBUG_IPCOMP, "debug_ipcomp", &sysctl_ipsec_debug_ipcomp,
56227 + sizeof(int), 0644, NULL, &proc_dointvec},
56228 +#endif /* CONFIG_KLIPS_IPCOMP */
56229 +
56230 +#ifdef CONFIG_KLIPS_REGRESS
56231 + { NET_IPSEC_REGRESS_PFKEY_LOSSAGE, "pfkey_lossage",
56232 + &sysctl_ipsec_regress_pfkey_lossage,
56233 + sizeof(int), 0644, NULL, &proc_dointvec},
56234 +#endif /* CONFIG_KLIPS_REGRESS */
56235 +
56236 +#endif /* CONFIG_KLIPS_DEBUG */
56237 + { NET_IPSEC_ICMP, "icmp", &sysctl_ipsec_icmp,
56238 + sizeof(int), 0644, NULL, &proc_dointvec},
56239 + { NET_IPSEC_INBOUND_POLICY_CHECK, "inbound_policy_check", &sysctl_ipsec_inbound_policy_check,
56240 + sizeof(int), 0644, NULL, &proc_dointvec},
56241 + { NET_IPSEC_TOS, "tos", &sysctl_ipsec_tos,
56242 + sizeof(int), 0644, NULL, &proc_dointvec},
56243 + {0}
56244 +};
56245 +
56246 +static ctl_table ipsec_net_table[] = {
56247 + { NET_IPSEC, "ipsec", NULL, 0, 0555, ipsec_table },
56248 + { 0 }
56249 +};
56250 +
56251 +static ctl_table ipsec_root_table[] = {
56252 + { CTL_NET, "net", NULL, 0, 0555, ipsec_net_table },
56253 + { 0 }
56254 +};
56255 +
56256 +static struct ctl_table_header *ipsec_table_header;
56257 +
56258 +int ipsec_sysctl_register(void)
56259 +{
56260 + ipsec_table_header = register_sysctl_table(ipsec_root_table, 0);
56261 + if (!ipsec_table_header) {
56262 + return -ENOMEM;
56263 + }
56264 + return 0;
56265 +}
56266 +
56267 +void ipsec_sysctl_unregister(void)
56268 +{
56269 + unregister_sysctl_table(ipsec_table_header);
56270 +}
56271 +
56272 +#endif /* CONFIG_SYSCTL */
56273 +
56274 +/*
56275 + * $Log: sysctl_net_ipsec.c,v $
56276 + * Revision 1.17 2004/07/10 19:11:18 mcr
56277 + * CONFIG_IPSEC -> CONFIG_KLIPS.
56278 + *
56279 + * Revision 1.16 2004/04/06 02:49:26 mcr
56280 + * pullup of algo code from alg-branch.
56281 + *
56282 + * Revision 1.15 2002/04/24 07:55:32 mcr
56283 + * #include patches and Makefiles for post-reorg compilation.
56284 + *
56285 + * Revision 1.14 2002/04/24 07:36:35 mcr
56286 + * Moved from ./klips/net/ipsec/sysctl_net_ipsec.c,v
56287 + *
56288 + * Revision 1.13 2002/01/12 02:58:32 mcr
56289 + * first regression test causes acquire messages to be lost
56290 + * 100% of the time. This is to help testing of pluto.
56291 + *
56292 + * Revision 1.12 2001/06/14 19:35:13 rgb
56293 + * Update copyright date.
56294 + *
56295 + * Revision 1.11 2001/02/26 19:58:13 rgb
56296 + * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
56297 + *
56298 + * Revision 1.10 2000/09/16 01:50:15 rgb
56299 + * Protect sysctl_ipsec_debug_ipcomp with compiler defines too so that the
56300 + * linker won't blame rj_delete() for missing symbols. ;-> Damn statics...
56301 + *
56302 + * Revision 1.9 2000/09/15 23:17:51 rgb
56303 + * Moved stuff around to compile with debug off.
56304 + *
56305 + * Revision 1.8 2000/09/15 11:37:02 rgb
56306 + * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
56307 + * IPCOMP zlib deflate code.
56308 + *
56309 + * Revision 1.7 2000/09/15 07:37:15 rgb
56310 + * Munged silly log comment that was causing a warning.
56311 + *
56312 + * Revision 1.6 2000/09/15 04:58:23 rgb
56313 + * Added tos runtime switch.
56314 + * Removed 'sysctl_ipsec_' prefix from /proc/sys/net/ipsec/ filenames.
56315 + *
56316 + * Revision 1.5 2000/09/12 03:25:28 rgb
56317 + * Filled in and implemented sysctl.
56318 + *
56319 + * Revision 1.4 1999/04/11 00:29:03 henry
56320 + * GPL boilerplate
56321 + *
56322 + * Revision 1.3 1999/04/06 04:54:29 rgb
56323 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
56324 + * patch shell fixes.
56325 + *
56326 + */
56327 --- /dev/null Tue Mar 11 13:02:56 2003
56328 +++ linux/net/ipsec/trees.c Mon Feb 9 13:51:03 2004
56329 @@ -0,0 +1,1214 @@
56330 +/* trees.c -- output deflated data using Huffman coding
56331 + * Copyright (C) 1995-2002 Jean-loup Gailly
56332 + * For conditions of distribution and use, see copyright notice in zlib.h
56333 + */
56334 +
56335 +/*
56336 + * ALGORITHM
56337 + *
56338 + * The "deflation" process uses several Huffman trees. The more
56339 + * common source values are represented by shorter bit sequences.
56340 + *
56341 + * Each code tree is stored in a compressed form which is itself
56342 + * a Huffman encoding of the lengths of all the code strings (in
56343 + * ascending order by source values). The actual code strings are
56344 + * reconstructed from the lengths in the inflate process, as described
56345 + * in the deflate specification.
56346 + *
56347 + * REFERENCES
56348 + *
56349 + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
56350 + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
56351 + *
56352 + * Storer, James A.
56353 + * Data Compression: Methods and Theory, pp. 49-50.
56354 + * Computer Science Press, 1988. ISBN 0-7167-8156-5.
56355 + *
56356 + * Sedgewick, R.
56357 + * Algorithms, p290.
56358 + * Addison-Wesley, 1983. ISBN 0-201-06672-6.
56359 + */
56360 +
56361 +/* @(#) $Id: trees.c,v 1.4 2004/07/10 07:48:39 mcr Exp $ */
56362 +
56363 +/* #define GEN_TREES_H */
56364 +
56365 +#include "deflate.h"
56366 +
56367 +#ifdef DEBUG
56368 +# include <ctype.h>
56369 +#endif
56370 +
56371 +/* ===========================================================================
56372 + * Constants
56373 + */
56374 +
56375 +#define MAX_BL_BITS 7
56376 +/* Bit length codes must not exceed MAX_BL_BITS bits */
56377 +
56378 +#define END_BLOCK 256
56379 +/* end of block literal code */
56380 +
56381 +#define REP_3_6 16
56382 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */
56383 +
56384 +#define REPZ_3_10 17
56385 +/* repeat a zero length 3-10 times (3 bits of repeat count) */
56386 +
56387 +#define REPZ_11_138 18
56388 +/* repeat a zero length 11-138 times (7 bits of repeat count) */
56389 +
56390 +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
56391 + = {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};
56392 +
56393 +local const int extra_dbits[D_CODES] /* extra bits for each distance code */
56394 + = {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};
56395 +
56396 +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
56397 + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
56398 +
56399 +local const uch bl_order[BL_CODES]
56400 + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
56401 +/* The lengths of the bit length codes are sent in order of decreasing
56402 + * probability, to avoid transmitting the lengths for unused bit length codes.
56403 + */
56404 +
56405 +#define Buf_size (8 * 2*sizeof(char))
56406 +/* Number of bits used within bi_buf. (bi_buf might be implemented on
56407 + * more than 16 bits on some systems.)
56408 + */
56409 +
56410 +/* ===========================================================================
56411 + * Local data. These are initialized only once.
56412 + */
56413 +
56414 +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
56415 +
56416 +#if defined(GEN_TREES_H) || !defined(STDC)
56417 +/* non ANSI compilers may not accept trees.h */
56418 +
56419 +local ct_data static_ltree[L_CODES+2];
56420 +/* The static literal tree. Since the bit lengths are imposed, there is no
56421 + * need for the L_CODES extra codes used during heap construction. However
56422 + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
56423 + * below).
56424 + */
56425 +
56426 +local ct_data static_dtree[D_CODES];
56427 +/* The static distance tree. (Actually a trivial tree since all codes use
56428 + * 5 bits.)
56429 + */
56430 +
56431 +uch _dist_code[DIST_CODE_LEN];
56432 +/* Distance codes. The first 256 values correspond to the distances
56433 + * 3 .. 258, the last 256 values correspond to the top 8 bits of
56434 + * the 15 bit distances.
56435 + */
56436 +
56437 +uch _length_code[MAX_MATCH-MIN_MATCH+1];
56438 +/* length code for each normalized match length (0 == MIN_MATCH) */
56439 +
56440 +local int base_length[LENGTH_CODES];
56441 +/* First normalized length for each code (0 = MIN_MATCH) */
56442 +
56443 +local int base_dist[D_CODES];
56444 +/* First normalized distance for each code (0 = distance of 1) */
56445 +
56446 +#else
56447 +# include "trees.h"
56448 +#endif /* GEN_TREES_H */
56449 +
56450 +struct static_tree_desc_s {
56451 + const ct_data *static_tree; /* static tree or NULL */
56452 + const intf *extra_bits; /* extra bits for each code or NULL */
56453 + int extra_base; /* base index for extra_bits */
56454 + int elems; /* max number of elements in the tree */
56455 + int max_length; /* max bit length for the codes */
56456 +};
56457 +
56458 +local static_tree_desc static_l_desc =
56459 +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
56460 +
56461 +local static_tree_desc static_d_desc =
56462 +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
56463 +
56464 +local static_tree_desc static_bl_desc =
56465 +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
56466 +
56467 +/* ===========================================================================
56468 + * Local (static) routines in this file.
56469 + */
56470 +
56471 +local void tr_static_init OF((void));
56472 +local void init_block OF((deflate_state *s));
56473 +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
56474 +local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
56475 +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
56476 +local void build_tree OF((deflate_state *s, tree_desc *desc));
56477 +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
56478 +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
56479 +local int build_bl_tree OF((deflate_state *s));
56480 +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
56481 + int blcodes));
56482 +local void compress_block OF((deflate_state *s, const ct_data *ltree,
56483 + const ct_data *dtree));
56484 +local void set_data_type OF((deflate_state *s));
56485 +local unsigned bi_reverse OF((unsigned value, int length));
56486 +local void bi_windup OF((deflate_state *s));
56487 +local void bi_flush OF((deflate_state *s));
56488 +local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
56489 + int header));
56490 +
56491 +#ifdef GEN_TREES_H
56492 +local void gen_trees_header OF((void));
56493 +#endif
56494 +
56495 +#ifndef DEBUG
56496 +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
56497 + /* Send a code of the given tree. c and tree must not have side effects */
56498 +
56499 +#else /* DEBUG */
56500 +# define send_code(s, c, tree) \
56501 + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
56502 + send_bits(s, tree[c].Code, tree[c].Len); }
56503 +#endif
56504 +
56505 +/* ===========================================================================
56506 + * Output a short LSB first on the stream.
56507 + * IN assertion: there is enough room in pendingBuf.
56508 + */
56509 +#define put_short(s, w) { \
56510 + put_byte(s, (uch)((w) & 0xff)); \
56511 + put_byte(s, (uch)((ush)(w) >> 8)); \
56512 +}
56513 +
56514 +/* ===========================================================================
56515 + * Send a value on a given number of bits.
56516 + * IN assertion: length <= 16 and value fits in length bits.
56517 + */
56518 +#ifdef DEBUG
56519 +local void send_bits OF((deflate_state *s, int value, int length));
56520 +
56521 +local void send_bits(s, value, length)
56522 + deflate_state *s;
56523 + int value; /* value to send */
56524 + int length; /* number of bits */
56525 +{
56526 + Tracevv((stderr," l %2d v %4x ", length, value));
56527 + Assert(length > 0 && length <= 15, "invalid length");
56528 + s->bits_sent += (ulg)length;
56529 +
56530 + /* If not enough room in bi_buf, use (valid) bits from bi_buf and
56531 + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
56532 + * unused bits in value.
56533 + */
56534 + if (s->bi_valid > (int)Buf_size - length) {
56535 + s->bi_buf |= (value << s->bi_valid);
56536 + put_short(s, s->bi_buf);
56537 + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
56538 + s->bi_valid += length - Buf_size;
56539 + } else {
56540 + s->bi_buf |= value << s->bi_valid;
56541 + s->bi_valid += length;
56542 + }
56543 +}
56544 +#else /* !DEBUG */
56545 +
56546 +#define send_bits(s, value, length) \
56547 +{ int len = length;\
56548 + if (s->bi_valid > (int)Buf_size - len) {\
56549 + int val = value;\
56550 + s->bi_buf |= (val << s->bi_valid);\
56551 + put_short(s, s->bi_buf);\
56552 + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
56553 + s->bi_valid += len - Buf_size;\
56554 + } else {\
56555 + s->bi_buf |= (value) << s->bi_valid;\
56556 + s->bi_valid += len;\
56557 + }\
56558 +}
56559 +#endif /* DEBUG */
56560 +
56561 +
56562 +#define MAX(a,b) (a >= b ? a : b)
56563 +/* the arguments must not have side effects */
56564 +
56565 +/* ===========================================================================
56566 + * Initialize the various 'constant' tables.
56567 + */
56568 +local void tr_static_init()
56569 +{
56570 +#if defined(GEN_TREES_H) || !defined(STDC)
56571 + static int static_init_done = 0;
56572 + int n; /* iterates over tree elements */
56573 + int bits; /* bit counter */
56574 + int length; /* length value */
56575 + int code; /* code value */
56576 + int dist; /* distance index */
56577 + ush bl_count[MAX_BITS+1];
56578 + /* number of codes at each bit length for an optimal tree */
56579 +
56580 + if (static_init_done) return;
56581 +
56582 + /* For some embedded targets, global variables are not initialized: */
56583 + static_l_desc.static_tree = static_ltree;
56584 + static_l_desc.extra_bits = extra_lbits;
56585 + static_d_desc.static_tree = static_dtree;
56586 + static_d_desc.extra_bits = extra_dbits;
56587 + static_bl_desc.extra_bits = extra_blbits;
56588 +
56589 + /* Initialize the mapping length (0..255) -> length code (0..28) */
56590 + length = 0;
56591 + for (code = 0; code < LENGTH_CODES-1; code++) {
56592 + base_length[code] = length;
56593 + for (n = 0; n < (1<<extra_lbits[code]); n++) {
56594 + _length_code[length++] = (uch)code;
56595 + }
56596 + }
56597 + Assert (length == 256, "tr_static_init: length != 256");
56598 + /* Note that the length 255 (match length 258) can be represented
56599 + * in two different ways: code 284 + 5 bits or code 285, so we
56600 + * overwrite length_code[255] to use the best encoding:
56601 + */
56602 + _length_code[length-1] = (uch)code;
56603 +
56604 + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
56605 + dist = 0;
56606 + for (code = 0 ; code < 16; code++) {
56607 + base_dist[code] = dist;
56608 + for (n = 0; n < (1<<extra_dbits[code]); n++) {
56609 + _dist_code[dist++] = (uch)code;
56610 + }
56611 + }
56612 + Assert (dist == 256, "tr_static_init: dist != 256");
56613 + dist >>= 7; /* from now on, all distances are divided by 128 */
56614 + for ( ; code < D_CODES; code++) {
56615 + base_dist[code] = dist << 7;
56616 + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
56617 + _dist_code[256 + dist++] = (uch)code;
56618 + }
56619 + }
56620 + Assert (dist == 256, "tr_static_init: 256+dist != 512");
56621 +
56622 + /* Construct the codes of the static literal tree */
56623 + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
56624 + n = 0;
56625 + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
56626 + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
56627 + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
56628 + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
56629 + /* Codes 286 and 287 do not exist, but we must include them in the
56630 + * tree construction to get a canonical Huffman tree (longest code
56631 + * all ones)
56632 + */
56633 + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
56634 +
56635 + /* The static distance tree is trivial: */
56636 + for (n = 0; n < D_CODES; n++) {
56637 + static_dtree[n].Len = 5;
56638 + static_dtree[n].Code = bi_reverse((unsigned)n, 5);
56639 + }
56640 + static_init_done = 1;
56641 +
56642 +# ifdef GEN_TREES_H
56643 + gen_trees_header();
56644 +# endif
56645 +#endif /* defined(GEN_TREES_H) || !defined(STDC) */
56646 +}
56647 +
56648 +/* ===========================================================================
56649 + * Genererate the file trees.h describing the static trees.
56650 + */
56651 +#ifdef GEN_TREES_H
56652 +# ifndef DEBUG
56653 +# include <stdio.h>
56654 +# endif
56655 +
56656 +# define SEPARATOR(i, last, width) \
56657 + ((i) == (last)? "\n};\n\n" : \
56658 + ((i) % (width) == (width)-1 ? ",\n" : ", "))
56659 +
56660 +void gen_trees_header()
56661 +{
56662 + FILE *header = fopen("trees.h", "w");
56663 + int i;
56664 +
56665 + Assert (header != NULL, "Can't open trees.h");
56666 + fprintf(header,
56667 + "/* header created automatically with -DGEN_TREES_H */\n\n");
56668 +
56669 + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
56670 + for (i = 0; i < L_CODES+2; i++) {
56671 + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
56672 + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
56673 + }
56674 +
56675 + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
56676 + for (i = 0; i < D_CODES; i++) {
56677 + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
56678 + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
56679 + }
56680 +
56681 + fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
56682 + for (i = 0; i < DIST_CODE_LEN; i++) {
56683 + fprintf(header, "%2u%s", _dist_code[i],
56684 + SEPARATOR(i, DIST_CODE_LEN-1, 20));
56685 + }
56686 +
56687 + fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
56688 + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
56689 + fprintf(header, "%2u%s", _length_code[i],
56690 + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
56691 + }
56692 +
56693 + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
56694 + for (i = 0; i < LENGTH_CODES; i++) {
56695 + fprintf(header, "%1u%s", base_length[i],
56696 + SEPARATOR(i, LENGTH_CODES-1, 20));
56697 + }
56698 +
56699 + fprintf(header, "local const int base_dist[D_CODES] = {\n");
56700 + for (i = 0; i < D_CODES; i++) {
56701 + fprintf(header, "%5u%s", base_dist[i],
56702 + SEPARATOR(i, D_CODES-1, 10));
56703 + }
56704 +
56705 + fclose(header);
56706 +}
56707 +#endif /* GEN_TREES_H */
56708 +
56709 +/* ===========================================================================
56710 + * Initialize the tree data structures for a new zlib stream.
56711 + */
56712 +void _tr_init(s)
56713 + deflate_state *s;
56714 +{
56715 + tr_static_init();
56716 +
56717 + s->l_desc.dyn_tree = s->dyn_ltree;
56718 + s->l_desc.stat_desc = &static_l_desc;
56719 +
56720 + s->d_desc.dyn_tree = s->dyn_dtree;
56721 + s->d_desc.stat_desc = &static_d_desc;
56722 +
56723 + s->bl_desc.dyn_tree = s->bl_tree;
56724 + s->bl_desc.stat_desc = &static_bl_desc;
56725 +
56726 + s->bi_buf = 0;
56727 + s->bi_valid = 0;
56728 + s->last_eob_len = 8; /* enough lookahead for inflate */
56729 +#ifdef DEBUG
56730 + s->compressed_len = 0L;
56731 + s->bits_sent = 0L;
56732 +#endif
56733 +
56734 + /* Initialize the first block of the first file: */
56735 + init_block(s);
56736 +}
56737 +
56738 +/* ===========================================================================
56739 + * Initialize a new block.
56740 + */
56741 +local void init_block(s)
56742 + deflate_state *s;
56743 +{
56744 + int n; /* iterates over tree elements */
56745 +
56746 + /* Initialize the trees. */
56747 + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
56748 + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
56749 + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
56750 +
56751 + s->dyn_ltree[END_BLOCK].Freq = 1;
56752 + s->opt_len = s->static_len = 0L;
56753 + s->last_lit = s->matches = 0;
56754 +}
56755 +
56756 +#define SMALLEST 1
56757 +/* Index within the heap array of least frequent node in the Huffman tree */
56758 +
56759 +
56760 +/* ===========================================================================
56761 + * Remove the smallest element from the heap and recreate the heap with
56762 + * one less element. Updates heap and heap_len.
56763 + */
56764 +#define pqremove(s, tree, top) \
56765 +{\
56766 + top = s->heap[SMALLEST]; \
56767 + s->heap[SMALLEST] = s->heap[s->heap_len--]; \
56768 + pqdownheap(s, tree, SMALLEST); \
56769 +}
56770 +
56771 +/* ===========================================================================
56772 + * Compares to subtrees, using the tree depth as tie breaker when
56773 + * the subtrees have equal frequency. This minimizes the worst case length.
56774 + */
56775 +#define smaller(tree, n, m, depth) \
56776 + (tree[n].Freq < tree[m].Freq || \
56777 + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
56778 +
56779 +/* ===========================================================================
56780 + * Restore the heap property by moving down the tree starting at node k,
56781 + * exchanging a node with the smallest of its two sons if necessary, stopping
56782 + * when the heap property is re-established (each father smaller than its
56783 + * two sons).
56784 + */
56785 +local void pqdownheap(s, tree, k)
56786 + deflate_state *s;
56787 + ct_data *tree; /* the tree to restore */
56788 + int k; /* node to move down */
56789 +{
56790 + int v = s->heap[k];
56791 + int j = k << 1; /* left son of k */
56792 + while (j <= s->heap_len) {
56793 + /* Set j to the smallest of the two sons: */
56794 + if (j < s->heap_len &&
56795 + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
56796 + j++;
56797 + }
56798 + /* Exit if v is smaller than both sons */
56799 + if (smaller(tree, v, s->heap[j], s->depth)) break;
56800 +
56801 + /* Exchange v with the smallest son */
56802 + s->heap[k] = s->heap[j]; k = j;
56803 +
56804 + /* And continue down the tree, setting j to the left son of k */
56805 + j <<= 1;
56806 + }
56807 + s->heap[k] = v;
56808 +}
56809 +
56810 +/* ===========================================================================
56811 + * Compute the optimal bit lengths for a tree and update the total bit length
56812 + * for the current block.
56813 + * IN assertion: the fields freq and dad are set, heap[heap_max] and
56814 + * above are the tree nodes sorted by increasing frequency.
56815 + * OUT assertions: the field len is set to the optimal bit length, the
56816 + * array bl_count contains the frequencies for each bit length.
56817 + * The length opt_len is updated; static_len is also updated if stree is
56818 + * not null.
56819 + */
56820 +local void gen_bitlen(s, desc)
56821 + deflate_state *s;
56822 + tree_desc *desc; /* the tree descriptor */
56823 +{
56824 + ct_data *tree = desc->dyn_tree;
56825 + int max_code = desc->max_code;
56826 + const ct_data *stree = desc->stat_desc->static_tree;
56827 + const intf *extra = desc->stat_desc->extra_bits;
56828 + int base = desc->stat_desc->extra_base;
56829 + int max_length = desc->stat_desc->max_length;
56830 + int h; /* heap index */
56831 + int n, m; /* iterate over the tree elements */
56832 + int bits; /* bit length */
56833 + int xbits; /* extra bits */
56834 + ush f; /* frequency */
56835 + int overflow = 0; /* number of elements with bit length too large */
56836 +
56837 + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
56838 +
56839 + /* In a first pass, compute the optimal bit lengths (which may
56840 + * overflow in the case of the bit length tree).
56841 + */
56842 + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
56843 +
56844 + for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
56845 + n = s->heap[h];
56846 + bits = tree[tree[n].Dad].Len + 1;
56847 + if (bits > max_length) bits = max_length, overflow++;
56848 + tree[n].Len = (ush)bits;
56849 + /* We overwrite tree[n].Dad which is no longer needed */
56850 +
56851 + if (n > max_code) continue; /* not a leaf node */
56852 +
56853 + s->bl_count[bits]++;
56854 + xbits = 0;
56855 + if (n >= base) xbits = extra[n-base];
56856 + f = tree[n].Freq;
56857 + s->opt_len += (ulg)f * (bits + xbits);
56858 + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
56859 + }
56860 + if (overflow == 0) return;
56861 +
56862 + Trace((stderr,"\nbit length overflow\n"));
56863 + /* This happens for example on obj2 and pic of the Calgary corpus */
56864 +
56865 + /* Find the first bit length which could increase: */
56866 + do {
56867 + bits = max_length-1;
56868 + while (s->bl_count[bits] == 0) bits--;
56869 + s->bl_count[bits]--; /* move one leaf down the tree */
56870 + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
56871 + s->bl_count[max_length]--;
56872 + /* The brother of the overflow item also moves one step up,
56873 + * but this does not affect bl_count[max_length]
56874 + */
56875 + overflow -= 2;
56876 + } while (overflow > 0);
56877 +
56878 + /* Now recompute all bit lengths, scanning in increasing frequency.
56879 + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
56880 + * lengths instead of fixing only the wrong ones. This idea is taken
56881 + * from 'ar' written by Haruhiko Okumura.)
56882 + */
56883 + for (bits = max_length; bits != 0; bits--) {
56884 + n = s->bl_count[bits];
56885 + while (n != 0) {
56886 + m = s->heap[--h];
56887 + if (m > max_code) continue;
56888 + if (tree[m].Len != (unsigned) bits) {
56889 + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
56890 + s->opt_len += ((long)bits - (long)tree[m].Len)
56891 + *(long)tree[m].Freq;
56892 + tree[m].Len = (ush)bits;
56893 + }
56894 + n--;
56895 + }
56896 + }
56897 +}
56898 +
56899 +/* ===========================================================================
56900 + * Generate the codes for a given tree and bit counts (which need not be
56901 + * optimal).
56902 + * IN assertion: the array bl_count contains the bit length statistics for
56903 + * the given tree and the field len is set for all tree elements.
56904 + * OUT assertion: the field code is set for all tree elements of non
56905 + * zero code length.
56906 + */
56907 +local void gen_codes (tree, max_code, bl_count)
56908 + ct_data *tree; /* the tree to decorate */
56909 + int max_code; /* largest code with non zero frequency */
56910 + ushf *bl_count; /* number of codes at each bit length */
56911 +{
56912 + ush next_code[MAX_BITS+1]; /* next code value for each bit length */
56913 + ush code = 0; /* running code value */
56914 + int bits; /* bit index */
56915 + int n; /* code index */
56916 +
56917 + /* The distribution counts are first used to generate the code values
56918 + * without bit reversal.
56919 + */
56920 + for (bits = 1; bits <= MAX_BITS; bits++) {
56921 + next_code[bits] = code = (code + bl_count[bits-1]) << 1;
56922 + }
56923 + /* Check that the bit counts in bl_count are consistent. The last code
56924 + * must be all ones.
56925 + */
56926 + Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
56927 + "inconsistent bit counts");
56928 + Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
56929 +
56930 + for (n = 0; n <= max_code; n++) {
56931 + int len = tree[n].Len;
56932 + if (len == 0) continue;
56933 + /* Now reverse the bits */
56934 + tree[n].Code = bi_reverse(next_code[len]++, len);
56935 +
56936 + Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
56937 + n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
56938 + }
56939 +}
56940 +
56941 +/* ===========================================================================
56942 + * Construct one Huffman tree and assigns the code bit strings and lengths.
56943 + * Update the total bit length for the current block.
56944 + * IN assertion: the field freq is set for all tree elements.
56945 + * OUT assertions: the fields len and code are set to the optimal bit length
56946 + * and corresponding code. The length opt_len is updated; static_len is
56947 + * also updated if stree is not null. The field max_code is set.
56948 + */
56949 +local void build_tree(s, desc)
56950 + deflate_state *s;
56951 + tree_desc *desc; /* the tree descriptor */
56952 +{
56953 + ct_data *tree = desc->dyn_tree;
56954 + const ct_data *stree = desc->stat_desc->static_tree;
56955 + int elems = desc->stat_desc->elems;
56956 + int n, m; /* iterate over heap elements */
56957 + int max_code = -1; /* largest code with non zero frequency */
56958 + int node; /* new node being created */
56959 +
56960 + /* Construct the initial heap, with least frequent element in
56961 + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
56962 + * heap[0] is not used.
56963 + */
56964 + s->heap_len = 0, s->heap_max = HEAP_SIZE;
56965 +
56966 + for (n = 0; n < elems; n++) {
56967 + if (tree[n].Freq != 0) {
56968 + s->heap[++(s->heap_len)] = max_code = n;
56969 + s->depth[n] = 0;
56970 + } else {
56971 + tree[n].Len = 0;
56972 + }
56973 + }
56974 +
56975 + /* The pkzip format requires that at least one distance code exists,
56976 + * and that at least one bit should be sent even if there is only one
56977 + * possible code. So to avoid special checks later on we force at least
56978 + * two codes of non zero frequency.
56979 + */
56980 + while (s->heap_len < 2) {
56981 + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
56982 + tree[node].Freq = 1;
56983 + s->depth[node] = 0;
56984 + s->opt_len--; if (stree) s->static_len -= stree[node].Len;
56985 + /* node is 0 or 1 so it does not have extra bits */
56986 + }
56987 + desc->max_code = max_code;
56988 +
56989 + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
56990 + * establish sub-heaps of increasing lengths:
56991 + */
56992 + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
56993 +
56994 + /* Construct the Huffman tree by repeatedly combining the least two
56995 + * frequent nodes.
56996 + */
56997 + node = elems; /* next internal node of the tree */
56998 + do {
56999 + pqremove(s, tree, n); /* n = node of least frequency */
57000 + m = s->heap[SMALLEST]; /* m = node of next least frequency */
57001 +
57002 + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
57003 + s->heap[--(s->heap_max)] = m;
57004 +
57005 + /* Create a new node father of n and m */
57006 + tree[node].Freq = tree[n].Freq + tree[m].Freq;
57007 + s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
57008 + tree[n].Dad = tree[m].Dad = (ush)node;
57009 +#ifdef DUMP_BL_TREE
57010 + if (tree == s->bl_tree) {
57011 + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
57012 + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
57013 + }
57014 +#endif
57015 + /* and insert the new node in the heap */
57016 + s->heap[SMALLEST] = node++;
57017 + pqdownheap(s, tree, SMALLEST);
57018 +
57019 + } while (s->heap_len >= 2);
57020 +
57021 + s->heap[--(s->heap_max)] = s->heap[SMALLEST];
57022 +
57023 + /* At this point, the fields freq and dad are set. We can now
57024 + * generate the bit lengths.
57025 + */
57026 + gen_bitlen(s, (tree_desc *)desc);
57027 +
57028 + /* The field len is now set, we can generate the bit codes */
57029 + gen_codes ((ct_data *)tree, max_code, s->bl_count);
57030 +}
57031 +
57032 +/* ===========================================================================
57033 + * Scan a literal or distance tree to determine the frequencies of the codes
57034 + * in the bit length tree.
57035 + */
57036 +local void scan_tree (s, tree, max_code)
57037 + deflate_state *s;
57038 + ct_data *tree; /* the tree to be scanned */
57039 + int max_code; /* and its largest code of non zero frequency */
57040 +{
57041 + int n; /* iterates over all tree elements */
57042 + int prevlen = -1; /* last emitted length */
57043 + int curlen; /* length of current code */
57044 + int nextlen = tree[0].Len; /* length of next code */
57045 + int count = 0; /* repeat count of the current code */
57046 + int max_count = 7; /* max repeat count */
57047 + int min_count = 4; /* min repeat count */
57048 +
57049 + if (nextlen == 0) max_count = 138, min_count = 3;
57050 + tree[max_code+1].Len = (ush)0xffff; /* guard */
57051 +
57052 + for (n = 0; n <= max_code; n++) {
57053 + curlen = nextlen; nextlen = tree[n+1].Len;
57054 + if (++count < max_count && curlen == nextlen) {
57055 + continue;
57056 + } else if (count < min_count) {
57057 + s->bl_tree[curlen].Freq += count;
57058 + } else if (curlen != 0) {
57059 + if (curlen != prevlen) s->bl_tree[curlen].Freq++;
57060 + s->bl_tree[REP_3_6].Freq++;
57061 + } else if (count <= 10) {
57062 + s->bl_tree[REPZ_3_10].Freq++;
57063 + } else {
57064 + s->bl_tree[REPZ_11_138].Freq++;
57065 + }
57066 + count = 0; prevlen = curlen;
57067 + if (nextlen == 0) {
57068 + max_count = 138, min_count = 3;
57069 + } else if (curlen == nextlen) {
57070 + max_count = 6, min_count = 3;
57071 + } else {
57072 + max_count = 7, min_count = 4;
57073 + }
57074 + }
57075 +}
57076 +
57077 +/* ===========================================================================
57078 + * Send a literal or distance tree in compressed form, using the codes in
57079 + * bl_tree.
57080 + */
57081 +local void send_tree (s, tree, max_code)
57082 + deflate_state *s;
57083 + ct_data *tree; /* the tree to be scanned */
57084 + int max_code; /* and its largest code of non zero frequency */
57085 +{
57086 + int n; /* iterates over all tree elements */
57087 + int prevlen = -1; /* last emitted length */
57088 + int curlen; /* length of current code */
57089 + int nextlen = tree[0].Len; /* length of next code */
57090 + int count = 0; /* repeat count of the current code */
57091 + int max_count = 7; /* max repeat count */
57092 + int min_count = 4; /* min repeat count */
57093 +
57094 + /* tree[max_code+1].Len = -1; */ /* guard already set */
57095 + if (nextlen == 0) max_count = 138, min_count = 3;
57096 +
57097 + for (n = 0; n <= max_code; n++) {
57098 + curlen = nextlen; nextlen = tree[n+1].Len;
57099 + if (++count < max_count && curlen == nextlen) {
57100 + continue;
57101 + } else if (count < min_count) {
57102 + do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
57103 +
57104 + } else if (curlen != 0) {
57105 + if (curlen != prevlen) {
57106 + send_code(s, curlen, s->bl_tree); count--;
57107 + }
57108 + Assert(count >= 3 && count <= 6, " 3_6?");
57109 + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
57110 +
57111 + } else if (count <= 10) {
57112 + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
57113 +
57114 + } else {
57115 + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
57116 + }
57117 + count = 0; prevlen = curlen;
57118 + if (nextlen == 0) {
57119 + max_count = 138, min_count = 3;
57120 + } else if (curlen == nextlen) {
57121 + max_count = 6, min_count = 3;
57122 + } else {
57123 + max_count = 7, min_count = 4;
57124 + }
57125 + }
57126 +}
57127 +
57128 +/* ===========================================================================
57129 + * Construct the Huffman tree for the bit lengths and return the index in
57130 + * bl_order of the last bit length code to send.
57131 + */
57132 +local int build_bl_tree(s)
57133 + deflate_state *s;
57134 +{
57135 + int max_blindex; /* index of last bit length code of non zero freq */
57136 +
57137 + /* Determine the bit length frequencies for literal and distance trees */
57138 + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
57139 + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
57140 +
57141 + /* Build the bit length tree: */
57142 + build_tree(s, (tree_desc *)(&(s->bl_desc)));
57143 + /* opt_len now includes the length of the tree representations, except
57144 + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
57145 + */
57146 +
57147 + /* Determine the number of bit length codes to send. The pkzip format
57148 + * requires that at least 4 bit length codes be sent. (appnote.txt says
57149 + * 3 but the actual value used is 4.)
57150 + */
57151 + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
57152 + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
57153 + }
57154 + /* Update opt_len to include the bit length tree and counts */
57155 + s->opt_len += 3*(max_blindex+1) + 5+5+4;
57156 + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
57157 + s->opt_len, s->static_len));
57158 +
57159 + return max_blindex;
57160 +}
57161 +
57162 +/* ===========================================================================
57163 + * Send the header for a block using dynamic Huffman trees: the counts, the
57164 + * lengths of the bit length codes, the literal tree and the distance tree.
57165 + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
57166 + */
57167 +local void send_all_trees(s, lcodes, dcodes, blcodes)
57168 + deflate_state *s;
57169 + int lcodes, dcodes, blcodes; /* number of codes for each tree */
57170 +{
57171 + int rank; /* index in bl_order */
57172 +
57173 + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
57174 + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
57175 + "too many codes");
57176 + Tracev((stderr, "\nbl counts: "));
57177 + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
57178 + send_bits(s, dcodes-1, 5);
57179 + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
57180 + for (rank = 0; rank < blcodes; rank++) {
57181 + Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
57182 + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
57183 + }
57184 + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
57185 +
57186 + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
57187 + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
57188 +
57189 + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
57190 + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
57191 +}
57192 +
57193 +/* ===========================================================================
57194 + * Send a stored block
57195 + */
57196 +void _tr_stored_block(s, buf, stored_len, eof)
57197 + deflate_state *s;
57198 + charf *buf; /* input block */
57199 + ulg stored_len; /* length of input block */
57200 + int eof; /* true if this is the last block for a file */
57201 +{
57202 + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
57203 +#ifdef DEBUG
57204 + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
57205 + s->compressed_len += (stored_len + 4) << 3;
57206 +#endif
57207 + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
57208 +}
57209 +
57210 +/* ===========================================================================
57211 + * Send one empty static block to give enough lookahead for inflate.
57212 + * This takes 10 bits, of which 7 may remain in the bit buffer.
57213 + * The current inflate code requires 9 bits of lookahead. If the
57214 + * last two codes for the previous block (real code plus EOB) were coded
57215 + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
57216 + * the last real code. In this case we send two empty static blocks instead
57217 + * of one. (There are no problems if the previous block is stored or fixed.)
57218 + * To simplify the code, we assume the worst case of last real code encoded
57219 + * on one bit only.
57220 + */
57221 +void _tr_align(s)
57222 + deflate_state *s;
57223 +{
57224 + send_bits(s, STATIC_TREES<<1, 3);
57225 + send_code(s, END_BLOCK, static_ltree);
57226 +#ifdef DEBUG
57227 + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
57228 +#endif
57229 + bi_flush(s);
57230 + /* Of the 10 bits for the empty block, we have already sent
57231 + * (10 - bi_valid) bits. The lookahead for the last real code (before
57232 + * the EOB of the previous block) was thus at least one plus the length
57233 + * of the EOB plus what we have just sent of the empty static block.
57234 + */
57235 + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
57236 + send_bits(s, STATIC_TREES<<1, 3);
57237 + send_code(s, END_BLOCK, static_ltree);
57238 +#ifdef DEBUG
57239 + s->compressed_len += 10L;
57240 +#endif
57241 + bi_flush(s);
57242 + }
57243 + s->last_eob_len = 7;
57244 +}
57245 +
57246 +/* ===========================================================================
57247 + * Determine the best encoding for the current block: dynamic trees, static
57248 + * trees or store, and output the encoded block to the zip file.
57249 + */
57250 +void _tr_flush_block(s, buf, stored_len, eof)
57251 + deflate_state *s;
57252 + charf *buf; /* input block, or NULL if too old */
57253 + ulg stored_len; /* length of input block */
57254 + int eof; /* true if this is the last block for a file */
57255 +{
57256 + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
57257 + int max_blindex = 0; /* index of last bit length code of non zero freq */
57258 +
57259 + /* Build the Huffman trees unless a stored block is forced */
57260 + if (s->level > 0) {
57261 +
57262 + /* Check if the file is ascii or binary */
57263 + if (s->data_type == Z_UNKNOWN) set_data_type(s);
57264 +
57265 + /* Construct the literal and distance trees */
57266 + build_tree(s, (tree_desc *)(&(s->l_desc)));
57267 + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
57268 + s->static_len));
57269 +
57270 + build_tree(s, (tree_desc *)(&(s->d_desc)));
57271 + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
57272 + s->static_len));
57273 + /* At this point, opt_len and static_len are the total bit lengths of
57274 + * the compressed block data, excluding the tree representations.
57275 + */
57276 +
57277 + /* Build the bit length tree for the above two trees, and get the index
57278 + * in bl_order of the last bit length code to send.
57279 + */
57280 + max_blindex = build_bl_tree(s);
57281 +
57282 + /* Determine the best encoding. Compute first the block length in bytes*/
57283 + opt_lenb = (s->opt_len+3+7)>>3;
57284 + static_lenb = (s->static_len+3+7)>>3;
57285 +
57286 + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
57287 + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
57288 + s->last_lit));
57289 +
57290 + if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
57291 +
57292 + } else {
57293 + Assert(buf != (char*)0, "lost buf");
57294 + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
57295 + }
57296 +
57297 +#ifdef FORCE_STORED
57298 + if (buf != (char*)0) { /* force stored block */
57299 +#else
57300 + if (stored_len+4 <= opt_lenb && buf != (char*)0) {
57301 + /* 4: two words for the lengths */
57302 +#endif
57303 + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
57304 + * Otherwise we can't have processed more than WSIZE input bytes since
57305 + * the last block flush, because compression would have been
57306 + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
57307 + * transform a block into a stored block.
57308 + */
57309 + _tr_stored_block(s, buf, stored_len, eof);
57310 +
57311 +#ifdef FORCE_STATIC
57312 + } else if (static_lenb >= 0) { /* force static trees */
57313 +#else
57314 + } else if (static_lenb == opt_lenb) {
57315 +#endif
57316 + send_bits(s, (STATIC_TREES<<1)+eof, 3);
57317 + compress_block(s, static_ltree, static_dtree);
57318 +#ifdef DEBUG
57319 + s->compressed_len += 3 + s->static_len;
57320 +#endif
57321 + } else {
57322 + send_bits(s, (DYN_TREES<<1)+eof, 3);
57323 + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
57324 + max_blindex+1);
57325 + compress_block(s, s->dyn_ltree, s->dyn_dtree);
57326 +#ifdef DEBUG
57327 + s->compressed_len += 3 + s->opt_len;
57328 +#endif
57329 + }
57330 + Assert (s->compressed_len == s->bits_sent, "bad compressed size");
57331 + /* The above check is made mod 2^32, for files larger than 512 MB
57332 + * and uLong implemented on 32 bits.
57333 + */
57334 + init_block(s);
57335 +
57336 + if (eof) {
57337 + bi_windup(s);
57338 +#ifdef DEBUG
57339 + s->compressed_len += 7; /* align on byte boundary */
57340 +#endif
57341 + }
57342 + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
57343 + s->compressed_len-7*eof));
57344 +}
57345 +
57346 +/* ===========================================================================
57347 + * Save the match info and tally the frequency counts. Return true if
57348 + * the current block must be flushed.
57349 + */
57350 +int _tr_tally (s, dist, lc)
57351 + deflate_state *s;
57352 + unsigned dist; /* distance of matched string */
57353 + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
57354 +{
57355 + s->d_buf[s->last_lit] = (ush)dist;
57356 + s->l_buf[s->last_lit++] = (uch)lc;
57357 + if (dist == 0) {
57358 + /* lc is the unmatched char */
57359 + s->dyn_ltree[lc].Freq++;
57360 + } else {
57361 + s->matches++;
57362 + /* Here, lc is the match length - MIN_MATCH */
57363 + dist--; /* dist = match distance - 1 */
57364 + Assert((ush)dist < (ush)MAX_DIST(s) &&
57365 + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
57366 + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
57367 +
57368 + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
57369 + s->dyn_dtree[d_code(dist)].Freq++;
57370 + }
57371 +
57372 +#ifdef TRUNCATE_BLOCK
57373 + /* Try to guess if it is profitable to stop the current block here */
57374 + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
57375 + /* Compute an upper bound for the compressed length */
57376 + ulg out_length = (ulg)s->last_lit*8L;
57377 + ulg in_length = (ulg)((long)s->strstart - s->block_start);
57378 + int dcode;
57379 + for (dcode = 0; dcode < D_CODES; dcode++) {
57380 + out_length += (ulg)s->dyn_dtree[dcode].Freq *
57381 + (5L+extra_dbits[dcode]);
57382 + }
57383 + out_length >>= 3;
57384 + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
57385 + s->last_lit, in_length, out_length,
57386 + 100L - out_length*100L/in_length));
57387 + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
57388 + }
57389 +#endif
57390 + return (s->last_lit == s->lit_bufsize-1);
57391 + /* We avoid equality with lit_bufsize because of wraparound at 64K
57392 + * on 16 bit machines and because stored blocks are restricted to
57393 + * 64K-1 bytes.
57394 + */
57395 +}
57396 +
57397 +/* ===========================================================================
57398 + * Send the block data compressed using the given Huffman trees
57399 + */
57400 +local void compress_block(s, ltree, dtree)
57401 + deflate_state *s;
57402 + const ct_data *ltree; /* literal tree */
57403 + const ct_data *dtree; /* distance tree */
57404 +{
57405 + unsigned dist; /* distance of matched string */
57406 + int lc; /* match length or unmatched char (if dist == 0) */
57407 + unsigned lx = 0; /* running index in l_buf */
57408 + unsigned code; /* the code to send */
57409 + int extra; /* number of extra bits to send */
57410 +
57411 + if (s->last_lit != 0) do {
57412 + dist = s->d_buf[lx];
57413 + lc = s->l_buf[lx++];
57414 + if (dist == 0) {
57415 + send_code(s, lc, ltree); /* send a literal byte */
57416 + Tracecv(isgraph(lc), (stderr," '%c' ", lc));
57417 + } else {
57418 + /* Here, lc is the match length - MIN_MATCH */
57419 + code = _length_code[lc];
57420 + send_code(s, code+LITERALS+1, ltree); /* send the length code */
57421 + extra = extra_lbits[code];
57422 + if (extra != 0) {
57423 + lc -= base_length[code];
57424 + send_bits(s, lc, extra); /* send the extra length bits */
57425 + }
57426 + dist--; /* dist is now the match distance - 1 */
57427 + code = d_code(dist);
57428 + Assert (code < D_CODES, "bad d_code");
57429 +
57430 + send_code(s, code, dtree); /* send the distance code */
57431 + extra = extra_dbits[code];
57432 + if (extra != 0) {
57433 + dist -= base_dist[code];
57434 + send_bits(s, dist, extra); /* send the extra distance bits */
57435 + }
57436 + } /* literal or match pair ? */
57437 +
57438 + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
57439 + Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
57440 +
57441 + } while (lx < s->last_lit);
57442 +
57443 + send_code(s, END_BLOCK, ltree);
57444 + s->last_eob_len = ltree[END_BLOCK].Len;
57445 +}
57446 +
57447 +/* ===========================================================================
57448 + * Set the data type to ASCII or BINARY, using a crude approximation:
57449 + * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
57450 + * IN assertion: the fields freq of dyn_ltree are set and the total of all
57451 + * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
57452 + */
57453 +local void set_data_type(s)
57454 + deflate_state *s;
57455 +{
57456 + int n = 0;
57457 + unsigned ascii_freq = 0;
57458 + unsigned bin_freq = 0;
57459 + while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
57460 + while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
57461 + while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
57462 + s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
57463 +}
57464 +
57465 +/* ===========================================================================
57466 + * Reverse the first len bits of a code, using straightforward code (a faster
57467 + * method would use a table)
57468 + * IN assertion: 1 <= len <= 15
57469 + */
57470 +local unsigned bi_reverse(code, len)
57471 + unsigned code; /* the value to invert */
57472 + int len; /* its bit length */
57473 +{
57474 + register unsigned res = 0;
57475 + do {
57476 + res |= code & 1;
57477 + code >>= 1, res <<= 1;
57478 + } while (--len > 0);
57479 + return res >> 1;
57480 +}
57481 +
57482 +/* ===========================================================================
57483 + * Flush the bit buffer, keeping at most 7 bits in it.
57484 + */
57485 +local void bi_flush(s)
57486 + deflate_state *s;
57487 +{
57488 + if (s->bi_valid == 16) {
57489 + put_short(s, s->bi_buf);
57490 + s->bi_buf = 0;
57491 + s->bi_valid = 0;
57492 + } else if (s->bi_valid >= 8) {
57493 + put_byte(s, (Byte)s->bi_buf);
57494 + s->bi_buf >>= 8;
57495 + s->bi_valid -= 8;
57496 + }
57497 +}
57498 +
57499 +/* ===========================================================================
57500 + * Flush the bit buffer and align the output on a byte boundary
57501 + */
57502 +local void bi_windup(s)
57503 + deflate_state *s;
57504 +{
57505 + if (s->bi_valid > 8) {
57506 + put_short(s, s->bi_buf);
57507 + } else if (s->bi_valid > 0) {
57508 + put_byte(s, (Byte)s->bi_buf);
57509 + }
57510 + s->bi_buf = 0;
57511 + s->bi_valid = 0;
57512 +#ifdef DEBUG
57513 + s->bits_sent = (s->bits_sent+7) & ~7;
57514 +#endif
57515 +}
57516 +
57517 +/* ===========================================================================
57518 + * Copy a stored block, storing first the length and its
57519 + * one's complement if requested.
57520 + */
57521 +local void copy_block(s, buf, len, header)
57522 + deflate_state *s;
57523 + charf *buf; /* the input data */
57524 + unsigned len; /* its length */
57525 + int header; /* true if block header must be written */
57526 +{
57527 + bi_windup(s); /* align on byte boundary */
57528 + s->last_eob_len = 8; /* enough lookahead for inflate */
57529 +
57530 + if (header) {
57531 + put_short(s, (ush)len);
57532 + put_short(s, (ush)~len);
57533 +#ifdef DEBUG
57534 + s->bits_sent += 2*16;
57535 +#endif
57536 + }
57537 +#ifdef DEBUG
57538 + s->bits_sent += (ulg)len<<3;
57539 +#endif
57540 + while (len--) {
57541 + put_byte(s, *buf++);
57542 + }
57543 +}
57544 --- /dev/null Tue Mar 11 13:02:56 2003
57545 +++ linux/net/ipsec/trees.h Mon Feb 9 13:51:03 2004
57546 @@ -0,0 +1,128 @@
57547 +/* header created automatically with -DGEN_TREES_H */
57548 +
57549 +local const ct_data static_ltree[L_CODES+2] = {
57550 +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
57551 +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
57552 +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
57553 +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
57554 +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
57555 +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
57556 +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
57557 +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
57558 +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
57559 +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
57560 +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
57561 +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
57562 +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
57563 +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
57564 +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
57565 +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
57566 +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
57567 +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
57568 +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
57569 +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
57570 +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
57571 +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
57572 +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
57573 +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
57574 +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
57575 +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
57576 +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
57577 +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
57578 +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
57579 +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
57580 +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
57581 +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
57582 +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
57583 +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
57584 +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
57585 +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
57586 +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
57587 +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
57588 +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
57589 +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
57590 +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
57591 +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
57592 +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
57593 +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
57594 +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
57595 +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
57596 +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
57597 +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
57598 +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
57599 +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
57600 +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
57601 +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
57602 +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
57603 +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
57604 +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
57605 +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
57606 +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
57607 +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
57608 +};
57609 +
57610 +local const ct_data static_dtree[D_CODES] = {
57611 +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
57612 +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
57613 +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
57614 +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
57615 +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
57616 +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
57617 +};
57618 +
57619 +const uch _dist_code[DIST_CODE_LEN] = {
57620 + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
57621 + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
57622 +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
57623 +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
57624 +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
57625 +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
57626 +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
57627 +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
57628 +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
57629 +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
57630 +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
57631 +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
57632 +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
57633 +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
57634 +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
57635 +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
57636 +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
57637 +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
57638 +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
57639 +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
57640 +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
57641 +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
57642 +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
57643 +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
57644 +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
57645 +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
57646 +};
57647 +
57648 +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
57649 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
57650 +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
57651 +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
57652 +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
57653 +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
57654 +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
57655 +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
57656 +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
57657 +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
57658 +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
57659 +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
57660 +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
57661 +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
57662 +};
57663 +
57664 +local const int base_length[LENGTH_CODES] = {
57665 +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
57666 +64, 80, 96, 112, 128, 160, 192, 224, 0
57667 +};
57668 +
57669 +local const int base_dist[D_CODES] = {
57670 + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
57671 + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
57672 + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
57673 +};
57674 +
57675 --- /dev/null Tue Mar 11 13:02:56 2003
57676 +++ linux/net/ipsec/ultoa.c Mon Feb 9 13:51:03 2004
57677 @@ -0,0 +1,66 @@
57678 +/*
57679 + * convert unsigned long to ASCII
57680 + * Copyright (C) 1998, 1999 Henry Spencer.
57681 + *
57682 + * This library is free software; you can redistribute it and/or modify it
57683 + * under the terms of the GNU Library General Public License as published by
57684 + * the Free Software Foundation; either version 2 of the License, or (at your
57685 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57686 + *
57687 + * This library is distributed in the hope that it will be useful, but
57688 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57689 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57690 + * License for more details.
57691 + *
57692 + * RCSID $Id: ultoa.c,v 1.10 2004/07/10 07:48:37 mcr Exp $
57693 + */
57694 +#include "openswan.h"
57695 +
57696 +/*
57697 + - ultoa - convert unsigned long to decimal ASCII
57698 + */
57699 +size_t /* length required for full conversion */
57700 +ultoa(n, base, dst, dstlen)
57701 +unsigned long n;
57702 +int base;
57703 +char *dst; /* need not be valid if dstlen is 0 */
57704 +size_t dstlen;
57705 +{
57706 + char buf[3*sizeof(unsigned long) + 1];
57707 + char *bufend = buf + sizeof(buf);
57708 + size_t len;
57709 + char *p;
57710 + static char hex[] = "0123456789abcdef";
57711 +
57712 + p = bufend;
57713 + *--p = '\0';
57714 + if (base == 10) {
57715 + do {
57716 + *--p = n%10 + '0';
57717 + n /= 10;
57718 + } while (n != 0);
57719 + } else if (base == 16) {
57720 + do {
57721 + *--p = hex[n&0xf];
57722 + n >>= 4;
57723 + } while (n != 0);
57724 + *--p = 'x';
57725 + *--p = '0';
57726 + } else if (base == 8) {
57727 + do {
57728 + *--p = (n&07) + '0';
57729 + n >>= 3;
57730 + } while (n != 0);
57731 + *--p = '0';
57732 + } else
57733 + *--p = '?';
57734 +
57735 + len = bufend - p;
57736 +
57737 + if (dstlen > 0) {
57738 + if (len > dstlen)
57739 + *(p + dstlen - 1) = '\0';
57740 + strcpy(dst, p);
57741 + }
57742 + return len;
57743 +}
57744 --- /dev/null Tue Mar 11 13:02:56 2003
57745 +++ linux/net/ipsec/ultot.c Mon Feb 9 13:51:03 2004
57746 @@ -0,0 +1,82 @@
57747 +/*
57748 + * convert unsigned long to text
57749 + * Copyright (C) 2000 Henry Spencer.
57750 + *
57751 + * This library is free software; you can redistribute it and/or modify it
57752 + * under the terms of the GNU Library General Public License as published by
57753 + * the Free Software Foundation; either version 2 of the License, or (at your
57754 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57755 + *
57756 + * This library is distributed in the hope that it will be useful, but
57757 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57758 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57759 + * License for more details.
57760 + *
57761 + * RCSID $Id: ultot.c,v 1.5 2004/07/10 07:48:37 mcr Exp $
57762 + */
57763 +#include "openswan.h"
57764 +
57765 +/*
57766 + - ultot - convert unsigned long to text
57767 + */
57768 +size_t /* length required for full conversion */
57769 +ultot(n, base, dst, dstlen)
57770 +unsigned long n;
57771 +int base;
57772 +char *dst; /* need not be valid if dstlen is 0 */
57773 +size_t dstlen;
57774 +{
57775 + char buf[3*sizeof(unsigned long) + 1];
57776 + char *bufend = buf + sizeof(buf);
57777 + size_t len;
57778 + char *p;
57779 + static char hex[] = "0123456789abcdef";
57780 +# define HEX32 (32/4)
57781 +
57782 + p = bufend;
57783 + *--p = '\0';
57784 + switch (base) {
57785 + case 10:
57786 + case 'd':
57787 + do {
57788 + *--p = n%10 + '0';
57789 + n /= 10;
57790 + } while (n != 0);
57791 + break;
57792 + case 16:
57793 + case 17:
57794 + case 'x':
57795 + do {
57796 + *--p = hex[n&0xf];
57797 + n >>= 4;
57798 + } while (n != 0);
57799 + if (base == 17)
57800 + while (bufend - p < HEX32 + 1)
57801 + *--p = '0';
57802 + if (base == 'x') {
57803 + *--p = 'x';
57804 + *--p = '0';
57805 + }
57806 + break;
57807 + case 8:
57808 + case 'o':
57809 + do {
57810 + *--p = (n&07) + '0';
57811 + n >>= 3;
57812 + } while (n != 0);
57813 + if (base == 'o')
57814 + *--p = '0';
57815 + break;
57816 + default:
57817 + return 0;
57818 + break;
57819 + }
57820 +
57821 + len = bufend - p;
57822 + if (dstlen > 0) {
57823 + if (len > dstlen)
57824 + *(p + dstlen - 1) = '\0';
57825 + strcpy(dst, p);
57826 + }
57827 + return len;
57828 +}
57829 --- /dev/null Tue Mar 11 13:02:56 2003
57830 +++ linux/net/ipsec/version.c Mon Feb 9 13:51:03 2004
57831 @@ -0,0 +1,44 @@
57832 +/*
57833 + * return IPsec version information
57834 + * Copyright (C) 2001 Henry Spencer.
57835 + *
57836 + * This library is free software; you can redistribute it and/or modify it
57837 + * under the terms of the GNU Library General Public License as published by
57838 + * the Free Software Foundation; either version 2 of the License, or (at your
57839 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57840 + *
57841 + * This library is distributed in the hope that it will be useful, but
57842 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57843 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57844 + * License for more details.
57845 + *
57846 + * RCSID $Id: version.in.c,v 1.2 2004/04/14 05:09:46 ken Exp $
57847 + */
57848 +
57849 +#ifdef __KERNEL__
57850 +#include <linux/netdevice.h>
57851 +#endif
57852 +
57853 +#include "openswan.h"
57854 +
57855 +#define V "2.5.13" /* substituted in by Makefile */
57856 +static const char openswan_number[] = V;
57857 +static const char openswan_string[] = "Openswan " V;
57858 +
57859 +/*
57860 + - ipsec_version_code - return IPsec version number/code, as string
57861 + */
57862 +const char *
57863 +ipsec_version_code()
57864 +{
57865 + return openswan_number;
57866 +}
57867 +
57868 +/*
57869 + - ipsec_version_string - return full version string
57870 + */
57871 +const char *
57872 +ipsec_version_string()
57873 +{
57874 + return openswan_string;
57875 +}
57876 --- /dev/null Tue Mar 11 13:02:56 2003
57877 +++ linux/net/ipsec/zutil.c Mon Feb 9 13:51:03 2004
57878 @@ -0,0 +1,227 @@
57879 +/* zutil.c -- target dependent utility functions for the compression library
57880 + * Copyright (C) 1995-2002 Jean-loup Gailly.
57881 + * For conditions of distribution and use, see copyright notice in zlib.h
57882 + */
57883 +
57884 +/* @(#) $Id: zutil.c,v 1.5 2004/07/10 07:48:40 mcr Exp $ */
57885 +
57886 +#include <zlib/zutil.h>
57887 +
57888 +#define MY_ZCALLOC
57889 +
57890 +struct internal_state {int dummy;}; /* for buggy compilers */
57891 +
57892 +#ifndef STDC
57893 +extern void exit OF((int));
57894 +#endif
57895 +
57896 +const char *z_errmsg[10] = {
57897 +"need dictionary", /* Z_NEED_DICT 2 */
57898 +"stream end", /* Z_STREAM_END 1 */
57899 +"", /* Z_OK 0 */
57900 +"file error", /* Z_ERRNO (-1) */
57901 +"stream error", /* Z_STREAM_ERROR (-2) */
57902 +"data error", /* Z_DATA_ERROR (-3) */
57903 +"insufficient memory", /* Z_MEM_ERROR (-4) */
57904 +"buffer error", /* Z_BUF_ERROR (-5) */
57905 +"incompatible version",/* Z_VERSION_ERROR (-6) */
57906 +""};
57907 +
57908 +
57909 +const char * ZEXPORT zlibVersion()
57910 +{
57911 + return ZLIB_VERSION;
57912 +}
57913 +
57914 +#ifdef DEBUG
57915 +
57916 +# ifndef verbose
57917 +# define verbose 0
57918 +# endif
57919 +int z_verbose = verbose;
57920 +
57921 +void z_error (m)
57922 + char *m;
57923 +{
57924 + fprintf(stderr, "%s\n", m);
57925 + exit(1);
57926 +}
57927 +#endif
57928 +
57929 +/* exported to allow conversion of error code to string for compress() and
57930 + * uncompress()
57931 + */
57932 +const char * ZEXPORT zError(err)
57933 + int err;
57934 +{
57935 + return ERR_MSG(err);
57936 +}
57937 +
57938 +
57939 +#ifndef HAVE_MEMCPY
57940 +
57941 +void zmemcpy(dest, source, len)
57942 + Bytef* dest;
57943 + const Bytef* source;
57944 + uInt len;
57945 +{
57946 + if (len == 0) return;
57947 + do {
57948 + *dest++ = *source++; /* ??? to be unrolled */
57949 + } while (--len != 0);
57950 +}
57951 +
57952 +int zmemcmp(s1, s2, len)
57953 + const Bytef* s1;
57954 + const Bytef* s2;
57955 + uInt len;
57956 +{
57957 + uInt j;
57958 +
57959 + for (j = 0; j < len; j++) {
57960 + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
57961 + }
57962 + return 0;
57963 +}
57964 +
57965 +void zmemzero(dest, len)
57966 + Bytef* dest;
57967 + uInt len;
57968 +{
57969 + if (len == 0) return;
57970 + do {
57971 + *dest++ = 0; /* ??? to be unrolled */
57972 + } while (--len != 0);
57973 +}
57974 +#endif
57975 +
57976 +#ifdef __TURBOC__
57977 +#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
57978 +/* Small and medium model in Turbo C are for now limited to near allocation
57979 + * with reduced MAX_WBITS and MAX_MEM_LEVEL
57980 + */
57981 +# define MY_ZCALLOC
57982 +
57983 +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
57984 + * and farmalloc(64K) returns a pointer with an offset of 8, so we
57985 + * must fix the pointer. Warning: the pointer must be put back to its
57986 + * original form in order to free it, use zcfree().
57987 + */
57988 +
57989 +#define MAX_PTR 10
57990 +/* 10*64K = 640K */
57991 +
57992 +local int next_ptr = 0;
57993 +
57994 +typedef struct ptr_table_s {
57995 + voidpf org_ptr;
57996 + voidpf new_ptr;
57997 +} ptr_table;
57998 +
57999 +local ptr_table table[MAX_PTR];
58000 +/* This table is used to remember the original form of pointers
58001 + * to large buffers (64K). Such pointers are normalized with a zero offset.
58002 + * Since MSDOS is not a preemptive multitasking OS, this table is not
58003 + * protected from concurrent access. This hack doesn't work anyway on
58004 + * a protected system like OS/2. Use Microsoft C instead.
58005 + */
58006 +
58007 +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
58008 +{
58009 + voidpf buf = opaque; /* just to make some compilers happy */
58010 + ulg bsize = (ulg)items*size;
58011 +
58012 + /* If we allocate less than 65520 bytes, we assume that farmalloc
58013 + * will return a usable pointer which doesn't have to be normalized.
58014 + */
58015 + if (bsize < 65520L) {
58016 + buf = farmalloc(bsize);
58017 + if (*(ush*)&buf != 0) return buf;
58018 + } else {
58019 + buf = farmalloc(bsize + 16L);
58020 + }
58021 + if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
58022 + table[next_ptr].org_ptr = buf;
58023 +
58024 + /* Normalize the pointer to seg:0 */
58025 + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
58026 + *(ush*)&buf = 0;
58027 + table[next_ptr++].new_ptr = buf;
58028 + return buf;
58029 +}
58030 +
58031 +void zcfree (voidpf opaque, voidpf ptr)
58032 +{
58033 + int n;
58034 + if (*(ush*)&ptr != 0) { /* object < 64K */
58035 + farfree(ptr);
58036 + return;
58037 + }
58038 + /* Find the original pointer */
58039 + for (n = 0; n < next_ptr; n++) {
58040 + if (ptr != table[n].new_ptr) continue;
58041 +
58042 + farfree(table[n].org_ptr);
58043 + while (++n < next_ptr) {
58044 + table[n-1] = table[n];
58045 + }
58046 + next_ptr--;
58047 + return;
58048 + }
58049 + ptr = opaque; /* just to make some compilers happy */
58050 + Assert(0, "zcfree: ptr not found");
58051 +}
58052 +#endif
58053 +#endif /* __TURBOC__ */
58054 +
58055 +
58056 +#if defined(M_I86) && !defined(__32BIT__)
58057 +/* Microsoft C in 16-bit mode */
58058 +
58059 +# define MY_ZCALLOC
58060 +
58061 +#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
58062 +# define _halloc halloc
58063 +# define _hfree hfree
58064 +#endif
58065 +
58066 +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
58067 +{
58068 + if (opaque) opaque = 0; /* to make compiler happy */
58069 + return _halloc((long)items, size);
58070 +}
58071 +
58072 +void zcfree (voidpf opaque, voidpf ptr)
58073 +{
58074 + if (opaque) opaque = 0; /* to make compiler happy */
58075 + _hfree(ptr);
58076 +}
58077 +
58078 +#endif /* MSC */
58079 +
58080 +
58081 +#ifndef MY_ZCALLOC /* Any system without a special alloc function */
58082 +
58083 +#ifndef STDC
58084 +extern voidp calloc OF((uInt items, uInt size));
58085 +extern void free OF((voidpf ptr));
58086 +#endif
58087 +
58088 +voidpf zcalloc (opaque, items, size)
58089 + voidpf opaque;
58090 + unsigned items;
58091 + unsigned size;
58092 +{
58093 + if (opaque) items += size - size; /* make compiler happy */
58094 + return (voidpf)calloc(items, size);
58095 +}
58096 +
58097 +void zcfree (opaque, ptr)
58098 + voidpf opaque;
58099 + voidpf ptr;
58100 +{
58101 + free(ptr);
58102 + if (opaque) return; /* make compiler happy */
58103 +}
58104 +
58105 +#endif /* MY_ZCALLOC */
58106 --- swan26/net/ipv4/af_inet.c.orig Wed Jun 16 01:18:58 2004
58107 +++ swan26/net/ipv4/af_inet.c Fri Aug 13 23:09:27 2004
58108 @@ -1169,6 +1169,18 @@
58109 #if defined(CONFIG_IP_MROUTE)
58110 ip_mr_init();
58111 #endif
58112 +
58113 +#if defined(CONFIG_KLIPS)
58114 + {
58115 + extern int ipsec_klips_init(void);
58116 + /*
58117 + * Initialise AF_INET ESP and AH protocol support including
58118 + * e-routing and SA tables
58119 + */
58120 + ipsec_klips_init();
58121 + }
58122 +#endif /* CONFIG_IPSEC */
58123 +
58124 /*
58125 * Initialise per-cpu ipv4 mibs
58126 */
58127 --- /dev/null Fri May 10 13:59:54 2002
58128 +++ linux/net/ipsec/Makefile.ver Sun Jul 28 22:10:40 2002
58129 @@ -0,0 +1 @@
58130 +IPSECVERSION='2.5.13'